MObjFrame::MObjFrame()
{
LoadFrame(IDR_MOBJFRAME); 
}int MObjFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
m_wndToolBar.CreateEx(this);
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_GRIPPER |CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndToolBar.LoadToolBar(IDR_MOBJFRAME);
RecalcLayout(TRUE); // m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
// EnableDocking(CBRS_ALIGN_ANY); 
// DockControlBar(&m_wndToolBar);
return 0;
}
void MObjFrame::OnPaint() 
{
CPaintDC dc(this); // device context for painting
dc.TextOut(0,0,"MobjDraw Window" );
m_wndToolBar.RedrawWindow(); 
}
在客户区绘图时,发现(0,0)是从ToolBar的左上角开始,就如上面代码执行后 MobjDraw Window会看不见。而当我停靠了ToolBar的时候(注释部分),每次重画客户区,ToolBar的按钮旁边的区域都白了,然后下面的字就可以看到一部分?而当我用同样的方法在MainFrame中创建ToolBar的时候却很好,绘图时客户区左上角也在空白的地方,而不是何ToolBar左上角。
    有时候也会遇到MainFrame出现这样的情况,查了很多网站,没有结果。请问,到底时什么地方出了错误?或是MFC本身的Bug请高手相救:3X

解决方案 »

  1.   


    呵呵,老地,试你高错了吧。单文档的,你应该在那个VIEW类中PAINT吧?
      

  2.   

    为什么不能在框架客户区?
    那么,如果不绘图,为什么ToolBar,看上去不和菜单是相平的。
    另外,已经是有一个单文档模板了,我想另做一个没有视图的窗口,为了简单起见,定义了一个MobjFrame类,只是为了输出一些图形。另外加一个菜单和简单的几个Bar,所以才使用FrameWnd,并不是我不知道要在视图里绘制。
    我的意思是ToolBar不应该在客户区。
    如:VCKBASE.com 第11期 如何让工具条显示256色图像 ,类似的问题(当然,该文并非指出这个问题,只是该问题与本文的问题相同而已)。
    是否能够不用类生成向导来做一个FrameWnd而保证ToolBar不至于看上去比Menu低?
      

  3.   

    并非小弟搞夸张,只是这几天一直在想办法找到CMainFrame,和自定义的Frame类、创建的对象到底有何差别。MFC在程序初始化的时候:
    CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
    IDR_MAINFRAME,
    RUNTIME_CLASS(CMAssDoc),
    RUNTIME_CLASS(CMainFrame),       // main SDI frame window
    RUNTIME_CLASS(CMAssView));
    AddDocTemplate(pDocTemplate);然后,主窗体就显示出来了。如果你把 CMainFrame的构造函数设置为public的,
    然后在程序的某个文件中
    #include "MainFrm.h"
    某个地方,添加如下代码:
    pFrm=new CMainFrame;
    pFrm->LoadFrame(IDR_MAINFRAME);  
    pFrm->ShowWindow(SW_SHOWNORMAL|SW_SHOW);
    pFrm->UpdateWindow();   
    会出现什么情况呢,奇怪的事情出现了,ToolBar应该变得不一样了,不明白
    pDocTemplate = new CSingleDocTemplate()到底做了什么?
    AddDocTemplate(pDocTemplate);
      

  4.   

    看看这些ToolBar
    效果如图:
    http://www.vckbase.com/vckbase/vckbase11/images/cfig111300102.gif
    这是使用文档模板时,偶尔会出现的同样的问题
    http://www.vckbase.com/Document/journal/vckbase18/images/cfig20021012.jpg
    您是否也有遇到同样的情况?
      

  5.   

    既然是框架,就需要包含内容:Doc/View。直接在框架上绘制,当然不一样。
      

  6.   

    你还是看看《深入浅出MFC》吧!有答案的:)
      

  7.   

    谢谢楼上二位,我会看看《深入浅出MFC》,继续寻找答案的。
      

  8.   

    还是看visual c++技术内幕或MFC 技术内幕为好
    高屋建瓴,
    孟尝君的书,参考可以,不足为道
      

  9.   

    我解决了ToolBar显示效果的问题。
    ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED);
    使ToolBar看上去和Menu是平的,对于本贴引用的VCKBASE的例子中的ToolBar的问题可以解决。但是我想这不是我想要的。刷新时,Dock后的ToolBar即使ReDraw了,显示还是有问题,Gripper那里是白的,而右边也是有一个白色的分割条。而当FrameWnd显示出来的时候,我想即使不加入View也可以出现窗体边框(象MainFrame一样)。另外,我想重载
    void MObjFrame::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
    试试看。
      

  10.   

    这是在codeguru上搜索ToolBar后得到的一个例子(尽管该例子也不是将ToolBar)
    http://www.codeguru.com/forum/showthread.php?s=d5fe666eefdd71e3614037fb64166df0&threadid=238697&highlight=ToolBarint CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
    return -1;
    // create a view to occupy the client area of the frame
    if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
    CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
    {
    TRACE0("Failed to create view window\n");
    return -1;
    }if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
    | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
    TRACE0("Failed to create toolbar\n");
    return -1; // fail to create
    }if (!m_wndStatusBar.Create(this) ||
    !m_wndStatusBar.SetIndicators(indicators,
    sizeof(indicators)/sizeof(UINT)))
    {
    TRACE0("Failed to create status bar\n");
    return -1; // fail to create
    }
    // TODO: Delete these three lines if you don't want the toolbar to be dockable
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);return 0;
    }
    用这种方法也比较简单,并没有使用VIew/DOC/FRAME=>DocTemple 结构,但是创建的FrameWnd有血有肉。这是一种方法,创建了一个简单的FrameWnd。
    相信有很多朋友跟我的想法一致,为了省事或者简单,不使用View而直接在Frame里绘图,结果容易导致ToolBar显示不完全。原因当窗体重画时,m_wndToolBar并不会接收到WM_PAINT消息,只有手动刷新,而m_wndToolBar在重绘制的时候,Gripper和右边界处于Invalidate的区域,所以重画后显示不完全。
        显然,在Paint时并不需要重绘ToolBar,一般在Paint前,需要擦除以前显示的内容,通常都调用RedrawWindow(),让窗体自己擦除然后重绘(并调用重载的OnPaint()消息函数)。因而有两种方法解决:第一种方法是用视图绘制,可以借鉴上面引用的例子,不用担心客户区重绘影响ToolBar显示。而且显示效果也比较好第二种方法是: RECT rect,rectBar;
    GetClientRect(&rect);
    m_wndToolBar.GetWindowRect(&rectBar);
    ScreenToClient(&rectBar);
    rect.top=rectBar.bottom; //假定不停靠并且ToolBar在客户区上面
    RedrawWindow(&rect);        //只重绘需要ToolBar以外的区域   前面,小弟提到 MainFrameWnd的ToolBar在非客户区,是对Doc/View/Frame结构理解的错误。
    在此更正,MainFrameWnd的ToolBar应该是在MainFrameWnd的客户区,我们看到的窗口有客户区边框应该是View的客户区边框,而MainFrameWnd的客户区边框没有显示出来。因而是我理解错误。
       如果您循规蹈矩,也许不会象我一样遇到这么多的麻烦事,呵呵,就应该照人家模式去做。   另外,对于本帖的标题,小弟并非搞夸张,只是因为很久都找不到答案,而 界面版有过类似的ToolBar显示不出来的帖子一直没有得到妥善的解决,才觉得这个问题比较难,希望高手能够出手相助。如果您觉得本文的问题只在哗众取宠,那您无需保留您的意见。
      

  11.   

    http://www.csdn.net/develop/article/15/15200.shtm
    http://www.csdn.net/Develop/Read_Article.asp?Id=15409
    http://www.csdn.net/Develop/Read_Article.asp?Id=7209
    对理解框架和视图的关系有很大帮助。
    另外,如果不创建文档,和文档模板,要使用指针的成员变量,不然会出现ASSERT FAILURE。
    至于什么原因,就不得而知了。