MFC 单文档框架的主菜单创建时间

    在主框架的OnCreate函数中,你可以看到工具条和状态栏的创建,理论上来说,你也应该可以看到主菜单的创建。找找看,发现没有。但是当你运行程序的时候,却又明明有主菜单。很显然,MFC还是创建了主菜单,只是在某个函数中将它隐藏了。那是在哪呢?慢慢找,不着急。

 你看到前面有这样的一句话,

if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
     return -1;

感觉有点像,莫非主框架类调用了基类的oncreate函数创建了主菜单?看看它的参数,在CSDN看看,如下:

typedef struct tagCREATESTRUCT { // cs LPVOID lpCreateParams;

HINSTANCE hInstance;

HMENU hMenu;

HWND hwndParent;

int cy;

int cx;

int y;

int x;

LONG style;

LPCTSTR lpszName;

LPCTSTR lpszClass;

DWORD dwExStyle;

} CREATESTRUCT;

里面果真有个HMENU,这是个菜单句柄,可能性加大了。但是你现在还不能肯定,怎么办?把这句话注释掉,看是不是主菜单没有了?如果没有了主菜单,那么就可以肯定主菜单肯定是在这句代码中创建的。好的,试试看,主菜单还在。显然寻找失败了,不然主菜单不可能还在。

 继续寻找,发现下面还有个:

if( !CFrameWnd::PreCreateWindow(cs) )
       return FALSE;
    return TRUE;

}

难道是这个吗?按照上面相同的方法,我将这句注释掉,发现主菜单不见了,而且提示“创建空文档失败”。显然,我们现在还不能肯定主菜单一定是在这个函数中创建的。我们搜下包含文字"LoadMenu"的文件,因为创建主菜单往往要加载菜单资源。发现在WINFRAM.CPP中有CFrameWnd::Create函数包含loadMenu. 接下来分别在CFrameWnd::OnCreate(lpCreateStruct) == -1),  if( !CFrameWnd::PreCreateWindow(cs) ) 和LOADMENU加三个断点,发现程序的确运行到这三个位置,并且LOADMENU是在CFrameWnd::OnCreate(lpCreateStruct) == -1)之前。现在看看CFrameWnd::PreCreateWindow(cs),代码如下:

BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
    if (cs.lpszClass == NULL)
    {
        VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
        cs.lpszClass = _afxWndFrameOrView;  // COLOR_WINDOW background
    }

    if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4)
        cs.style |= FWS_PREFIXTITLE;

    if (afxData.bWin4)
        cs.dwExStyle |= WS_EX_CLIENTEDGE;

    return TRUE;
}可以看到,它并没有做什么,只是修改了窗口的样式。

现在我们可以得出两个结论,主菜单是在precreatewindow之后创建的,并且是在oncreate被调用之前创建的。

我们看看还有什么代码我们没有用到,在这些代码中可能含有我们所要找的东西。我们知道设置主菜单的函数为setmenu,它是CFRAMEWND的成员函数,我们在CFRAMEWND的实现代码中搜索它,有以下几个函数包括它。

OnUpdateFrameMenu,OnDestroy,OnSetPreviewMode.这三个函数都有可能,我们用排除法。查询MSDN,发现后面两个在一般情况下不会被调用,故可以肯定主菜单是在cframewnd加载,在ONUPDATEFRAMEMENU中设置的。我们可以看下主框架的函数调用顺序。

 

loadFrame->precreatewindow->create(加载菜单)->oncreate->oncreateclient->createview->InitialUpdateFrame->

OnIdleUpdateCmdUI(在这里调用了OnIdleUpdateCmdUI设置了主菜单)。

这是我自己的探索过程,能力有限,有可能有错误,关键在于思路。

 

另外提示一下:如果 要隐藏主菜单或者设置自己的菜单为主菜单,可以映射主框架的Wm_SHOWWINDOW消息。这个消息是发生在主框架和视图已经建立后,窗口显示前。如果在之前的地方设置,会出现错误,而在显示之后再设置菜单就达不到预定的目的。

 

 

 

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值