OWNCOMBO.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:36k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright (C) 1993 - 1997 Microsoft Corp.
  4. *       All rights reserved. 
  5. *       This source code is only intended as a supplement to 
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the 
  8. *       Microsoft samples programs.
  9. ******************************************************************************/
  10. /***************************************************************************
  11.  *                                                                         *
  12.  *  PROGRAM     : OwnCombo.c                                               *
  13.  *                                                                         *
  14.  *  PURPOSE     : Illustrates the use of functions and messages for        *
  15.  *                combo boxes and owner-draw control styles.               *
  16.  *                                                                         *
  17.  *  FUNCTIONS   : WinMain                - Creates the app. window and     *
  18.  *                                         enters the message loop.        *
  19.  *                                                                         *
  20.  *                OwnComboInit           - Registers the main window class *
  21.  *                                                                         *
  22.  *                About                  - Dialog function for the About   *
  23.  *                                         dialog.                         *
  24.  *                                                                         *
  25.  *                OwnComboWndProc        - Window function for app. It     *
  26.  *                                         handles the menu selections     *
  27.  *                                         and processes the other window  *
  28.  *                                         messages.                       *
  29.  *                                                                         *
  30.  *                DrawEntireItem         - Handles the drawing of a list   *
  31.  *                                         list box or combo box item.     *
  32.  *                                                                         *
  33.  *                HandleSelectionState   - Handles the selecting/deselect- *
  34.  *                                         ing of a list box or combo box  *
  35.  *                                         item.                           *
  36.  *                                                                         *
  37.  *                HandleFocusState       - Handles the getting/losing of   *
  38.  *                                         the input focus by a list box   *
  39.  *                                                                         *
  40.  *                ListBoxExample         - Dialog function for the         *
  41.  *                                         owner-draw list box example.    *
  42.  *                                                                         *
  43.  *                ComboBoxExample        - Dialog function for the text    *
  44.  *                                         combo dialog.                   *
  45.  *                                                                         *
  46.  *                OwnerComboBoxExample   - Dialog fubction for the drop-   *
  47.  *                                         down-list combobox with         *
  48.  *                                         ownerdraw.                      *
  49.  *                                                                         *
  50.  ***************************************************************************/
  51. #include "windows.h"
  52. #include "owncombo.h"
  53. HANDLE  hInst;
  54. /****************************************************************************
  55.  *                                                                          *
  56.  *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)                        *
  57.  *                                                                          *
  58.  *  PURPOSE    : Creates the app. window and enters the message loop.       *
  59.  *                                                                          *
  60.  ****************************************************************************/
  61. int APIENTRY WinMain(
  62.     HINSTANCE hInstance,
  63.     HINSTANCE hPrevInstance,
  64.     LPSTR lpCmdLine,
  65.     int nCmdShow
  66.     )
  67. {
  68.     HWND  hWnd;
  69.     MSG   msg;
  70.     UNREFERENCED_PARAMETER( lpCmdLine );
  71.     if (!hPrevInstance)
  72.         if (!OwnComboInit (hInstance))
  73.             return (0);
  74.     hInst = hInstance;
  75.     /* Create the app. window */
  76.     hWnd = CreateWindow ("owncombo",
  77.                          "Owner-draw & Combo Box Example",
  78.                          WS_OVERLAPPEDWINDOW,
  79.                          CW_USEDEFAULT,
  80.                          CW_USEDEFAULT,
  81.                          CW_USEDEFAULT,
  82.                          CW_USEDEFAULT,
  83.                          (HWND) NULL,
  84.                          NULL,
  85.                          hInstance,
  86.                          (LPSTR) NULL);
  87.     if (!hWnd)
  88.         return (0);
  89.     ShowWindow (hWnd, nCmdShow);
  90.     while (GetMessage (&msg, NULL, 0, 0)){
  91.         TranslateMessage (&msg);
  92.         DispatchMessage (&msg);
  93.     }
  94.     return(msg.wParam);
  95. }
  96. /****************************************************************************
  97.  *                                                                          *
  98.  *  FUNCTION   : OwnComboInit (hInstance)                                   *
  99.  *                                                                          *
  100.  *  PURPOSE    : Registers the main window class.                           *
  101.  *                                                                          *
  102.  *  RETURNS    : TRUE  - if RegisterClass () succeeds.                      *
  103.  *               FALSE - if RegisterClass () fails.                         *
  104.  *                                                                          *
  105.  ****************************************************************************/
  106. BOOL NEAR PASCAL OwnComboInit (HANDLE hInstance)
  107. {
  108.     HANDLE     hMemory;
  109.     PWNDCLASS  pWndClass;
  110.     BOOL       bSuccess;
  111.     /* Allocate for and fill class structure. */
  112.     hMemory = LocalAlloc (LPTR, sizeof (WNDCLASS));
  113.     if(!hMemory){
  114.         MessageBox(NULL, "<OwnComboInit> Not enough memory.", NULL, MB_OK | MB_ICONHAND);
  115.         return(FALSE);
  116.     }
  117.     pWndClass = (PWNDCLASS) LocalLock (hMemory);
  118.     pWndClass->style         = 0;
  119.     pWndClass->lpfnWndProc   = (WNDPROC) OwnComboWndProc;
  120.     pWndClass->hInstance    = hInstance;
  121.     pWndClass->hIcon         = LoadIcon (hInstance, "owncombo");
  122.     pWndClass->hCursor       = LoadCursor (NULL, IDC_ARROW);
  123.     pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  124.     pWndClass->lpszMenuName  = (LPSTR) "OwnComboMenu",
  125.     pWndClass->lpszClassName = (LPSTR) "owncombo";
  126.     bSuccess = RegisterClass (pWndClass);
  127.     LocalUnlock (hMemory);
  128.     LocalFree (hMemory);
  129.     return (bSuccess);
  130. }
  131. /****************************************************************************
  132.  *                                                                          *
  133.  *  FUNCTION   : About (hDlg,message, wParam, lParam)                       *
  134.  *                                                                          *
  135.  *  PURPOSE    : Dialog function for the About... dialog.                   *
  136.  *                                                                          *
  137.  ****************************************************************************/
  138. BOOL APIENTRY About (
  139.     HWND         hDlg,
  140.     UINT     message,
  141.     UINT         wParam,
  142.     LONG         lParam)
  143. {
  144.         UNREFERENCED_PARAMETER(lParam);
  145.     switch (message){
  146.         case WM_INITDIALOG:
  147.             return(TRUE);
  148.         case WM_COMMAND:
  149.             if (LOWORD(wParam) == IDOK){
  150.                 EndDialog (hDlg,0);
  151.                 return(FALSE);
  152.             }
  153.             break;
  154.         default:
  155.             break;
  156.     }
  157.   return(FALSE);
  158. }
  159. /****************************************************************************
  160.  *                                                                          *
  161.  *  FUNCTION   : OwnComboWndProc(hWnd, message, wParam, lParam)             *
  162.  *                                                                          *
  163.  *  PURPOSE    : Window function for the app. It handles menu selections    *
  164.  *               and processes window WM_ messages.                         *
  165.  *                                                                          *
  166.  ****************************************************************************/
  167. LONG APIENTRY OwnComboWndProc (
  168.     HWND         hWnd,
  169.     UINT     message,
  170.     UINT         wParam,
  171.     LONG         lParam)
  172. {
  173.     switch (message){
  174.         case WM_COMMAND:
  175.             switch (LOWORD(wParam)){
  176.                 case IDM_EXIT:
  177.                     DestroyWindow (hWnd);
  178.                     break;
  179.                 case IDM_ABOUT:
  180.                     /* Bring up the about box */
  181.                     DialogBox (hInst,
  182.                                "AboutBox",
  183.                                hWnd,
  184.                                About);
  185.                     break;
  186.                 case IDM_LISTBOX:
  187.                     /* Bring up the list box example */
  188.                     DialogBox (hInst,
  189.                                "ListBoxDialog",
  190.                                hWnd,
  191.                                About);
  192.                     break;
  193.                 case IDM_MULTILISTBOX:
  194.                     /* Bring up the multiple selection list box example */
  195.                     DialogBox (hInst,
  196.                                "MultiListBoxDialog",
  197.                                hWnd,
  198.                                About);
  199.                     break;
  200.                 case IDM_COMBOBOX:
  201.                     /* Bring up the combo box example */
  202.                     DialogBox (hInst,
  203.                                "ComboBoxDialog",
  204.                                hWnd,
  205.                                About);
  206.                     break;
  207.                 case IDM_OWNERCOMBOBOX:
  208.                     /* Bring up the owner-draw dropdown list box example */
  209.                     DialogBox (hInst,
  210.                                "OwnerComboBoxDialog",
  211.                                hWnd,
  212.                                About);
  213.                     break;
  214.             }
  215.             break;
  216.         case WM_DESTROY:
  217.             PostQuitMessage (0);
  218.             break;
  219.         default:
  220.             return(DefWindowProc(hWnd, message, wParam, lParam));
  221.     }
  222.     return(0);
  223. }
  224. /****************************************************************************
  225.  *                                                                          *
  226.  *  FUNCTION   : HandleSelectionState(LPDRAWITEMSTRUCT, int)                *
  227.  *                                                                          *
  228.  *  PURPOSE    : Handles a change in an item selection state. If an item is *
  229.  *               selected, a black rectangular frame is drawn around that   *
  230.  *               item; if an item is de-selected, the frame is removed.     *
  231.  *                                                                          *
  232.  *  COMMENT    : The black selection frame is slightly larger than the gray *
  233.  *               focus frame so they won't paint over each other.           *
  234.  *                                                                          *
  235.  ****************************************************************************/
  236. VOID APIENTRY HandleSelectionState(
  237.         LPDRAWITEMSTRUCT        lpdis,
  238.         INT                     inflate)
  239. {
  240.         RECT    rc;
  241.         HBRUSH  hbr;
  242.         /* Resize rectangle to place selection frame outside of the focus
  243.          * frame and the item.
  244.          */
  245.         CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
  246.         InflateRect ((LPRECT)&rc, inflate, inflate);
  247.         if (lpdis->itemState & ODS_SELECTED)
  248.         {
  249.                 /* selecting item -- paint a black frame */
  250.                 hbr = GetStockObject(BLACK_BRUSH);
  251.         }
  252.         else
  253.         {
  254.                 /* de-selecting item -- remove frame */
  255.                 hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  256.         }
  257.         FrameRect(lpdis->hDC, (LPRECT)&rc, hbr);
  258.         DeleteObject (hbr);
  259. }
  260. /****************************************************************************
  261.  *                                                                          *
  262.  *  FUNCTION   : HandleFocusState(LPDRAWITEMSTRUCT, int)                    *
  263.  *                                                                          *
  264.  *  PURPOSE    : Handle a change in item focus state. If an item gains the  *
  265.  *               input focus, a gray rectangular frame is drawn around that *
  266.  *               item; if an item loses the input focus, the gray frame is  *
  267.  *               removed.                                                   *
  268.  *                                                                          *
  269.  *  COMMENT    : The gray focus frame is slightly smaller than the black    *
  270.  *               selection frame so they won't paint over each other.       *
  271.  *                                                                          *
  272.  ****************************************************************************/
  273. VOID APIENTRY HandleFocusState(
  274.         LPDRAWITEMSTRUCT        lpdis,
  275.         INT                     inflate)
  276. {
  277.         RECT    rc;
  278.         HBRUSH  hbr;
  279.         /* Resize rectangle to place focus frame between the selection
  280.          * frame and the item.
  281.          */
  282.         CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
  283.         InflateRect ((LPRECT)&rc, inflate, inflate);
  284.         if (lpdis->itemState & ODS_FOCUS)
  285.         {
  286.                 /* gaining input focus -- paint a gray frame */
  287.                 hbr = GetStockObject(GRAY_BRUSH);
  288.         }
  289.         else
  290.         {
  291.                 /* losing input focus -- remove (paint over) frame */
  292.                 hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  293.         }
  294.         FrameRect(lpdis->hDC, (LPRECT)&rc, hbr);
  295.         DeleteObject (hbr);
  296. }
  297. /****************************************************************************
  298.  *                                                                          *
  299.  *  FUNCTION   : DrawEntireItem(LPDRAWITEMSTRUCT, int)                      *
  300.  *                                                                          *
  301.  *  PURPOSE    : Draws an item and frames it with a selection frame and/or  *
  302.  *               a focus frame when appropriate.                            *
  303.  *                                                                          *
  304.  ****************************************************************************/
  305. VOID APIENTRY DrawEntireItem(
  306.         LPDRAWITEMSTRUCT        lpdis,
  307.         INT                     inflate)
  308. {
  309.         RECT    rc;
  310.         HBRUSH  hbr;
  311.         /* Resize rectangle to leave space for frames */
  312.         CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
  313.         InflateRect ((LPRECT)&rc, inflate, inflate);
  314.         /* Create a brush using the value in the item data field (this value
  315.          * was initialized when we added the item to the list/combo box using
  316.          * LB_ADDSTRING/CB_ADDSTRING) and draw the color in the list/combo box.
  317.          */
  318.         hbr = CreateSolidBrush (lpdis->itemData);
  319.         FillRect (lpdis->hDC, (LPRECT)&rc, hbr);
  320.         DeleteObject (hbr);
  321.         /* Draw or erase appropriate frames */
  322.         HandleSelectionState(lpdis, inflate + 4);
  323.         HandleFocusState(lpdis, inflate + 2);
  324. }
  325. /****************************************************************************
  326.  *                                                                          *
  327.  *  FUNCTION   : ListBoxExample (hDlg, message, wParam, lParam)             *
  328.  *                                                                          *
  329.  *  PURPOSE    : Dialog function for the owner-draw list box example.       *
  330.  *               It sets up the example dialog with the owner-draw list box,*
  331.  *               adds the colors to the list box, and handles setting the   *
  332.  *               selection and focus for the items.                         *
  333.  *                                                                          *
  334.  ****************************************************************************/
  335. BOOL APIENTRY ListBoxExample (
  336.     HWND hDlg,
  337.     UINT message,
  338.     UINT wParam,
  339.     LONG lParam)
  340. {
  341.     LPDRAWITEMSTRUCT    lpdis;
  342.     LPMEASUREITEMSTRUCT lpmis;
  343.     /* Vars for WM_DRAWITEM */
  344.     switch (message){
  345.         case WM_COMMAND:
  346.             switch (LOWORD(wParam)){
  347.                 case IDOK:
  348.                    EndDialog (hDlg, 0);
  349.                    return (TRUE);
  350.                    break;
  351.                 /* Clicking any of these buttons adds the corresponding color
  352.                  * to the list box. The application-supplied data is the RGB
  353.                  * value for the color to be drawn in the listbox.
  354.                  */
  355.                 case ID_BLACK:
  356.                     SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
  357.                                  LB_ADDSTRING,
  358.                                  0,
  359.                                  RGB (0,0,0));
  360.                     return(TRUE);
  361.                     break;
  362.                 case ID_RED:
  363.                     SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
  364.                                  LB_ADDSTRING,
  365.                                  0,
  366.                                  RGB (255,0,0));
  367.                     return(TRUE);
  368.                     break;
  369.                 case ID_BLUE:
  370.                     SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
  371.                                  LB_ADDSTRING,
  372.                                  0,
  373.                                  RGB (0,0,255));
  374.                     return(TRUE);
  375.                     break;
  376.                 case ID_GREEN:
  377.                     SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
  378.                                  LB_ADDSTRING,
  379.                                  0,
  380.                                  RGB (0,255,0));
  381.                     return(TRUE);
  382.                     break;
  383.                 default:
  384.                     return(FALSE);
  385.                     break;
  386.             }
  387.         case WM_DRAWITEM:
  388.             /* Get pointer to the DRAWITEMSTRUCT */
  389.             lpdis = (LPDRAWITEMSTRUCT)lParam;
  390.             if (lpdis->itemID == -1)
  391.             {
  392.                 /* We have a request to draw an item in the list box, yet there
  393.                  * are no list box items. This is sent when the user TABS into
  394.                  * an empty list box or an empty list box gets the focus. We
  395.                  * have to indicate (somehow) that this owner-draw list box has
  396.                  * the focus. We do it in response to this message. Note that
  397.                  * lpdis->itemData field would be invalid in this instance so
  398.                  * we can't allow it to fall into our standard routines.
  399.                  */
  400.                 HandleFocusState(lpdis, -5);
  401.             }
  402.             else
  403.             {
  404.                 switch (lpdis->itemAction)
  405.                 {
  406.                         case ODA_DRAWENTIRE:
  407.                                 DrawEntireItem(lpdis, -7);
  408.                                 break;
  409.                         case ODA_SELECT:
  410.                                 HandleSelectionState(lpdis, -3);
  411.                                 break;
  412.                         case ODA_FOCUS:
  413.                                 HandleFocusState(lpdis, -5);
  414.                                 break;
  415.                 }
  416.             }
  417.             /* Return TRUE meaning that we processed this message. */
  418.             return(TRUE);
  419.             break;
  420.         case WM_MEASUREITEM:
  421.             lpmis = (LPMEASUREITEMSTRUCT)lParam;
  422.             /* All the items are the same height since the list box style is
  423.              * LBS_OWNERDRAWFIXED
  424.              */
  425.             lpmis->itemHeight = 30;
  426.             break;
  427.         case WM_CLOSE:
  428.             EndDialog(hDlg, 0);
  429.             return(TRUE);
  430.             break;
  431.         default:
  432.             return(FALSE);
  433.     }
  434.     return(TRUE);
  435. }
  436. /****************************************************************************
  437.  *                                                                          *
  438.  *  FUNCTION   : ComboBoxExample(hWnd, message, wParam, lParam)             *
  439.  *                                                                          *
  440.  *  PURPOSE    : Dialog function for the text combo dialog. The push buttons*
  441.  *               send various messages to the combo box and the edit control*
  442.  *               when selected. They allow the user to vary data sent with  *
  443.  *               each message.                                              *
  444.  *                                                                          *
  445.  ****************************************************************************/
  446. BOOL APIENTRY ComboBoxExample(
  447.     HWND hDlg,
  448.     UINT message,
  449.     UINT wParam,
  450.     LONG lParam)
  451. {
  452.     HWND hWndCombo;                  /* Handle to the combo box control */
  453.                                      /* in the dialog box window        */
  454.     HWND hWndCheckBox;               /* Handle to the Auto Check Box    */
  455.     CHAR strSingleEditLine[255];     /* Single line edit control input  */
  456.     INT  wIndex, wCount;
  457.     /* Get handles to the Combo box and the Check box */
  458.     hWndCombo     = GetDlgItem(hDlg, ID_COMBOBOX);
  459.     hWndCheckBox  = GetDlgItem(hDlg, ID_STEPSBOX);
  460.     switch (message){
  461.         case WM_COMMAND:
  462.             switch (LOWORD(wParam)){
  463.                 case IDOK:
  464.                     EndDialog (hDlg,0);
  465.                     return(TRUE);
  466.                 case ID_UNSLBUTTON:
  467.                     /* Selecting this button unselects any selection in the
  468.                      * combo box.
  469.                      */
  470.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  471.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  472.                     wIndex = (WORD) SendMessage( hWndCombo, CB_GETCURSEL, 0, 0L);
  473.                     if (wIndex == CB_ERR)
  474.                         MessageBox (hDlg, (LPSTR)"No Selection", NULL, MB_OK);
  475.                     else
  476.                         SendMessage (hWndCombo, CB_SETCURSEL, (WPARAM)-1, 0L);
  477.                     SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
  478.                     break;
  479.                 case ID_NUMSELBUTTON:
  480.                     /* An integer value is taken from the edit control and an
  481.                      * attempt is made to select a combo box entry having this
  482.                      * index.
  483.                      */
  484.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  485.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  486.                     wCount = (WORD) SendMessage (hWndCombo, CB_GETCOUNT, 0, 0L);
  487.                     wIndex = (INT) GetDlgItemInt (hDlg, ID_SINGLEEDIT, NULL, TRUE);
  488.                     if (wIndex >= wCount)
  489.                         MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
  490.                     else
  491.                         SendMessage(hWndCombo, CB_SETCURSEL, wIndex, 0L);
  492.                     SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
  493.                     break;
  494.                 case ID_TXTSELBUTTON:
  495.                     /* A text string is taken from the edit control and an
  496.                      * attempt is made to select a combo box entry having the
  497.                      * string as a prefix.
  498.                      */
  499.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  500.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  501.                     GetDlgItemText (hDlg, ID_SINGLEEDIT,
  502.                                  (LPSTR)strSingleEditLine, 255);
  503.                     wIndex = (WORD) SendMessage (hWndCombo,
  504.                                                 CB_SELECTSTRING,
  505.                                                 (WPARAM)-1,
  506.                                                 (LONG)(LPSTR)strSingleEditLine);
  507.                     if (wIndex == CB_ERR)
  508.                       MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
  509.                     SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
  510.                     break;
  511.                 case ID_FNDSELBUTTON:
  512.                     /* Searches for the text specified in the list of combo
  513.                      * entries and returns the index (in combo box) of the
  514.                      * first match. The index is displayed in the "Text1"
  515.                      * field of the dialog.
  516.                      */
  517.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  518.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  519.                     GetDlgItemText (hDlg,
  520.                                     ID_SINGLEEDIT,
  521.                                     (LPSTR)strSingleEditLine,
  522.                                     255);
  523.                     wIndex = (WORD)SendMessage (hWndCombo,
  524.                                                CB_FINDSTRING,(WPARAM)-1,
  525.                                                (LONG)(LPSTR)strSingleEditLine);
  526.                     if (wIndex == CB_ERR)
  527.                         MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
  528.                     else
  529.                         SetDlgItemInt (hDlg, ID_TEXT1, wIndex, FALSE);
  530.                     SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
  531.                     break;
  532.                 case ID_CLRBUTTON:
  533.                     /* Clears the combo box of all it's entries */
  534.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  535.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  536.                     wCount = (WORD) SendMessage (hWndCombo, CB_GETCOUNT, 0, 0L);
  537.                     if (!wCount)
  538.                         MessageBox (hDlg, (LPSTR)"Already clear", NULL, MB_OK);
  539.                     else{
  540.                         SetDlgItemInt (hDlg, ID_TEXT1, wCount, TRUE);
  541.                         SetDlgItemText (hDlg, ID_TEXT2, "Items cleared");
  542.                         SendMessage (hWndCombo,CB_RESETCONTENT, 0, 0L);
  543.                     }
  544.                     SetFocus (GetDlgItem (hDlg,ID_SINGLEEDIT));
  545.                     break;
  546.                 case ID_ADDBUTTON:
  547.                     /* Takes the string specified in the edit control and
  548.                      * adds it to the combo box.
  549.                      */
  550.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  551.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  552.                     GetDlgItemText (hDlg, ID_SINGLEEDIT, strSingleEditLine, 255);
  553.                     SendMessage (hWndCombo,
  554.                                  CB_ADDSTRING,
  555.                                  0,
  556.                                  (LONG)(LPSTR) strSingleEditLine);
  557.                     SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
  558.                     break;
  559.                 case ID_DELETEBUTTON:
  560.                     /* Delete the currently selected item from the combo box. */
  561.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  562.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  563.                     wIndex = (WORD) SendMessage (hWndCombo, CB_GETCURSEL, 0, 0L);
  564.                     if (SendMessage (hWndCombo, CB_DELETESTRING, wIndex, 0L) == CB_ERR)
  565.                         MessageBox (hDlg, (LPSTR)"No Selection", NULL, MB_OK);
  566.                     else{
  567.                         SetDlgItemText (hDlg, ID_TEXT1, "deleted index #");
  568.                         SetDlgItemInt  (hDlg, ID_TEXT2, wIndex, TRUE);
  569.                     }
  570.                     SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
  571.                     break;
  572.                 case ID_CBDIRBUTTON:
  573.                     /* Appends a directory listing of the current directory
  574.                      * to the combo box entries.
  575.                      */
  576.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  577.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  578.                     wIndex = (WORD)SendMessage (hWndCombo,
  579.                                                CB_DIR,
  580.                                                0x10|0x4000,
  581.                                                (LONG)(LPSTR)"*.*");
  582.                     SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
  583.                     break;
  584.                 case ID_CPYBUTTON:
  585.                     /* Copies the currently selected item in the combo box to
  586.                      * the edit control.
  587.                      */
  588.                     SetDlgItemText (hDlg, ID_TEXT1, "");
  589.                     SetDlgItemText (hDlg, ID_TEXT2, "");
  590.                     wIndex = (WORD) SendMessage (hWndCombo, CB_GETCURSEL, 0, 0L);
  591.                     if (wIndex == CB_ERR)
  592.                         MessageBox(hDlg, (LPSTR)"No Selection", NULL, MB_OK);
  593.                     else{
  594.                         wCount = SendMessage (hWndCombo, CB_GETLBTEXTLEN, wIndex, 0L);
  595.                         SendMessage (hWndCombo,
  596.                                      CB_GETLBTEXT,
  597.                                      wIndex,
  598.                                      (LONG)(LPSTR)strSingleEditLine);
  599.                         SetDlgItemText(hDlg, ID_SINGLEEDIT,
  600.                                        (LPSTR)strSingleEditLine);
  601.                         SetDlgItemText(hDlg, ID_TEXT1, "copied index #");
  602.                         SetDlgItemInt(hDlg, ID_TEXT2, wIndex, TRUE);
  603.                     }
  604.                     SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
  605.                     break;
  606.                 /* When the combo notification box is checked, a message box
  607.                  * is flashed showing what notification codes the combo box is
  608.                  * returning to the app. in response to the messages sent by
  609.                  * the buttons.
  610.                  */
  611.                 case ID_COMBOBOX:
  612.                     if (SendMessage (hWndCheckBox, BM_GETCHECK, 0, 0L)){
  613.                         switch (HIWORD(lParam)){
  614.                             case (WORD)CBN_ERRSPACE:
  615.                               MessageBox (hDlg, (LPSTR)"CB Out of Space",
  616.                                          "CB MSG", MB_OK);
  617.                               break;
  618.                             case CBN_SELCHANGE:
  619.                               MessageBox (hDlg, (LPSTR)"CB Sel Change",
  620.                                          "CB MSG", MB_OK);
  621.                               break;
  622.                             case CBN_DBLCLK:
  623.                               MessageBox(hDlg, (LPSTR)"CB Double Click",
  624.                                          "CB MSG", MB_OK);
  625.                               break;
  626.                             case CBN_SETFOCUS:
  627.                               SetDlgItemText(hDlg, ID_TEXT1, "CB SetFocus");
  628.                               break;
  629.                             case CBN_KILLFOCUS:
  630.                               SetDlgItemText(hDlg, ID_TEXT1, "CB KillFocus");
  631.                               break;
  632.                         }
  633.                     }
  634.                     break;
  635.                 default:
  636.                     return(FALSE);
  637.             }
  638.             break;
  639.         case WM_CLOSE:
  640.             EndDialog(hDlg, 0);
  641.             return(TRUE);
  642.             break;
  643.         default:
  644.             return(FALSE);
  645.     }
  646.     return(TRUE);
  647. }
  648. /****************************************************************************
  649.  *                                                                          *
  650.  *  FUNCTION   : OwnerComboBoxExample(hWnd, message, wParam, lParam)        *
  651.  *                                                                          *
  652.  *  PURPOSE    : Dialog function for the dropdown list combo box with       *
  653.  *               owner-draw.                                                *
  654.  *                                                                          *
  655.  ****************************************************************************/
  656. BOOL APIENTRY OwnerComboBoxExample (
  657.     HWND hDlg,
  658.     UINT message,
  659.     UINT wParam,
  660.     LONG lParam)
  661. {
  662.     LPDRAWITEMSTRUCT    lpdis;
  663.     LPMEASUREITEMSTRUCT lpmis;
  664.     switch (message){
  665.         case WM_COMMAND:
  666.             switch (LOWORD(wParam)){
  667.                 case IDOK:
  668.                    EndDialog (hDlg, 0);
  669.                    return(TRUE);
  670.                    break;
  671.                 /* Clicking any of these buttons adds the corresponding color
  672.                  * to the combo box. The application-supplied data is the RGB
  673.                  * value for the color to be drawn in the listbox.
  674.                  */
  675.                 case ID_BLACK:
  676.                    SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
  677.                                 CB_ADDSTRING,
  678.                                 0,
  679.                                 RGB (0,0,0));
  680.                    return(TRUE);
  681.                    break;
  682.                 case ID_RED:
  683.                    SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
  684.                                 CB_ADDSTRING,
  685.                                 0,
  686.                                 RGB (255,0,0));
  687.                    return(TRUE);
  688.                    break;
  689.                 case ID_BLUE:
  690.                    SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
  691.                                 CB_ADDSTRING,
  692.                                 0,
  693.                                 RGB (0,0,255));
  694.                    return(TRUE);
  695.                    break;
  696.                 case ID_GREEN:
  697.                    SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
  698.                                 CB_ADDSTRING,
  699.                                 0,
  700.                                 RGB (0,255,0));
  701.                    return(TRUE);
  702.                    break;
  703.                 default:
  704.                    return(TRUE);
  705.                    break;
  706.             }
  707.         case WM_DRAWITEM:
  708.             /* Get pointer to the DRAWITEMSTRUCT */
  709.             lpdis = (LPDRAWITEMSTRUCT)lParam;
  710.             if (lpdis->itemID == -1){
  711.                 /* We have a request to draw an item in the combo box, yet there
  712.                  * are no combo box items. This is sent when the user TABS into
  713.                  * an empty combo box or an empty combo box gets the focus. We
  714.                  * have to indicate (somehow) that this owner-draw combo box has
  715.                  * the focus. We do it in response to this message. Note that
  716.                  * lpdis->itemData field would be invalid in this instance so
  717.                  * we can't allow it to fall into our standard routines.
  718.                  */
  719.                 HandleFocusState(lpdis, -2);
  720.             }
  721.             else
  722.             {
  723.                 switch (lpdis->itemAction)
  724.                 {
  725.                         case ODA_DRAWENTIRE:
  726.                                 DrawEntireItem(lpdis, -4);
  727.                                 break;
  728.                         case ODA_SELECT:
  729.                                 HandleSelectionState(lpdis, 0);
  730.                                 break;
  731.                         case ODA_FOCUS:
  732.                                 HandleFocusState(lpdis, -2);
  733.                                 break;
  734.                 }
  735.             }
  736.             /* Return TRUE meaning that we processed this message. */
  737.             return(TRUE);
  738.             break;
  739.         case WM_MEASUREITEM:
  740.             lpmis = (LPMEASUREITEMSTRUCT)lParam;
  741.             /* All the items are the same height since the combo box is
  742.              * CBS_OWNERDRAWFIXED
  743.              */
  744.             if (lpmis->itemID == -1){
  745.                 /* If -1 for item, then we are setting the height of the
  746.                  * always visible static item part of the dropdown combo box.
  747.                  */
  748.                 lpmis->itemHeight = 25;
  749.                 return(TRUE);
  750.             }
  751.             lpmis->itemHeight = 30;
  752.             break;
  753.         case WM_CLOSE:
  754.             EndDialog(hDlg, 0);
  755.             return(TRUE);
  756.             break;
  757.         default:
  758.             return(FALSE);
  759.     }
  760.     return(TRUE);
  761. }