Win32开发

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);
}

作者: 祁莫问.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值