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