事件,消息,消息处理函数,第一个图形界面程序(附带官方解释链接)

简介: 事件,消息,消息处理函数,第一个图形界面程序(附带官方解释链接)

上一章节中我们讲解了Win32 API,Win32入口程序和宽字符,这一章节为大家介绍Win32中的事件,消息,消息处理函数,并且带领大家写出第一个图形界面程序。

一.事件,消息

Windows中的事件实际上是一个“动作”,这个动作可能是用户操作应用程序产生的,也可能是Windows自己产生的。而消息,就是用来描述这些动作的,比如这个动作何时产生,那个应用程序产生的,在哪个位置产生的。

Windows为了描述这些消息,提供了一个结构:

typedef struct{
HWND hwnd;          //窗口句柄
UINI message;       //消息类型
WPARM wParm;        //附加消息
LPARM lParm;        //附加消息
DWORD time;         //时间
POINT pt;         //坐标,表示动作的位置
}MSG,*PMSG;

其中,hwnd是窗口句柄,表示消息产生在哪个窗口,一个消息一般与一个窗口函数相关联,在Windows中一般HWND类型的变量用来标识窗口。

二.系统消息队列与应用消息队列

在这里给出一张图帮助大家理解:

我们来看看当某个动作触发消息,传送到应用程序的过程:

事件MSG→系统消息队列→应用程序消息队列→循环取出消息→处理消息

注意: 当应用程序处理消息的时候,与自己相关的消息会处理,与自己不相关的消息会交给windows处理。

  • 1.用户触发某个动作
  • 2.系统将这些信息存储到MSG结构体中
  • 3.系统将这些消息存储到相关应用程序的队列中
  • 4.应用程序循环取出消息
while(GetMessage(&MSG,NULL,0,0)){
Translatement(&MSG);    //翻译消息
DispatchMessage(&MSG);    //分发消息
}

  • 5.DispachMessage将加工过的消息传递给操作系统
  • 6.系统调用窗口过程函数

三.第一个图形界面程序

我们在写出第一个图形界面程序之前,我们要清楚步骤:

1.创建一个自己的窗口类

WNDCLASS wndclass;

我们来看看已经定义好的窗口类:

typedef struct tagWNDCLASSW {
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCWSTR   lpszMenuName;
  LPCWSTR   lpszClassName;
} WNDCLASSW, *PWNDCLASSW, *NPWNDCLASSW, *LPWNDCLASSW;

WNDCLASS结构注释

2.将类的对象全部赋值,记得一定要全部赋值,注册窗口的时候必须要完整的窗口类

3.注册窗口类

RegistrClass(&wndclass);
• 1

官方解释RegisterClassW function

4.创建窗口

HWND hwnd = CreateWindow();
• 1

CreateWindwo宏

5.显示窗口

ShowWindow(hwnd,SW_SHOW);
• 1

ShowWindow函数

6.消息循环

MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd,NULL, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

官方解释GetMessage函数

官方解释TranslateMessage函数

官方解释DispatchMessage函数

7.回调函数

这个我们会在下一章节中介绍到

// Win32VS版本.cpp : 定义应用程序的入口点。
//
#include "framework.h"
#include "Win32VS版本.h"
#define MAX_LOADSTRING 100
LRESULT CALLBACK WindowProc(
  IN  HWND hwnd,
  IN  UINT uMsg,
  IN  WPARAM wParam,
  IN  LPARAM lParam
);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    //窗口类名
    TCHAR className[] = L"My First Windows.";
    //创建窗口对象
    WNDCLASS wndclass = { 0 };
    wndclass.hbrBackground = (HBRUSH)COLOR_MENU;            //窗口背景颜色
    wndclass.lpfnWndProc = WindowProc;                    //窗口的过程函数
    wndclass.lpszClassName = className;                     //窗口的类名字
    wndclass.hInstance = hInstance;                         //定义窗口类的应用程序的实例句柄
    //注册窗口
    RegisterClass(&wndclass);
    //创建窗口
    HWND hwnd = CreateWindow(
        className,                          //lpname类名
        TEXT("我的第一个窗口。"),          //窗口标题
        WS_OVERLAPPEDWINDOW,               //dwStyle
        10,
        10,
        600,
        300,
        NULL,
        NULL,
        hInstance,
        NULL);
    //显示窗口
    ShowWindow(hwnd, SW_SHOW);
    // 主消息循环:
    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd,NULL, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (int) msg.wParam;
}
LRESULT CALLBACK WindowProc(
  IN  HWND hwnd,
  IN  UINT uMsg,
  IN  WPARAM wParam,
  IN  LPARAM lParam
)
{
  switch (uMsg)
  {
    //窗口消息              
  case WM_CREATE:
  {
    CREATESTRUCT* createst = (CREATESTRUCT*)lParam;
    return 0;
  }
  case WM_MOVE:
  {
    POINTS points = MAKEPOINTS(lParam);
    return 0;
  }
  case WM_SIZE:
  {
    int newWidth = (int)(short)LOWORD(lParam);
    int newHeight = (int)(short)HIWORD(lParam);
    return 0;
  }
  case WM_DESTROY:
  {
    PostQuitMessage(0);
    return 0;
  }
  //键盘消息              
  case WM_KEYUP:
  {
    return 0;
  }
  case WM_KEYDOWN:
  {
    return 0;
  }
  //鼠标消息              
  case WM_LBUTTONDOWN:
  {
    POINTS points = MAKEPOINTS(lParam);
    return 0;
  }
  }
  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
相关文章
|
6月前
|
Java API 调度
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
319 0
|
4月前
|
开发者
Qt中的事件该如何学习?(附带案例)
事件是Qt中比较重要的一部分,在初期如果理解不当学习可能会比较困难,这里提一嘴当初教我的那位老师水平是真的高,让我很轻易的就理解了事件的概念。 在平时我们见到那些界面上的某些快捷键就有可能是事件做的,例如ESC关闭窗口,Enter提交或者登录这种类似的,这也是事件的强大之处。
110 0
|
5月前
|
监控 Serverless Linux
函数计算操作报错合集之安装模块时遇到错误,该如何处理
在使用函数计算服务(如阿里云函数计算)时,用户可能会遇到多种错误场景。以下是一些常见的操作报错及其可能的原因和解决方法,包括但不限于:1. 函数部署失败、2. 函数执行超时、3. 资源不足错误、4. 权限与访问错误、5. 依赖问题、6. 网络配置错误、7. 触发器配置错误、8. 日志与监控问题。
|
Java
高级循环(附带小练习以及详细代码)
高级循环(附带小练习以及详细代码)
81 0
|
存储 文件存储
【课堂笔记】VB 自定义过程sub,消息窗体的输入输出,断点调试方法
【课堂笔记】VB 自定义过程sub,消息窗体的输入输出,断点调试方法
426 0
从零开始学Pyqt5之【如何解决自定义槽函数需要参数而信号没有参数传递的问题?(2种方式)】
从零开始学Pyqt5之【如何解决自定义槽函数需要参数而信号没有参数传递的问题?(2种方式)】
怎样使用阿里云消息服务?
阿里云消息服务(Message Service)是一种高效、可靠、安全、便捷、可弹性扩展的分布式消息服务。MNS能够帮助应用开发者在他们应用的分布式组件上自由的传递数据、通知消息,构建松耦合系统。 消息服务同时支持各种类型消息推送,其中和短信前后端的无缝整合更高效的为用户提供了大批量短信发送能力。