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

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

上一章节中我们讲解了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);
}
相关文章
|
5月前
|
Java API 调度
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
233 0
|
Java Linux 数据安全/隐私保护
R语言自动发送运行提示邮件
R语言自动发送运行提示邮件
|
2月前
|
开发工具
影创SDK☀️五、创建第一个手势交互的例子
影创SDK☀️五、创建第一个手势交互的例子
|
3月前
|
开发者
Qt中的事件该如何学习?(附带案例)
事件是Qt中比较重要的一部分,在初期如果理解不当学习可能会比较困难,这里提一嘴当初教我的那位老师水平是真的高,让我很轻易的就理解了事件的概念。 在平时我们见到那些界面上的某些快捷键就有可能是事件做的,例如ESC关闭窗口,Enter提交或者登录这种类似的,这也是事件的强大之处。
|
4月前
|
监控 Serverless Linux
函数计算操作报错合集之安装模块时遇到错误,该如何处理
在使用函数计算服务(如阿里云函数计算)时,用户可能会遇到多种错误场景。以下是一些常见的操作报错及其可能的原因和解决方法,包括但不限于:1. 函数部署失败、2. 函数执行超时、3. 资源不足错误、4. 权限与访问错误、5. 依赖问题、6. 网络配置错误、7. 触发器配置错误、8. 日志与监控问题。
|
监控 Python
Python自动发送消息小脚本,可用于各种聊天框~
Python自动发送消息小脚本,,懂的都懂~~
185 0
Python自动发送消息小脚本,可用于各种聊天框~
|
Java
高级循环(附带小练习以及详细代码)
高级循环(附带小练习以及详细代码)
73 0
PyWin32库操作微信自动发送消息
闲得无聊随便练练
125 0
|
存储 文件存储
【课堂笔记】VB 自定义过程sub,消息窗体的输入输出,断点调试方法
【课堂笔记】VB 自定义过程sub,消息窗体的输入输出,断点调试方法
418 0
|
Web App开发
Chrome 插件开发-桌面通知设置实战演示,设置通知显示、存在时间
Chrome 插件开发-桌面通知设置实战演示,设置通知显示、存在时间
702 0
Chrome 插件开发-桌面通知设置实战演示,设置通知显示、存在时间