/*typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);*/
/*窗口视图讯息处理程序:
视窗讯息处理程式确定了在视窗
的显示区域中显示些什么以及视窗怎样回应使用者输入。
*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
static char* thisAppName = "hello windows";
switch (message)
{
case WM_PAINT: //重绘消息
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);/*得到的是相对于窗口客户区左上角的坐标。*/
MoveToEx(hdc, 10, 10, 0);/*移动当前画笔的位置*/
SelectObject(hdc, ::CreatePen(PS_SOLID, 1, RGB(0, 0, 255)));/*把一个对象(位图、画笔、画刷等)选入指定的设备描述表。新的对象代替同一类型的老对象。*/
LineTo(hdc, 300, 200);
Rectangle(hdc, 150, 150, 400, 400);
// DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_CREATE:
RegisterHotKey(hWnd, 1, 0, 0x41);
break;
case WM_HOTKEY:
MessageBox(hWnd, TEXT("This is WM_HOTKEY"), 0, 0);/*MessageBox(HandleWNd, TEXT("This program requires Windows NT!"),
thisAppName, MB_ICONERROR);*/
break;
case WM_TIMER:
break;
case WM_DESTROY: //窗口销毁消息
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
int APIENTRY WinMain(HINSTANCE hInstance, //应用程序的实例句柄,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine, //命令行
int nCmdShow)
{
/*1.0初始化结构*/
WNDCLASSEX wcex = { 0 };/*实验表明必须初始化,负责窗口视图注册会失败*/
HWND HandleWNd;
MSG _msg;
static char thisAppName[] = "hello windows";
char szWindowClass[] = "winclass";
char szTitle[] = "系统信息";
wcex.cbSize = sizeof(WNDCLASSEX); //WNDCLASSEX结构体大小
wcex.style = CS_HREDRAW | CS_VREDRAW; //位置改变时重绘
wcex.lpfnWndProc = (WNDPROC)WndProc; //消息处理函数
wcex.hInstance = 0; //当前实例句柄
wcex.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME; //背景色
wcex.lpszClassName = szWindowClass; //参窗口类名
wcex.hIcon = 0; //图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //光标
wcex.lpszMenuName = 0; //菜单名称
wcex.hIconSm = 0; //最小化图标
/*2.0注册窗口视图*/
RegisterClassEx(&wcex);
//{
// //MessageBox(/*HandleWNd*/NULL, TEXT("This program requires Windows NT!"),
// //thisAppName, MB_ICONERROR);
//
//}
/*3.0创建窗口视图*/
HandleWNd = CreateWindow(szWindowClass, szTitle, WS_SYSMENU | WS_VISIBLE, //创建窗口
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, 0, NULL);
//CreateWindow(szWindowClass, szTitle, WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, 0, NULL);
/*显示窗口视图*/
//ShowWindow(HandleWNd, nCmdShow);
ShowWindow(HandleWNd, nCmdShow);
/*更新窗口视图*/
UpdateWindow(HandleWNd);
/*讯息回圈*/
/*程式现在必须准备
读入使用者用键盘和滑鼠输入的资料。Windows 为当前执行的每个Windows 程式
维护一个「讯息伫列」。在发生输入事件之後,Windows 将事件转换为一个「讯
息」并将讯息放入程式的讯息伫列中。
GetMessage:
这一呼叫传给Windows 一个指标,指向名为msg 的MSG 结构。第二、第三
和第四个参数设定为NULL 或者0,表示程式接收它自己建立的所有视窗的所有
讯息
*/
while (GetMessage(&_msg, NULL, 0, 0)) // 消息循环:
{
TranslateMessage(&_msg); //将msg 结构传给Windows,进行一些键盘转换 转化虚拟按键到字符消息
DispatchMessage(&_msg); // 又将msg 结构回传给Windows ,分派消息调用回调函数
}
return _msg.wParam;
}
视图和讯息编程中,大多涉及到windows的API,从代码的纵向结构上分析,程序可分为7个步骤:
step1:结构初始化
结构的初始化可以根据设计需求,进行初始化。
HWND HandleWNd;
char szWindowClass[] = "winclass";
char szTitle[] = "系统信息";
wcex.cbSize = sizeof(WNDCLASSEX); //WNDCLASSEX结构体大小
wcex.style = CS_HREDRAW | CS_VREDRAW; //位置改变时重绘
wcex.lpfnWndProc = (WNDPROC)WndProc; //消息处理函数
wcex.hInstance = 0; //当前实例句柄
wcex.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME; //背景色
wcex.lpszClassName = szWindowClass; //参窗口类名
wcex.hIcon = 0; //图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //光标
wcex.lpszMenuName = 0; //菜单名称
wcex.hIconSm = 0; //最小化图标
注意:WNDCLASSEX wcex = { 0 };/*实验表明必须初始化,负责窗口视图注册会失败*/
step2 视窗注册:
RegisterClassEx(&wcex);
RegisterClass()函数注册一个窗口类,RegisterClassEx()函数注册一个拓展的窗口类。如果注册成功,两个函数都会返回非零值,否则都返回0。
头文件:winuser.h
链接库:user32.lib
(3)参数说明
lpWndClass:一个指向WNDCLASS结构的长指针,在传递给函数之前,必须使用合理的类属性来填充此结构。
lpwxz:一个指向WNDCLASSEX结构的长指针,在传递给函数之前,必须使用合理的类属性来填充此结构。
step3:建立视窗
HandleWNd = CreateWindow(szWindowClass, szTitle, WS_SYSMENU | WS_VISIBLE, //创建窗口
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, 0, NULL);
API 函数原型:
HWND WINAPI CreateWindow(
_In_opt_ LPCTSTR lpClassName, // 窗口类名称
_In_opt_ LPCTSTR lpWindowName, // 窗口标题
_In_ DWORD dwStyle, // 窗口风格,或称窗口格式
_In_ int x, // 初始 x 坐标
_In_ int y, // 初始 y 坐标
_In_ int nWidth, // 初始 x 方向尺寸
_In_ int nHeight, // 初始 y 方向尺寸
_In_opt_ HWND hWndParent, // 父窗口句柄
_In_opt_ HMENU hMenu, // 窗口菜单句柄
_In_opt_ HINSTANCE hInstance, // 程序实例句柄
_In_opt_ LPVOID lpParam // 创建参数
);
注:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数(不是说没有参数,而是可以利用宏搭配参数)。
step4 显示视窗:
ShowWindow(HandleWNd, nCmdShow);
第一个参数是刚刚用CreateWindow 建立的视窗代号。第二个参数是作为参
数传给WinMain 的iCmdShow。它确定最初如何在萤幕上显示视窗,是一般大小、
最小化还是最大化。
step5 更新窗口视图:
UpdateWindow(HandleWNd);用来更新无效区域。
step6 讯息回圈
while (GetMessage(&_msg, NULL, 0, 0)) // 消息循环:
{
TranslateMessage(&_msg); //将msg 结构传给Windows,进行一些键盘转换 转化虚拟按键到字符消息
DispatchMessage(&_msg); // 又将msg 结构回传给Windows ,分派消息调用回调函数
}
呼叫UpdateWindow之後,视窗就出现在视讯显示器上。程式现在必须准备
读入使用者用键盘和滑鼠输入的资料。Windows 为当前执行的每个Windows 程式
维护一个「讯息伫列」。在发生输入事件之後,Windows 将事件转换为一个「讯
息」并将讯息放入程式的讯息伫列中。
最后一步就是窗口信息处理函数的设计,LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)