Windows编程

简介: Windows编程

WINDOWS编程

控制台程序 Console

DOS程序,本身没有窗口,通过Windows DOS窗口执行

窗口程序

拥有自己的窗口,可以与用户交互

库程序

存放代码,数据的程序,执行文件可以从中取出代码执行和获取数据

静态库:扩展名LIB,在编译链接程序时,将代码放入执行文件中

动态库:扩展名DLL,在执行文件执行时从中获取代码

开发工具和库

编译工具

编译器 CL.EXE 将源代码编译成目标代码

链接器 LINK.EXE 将目标代码,库链接生成最终文件

资源编译器RC.EXE 将资源编译,最终通过链接器存入最终文件

C:\Program Files(x86)\Microsoft Visual Studio 10.0\VC\bin

库和头文件

Windows库

kernel32.dll 提供了核心的API,例如进程,线程,内存管理等

user32.dll 提供了窗口,消息等API

gdi32.dll 绘图相关的API

路径 C:\Windows\System32

头文件

windows.h 所有windows头文件的集合

windef.h windows数据类型

winbase.h kernel32的API

wingdi.h gdi32的API

winuser.h user32的API

winnt.h UNICODE字符集支持

相关函数

WinMain函数

int WINAPI WinMain(
•   HINSTANCE hInstance   //当前程序的实例句柄
•   HINSTANCE hPrevInstance  //当前程序的前一个实例句柄
•   LPSTR lpCmdLine  //命令行参数字符串
•   int nCmdShow  //窗口的显示方式
)
int MessageBox(
•   HWND hWnd //父窗口句柄
•   LPCTSTR lpText  //显示在消息框中的文字
•   LPCTSTR lpCaption   //显示在标题栏中的文字
•   UINT uType  //消息框中的按钮,图标显示类型
)  ;//返回点击的按钮ID

窗口创建过程

定义WInMain函数

定义窗口处理函数(自定义,处理消息)

注册窗口类(向操作系统写入一些数据)

创建窗口(内存中创建窗口)

显示窗口(绘制窗口的图像)

消息循环(获取/翻译/派发消息)

消息处理

字符编码

ASC

7位128个

ASCII

8位256个

DBCS

单双字节混合编码

UNICODE

几乎所有国家的字符

Ubuntu一般使用UTF-8,Windows使用的UTF-16

宽字节字符

wchar_t 每个字符占两个字节,不是基本的数据类型,实际上是unsigned short类型

定义时,需要加"L"

通知编译器按照双字节编译字符串

wchar_t* pwszText=L"Hello World";

TCHAR

定义Unicode宏的情况下是wchar_t

否则是char

#ifdef UNICODE
typedef wchar_t TCHAR;
#define __TEXT.(quote) L##quote
#else
typedef char TCHAR;
#define __TEXT(quote) quote
#endif

系统调用函数的参数类型

LPSTR===char
LPCSTR===const char*
LPWSTR===wchar_t*
LPCWSTR===const wchar_t*
LPTSTR===TCHAR*
LPCTSTR===const TCHAR*

注册窗口类

窗口类的概念

  • 窗口类就是包含了窗口各种参数信息的数据结构
  • 每个窗口都具有窗口类,基于窗口类创建窗口
  • 每个窗口类都有一个名称,使用前必须注册到系统

窗口类是操作系统内核的一堆数据

窗口类的分类

系统窗口类

系统已经定义好的窗口类,所有应用程序都可以直接使用

应用程序全局窗口类

由用户自己定义,当前应用程序所有模块都可以使用

应用程序局部窗口类

由用户自己定义,当前应用程序中本模块都可以使用

注册窗口类

typedef struct_WNDCLASS{
    int cbClsExtra;//窗口类的附加数据缓冲区字节大小
    int cbWndExtra;//窗口的附加数据缓冲区字节大小
    HBRUSH hbrBackground;//窗口背景画刷句柄
    HICON  hIcon;//窗口图标句柄
    HCURSOR  hCursor;//窗口光标句柄
    HINSTANCE  hInstance;//当前模块实例句柄
    WNDPROC lpfnWndProc;//窗口处理函数
    LPCTSTR lpszClassName;//窗口类名
    LPCTSTR lpszMenuName;//窗口菜单的资源ID字符串
    UINT style;//窗口类的风格
}WNDCLASS *PWNDCLASS;

style的几个参数:

CS_DBCLKS 允许窗口接收鼠标双击

CS_NOCLOSE 窗口没有关闭按钮

全局和局部窗口类

style窗口类风格

应用程序全局窗口类注册,需要在窗口类的风格中增加CS_GLOBALCLASS。

例如:

WNDCLASS wce={0};

wce.style=....|CS_GLOBALCLASS

不增加CS_GLOBALCLASS就是局部窗口类

不建议用全局窗口类,全局窗口类能完成的局部窗口类也能完成

创建窗口

HWND CreateWindowEx(          DWORD dwExStyle,
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);

注册窗口类的两个重要成员

wc.hInstance=Ins;

wc.lpszClassName="Main";

CreateWindowEx

进入这个函数就进入内核态

CreateWindowEx(.."Main",...hIns..)

消息的概念和作用

系统根据传入窗口类名称,在应用程序局部窗口类中查找,如果找到执行2,如果未找到执行3

比较局部窗口类和创建窗口传入的HINSTANCE变量。如果发现相等,创建和注册的窗口类在同一模块(进程),创建窗口返回。如果不相等,继续执行3

在应用程序全局窗口类,如果找到,执行4,如果没有找到执行5

使用找到的窗口类的信息,创建窗口返回

在系统窗口类中查找,如果找到创建窗口返回,否则创建窗口失败

创建子窗口

创建时要设置父窗口句柄

创建风格要增加WS_CHILD|WS_VISIBLE

消息基础

消息的概念和作用

消息组成

窗口句柄

消息ID

消息的两个参数(两个附带信息)

消息的产生时间

消息产生时的鼠标位置

typedef struct tagMSG
{
HWND hwnd; // 消息所指窗口句柄
UINT message; //消息名称,形式如WM_SIZE
WPARAM wParam; //32位消息的特定附加信息
LPARAM lParam; //32位消息的特定附加信息
DWORD time; //消息创建时间
POINT pt; //消息创建时的鼠标位置
} MSG;

消息的作用

ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
MSG nMsg={0};
while(GetMessage(&nMsg,NULL,0,0)){
  TranslateMessage(&nMsg);
  DispatchMessage(&nMSg);
}

当系统通知窗口工作时,就采用消息的方式派发给窗口

每个窗口都必须有窗口处理函数

//窗口处理函数
LRESULT CALLBACK WindowProc(
    HWND hwnd;
    UNIT uMsg;
    WPARAM wParam;
    LPARAM IParam;
)

当系统通知窗口时,会调用窗口处理函数,同时将消息ID和消息参数传递给窗口处理函数。在窗口处理函数中,不处理消息,使用缺省窗口处理函数。例如:DefWindowProc

可以给各种消息做默认处理

三个消息处理函数

BOOL GetMessage(
    LPMSG lpMsg**,** // address of structure with message
    HWND hWnd**,** // handle of window
    UINT wMsgFilterMin**,** // first message
    UINT wMsgFilterMax // last message
);

lpMsg 当获取到消息后,将消息的参数存放到MSG结构中

hWnd 获取到hWnd所指定窗口的消息

BOOL TranslateMessage(
    CONST MSG **lpMsg* // address of structure with message
);

TranslateMessage将按键消息翻译成字符消息

检查消息是否是按键消息,如果不是按键消息,不做处理,继续执行

LONG DispatchMessage(
    CONST MSG *lpmsg
     // pointer to structure with message
);

将消息派发到该消息所属窗口的窗口处理函数上

常见消息

一个消息需要掌握的三个方面

产生时间

附带的两个信息告诉我们什么

消息的一般用法(能拿来做什么)

常见的消息

WM_DESTROY

产生时间:窗口被销毁时的消息

附带信息:wParam 为0

lParam 为0

一般用法:常用于窗口被销毁之前,做相应的善后处理,例如资源,内存等

WM_SYSCOMMAND

产生时间:当点击窗口的最大化,最小化,关闭等

附带信息:wParam 具体点击的位置,例如关闭SC_CLOSE等

lParam 鼠标光标的位置

LOWORD(lParam)//水平位置

HIWORD(lParam)//垂直位置

一般用法:常用在窗口关闭时,提示用户处理

WM_CREATE

产生时间:在窗口创建成功但还未显示时

附带信息:wParam 为0

lParam 为CREATESTRUCT类型的指针

通过这个指针可知获取CreateWindowEx中的全部12个参数的信息

一般用法:常用于初始化窗口的参数,资源等等,包括创建子窗口

WM_SIZE

产生时间:在窗口大小发生变化后

附带信息:wParam 窗口大小变化的原因

lParam 窗口变化后的大小

LOWORD(lParam)//变化后的宽度

HIWORD(lParam)//变化后的高度

一般用法:常用于窗口大小变化后,调整窗口内各个部分的布局

消息循环原理

GetMessage从系统获取信息,将消息从系统中移除,阻塞函数。当系统无消息时,会阻塞等候下一条消息。

PeekMessage 以查看的方式从系统中获取消息,可以不将消息从系统中移除,非阻塞函数。当系统无消息时,返回False,继续执行后续代码

BOOL PeekMessage(
LPMSG lpMsg**,** // pointer to structure for message
HWND hWnd**,** // handle to window
UINT wMsgFilterMin**,** // first message
UINT wMsgFilterMax**,** // last message
UINT wRemoveMsg // removal flags
);

发送消息

SendMessage 发送消息,会等候消息处理结果

PostMessage 投递消息,消息发出之后立刻返回,不等候消息执行结果

LRESULT SendMessage(
HWND hWnd**,** // handle of destination window
UINT Msg**,** // message to send
WPARAM wParam**,** // first message parameter
LPARAM lParam // second message parameter
);

消息分类

系统消息-ID范围 0-0x03FF

由系统定义好的消息,可以在程序中直接使用

用户自定义消息 ID范围 0x0400-0x7FFF

由用户自己定义,满足用户自己的需求,由用户自己发出消息,并响应处理

自定义消息宏:WM_USER

消息队列

  • 用来存放消息的队列
  • 消息在队列中先入先出
  • 所有窗口程序都具有消息队列
  • 程序可以从队列中获取信息

消息队列的分类

  • 系统消息队列-由系统维护消息队列,存放系统产生的消息,例如鼠标,键盘
  • 程序消息队列-属于每一个应用程序的消息队列,由应用程序维护

消息和消息队列的关系

1.当鼠标,键盘产生消息时,会将消息存放到系统消息队列

2.系统会根据存放的消息,找到对应程序的消息队列

3.将消息投递到程序的消息队列

根据消息和消息队列的关系,将消息分为两类:

  • 队列消息
  • 非队列消息

常见的队列消息:键盘,鼠标,定时器,WM_PAINT

键盘消息

WM_KEYDOWN 按键被按下时产生

WM_KEYUP 按键被放开时产生

WM_SYSKEYDOWN 系统键按下时产生,比如ALT,F10

WM_SYSKEYDOWN 系统键放开时产生

附带信息

WPARAM 按键的Virtual Key

LPARAM 按键的参数,按下次数

鼠标消息

鼠标消息分类

基本鼠标消息

WM_LBUTTONDOWN 鼠标左键按下

WM_LBUTTONUP 鼠标左键抬起

WM_RBUTTONDOWN 鼠标右键按下

WM_RBUTTONUP 鼠标右键抬起

WM_MOUSEMOVE 鼠标移动消息

双击消息

WM_LBUTTONDBLOCK 鼠标左键双击

WM_RBUTTONDBLOCK 鼠标右键双击

滚轮消息

WM_MOUSEWHELL 鼠标滚轮消息

附带信息:

wPARAM 其他按键的状态,例如Ctrl/Shift等

lPARAM 鼠标的位置,窗口客户区坐标系

一般情况鼠标按下/抬起成对出现,在鼠标移动过程中,会根据移动速度产生一系列WM_MOUSEMOVE消息

定时器消息

定时器消息的介绍

在程序中创建定时器,当到达时间间隔时,定时器想程序发送一个WM_TIMER消息,定时器的精度是毫秒,但是准确度很低,例如设置时间间隔为1000ms,但是会在非1000ms到达消息

附带信息:wPARAM 定时器ID

lPARAM 定时器处理函数的指针

UINT SetTimer(  
  **HWND** *hWnd***,** // handle of window for timer messages  
  **UINT** *nIDEvent***,** // timer identifier  
  **UINT** *uElapse***,** // time-out value  
  **TIMERPROC** *lpTimerFunc* // address of timer procedure
  **);**
BOOL KillTimer(
    HWND hWnd,
     // handle of window that installed timer
    UINT uIDEvent
     // timer identifier
);

菜单资源

菜单分类

  • 窗口的顶层菜单
  • 弹出式菜单
  • 系统菜单

菜单资源的使用

添加菜单资源

加载菜单资源

  • 注册窗口类时设置菜单
  • 创建窗口传参设置菜单
  • 在主窗口WM_CREATE消息中利用SetMenu函数设置菜单

未完待续

相关文章
|
10月前
|
消息中间件 C++ Windows
02 MFC - Windows 编程模型
02 MFC - Windows 编程模型
39 0
|
11月前
|
监控 编译器 API
[笔记]Windows核心编程《二十二》注入DLL和拦截API(一)
[笔记]Windows核心编程《二十二》注入DLL和拦截API
201 0
|
7天前
|
数据库 Windows
超详细步骤解析:从零开始,手把手教你使用 Visual Studio 打造你的第一个 Windows Forms 应用程序,菜鸟也能轻松上手的编程入门指南来了!
【8月更文挑战第31天】创建你的第一个Windows Forms (WinForms) 应用程序是一个激动人心的过程,尤其适合编程新手。本指南将带你逐步完成一个简单WinForms 应用的开发。首先,在Visual Studio 中创建一个“Windows Forms App (.NET)”项目,命名为“我的第一个WinForms 应用”。接着,在空白窗体中添加一个按钮和一个标签控件,并设置按钮文本为“点击我”。然后,为按钮添加点击事件处理程序`button1_Click`,实现点击按钮后更新标签文本为“你好,你刚刚点击了按钮!”。
22 0
|
1月前
|
编译器 开发工具 C语言
解锁QtCreator跨界神技!Windows下轻松驾驭OpenCV动态库,让你的跨平台开发如虎添翼,秒变视觉编程大师!
【8月更文挑战第4天】QtCreator是一款强大的跨平台IDE,便于创建多平台应用。本教程教你如何在Windows环境下集成OpenCV库至Qt项目。首先,下载匹配MinGW的OpenCV预编译版并解压。接着,在QtCreator中新建或打开项目,并在.pro文件中添加OpenCV的头文件和库文件路径。确保编译器设置正确。随后编写测试代码,例如加载和显示图片,并进行编译运行。完成这些步骤后,你就能在QtCreator中利用OpenCV进行图像处理开发了。
77 6
|
3月前
|
Java C++
jni编程(windows+JDK11+clion)
jni编程(windows+JDK11+clion)
|
4月前
|
API C++ Windows
windows编程入门_链接错误的配置
windows编程入门_链接错误的配置
44 0
|
11月前
|
C++ Windows
[笔记]Windows核心编程《番外篇》几种常见的执行命令行方法
[笔记]Windows核心编程《番外篇》几种常见的执行命令行方法
|
4月前
|
Windows
火山中文编程 -- 第一个windows程序
火山中文编程 -- 第一个windows程序
28 0
|
4月前
|
编译器 API Windows
windows编程基础
windows编程基础
33 0
|
4月前
|
Windows
win32编程 -- windows绘图操作
win32编程 -- windows绘图操作
56 0
下一篇
DDNS