C++ Windows编程设计预备篇(MFC)

C++ Windows编程预备(MFC)

##前言
写这篇文章目的是为了让大家知道学习MFC之前用到的知识,方便后面能很容易理解windows编程,MFC的文件结构以及框架。

##Windows程序设计基础

  • Dos与Windows

首先可以简单区分一下Windows与Dos,学了Windows操作系统,我们都知道Windows是可以在同一时间运行多个程序的,而Dos界面下这是一个过程接一个的。Windows中窗口是Windows程序的基本单元,Windows程序的运行过程就是窗口内部、窗口之间及窗口与用户之间的信息交换过程。

  • 事件驱动

事件是指人们应用计算机的过程中发生的操作,如移动鼠标。

  • 消息响应

每发生一个事件,就会产生一个与之对应的特定消息,该消息会被Windows系统捕获,然后将通过此消息调用执行与之对应的程序代码,实现相应的程序功能。

  • 系统消息队列

由Windows系统维护管理的消息队列,每当有消息发生时,该消息将首先被存入系统消息队列。

  • 应用程序消息队列

Windows系统会为每个应用程序建立一个独立的消息队列,用于存放该应用程序的消息。
消息循环:每个应用程序都有一个循环机构,该循环机构则不断地重复查看程序自身的消息队列,如果列中有消息,就将其取出并执行相应的消息处理代码,这个处理消息的循环机构称为消息循环

  • 事件驱动与消息循环原理*(注:此处为重点,前面概念就是为了解释原理)*

程序启动->等待用户操作程序窗口->操作引发事件产生消息->windows捕获分析(系统消息列)->程序消息队列->循环获取消息->窗口处理函数处理消息->实现程序功能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SN0C9DDB-1650768261873)(//img-blog.youkuaiyun.com/20180314223204555?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0Jvc3RvblJheUFsZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)]

  • Windows程序的组成
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SEOdKIik-1650768261875)(//img-blog.youkuaiyun.com/20180314225025375?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0Jvc3RvblJheUFsZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)]

##Windows程序设计的常用数据结构

  1. 句柄
    句柄是整个Windows编程的基础。一个句柄是指Windows使用的一个唯一的整数值,是一个4字长(32位无符号整数)的数值,用于标识应用程序中不同的对象和同类对象中不同的实例。总的来说就是应用程序通过句柄能够访问相应的对象信息。
  2. 数据类型
    数据结构跟编程语言里面都差不多。
  3. 点和矩形区域
    坐标,长宽,颜色有固定的结构体来描述。
  4. 消息结构

typedef struct tagMSG {
HWND hwnd; //消息发向的窗口句柄
UINT message; //消息标识符, WPARAM
LPARAM lParam; //32位的消息参数,值因消息异
DWORD time; //消息放入消息队列的时间
POINT pt; //消息放入消息队列的鼠标位置。
} MSG;

##Windows程序的基本结构
WinMain ( ) : 必有且仅有一个。是程序执行的入口点,类似于C程序中的main函数
窗口函数 : 每个窗口对应一个窗口函数,以响应该程序窗口中发生的事件消息。

##Windows程序的控制流程(重点

  • WinMain->程序启动->等待用户操作程序窗口->操作引发事件产生消息->windows捕获分析(系统消息列)->程序消息队列->循环获取消息->窗口处理函数处理消息->实现程序功能。

  • WinMain:调用API函数定义并注册窗口类,创建程序窗口,显示窗口,建立消息循环

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ykJIsnrB-1650768261875)(//img-blog.youkuaiyun.com/20180319173906326?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0Jvc3RvblJheUFsZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)]

##Windows程序的数据输出
这里以图形为例
1、程序首先获取设备环境句柄
2、通过该句柄调用图形设备接口的绘图函数绘图。
3、绘图函数所绘制的图形被Windows系统提供的设备驱动程序转换成具体物理设备的绘图函数,从而在具体硬件设备上绘制出图形。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MJs8Vv4o-1650768261876)(//img-blog.youkuaiyun.com/20180319222907987?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0Jvc3RvblJheUFsZW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)]

根据进程id和模块名称获取模块基址

PVOID GetProcessImageBase3(DWORD dwProcessId, const TCHAR*  moduleName)//dwProcessId就是程序的标识符
{
    PVOID pProcessImageBase = NULL;
    //打开进程, 获取进程句柄
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (NULL == hProcess)
    {
        return pProcessImageBase;
    }
    // 遍历进程模块,
    HMODULE hModule[100] = { 0 };
    DWORD dwRet = 0;
    BOOL bRet = EnumProcessModules(hProcess, (HMODULE*)(hModule), sizeof(hModule), &dwRet);
    if (FALSE == bRet)
    {
        CloseHandle(hProcess);
        return pProcessImageBase;
    }
    int iSel = 0;
    for (int i = 0; i < (dwRet / sizeof(HMODULE)); i++)
    {
        TCHAR szModName[MAX_PATH];
 
        // Get the full path to the module's file.
 
        if (GetModuleFileNameEx(hProcess, hModule[i], szModName,
            sizeof(szModName) / sizeof(TCHAR)))
        {
            // 遍历模块名,与传入的模块名比较,相同则记录序号(只比较文件名,不比较路径,注意文件名带扩展名)
            basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> >
                str(szModName);
            if (str.find_last_of('\\') >= 0)
                str = str.substr(str.find_last_of(_T("\\"))+1);
 
            if (_tcsicmp(str.c_str(), moduleName) == 0)
            {
                iSel = i;
                break;
            }
            _tprintf(TEXT("\t%s (0x%08X)\n"), szModName, hModule[i]);
        }
    }
    // 获取指定名称模块的加载基址,未找到则返回第0个
    pProcessImageBase = hModule[iSel];
    // 关闭句柄
    CloseHandle(hProcess);
    return pProcessImageBase;
}
 
 
int APIENTRY _tWinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPTSTR    lpCmdLine,
    int       nCmdShow)
{
    PVOID p = GetProcessImageBase3(12124, _T("devenv.exe"));//12124改成你的devenv.exe的pid
 
    return 0;
}
目 录 译者序 前言 第一部分 基础知识 第1章 窗口 2 1.1 窗口和API环境 2 1.1.1 三种类型窗口 2 1.1.2 客户区和非客户区 3 1.2 窗口和MFC环境 4 1.3 怎样应用MFC创建一个窗口 5 1.4 怎样使用MFC销毁一个窗口 9 1.4.1 捆绑到一个已有的窗口 9 1.4.2 窗口类 10 1.4.3 窗口进程 10 1.5 怎样使用MFC创建一个窗口类 11 1.5.1 使用AfxRegisterWndClass () 函数注册一个窗口类 11 1.5.2 使用AfxRegisterClass ()函数 创建一个窗口类 12 1.6 怎样销毁一个MFC窗口类 14 1.7 厂商安装的窗口类 14 1.8 其他类型窗口 15 1.9 桌面窗口 16 1.10 小结 16 第2章 类 18 2.1 基类 18 2.1.1 CObject 18 2.1.2 CCmdTarget 19 2.1.3 CWnd 19 2.2 应用程序、框架、文档和视图类 19 2.2.1 CWinApp(O/C/W) 20 2.2.2 CView (O/C/W) 21 2.3 其他用户界面类 22 2.3.1 通用控件类 23 2.3.2 菜单类 23 2.3.3 对话框类 24 2.3.4 控制条类 24 2.3.5 属性类 25 2.4 绘图类 25 2.4.1 设备环境类 25 2.4.2 图形对象类 25 2.5 文件类 26 2.6 数据库类 26 2.6.1 ODBC类 26 2.6.2 DAO类 27 2.7 数据集类 27 2.8 其他数据类 27 2.9 通信类 28 2.10 其他类 29 2.11 小结 31 第3章 消息处理 32 3.1 发送或寄送一个消息 32 3.1.1 发送一个消息 32 3.1.2 寄送一个消息 32 3.1.3 发送一个消息与寄送一个消息 的比较 32 3.2 怎样使用MFC发送一个消息 33 3.3 怎样用MFC寄送一个消息 33 3.4 三种类型的消息 34 3.4.1 窗口消息 34 3.4.2 命令消息 34 3.4.3 控件通知 34 3.5 MFC怎样接收一个寄送的消息 36 3.6 MFC怎样处理一个接收到的消息 36 3.7 处理用户界面的对象 44 3.8 创建自定义窗口消息 45 3.8.1 静态分配的窗口消息 45 3.8.2 动态分配的窗口消息 46 3.9 重定向消息 47 3.9.1 子分类和超分类 47 3.9.2 用MFC子分类窗口 48 3.9.3 重载OnCmdMsg ( ) 49 3.9.4 使用SetWindowsHookEx ( ) 49 3.9.5 使用SetCapture ( ) 49 3.9.6 专有的消息泵 50 3.10 小结 50 第4章 绘图 51 4.1 设备环境 51 4.2 在MFC环境中创建一个设备环境 52 4.2.1 屏幕 52 4.2.2 打印机 53 4.2.3 内存 54 4.2.4 信息 54 4.3 绘图例程 55 4.3.1 画点 55 4.3.2 画线 55 4.3.3 画形状 55 4.3.4 形状填充和翻转 55 4.3.5 滚动 56 4.3.6 绘制文本 56 4.3.7 绘制位图和图标 56 4.4 绘图属性 56 4.4.1 设备环境属性 57 4.4.2 画线属性 58 4.4.3 形状填充属性 58 4.4.4 文本绘制属性 58 4.4.5 映像模式 59 4.4.6 调色板属性 62 4.4.7 混合属性 62 4.4.8 剪裁属性 63 4.4.9 位图绘制属性 64 4.5 元文件和路径 65 4.5.1 元文件 65 4.5.2 路径 66 4.6 颜色和调色板 66 4.6.1 抖动色 67 4.6.2 未经抖动色 67 4.6.3 系统调色板 67 4.6.4 使用系统调色板 68 4.6.5 动画色 71 4.7 控制什么时候在哪里绘图 71 4.7.1 处理WM_PAINT 71 4.7.2 只绘制被无效化的区域 72 4.7.3 处理WM_DRAWIT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值