教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

C++培訓之MFC-修改窗口的光標 圖標 背景

更新時間:2015年12月28日16時32分 來源:傳智播客C/C++學科 瀏覽次數(shù):

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

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

方式1

在我們創(chuàng)建的CMainFrame類的PreCreateWindow函數(shù)中寫一個自己的窗口類并注冊
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;
//注冊窗口類
   RegisterClass(&wc);
   //類名稱設置為我們設計的窗口類的名字
   cs.lpszClass = _T("傳智播客");
    return TRUE;
}
上邊的代碼把我們的應用程序改成了黑色背景,幫助光標,錯誤圖標。使用默認窗口過程函數(shù)。
關(guān)于為什么菜單被創(chuàng)建
運行程序發(fā)現(xiàn)只有圖標改變了,背景和光標并沒有改變,菜單項也沒有消失,為什么呢?
在利用MFC向?qū)蒘DI應用程序時,在應用程序類的InitInstance函數(shù)中有如下代碼:
    // 注冊應用程序的文檔模板。  文檔模板
    // 將用作文檔、框架窗口和視圖之間的連接
    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)建文檔模板時,將菜單資源標識(IDR_MAINFRAME)作為其中的一個參數(shù)傳入,當MFC底層代碼在創(chuàng)建框架窗口時,就會將此標識轉(zhuǎn)換為相應菜單句柄,然后去創(chuàng)建菜單和框架窗口。因此在這里將菜單設置為NULL,并不會影響菜單的創(chuàng)建。
關(guān)于為什么窗口背景和光標沒有改變
應用程序包含連個窗口:
l  應用程序框架窗口
l  視類窗口
前者包含了后者,后者覆蓋在前者上面。程序運行后我們看到的窗口實際上是視類窗口,而我們代碼中實際上修改的是框架窗口的背景和光標。應用程序的圖標屬于框架窗口,所以程序運行后看到圖標改變了。
改變背景和光標的操作我們應該放在視類中實現(xiàn),我們應該在視類窗口創(chuàng)建之前,即在PreCreateWindow函數(shù)中將窗口類設置為先前自定義的那個類,因為這是那個窗口類已經(jīng)注冊了,所以可以直接使用那么窗口類的名字:
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
       // TODO:  在此處通過修改
       //  CREATESTRUCT cs 來修改窗口類或樣式
       cs.lpszClass = _T("傳智播客");
       return CView::PreCreateWindow(cs);
}
在MFC中如果想修改應用程序的窗口的圖標,應該在框架類中進行,因為框架窗口中才有標題欄,所以才能修改位于標題欄上的圖標。如果想修改應用程序窗口的背景和光標,就應該在視類中進行。

方式2

通過上邊的例子我們可以知道,在框架類中只能修改窗口的圖標,而為了實現(xiàn)這一功能,我們需要重寫整個窗口類。顯然,這是一件很麻煩的事情,MFC給我們提供了一個全局函數(shù): AfxRegisterWndClass,用來設定窗口的類型、光標、圖標、背景。其函數(shù)原型定義如下:
        LPCTSTR AFXAPI AfxRegisterWndClass(
             UINT nClassStyle,
             HCURSOR hCursor = 0,
             HBRUSH hbrBackground = 0,
             HICON hIcon = 0
);
設置圖標:
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;
}
設置光標和背景色:
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: 指定要設置的索引
n  GCL_HBRBACKGROUND 設置新的背景畫刷
n  GCL_HCURSOR 設置新的光標
n  GCL_HICON 設置新的圖標
n  GCL_STYLE 設置新的窗口樣式

設置圖標:

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

設置光標和背景

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

本文版權(quán)歸傳智播客C++培訓學院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
作者:傳智播客C/C++培訓學院
首發(fā):http://metathetuscanyresort.com/c/
 
 
 
0 分享到:
和我們在線交談!