爱丽小屋十色眼影盘:关于CListBox和CComboBox修改窗口Style的问题
来源:百度文库 编辑:中财网 时间:2024/04/28 07:22:29
在界面编程中,经常遇到修改CListBox和CComboBox窗口式样(style)的问题.可恼的时,一旦窗口创建后(Creation),没有办法可以修改窗口式样.也就是说,ModifyStyle()和SetWindowLong()都不起作用(但调用会成功).如下面的代码:
// you can not change the style of a list box dynamically, after creation.
A. Use ModifyStyle()
m_ListBox.ModifyStyle(0,WS_HSCROLL|LBS_MULTICOLUMN);
B. Use SetWindowLong()
long style=GetWindowLong(m_ListBox,GWL_STYLE);
style|=LBS_MULTICOLUMN;
style|=WS_HSCROLL;
SetWindowLong(m_ListBox1,GWL_STYLE,style);
而在模式对话框运用中,系统是不产生OnCreate()消息的,所以就没机会修改窗口式样了.
1. 关于"CListBox"的多列功能:
当使用该功能时”垂直滚动”将不起作用,这是因为第一列后的列要等前一列的行用完后才开始使用,这很象报纸上的”栏”,有时也叫”蛇形列(snaking column)”.如果窗口只有一行, 多列显示的list象一个横向list.除非一定要这样做,不如用TabStop功能.
2. 关于"CComboBox"中list的多列功能:
CComboBox其实有3个窗口,分别为combo,edit,list.要得到edit和list的窗口句柄不容易可以参考”http://support.microsoft.com/default.aspx?scid=kb;en-us;Q174667”. 在”.net”下可以使用GetComboBoxInfo(),可惜VC++6.0下无这个函数.
// .net
//typedef struct ComboBoxInfo_tag
//{
//int cbSize;
//RECT rcItem;
//RECT rcButton;
//int stateButton;
//HWND hwndCombo;
//HWND hwndEdit;
//HWND hwndList; // That's what I'm interested in....
//} COMBOBOXINFO,*PCOMBOBOXINFO;
//[DllImport("user32")] public static extern bool
//BOOL GetComboBoxInfo(HWND hwndCombo,COMBOBOXINFO& info);
// COMBOBOXINFO info;
// BOOL bl=GetComboBoxInfo(this->m_hWnd, info);
CComboBox中的listbox叫”COMBOLBOX”,不过跟CLlistBox好像一样(?).
3. 下面说一下对CComboBox中的listbox修改式样的方法:
a. 新建一个CSuperCombo类.响应OnCtlColor(),OnDestroy()和OnDropdown():
HBRUSH CSuperComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here
if (nCtlColor == CTLCOLOR_LISTBOX)
{//ListBox control,It is a COMBOLBOX,not a normal listbox.Besides,
//It is not a child window of combobox.
if (m_listbox.GetSafeHwnd() == NULL)
{
m_listbox.SubclassWindow(pWnd->GetSafeHwnd());
//too later to change the sytle!
m_listbox.ModifyStyle(0,WS_HSCROLL|LBS_MULTICOLUMN);
//you have to create a new list box.
//see "Dynamically re-creating a list box" from “code project”.
RecreateComboLBox(&m_listbox); }
}
//
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
void CSuperComboBox::OnDestroy()
{
if (m_listbox.GetSafeHwnd() != NULL) m_listbox.UnsubclassWindow();
CComboBox::OnDestroy();
}
void CSuperComboBox::OnDropdown()
{
// TODO: Add your control notification handler code here
if(IsWindow(m_listbox) && !GetDroppedState())
{
m_listbox.ShowWindow(SW_NORMAL);
}
}
还要一个函数来重新创建一个listbox(CSuperList类):
BOOL CSuperComboBox::RecreateComboLBox(CListBox* pList, LPVOID lpParam)
{
CWnd* pParent = GetParent();//父窗口是对话框 dlg
// get current attributes
DWORD dwStyle = pList->GetStyle();
DWORD dwStyleEx = pList->GetExStyle();
CRect rc;
pList->GetWindowRect(&rc);
pParent->ScreenToClient(&rc); // 到客户坐标
UINT nID = IDC_COMBO;
CFont* pFont = pList->GetFont();
// create the new list box and copy the old list box items
// into a new listbox along with each item's data, and selection state
CListBox listNew;//这是临时对象
// 创建一个你需要式样的listbox
if (! listNew.CreateEx(dwStyleEx, _T("COMBOLBOX"), _T(""), dwStyle,
rc, pParent, nID, lpParam))
return FALSE;
listNew.SetFont(pFont);
int nNumItems = pList->GetCount();
BOOL bMultiSel = (dwStyle & LBS_MULTIPLESEL || dwStyle & LBS_EXTENDEDSEL);
for (int n = 0; n < nNumItems; n++)
{ //所有项
CString sText;
pList->GetText(n, sText);
int nNewIndex = listNew.AddString(sText);
listNew.SetItemData(nNewIndex, pList->GetItemData(n));
if (bMultiSel && pList->GetSel(n)) listNew.SetSel(nNewIndex);
}
if (! bMultiSel)
{// 所有选择项
int nCurSel = pList->GetCurSel();
if (nCurSel != -1)
{
CString sSelText;
// get the selection in the old list
pList->GetText(nCurSel, sSelText);
// now find and select it in the new list
listNew.SetCurSel(listNew.FindStringExact(-1, sSelText));
}
}
// destroy the existing window, then attach the new one
pList->DestroyWindow();
HWND hwnd = listNew.Detach();
pList->Attach(hwnd);
//
return TRUE;
}
b. 经过上步后,还要新建一个”CSuperList”类,否则listbox不会响应鼠标,要响应OnLButtonDown(),OnMouseMove():
void CSuperList::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
BOOL bOutside;
UINT idx=ItemFromPoint(point,bOutside);
CString txt;
GetText(idx,txt);
ShowWindow(SW_HIDE);
CMyComboDlg* pCmoboTest=(CMyComboDlg*)GetParent();
if(idx>=0)
{// 置ComboBox的Edit
pCmoboTest->m_ComboTest.SetWindowText(txt);
pCmoboTest->m_ComboTest.SetEditSel(0,-1);
pCmoboTest->m_ComboTest.SetFocus();
}
// CListBox::OnLButtonDown(nFlags, point);
}
void CSuperList::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
BOOL bOutside;
UINT idx=ItemFromPoint(point,bOutside);
// afxDump <
if(idx>=0) SetCurSel(idx);
CListBox::OnMouseMove(nFlags, point);
}
注意:
class CSuperComboBox : public CComboBox
{…
CSuperList m_listbox;
..
};
4. 结果:
缺图
源码见"schlafenhamster"发布的csdn资源