Windows编程基础之:基本窗口模型

FLowUs邀请链接:https://flowus.cn/login?code=AXNU63
FlowUs邀请码:AXNU63


/* -------------------------------------------------------------------
                    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);
}
posted @ 2020-11-15 02:59  wbytts  阅读(148)  评论(0编辑  收藏  举报