VC的Bug? ComboBox为什么不显示内容? 可能是你没有打开下拉框吧?选中combobox,移动鼠标到它的下拉按钮,光标变成上下箭头时点击出来下拉框后将它拉大。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 救命拉。好奇怪,在资源编辑器中按Ctrl+T测试还是好的,编译执行就完了。@_@ 5555555555555 救命拉。好奇怪,在资源编辑器中按Ctrl+T测试还是好的,编译执行就完了。@_@ 5555555555555 如果不是做研究的话,就手工加把。在hwndScan = CreateDialog (hInstance, szAppName, 0, NULL) ;后添加如下代码:HWND hCMB = GetDlgItem(hwndscan,IDC_COMBO1);if (hCMB == NULL){ char szBuff[256]={0}; wsprintf(szBuff,"Errror code:%d ",GetLastError()); MessageBox (NULL, szBuff, NULL, MB_ICONERROR) ; return 1;}SendMessage(hCMB,CB_ADDSTRING,0,(LONG)"AAA"); 呵呵,这由于只有在MFC编程中,在模版中加入ComBox或ListBox项才有效。如果用SDK,这样的行:SIMPLE_SCAN DLGINITBEGIN IDC_COMBO1, 0x403, 5, 00x6554, 0x7478, "\000" IDC_COMBO1, 0x403, 22, 00x6c42, 0x6361, 0x206b, 0x6e61, 0x2064, 0x6857, 0x7469, 0x2065, 0x6850, 0x746f, 0x006f, IDC_COMBO1, 0x403, 17, 00x7247, 0x7961, 0x4320, 0x6c6f, 0x726f, 0x5020, 0x6f68, 0x6f74, "\000" IDC_COMBO1, 0x403, 19, 00x3834, 0x422d, 0x7469, 0x4320, 0x6c6f, 0x726f, 0x5020, 0x6f68, 0x6f74, "\000" 0END是被忽略的。在MFC中,CDialog类在显示前调用了OnInitDialog()而它又调用了CWnd::ExecuteDlgInit( LPCTSTR lpszResourceName )/CWnd::ExecuteDlgInit( LPVOID lpResource )函数(实际上ExecuteDlgInit( LPCTSTR lpszResourceName )在内部取得了模版指针后调用了CWnd::ExecuteDlgInit( LPVOID lpResource )):而在ExecuteDlgInit()中有下列语句:BOOL CWnd::ExecuteDlgInit(LPVOID lpResource){ BOOL bSuccess = TRUE; if (lpResource != NULL) { UNALIGNED WORD* lpnRes = (WORD*)lpResource; while (bSuccess && *lpnRes != 0) { WORD nIDC = *lpnRes++; WORD nMsg = *lpnRes++; DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++; // In Win32 the WM_ messages have changed. They have // to be translated from the 32-bit values to 16-bit // values here. #define WIN16_LB_ADDSTRING 0x0401 #define WIN16_CB_ADDSTRING 0x0403 #define AFX_CB_ADDSTRING 0x1234 // unfortunately, WIN16_CB_ADDSTRING == CBEM_INSERTITEM if (nMsg == AFX_CB_ADDSTRING) nMsg = CBEM_INSERTITEM; else if (nMsg == WIN16_LB_ADDSTRING) nMsg = LB_ADDSTRING; else if (nMsg == WIN16_CB_ADDSTRING) nMsg = CB_ADDSTRING; // check for invalid/unknown message types#ifdef _AFX_NO_OCC_SUPPORT ASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING || nMsg == CBEM_INSERTITEM);#else ASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING || nMsg == CBEM_INSERTITEM || nMsg == WM_OCC_LOADFROMSTREAM || nMsg == WM_OCC_LOADFROMSTREAM_EX || nMsg == WM_OCC_LOADFROMSTORAGE || nMsg == WM_OCC_LOADFROMSTORAGE_EX || nMsg == WM_OCC_INITNEW);#endif#ifdef _DEBUG // For AddStrings, the count must exactly delimit the // string, including the NULL termination. This check // will not catch all mal-formed ADDSTRINGs, but will // catch some. if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING || nMsg == CBEM_INSERTITEM) ASSERT(*((LPBYTE)lpnRes + (UINT)dwLen - 1) == 0);#endif if (nMsg == CBEM_INSERTITEM) { USES_CONVERSION; COMBOBOXEXITEM item; item.mask = CBEIF_TEXT; item.iItem = -1; item.pszText = A2T(LPSTR(lpnRes)); if (::SendDlgItemMessage(m_hWnd, nIDC, nMsg, 0, (LPARAM) &item) == -1) bSuccess = FALSE; }#ifndef _AFX_NO_OCC_SUPPORT else if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING)#endif // !_AFX_NO_OCC_SUPPORT { // List/Combobox returns -1 for error if (::SendDlgItemMessageA(m_hWnd, nIDC, nMsg, 0, (LPARAM) lpnRes) == -1) bSuccess = FALSE; } // skip past data lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen); } } // send update message to all controls after all other siblings loaded if (bSuccess) SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, FALSE, FALSE); return bSuccess;}很明显,ExecuteDlgInit()函数的目的就是处理最上面那些行,为对话框中的ListBox,ComBox添加子项的。如果要在SDK中获得子项的话,最好仿造以上代码,自己在WM_INITDIALOG中写入类似的代码了,不过,还是直接在 WM_INITDIALOG中手工添加Item,不通过模版来做比较简单。 说明一下: 我的意思是指SDK的CreateDialog根本不管对话框模版中为ListBox,Combox添加Item的部分,这个新功能是MFC CDialog添加的,从上面的代码可以看出,CDialog在响应WM_INITDIALOG消息时,处理模版,查找0x0401,0x0403,0x1234 WORD值,读出相应的Item参数插入对应的ListBox,Combox。如果CreateDialog已经处理了,那这些就不必要了。 谢谢In355Hz,好像是这样的。但是奇怪的是,我刚开始的时候,用SDK程序也自动加载了这些字符串资源。后来当我在调整完界面后就突然不行了。我只改动了控件的位置,没有修改字符串部分,所以觉得很奇怪。也可能SDK里也有加载资源字符串的功能,我不小心把它del了。请大家再想一想,我只是想搞懂为什么。 To : zero100感谢你的热心,不过我又发现一个问题为什么我把代码放入对话框的WM_INITDIALOG消息中处理就不显示,放入你说的CreateDialog下面就可以。是不是由于对话框重绘的问题?可以通过调用API函数解决吗?如何解决? 你的消息处理不会代WM_INITDIALOG。只到了WM_CREATE;在处理WM_CREATE的时候,因为还没有创建COMBOBOX,用GetDlgItem得到的HWND==NULL;所以就只好在CreateDialog后面加落,只有实战,没有理论的 理论我来说吧:使用CreateDialog()来创建对话,它默认在获取WM_OINITDIALOG消息时调用函数的第四个参数就是DialogProc()来处理对话初始化,而不是用窗口消息处理WndProc;所以要如下使用:BOOL CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){ if(uMsg == WM_INITDIALOG) { //Add ComboBox Item here return TRUE; } return FALSE;} hwndScan = CreateDialog (hInstance, szAppName, 0, DialogProc) ; 此外,试了好几种SDK创建Dialog的方法(包括用完全自动生成的模版,没经过任何手工改动),都不能自动将ComboBox的Item加进去,能不能问一下你原来是怎么做的? 我就是忘了啊,因为一开始很正常,所以我就没有备份,直接在Ultraedit中修改*.rc文件,突然,噩耗降临。 :-( to In355Hz:你好扎实,交个朋友吧,我刚刚开始真正的程序员生活,所以很多不懂。我在深圳宝安区工作。愿意交个朋友吗?先不急着给你分,再问两个问题再说 :)hahahahahahahaha....... to In355Hz:我采用你说的方法试了,不过没有任何作用。hwndScan = CreateDialog (hInstance, szAppName, 0, DialogProc) ;调试发现程序根本不进入DialogProc函数。是不是这种调用有什么限制?比如我的对话框使用资源编辑器建立,并且作为程序的主窗口就不行了? to In355Hz:我在RC文件中指明了对话框用的窗口类,所以不能了。谢谢你,愿意交个朋友吗? to In355Hz: 你的说法有问题! Robin_Hood_POT的例子中的CreateDialog的DlgProc是NULL来的,即使是有,也不会执行到那里的,原因是rc文件dialog的声明中有一句: CLASS "Simple_Scan"。 你调试的话,可以发现根本不会产生WM_INITDIALOG的消息,而是产生一个WM_CREATE的消息。 这是由窗口类决定的。再试取消前面的wndclass注册,CreateDialog就会返回NULL。GetLastError() 会告诉你原因的。 敲的真累,有事OICQ上说: zero100;604744 我不能上OICQ, @_@ 55555555555555OK,晚上给分 你打开资源文件,将ComboBox的选项找到然后手工编辑它的大小。你这个bug不大,我有一次遇见ComboBox的下拉按钮居然在左边,ListBox里面的数据右对齐。呵呵 对!在SDK中有加载字符串的函数: ComboBox_AddString(hwnd,pszText),其中hwnd是此控件的句柄,pszText是一个TCHAR的字符串,这样,就可以了。祝你好运!!! to bigsail:不行吧,编辑大小能让ComboBox重新显示RC里定义的字符串吗?两者好像没有什么关系啊!to codica:我就是不想在SDK中用这些函数才使用RC编辑对话框模版的,唉,我希望代码量能够尽量小 还是zero100对,修改了窗口类,的确不产生WM_INITDIALOG消息,惭愧惭愧。 数据库的com_error错误 VC++2005中如何正确运行程序步骤? CFileDialog非模态显示 如何读文本,按照16进制串口进行发送,急,多谢! 关于 Transparent Overlay Key Color的问题 ,100分相送 关于 SQL 的datetime 在VC++中转换成 CString 一个基础性的问题, 在线等候 help:那有《Visual C++高级界面制作百例》源码下载? 高分请教:局域网中的dll问题 NTFS格式向FAT32转换 谁能推荐本学习VC SDK编程的书,能马上下载的?及具体的网址 COM程序如何与标准的Windows Exe程序通信?
好奇怪,在资源编辑器中按Ctrl+T测试还是好的,编译执行就完了。
@_@ 5555555555555
好奇怪,在资源编辑器中按Ctrl+T测试还是好的,编译执行就完了。
@_@ 5555555555555
在hwndScan = CreateDialog (hInstance, szAppName, 0, NULL) ;后添加如下代码:HWND hCMB = GetDlgItem(hwndscan,IDC_COMBO1);
if (hCMB == NULL)
{
char szBuff[256]={0};
wsprintf(szBuff,"Errror code:%d ",GetLastError());
MessageBox (NULL, szBuff, NULL, MB_ICONERROR) ;
return 1;
}
SendMessage(hCMB,CB_ADDSTRING,0,(LONG)"AAA");
如果用SDK,这样的行:SIMPLE_SCAN DLGINIT
BEGIN
IDC_COMBO1, 0x403, 5, 0
0x6554, 0x7478, "\000"
IDC_COMBO1, 0x403, 22, 0
0x6c42, 0x6361, 0x206b, 0x6e61, 0x2064, 0x6857, 0x7469, 0x2065, 0x6850,
0x746f, 0x006f,
IDC_COMBO1, 0x403, 17, 0
0x7247, 0x7961, 0x4320, 0x6c6f, 0x726f, 0x5020, 0x6f68, 0x6f74, "\000"
IDC_COMBO1, 0x403, 19, 0
0x3834, 0x422d, 0x7469, 0x4320, 0x6c6f, 0x726f, 0x5020, 0x6f68, 0x6f74,
"\000"
0
END
是被忽略的。在MFC中,CDialog类在显示前调用了OnInitDialog()
而它又调用了CWnd::ExecuteDlgInit( LPCTSTR lpszResourceName )/CWnd::ExecuteDlgInit( LPVOID lpResource )函数(实际上ExecuteDlgInit( LPCTSTR lpszResourceName )在内部取得了模版指针后调用了CWnd::ExecuteDlgInit( LPVOID lpResource )):
而在ExecuteDlgInit()中有下列语句:
BOOL CWnd::ExecuteDlgInit(LPVOID lpResource)
{
BOOL bSuccess = TRUE;
if (lpResource != NULL)
{
UNALIGNED WORD* lpnRes = (WORD*)lpResource;
while (bSuccess && *lpnRes != 0)
{
WORD nIDC = *lpnRes++;
WORD nMsg = *lpnRes++;
DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++; // In Win32 the WM_ messages have changed. They have
// to be translated from the 32-bit values to 16-bit
// values here. #define WIN16_LB_ADDSTRING 0x0401
#define WIN16_CB_ADDSTRING 0x0403
#define AFX_CB_ADDSTRING 0x1234 // unfortunately, WIN16_CB_ADDSTRING == CBEM_INSERTITEM
if (nMsg == AFX_CB_ADDSTRING)
nMsg = CBEM_INSERTITEM;
else if (nMsg == WIN16_LB_ADDSTRING)
nMsg = LB_ADDSTRING;
else if (nMsg == WIN16_CB_ADDSTRING)
nMsg = CB_ADDSTRING; // check for invalid/unknown message types
#ifdef _AFX_NO_OCC_SUPPORT
ASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING ||
nMsg == CBEM_INSERTITEM);
#else
ASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING ||
nMsg == CBEM_INSERTITEM ||
nMsg == WM_OCC_LOADFROMSTREAM ||
nMsg == WM_OCC_LOADFROMSTREAM_EX ||
nMsg == WM_OCC_LOADFROMSTORAGE ||
nMsg == WM_OCC_LOADFROMSTORAGE_EX ||
nMsg == WM_OCC_INITNEW);
#endif#ifdef _DEBUG
// For AddStrings, the count must exactly delimit the
// string, including the NULL termination. This check
// will not catch all mal-formed ADDSTRINGs, but will
// catch some.
if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING || nMsg == CBEM_INSERTITEM)
ASSERT(*((LPBYTE)lpnRes + (UINT)dwLen - 1) == 0);
#endif if (nMsg == CBEM_INSERTITEM)
{
USES_CONVERSION;
COMBOBOXEXITEM item;
item.mask = CBEIF_TEXT;
item.iItem = -1;
item.pszText = A2T(LPSTR(lpnRes)); if (::SendDlgItemMessage(m_hWnd, nIDC, nMsg, 0, (LPARAM) &item) == -1)
bSuccess = FALSE;
}
#ifndef _AFX_NO_OCC_SUPPORT
else if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING)
#endif // !_AFX_NO_OCC_SUPPORT
{
// List/Combobox returns -1 for error
if (::SendDlgItemMessageA(m_hWnd, nIDC, nMsg, 0, (LPARAM) lpnRes) == -1)
bSuccess = FALSE;
}
// skip past data
lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen);
}
} // send update message to all controls after all other siblings loaded
if (bSuccess)
SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, FALSE, FALSE); return bSuccess;
}
很明显,ExecuteDlgInit()函数的目的就是处理最上面那些行,为对话框中的ListBox,ComBox添加子项的。
如果要在SDK中获得子项的话,最好仿造以上代码,自己在WM_INITDIALOG中写入类似的代码了,不过,还是直接在 WM_INITDIALOG中手工添加Item,不通过模版来做比较简单。
我的意思是指SDK的CreateDialog根本不管对话框模版中为ListBox,Combox添加Item的部分,这个新功能是MFC CDialog添加的,从上面的代码可以看出,CDialog在响应WM_INITDIALOG消息时,处理模版,查找0x0401,0x0403,0x1234 WORD值,读出相应的Item参数插入对应的ListBox,Combox。如果CreateDialog已经处理了,那这些就不必要了。
也可能SDK里也有加载资源字符串的功能,我不小心把它del了。
请大家再想一想,我只是想搞懂为什么。
感谢你的热心,不过我又发现一个问题为什么我把代码放入对话框的WM_INITDIALOG消息中处理就不显示,放入你说的CreateDialog下面就可以。是不是由于对话框重绘的问题?可以通过调用API函数解决吗?如何解决?
在处理WM_CREATE的时候,因为还没有创建COMBOBOX,用GetDlgItem得到的HWND==NULL;
所以就只好在CreateDialog后面加落,只有实战,没有理论的
使用CreateDialog()来创建对话,它默认在获取WM_OINITDIALOG消息时调用函数的第四个参数就是DialogProc()来处理对话初始化,而不是用窗口消息处理WndProc;
所以要如下使用:
BOOL CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
if(uMsg == WM_INITDIALOG) {
//Add ComboBox Item here
return TRUE;
}
return FALSE;
}
hwndScan = CreateDialog (hInstance, szAppName, 0, DialogProc) ;
你好扎实,交个朋友吧,我刚刚开始真正的程序员生活,所以很多不懂。
我在深圳宝安区工作。
愿意交个朋友吗?先不急着给你分,再问两个问题再说 :)hahahahahahahaha.......
我采用你说的方法试了,不过没有任何作用。
hwndScan = CreateDialog (hInstance, szAppName, 0, DialogProc) ;
调试发现程序根本不进入DialogProc函数。
是不是这种调用有什么限制?比如我的对话框使用资源编辑器建立,并且作为程序的主窗口就不行了?
我在RC文件中指明了对话框用的窗口类,所以不能了。谢谢你,愿意交个朋友吗?
你的说法有问题!
Robin_Hood_POT的例子中的CreateDialog的DlgProc是NULL来的,即使是有,也不会执行到那里的,原因是rc文件dialog的声明中有一句:
CLASS "Simple_Scan"。
你调试的话,可以发现根本不会产生WM_INITDIALOG的消息,而是产生一个WM_CREATE的消息。
这是由窗口类决定的。再试取消前面的wndclass注册,CreateDialog就会返回NULL。GetLastError() 会告诉你原因的。
敲的真累,有事OICQ上说:
zero100;604744
ComboBox_AddString(hwnd,pszText),其中hwnd是此控件的句柄,pszText是一个TCHAR的字符串,这样,就可以了。
祝你好运!!!
不行吧,编辑大小能让ComboBox重新显示RC里定义的字符串吗?
两者好像没有什么关系啊!to codica:
我就是不想在SDK中用这些函数才使用RC编辑对话框模版的,唉,我希望代码量能够尽量小