• [百度空间] [原]MFC杂乱笔记


    1.

    创建动态菜单

    假如ID是动态分配的,那么重载
    virtual BOOLOnCmdMsg(UINT,int,void*,AFX_CMDHANDLERINFO*);

    据MSDN不详细解释,当第二个参数值为CN_COMMAND时,是执行Command的消息,不过要看最后一个参数,如果最后一个参数为空,则为真正执行该命令.否则是查找是否有该命令ID的handler

    BOOL TheWindow::OnCmdMsg(UINT nID,int nCode,void* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo)
    {

        if( nCode == CN_COMMAND  )
        {
            if( nID >= BaseMenuID && nID < MaxMenuID )
            {
                if( pHandlerInfo == NULL )
                {
                    //handle the Command nID here

                }

                return TRUE;

            }

        }

    return ParentWnd::OnCmdMsg(nID,nCode,pExtra,pHandlerInfo);

    }

    根据MSDN,菜单的ID应该是全局的(貌似应该大于0x8000), 又根据WM_COMMAND消息格式,ID最好是一个WORD,ID如果超过一个WORD,例如0x10000,那么WM_COMMAND可以收到这个菜单的命令ID(但跟MSDN的描述LOWORD不一致,而是整个DWORD,这个可能是凑巧),但是MFC的OnCmdMsg只能收到更新消息(CN_UPDATE_COMMAND_UI),不能收到执行消息.

    实时设置Menu的Enable和Disable状态(MF_ENABLED,MF_DISABLED,MF_GRAYED)为何无效?比如为何不能禁用菜单项?
    在查了MSDN半天之后,终于在一个code example中看到了一段不起眼的注释:

    // The code fragment below shows how to disable (and gray out) the
    // FileNew menu item.
    // NOTE: m_bAutoMenuEnable is set to FALSE in the constructor of

    // CMainFrame so no ON_UPDATE_COMMAND_UI or ON_COMMAND handlers are

    // needed, and CMenu::EnableMenuItem() will work as expected.

    大意就是说如果设置m_bAutoMenuEnable该标志为FALSE的话,EnableMenuItem()就可以正常使用了
    没有设置该标志呢?猜测framework会自动更新菜单:根据消息映射检查菜单ID是否有handler,如果有,就将其激活,否则就禁用.所以每次手动设置之后就被自动改回来了....

    2.

    CMDIFrameWnd为何不能处理WM_KEYDOWN消息?(MFC9) 经研究发现,接受焦点的不是他本身,而是他的Client - m_hWndMDIClient,经测试GetFocus() 的返回值的HWND与m_hWndMDIClient的值一致.

    因为焦点在他的客户区m_hWndMDIClient上,不在他自己身上,所以他自己无法接受WM_KEYDOWN等等.

    3.

    MFC DLL注意事项: 每次从外部调用,第一次进入MFC的DLL,都需要调用 AFX_MANAGE_STATE(::AfxGetStaticModuleState());

    关于AFX_MANAGE_STATE,MSDN已经说得很清楚了:  Call this macro to protect an exported function in a DLL.

    4.

    如何在控件反射了自己的消息之后,还能让父窗口处理?答: ON_CONTROL_REFLECT_EX ,使用一个BOOL的返回值来确定是否让父窗口继续处理,TRUE表示让父窗口跳过该消息,FLASE则继续让父窗口处理.

    ON_CONTROL_REFLECT 的消息处理函数返回值是void,即父窗口不能处理.但是这个消息会自动检查数据变化(如果数据没有变化,则不会调用该handler)

    ON_CONTROL_REFLECT_EX 则不同,一旦控件被操作,就调用该handler,所以要手动检查数据.

    ON_CONTROL_REFLECT_EX(CBN_SELCHANGE,&TheCombbox::OnSelectChange)

    BOOL TheCombbox::OnSelectChange()
    {
        //数据真的改变?
        {
            处理数据,返回FALSE ,通知父窗口
        }
        否则
        {
            返回TRUE,跳过
        }
    }

    暂时到这里.

  • 相关阅读:
    TranslateAnimation 运行动画后实际位置不正确问题
    Linux下如何编译并运行C程序
    row_number() OVER (PARTITION BY COL1 ORDER BY COL2)
    C++软件开发常用辅助软件——gprof
    C++软件开发常用辅助软件——Cppcheck
    C++软件开发常用辅助软件——SCons
    C++软件开发常用辅助软件——Valgrind
    救援linux
    C/C++代码覆盖率生成
    排列的逆
  • 原文地址:https://www.cnblogs.com/crazii/p/4512783.html
Copyright © 2020-2023  润新知