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

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

上一章节中我们讲解了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);
}
相关文章
|
7月前
|
Python
【python自动化】Playwright基础教程(五)事件操作②悬停&输入&清除精讲
【python自动化】Playwright基础教程(五)事件操作②悬停&输入&清除精讲
180 0
|
存储 文件存储
【课堂笔记】VB 自定义过程sub,消息窗体的输入输出,断点调试方法
【课堂笔记】VB 自定义过程sub,消息窗体的输入输出,断点调试方法
431 0
从零开始学Pyqt5之【如何解决自定义槽函数需要参数而信号没有参数传递的问题?(2种方式)】
从零开始学Pyqt5之【如何解决自定义槽函数需要参数而信号没有参数传递的问题?(2种方式)】
win10显示此设备不支持接收miracast的解决办法【【百度的方法均不好使,自己发现的,亲测有效!!!!】】
win10显示此设备不支持接收miracast的解决办法【【百度的方法均不好使,自己发现的,亲测有效!!!!】】
win10显示此设备不支持接收miracast的解决办法【【百度的方法均不好使,自己发现的,亲测有效!!!!】】
|
Web App开发
Chrome 插件开发-桌面通知设置实战演示,设置通知显示、存在时间
Chrome 插件开发-桌面通知设置实战演示,设置通知显示、存在时间
744 0
Chrome 插件开发-桌面通知设置实战演示,设置通知显示、存在时间
讨论:有多少项目是因为程序的原因而失败的
导读:外刊IT评论翻译了一篇《关于程序成本的讨论》以下是文章全部内容: 昨天在#SCNA(北美2010软件技术大会)的一个专题小组讨论会上,@chadfowler 提出了这个问题:”有多少项目是因为程序的原因而失败的?“我想,他是想说造成项目失败的主要原因是业务问题,而非技术问题。
1066 0