HelloWorld
打开VS,创建新项目 选择C++ 桌面向导文件
应用程序类型选择桌面应用程序(.exe),勾选空项目,然后单击确定按钮
在左侧的解决方案资源管理器中,右键单击鼠标,选择源文件,添加,新建项,选择C++文件,命名为HelloWorld.cpp
#include <Windows.h>
int WINAPI WinMain(
HINSTANCE hInsetance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MessageBox(NULL, TEXT("Hello World!"),TEXT("12"), MB_OKCANCEL | MB_ICONINFORMATION |
MB_DEFBUTTON2);
return 0;
}
程序的入口函数为WinMain
int WINAPI WinMain(
HINSTANCE hInsetance,//程序的实例句柄
HINSTANCE hPrevInstance,//上一个程序的实例句柄
LPSTR lpCmdLine,//char * arg[] 命令行参数
int nCmdShow //显示方式
)
MessageBox语法
int MessageBox(
[in, optional] HWND hWnd,
[in, optional] LPCTSTR lpText,
[in, optional] LPCTSTR lpCaption,
[in] UINT uType
);
类型:HWND
要创建的消息框的所有者窗口的句柄。 如果此参数为 NULL,则消息框没有所有者窗口。
类型: LPCTSTR
要显示的消息。 如果字符串由多行组成,则可以在每行之间使用回车符和/或换行符分隔行。
类型: LPCTSTR
对话框标题。 如果此参数为 NULL,则默认标题为 Error。
类型: UINT
对话框的内容和行为。 此参数可以是以下标志组的标志的组合。
更多参数查看learn.microsoft.com/zh-cn/windo…
字符串处理
C++支持两种字符串,常规的ANSI编码(使用""包裹)和Unicode编码(使用L""包裹)
- 普通字符串类型CHAR
- 宽字符串类型WCHAR 输出用%ls
- 通用字符串类型TCHAR 类型未知由环境决定。需要引用tchar.h头文件
微软将这两套字符集及其操作进行了统一,通过条件编译(通过_UNICODE和UNICODE宏)控制实际使用的字符集,这样就有了_T("")这样字符串 字符串常用函数 字符串长度计算:strlen、wcslen、_tcslen 字符串转数字: A版本:atoi、strtol W版本:_wtoi、wcstol T版本:_ttoi、_tcstol 数字到字符串转换: A版本 itoa(不安全)_itoa_s W版本_itow_s T版本_itot_s
演示
#include<Windows.h>
#include<iostream>
#include<tchar.h>
int main()
{
CHAR char_buff[] = "123456";
WCHAR wchar_buff[] = L"123456";
TCHAR tchar_buff[] = _T("123456");
printf("sizeof char_buff=%d\n", sizeof(char_buff));
printf("sizeof wchar_buff=%d\n", sizeof(wchar_buff));
printf("sizeof tchar_buff=%d\n", sizeof(tchar_buff));
return 0;
}
通用字符串类型TCHAR 类型未知由环境决定
更改字符集后
#include<Windows.h>
#include<iostream>
#include<tchar.h>
int main()
{
CHAR char_buff[] = "123456";
WCHAR wchar_buff[] = L"12345678";
TCHAR tchar_buff[] = _T("123456789");
printf("sizeof char_buff=%d\n", sizeof(char_buff));
printf("sizeof wchar_buff=%d\n", sizeof(wchar_buff));
printf("sizeof tchar_buff=%d\n", sizeof(tchar_buff));
printf("char_buff的长度为:%d\n", strlen(char_buff));
printf("wchar_buff的长度为:%d\n", wcslen(wchar_buff));
printf("tchar_buff的长度为:%d\n", _tcslen(tchar_buff));
return 0;
}
宽字节字符转换多字符
WideCharToMultiByte()
#define WCHAR_TO_CHAR(lpW_Char,lpChar)
WideCharToMultiByte(CP_ACP,NULL,lpW_Char,-1,lpChar,_countof(lpChar),NULL,FALSE)
多字符转换宽字符
MultiByteToWideChar()
#define CHAR_TO_WCHAR(lpChar,lpWChar)
MultiByteToWideChar(CP_ACP,NULL, lpChar, -1,lpWChar,_countof(lpWChar))
第一个窗口程序
#include<Windows.h>
#include<iostream>
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
switch (uMsg)
{
case WM_CREATE:
MessageBoxW(hwnd, L"窗口创建了", L"提示",MB_OK);
break;
case WM_CLOSE:
MessageBoxW(hwnd, L"窗口关闭了", L"提示", MB_OK);
DestroyWindow(hwnd);
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//1、创建一个窗口类
WNDCLASSW myClass = { 0 };
myClass.lpszClassName = L"xiaowang";
myClass.lpfnWndProc = WindowProc;
//2、注册窗口类
RegisterClassW(&myClass);
//3、创建窗口
HWND hwindow=CreateWindowW(
myClass.lpszClassName,
L"xiaowang",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
0
);
//4、显示窗口
ShowWindow(hwindow,SW_SHOWNORMAL );
//5、获取消息
MSG msg = { 0 };
while (GetMessageW(&msg,0,0,0))
{
DispatchMessageW(&msg);//分发消息给消息处理函数
}
return 0;
}
windows程序框架-消息 windows系统是基于消息的操作系统 每一个窗口都在不停的处理消息,所有的操作都是接收到消息之后,进行处理的结果。 围绕着消息的处理,产生了获取消息的消息泵机制也叫消息循环,以及处理消息的窗口回调函数机制。 消息的产生 windows下产生消息的时机共有以下四种:
- 用户主动产生的消息
- windows系统本身产生的消息
- 应用程序本身产生的消息
- 其他应用程序产生的消息
应用程序如何接受消息 windows操作系统有一个系统消息队列,每个GUI程序,都有自己的消息队列,系统消息队列负责将消息发送给不同GUI程序的消息队列 API函数: GetMessage 从消息队列中取出消息 DisoatchMessage 将消息发送给消息处理函数
消息处理
Windows通用消息: windows通用消息标志都定义在WINUSER.H中,以WM_开头,大体分为三类。
- 窗口消息
例如:WM_CREATE,WM_CLOSE
- 命令消息
特指WM_COMMAND消息,与处理用户请求有关,如点击菜单项,工具栏,控件等就会产生命令消息。
- 通知消息
特指WM_NOTIFY消息,只使用用windows的公共控件,如列表,视图等 Windows控件消息 控件消息是用于控制控件的一些行为的,不同的控件有不同的控制消息,命名规则如下: BM_按钮控制消息 EM_编辑框控制消息 STM_静态文本控制消息 CM_组合框控制消息 LBM_列表框控制消息 用户自定义消息 除了windows消息外,我们也可以定义自己的消息。系统的消息码在0-WM_USER之间,故我们定义的消息大于WM_USER即可 消息的发送 PostMessage、SendMessage PostMessage会将消息发送到消息队列,应用程序的消息循环会最终得到消息,并分发给回调函数。 SendMessage相当于直接调用窗口的回调函数,等待窗口过程处理结束并返回结果 根据发送消息的方式不同,消息分为两类: 队列消息、非队列消息。
#include<Windows.h>
#include<iostream>
//消息处理函数
void print(LPCWSTR format,...)
{
WCHAR wchar_buff[100]{ 0 };
va_list arglist;
va_start(arglist, format);
wvsprintfW(wchar_buff, format, arglist);
va_end(arglist);
OutputDebugStringW(wchar_buff);
}
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
switch (uMsg)
{
case WM_CREATE:
MessageBoxW(hwnd, L"窗口创建了", L"提示",MB_OK);
break;
case WM_CLOSE:
MessageBoxW(hwnd, L"窗口关闭了", L"提示", MB_OK);
DestroyWindow(hwnd);
PostQuitMessage(0);
break;
//鼠标移动
case WM_MOUSEMOVE:
{
WORD X = LOWORD(lParam);
WORD Y = HIWORD(lParam);
print(L"鼠标移动了!X坐标%d,Y坐标%d\n",X,Y);
break;
}
//鼠标左键
case WM_LBUTTONDOWN:
print(L"鼠标左键按下了\n");
break;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//1、创建一个窗口类
WNDCLASSW myClass = { 0 };
myClass.lpszClassName = L"xiaowang";
myClass.lpfnWndProc = WindowProc;
//2、注册窗口类
RegisterClassW(&myClass);
//3、创建窗口
HWND hwindow=CreateWindowW(
myClass.lpszClassName,
L"xiaowang",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
0
);
//4、显示窗口
ShowWindow(hwindow,SW_SHOWNORMAL );
//5、获取消息
MSG msg = { 0 };
while (GetMessageW(&msg,0,0,0))
{
DispatchMessageW(&msg);//分发消息给消息处理函数
}
return 0;
}
自定义消息
const UINT WM_USERMSG = WM_USER + 1;
case WM_LBUTTONDOWN:
print(L"鼠标左键按下了\n");
SendMessageW(hwnd, WM_USERMSG, 0, 0);
break;
case WM_USERMSG:
print(L"自定义消息\n");
break;
#include<Windows.h>
#include<iostream>
const UINT WM_USERMSG = WM_USER + 1;
void print(LPCWSTR format,...)
{
WCHAR wchar_buff[100]{ 0 };
va_list arglist;
va_start(arglist, format);
wvsprintfW(wchar_buff, format, arglist);
va_end(arglist);
OutputDebugStringW(wchar_buff);
}
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
switch (uMsg)
{
case WM_CREATE:
MessageBoxW(hwnd, L"窗口创建了", L"提示",MB_OK);
break;
case WM_CLOSE:
MessageBoxW(hwnd, L"窗口关闭了", L"提示", MB_OK);
DestroyWindow(hwnd);
PostQuitMessage(0);
break;
case WM_MOUSEMOVE:
{
WORD X = LOWORD(lParam);
WORD Y = HIWORD(lParam);
print(L"鼠标移动了!X坐标%d,Y坐标%d\n",X,Y);
break;
}
case WM_LBUTTONDOWN:
print(L"鼠标左键按下了\n");
SendMessageW(hwnd, WM_USERMSG, 0, 0);
break;
case WM_USERMSG:
print(L"自定义消息\n");
break;
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//1、创建一个窗口类
WNDCLASSW myClass = { 0 };
myClass.lpszClassName = L"xiaowang";
myClass.lpfnWndProc = WindowProc;
//2、注册窗口类
RegisterClassW(&myClass);
//3、创建窗口
HWND hwindow=CreateWindowW(
myClass.lpszClassName,
L"xiaowang",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
0
);
//4、显示窗口
ShowWindow(hwindow,SW_SHOWNORMAL );
//5、获取消息
MSG msg = { 0 };
while (GetMessageW(&msg,0,0,0))
{
DispatchMessageW(&msg);//分发消息给消息处理函数
}
return 0;
}
效果
SendMessageW演示
关闭窗口
打开工具下的spy++
点击望远镜将准星拖向目标窗口获取句柄
SendMessageW参数1填句柄 参数2填控制消息
case WM_RBUTTONDOWN:
SendMessageW((HWND)0x00200B2A, WM_CLOSE, 0, 0);
break;