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 Peters 
  7:   */
  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: