1: /* 2: * A basic example of Win32 programming in C. 3: * 4: * This source code is in the PUBLIC DOMAIN and has NO WARRANTY. 5: * 6: * Colin Peters7: */ 8: 9: #include 10: #include 11: 12: /* 13: * This is the window function for the main window. Whenever a message is 14: * dispatched using DispatchMessage (or sent with SendMessage) this function 15: * gets called with the contents of the message. 16: */ 17: LRESULT CALLBACK 18: MainWndProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam) 19: { 20: /* The window handle for the "Click Me" button. */ 21: static HWND hwndButton = 0; 22: static int cx, cy; /* Height and width of our button. */ 23: 24: HDC hdc; /* A device context used for drawing */ 25: PAINTSTRUCT ps; /* Also used during window drawing */ 26: RECT rc; /* A rectangle used during drawing */ 27: 28: /* 29: * Perform processing based on what kind of message we got. 30: */ 31: switch (nMsg) 32: { 33: case WM_CREATE: 34: { 35: /* The window is being created. Create our button 36: * window now. */ 37: TEXTMETRIC tm; 38: 39: /* First we use the system fixed font size to choose 40: * a nice button size. */ 41: hdc = GetDC (hwnd); 42: SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)); 43: GetTextMetrics (hdc, &tm); 44: cx = tm.tmAveCharWidth * 30; 45: cy = (tm.tmHeight + tm.tmExternalLeading) * 2; 46: ReleaseDC (hwnd, hdc); 47: 48: /* Now create the button */ 49: hwndButton = CreateWindow ( 50: "button", /* Builtin button class */ 51: "Click Here", 52: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 53: 0, 0, cx, cy, 54: hwnd, /* Parent is this window. */ 55: (HMENU) 1, /* Control ID: 1 */ 56: ((LPCREATESTRUCT) lParam)->hInstance, 57: NULL 58: ); 59: 60: return 0; 61: break; 62: } 63: 64: case WM_DESTROY: 65: /* The window is being destroyed, close the application 66: * (the child button gets destroyed automatically). */ 67: PostQuitMessage (0); 68: return 0; 69: break; 70: 71: case WM_PAINT: 72: /* The window needs to be painted (redrawn). */ 73: hdc = BeginPaint (hwnd, &ps); 74: GetClientRect (hwnd, &rc); 75: 76: /* Draw "Hello, World" in the middle of the upper 77: * half of the window. */ 78: rc.bottom = rc.bottom / 2; 79: DrawText (hdc, "Hello, World", -1, &rc, 80: DT_SINGLELINE | DT_CENTER | DT_VCENTER); 81: 82: EndPaint (hwnd, &ps); 83: return 0; 84: break; 85: 86: case WM_SIZE: 87: /* The window size is changing. If the button exists 88: * then place it in the center of the bottom half of 89: * the window. */ 90: if (hwndButton && 91: (wParam == SIZEFULLSCREEN || 92: wParam == SIZENORMAL) 93: ) 94: { 95: rc.left = (LOWORD(lParam) - cx) / 2; 96: rc.top = HIWORD(lParam) * 3 / 4 - cy / 2; 97: MoveWindow ( 98: hwndButton, 99: rc.left, rc.top, cx, cy, TRUE); 100: } 101: break; 102: 103: case WM_COMMAND: 104: /* Check the control ID, notification code and 105: * control handle to see if this is a button click 106: * message from our child button. */ 107: if (LOWORD(wParam) == 1 && 108: HIWORD(wParam) == BN_CLICKED && 109: (HWND) lParam == hwndButton) 110: { 111: /* Our button was clicked. Close the window. */ 112: DestroyWindow (hwnd); 113: } 114: return 0; 115: break; 116: } 117: 118: /* If we don't handle a message completely we hand it to the system 119: * provided default window function. */ 120: return DefWindowProc (hwnd, nMsg, wParam, lParam); 121: } 122: 123: 124: int STDCALL 125: WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) 126: { 127: HWND hwndMain; /* Handle for the main window. */ 128: MSG msg; /* A Win32 message structure. */ 129: WNDCLASSEX wndclass; /* A window class structure. */ 130: char* szMainWndClass = "WinTestWin"; 131: /* The name of the main window class */ 132: 133: /* 134: * First we create a window class for our main window. 135: */ 136: 137: /* Initialize the entire structure to zero. */ 138: memset (&wndclass, 0, sizeof(WNDCLASSEX)); 139: 140: /* This class is called WinTestWin */ 141: wndclass.lpszClassName = szMainWndClass; 142: 143: /* cbSize gives the size of the structure for extensibility. */ 144: wndclass.cbSize = sizeof(WNDCLASSEX); 145: 146: /* All windows of this class redraw when resized. */ 147: wndclass.style = CS_HREDRAW | CS_VREDRAW; 148: 149: /* All windows of this class use the MainWndProc window function. */ 150: wndclass.lpfnWndProc = MainWndProc; 151: 152: /* This class is used with the current program instance. */ 153: wndclass.hInstance = hInst; 154: 155: /* Use standard application icon and arrow cursor provided by the OS */ 156: wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); 157: wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 158: wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); 159: 160: /* Color the background white */ 161: wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); 162: 163: /* 164: * Now register the window class for use. 165: */ 166: RegisterClassEx (&wndclass); 167: 168: /* 169: * Create our main window using that window class. 170: */ 171: hwndMain = CreateWindow ( 172: szMainWndClass, /* Class name */ 173: "Hello", /* Caption */ 174: WS_OVERLAPPEDWINDOW, /* Style */ 175: CW_USEDEFAULT, /* Initial x (use default) */ 176: CW_USEDEFAULT, /* Initial y (use default) */ 177: CW_USEDEFAULT, /* Initial x size (use default) */ 178: CW_USEDEFAULT, /* Initial y size (use default) */ 179: NULL, /* No parent window */ 180: NULL, /* No menu */ 181: hInst, /* This program instance */ 182: NULL /* Creation parameters */ 183: ); 184: 185: /* 186: * Display the window which we just created (using the nShow 187: * passed by the OS, which allows for start minimized and that 188: * sort of thing). 189: */ 190: ShowWindow (hwndMain, nShow); 191: UpdateWindow (hwndMain); 192: 193: /* 194: * The main message loop. All messages being sent to the windows 195: * of the application (or at least the primary thread) are retrieved 196: * by the GetMessage call, then translated (mainly for keyboard 197: * messages) and dispatched to the appropriate window procedure. 198: * This is the simplest kind of message loop. More complex loops 199: * are required for idle processing or handling modeless dialog 200: * boxes. When one of the windows calls PostQuitMessage GetMessage 201: * will return zero and the wParam of the message will be filled 202: * with the argument to PostQuitMessage. The loop will end and 203: * the application will close. 204: */ 205: while (GetMessage (&msg, NULL, 0, 0)) 206: { 207: TranslateMessage (&msg); 208: DispatchMessage (&msg); 209: } 210: return msg.wParam; 211: } 212: 213: 214: