/* -------------------------------------------------------------------
MyWindows.c -- 基本窗口模型
--------------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// WINAPI:代表 __stdcall 参数的传递顺序:从右到左,依次入栈,并在函数返回前清空堆栈
// WINAPI:调用约定,主要是参数入栈顺序,这个栈空间的清理者
int WINAPI WinMain(
HINSTANCE hInstance, // 应用程序实例句柄
HINSTANCE hPrevInstance, // 上一个应用程序实例句柄,在win32环境下,参数一般为NULL,不起作用了
PSTR szCmdLine, // char * argv[]
int iCmdShow // 显示命令:最大化、最小化、正常
)
{
static TCHAR szAppName[] = TEXT("MyWindows");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
// 设计一个窗口
wndclass.style = CS_HREDRAW | CS_VREDRAW; // 显示的风格
wndclass.lpfnWndProc = WndProc; // 回调函数
wndclass.cbClsExtra = 0; // 类的额外的内存
wndclass.cbWndExtra = 0; // 窗口的额外的内存
wndclass.hInstance = hInstance; // 应用程序实例句柄
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 窗口图标,第一个参数为NULL,表示使用系统提供的图标
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标样式,第一个参数为NULL,表示使用系统提供的光标
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 背景
wndclass.lpszMenuName = NULL; // 菜单名称,为NULL表示不使用菜单
wndclass.lpszClassName = szAppName; // 窗口名称
// 注册窗口,注册失败则返回NULL,提示操作系统是否支持窗口
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
return 0;
}
// 创建窗口,hwnd接收窗口句柄
hwnd = CreateWindow(szAppName, // 类名
TEXT("title"), // 标题名
WS_OVERLAPPEDWINDOW, // 风格
CW_USEDEFAULT, // 显示坐标x,CW_USEDEFAULT默认值
CW_USEDEFAULT, // 显示坐标y
CW_USEDEFAULT, // 宽
CW_USEDEFAULT, // 高
NULL, // 父窗口
NULL, // 菜单
hInstance, // 父实例句柄
NULL // 附加值
);
// 显示窗口
ShowWindow(hwnd, iCmdShow);
// 更新窗口
UpdateWindow(hwnd);
// 消息循环
/*
MSG:消息结构体
HWND hwnd : 主窗口句柄
UINT message : 具体消息名称
WPARAM wParam : 附加消息 之 键盘消息
LPARAM lParam : 附加消息 之 鼠标消息
DWORD time : 消息产生的时间
POINT pt : 附加消息 之 鼠标位置
*/
/*
GetMessage:捕获消息
LPMSG lpMsg : lpMsg 消息
HWND hWnd : 窗口句柄
UINT wMsgFilterMin : 最小过滤消息(一般填0,表示捕获所有消息)
UINT wMsgFilterMax : 最大过滤消息(一般填0,表示捕获所有消息)
*/
while (GetMessage(&msg, NULL, 0, 0) == TRUE)
{
// 解释消息
TranslateMessage(&msg);
// 分发消息
DispatchMessage(&msg);
}
return msg.wParam;
}
// 窗口处理过程
/*
CALLBACK 表示参数的传递顺序,入栈,函数返回前清空堆栈
参数:
HWND hwnd 窗口句柄
UINT message 具体的消息名称
WPARAM wParam 键盘附加消息
LPARAM lParam 鼠标附加消息
*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
// 选择感兴趣的消息进行处理
switch (message)
{
case WM_PAINT: // 窗口绘制
hdc = BeginPaint(hwnd, &ps); // 绘画初始化
GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("大家好,这是我的第一个窗口程序!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
case WM_LBUTTONDOWN: // 鼠标左键按下
{ // C语言中,在case中定义变量的话,case 体 要用大括号括起来
// 获取鼠标的位置信息
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
WCHAR buf[1024]; // LPWSTR 或者 WCHAR buf[1024]
wsprintf(buf, TEXT("x = %d, y = %d"), xPos, yPos);
MessageBox(hwnd, buf, TEXT("鼠标左键点击"), MB_OK);
return 0;
}
case WM_DESTROY: // 窗口销毁
PostQuitMessage(0);
return 0;
}
// 使用系统默认处理方式处理剩余消息
return DefWindowProc(hwnd, message, wParam, lParam);
}