• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 深入MDI客戶窗口編程

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    作者:北京工業大學計算機學院 網絡 學科部 胡擊 在使用VC6.0/5.0的AppWizard生成MDI應用的時候,我們發現MDI主窗口的客戶區背景千篇一律的是深灰的。VC6.0/5.0并沒有提供修改其背景色的方法。甚至使用SDK編程也沒有好的方法修改背景色。以至于微軟的產品如Of
    作者:北京工業大學計算機學院網絡學科部 胡擊

    在使用VC6.0/5.0的AppWizard生成MDI應用的時候,我們發現MDI主窗口的客戶區背景千篇一律的是深灰的。VC6.0/5.0并沒有提供修改其背景色的方法。甚至使用SDK編程也沒有好的方法修改背景色。以至于微軟的產品如Office也是灰蒙蒙的背景。那么,有沒有辦法將背景設置為自己喜歡的顏色呢?

    筆者在學習過程中摸索出一套隨意改變客戶區窗口顏色的方法。利用這套方法,可以將客戶區窗口設為256色背景甚至設為BITMAP位圖以至于動畫等等。大大地增強了程序的多媒體效果。



    先介紹對MDI客戶窗口編程的基本原理。

    一、MDI客戶窗口

    一個MDI應用的主框架窗口包含一個特殊的子窗口稱為MDICLIENT窗口。MDICLIENT窗口負責管理主框架窗口的客戶區。MDICLIENT窗口本身有自己的子窗口即由CMDIChildWnd派生的文檔窗口,也就是MDI子窗口。MDI主框架窗口負責管理MDICLIENT子窗口。當控制條(菜單條,狀態條等)發生變化時,MDI主框架窗口重新配置MDICLIENT窗口。MDICLIENT子窗口負責管理全部的MDI子窗口。父窗口負責將某些命令傳遞到子窗口。因此,消息隊列發向MDI子窗口的消息由MDICLIENT窗口負責傳遞,發向MDICLIENT窗口和MDI子窗口的消息由主框架窗口負責傳遞。這樣,我們可以在主框架窗口截獲關于MDICLIENT窗口的重畫消息然后加入自己設計的代碼。

    二、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 函數以前預先解釋消息??梢灾剌d該函數截獲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);

    //******增加代碼尾******

    }

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>