看孙鑫书,第6章,最后个例子练习下。问题是这样,在frame中重写了oncommand函数,来捕捉菜单消息,在客户区上显示一行字符串。代码如下。
我想在显示字符串之前,清空客户区以前显示的内容,于是就用了 updatewindow()函数,但是不起作用,
为什么?然后改用,Invalidate() 函数,让整个客户区无效,使得下一次WM_PAINT时,能重绘整个客户区,结果发现
客户区就一直是白色的,dc.textout语句执行了,但是看不到任何我要显示的东西,为什么?我该如何做,才是正确的?最后一个问题,为什么 CMyView::OnCommand() 不能像 CMainFrame::OnCommand一样捕捉到 菜单命令?
先谢过了,望赐教BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
        // TODO: Add your specialized code here and/or call the base class
        
        int MenuCmdUI = LOWORD( wParam );        Cmfc_phonebookdemoView *pView = dynamic_cast<Cmfc_phonebookdemoView *>( GetActiveView() );
        
        if( MenuCmdUI >= IDM_PHONE1 && MenuCmdUI < pView->m_strArray.GetSize()+IDM_PHONE1 ) {
             //   MessageBox( "phone number clicked!" );
                CString str;
                str.Format( "phonenumber:  %s", pView->m_strArray.GetAt( MenuCmdUI-IDM_PHONE1) );                //UpdateWindow();
                //Invalidate();
                CClientDC dc( pView );
                dc.TextOut( 0, 0, str );
               
                return true;
                
        }        return CFrameWnd::OnCommand(wParam, lParam);
}

解决方案 »

  1.   

    View类覆盖在Frame类上所以你的代码应该在 CMyView 里写
      

  2.   

    最后一个问题,貌似已经知道答案了,不知道对不对。command 消息路由,先由frame 开始,然后按照《深入浅出》那本书所述,进行路由。CMyView::oncommand更本没有机会被调用 - -!
      

  3.   

    二楼说的是错的,我讨论的是command消息。
      

  4.   

    int MenuCmdUI = LOWORD( wParam );         Cmfc_phonebookdemoView *pView = (Cmfc_phonebookdemoView *)GetActiveView(); 
            
            if( MenuCmdUI >= IDM_PHONE1 && MenuCmdUI < pView->m_strArray.GetSize()+IDM_PHONE1 ) { 
                //  MessageBox( "phone number clicked!" ); 
                    CString str; 
                    str.Format( "phonenumber:  %s", pView->m_strArray.GetAt( MenuCmdUI-IDM_PHONE1) );            
                    CClientDC dc( pView ); 
                    dc.TextOut( 0, 0, str ); 
                  
                    return true; 
                    
            } 
      

  5.   

    调用 pView->Invalidate(); 
      

  6.   

    Invalidate()不管你放在函数哪个位置,它永远在函数末尾执行,也就是说,你先TextOut,其次才执行Invalidate。
    解决办法你可以试下下面两个:
    不要用TextOut,添加一个Static控件用于输出字符串,可以用Invalidate()刷新。在OnDraw里
    if(m_bShow)
    {
    dc.TextOut(m_str);
    }
    //在按钮只修改字符串,然后用Invalidate()刷新
      

  7.   

    楼上,正解。让我对 invalidate 和 updatewindow 以及 redrawwindow 3个函数加深理解了。