Windows SDK(二)窗口程序创建流程

窗口程序创建流程

1.填充窗口类 

2.创建窗口

3.显示窗口

4.更新窗口

5.建立消息循环

6.实现窗口过程函数

程序预先处理、

#include 包含头文件

const WCHAR *wszClassName = L"rkvir"; 定义一个窗口类名

const WCHAR *wszTitle = L"GrkDemo"; 定义一个标题名

填充窗口类 

声明主窗口过程

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  声明主窗口过程 CALLBACK为回调函数 参数依次是 窗口句柄 消息 参数 参数

{

    switch (message) 根据接收到的消息进行不同的分发

    {

    case WM_COMMAND:  处理应用的程序菜单,如点击程序帮助,接收的消息都会发送到此处

    {

       break;

    }

    case WM_PAINT: 绘制主窗口

    {

       PAINTSTRUCT ps; PAINTSTRUCT为一个结构,包含窗口的信息

       HDC hDC = BeginPaint(hWnd, &ps); 绘制窗口 参数依次 窗口句柄 窗口结构

       EndPaint(hWnd, &ps);

       break;

    }

    case WM_DESTROY: 退出程序,必须有,否则点击窗口关闭,窗口消失但线程无法结束

    {

       PostQuitMessage(0); 向操作系统发送已经终止/退出的请求

       break;

    }

    default:

       return DefWindowProc(hWnd, message, wParam, lParam); 默认窗口过程,处理接不住的消息

       break;

    }

    return 0;

}

声明窗口

ATOM MyRegisterClass(HINSTANCE hInstance)  ATOM实际是WORD别名

{

    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX); 填充结构尺寸

    wcex.style = CS_HREDRAW | CS_VREDRAW; 填充窗口的风格

    wcex.lpfnWndProc = WndProc; Windows窗口的主过程(消息的处理函数)

    wcex.cbClsExtra = 0; 跟在窗口类结构后面的附加字节数,给类预留的空间

    wcex.cbWndExtra = 0; 跟在窗口实例后面的附加字节数,给实例预留的空间

    wcex.hInstance = hInstance; 实例句柄

    wcex.hIcon = 0; 图标 如果没有则值为0,若有调用oadIcon接口,图标的格式是ico

    wcex.hCursor = 0; 光标 如果没有则值为0,若有调用LoadCursor接口加载

    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 类背景画笔的句柄

    wcex.lpszMenuName = 0; 菜单的句柄,没有时值为0

    wcex.lpszClassName = wszClassName; 指向类名称的句柄,一般说类名称必须有

    wcex.hIconSm = 0; 任务栏图标,如果没有则值为0,若有调用oadIcon接口

    return RegisterClassExW(&wcex); 注册窗口类

}

创建显示更新窗口

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow); 初始化即创建窗口 参数为实例句柄和显示模式

{

    HWND hWnd = CreateWindow(wszClassName , wszTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 500, 500, nullptr, nullptr, hInstance, nullptr);

参数依次 窗口类名称 标题名 风格 x坐标,如上参数是一个绝对坐标 y坐标 宽度 高度 副窗口句柄,没有写nullptr 菜单句柄,没有写nullptr 实例句柄 参数,没有填nullptr,其返回值是一个窗口句柄

此时窗口在内存中被创建,但并没有被显示

    if (!hWnd) 判断窗口是否被创建

    {

       return FALSE; 窗口创建失败,直接返回

    }

    ShowWindow(hWnd, nCmdShow); 显示窗口:参数依次窗口句柄 命令行用于填充显示模式

    UpdateWindow(hWnd); 更新窗口 参数为句柄

    return TRUE;

}

建立消息循环

当主程序代码块为空时,程序运行时有控制台一闪而过,利用system(“pause”)可以观察到,但是

Windows程序内会有一个消息循环(死循环)所以可以不用利用该函数

Windows是以消息驱动的操作系统,需要不停获取消息并分发,也叫消息循环

进程中存在消息队列,用于存储消息。

Windows系统会对消息进行填充并发放到消息队列中,此时进程类的窗口的消息循环会从队列中取

回并派发到窗口过程函数中进行处理,处理完毕后返回到消息循环,再次访问消息队列,重复以上

操作,叫做消息循环

消息结构包含:

HWND        hwnd;        窗口句柄

UINT        message;     消息

WPARAM      wParam;      消息的附加信息

LPARAM      lParam;      消息的附加信息

DWORD       time;        消息的创建发布时间

POINT       pt;          消息发送时,光标所在的位置

MSG msg; MSG结构:消息结构 GetMessage在消息队列中获取消息

实现窗口过程函数

while (GetMessage(&msg,nullptr,0,0)) 窗口主循环,它是个死循环,GetMessage()参数依次是 消息地址 其余默认填nullptr 0 0

{

   TranslateMessage(&msg); 翻译传入的消息,如键盘打字传入的消息是虚拟键码,此处转换成字符消息

   DispatchMessage(&msg); 派发消息

}

主程序编写

程序入口 参数依次实例句柄 被启用的实例句柄 命令行 LPWSTR实际是对WCHAR的封装,与之类

似还有LPSTR和char 显示模式,int类型

int APIENTRY wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR              

lpCmdLine,int nCmdShow)

{

    MyRegisterClass(hInstance); 填充窗口类

    if (!InitInstance(hInstance, nCmdShow)) 判断该窗口是否创建成功

    {

       return FALSE;

    }

    MSG msg; 

    while (GetMessage(&msg,nullptr,0,0)) 

    {    

       TranslateMessage(&msg); 

       DispatchMessage(&msg); 

    }

    return 0;

}

此时一个窗口构建完毕,运行程序结果是

Windows SDK(二)窗口程序创建流程_第1张图片

你可能感兴趣的:(windows)