Functions in C/C++ actually need two things.
Declaration: which is the prototype of the function you want to call
like: int printf(char *format, ...);
The compiler will use that for type checking, matching the number of arguments and pushing them in the expected format. This declaration will provide the information needed for compiling the caller code.
After the compiler is done from the first stage, the linker will come and put the functions together and point the calls to the offset of each function. Here where the linker is expecting to see the Definition of the functions (the code). the definition might be a code you written in your source code or external code inside a DLL.
In your case MessageBox is a Windows function and its code is inside user32.dll.
winuser.h actually contains the declaration of MessageBox but you don't need to include it because it is already included in windows.h and that is why the first stage is succeeded. If you the compiler doesn't see the declaration you will instead get "Unknown Identifier".
What happening is when the linker is trying to find the code for MessageBox it can't find it and that is why you are getting the linker error.
What user32.lib does is actually will tell the linker that the code for MessageBox is actually inside the user32.dll so the linker will know what to do.