Windows Programming //Skeleton Windows Program - a very basic Hello World program. //Copyright 2001 by David Friend. All rights reserved. //Comments / Questions: [email protected] //Freely reuse and redistribute provided nothing is removed. //Hint: Windows (with a capital) implies the Windows Operating System // window (lowercase) implies a window of a program #include <windows.h> //Includes ALL of the functions that we will use. //These functions are defined in various DLLs packaged //with 32-bit Windows versions (Win95 and higher). //Therefore, our executable program (the *.exe thing) //will be small because it uses "built-in" Windows //functions. (Don't worry, DLLs are still fast...) //Function prototyes (programmer defined) //For this program there is only one... LRESULT CALLBACK WindowProc(HWND, // handle to window (notice, lowercase) UINT, // message identifier WPARAM, // first message parameter LPARAM); // second message parameter /*****************************************************************************\ * WinMain is the entry point of the program. It is like the main() funtion in * * a console application. WinMain sets up a window, displays it to the user, * * and contains the main program loop. * \*****************************************************************************/ int WINAPI WinMain(HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow) // show state (minimized, default, etc) //The return types on this and WindowProc look foreign; don't worry about them. { /* DEFINITION - Handle (any varaible type that begins with an H is a handle) A Handle is a unique identifier of an object. Everything that you see in Windows has a handle that unique identifies it to the OS and other programs. Every button, window, text label, graphic device, etc. has a handle. Even a variable can have a handle, so handles are not only for objects that the user can see. */ HWND hWnd; //Handle to window MSG msg; //Messages WNDCLASS wndClass; //window class structure char szWindowClassName[] = "CBlankWindow"; //Class name /* Define a window class - Fill a WNDCLASS structure with parameters Don't be confused by the CLASS part of WNDCLASS - it is NOT a class. (In Windows programming, a variable type that starts with a C is a class. Examples include CString - string class, and CArray.) The following lines of code go through each member of the WNDCLASS struct and set it to an appropiate value. Collectively, this data is a description of a window. */ wndClass.style = NULL; //Specifies the class style(s) wndClass.lpfnWndProc = WindowProc; //Pointer to procedure that //processes window messages //(more on this later...) wndClass.cbClsExtra = 0; //Extra bytes after structure for //programmer defined data wndClass.cbWndExtra = 0; //Extra bytes after window //instance used for various window //styles. wndClass.hInstance = hInstance; //Application instance in case //the window class is registered //more than once by more than //one application. This is one of the //parameters passed to WinMain. wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); //handle to icon of window wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); //handle to cursor of window wndClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); //Handle to the //background color wndClass.lpszMenuName = NULL; //pointer to menu resource (in resource file) wndClass.lpszClassName = szWindowClassName; //Pointer to window class name //This name will be used to //create a window with this data //Ultimately, this name is a //name associated with this //unique window data. /* Register Window Class - Let Windows know that we have a window that we will be using. Once we have loaded the data into the WNDCLASS, we need to tell Windows about the window, or register the window with Windows so that it will let us create the window. This function associates our window data with the szWindowClassName. Remember: wndClass.lpszClassName = szWindowClassName. */ if (!RegisterClass(&wndClass)) return 0; //If error, exit /* Now that we have told Windows about this new window, we can use it. CreateWindow tells Windows to create a new window described by our class (really a struct) that we registered. Depsite the data we filled into the WNDCLASS structure, it was just an outline of the window. We now have to add more detail. Notice that CreateWindow returns a handle to the window that it creates. This allows our program to access and control the window. */ hWnd = CreateWindow( szWindowClassName, //Which window class name to use "Hello World!", //Window caption WS_POPUP | //Window style WS_OVERLAPPEDWINDOW, 100, //Logical x coordinate of upper-left corner 100, //Logical y coordinate of upper-right corner 200, //Width of window (x) 200, //Height of window (y) NULL, //Handle to window's parent NULL, //Handle to window's menu (in resource file) hInstance, //handle to instance of the application NULL); //Pointer to above parameters if not listed /* ShowWindow. Although we created it, Windows does not automatically show our window to the user. ShowWindow displays the window. Notice that it recieves a handle to identify which window to show. nCmdShow was passed to WinMain and specifies the state - minimized, maximized, etc. that the window should have. */ ShowWindow(hWnd, nCmdShow); /* Update the window - make it paint itself, etc. */ UpdateWindow(hWnd); //Main Program Loop while (GetMessage(&msg, NULL, 0, 0)) //GetMessage recieves any new message //that is floating around the OS { TranslateMessage(&msg); //Translate that message into something our //program / window can understand DispatchMessage(&msg); //Send the message to the procedure that //will process it - Remember, we specified //this procedure in our WNDCLASS structure. //In this program it is called "WindowProc" } return msg.wParam; //Standard return value for Windows, like return 0; } /***************************************************************************************\ * WindowProc() * * This processes the window input. This input could be any type of input in the form * * of messages. It recieves the message dispatched by DispatchMessage of our WinMain. * * Realize that this input is for the window, originating from 1. the user, 2. Windows, * * and 3. other programs / other windows. * * OK, we could have called this whatever we wanted. It is called by Windows through a * * pointer. And how did Windows know what the pointer was? We told it when we defined * * the window class. Remember, wndClass.lpfnWndProc = WindowProc. * \***************************************************************************************/ LRESULT CALLBACK WindowProc( HWND hWnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam) // second message parameter { /* EVERYTHING is done through messages. EVERYTHING. If the user presses a button, the OS sends the program a message. If the user wants to close the program, the OS sends a message. If any window moves, the OS sends a message (usually telling this program to redraw itself). */ switch(uMsg) { case WM_DESTROY: //The user click the close button //or the OS is trying to close the //program PostQuitMessage(0); //Close the program break; default: //Default message processing function - will do //everything except close our program when needed. return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } |