Oh, but they are, good sir! Sandboxing is not a new concept and has been around since the 1980s; however, as you have probably gathered, the limits of those types of sandboxing have been pushed to the point from a security point of view they look inadequate.
About sandboxing and the permissions model
Let me explain. When your computer boots, it starts up in 16-bit real mode for compatibility reasons (i.e. so you can still run DOS). To cut to the chase, you basically switch to 32-bit protected mode or 64-bit long mode, which are slightly different, but also reasonably similar. At this point your x86-based CPU is in supervisor mode and must set up and handle things like page faults and sysenter or software interrupts so you can do system calls. Skip a few million lines of code to launch all your hardware devices and tada, your first process runs.
Your process, as you may know, is created knowing nothing about the underlying system memory - it sees virtual memory. It is also created running in normal mode (called ring 3) which means it can't do things like set interrupt handlers or alter page flags. In short, it can't see other processes' existence (it "believes" it has full run of the computer) except by asking the operating system.
So, your average every day process is sandboxed, after a fashion. Now, all processes* must ask the operating system to do things, including Administrator ones. What decides whether they can is... the operating system.
Currently, this is mostly done via user permissions. Processes inherit the context of the user they are running as; so a process run as an Administrator user can do anything because the Windows kernel will check its permissions, find out it is an administrator and say "yes, ok" (with exceptions; user mode processes can't technically do certain things but they can load kernel mode processes (e.g. drivers) that can). Likewise, on Linux, root is assumed to be able to do anything.
So the current model (and now I finally get to your question) says that processes inherit and can do exactly what your user can do.
Now this might be a reasonable assumption, except that you might want to have a sensitive word document on your disk and run a web browser. As a result of the fact that your web browser can do anything you the user can do, the fact that you can read the document using word means the web browser could, if it wanted to, as well and there exists no provisions to prevent this.
There are designs for more invasive, more sandboxed permissions systems for operating systems, such as MAC. These systems all propose variants of the idea that each process is additionally constrained in what it can do; so your web browser is allowed only to access the network, temporary storage and the downloads folder. I asked for reasons for their lack of uptake here and the general consensus appears to be complexity is a major factor. People understand the current model well, even if that understanding is simply "I run as Administrator to prevent all the annoying dialogs". MAC systems are inherently complicated; you need knowledge of what a process should be able to do to constrain it.
The much maligned much hated security-failure Windows Vista actually introduced, amongst a slew of other excellent security features and a rebuild of certain OS components, Mandatory Integrity Controls. These go some way to building MAC-type components into Windows.
So, tl;dr for the general question: MAC is hard to understand and complicated to implement.
About those API calls
Now, onto scary API calls:
VirtualProtectEx: Changes the protection on a region of committed pages in the virtual address space of a specified process
WriteProcessMemory: Writes data to an area of memory in a specified process. The entire area to be written to must be accessible or the operation fails.
Take a note of the notes on the bottom of the latter one:
Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process to be written to can call the function. Typically but not always, the process with address space that is being written to is being debugged.
These all-caps values are constants which represent Windows permissions - you can only call that function if you have or can obtain those permissions on a process. On the former function, note:
The handle must have the PROCESS_VM_OPERATION access right. For more information, see Process Security and Access Rights.
The full set of process rights is discussed here. Now, most crucial of all to note is that you need SeDebugPrivilege. The details of this are best explained on the Old New Thing:
By default, users can debug only processes that they own. In order to debug processes owned by other users, you have to possess the SeDebugPrivilege privilege. But don't grant this privilege casually, because once you do, you gave away farm.
So yes, it is possible for you as a user to call these functions and debug processes, but only ones you already own. As the permissions model allows any process you have to do anything your user (including processes you have running) can do, this is expected. Debugging your own processes is a reasonable activity, although yes, it could be used for ill - this ability is the crux of the issue with the current model.
Now, onto GetKeyboardState:
An application can call this function to retrieve the current status of all the virtual keys. The status changes as a thread removes keyboard messages from its message queue.
All windows processes running GUIs have a message queue of events that have happened to them. What this says is that you can retrieve the keyboard state of your process after you have read an event. However, note that:
The status does not change as keyboard messages are posted to the thread's message queue, nor does it change as keyboard messages are posted to or retrieved from message queues of other threads. (Exception: Threads that are connected through AttachThreadInput share the same keyboard state.)
So, yes, you can use AttachThreadInput to hook other processes inputs. There is a workaround for this - see How does Windows Secure Desktop Mode Work?. Essentially, Windows supports multiple desktops and by using these you make it impossible to AttachThreadInput onto them.
tl;dr these functions combined with the current security model do represent a risk and a limitation of the current model, especially to the data and processes of the current user; however, there are levels of security protection in place for your system as a whole provided you are not running as an Administrator user!