关于CListBox和CComboBox修改窗口Style的问题
来源:互联网 发布:上海市行知小学照片 编辑:程序博客网 时间:2024/05/18 00:03
在界面编程中,经常遇到修改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 <<idx <<"/n";
if(idx>=0) SetCurSel(idx);
CListBox::OnMouseMove(nFlags, point);
}
注意:
class CSuperComboBox : public CComboBox
{…
CSuperList m_listbox;
..
};
4. 结果:
缺图
源码见"schlafenhamster"发布的csdn资源
- 关于CListBox和CComboBox修改窗口Style的问题
- CComboBox获取其CEdit和CListBox的另一种方法
- CListBox的CBN_SELCHANGE CCOMboBox的LBN_SELCHANGE
- CComboBox And CListBox ResetContent
- CListCtrl 和 CListBox的设置选中问题
- CListCtrl 和 CListBox的设置选中问题
- 关于修改窗体风格Style引起的程序问题
- 关于mfc重载CListbox控件出现参数错误的问题
- 修改窗口STYLE属性
- 关于 MFC 创建的窗口style
- 关于CLISTBOX 的另类操作
- 解决CListBox 响应Shift和Ctrl键盘的问题
- 关于VC6中基于对话框的程序,往Combox 添加一个CComboBox变量,然后程序编译运行,窗口不出现的问题
- CListBox的AddString 排序问题
- CListBox的AddString 排序问题
- 关于修改Matlab2014a菜单栏和命令窗口字体大小问题
- 关于CComboBox的自绘
- 一些关于style和attr的使用问题
- Java中代理模式的实现步骤
- 可以登录了
- 页面自动刷新
- 哪有一天不等你啊!
- PKU 3639 Exchange Rates
- 关于CListBox和CComboBox修改窗口Style的问题
- 从服务器上拿数据下来.
- matlab并行计算中worker与cpu core的关系
- fork and exec
- asp.net日期格式化
- 跟老老紫竹学Java - 短消息系统演示和下载地址
- string class的实现
- 哇塞,CSDN有回来啦,可喜可贺啊
- PKU 3070 Fibonacci