大家可以试一下,
新建一个基于对话框(1)的工程,支持activex(2),往对话框上加入任一个activex控件(3),这时候会在rc资源文件里生成一个DLGINIT的条目(这个条目去掉就没事,当然activex也用不了,combobox的DLGINIT条目就没有影响)。
这时候在程序里加上new CFrameWnd, Create()/LoadFrame,ShowWindow(我是加在InitInstance里)程序运行起来,好像没问题。
但是你在CFrameWnd焦点下,按一下键盘,你发现程序没有响应了。
发现OnKeyDown还有,OnChar就收不到了。同样的工程用vc7打开(自动转换)或直接用vc7建一个同样的,就没有问题!但是已经做了大半的工程,用vc7编译会碰到不兼容的问题,有谁能帮帮我?
新建一个基于对话框(1)的工程,支持activex(2),往对话框上加入任一个activex控件(3),这时候会在rc资源文件里生成一个DLGINIT的条目(这个条目去掉就没事,当然activex也用不了,combobox的DLGINIT条目就没有影响)。
这时候在程序里加上new CFrameWnd, Create()/LoadFrame,ShowWindow(我是加在InitInstance里)程序运行起来,好像没问题。
但是你在CFrameWnd焦点下,按一下键盘,你发现程序没有响应了。
发现OnKeyDown还有,OnChar就收不到了。同样的工程用vc7打开(自动转换)或直接用vc7建一个同样的,就没有问题!但是已经做了大半的工程,用vc7编译会碰到不兼容的问题,有谁能帮帮我?
代码没有问题(如果有问题可能是缺什么afxXXX()的函数),写最简单的基于dialog的mfc应用程序,
只在initinstance里加入cframewnd new , create/loadframe, show
没有加入activex控件的时候是没有问题的,
加入activex但如果是vc7编译的,也是没有问题的,
如果cframewnd new,create,show改成一个非模态的cdialog new,create,show也没有问题
我写一下步骤,大家可以试试:1、新建一个MFC exe,选基于对话框,完成
2、在initinstance第一句(随便别的地方也一样,如对话框OK按钮双击出来的OnOK里)
写上:
CFrameWnd* frame = new CFrameWnd();
frame->LoadFrame(IDR_MENU1, WS_CAPTION, NULL,NULL);
frame->ShowWindow(SW_SHOW);
LoadFrame里的menu随便建,也可以写成
frame->Create(NULL, NULL);
3、编译测试(正常)
4、在dlg资源里随便加上个activex控件,如(microsoft web browser),不需要生成成员变量
5、编译测试(不行)
6、用VC7打开dsw,自动转换,正常
7、用vc7按同样步聚创建一个程序,正常!
用到framewnd是基中一个功能有画板,有dock toolbar。
{
CWnd* pWndStart;
CWnd* pWndT;
int i = 0; // Check if we are in a group box so we can find local mnemonics.
pWndStart = _AfxGetChildControl(pWndDlg, pWnd); while ((pWndT = pWndDlg->GetNextDlgGroupItem(pWndStart)) != NULL)
{
i++; // Avoid infinite looping.
if (pWndT == pWnd || i > 60)
break; pWndStart = pWndT; if (COccManager::IsMatchingMnemonic(pWndT, lpMsg))
return pWndT;
} pWnd = pWndStart = _AfxGetChildControl(pWndDlg, pWnd); while (TRUE)
{
pWnd = _AfxNextControl(pWndDlg, pWnd, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED); if (COccManager::IsMatchingMnemonic(pWnd, lpMsg))
break; if (pWnd == pWndStart)
return NULL;
} return pWnd;
}
堆栈如下:
_AfxFindNextMnem(CWnd * 0x0012fe74 {CTest35Dlg hWnd=0x002507ec}, CWnd * 0x00372f50 {CTempWnd hWnd=0x00450758}, tagMSG * 0x004167f8 {msg=0x00000102 wp=0x00000061 lp=0x001e0001}) line 160
_AfxGetNextMnem(CWnd * 0x0012fe74 {CTest35Dlg hWnd=0x002507ec}, CWnd * 0x00373130 {testframe hWnd=0x00180830}, tagMSG * 0x004167f8 {msg=0x00000102 wp=0x00000061 lp=0x001e0001}) line 186 + 17 bytes
COccManager::IsDialogMessageA(CWnd * 0x0012fe74 {CTest35Dlg hWnd=0x002507ec}, tagMSG * 0x004167f8 {msg=0x00000102 wp=0x00000061 lp=0x001e0001}) line 517 + 17 bytes
CWnd::IsDialogMessageA(tagMSG * 0x004167f8 {msg=0x00000102 wp=0x00000061 lp=0x001e0001}) line 179 + 33 bytes
CWnd::PreTranslateInput(tagMSG * 0x004167f8 {msg=0x00000102 wp=0x00000061 lp=0x001e0001}) line 3424
CDialog::PreTranslateMessage(tagMSG * 0x004167f8 {msg=0x00000102 wp=0x00000061 lp=0x001e0001}) line 92
CWinThread::PreTranslateMessage(tagMSG * 0x004167f8 {msg=0x00000102 wp=0x00000061 lp=0x001e0001}) line 681 + 18 bytes
包含activex控件时,cdialog的CWnd::IsDialogMessageA,
会改变分支到COccManager::IsDialogMessageA
否则是到::IsDialogMessageA(正常)但_AfxFindNextMnem里的实现是有bug的,
_AfxNextControl会循环获取对话框上的控件(到最后一个会继续第一个)
但没有一个控件要处理cframewnd事件(因为cframewnd并不是真正cdialog上的控件)
所以死循环。
vc7的实现有点不同,没有细看。如果改vc6 mfc代码,还要重新编译mfc,怕不稳定,研究了一下,用下面的方法:
我在framewnd的PreTranslateMessage里加入
if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) {
BOOL ret = ::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
return TRUE;
}
搞定。