当你点击组合框的“下拉列表”按钮时,下拉列表框会出现在下面组合框,除非下面没有足够的空间,在这种情况下列表框会出现
现在我想知道是否有可能强制lisbox在组合框上方出现,即使下面有足够的空间。
插图
当我点击组合框时,我希望“下拉”列表框始终显示在左侧屏幕副本的上方。
答案 0 :(得分:3)
一切皆有可能,您无需“从头开始”实施控制。
首先,您可以继承ComboBox的ListBox部分以完全控制它,如MSDN中所述。您可以使用类向导创建一个派生自CListBox的类。您只需要在其中实现WM_WINPOSITIONCHANGING
处理程序:
void CTopListBox::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
CListBox::OnWindowPosChanging(lpwndpos);
if ((lpwndpos->flags & SWP_NOMOVE) == 0)
{
lpwndpos->y -= lpwndpos->cy + 30;
}
}
在这里,为简单起见,我将箱子向上移动(高度+30)。您可以获得ComboBox的高度而不是我的30
。
然后在对话框类中声明一个成员变量:
CTopListBox m_listbox;
并将其子类化为:
HBRUSH CMFCDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (nCtlColor == CTLCOLOR_LISTBOX)
{
if (m_listbox.GetSafeHwnd() == NULL)
{
m_listbox.SubclassWindow(pWnd->GetSafeHwnd());
CRect r;
m_listbox.GetWindowRect(r);
m_listbox.MoveWindow(r);
}
}
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
请注意,我在那里打电话给m_listbox.MoveWindow(r)
;它是必需的,因为该列表框的第一个WM_CONTROLCOLOR
消息在它被定位后出现,所以它第一次下降而不是向上。
免责声明:这不是一个非常干净的解决方案,因为如果你启用了Windows动画,你会看到列表从上到下展开。
或者,您应该能够“欺骗”组合框,使其太靠近屏幕底部;然后它会自行消失。我把它作为练习留给读者:)
答案 1 :(得分:1)
这是相对容易的,除非组合框有"滑开"影响。如果您将下拉列表框移到顶部,并且组合幻灯片从上到下打开,则看起来很奇怪。所以你必须禁用动画或反转它。
在此功能中,我在AnimateWindow
中呼叫OnWindowPosChanging
,它似乎不会导致任何问题,但我不是100%肯定它!
class CComboBox_ListBox : public CListBox
{
public:
CWnd *comboBox;
void OnWindowPosChanging(WINDOWPOS *wndpos)
{
CListBox::OnWindowPosChanging(wndpos);
if (comboBox && wndpos->cx && wndpos->cy && !(wndpos->flags & SWP_NOMOVE))
{
CRect rc;
comboBox->GetWindowRect(&rc);
//if listbox is at the bottom...
if (wndpos->y > rc.top) {
//if there is enough room for listbox to go on top...
if (rc.top > wndpos->cy) {
wndpos->y = rc.top - wndpos->cy;
BOOL animation;
SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &animation, 0);
//if combobox slides open...
if (animation) {
//we have to set the x coordinate otherwise listbox
//is in the wrong place when parent window moves
SetWindowPos(0, wndpos->x, wndpos->y, 0, 0,
SWP_NOSENDCHANGING | SWP_HIDEWINDOW | SWP_NOSIZE);
AnimateWindow(100, AW_VER_NEGATIVE);
}
}
}
}
}
DECLARE_MESSAGE_MAP()
};
用法:
COMBOBOXINFO ci = { sizeof(COMBOBOXINFO) };
comboBox.GetComboBoxInfo(&ci);
CComboBox_ListBox *listBox = new CComboBox_ListBox;
listBox->comboBox = &comboBox;
listBox->SubclassWindow(ci.hwndList);
此外,您可以使用SetMinVisibleItems
来降低列表框高度,并确保下拉列表最适合。