[MFC]_簡(jiǎn)單知識(shí)總結(jié)以及GDI程序簡(jiǎn)單設(shè)計(jì)

GDI(Graphics Device Interface)是圖形設(shè)備接口的英文縮寫,主要任務(wù)是負(fù)責(zé)系統(tǒng)與繪圖程序之間的信息交換,處理所有Windows程序的圖形和圖像輸出。GDI的出現(xiàn)使程序員無(wú)需要關(guān)心硬件設(shè)備及設(shè)備正常驅(qū)動(dòng),就可以將應(yīng)用程序的輸出轉(zhuǎn)化為硬件設(shè)備上的輸出和構(gòu)成,實(shí)現(xiàn)了程序開發(fā)者與硬件設(shè)備的隔離,大大方便了開發(fā)工作。

  • 消息反射

windows的消息反射機(jī)制,通過(guò)控件之間的消息反射,用來(lái)實(shí)現(xiàn)較為復(fù)雜的多控件之間的交互問(wèn)題.

在vs2019中,我們可以通過(guò)類向?qū)?來(lái)為控件指定對(duì)應(yīng)的消息反射,在類向?qū)е?反射型的消息和單獨(dú)的消息已經(jīng)區(qū)分開了,反射性質(zhì)的叫做命令,普通的消息叫為消息:

圖片.png

當(dāng)然,具體的消息類別,我們可以在逐漸的熟悉使用的過(guò)程中,來(lái)慢慢了解和學(xué)習(xí).

  • 成員變量
圖片.png

在類向?qū)е型瑯涌梢栽O(shè)置虛函數(shù),成員變量等其他功能,虛函數(shù)還不甚了解,這里簡(jiǎn)單記錄下使用到的成員變量,通過(guò)類向?qū)?lái)為各個(gè)控件設(shè)置成員變量主要是快速便捷.
不過(guò)比較特殊的是,MFC中有重新封裝控件類型,和值類型.當(dāng)然,在大多時(shí)候,MFC封裝的類型是更加好用的.但是有時(shí)候還是不太適應(yīng).

圖片.png
  • 三大坐標(biāo)系

基于MFC的窗口應(yīng)用程序有三大基本坐標(biāo)系:基于客戶區(qū),非客戶區(qū),屏幕.都是以左上角為坐標(biāo)原點(diǎn):

圖片.png
  • 通過(guò)空項(xiàng)目來(lái)構(gòu)建從頭構(gòu)建窗口項(xiàng)目

GDI(Graphics Device Interface)是圖形設(shè)備接口的英文縮寫,主要任務(wù)是負(fù)責(zé)系統(tǒng)與繪圖程序之間的信息交換,處理所有Windows程序的圖形和圖像輸出。GDI的出現(xiàn)使程序員無(wú)需要關(guān)心硬件設(shè)備及設(shè)備正常驅(qū)動(dòng),就可以將應(yīng)用程序的輸出轉(zhuǎn)化為硬件設(shè)備上的輸出和構(gòu)成,實(shí)現(xiàn)了程序開發(fā)者與硬件設(shè)備的隔離,大大方便了開發(fā)工作。

在vs2019中創(chuàng)建一個(gè)空項(xiàng)目

圖片.png

創(chuàng)建一個(gè)test_gdi.cpp文件,再添加一個(gè)dialog資源:

圖片.png
圖片.png
圖片.png

進(jìn)入資源屬性界面,更改一下dialog的id: IDD_MAIN_DLG,設(shè)定為主窗口,在之后更改caption 改一下窗口的標(biāo)題為test_GDI,設(shè)定后記得保存一下,查看頭文件resource.h中有沒(méi)有id的聲明:

圖片.png
圖片.png

注意這里一定要有控件id的聲明,否則cpp文件中是無(wú)法識(shí)別的.

再進(jìn)入cpp文件中定義WinMain主函數(shù)(WinMain函數(shù)是windows窗口程序的入口函數(shù),main函數(shù)在windows應(yīng)用程序中是無(wú)法使用的),引入windows.h頭文件和我們的resource,h資源頭文件,記住四個(gè)主要的參數(shù):

#include<Windows.h>
#include"resource.h"

INT_PTR CALLBACK theProc(
    HWND hwnDlg,
    UINT Msg,
    WPARAM wPream,
    LPARAM ipream) {
    return 0;
}

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPTSTR sCmdLine,int nCmd) {

    DialogBox(hInst, (LPCSTR)IDD_MAIN_DLG, NULL, theProc);
    return 0;
}

調(diào)試運(yùn)行,在vs2019中,創(chuàng)建的空項(xiàng)目是不能直接運(yùn)行窗口程序的,會(huì)報(bào)錯(cuò):

圖片.png

這主要是因?yàn)関s2019中空項(xiàng)目默認(rèn)的編譯是控制臺(tái)程序,我們將項(xiàng)目屬性中鏈接器->系統(tǒng)->子系統(tǒng)中的subsystem: console修改為windows.

圖片.png

再次編譯運(yùn)行,輸出窗口:

圖片.png
  • WM_PAINT消息 :功能和發(fā)生時(shí)間,

  • beginPaint與EndPaint必須成對(duì)使用.

  • BeginPaint返回的DC句柄,是基于其所關(guān)聯(lián)的窗口的客戶區(qū)坐標(biāo)系繪制圖形的.

  • 在MFC中是把這兩個(gè)函數(shù)封裝為一個(gè)類:CPaintDC類的.

  • MFC第二大類 CDC繪圖類.
    CDC類的核心句柄就是m_hdDC.它的繪圖功能基本都是來(lái)自m_hDC句柄原有的功能.封裝而成.
    派生類有:
    CPaint類,客戶區(qū)標(biāo)準(zhǔn)繪圖類,專門提供給WM_PAINT消息提供的.
    CClientDC類,客戶區(qū)臨時(shí)繪圖類.在任何其他消息中都可以使用的.
    CWindowDC類: 非客戶區(qū)標(biāo)準(zhǔn)繪圖類,專門在WM_NC_PAINT消息下使用(不常使用,基本不會(huì)有使用到在非客戶區(qū)進(jìn)行繪制圖像的使用場(chǎng)景).


要想在客戶區(qū)進(jìn)行標(biāo)準(zhǔn)繪圖,首先要在回調(diào)函數(shù) theProc中聲明一個(gè)switch結(jié)構(gòu),來(lái)對(duì)各種不同類消息進(jìn)行不同的處理:


// 窗口句柄參數(shù):HWND hwnDlg, UINT 消息類型參數(shù).
INT_PTR CALLBACK theProc(HWND hwnDlg,UINT uMsg,WPARAM wPream,LPARAM ipream) {

    switch (uMsg)
    {
// WM_NCPAINT消息是一個(gè)非客戶區(qū)的一個(gè)繪制消息.
    case WM_NCPAINT:
         OnNCPaint(hwnDlg);
         return TRUE;
        // 繪圖非常重要的一個(gè)消息,WM_PAINT消息,在客戶區(qū)內(nèi)繪制:
    case WM_PAINT:
        // 調(diào)用函數(shù)
        OnPaint(hwnDlg);
        return TRUE;
    
    case WM_COMMAND:
        if (wPream == IDCANCEL) {
            EndDialog(hwnDlg, IDCANCEL);
            return TRUE;
        }
        return FALSE;
    default:
        break;
    }
    return 0;
}

在switch結(jié)構(gòu)中對(duì)應(yīng)的消息支路上,調(diào)用對(duì)應(yīng)的繪制函數(shù),即可完成簡(jiǎn)單的繪制工作任務(wù):

//定義一個(gè)OnPint函數(shù),傳入一個(gè)句柄參數(shù),在MFC中將窗口句柄都封裝到類中了:
void OnPaint(HWND hwndDlg) {

    // 相當(dāng)于beginpaint
    PAINTSTRUCT ps;
    // HDC是一個(gè)繪圖句柄,相當(dāng)于指定繪制圖形的窗口的作用.
    HDC hdc = BeginPaint(hwndDlg, &ps);
    // 在beginpaint與endpaint之間就可以進(jìn)行繪圖操作了,可以調(diào)用各種封裝好的繪制函數(shù)來(lái)實(shí)現(xiàn)繪制各種東西的.

    /*
    橢圓繪制函數(shù),五個(gè)參數(shù),第一個(gè)是繪圖句柄hdc類型的參數(shù),指定繪制的窗口,
    其余四個(gè)int變量指定位置和橢圓的高度和寬度,也可以用來(lái)繪制圓形.
    WM_PAINT消息繪制是基于客戶區(qū)繪制的.
    */

    // textout方法,繪制文本
    LPCSTR str = _T("text 測(cè)試消息");
    TextOut(hdc,100,100,str,strlen(str));

    Ellipse(hdc, 0, 0,100,100);
    // 結(jié)束的位置 endpaint 與beginpaint必須得成對(duì)使用才行
    EndPaint(hwndDlg,&ps);

    // 提供的一個(gè)控制臺(tái)輸出函數(shù),相當(dāng)于printf
    OutputDebugString(_T("WM_PAINT_onpaint \n"));

}
圖片.png

WM_NCPAINT 消息是非客戶區(qū)的標(biāo)準(zhǔn)繪圖消息.可以通過(guò)該消息來(lái)實(shí)現(xiàn)在非窗口區(qū)的繪制(但是該方法一般不常使用).

void OnNCPaint(HWND hwndDlg) {

    // 獲取坐標(biāo)系,相當(dāng)于屏幕.
    RECT rect;
    GetWindowRect(hwndDlg,&rect);


    // 獲取一個(gè)窗口的HDC句柄對(duì)象.
    HDC hdc = GetWindowDC(hwndDlg); // CWindwDC在MFC中封裝了getWindDC函數(shù)
    // 繪制矩形
    Rectangle(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top);

    // 在兩個(gè)函數(shù)之間就可以執(zhí)行一些繪圖,或者文字輸出的功能了
    LPCTSTR str =_T("testNCPaint消息");
    SetTextColor(hdc,RGB(255,0,0));
    TextOut(hdc, 2, 2,str,strlen(str));

    ReleaseDC(hwndDlg,hdc); //反函數(shù)是releaseDC,將hdc與窗口連接
}

圖片.png

2019.12.20
8.42

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容