[MFC]_简单知识总结以及GDI程序简单设计

GDI(Graphics Device Interface)是图形设备接口的英文缩写,主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形和图像输出。GDI的出现使程序员无需要关心硬件设备及设备正常驱动,就可以将应用程序的输出转化为硬件设备上的输出和构成,实现了程序开发者与硬件设备的隔离,大大方便了开发工作。

  • 消息反射

windows的消息反射机制,通过控件之间的消息反射,用来实现较为复杂的多控件之间的交互问题.

在vs2019中,我们可以通过类向导,来为控件指定对应的消息反射,在类向导中,反射型的消息和单独的消息已经区分开了,反射性质的叫做命令,普通的消息叫为消息:

图片.png

当然,具体的消息类别,我们可以在逐渐的熟悉使用的过程中,来慢慢了解和学习.

  • 成员变量
图片.png

在类向导中同样可以设置虚函数,成员变量等其他功能,虚函数还不甚了解,这里简单记录下使用到的成员变量,通过类向导来为各个控件设置成员变量主要是快速便捷.
不过比较特殊的是,MFC中有重新封装控件类型,和值类型.当然,在大多时候,MFC封装的类型是更加好用的.但是有时候还是不太适应.

图片.png
  • 三大坐标系

基于MFC的窗口应用程序有三大基本坐标系:基于客户区,非客户区,屏幕.都是以左上角为坐标原点:

图片.png
  • 通过空项目来构建从头构建窗口项目

GDI(Graphics Device Interface)是图形设备接口的英文缩写,主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形和图像输出。GDI的出现使程序员无需要关心硬件设备及设备正常驱动,就可以将应用程序的输出转化为硬件设备上的输出和构成,实现了程序开发者与硬件设备的隔离,大大方便了开发工作。

在vs2019中创建一个空项目

图片.png

创建一个test_gdi.cpp文件,再添加一个dialog资源:

图片.png
图片.png
图片.png

进入资源属性界面,更改一下dialog的id: IDD_MAIN_DLG,设定为主窗口,在之后更改caption 改一下窗口的标题为test_GDI,设定后记得保存一下,查看头文件resource.h中有没有id的声明:

图片.png
图片.png

注意这里一定要有控件id的声明,否则cpp文件中是无法识别的.

再进入cpp文件中定义WinMain主函数(WinMain函数是windows窗口程序的入口函数,main函数在windows应用程序中是无法使用的),引入windows.h头文件和我们的resource,h资源头文件,记住四个主要的参数:

#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;
}

调试运行,在vs2019中,创建的空项目是不能直接运行窗口程序的,会报错:

图片.png

这主要是因为vs2019中空项目默认的编译是控制台程序,我们将项目属性中链接器->系统->子系统中的subsystem: console修改为windows.

图片.png

再次编译运行,输出窗口:

图片.png
  • WM_PAINT消息 :功能和发生时间,

  • beginPaint与EndPaint必须成对使用.

  • BeginPaint返回的DC句柄,是基于其所关联的窗口的客户区坐标系绘制图形的.

  • 在MFC中是把这两个函数封装为一个类:CPaintDC类的.

  • MFC第二大类 CDC绘图类.
    CDC类的核心句柄就是m_hdDC.它的绘图功能基本都是来自m_hDC句柄原有的功能.封装而成.
    派生类有:
    CPaint类,客户区标准绘图类,专门提供给WM_PAINT消息提供的.
    CClientDC类,客户区临时绘图类.在任何其他消息中都可以使用的.
    CWindowDC类: 非客户区标准绘图类,专门在WM_NC_PAINT消息下使用(不常使用,基本不会有使用到在非客户区进行绘制图像的使用场景).


要想在客户区进行标准绘图,首先要在回调函数 theProc中声明一个switch结构,来对各种不同类消息进行不同的处理:


// 窗口句柄参数:HWND hwnDlg, UINT 消息类型参数.
INT_PTR CALLBACK theProc(HWND hwnDlg,UINT uMsg,WPARAM wPream,LPARAM ipream) {

    switch (uMsg)
    {
// WM_NCPAINT消息是一个非客户区的一个绘制消息.
    case WM_NCPAINT:
         OnNCPaint(hwnDlg);
         return TRUE;
        // 绘图非常重要的一个消息,WM_PAINT消息,在客户区内绘制:
    case WM_PAINT:
        // 调用函数
        OnPaint(hwnDlg);
        return TRUE;
    
    case WM_COMMAND:
        if (wPream == IDCANCEL) {
            EndDialog(hwnDlg, IDCANCEL);
            return TRUE;
        }
        return FALSE;
    default:
        break;
    }
    return 0;
}

在switch结构中对应的消息支路上,调用对应的绘制函数,即可完成简单的绘制工作任务:

//定义一个OnPint函数,传入一个句柄参数,在MFC中将窗口句柄都封装到类中了:
void OnPaint(HWND hwndDlg) {

    // 相当于beginpaint
    PAINTSTRUCT ps;
    // HDC是一个绘图句柄,相当于指定绘制图形的窗口的作用.
    HDC hdc = BeginPaint(hwndDlg, &ps);
    // 在beginpaint与endpaint之间就可以进行绘图操作了,可以调用各种封装好的绘制函数来实现绘制各种东西的.

    /*
    椭圆绘制函数,五个参数,第一个是绘图句柄hdc类型的参数,指定绘制的窗口,
    其余四个int变量指定位置和椭圆的高度和宽度,也可以用来绘制圆形.
    WM_PAINT消息绘制是基于客户区绘制的.
    */

    // textout方法,绘制文本
    LPCSTR str = _T("text 测试消息");
    TextOut(hdc,100,100,str,strlen(str));

    Ellipse(hdc, 0, 0,100,100);
    // 结束的位置 endpaint 与beginpaint必须得成对使用才行
    EndPaint(hwndDlg,&ps);

    // 提供的一个控制台输出函数,相当于printf
    OutputDebugString(_T("WM_PAINT_onpaint \n"));

}
图片.png

WM_NCPAINT 消息是非客户区的标准绘图消息.可以通过该消息来实现在非窗口区的绘制(但是该方法一般不常使用).

void OnNCPaint(HWND hwndDlg) {

    // 获取坐标系,相当于屏幕.
    RECT rect;
    GetWindowRect(hwndDlg,&rect);


    // 获取一个窗口的HDC句柄对象.
    HDC hdc = GetWindowDC(hwndDlg); // CWindwDC在MFC中封装了getWindDC函数
    // 绘制矩形
    Rectangle(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top);

    // 在两个函数之间就可以执行一些绘图,或者文字输出的功能了
    LPCTSTR str =_T("testNCPaint消息");
    SetTextColor(hdc,RGB(255,0,0));
    TextOut(hdc, 2, 2,str,strlen(str));

    ReleaseDC(hwndDlg,hdc); //反函数是releaseDC,将hdc与窗口连接
}

图片.png

2019.12.20
8.42

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容