科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件深入MDI客户窗口编程

深入MDI客户窗口编程

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在使用VC6.0/5.0的AppWizard生成MDI应用的时候,我们发现MDI主窗口的客户区背景千篇一律的是深灰的......

作者:胡击 来源:天极论坛 2007年10月22日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
二、MDI客户窗口编程方法

  对MDI客户窗口编程有一定的难度。原因是MDIFrameWnd的客户区完全被MDICLIENT窗口覆盖掉了。这样,MDI主窗口类MDIFrameWnd的背景色和光标都不起作用。同时,微软并不支持将MDICLIENT窗口作为子类,MDICLIENT窗口只能使用标准的背景色和光标。所以,对MDI客户窗口编程不能象对普通窗口那样简单地重载WM_PAINT的消息处理函数。 改变MDI客户窗口背景的方法有两种。

  使用CMDIFrameWnd::CreateClient 函数:

  CreateClient( LPCREATESTRUCT lpCreateStruct, CMenu* pWindowMenu );

  参数lpCreateStruct是指向CREATESTRUCT 结构的指针。在CREATESTRUCT 结构中lpszClass项指向窗口类WNDCLASS结构。通过改变WNDCLASS结构中的HbrBackground项和hCursor项可以更改MDICLIENT窗口的背景刷和光标。由于该函数创建新的MDICLIENT窗口对象,必须在重载的主窗口的OnCreate成员函数中调用。该方法比较复杂,必须手动创建MDI客户窗口,不能利用AppWizard自动提供的功能。而且,只能使用Windows95有限的16色背景刷。本文采用第二种方法。

  在主框架窗口的消息队列中截获发向MDI客户窗口的WM_PAINT消息并向主框架窗口发送一条标志消息。在这条标志消息的处理函数中对MDI客户窗口进行操作。该方法比较简捷,但有几点值得注意的地方。

  首先,如何截获MDI客户窗口WM_PAINT消息。MFC提供了PreTranslateMessage(MSG* pMsg) 函数。它在消息发送到TranslateMessage 和DispatchMessage 函数以前预先解释消息。可以重载该函数截获MDI客户窗口WM_PAINT消息:

BOOL PreTranslateMessage(MSG* pMsg)

{

if(pMsg->hwnd==m_hWndMDIClient && pMsg->message==WM_PAINT)

PostMessage(WM_PAINT);

return CMDIFrameWnd::PreTranslateMessage(pMsg);

}

  其次,为简单起见,这里将标志消息设为MDI主窗口的WM_PAINT。在MDI主窗口WM_PAINT的消息处理函数中增加重画MDI客户窗口的代码。读者也可以自定义消息,不过麻烦一点。

  最后,由于对MDI客户窗口的操作都是在主窗口完成的。如何在主窗口中获得MDI客户窗口的设备描述表呢。其实,在MDI主窗口类中有MDI客户窗口成员m_hWndMDIClient。按如下方法得到客户窗口的设备描述表

  dc.m_hDC=::GetDC(this->m_hWndMDIClient);

  然后就可以对客户窗口进行操作了。

  三、实例

  将客户窗口设为256色背景。

  使用AppWizard生成MDI应用TEST。

  在TEST.CPP中的函数,增加如下代码:

BOOL CTestApp::InitInstance()

{

AfxEnableControlContainer();

#ifdef _AFXDLL

Enable3dControls(); // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic(); // Call this when linking to MFC statically

#endif

SetRegistryKey(_T("Local AppWizard-Generated Applications"));

LoadStdProfileSettings(); // Load standard INI file options (including MRU)

CMultiDocTemplate* pDocTemplate;

pDocTemplate = new CMultiDocTemplate(

IDR_TESTTYPE,

RUNTIME_CLASS(CTestDoc),

RUNTIME_CLASS(CChildFrame), // custom MDI child frame

RUNTIME_CLASS(CTestView));

AddDocTemplate(pDocTemplate);

// create main MDI Frame window

CMainFrame* pMainFrame = new CMainFrame;

if (!pMainFrame->LoadFrame(IDR_MAINFRAME))

return FALSE;

m_pMainWnd = pMainFrame;

// Parse command line for standard shell commands, DDE, file open

CCommandLineInfo cmdInfo;

ParseCommandLine(cmdInfo);

// Dispatch commands specified on the command line

if (!ProcessShellCommand(cmdInfo))

return FALSE;

// The main window has been initialized, so show and update it.

pMainFrame->ShowWindow(m_nCmdShow);

//******增加代码头******

AfxGetMainWnd()->PostMessage(WM_PAINT);

//******增加代码尾******

pMainFrame->UpdateWindow();

return TRUE;

}

  保证程序一开始就更新客户窗口。

  使用ClassWard在CmainFrame类中加入PreTranslateMessage消息处理函数入如下:

BOOL PreTranslateMessage(MSG* pMsg)

{ //******增加代码头******

if(pMsg->hwnd==m_hWndMDIClient && pMsg->message==WM_PAINT)

PostMessage(WM_PAINT);

//******增加代码尾******

return CMDIFrameWnd::PreTranslateMessage(pMsg);

}

  在主窗口的WMPAINT消息处理函数中加入:

void CMainFrame::OnPaint()

{

//******增加代码头******

CMDIFrameWnd::OnPaint();

CRect rc;

CDC dc;

dc.m_hDC=::GetDC(this->m_hWndMDIClient);

CBrush br(RGB(120,200,40));//256色刷子

dc.SelectObject(&br);

dc.GetClientRect(&rc);

dc.PatBlt(rc.left,rc.top,rc.Width(),rc.Height(),PATCOPY);

ReleaseDC(&dc);

//******增加代码尾******

}

  将客户窗口设为Bitmap位图。

  1,2,3同例一。

  4.在资源中加入自己喜欢的位图并设为IDB_BITMAP1。在主窗口类加入Cbitmap类成员m_bmp。并在CMDIFrameWnd::OnCreate()函数末尾初始化:

  m_bmp.LoadBitmap(IDB_BITMAP1);

  5.在主窗口的WM_PAINT消息处理函数中加入:

void CMainFrame::OnPaint()

{

//******增加代码头******

CMDIFrameWnd::OnPaint();

CRect rc,memrc;

CDC dc,memdc;

dc.m_hDC=::GetDC(this->m_hWndMDIClient);

memdc.CreateCompatibleDC(&dc);

memdc.SelectObject(&m_bmp);

GetClientRect(&rc) ;

dc.BitBlt(rc.top,rc.left,rc.Width(),rc.Height()

,&memdc,rc.top,rc.left,SRCCOPY);

ReleaseDC(&memdc);

ReleaseDC(&dc);

//******增加代码尾******

}

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章