|
|
1.1 root 1: /****************************************************************************
2:
1.1.1.3 ! root 3: PROGRAM: Generic.c
1.1 root 4:
1.1.1.3 ! root 5: PURPOSE: Generic template for Windows applications
1.1 root 6:
1.1.1.3 ! root 7: FUNCTIONS:
1.1 root 8:
9: WinMain() - calls initialization function, processes message loop
10: InitApplication() - initializes window data and registers window
11: InitInstance() - saves instance handle and creates main window
1.1.1.3 ! root 12: WndProc() - processes messages
! 13: CenterWindow() - used to center the "About" box over application window
1.1 root 14: About() - processes messages for "About" dialog box
15:
1.1.1.3 ! root 16: COMMENTS:
1.1 root 17:
1.1.1.3 ! root 18: The Windows SDK Generic Application Example is a sample application
! 19: that you can use to get an idea of how to perform some of the simple
! 20: functionality that all Applications written for Microsoft Windows
! 21: should implement. You can use this application as either a starting
! 22: point from which to build your own applications, or for quickly
! 23: testing out functionality of an interesting Windows API.
! 24:
! 25: This application is source compatible for with Windows 3.1 and
! 26: Windows NT.
1.1 root 27:
28: ****************************************************************************/
29:
1.1.1.3 ! root 30: #include <windows.h> // required for all Windows applications
! 31: #if !defined(WIN32)
! 32: #include <ver.h>
! 33: #endif
! 34: #include "generic.h" // specific to this program
! 35:
! 36: #if !defined (APIENTRY) // Windows NT defines APIENTRY, but 3.x doesn't
! 37: #define APIENTRY far pascal
! 38: #endif
! 39:
! 40: #if !defined(WIN32) // Windows 3.x uses a FARPROC for dialogs
! 41: #define DLGPROC FARPROC
! 42: #endif
! 43:
! 44: HANDLE hInst; // current instance
1.1 root 45:
1.1.1.3 ! root 46: char szAppName[] = "Generic"; // The name of this application
! 47: char szTitle[] = "Generic Sample Application"; // The title bar text
1.1 root 48:
49: /****************************************************************************
50:
1.1.1.3 ! root 51: FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
1.1 root 52:
1.1.1.3 ! root 53: PURPOSE: calls initialization function, processes message loop
1.1 root 54:
1.1.1.3 ! root 55: COMMENTS:
1.1 root 56:
1.1.1.3 ! root 57: Windows recognizes this function by name as the initial entry point
! 58: for the program. This function calls the application initialization
! 59: routine, if no other instance of the program is running, and always
! 60: calls the instance initialization routine. It then executes a message
! 61: retrieval and dispatch loop that is the top-level control structure
! 62: for the remainder of execution. The loop is terminated when a WM_QUIT
! 63: message is received, at which time this function exits the application
! 64: instance by returning the value passed by PostQuitMessage().
1.1 root 65:
1.1.1.3 ! root 66: If this function must abort before entering the message loop, it
! 67: returns the conventional value NULL.
1.1 root 68:
69: ****************************************************************************/
1.1.1.3 ! root 70: int APIENTRY WinMain(
! 71: HANDLE hInstance,
! 72: HANDLE hPrevInstance,
! 73: LPSTR lpCmdLine,
! 74: int nCmdShow)
1.1 root 75: {
76:
1.1.1.3 ! root 77: MSG msg;
! 78: HANDLE hAccelTable;
1.1 root 79:
1.1.1.3 ! root 80: if (!hPrevInstance) { // Other instances of app running?
! 81: if (!InitApplication(hInstance)) { // Initialize shared things
! 82: return (FALSE); // Exits if unable to initialize
! 83: }
! 84: }
1.1 root 85:
1.1.1.3 ! root 86: /* Perform initializations that apply to a specific instance */
1.1 root 87:
1.1.1.3 ! root 88: if (!InitInstance(hInstance, nCmdShow)) {
! 89: return (FALSE);
! 90: }
1.1 root 91:
1.1.1.3 ! root 92: hAccelTable = LoadAccelerators (hInstance, szAppName);
1.1 root 93:
1.1.1.3 ! root 94: /* Acquire and dispatch messages until a WM_QUIT message is received. */
1.1 root 95:
1.1.1.3 ! root 96: while (GetMessage(&msg, // message structure
! 97: NULL, // handle of window receiving the message
! 98: 0, // lowest message to examine
! 99: 0)) // highest message to examine
1.1 root 100: {
1.1.1.3 ! root 101: if (!TranslateAccelerator (msg.hwnd, hAccelTable, &msg)) {
! 102: TranslateMessage(&msg);// Translates virtual key codes
! 103: DispatchMessage(&msg); // Dispatches message to window
! 104: }
! 105: }
! 106:
! 107:
! 108: return (msg.wParam); // Returns the value from PostQuitMessage
! 109:
! 110: lpCmdLine; // This will prevent 'unused formal parameter' warnings
1.1 root 111: }
112:
113:
114: /****************************************************************************
115:
1.1.1.3 ! root 116: FUNCTION: InitApplication(HANDLE)
1.1 root 117:
1.1.1.3 ! root 118: PURPOSE: Initializes window data and registers window class
1.1 root 119:
1.1.1.3 ! root 120: COMMENTS:
1.1 root 121:
1.1.1.3 ! root 122: This function is called at initialization time only if no other
! 123: instances of the application are running. This function performs
! 124: initialization tasks that can be done once for any number of running
! 125: instances.
1.1 root 126:
1.1.1.3 ! root 127: In this case, we initialize a window class by filling out a data
! 128: structure of type WNDCLASS and calling the Windows RegisterClass()
! 129: function. Since all instances of this application use the same window
! 130: class, we only need to do this when the first instance is initialized.
1.1 root 131:
132:
133: ****************************************************************************/
134:
1.1.1.3 ! root 135: BOOL InitApplication(HANDLE hInstance)
1.1 root 136: {
1.1.1.3 ! root 137: WNDCLASS wc;
1.1 root 138:
1.1.1.3 ! root 139: // Fill in window class structure with parameters that describe the
! 140: // main window.
1.1 root 141:
1.1.1.3 ! root 142: wc.style = CS_HREDRAW | CS_VREDRAW;// Class style(s).
! 143: wc.lpfnWndProc = (WNDPROC)WndProc; // Window Procedure
! 144: wc.cbClsExtra = 0; // No per-class extra data.
! 145: wc.cbWndExtra = 0; // No per-window extra data.
! 146: wc.hInstance = hInstance; // Owner of this class
! 147: wc.hIcon = LoadIcon (hInstance, szAppName); // Icon name from .RC
! 148: wc.hCursor = LoadCursor(NULL, IDC_ARROW);// Cursor
! 149: wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);// Default color
! 150: wc.lpszMenuName = szAppName; // Menu name from .RC
! 151: wc.lpszClassName = szAppName; // Name to register as
1.1 root 152:
1.1.1.3 ! root 153: // Register the window class and return success/failure code.
! 154: return (RegisterClass(&wc));
1.1 root 155: }
156:
157:
158: /****************************************************************************
159:
1.1.1.3 ! root 160: FUNCTION: InitInstance(HANDLE, int)
! 161:
! 162: PURPOSE: Saves instance handle and creates main window
1.1 root 163:
1.1.1.3 ! root 164: COMMENTS:
1.1 root 165:
1.1.1.3 ! root 166: This function is called at initialization time for every instance of
! 167: this application. This function performs initialization tasks that
! 168: cannot be shared by multiple instances.
1.1 root 169:
1.1.1.3 ! root 170: In this case, we save the instance handle in a static variable and
! 171: create and display the main program window.
1.1 root 172:
173: ****************************************************************************/
174:
175: BOOL InitInstance(
1.1.1.3 ! root 176: HANDLE hInstance,
! 177: int nCmdShow)
1.1 root 178: {
1.1.1.3 ! root 179: HWND hWnd; // Main window handle.
! 180:
! 181: // Save the instance handle in static variable, which will be used in
! 182: // many subsequence calls from this application to Windows.
1.1 root 183:
1.1.1.3 ! root 184: hInst = hInstance; // Store instance handle in our global variable
1.1 root 185:
1.1.1.3 ! root 186: // Create a main window for this application instance.
1.1 root 187:
1.1.1.3 ! root 188: hWnd = CreateWindow(
! 189: szAppName, // See RegisterClass() call.
! 190: szTitle, // Text for window title bar.
! 191: WS_OVERLAPPEDWINDOW,// Window style.
! 192: CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, // Use default positioning
! 193: NULL, // Overlapped windows have no parent.
! 194: NULL, // Use the window class menu.
! 195: hInstance, // This instance owns this window.
! 196: NULL // We don't use any data in our WM_CREATE
! 197: );
! 198:
! 199: // If window could not be created, return "failure"
! 200: if (!hWnd) {
! 201: return (FALSE);
! 202: }
! 203:
! 204: // Make the window visible; update its client area; and return "success"
! 205: ShowWindow(hWnd, nCmdShow); // Show the window
! 206: UpdateWindow(hWnd); // Sends WM_PAINT message
1.1 root 207:
1.1.1.3 ! root 208: return (TRUE); // We succeeded...
1.1 root 209:
210: }
211:
212: /****************************************************************************
213:
1.1.1.3 ! root 214: FUNCTION: WndProc(HWND, UINT, UINT, LONG)
1.1 root 215:
1.1.1.3 ! root 216: PURPOSE: Processes messages
1.1 root 217:
1.1.1.3 ! root 218: MESSAGES:
1.1 root 219:
220: WM_COMMAND - application menu (About dialog box)
221: WM_DESTROY - destroy window
222:
1.1.1.3 ! root 223: COMMENTS:
1.1 root 224:
225: To process the IDM_ABOUT message, call MakeProcInstance() to get the
226: current instance address of the About() function. Then call Dialog
227: box which will create the box according to the information in your
1.1.1.3 ! root 228: generic.rc file and turn control over to the About() function. When
1.1 root 229: it returns, free the intance address.
230:
231: ****************************************************************************/
232:
1.1.1.3 ! root 233: LONG APIENTRY WndProc(
! 234: HWND hWnd, // window handle
! 235: UINT message, // type of message
! 236: UINT uParam, // additional information
! 237: LONG lParam) // additional information
1.1 root 238: {
1.1.1.3 ! root 239: FARPROC lpProcAbout; // pointer to the "About" function
! 240: int wmId, wmEvent;
1.1 root 241:
1.1.1.3 ! root 242: switch (message) {
! 243:
! 244: case WM_COMMAND: // message: command from application menu
! 245:
! 246: // Message packing of uParam and lParam have changed for Win32, let us
! 247: // handle the differences in a conditional compilation:
! 248: #if defined (WIN32)
! 249: wmId = LOWORD(uParam);
! 250: wmEvent = HIWORD(uParam);
! 251: #else
! 252: wmId = uParam;
! 253: wmEvent = HIWORD(lParam);
! 254: #endif
! 255:
! 256: switch (wmId) {
! 257: case IDM_ABOUT:
! 258: lpProcAbout = MakeProcInstance((FARPROC)About, hInst);
! 259:
! 260: DialogBox(hInst, // current instance
! 261: "AboutBox", // dlg resource to use
! 262: hWnd, // parent handle
! 263: (DLGPROC)lpProcAbout); // About() instance address
! 264:
! 265: FreeProcInstance(lpProcAbout);
! 266: break;
! 267:
! 268: case IDM_EXIT:
! 269: DestroyWindow (hWnd);
! 270: break;
! 271:
! 272: case IDM_HELPCONTENTS:
! 273: if (!WinHelp (hWnd, "GENERIC.HLP", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) {
! 274: MessageBox (GetFocus(),
! 275: "Unable to activate help",
! 276: szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);
! 277: }
! 278: break;
! 279:
! 280: case IDM_HELPSEARCH:
! 281: if (!WinHelp(hWnd, "GENERIC.HLP", HELP_PARTIALKEY, (DWORD)(LPSTR)"")) {
! 282: MessageBox (GetFocus(),
! 283: "Unable to activate help",
! 284: szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);
! 285: }
! 286: break;
! 287:
! 288: case IDM_HELPHELP:
! 289: if(!WinHelp(hWnd, (LPSTR)NULL, HELP_HELPONHELP, 0)) {
! 290: MessageBox (GetFocus(),
! 291: "Unable to activate help",
! 292: szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);
! 293: }
! 294: break;
! 295:
! 296: // Here are all the other possible menu options,
! 297: // all of these are currently disabled:
! 298: case IDM_NEW:
! 299: case IDM_OPEN:
! 300: case IDM_SAVE:
! 301: case IDM_SAVEAS:
! 302: case IDM_UNDO:
! 303: case IDM_CUT:
! 304: case IDM_COPY:
! 305: case IDM_PASTE:
! 306: case IDM_LINK:
! 307: case IDM_LINKS:
! 308:
! 309: default:
! 310: return (DefWindowProc(hWnd, message, uParam, lParam));
! 311: }
! 312: break;
! 313:
! 314: case WM_DESTROY: // message: window being destroyed
! 315: PostQuitMessage(0);
! 316: break;
! 317:
! 318: default: // Passes it on if unproccessed
! 319: return (DefWindowProc(hWnd, message, uParam, lParam));
! 320: }
! 321: return (NULL);
! 322: }
! 323:
! 324: /****************************************************************************
! 325:
! 326: FUNCTION: CenterWindow (HWND, HWND)
! 327:
! 328: PURPOSE: Center one window over another
! 329:
! 330: COMMENTS:
! 331:
! 332: Dialog boxes take on the screen position that they were designed at,
! 333: which is not always appropriate. Centering the dialog over a particular
! 334: window usually results in a better position.
! 335:
! 336: ****************************************************************************/
! 337:
! 338: BOOL CenterWindow (HWND hwndChild, HWND hwndParent)
! 339: {
! 340: RECT rChild, rParent;
! 341: int wChild, hChild, wParent, hParent;
! 342: int wScreen, hScreen, xNew, yNew;
! 343: HDC hdc;
! 344:
! 345: // Get the Height and Width of the child window
! 346: GetWindowRect (hwndChild, &rChild);
! 347: wChild = rChild.right - rChild.left;
! 348: hChild = rChild.bottom - rChild.top;
! 349:
! 350: // Get the Height and Width of the parent window
! 351: GetWindowRect (hwndParent, &rParent);
! 352: wParent = rParent.right - rParent.left;
! 353: hParent = rParent.bottom - rParent.top;
! 354:
! 355: // Get the display limits
! 356: hdc = GetDC (hwndChild);
! 357: wScreen = GetDeviceCaps (hdc, HORZRES);
! 358: hScreen = GetDeviceCaps (hdc, VERTRES);
! 359: ReleaseDC (hwndChild, hdc);
! 360:
! 361: // Calculate new X position, then adjust for screen
! 362: xNew = rParent.left + ((wParent - wChild) /2);
! 363: if (xNew < 0) {
! 364: xNew = 0;
! 365: } else if ((xNew+wChild) > wScreen) {
! 366: xNew = wScreen - wChild;
! 367: }
! 368:
! 369: // Calculate new Y position, then adjust for screen
! 370: yNew = rParent.top + ((hParent - hChild) /2);
! 371: if (yNew < 0) {
! 372: yNew = 0;
! 373: } else if ((yNew+hChild) > hScreen) {
! 374: yNew = hScreen - hChild;
! 375: }
! 376:
! 377: // Set it, and return
! 378: return SetWindowPos (hwndChild, NULL,
! 379: xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
1.1 root 380: }
381:
382:
383: /****************************************************************************
384:
1.1.1.3 ! root 385: FUNCTION: About(HWND, unsigned, WORD, LONG)
1.1 root 386:
1.1.1.3 ! root 387: PURPOSE: Processes messages for "About" dialog box
1.1 root 388:
1.1.1.3 ! root 389: MESSAGES:
1.1 root 390:
391: WM_INITDIALOG - initialize dialog box
392: WM_COMMAND - Input received
393:
1.1.1.3 ! root 394: COMMENTS:
1.1 root 395:
1.1.1.3 ! root 396: Display version information from the version section of the
! 397: application resource.
1.1 root 398:
399: Wait for user to click on "Ok" button, then close the dialog box.
400:
401: ****************************************************************************/
402:
403: BOOL APIENTRY About(
1.1.1.3 ! root 404: HWND hDlg, // window handle of the dialog box
! 405: UINT message, // type of message
! 406: UINT uParam, // message-specific information
1.1 root 407: LONG lParam)
408: {
1.1.1.3 ! root 409: static HFONT hfontDlg;
! 410: LPSTR lpVersion;
! 411: DWORD dwVerInfoSize;
! 412: DWORD dwVerHnd;
! 413: UINT uVersionLen;
! 414: WORD wRootLen;
! 415: BOOL bRetCode;
! 416: int i;
! 417: char szFullPath[256];
! 418: char szResult[256];
! 419: char szGetName[256];
! 420:
! 421: switch (message) {
! 422: case WM_INITDIALOG: // message: initialize dialog box
! 423: // Create a font to use
! 424: hfontDlg = CreateFont(14, 0, 0, 0, 0, 0, 0, 0,
! 425: 0, 0, 0, 0,
! 426: VARIABLE_PITCH | FF_SWISS, "");
! 427:
! 428: // Center the dialog over the application window
! 429: CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
! 430:
! 431: // Get version information from the application
! 432: GetModuleFileName (hInst, szFullPath, sizeof(szFullPath));
! 433: dwVerInfoSize = GetFileVersionInfoSize(szFullPath, &dwVerHnd);
! 434: if (dwVerInfoSize) {
! 435: // If we were able to get the information, process it:
! 436: LPSTR lpstrVffInfo;
! 437: HANDLE hMem;
! 438: hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
! 439: lpstrVffInfo = GlobalLock(hMem);
! 440: GetFileVersionInfo(szFullPath, dwVerHnd, dwVerInfoSize, lpstrVffInfo);
! 441: lstrcpy(szGetName, "\\StringFileInfo\\040904E4\\");
! 442: wRootLen = lstrlen(szGetName);
! 443:
! 444: // Walk through the dialog items that we want to replace:
! 445: for (i = DLG_VERFIRST; i <= DLG_VERLAST; i++) {
! 446: GetDlgItemText(hDlg, i, szResult, sizeof(szResult));
! 447: szGetName[wRootLen] = (char)0;
! 448: lstrcat (szGetName, szResult);
! 449: uVersionLen = 0;
! 450: lpVersion = NULL;
! 451: bRetCode = VerQueryValue((LPVOID)lpstrVffInfo,
! 452: (LPSTR)szGetName,
! 453: (LPVOID)&lpVersion,
! 454: #if defined (WIN32)
! 455: (LPDWORD)&uVersionLen); // For MIPS strictness
! 456: #else
! 457: (UINT *)&uVersionLen);
! 458: #endif
! 459:
! 460: if ( bRetCode && uVersionLen && lpVersion) {
! 461: // Replace dialog item text with version info
! 462: lstrcpy(szResult, lpVersion);
! 463: if (uVersionLen != (UINT)lstrlen(lpVersion)) {
! 464: // VerQueryValue appears to want to return UniCode strings
! 465: // at the moment. This is a hack to fix that problem
! 466: // for now
! 467: // MessageBeep(0);
! 468: WideCharToMultiByte((UINT)CP_ACP, (DWORD)0, (LPWSTR)lpVersion, (int)uVersionLen,
! 469: (LPSTR)szResult, (int)sizeof(szResult), (LPSTR)NULL, (LPBOOL)NULL);
! 470: }
! 471: SetDlgItemText(hDlg, i, szResult);
! 472: SendMessage (GetDlgItem (hDlg, i), WM_SETFONT, (UINT)hfontDlg, TRUE);
! 473: }
! 474: } // for (i = DLG_VERFIRST; i <= DLG_VERLAST; i++)
! 475:
! 476: GlobalUnlock(hMem);
! 477: GlobalFree(hMem);
! 478: } // if (dwVerInfoSize)
! 479:
! 480: return (TRUE);
! 481:
! 482: case WM_COMMAND: // message: received a command
! 483: if (LOWORD(uParam) == IDOK // "OK" box selected?
! 484: || LOWORD(uParam) == IDCANCEL) { // System menu close command?
! 485: EndDialog(hDlg, TRUE); // Exit the dialog
! 486: DeleteObject (hfontDlg);
! 487: return (TRUE);
! 488: }
! 489: break;
! 490: }
! 491: return (FALSE); // Didn't process the message
1.1.1.2 root 492:
1.1.1.3 ! root 493: lParam; // This will prevent 'unused formal parameter' warnings
! 494: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.