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