Win32开发之初识
一.Win32 基本简介
Windows被开发出来之后,向上提供了一套16/32位的API接口,我们称之为Win16/Win32,当然Win16已经随着16位Windows操作系统被淘汰,但是Win32 API接口一直延续到现在;早期的应用程序都是采用C/C++配合Win32 API去构建和开发出来的,这种方式我们称之为Windows古典应用程序开发!
下面引用Win32编程书籍中一段话:
二.Win32 基本概念
1. 窗体
Windows窗体其实就是屏幕上的一个矩形区域,可以响应用户的输入和操作,以文本或者图形的格式来展示!
2. 句柄
句柄其实是Windows上面用来标识一个实体对象的一个ID,比如:文件句柄(标识打开的文件对象),窗体句柄(标识一个窗体对象),内核对象句柄(信号量,互斥量,事件等)
3. 消息
Windows是靠消息来驱动的,所有的动作/事件都被映射成一个消息,通过消息我们可以知晓当前发生的动作或者事件!
4. 消息模型

5. 消息队列
1. 系统队列:操作系统维护的消息队列!
2. 应用队列:GUI应用程序的消息队列!
3. 消息泵:获取消息-加工消息-消息分发!
6. 消息类型
同步消息:不放置队列,直接交付窗口过程处理等待处理!PostMessage
异步消息:放置队列中,不等待异步处理!SendMessage
7. 消息处理
窗口过程:其实就是消息处理回调函数,将来会把消息交付给对应窗体的窗口过程!
三.Win32 基本结构
1. 描述窗体
API:
typedef struct tagWNDCLASSEXW {
UINT cbSize;//结构字节大小
UINT style;//窗口样式
WNDPROC lpfnWndProc;//窗口过程(消息处理函数)typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
int cbClsExtra;//窗口结构:额外信息 默认:0
int cbWndExtra;//窗口实例:额外信息 默认:0 (资源文件创建对话框:参数必须设置为DLGWINDOWEXTRA)
HINSTANCE hInstance;//应用程序实例
HICON hIcon;//图标
HCURSOR hCursor;//光标
HBRUSH hbrBackground;//窗口背景画刷
LPCWSTR lpszMenuName;//菜单
LPCWSTR lpszClassName;//窗口类名
HICON hIconSm;//小图标句柄(任务栏)
} WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
实例:
HBRUSH wndBgBrush;
wndBgBrush = CreateSolidBrush(RGB(255, 255, 0));
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(WNDCLASSEX);
wc.hInstance = hInstance;
wc.lpszClassName = L"MyWin32Window";
wc.lpfnWndProc = WndMsgProc;
wc.hbrBackground = wndBgBrush;
wc.style = CS_HREDRAW | CS_VREDRAW;
2. 注册窗体
API:
ATOM WINAPI RegisterClassExW(__in CONST WNDCLASSEXW *);
实例:
ATOM ret = RegisterClassEx(&wc);
if (ret == 0)
{
MessageBox(NULL, L"窗口注册失败!", L"Err", MB_OK);
return false;
}
3. 创建窗体
API:
HWND WINAPI CreateWindow(
_In_opt_ LPCTSTR lpClassName,//窗口类的名称
_In_opt_ LPCTSTR lpWindowName,//窗口的名字
_In_ DWORD dwStyle,//窗口的样式,要注意区分 WNDCLASS 中的 style 成员与 CreateWindow 函数的 dwStyle 参数, 前者是指定窗口类的样式, 基于该窗口类创建的窗口都具有这些样式,
后者是指定某个具体的窗口的样式。我们可以给创建的窗口指定WS_OVERLAPPEDWINDOW类型,这是一种多种窗口类型的组合类型
_In_ int x,//窗口的左上角X值
_In_ int y,//窗口左上角Y值
_In_ int nWidth,//窗口的宽度
_In_ int nHeight,//窗口的高度
_In_opt_ HWND hWndParent,//窗口的父窗口句柄
_In_opt_ HMENU hMenu,//窗口的菜单句柄
_In_opt_ HINSTANCE hInstance,//窗口的应用程序句柄
_In_opt_ LPVOID lpParam 作为 WM_CREATE 消息的附加参数 lParam 传入的数据指针。 在创建多文档界面的客户窗口时, lpParam 必须指向 CLIENTCREATESTRUCT 结构体。多数窗口将这个参数设置为 NULL。
);
实例:
HWND hWnd = CreateWindow(wc.lpszClassName, L"MyTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
{
MessageBox(NULL, L"窗体创建失败!", L"Err", MB_OK);
return false;
}
4. 显示窗体
API:
BOOL WINAPI ShowWindow(__in HWND hWnd, __in int nCmdShow);
实例:
ShowWindow(hWnd, SW_SHOW);//显示窗口
5. 刷新窗体
API:
BOOL WINAPI UpdateWindow(__in HWND hWnd);
实例:
UpdateWindow(hwnd);
6. 消息循环
API:
1. BOOL WINAPI GetMessageW(__out LPMSG lpMsg,__in_opt HWND hWnd,__in UINT wMsgFilterMin,__in UINT wMsgFilterMax);
2. BOOL WINAPI TranslateMessage( __in CONST MSG *lpMsg);
3. LRESULT WINAPI DispatchMessageW(__in CONST MSG *lpMsg);
实例:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
7. 消息处理
实例:
wc.lpfnWndProc = WndMsgProc;
LRESULT CALLBACK WndMsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
四.Win32 例子代码
// DuilibDPI.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#define IDB_QUIT 1
HINSTANCE g_hInstance = NULL;
LRESULT CALLBACK WndMsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
/*Win32窗体*/
/*
1.描述窗体
typedef struct tagWNDCLASSEXW {
UINT cbSize;//结构字节大小
UINT style;//窗口样式
WNDPROC lpfnWndProc;//窗口过程(消息处理函数)typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
int cbClsExtra;//窗口结构:额外信息 默认:0
int cbWndExtra;//窗口实例:额外信息 默认:0 (资源文件创建对话框:参数必须设置为DLGWINDOWEXTRA)
HINSTANCE hInstance;//应用程序实例
HICON hIcon;//图标
HCURSOR hCursor;//光标
HBRUSH hbrBackground;//窗口背景画刷
LPCWSTR lpszMenuName;//菜单
LPCWSTR lpszClassName;//窗口类名
HICON hIconSm;//小图标句柄(任务栏)
} WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
2.注册窗体
RegisterClassEx
3.创建窗体
HWND WINAPI CreateWindow(
_In_opt_ LPCTSTR lpClassName,//窗口类的名称
_In_opt_ LPCTSTR lpWindowName,//窗口的名字
_In_ DWORD dwStyle,//窗口的样式,要注意区分 WNDCLASS 中的 style 成员与 CreateWindow 函数的 dwStyle 参数, 前者是指定窗口类的样式, 基于该窗口类创建的窗口都具有这些样式,
后者是指定某个具体的窗口的样式。我们可以给创建的窗口指定WS_OVERLAPPEDWINDOW类型,这是一种多种窗口类型的组合类型
_In_ int x,//窗口的左上角X值
_In_ int y,//窗口左上角Y值
_In_ int nWidth,//窗口的宽度
_In_ int nHeight,//窗口的高度
_In_opt_ HWND hWndParent,//窗口的父窗口句柄
_In_opt_ HMENU hMenu,//窗口的菜单句柄
_In_opt_ HINSTANCE hInstance,//窗口的应用程序句柄
_In_opt_ LPVOID lpParam 作为 WM_CREATE 消息的附加参数 lParam 传入的数据指针。 在创建多文档界面的客户窗口时, lpParam 必须指向 CLIENTCREATESTRUCT 结构体。多数窗口将这个参数设置为 NULL。
);
4.显示窗体
ShowWindow(hWnd, SW_SHOW);//显示窗口
5.刷新窗体
UpdateWindow(hWnd);//窗口刷新,这个函数与wm_paint消息有关系!
6.消息循环
MSG msg;//消息结构体
while (GetMessage(&msg, NULL, 0, 0))//从应用程序消息队列获取消息
{
TranslateMessage(&msg);//加工消息
DispatchMessage(&msg);//分发消息 -> 窗口过程
}
*/
g_hInstance = hInstance;
HBRUSH wndBgBrush;
wndBgBrush = CreateSolidBrush(RGB(255, 255, 0));
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(WNDCLASSEX);
wc.hInstance = hInstance;
wc.lpszClassName = L"MyWin32Window";
wc.lpfnWndProc = WndMsgProc;
wc.hbrBackground = wndBgBrush;
wc.style = CS_HREDRAW | CS_VREDRAW;
ATOM ret = RegisterClassEx(&wc);
if (ret == 0)
{
MessageBox(NULL, L"窗口注册失败!", L"Err", MB_OK);
return false;
}
HWND hWnd = CreateWindow(wc.lpszClassName, L"MyTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (hWnd == NULL)
{
MessageBox(NULL, L"窗体创建失败!", L"Err", MB_OK);
return false;
}
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WndMsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT pt;
WCHAR* str = L"hello";
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
CreateWindow(L"Button", L"退出", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 30, 30, 100, 50, hWnd, (HMENU)IDB_QUIT, g_hInstance, NULL);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDB_QUIT:
PostQuitMessage(0);
break;
default:
break;
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &pt);
TextOut(hdc, 0, 0, str, wcslen(str));
EndPaint(hWnd, &pt);
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
作者: 祁莫问.

10万+

被折叠的 条评论
为什么被折叠?



