我现在在学习VC的小示例,其中有一部分是“模态对话框”和“非模态对话框”书上介绍的例子中(单文档)
“模态对话框”的消息响应是在主框架中定义消息处理函数的(添加一个菜单,然后消息处理)
而“非模态对话框”的消息则是在视图中处理的,而且在例子的最后它还特别有这么一句:
请注意,这里的消息处理函数是在视图类中定义的。难道就不能定义在框架中了吗???后来,我试了一下,发现无论是在框架还是视图中都是可以正确响应处理的,但是如果我两者都同时定义这个消息的处理函数,则框架的处理函数并屏蔽了。那么,我想问一下:实际开发程序的时候,怎么来判断到底这个消息在“框架”或“视图”,“文档”以及“应用程序”哪个类中响应好呢????--------------------------------------------------
另外,还有一个问题请教:
在非模态对话框的处理函数中是这样写的:   CModalessDlg *pDlg = new CModelessDlg;
   pDlg->Create(ID_MODALESS,NULL);
   pDlg->ShowWindow(SW_SHOW);后来,我就想可不可以不用指针呢,修改为:
   CModalessDlg myDlg;
   myDlg.Create(ID_MODALESS,NULL);
   myDlg.ShowWindow(SW_SHOW);这样修改可以运行,但是点菜单时没有反应,只是突然闪烁一下。那么我想问:
   为什么这里不能用变量呢??   还有就是,记得有个菜单的例子:
   CMenu *pMenu;
   这样直接用一个指针而没有用new,这样不就指向了一个未知的内存空间了吗??
   可是为什么没错呢??但是错误的情况也是有的,
譬如: CString *pStr;
      pStr->LoadString(ID_MYSTR);
这样就错误了,显然是没有初始化造成的,所以通常我们使用CString Str;这样的类型如果是这样,我什么时候确定用指针或是用普通变量呢????请教!!!!!

解决方案 »

  1.   

    CModalessDlg myDlg;
       myDlg.Create(ID_MODALESS,NULL);
       myDlg.ShowWindow(SW_SHOW);
    退出函数后myDlg就释放了,当然是一闪就没了
      

  2.   

    消息在“框架”或“视图”,“文档”以及“应用程序”哪个类中响应,我一般是如果消息处理中要用到哪个中的变量就在哪个中响应,这样可以避免去获取要使用的对象。比如说你在框架中设定消息响应函数,可是你在消息响应中你要访问视图的变量,你就要用GetActiveView()或其他办法去获取视图对象的指针,然后才能访问该变量。如果直接放在视图类中响应就不用这么麻烦了。另外就是如果这个消息响应就和你的视图或者框架等中的一个相关,则直接放到该类中响应。
      

  3.   

    至于什么时候用变量,什么时候用指针,其实很简单,如果这个对象是客观存在的,你去获取它的指针,则用指针。如果对象不存在,是需要你去创建的,用变量。但是如果该对象需要在你创建它的函数体之外还存在,而不是出了函数就销毁,则需要用new创建对象。
      

  4.   

    CModalessDlg myDlg;//变量不能定义为局部变量,否则,函数结束,变量就释放了。
       myDlg.Create(ID_MODALESS,NULL);
       myDlg.ShowWindow(SW_SHOW);   CMenu *pMenu;
       这样直接用一个指针而没有用new,这样不就指向了一个未知的内存空间了吗??
    ——肯定是调用某个函数,在那个函数内部申请了内存。如果是这样,我什么时候确定用指针或是用普通变量呢????
    ——去研究一下变量的生存期、作用域。
      

  5.   

    变量的生存期的问题!消息的问题你可以看看MFC的代码
    这是CWnd的虚函数
    virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
    AFX_CMDHANDLERINFO* pHandlerInfo);
    你的Frame/View/Dialog都是从CWnd来的,所以都会有这个函数
    再看看CFrameWnd对这个函数的实现/重载就会明白是怎么回事了!
    BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,
    AFX_CMDHANDLERINFO* pHandlerInfo)
    {
    CPushRoutingFrame push(this); // pump through current view FIRST
    CView* pView = GetActiveView();
    if (pView != NULL && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    return TRUE; // then pump through frame
    if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    return TRUE; // last but not least, pump through app
    CWinApp* pApp = AfxGetApp();
    if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    return TRUE; return FALSE;
    }三段注释很清楚了:
    // pump through current view FIRST
    // then pump through frame
    // last but not least, pump through app
    所以Command(菜单,工具栏)消息在Frame结构的MFC程序里最先是让View来处理,如果View没有处理这个消息就会给Frame自己就是你的CMainWnd处理,如果还不行最后就给App你的CXXXApp处理。
    所以你对一个消息生成三个处理函数的话只能在View里处理