home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / d / d020_1_4 / 6.ddi / OWNCOMBO / OWNCOMBO.C next >
Encoding:
C/C++ Source or Header  |  1990-06-01  |  25.7 KB  |  870 lines

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