Annotation of q_a/samples/bob/bob.c, revision 1.1.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.