一个MFC窗口程序,以下是系统自动生成的MainFrm.cpp代码,
我映射的“文件打开、关闭、保存、另存”四个消息函数,只有“打开”是好用的,
其他三个我通过单步调试都没有跟踪到(但仍然会触发系统默认的处理流程)
无奈我只好新增了几个ID作映射(默认宏名称后加了一个"1"),
这样就好用了,请教各位神仙是怎么回事呢?下面是修改后的代码。
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(ID_STARTSTOP, OnStartStop)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(ID_FILE_SAVE1, OnFileSave)
ON_COMMAND(ID_FILE_CLOSE1, OnFileClose)
ON_COMMAND(ID_APP_EXIT, OnAppExit)
ON_COMMAND(ID_FILE_SAVE_AS1, OnFileSaveAs)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

解决方案 »

  1.   

    注:我的这几个函数和消息映射都是ClassWizard帮我默认放在MainFrm中的。
      

  2.   

    文件相关的消息,应该由doc类来接收和处理
      

  3.   

    谢谢,我试了一下,果然是这样的,但是为什么OPEN是好用的呢?
      

  4.   

    你看看C...App中的消息映射表。
      

  5.   

    楼上哥们能说明白点吗,app类中的映射表是这样:
    我把其中的ID_FILE_OPEN注释掉,效果是一样的
    BEGIN_MESSAGE_MAP(CDTApp, CWinApp)
    //{{AFX_MSG_MAP(CDTApp)
    ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
    //}}AFX_MSG_MAP
    // Standard file based document commands
    ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
    ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
    // Standard print setup command
    ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
    END_MESSAGE_MAP()
      

  6.   

    我让你看,还看不出来吗?CWinApp类已经映射了这几个菜单命令消息。将其注释掉就可以了。不过既然MFC在CWinApp类中处理这几个消息,自然有其道理。
      

  7.   

    刚才建了一个MFC工程,由框架生成的代码里,发现窗口类不会映射这个消息,而默认的CDocument映射了这些消息,
    通常情况下文档类会先于框架窗口被处理(CView -> CDocument -> CFrameWnd ->CWinApp),所以一直处理的是默认处理方式。 说明一下MFC处理消息函数都是实函数,从C++的角度看它违背了设计原则即实函数接口一定不能被改写,否则造成接口混乱,但这样做的好处是消息调用是分层的, 考虑到是在框架调用这些处理函数,我也接受这种做法,有更好的解释吗,请告诉我哦,或者是宏中不能添加虚函数地址。小弟没写过MFC程序,最近才开始学的,不知道怎么学就开始看源代码,才看了消息处理部分,写的不对请大家多指正,如果有好的学习方法也请告诉我一下啊,谢谢
      

  8.   

    是的,我看了一下CFrameWnd::OnCmdMsg()函数,确实和楼上所说一样,调用栈如下,CWinApp并不处理open消息.

    CDTDoc::OnFileOpen() line 96
    _AfxDispatchCmdMsg(CCmdTarget * 0x00431640 {CDTDoc}, unsigned int 0x0000e101, int 0x00000000, void (void)* 0x0040124e CDTDoc::OnFileOpen(void), void * 0x00000000, unsigned int 0x0000000c, AFX_CMDHANDLERINFO * 0x00000000) line 88
    CCmdTarget::OnCmdMsg(unsigned int 0x0000e101, int 0x00000000, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 302 + 39 bytes
    CDocument::OnCmdMsg(unsigned int 0x0000e101, int 0x00000000, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 894 + 24 bytes
    CView::OnCmdMsg(unsigned int 0x0000e101, int 0x00000000, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 167 + 33 bytes
    CFrameWnd::OnCmdMsg(unsigned int 0x0000e101, int 0x00000000, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 890 + 33 bytes
    CWnd::OnCommand(unsigned int 0x0001e101, long 0x00000000) line 2088
    CFrameWnd::OnCommand(unsigned int 0x0001e101, long 0x00000000) line 317
    CWnd::OnWndMsg(unsigned int 0x00000111, unsigned int 0x0001e101, long 0x00000000, long * 0x0012fc14) line 1597 + 28 bytes
    CWnd::WindowProc(unsigned int 0x00000111, unsigned int 0x0001e101, long 0x00000000) line 1585 + 30 bytes
    AfxCallWndProc(CWnd * 0x00431260 {CMainFrame hWnd=???}, HWND__ * 0x00060b02, unsigned int 0x00000111, unsigned int 0x0001e101, long 0x00000000) line 215 + 26 bytes
    AfxWndProc(HWND__ * 0x00060b02, unsigned int 0x00000111, unsigned int 0x0001e101, long 0x00000000) line 368
    AfxWndProcBase(HWND__ * 0x00060b02, unsigned int 0x00000111, unsigned int 0x0001e101, long 0x00000000) line 220 + 21 bytes
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d1b4c0()
    USER32! 77d1b50c()
    NTDLL! 7c92eae3()
    CFrameWnd::PreTranslateMessage(tagMSG * 0x0041d8b8 {msg=0x00000100 wp=0x0000004f lp=0x00180001}) line 200 + 27 bytes
    CWnd::WalkPreTranslateTree(HWND__ * 0x00060b02, tagMSG * 0x0041d8b8 {msg=0x00000100 wp=0x0000004f lp=0x00180001}) line 2667 + 18 bytes
    CWinThread::PreTranslateMessage(tagMSG * 0x0041d8b8 {msg=0x00000100 wp=0x0000004f lp=0x00180001}) line 665 + 18 bytes
    CWinThread::PumpMessage() line 841 + 30 bytes
    CWinThread::Run() line 480 + 11 bytes
    CWinApp::Run() line 400
    AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f0f, int 0x00000001) line 49 + 11 bytes
    WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f0f, int 0x00000001) line 30
    WinMainCRTStartup() line 330 + 54 bytes
    KERNEL32! 7c816fd7()