首頁技術(shù)文章正文

C/c++培訓(xùn)之MFC-修改窗口的光標(biāo) 圖標(biāo) 背景

更新時(shí)間:2017-07-02 來源:黑馬程序員c/c++培訓(xùn)學(xué)院 瀏覽量:

首先,創(chuàng)建一個(gè)單文檔的應(yīng)用程序。

在窗口創(chuàng)建之前修改

方式1

在我們創(chuàng)建的CMainFrame類的PreCreateWindow函數(shù)中寫一個(gè)自己的窗口類并注冊(cè)
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
       return FALSE;
    // TODO:  在此處通過修改
    //  CREATESTRUCT cs 來修改窗口類或樣式
    WNDCLASS wc;
   wc.cbClsExtra = 0;
   wc.cbWndExtra = 0;
   wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
   wc.hCursor = LoadCursor(NULL, IDC_HELP);
   wc.hIcon = LoadIcon(NULL, IDI_ERROR);
   wc.hInstance = AfxGetInstanceHandle();
   wc.lpfnWndProc = ::DefWindowProc;
   wc.lpszClassName = _T("傳智播客");
   wc.lpszMenuName = NULL;
   wc.style = CS_HREDRAW | CS_VREDRAW;
//注冊(cè)窗口類
   RegisterClass(&wc);
   //類名稱設(shè)置為我們?cè)O(shè)計(jì)的窗口類的名字
   cs.lpszClass = _T("傳智播客");
    return TRUE;
}
上邊的代碼把我們的應(yīng)用程序改成了黑色背景,幫助光標(biāo),錯(cuò)誤圖標(biāo)。使用默認(rèn)窗口過程函數(shù)。
關(guān)于為什么菜單被創(chuàng)建
運(yùn)行程序發(fā)現(xiàn)只有圖標(biāo)改變了,背景和光標(biāo)并沒有改變,菜單項(xiàng)也沒有消失,為什么呢?
在利用MFC向?qū)蒘DI應(yīng)用程序時(shí),在應(yīng)用程序類的InitInstance函數(shù)中有如下代碼:
    // 注冊(cè)應(yīng)用程序的文檔模板。  文檔模板
    // 將用作文檔、框架窗口和視圖之間的連接
    CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
       IDR_MAINFRAME,
       RUNTIME_CLASS(CMenuDoc),
       RUNTIME_CLASS(CMainFrame),       // 主 SDI 框架窗口
       RUNTIME_CLASS(CMenuView));
    if (!pDocTemplate)
       return FALSE;
    AddDocTemplate(pDocTemplate);
也就是說在創(chuàng)建文檔模板時(shí),將菜單資源標(biāo)識(shí)(IDR_MAINFRAME)作為其中的一個(gè)參數(shù)傳入,當(dāng)MFC底層代碼在創(chuàng)建框架窗口時(shí),就會(huì)將此標(biāo)識(shí)轉(zhuǎn)換為相應(yīng)菜單句柄,然后去創(chuàng)建菜單和框架窗口。因此在這里將菜單設(shè)置為NULL,并不會(huì)影響菜單的創(chuàng)建。
關(guān)于為什么窗口背景和光標(biāo)沒有改變
應(yīng)用程序包含連個(gè)窗口:
l  應(yīng)用程序框架窗口
l  視類窗口
前者包含了后者,后者覆蓋在前者上面。程序運(yùn)行后我們看到的窗口實(shí)際上是視類窗口,而我們代碼中實(shí)際上修改的是框架窗口的背景和光標(biāo)。應(yīng)用程序的圖標(biāo)屬于框架窗口,所以程序運(yùn)行后看到圖標(biāo)改變了。
改變背景和光標(biāo)的操作我們應(yīng)該放在視類中實(shí)現(xiàn),我們應(yīng)該在視類窗口創(chuàng)建之前,即在PreCreateWindow函數(shù)中將窗口類設(shè)置為先前自定義的那個(gè)類,因?yàn)檫@是那個(gè)窗口類已經(jīng)注冊(cè)了,所以可以直接使用那么窗口類的名字:
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
       // TODO:  在此處通過修改
       //  CREATESTRUCT cs 來修改窗口類或樣式
       cs.lpszClass = _T("傳智播客");
       return CView::PreCreateWindow(cs);
}
在MFC中如果想修改應(yīng)用程序的窗口的圖標(biāo),應(yīng)該在框架類中進(jìn)行,因?yàn)榭蚣艽翱谥胁庞袠?biāo)題欄,所以才能修改位于標(biāo)題欄上的圖標(biāo)。如果想修改應(yīng)用程序窗口的背景和光標(biāo),就應(yīng)該在視類中進(jìn)行。

方式2

通過上邊的例子我們可以知道,在框架類中只能修改窗口的圖標(biāo),而為了實(shí)現(xiàn)這一功能,我們需要重寫整個(gè)窗口類。顯然,這是一件很麻煩的事情,MFC給我們提供了一個(gè)全局函數(shù): AfxRegisterWndClass,用來設(shè)定窗口的類型、光標(biāo)、圖標(biāo)、背景。其函數(shù)原型定義如下:
        LPCTSTR AFXAPI AfxRegisterWndClass(
             UINT nClassStyle,
             HCURSOR hCursor = 0,
             HBRUSH hbrBackground = 0,
             HICON hIcon = 0
);
設(shè)置圖標(biāo):
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
       if( !CFrameWnd::PreCreateWindow(cs) )
           return FALSE;
       // TODO:  在此處通過修改
       //  CREATESTRUCT cs 來修改窗口類或樣式
       cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, 0, 0,
         LoadIcon(NULL, IDI_ERROR));
       return TRUE;
}
設(shè)置光標(biāo)和背景色:
BOOL CMenuView::PreCreateWindow(CREATESTRUCT& cs)
{
       // TODO:  在此處通過修改
       //  CREATESTRUCT cs 來修改窗口類或樣式
       cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
LoadCursor(NULL, IDC_HELP),
(HBRUSH)GetStockObject(BLACK_BRUSH), NULL);
       return CView::PreCreateWindow(cs);
}

在窗口創(chuàng)建之后修改

使用Windows API函數(shù) SetClassLong
函數(shù)原型如下:
DWORD SetClassLong(HWND hWnd,int nlndex,LONG dwNewLong)
參數(shù):
l  hWnd:窗口句柄及間接給出的窗口所屬的類。
l  nIndex: 指定要設(shè)置的索引
n  GCL_HBRBACKGROUND 設(shè)置新的背景畫刷
n  GCL_HCURSOR 設(shè)置新的光標(biāo)
n  GCL_HICON 設(shè)置新的圖標(biāo)
n  GCL_STYLE 設(shè)置新的窗口樣式

設(shè)置圖標(biāo):

在CMainFram類的OnCreate函數(shù)最后,return語句之前添加如下代碼:
    SetClassLong(m_hWnd, GCL_HICON, (LONG)LoadIcon(NULL, IDI_ERROR));

設(shè)置光標(biāo)和背景

在瑩瑩程序生成的視類的OnCreate函數(shù)最后,return語句之前添加如下代碼:
    //背景色
SetClassLong(m_hWnd, GCL_HBRBACKGROUND,
 (LONG)(HBRUSH)GetStockObject(BLACK_BRUSH));
    //光標(biāo)
    SetClassLong(m_hWnd, GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_HELP));

本文版權(quán)歸黑馬程序員C/c++培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:黑馬程序員C/C++培訓(xùn)學(xué)院
首發(fā):http://c.itheima.com
 
 
 
分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!