15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


ComboBox List height

GoroKhM1 -- gorokhm1@SMTP.ATG-NET.COM
Friday, September 13, 1996

     Environment: Win95, VC4.2
     
     Question: How to set ComboBox List height?
               (for CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED)
     
     My app has a modeless dialog based on a dialog template 
     IDD_MY_DLG. For customization in CMyDialog::OnCreate() 
     I add different dialog items. Item's style and position I 
     take from one of separate dialog templates IDD_MY_ITEMS.
     
     No problems with CStatic and CEdit items. My ComboBox
     is placed and sized correctly too, except the List Height.
     It is ZERO. Moreover, it's working but not visible, the only
     solid line under static portion.
     
     Docs for CComboBox::MeasureItem() says:
     
       By default, this member function does nothing. Override 
       this member function and fill in the MEASUREITEMSTRUCT 
       structure to inform Windows of the dimensions of the 
       list box in the combo box.
     
     I did it with no luck.
     
     The ComboBox is subclassed in DDX_Control.
     
     Here is my code. What's wrong in it? 
     
     class CMyDialog : public CDialog
     {
       ...
       CMyComboBox m_Combo;
       ...
     }
     
     int CMyDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
     {
       if (CDialog::OnCreate(lpCreateStruct) == -1)
         return -1;
        
       // TODO: Add your specialized creation code here
       CDialog dlg;
       dlg.Create(IDD_MY_ITEMS);
     
       CreateControlFromDlg(&dlg, IDC_MY_COMBO,  &m_Combo);
     
       dlg.DestroyWindow();
       return 0;
     } // CMyDialog::OnCreate()
     
     #define COMBO_HEIGHT 18
     
     void CMyDialog::CreateControlFromDlg(CDialog* pDlg, UINT nID, 
                                          CSComboBox* pCombo)
     {
       ASSERT(pDlg);
       ASSERT(pCombo);
     
       CSComboBox* pDlgCombo = (CSComboBox*)pDlg->GetDlgItem(nID);
       ASSERT(pDlgCombo);
     
       // That I found while debugging...
       // 0x50010313 = pDlgCombo->GetStyle();
       // 0x40000000 = WS_CHILD 
       // 0x10000000 = WS_VISIBLE
       // 0x00010000 = WS_MAXIMIZEBOX
       // 0x00000100 = CBS_SORT
       // 0x00000200 = CBS_HASSTRINGS
       // 0x00000010 = CBS_OWNERDRAWFIXED
       // 0x00000003 = CBS_DROPDOWNLIST
     
       // 0x00000004 = pDlgCombo->GetExStyle();
       // 0x00000004 = WS_EX_NOPARENTNOTIFY
     
       WINDOWPLACEMENT wp;
       pDlgCombo->GetWindowPlacement(&wp);
     
       if (!pCombo->Create(pDlgCombo->GetStyle(), 
                           wp.rcNormalPosition, 
                           this, 
                           nID))
         return;
       pCombo->ModifyStyleEx(0, pDlgCombo->GetExStyle());
       pCombo->SetFont(...);
       pCombo->SetItemHeight(-1, COMBO_HEIGHT); // static portion
       pCombo->SetItemHeight( 0, COMBO_HEIGHT); // each item in a drop list
     } // CMyDialog::CreateControlFromDlg()
     
     Thanks for help.
     
     Mark 
     




murugesh@mail.cswl.com
Sunday, September 15, 1996

     Hai
     
     Try this
     
     void CMyDialog::CreateControlFromDlg(CDialog* pDlg, UINT nID, 
     CSComboBox* pCombo)
     {
     ASSERT(pDlg);
     ASSERT(pCombo);
     
     CSComboBox* pDlgCombo = (CSComboBox*)pDlg->GetDlgItem(nID); 
     ASSERT(pDlgCombo);
     
     // That I found while debugging...
     // 0x50010313 = pDlgCombo->GetStyle(); // 0x40000000 = WS_CHILD 
     // 0x10000000 = WS_VISIBLE
     // 0x00010000 = WS_MAXIMIZEBOX
     // 0x00000100 = CBS_SORT
     // 0x00000200 = CBS_HASSTRINGS
     // 0x00000010 = CBS_OWNERDRAWFIXED
     // 0x00000003 = CBS_DROPDOWNLIST
     
     // 0x00000004 = pDlgCombo->GetExStyle(); // 0x00000004 = 
     WS_EX_NOPARENTNOTIFY
     
     WINDOWPLACEMENT wp;
     CRect rect;
     pDlgCombo->GetWindowPlacement(&wp);
     pDlgCombo->GetWindowRect(rect);
     ScreenToClient(rect);
     
     if (!pCombo->Create(pDlgCombo->GetStyle(), 
     wp.rcNormalPosition, 
     this, 
     nID))
     return;
     pCombo->ModifyStyleEx(0, pDlgCombo->GetExStyle()); 
     pCombo->SetFont(...);
     pCombo->SetItemHeight(-1, COMBO_HEIGHT); // static portion 
     pCombo->SetItemHeight( 0, COMBO_HEIGHT); // each item in a drop list
     pCombo->MoveWindow(rect);
     
     } // CMyDialog::CreateControlFromDlg()
     


        The idea is u can set the height of the drop down listbox by calling 
either MoveWindow or SetWindowPos.


Regards
Murugesh SS
Murugesh@cswl.com
 

______________________________ Reply Separator _________________________________
Subject: ComboBox List height
Author:  mfc-l@netcom.com at internet
Date:    9/13/96 5:26 PM


     Environment: Win95, VC4.2
     
     Question: How to set ComboBox List height?
               (for CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED)
     
     My app has a modeless dialog based on a dialog template 
     IDD_MY_DLG. For customization in CMyDialog::OnCreate() 
     I add different dialog items. Item's style and position I 
     take from one of separate dialog templates IDD_MY_ITEMS.
     
     No problems with CStatic and CEdit items. My ComboBox
     is placed and sized correctly too, except the List Height. 
     It is ZERO. Moreover, it's working but not visible, the only 
     solid line under static portion.
     
     Docs for CComboBox::MeasureItem() says:
     
       By default, this member function does nothing. Override 
       this member function and fill in the MEASUREITEMSTRUCT 
       structure to inform Windows of the dimensions of the 
       list box in the combo box.
     
     I did it with no luck.
     
     The ComboBox is subclassed in DDX_Control.
     
     Here is my code. What's wrong in it? 
     
     class CMyDialog : public CDialog
     {
       ...
       CMyComboBox m_Combo;
       ...
     }
     
     int CMyDialog::OnCreate(LPCREATESTRUCT lpCreateStruct) 
     {
       if (CDialog::OnCreate(lpCreateStruct) == -1)
         return -1;
     
       // TODO: Add your specialized creation code here 
       CDialog dlg;
       dlg.Create(IDD_MY_ITEMS);
     
       CreateControlFromDlg(&dlg, IDC_MY_COMBO,  &m_Combo);
     
       dlg.DestroyWindow();
       return 0;
     } // CMyDialog::OnCreate()
     
     #define COMBO_HEIGHT 18
     
     void CMyDialog::CreateControlFromDlg(CDialog* pDlg, UINT nID, 
                                          CSComboBox* pCombo)
     {
       ASSERT(pDlg);
       ASSERT(pCombo);
     
       CSComboBox* pDlgCombo = (CSComboBox*)pDlg->GetDlgItem(nID); 
       ASSERT(pDlgCombo);
     
       // That I found while debugging...
       // 0x50010313 = pDlgCombo->GetStyle(); 
       // 0x40000000 = WS_CHILD 
       // 0x10000000 = WS_VISIBLE
       // 0x00010000 = WS_MAXIMIZEBOX
       // 0x00000100 = CBS_SORT
       // 0x00000200 = CBS_HASSTRINGS
       // 0x00000010 = CBS_OWNERDRAWFIXED
       // 0x00000003 = CBS_DROPDOWNLIST
     
       // 0x00000004 = pDlgCombo->GetExStyle(); 
       // 0x00000004 = WS_EX_NOPARENTNOTIFY
     
       WINDOWPLACEMENT wp;
       CRect rect;
       pDlgCombo->GetWindowPlacement(&wp);
     
       if (!pCombo->Create(pDlgCombo->GetStyle(), 
                           wp.rcNormalPosition, 
                           this, 
                           nID))
         return;
       pCombo->ModifyStyleEx(0, pDlgCombo->GetExStyle()); 
       pCombo->SetFont(...);
       pCombo->SetItemHeight(-1, COMBO_HEIGHT); // static portion 
       pCombo->SetItemHeight( 0, COMBO_HEIGHT); // each item in a drop list
       
     } // CMyDialog::CreateControlFromDlg()
     
     Thanks for help.
     
     Mark 
     
     




ktm@ormec.com
Monday, September 16, 1996

[Mini-digest: 2 responses]

Mark,  wrote:
> Environment: Win95, VC4.2
> 
> Question: How to set ComboBox List height?
> (for CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED)
> 
> [...]
> 
> No problems with CStatic and CEdit items. My ComboBox is placed 
> and sized correctly too, except the List Height. It is ZERO. 

Matt Kimberling,  also asks:
>How can I control the vertical size of the drop down for a Combo Box? 

This also came up at the beginning of the month - check the archives,
searching for the header "Pulling Hair over CComboBox sizing". As other
people have stated, you can use MoveWindow to set the size of the drop 
down. If you're trying to set the drop-down to show a specific number of
lines, the following function may be useful:

const int LINECOUNT = 8;        // standard # of lines
void set_DropDownSize(CComboBox& box)
/*--------------------------------------------------------------------------
 * Purpose:         Set the proper number of lines in a drop-down list or 
 *  combo box.
 * Description:     Resizes the combo box window to fit the proper number 
 *  of lines. The window must exist before calling this function.
 *  This function should be called when the combo box is created, and when
 *  the font of the combo box changes.
 *  Testing needed:
 *    OS other than Windows '95, where SM_CYBORDER might be appropriate
 *    owner-draw variable height combo box
 *    Subclassed combo box with horizontal scroll-bar
 * Returns:         nothing
 * Author:          KTM
 * See Also:
 *--------------------------------------------------------------------------*/
    {
    ASSERT(IsWindow(box));  // Window must exist or SetWindowPos won't work

    CRect cbSize;       // current size of combo box
    int Height;         // new height for combo box

    box.GetClientRect(cbSize);
    Height = box.GetItemHeight(-1);  // start with size of the edit-box portion
    Height += box.GetItemHeight(0) * LINECOUNT;  // add height of lines of text
      // this assumes that all lines are the same height, and is wrong for
      // CBS_OWNERDRAWVARIABLE

    // Note: The use of SM_CYEDGE assumes that we're using Windows '95
    //       SM_CYBORDER is appropriate for NT 3.51
    //       not sure what to use for NT 4.0 or Win 3.x + Win32s 1.3c
    // Now add on the height of the border of the edit box
    Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges

    // The height of the border of the drop-down box
    Height += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges

    // now set the size of the window
    box.SetWindowPos(NULL,              // not relative to any other windows
        0, 0,                           // TopLeft corner doesn't change
        cbSize.right, Height,           // existing width, new height
        SWP_NOMOVE | SWP_NOZORDER       // don't move box or change z-ordering.
        );
    }
-----From: "GoroKhM1" 

Thanks for response and help. The function  
suggested is working fine and the problem is solved.
The trick was:
  pCombo->SetWindowPos(
    NULL,
    0, 0,
    iWidth, iHeight,  // new drop-down list size
    SWP_NOMOVE | SWP_NOZORDER);

I have a question. Assume I have a combo box in a resource file:

  COMBOBOX IDC_MY_COMBO,40,50,60,70,CBS_DROPDOWNLIST | 
           CBS_OWNERDRAWFIXED | CBS_SORT | CBS_HASSTRINGS | 
           WS_VSCROLL | WS_TABSTOP

The numbers in the resource mean the following:
  40,50 - left/upper corner coord.
  60    - width of static and drop-down list portion
  70    - height of drop-down list portion

The height of static portion isn't defined at all and I think is 
calculated depending on font size in creation time.

Assume the dialog is created and pCombo is a pointer to that control.

1. pCombo->GetClientRect() returns the size of static portion.
2. pCombo->GetWindowRect() returns the location and size of static portion.

How to find the value "height of drop-down list portion" i.e. "70" ?

Mark








| Вернуться в корень Архива |