大家可以试一下,
新建一个基于对话框(1)的工程,支持activex(2),往对话框上加入任一个activex控件(3),这时候会在rc资源文件里生成一个DLGINIT的条目(这个条目去掉就没事,当然activex也用不了,combobox的DLGINIT条目就没有影响)。
这时候在程序里加上new CFrameWnd, Create()/LoadFrame,ShowWindow(我是加在InitInstance里)程序运行起来,好像没问题。
但是你在CFrameWnd焦点下,按一下键盘,你发现程序没有响应了。
发现OnKeyDown还有,OnChar就收不到了。同样的工程用vc7打开(自动转换)或直接用vc7建一个同样的,就没有问题!但是已经做了大半的工程,用vc7编译会碰到不兼容的问题,有谁能帮帮我?

解决方案 »

  1.   

    faint,用不了两分钟就能测试一下,大家研究研究啊
      

  2.   

    如果OnKeyDown还有,OnChar就收不到了,你要看一下PreTranslateMessage,跟进去看看,另外APP的主窗口最好设成CFrameWnd,有必要的话CFrameWnd关闭后再设回去
      

  3.   

    to dentistrydoctor
    代码没有问题(如果有问题可能是缺什么afxXXX()的函数),写最简单的基于dialog的mfc应用程序,
    只在initinstance里加入cframewnd new , create/loadframe, show
    没有加入activex控件的时候是没有问题的,
    加入activex但如果是vc7编译的,也是没有问题的,
    如果cframewnd new,create,show改成一个非模态的cdialog new,create,show也没有问题
      

  4.   

    两分钟操作!!!!!!!!!!!!!
    我写一下步骤,大家可以试试: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按同样步聚创建一个程序,正常!
      

  5.   

    to goodboyws, PreTranslateMessage我一会跟一下。基于CDialog是因为现在的工程是这样的,没法改了。
    用到framewnd是基中一个功能有画板,有dock toolbar。
      

  6.   

    PreTranslateMessage跟踪后找到地方了,在下面这个函数的最后一个while里,死循环了AFX_STATIC CWnd* AFXAPI _AfxFindNextMnem(CWnd* pWndDlg, CWnd* pWnd, LPMSG lpMsg)
    {
    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
      

  7.   

    问题解决了
    包含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;
    }
    搞定。