Annotation of q_a/samples/bob/bob.c, revision 1.1

1.1     ! root        1: /****************************************************************************\
        !             2: **                                                                         **
        !             3: **               Microsoft Developer Support                               **
        !             4: **               Copyright (c) 1992, 1993 Microsoft Corporation            **
        !             5: **                                                                         **
        !             6: **   MODULE:  BOB                                                          **
        !             7: **                                                                         **
        !             8: **                                                                         **
        !             9: **   PURPOSE: Demonstrates the steps needed to programmatically            **
        !            10: **            log off/reboot the machine. Note these features should       **
        !            11: **            only be used after you've notified the user what you         **
        !            12: **            are about to do. Windows itself will not provide any         **
        !            13: **            other warnings to the user.                                  **
        !            14: **                                                                         **
        !            15: **                                                                         **
        !            16: **                                                                         **
        !            17: **                                                                         **
        !            18: **   COMMENTS: Reads a file asynchronously writes to another synchronously **
        !            19: **                                                                         **
        !            20: **                                                                         **
        !            21: \***************************************************************************/
        !            22: 
        !            23: 
        !            24: 
        !            25: /*  To enable NT's Reboot feature enable the below
        !            26:  *  manifest constants. By default the program will
        !            27:  *  log the user off only.
        !            28:  */
        !            29: 
        !            30: // #define REBOOT
        !            31: 
        !            32: #define WIN32S  0x80000000l   // no manifest constance yet???
        !            33: 
        !            34: #define STRICT
        !            35: 
        !            36: #include <stddef.h>
        !            37: #include <stdlib.h>
        !            38: 
        !            39: 
        !            40: #define  OEMRESOURCE
        !            41: #include "windows.h"               /* required for all Windows applications */
        !            42: 
        !            43: #include "BOB.H"                   /* specific to this program              */
        !            44: 
        !            45: HINSTANCE ghInst;                  /* current instance                  */
        !            46: HWND     ghWnd;
        !            47: WNDPROC   OldButtonProc;
        !            48: 
        !            49: /****************************************************************************
        !            50: 
        !            51:     FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
        !            52: 
        !            53:     PURPOSE: calls initialization function, processes message loop
        !            54: 
        !            55:     COMMENTS:
        !            56: 
        !            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().
        !            65: 
        !            66:         If this function must abort before entering the message loop, it
        !            67:         returns the conventional value NULL.
        !            68: 
        !            69: ****************************************************************************/
        !            70: 
        !            71: int PASCAL WinMain(HINSTANCE hInstance,      /* current instance  */
        !            72:                   HINSTANCE hPrevInstance,  /* previous instance */
        !            73:                   LPSTR     lpCmdLine,      /* command line      */
        !            74:                   int       nCmdShow)       /* show-window type (open/icon) */
        !            75: {
        !            76:     MSG msg;                                /* message                      */
        !            77: 
        !            78:     if (!hPrevInstance)                         /* Other instances of app running? */
        !            79:        if (!InitApplication(hInstance)) /* Initialize shared things */
        !            80:            return (FALSE);              /* Exits if unable to initialize     */
        !            81: 
        !            82:     /* Perform initializations that apply to a specific instance */
        !            83: 
        !            84:     if (!InitInstance(hInstance, nCmdShow))
        !            85:         return (FALSE);
        !            86: 
        !            87:     /* Acquire and dispatch messages until a WM_QUIT message is received. */
        !            88: 
        !            89:     while (GetMessage(&msg,       /* message structure                      */
        !            90:            NULL,                  /* handle of window receiving the message */
        !            91:            0,                     /* lowest message to examine              */
        !            92:            0))                    /* highest message to examine             */
        !            93:     {
        !            94:         TranslateMessage(&msg);    /* Translates virtual key codes              */
        !            95:         DispatchMessage(&msg);     /* Dispatches message to window              */
        !            96: 
        !            97:     }
        !            98:     return (msg.wParam);          /* Returns the value from PostQuitMessage */
        !            99: UNREFERENCED_PARAMETER(lpCmdLine);
        !           100: }
        !           101: 
        !           102: 
        !           103: /****************************************************************************
        !           104: 
        !           105:     FUNCTION: InitApplication(HANDLE)
        !           106: 
        !           107:     PURPOSE: Initializes window data and registers window class
        !           108: 
        !           109:     COMMENTS:
        !           110: 
        !           111:         This function is called at initialization time only if no other
        !           112:         instances of the application are running.  This function performs
        !           113:         initialization tasks that can be done once for any number of running
        !           114:         instances.
        !           115: 
        !           116:         In this case, we initialize a window class by filling out a data
        !           117:         structure of type WNDCLASS and calling the Windows RegisterClass()
        !           118:         function.  Since all instances of this application use the same window
        !           119:         class, we only need to do this when the first instance is initialized.
        !           120: 
        !           121: 
        !           122: ****************************************************************************/
        !           123: 
        !           124: BOOL InitApplication(HANDLE hInstance)   /* current instance     */
        !           125: {
        !           126:     WNDCLASS  wc;
        !           127: 
        !           128:     /* Fill in window class structure with parameters that describe the       */
        !           129:     /* main window.                                                           */
        !           130: 
        !           131:     wc.style = 0;                       /* Class style(s).                    */
        !           132:     wc.lpfnWndProc = (WNDPROC)MainWndProc;      /* Function to retrieve messages for  */
        !           133:                                         /* windows of this class.             */
        !           134:     wc.cbClsExtra = 0;                  /* No per-class extra data.           */
        !           135:     wc.cbWndExtra = 0;                  /* No per-window extra data.          */
        !           136:     wc.hInstance = hInstance;           /* Application that owns the class.   */
        !           137:     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        !           138:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !           139:     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
        !           140:     wc.lpszMenuName =  "BOBMenu";       /* Name of menu resource in .RC file. */
        !           141:     wc.lpszClassName = "BOBWClass";     /* Name used in call to CreateWindow. */
        !           142: 
        !           143:     /* Register the window class and return success/failure code. */
        !           144: 
        !           145: 
        !           146:     if ( !RegisterClass(&wc) )
        !           147:         return( FALSE );
        !           148: 
        !           149: 
        !           150: }
        !           151: 
        !           152: 
        !           153: /****************************************************************************
        !           154: 
        !           155:     FUNCTION:  InitInstance(HANDLE, int)
        !           156: 
        !           157:     PURPOSE:  Saves instance handle and creates main window
        !           158: 
        !           159:     COMMENTS:
        !           160: 
        !           161:         This function is called at initialization time for every instance of
        !           162:         this application.  This function performs initialization tasks that
        !           163:         cannot be shared by multiple instances.
        !           164: 
        !           165:         In this case, we save the instance handle in a static variable and
        !           166:         create and display the main program window.
        !           167: 
        !           168: ****************************************************************************/
        !           169: 
        !           170: BOOL InitInstance(HANDLE hInstance,    /* Current instance identifier.     */
        !           171:                  int nCmdShow )        /* Param for first ShowWindow() call. */
        !           172: {
        !           173:     HWND      hWnd;               /* Main window handle.                */
        !           174:     HWND      hWndDeskTop;
        !           175:     RECT      rcDeskTop;
        !           176: 
        !           177: 
        !           178:     /* Save the instance handle in static variable, which will be used in  */
        !           179:     /* many subsequence calls from this application to Windows.            */
        !           180: 
        !           181:     ghInst = hInstance;
        !           182: 
        !           183:     /* Create a main window for this application instance.  */
        !           184: 
        !           185: 
        !           186: 
        !           187:     hWndDeskTop = GetDesktopWindow();
        !           188:     GetWindowRect( hWndDeskTop, &rcDeskTop );
        !           189: 
        !           190:     hWnd = CreateWindow(
        !           191:         "BOBWClass",                    /* See RegisterClass() call.          */
        !           192:         "BOB",                          /* Text for window title bar.         */
        !           193:        WS_OVERLAPPED,                  /* Window style.                        */
        !           194:        rcDeskTop.left+50,              /*  horizontal position.            */
        !           195:        rcDeskTop.bottom-200,           /*  vertical position.       */
        !           196:        150,                            /*  width.                   */
        !           197:        100,                            /*  height.                  */
        !           198:         NULL,                           /* Overlapped windows have no parent. */
        !           199:         NULL,                           /* Use the window class menu.         */
        !           200:         hInstance,                      /* This instance owns this window.    */
        !           201:         NULL                            /* Pointer to Createion Parameters    */
        !           202:     );
        !           203: 
        !           204:     /* If window could not be created, return "failure" */
        !           205: 
        !           206:     if (!hWnd)
        !           207:         return (FALSE);
        !           208: 
        !           209:     ShowWindow(hWnd, nCmdShow);  /* Show the window                        */
        !           210:     UpdateWindow(hWnd);         /* Sends WM_PAINT message                 */
        !           211:     ghWnd = hWnd;
        !           212: 
        !           213: }
        !           214: 
        !           215: /****************************************************************************
        !           216: 
        !           217:     FUNCTION: MainWndProc(HWND, WORD, WPARAM, LPARAM)
        !           218: 
        !           219:     PURPOSE:  Processes messages
        !           220: 
        !           221:     MESSAGES:
        !           222: 
        !           223:        WM_COMMAND    - application menu (About dialog box)
        !           224:        WM_DESTROY    - destroy window
        !           225: 
        !           226:     COMMENTS:
        !           227: 
        !           228:        To process the IDM_ABOUT message, call MakeProcInstance() to get the
        !           229:        current instance address of the About() function.  Then call Dialog
        !           230:        box which will create the box according to the information in your
        !           231:        BOB.RC file and turn control over to the About() function.      When
        !           232:        it returns, free the intance address.
        !           233: 
        !           234: ****************************************************************************/
        !           235: 
        !           236: long WINAPI MainWndProc(HWND hWnd,         /* window handle             */
        !           237:                            UINT message,   /* type of message           */
        !           238:                            WPARAM wParam,  /* additional information    */
        !           239:                            LPARAM lParam ) /* additional information    */
        !           240: {
        !           241:     DLGPROC lpProcAbout;
        !           242:     CHAR buffer[80];
        !           243: 
        !           244:     HANDLE hToken;
        !           245:     TOKEN_PRIVILEGES tkp;
        !           246: 
        !           247:     static CONTROLTEXT CtlText;
        !           248:     static TCHAR szTitle[10];
        !           249:     static RECT  FocusRect, SelectRect;
        !           250: 
        !           251:     switch (message) {
        !           252: 
        !           253:         case WM_CREATE: {
        !           254: 
        !           255:            HWND hWndButton;
        !           256:            CREATESTRUCT createStruct;
        !           257:            RECT rcClient;
        !           258: 
        !           259:             int   cbTitle;
        !           260:             SIZE  size;
        !           261:             HDC    hDC;
        !           262:             int    nSpaceWidth, nSpaceHeight;
        !           263: 
        !           264:             createStruct = *(LPCREATESTRUCT)lParam;
        !           265:            GetClientRect( hWnd,&rcClient );
        !           266: 
        !           267:             hWndButton = CreateWindow(
        !           268:                 "BUTTON",                    /* See RegisterClass() call.       */
        !           269:                TEXT("B. O. B."),          /* Text for window title bar.      */
        !           270:                WS_VISIBLE | WS_CHILD |
        !           271:                BS_PUSHBUTTON |
        !           272:                 BS_OWNERDRAW,
        !           273:                rcClient.left,
        !           274:                rcClient.top,
        !           275:                rcClient.right,
        !           276:                rcClient.bottom,
        !           277:                hWnd,                      /* Parent                          */
        !           278:                 (HMENU)BOB,                /* Child ID                        */
        !           279:                createStruct.hInstance,    /* This instance owns this window. */
        !           280:                 NULL                       /* Pointer to Createion Parameters */
        !           281:             );
        !           282: 
        !           283:            wsprintf( buffer, "hWndButton is %#x and hWnd is %#x\r\n",
        !           284:                  hWndButton, hWnd );
        !           285:            OutputDebugString ( buffer );
        !           286: 
        !           287:             if ( !hWndButton ) {
        !           288:                 MessageBox( hWnd, "Error creating Window", NULL, MB_OK );
        !           289:                 SendMessage( hWnd, WM_DESTROY, 0, 0 );
        !           290:             }
        !           291: 
        !           292:        SetFocus( hWndButton );
        !           293: 
        !           294:        OldButtonProc = SubclassWindow( hWndButton, ButtonProc );
        !           295: 
        !           296:         // define size of dashed rectangles around text in both bitmaps
        !           297:         hDC           = GetDC( hWndButton );
        !           298:         cbTitle = SendMessage( hWndButton,
        !           299:                                WM_GETTEXT,
        !           300:                                (WPARAM) sizeof(szTitle),
        !           301:                               (LPARAM)(LPTSTR)szTitle );
        !           302:         GetTextExtentPoint( hDC,
        !           303:                             szTitle,
        !           304:                             cbTitle,
        !           305:                             &size );
        !           306:         ReleaseDC( hWndButton, hDC);
        !           307: 
        !           308:        CtlText.ptPosition.x = (rcClient.right - size.cx) >> 1;
        !           309:        CtlText.ptPosition.y = (rcClient.bottom - size.cy) >> 1;
        !           310:         CtlText.szTitle = szTitle;
        !           311:         CtlText.cbTitle = cbTitle;
        !           312: 
        !           313:         // load bitmap
        !           314: 
        !           315:        CtlText.hDefaultButton = LoadBitmap(
        !           316:                         createStruct.hInstance,    /* This instance owns this window. */
        !           317:                        MAKEINTRESOURCE( DEFAULTBUTTON )
        !           318:                        );
        !           319: 
        !           320:        if ( !CtlText.hDefaultButton ) {
        !           321:            wsprintf( buffer, "Error loading BUTTONBITMAP %d",
        !           322:                  GetLastError() );
        !           323:             MessageBox( hWnd, "Error creating Window", NULL, MB_OK );
        !           324:             SendMessage( hWnd, WM_DESTROY, 0, 0 );
        !           325:         }
        !           326: 
        !           327:        CtlText.hSelectButton = LoadBitmap(
        !           328:                         createStruct.hInstance,    /* This instance owns this window. */
        !           329:                        MAKEINTRESOURCE(SELECTEDBUTTON)    // pushed state
        !           330:                        );
        !           331: 
        !           332:        if ( !CtlText.hSelectButton ) {
        !           333:            wsprintf( buffer, "Error loading BUTTONBITMAP %d",
        !           334:                  GetLastError() );
        !           335:             MessageBox( hWnd, "Error creating Window", NULL, MB_OK );
        !           336:             SendMessage( hWnd, WM_DESTROY, 0, 0 );
        !           337:         }
        !           338: 
        !           339: 
        !           340: 
        !           341: 
        !           342:         nSpaceWidth   = GetSystemMetrics(SM_CXBORDER) << 1;
        !           343:         nSpaceHeight  = GetSystemMetrics(SM_CYBORDER) << 1;
        !           344: 
        !           345:         FocusRect.top    = CtlText.ptPosition.y - nSpaceHeight;
        !           346:        FocusRect.bottom = FocusRect.top + size.cy + (nSpaceHeight << 1);
        !           347:         FocusRect.left   = CtlText.ptPosition.x - nSpaceWidth;
        !           348:        FocusRect.right  = FocusRect.left + size.cx + (nSpaceWidth << 1);
        !           349: 
        !           350:         SelectRect.top    = 2 + FocusRect.top;
        !           351:         SelectRect.bottom = 2 + FocusRect.bottom;
        !           352:         SelectRect.left   = 2 + FocusRect.left;
        !           353:         SelectRect.right  = 2 + FocusRect.right;
        !           354: 
        !           355:         return ( TRUE );
        !           356:         }
        !           357:        case WM_DRAWITEM:
        !           358:        {
        !           359:            LPDRAWITEMSTRUCT  lpdisCtrl;
        !           360: 
        !           361:            if ( (int)wParam == BOB ) {
        !           362:                lpdisCtrl = (LPDRAWITEMSTRUCT)lParam;
        !           363:                switch (lpdisCtrl->itemAction)
        !           364:                 {
        !           365:                     // handle normal drawing of button, but check if its
        !           366:                     // selected or focus
        !           367: 
        !           368:                    case ODA_DRAWENTIRE:
        !           369:                        OutputDebugString("WM_DRAWITEM: Action is ODA_DRAWENTIRE\r\n");
        !           370:                         // this handles both button down and button up
        !           371:                         HandleSelectedState(lpdisCtrl, &CtlText);
        !           372: 
        !           373:                         // this handles focus rectangle around Button text
        !           374:                         HandleFocusState(lpdisCtrl, &FocusRect, &SelectRect);
        !           375:                         return TRUE;
        !           376: 
        !           377:                    // handle drawing selection if needed
        !           378:                     //   selected is button down, not selected is button up
        !           379:                     //   focus will occur when button is pressed.
        !           380: 
        !           381:                     case ODA_SELECT:
        !           382:                        OutputDebugString("WM_DRAWITEM: Action is ODA_SELECT\r\n");
        !           383:                         HandleSelectedState(lpdisCtrl, &CtlText);
        !           384:                         HandleFocusState(lpdisCtrl, &FocusRect, &SelectRect);
        !           385:                         return TRUE;
        !           386: 
        !           387:                     // handle focus drawing if needed
        !           388:                     case ODA_FOCUS:
        !           389:                        OutputDebugString("WM_DRAWITEM: Action is ODA_FOCUS\r\n");
        !           390:                         HandleFocusState(lpdisCtrl, &FocusRect, &SelectRect);
        !           391:                         return TRUE;
        !           392:                 }
        !           393:             }
        !           394:             break;
        !           395:         }
        !           396:        case WM_COMMAND:           /* message: command from application menu */
        !           397: 
        !           398:             if ( HIWORD(wParam) == BN_CLICKED &&
        !           399:                 LOWORD(wParam) == BOB ) {
        !           400: /*
        !           401:  * Below are the steps needed to reboot the machine.
        !           402:  */
        !           403:                 lpProcAbout = (DLGPROC)MakeProcInstance((FARPROC)About, ghInst );
        !           404: #if defined(REBOOT)
        !           405:                 DialogBox (ghInst, TEXT("AboutBox"), hWnd, lpProcAbout);
        !           406: #else
        !           407:                 DialogBox (ghInst, TEXT("AboutBox"), hWnd, lpProcAbout);
        !           408: #endif
        !           409: 
        !           410:                 /* Get a token for this process. */
        !           411: 
        !           412:                 if ( !(GetVersion() & WIN32S) )
        !           413:                     {
        !           414: 
        !           415:                         OutputDebugString("Setting token");
        !           416:                     // Running on NT so need to change privileges
        !           417: 
        !           418:                         if (!OpenProcessToken(GetCurrentProcess(),
        !           419:                                 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
        !           420:                             wsprintf ( buffer, "OpenProcessToken Error #%d", GetLastError ());
        !           421:                             MessageBox(hWnd, buffer, NULL, MB_OK);
        !           422:                         }
        !           423:                         /* Get the LUID for shutdown privilege */
        !           424: 
        !           425:                         LookupPrivilegeValue(NULL, TEXT("SeShutdownPrivilege"),
        !           426:                                 &tkp.Privileges[0].Luid);
        !           427: 
        !           428:                         tkp.PrivilegeCount = 1;  /* one privilege to set    */
        !           429:                         tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        !           430: 
        !           431:                         /* Get shutdown privilege for this process. */
        !           432: 
        !           433:                         if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
        !           434:                                 (PTOKEN_PRIVILEGES)NULL, 0)) {
        !           435:                             wsprintf ( buffer, "AdjustTokenPrivileges Error #%d", GetLastError ());
        !           436:                             MessageBox(hWnd, buffer, NULL, MB_OK);
        !           437:                         }
        !           438:                 }
        !           439: 
        !           440: #if defined(REBOOT)
        !           441:                 /* Shut down the system, and reboot the system. */
        !           442: 
        !           443:                 if ( !ExitWindowsEx( EWX_REBOOT, 0 )) {
        !           444:                     wsprintf ( buffer, "Error ExitWindows Error #%d", GetLastError ());
        !           445:                     MessageBox(hWnd, buffer, NULL, MB_OK);
        !           446:                 }
        !           447: #else
        !           448:                 /* Shut down the system, and force all applications closed. */
        !           449: 
        !           450:                 if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0)) {
        !           451:                     wsprintf ( buffer, "Error ExitWindows Error #%d", GetLastError ());
        !           452:                     MessageBox(hWnd, buffer, NULL, MB_OK);
        !           453:                 }
        !           454: #endif
        !           455:                 break;
        !           456:            }
        !           457:            else                            /* Lets Windows process it       */
        !           458:                return (DefWindowProc(hWnd, message, wParam, lParam));
        !           459: 
        !           460:        case WM_DESTROY:                  /* message: window being destroyed */
        !           461:            DeleteObject(CtlText.hDefaultButton);
        !           462:            DeleteObject(CtlText.hSelectButton);
        !           463:            PostQuitMessage(0);
        !           464:            break;
        !           465: 
        !           466:        default:                          /* Passes it on if unproccessed    */
        !           467:            return (DefWindowProc(hWnd, message, wParam, lParam));
        !           468:     }
        !           469:     return ( 0 );
        !           470: }
        !           471: 
        !           472: 
        !           473: /****************************************************************************
        !           474: 
        !           475:     FUNCTION: About(HWND, unsigned, WORD, LONG)
        !           476: 
        !           477:     PURPOSE:  Processes messages for "About" dialog box
        !           478: 
        !           479:     MESSAGES:
        !           480: 
        !           481:        WM_INITDIALOG - initialize dialog box
        !           482:        WM_COMMAND    - Input received
        !           483: 
        !           484:     COMMENTS:
        !           485: 
        !           486:        No initialization is needed for this particular dialog box, but TRUE
        !           487:        must be returned to Windows.
        !           488: 
        !           489:        Wait for user to click on "Ok" button, then close the dialog box.
        !           490: 
        !           491: ****************************************************************************/
        !           492: 
        !           493: BOOL WINAPI About(HWND hDlg,       /* window handle of the dialog box */
        !           494:                      UINT message,    /* type of message                 */
        !           495:                      WPARAM wParam,   /* message-specific information    */
        !           496:                      LPARAM lParam )
        !           497: {
        !           498:     switch (message) {
        !           499:        case WM_INITDIALOG:                /* message: initialize dialog box */
        !           500:            return (TRUE);
        !           501: 
        !           502:        case WM_COMMAND:                      /* message: received a command */
        !           503:            if (wParam == IDOK                /* "OK" box selected?          */
        !           504:                 || wParam == IDCANCEL) {      /* System menu close command? */
        !           505:                EndDialog(hDlg, TRUE);        /* Exits the dialog box        */
        !           506:                return (TRUE);
        !           507:            }
        !           508:            break;
        !           509:     }
        !           510:     return (FALSE);                          /* Didn't process a message    */
        !           511: UNREFERENCED_PARAMETER(lParam);
        !           512: }
        !           513: 
        !           514: 
        !           515: 
        !           516: /*****************************************************************************
        !           517: 
        !           518:     FUNCTION: HandleSelectedState
        !           519: 
        !           520:     PURPOSE:  Draw button bitmaps and text:
        !           521:                   if button selected, draw "down"/pressed button bitmap
        !           522:                       with text shifted right and down 2 pixels
        !           523:                   else draw "up"/unpressed button bitmap
        !           524:                       with text centered in button
        !           525: 
        !           526: *****************************************************************************/
        !           527: void HandleSelectedState(LPDRAWITEMSTRUCT lpdisCtrl, LPCONTROLTEXT lpCtlText)
        !           528: {
        !           529: 
        !           530:     int nOldBkMode;
        !           531: 
        !           532:     // handle button pressed down select state -- button down bitmap
        !           533:     //   text is right & down 2 pixels
        !           534:     if (lpdisCtrl->itemState & ODS_SELECTED)
        !           535:     {
        !           536:         DrawBitmap(lpdisCtrl->hDC,
        !           537:                   lpdisCtrl->rcItem,
        !           538:                   lpCtlText->hSelectButton,
        !           539:                    SRCCOPY);
        !           540: 
        !           541:         // put text 2 pixels right and down of center of bitmap
        !           542:         nOldBkMode = SetBkMode(lpdisCtrl->hDC,TRANSPARENT);
        !           543: 
        !           544:         TextOut( lpdisCtrl->hDC,
        !           545:                  lpCtlText->ptPosition.x+2,
        !           546:                  lpCtlText->ptPosition.y+2,
        !           547:                  lpCtlText->szTitle,
        !           548:                  lpCtlText->cbTitle );
        !           549: 
        !           550:         SetBkMode(lpdisCtrl->hDC,nOldBkMode);
        !           551:     }
        !           552:     // not selected -- button up; text is in normal position
        !           553:     else
        !           554:     {
        !           555:         DrawBitmap(lpdisCtrl->hDC,
        !           556:                   lpdisCtrl->rcItem,
        !           557:                   lpCtlText->hDefaultButton,
        !           558:                    SRCCOPY);
        !           559: 
        !           560:         // center text in bitmap
        !           561:         nOldBkMode = SetBkMode(lpdisCtrl->hDC,TRANSPARENT);
        !           562:         TextOut( lpdisCtrl->hDC,
        !           563:                  lpCtlText->ptPosition.x,
        !           564:                  lpCtlText->ptPosition.y,
        !           565:                  lpCtlText->szTitle,
        !           566:                  lpCtlText->cbTitle );
        !           567: 
        !           568:         SetBkMode(lpdisCtrl->hDC,nOldBkMode);
        !           569:     }
        !           570: }
        !           571: 
        !           572: /*****************************************************************************
        !           573: 
        !           574:     FUNCTION: HandleFocusState
        !           575: 
        !           576:     PURPOSE:  If button has focus, draw dashed rectangle around text in button
        !           577: 
        !           578: *****************************************************************************/
        !           579: void HandleFocusState(LPDRAWITEMSTRUCT lpdisCtrl, LPRECT lpFocusRect, LPRECT lpSelectRect )
        !           580: {
        !           581:     // if focus state, draw a dashed rect around text
        !           582:     if (lpdisCtrl->itemState & ODS_FOCUS)
        !           583:     {
        !           584:         // if selected, shift focus rect right and down 2 pixels around text
        !           585:        if (lpdisCtrl->itemState & ODS_SELECTED) {
        !           586:        OutputDebugString("HandleFocusState: State is ODS_SELECTED\r\n");
        !           587:            DrawFocusRect(lpdisCtrl->hDC, lpSelectRect);
        !           588:        }
        !           589:         // else text centered, so focus rect will be too
        !           590:        else {
        !           591:            DrawFocusRect(lpdisCtrl->hDC, lpFocusRect);
        !           592:        OutputDebugString("HandleFocusState: State is ODS_FOCUS\r\n");
        !           593:        }
        !           594: 
        !           595:     }
        !           596:     else
        !           597:       if (lpdisCtrl->itemState & ODS_SELECTED)
        !           598:        OutputDebugString("Error HandleFocusState: State is ODS_SELECTED\r\n");
        !           599:     else {
        !           600:       char buffer[80];
        !           601:       wsprintf(buffer, "HandleFocusState:  lpdisCtrl->itemState is %#x\r\n",
        !           602:            lpdisCtrl->itemState );
        !           603:       OutputDebugString(buffer);
        !           604:    }
        !           605: }
        !           606: /****************************************************************************
        !           607: 
        !           608:     FUNCTION: DrawBitmap
        !           609: 
        !           610:     PURPOSE:  Draw default or pushed button bitmap
        !           611: 
        !           612: ****************************************************************************/
        !           613: 
        !           614: void DrawBitmap(HDC hDC, RECT rect, HBITMAP hBitmap, DWORD rop)
        !           615: {
        !           616:     HDC           hMemDC;
        !           617:     BITMAP        bm;
        !           618:     hMemDC = CreateCompatibleDC(hDC);
        !           619:     SelectObject(hMemDC, hBitmap);
        !           620: //    BitBlt(hDC, rect.left, rect.top, rect.right, rect.bottom, hMemDC, 0, 0, rop);
        !           621:     GetObject(hBitmap, sizeof (BITMAP), (LPVOID) &bm);
        !           622:     StretchBlt( hDC, rect.left, rect.top, rect.right, rect.bottom,
        !           623:                 hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, rop);
        !           624:     DeleteDC(hMemDC);
        !           625: }
        !           626: 
        !           627: long WINAPI ButtonProc(HWND hWnd,         /* window handle             */
        !           628:                            UINT message,   /* type of message           */
        !           629:                            WPARAM wParam,  /* additional information    */
        !           630:                            LPARAM lParam ) /* additional information    */
        !           631: {
        !           632: 
        !           633:    switch ( message )
        !           634:    {
        !           635:    case WM_CHAR:
        !           636:       OutputDebugString("ButtonProc: WM_CHAR received\r\n");
        !           637:       SendMessage( ghWnd, WM_COMMAND, MAKEWPARAM(BOB,BN_CLICKED), (LPARAM)(hWnd));
        !           638: 
        !           639:    default:
        !           640:       return CallWindowProc( OldButtonProc, hWnd, message, wParam, lParam );
        !           641: 
        !           642:    }
        !           643: 
        !           644:    return ( 0 );
        !           645: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.