home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_03_02 / 3n02054a < prev    next >
Text File  |  1992-03-09  |  12KB  |  424 lines

  1. /*
  2.  * GRAFBUTN.C
  3.  *
  4.  * A sample application demonstrating the use of
  5.  * a custom text button and a free-standing
  6.  * graphic pushbutton in an application's main
  7.  * window. 
  8.  *
  9.  * Written by Alex Leavens, for ShadowCat Technologies
  10.  */
  11.  
  12. #include <WINDOWS.H>
  13. #include "GRAFBUTN.H"
  14.  
  15. /* ID of user-created buttons  */
  16. #define    GRAPH_BUTTON_ID    4001
  17. #define    TEXT_BUTTON_ID    4002
  18.  
  19. /* defines for user-drawn buttons... */
  20. #define        NOFOCUS_NOFLAGS        0
  21. #define        FOCUS_NOFLAGS        1
  22. #define        FOCUS_FOCUS        2
  23. #define        DRAWALL            4
  24. #define        SELECT_NOFLAGS        8
  25. #define        SELECT_SELECT        0x10
  26. #define        SELECT_FOCUS        0x20
  27. #define        SELECT_FOCUS_SELECT    0x30
  28. #define        ALL_NOFLAGS        0x40
  29. #define        ALL_FOCUS        0x80
  30. #define        ALL_SELECT        0x100
  31. #define        ALL_FOCUS_SELECT    0x180
  32.  
  33. /*------- Function prototypes --------*/
  34.  
  35. HWND CreateGraphButtonWindow(HWND);
  36. HWND CreateTextButtonWindow(HWND);
  37. BOOL DrawBitmap (HDC, int, int, HBITMAP, DWORD);
  38. void DrawGraphicButton(HWND, unsigned, WORD, LONG);
  39. WORD NEAR PASCAL  GetDesiredButtonState(HWND, WORD, WORD);
  40.  
  41. /*----------- Global variables ---------*/
  42.  
  43. HANDLE  hInst   = 0;  /* Handle to instance.             */
  44. HWND    MainhWnd= 0;  /* Handle to main window.          */
  45. HWND    hClient = 0;  /* Handle to window in client area.*/
  46. FARPROC lpClient= 0L; /* Function for same.              */
  47.  
  48. HANDLE    hGraphButton;
  49. HANDLE    hTextButton;
  50.  
  51. /* WinMain() -    Main windows routine */
  52. int PASCAL WinMain(HANDLE hInstance,
  53.     HANDLE hPrevInstance, LPSTR lpCmdLine,
  54.     int nCmdShow)
  55. {
  56.     MSG msg;
  57.  
  58.     hInst = hInstance; /* Saves the current instance */
  59.     
  60.     if (!hPrevInstance) /* If already running */
  61.         if (!BLDRegisterClass(hInstance))
  62.             return FALSE;
  63.  
  64.     MainhWnd = BLDCreateWindow(hInstance);
  65.     if (!MainhWnd)
  66.         return FALSE;
  67.     ShowWindow(MainhWnd, nCmdShow);
  68.     UpdateWindow(MainhWnd);
  69.     while (GetMessage(&msg, 0, 0, 0))
  70.         {
  71.         TranslateMessage(&msg);
  72.         DispatchMessage(&msg);
  73.         }
  74.     return(msg.wParam);
  75. }
  76.  
  77. /*   WINDOW PROCEDURE FOR MAIN WINDOW  */
  78. long FAR PASCAL
  79. BLDMainWndProc(HWND hWnd, unsigned message, WORD wParam,
  80.     LONG lParam)
  81. {
  82.     switch (message)
  83.     {
  84.     case WM_DRAWITEM: /* Owner draw button message */
  85.     DrawGraphicButton(hWnd, message,
  86.             wParam, lParam);
  87.     break;
  88.     case WM_CREATE:
  89.         return DefWindowProc(hWnd, message, wParam, lParam);
  90.     case WM_SETFOCUS: /* notification of focus change */
  91.         return DefWindowProc(hWnd, message, wParam, lParam);
  92.     case WM_DESTROY:
  93.         PostQuitMessage(0);
  94.         return DefWindowProc(hWnd, message, wParam, lParam);
  95.         break;
  96.     case WM_COMMAND: /* command from the main window */
  97.         switch(wParam)
  98.         {
  99.         case IDM_Quit:
  100.             PostMessage(hWnd, WM_CLOSE, 0, 0L);
  101.             return DefWindowProc(hWnd, message,
  102.                         wParam,lParam);
  103.             break;
  104.         case GRAPH_BUTTON_ID:
  105.             MessageBox(hWnd,"You clicked my button!",
  106.                 "Graphic button example",
  107.                 MB_ICONEXCLAMATION | MB_OK);
  108.             break;
  109.         case TEXT_BUTTON_ID:
  110.             MessageBox(hWnd,"You clicked my button!",
  111.                 "Text button example",
  112.                 MB_ICONEXCLAMATION | MB_OK);
  113.             break;
  114.         default:
  115.             return DefWindowProc(hWnd, message,
  116.                                 wParam, lParam);
  117.         }
  118.         break;
  119.     default:
  120.         return DefWindowProc(hWnd, message, wParam, lParam);
  121.     }
  122.     return FALSE; /* Returns FALSE if processed */
  123. }
  124.  
  125. /* BLDRegisterClass() - Registers class for main window  */
  126.  
  127.     BOOL
  128. BLDRegisterClass(HANDLE    hInstance)
  129. {
  130.     WNDCLASS WndClass;
  131.   
  132.     WndClass.style         = 0;
  133.     WndClass.lpfnWndProc   = BLDMainWndProc;
  134.     WndClass.cbClsExtra    = 0;
  135.     WndClass.cbWndExtra    = 0;
  136.     WndClass.hInstance     = hInstance;
  137.     WndClass.hIcon         = LoadIcon(HInstance,"GRAPHIC");
  138.     WndClass.hCursor       = LoadCursor(NULL,IDC_ARROW);
  139.     WndClass.hbrBackground = CreateSolidBrush(
  140.                             GetSysColor(COLOR_WINDOW));
  141.     WndClass.lpszMenuName  = "GRAFBUTN";
  142.     WndClass.lpszClassName = "GRAFBUTN";
  143.  
  144.     return RegisterClass(&WndClass);
  145. }
  146.     
  147. /* BLDCreateWindow() - Creates the main window */
  148.  
  149.     HWND
  150. BLDCreateWindow(HANDLE    hInstance)
  151. {
  152.     HWND hWnd; /* window handle */
  153.     int coordinate[4]; /* Coordinates of main window  */
  154.  
  155.     coordinate[0]=CW_USEDEFAULT;
  156.     coordinate[1]=0;
  157.     coordinate[2]=CW_USEDEFAULT;
  158.     coordinate[3]=0;
  159.     
  160.     hWnd = CreateWindow(
  161.         "GRAFBUTN",  /* window class registered earlier */
  162.         "Graphic Picturebutton Example", /* caption */
  163.         WS_OVERLAPPED | WS_THICKFRAME |
  164.         WS_SYSMENU    | WS_MINIMIZEBOX|
  165.         WS_MAXIMIZEBOX,    /* window style */
  166.            CW_USEDEFAULT,  /* x position   */
  167.            0,              /* y position   */
  168.            CW_USEDEFAULT,  /* width        */
  169.            0,              /* height       */
  170.            0,              /* parent handle   */
  171.            0,              /* menu or child ID*/
  172.            hInstance,      /* instance        */
  173.            (LPSTR)NULL);   /* additional info */
  174.  
  175.     hGraphButton    = CreateGraphButtonWindow(hWnd);
  176.     hTextButton     = CreateTextButtonWindow(hWnd);
  177.     if (hGraphButton && hTextButton)
  178.         return hWnd;
  179.     else
  180.         return NULL;
  181. }
  182.  
  183. /* CreateTextButtonWindow()
  184.  *   Creates a free-standing child window
  185.  *   button in a program's main window.
  186.  */
  187.  
  188. HWND CreateTextButtonWindow(HWND hWnd)
  189. {
  190.     HWND     deskhWnd, hButton;
  191.     HDC        deskhDC;
  192.     int        gl_hchar, gl_wchar;
  193.     TEXTMETRIC    sysText;
  194.  
  195.     /* Get system metrics so that we can size the button properly.
  196.      */
  197.     deskhWnd = GetDesktopWindow();
  198.     deskhDC = GetDC(deskhWnd);
  199.     
  200.     /* Grab the size of text cells...
  201.      */
  202.     GetTextMetrics(deskhDC, (LPTEXTMETRIC)&sysText);
  203.     gl_wchar = sysText.tmAveCharWidth;
  204.     gl_hchar = sysText.tmHeight;
  205.     ReleaseDC(deskhWnd, deskhDC);
  206.     
  207.     hButton = CreateWindow(
  208.             "BUTTON",
  209.             (LPSTR)"My Button",
  210.             BS_PUSHBUTTON |
  211.                WS_CHILD   |
  212.                WS_VISIBLE,
  213.             60,
  214.             20,
  215.             11 * gl_wchar,
  216.             gl_hchar + gl_hchar / 3 + 1,
  217.             hWnd,
  218.             TEXT_BUTTON_ID,
  219.             hInst,
  220.             NULL);
  221.  
  222.     if (!hButton)
  223.     {
  224.         DestroyWindow(hWnd);
  225.         return FALSE;
  226.     }
  227.  
  228.     return hButton;
  229. }
  230.  
  231. /* CreateGraphButtonWindow() - Creates a free-standing
  232.  *     child window button in a program's main window.
  233.  */
  234. HWND CreateGraphButtonWindow(HWND hWnd)
  235. {
  236.     HWND        hButton;
  237.  
  238.     hButton = CreateWindow("BUTTON", (LPSTR)"My Button",
  239.             BS_OWNERDRAW | WS_CHILD | WS_VISIBLE,
  240.             20,     /* x offset */
  241.             20,     /* y offset */
  242.             32,     /* x size in pixels */
  243.             32,     /* y size in pixels */
  244.             hWnd, GRAPH_BUTTON_ID, hInst, NULL);
  245.     if (!hButton)
  246.         {
  247.         DestroyWindow(hWnd);
  248.         return FALSE;
  249.         }
  250.     return hButton;
  251. }
  252.  
  253. /*
  254.  * DrawBitmap()
  255.  *
  256.  * Given a handle to a bitmap, and a device
  257.  * context, this routine will draw the bitmap
  258.  * into that device context at the requested
  259.  * offset locations. 
  260.  *
  261.  * Returns: TRUE - bitmap sucessfully drawn
  262.  *        FALSE - bitmap was not drawn sucessfully
  263.  */
  264.  
  265.     BOOL
  266. DrawBitmap (HDC     hDC,    /* Destination DC */
  267.         int     x,      /* X offset */
  268.         int     y,      /* Y offset */
  269.         HBITMAP hbm,    /* Handle to source bitmap */
  270.         DWORD   rop)    /* Raster OP to perform */
  271. {
  272.     HDC           hMemoryDC;
  273.     BITMAP        bm;
  274.     BOOL          f;
  275.     HBITMAP    bmHand;
  276.  
  277.     if (!hDC || !hbm)    /* If either handle is bad, punt */
  278.         return FALSE;
  279.  
  280.     /* Before we can blit the bitmap, it has to be
  281.      * selected into a device context compatible
  282.      * with the destination.  So first, we need to
  283.      * create the compatible DC. 
  284.      */
  285.     hMemoryDC = CreateCompatibleDC(hDC);
  286.  
  287.     /* Select desired bitmap into the memory DC we
  288.      * just created.  Also remember the old bitmap
  289.      * handle that used to be in the DC, so that we
  290.      * can restore it after we're done. 
  291.      */
  292.     bmHand = SelectObject(hMemoryDC, hbm);
  293.  
  294.     /* Get information about the bitmap, so that we
  295.      * can blit it properly.
  296.      */
  297.     GetObject(hbm, sizeof(BITMAP), (LPSTR)&bm);
  298.  
  299.     /* Everything's set up--we can now blit the
  300.      * image into the destination DC.
  301.      */
  302.     f = BitBlt(hDC,     /* Destination DC */
  303.            x,       /* Destination x offset (if any) */
  304.            y,       /* Destination y offset (if any) */
  305.            bm.bmWidth,/* Width of source bitmap */
  306.            bm.bmHeight,/* Height of source bitmap */
  307.            hMemoryDC,/* Source DC */
  308.            0,       /* Source x offset (none) */
  309.            0,       /* Source y offset (none) */
  310.            rop);    /* Copy the bitmap... */
  311.  
  312.     /* Now select the old bitmap handle back into the
  313.      * memory DC.  (Failure to do this will cause a 
  314.      * small piece of Windows resource to be lost
  315.      * until re-boot time.)
  316.      */
  317.     SelectObject(hMemoryDC, bmHand);
  318.  
  319.     /* Delete the memory DC so that we're not
  320.      * using up system resources.
  321.      */
  322.     DeleteDC(hMemoryDC);
  323.  
  324.     /* Return status of the BitBlt() call. */
  325.     return f;
  326. }
  327.  
  328. /* DrawGraphicButton()
  329.  *    Draws a graphic bitmap button on the screen.
  330.  * Returns; Nothing
  331.  */
  332.  
  333.     void
  334. DrawGraphicButton(HWND hWnd, unsigned message, WORD wParam,
  335.                 LONG lParam)
  336. {
  337.     LPDRAWITEMSTRUCT lpDraw; /* Info about thing to draw */
  338.     WORD        flags;  /* Info about button state */
  339.     HBITMAP     bmButton; /* Handle to bitmap button */
  340.  
  341.     lpDraw = (LPDRAWITEMSTRUCT)lParam;
  342.  
  343.     /* If control is not the right type, punt.
  344.      * (This should never happen, right?)
  345.      */
  346.     if (lpDraw->CtlType != ODT_BUTTON)
  347.         return;
  348.  
  349.     /* Get button state   */
  350.     flags = GetDesiredButtonState(hWnd,
  351.             lpDraw->itemAction, lpDraw->itemState);
  352.     switch(flags)
  353.     {
  354.     case ALL_SELECT:
  355.         case ALL_FOCUS_SELECT:
  356.         case SELECT_SELECT:
  357.         case SELECT_FOCUS_SELECT:
  358.             bmButton = LoadBitmap(hInst, "DOWNFACE");
  359.         break;
  360.     default:
  361.             bmButton = LoadBitmap(hInst, "UPFACE");
  362.     }
  363.  
  364.     DrawBitmap(lpDraw->hDC, 0, 0, bmButton, SRCCOPY);
  365. }
  366.  
  367. /***************************
  368.  *
  369.  * GetDesiredButtonState()
  370.  *   Returns a value which indicates the desired end result
  371.  * of a button press on an owner-drawn button.
  372.  *
  373.  * Params:
  374.  *  hWnd - window handle
  375.  *  itemAction - action taken
  376.  *  itemState - desired end state
  377.  *
  378.  * Returns:
  379.  *  Flag setting
  380.  *
  381.  * Assumptions:
  382.  *  None
  383.  *
  384.  */
  385.  
  386.     WORD NEAR PASCAL
  387. GetDesiredButtonState(HWND    hWnd,
  388.               WORD    itemAction,
  389.               WORD    itemState)
  390. {
  391.     WORD lFlags;  /* Local flag value */
  392.     
  393.     /*-----------------------*/
  394.     
  395.     lFlags = NOFOCUS_NOFLAGS;
  396.     
  397.     if (itemAction & ODA_FOCUS)
  398.     {
  399.     if (itemState & ODS_FOCUS)
  400.         lFlags = FOCUS_FOCUS;
  401.     else
  402.         lFlags = FOCUS_NOFLAGS;
  403.     }
  404.  
  405.     if (itemAction & ODA_SELECT)
  406.     {
  407.     if (itemState & ODS_FOCUS)
  408.         lFlags |= SELECT_FOCUS;
  409.     if (itemState & ODS_SELECTED)
  410.         lFlags |= SELECT_SELECT;
  411.     }
  412.  
  413.     if (itemAction & ODA_DRAWENTIRE)
  414.     {
  415.         lFlags = ALL_NOFLAGS;
  416.     if (itemState & ODS_FOCUS)
  417.         lFlags |= ALL_FOCUS;
  418.     if (itemState & ODS_SELECTED)
  419.         lFlags |= ALL_SELECT;
  420.     }
  421.  
  422.     return (lFlags);
  423. }
  424.