window窗口运行机制

window内部运行机制

  • 窗口的使用
    1. 注册窗口类
WNDCLASS 窗口类
wcex.cbSize = sizeof(WNDCLASSEX);     //结构体大小
wcex.style          = CS_HREDRAW | CS_VREDRAW; 
//当横向和竖向发生拉伸就会发生重绘事件
wcex.lpfnWndProc    = WndProc;  //窗口回调函数
wcex.cbClsExtra     = 0;      //窗口类关联额外的空间
wcex.cbWndExtra     = 0;      //窗口关联的额外空间
wcex.hInstance      = hInstance; //当前程序实例
wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
//图标
wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
//光标,图形光标和等待光标
wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
//窗口的背景  画刷
wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WIN32PROJECT1);
//菜单
wcex.lpszClassName  = szWindowClass;
//应用程序类名,FindWindow就是通过类名和窗口名获取
wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
//小图标的使用
* 这里需要注册窗口类
RegisterClassEx();

相当于主题应用,什么风格的窗口
2. 创建窗口

创建窗口类有12个
CreateWindow(szWindowClass, szTitle, WS_MINIMIZEBOX | WS_SYSMENU,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
3. 显示更新窗口
   ShowWindow(hWnd, nCmdShow);  //显示窗口
   UpdateWindow(hWnd);          //更新窗口
4. 消息循环
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
5. 处理消息
* 窗口处理函数就可以处理了
* window窗口消息
    * 进队消息
        * 进队消息是用户输入的结果,如键盘点击,鼠标移动,鼠标单击,时钟消息,刷新消息,退出消息
        * postMessage,将信息传入到队列
    * 不进队消息
        * 调用特定的window函数
            * CreateWindow 发送WM_CREATE
            * Invaildate  发送WM_PAINT
            * GetWindowText 发送WM_GETTEXT
        * sendMessage发送消息

* 入口函数

WINAPI WinMain( 
        HINSTANCE hInstance,HINSTANCE hPreInstance,
        LPSTR lpCmdLine,   int showCmd)
  • 注意
    • 表示没有使用下面的参数
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
* 避免窗口大小改变
    case WM_NCHITTEST:
        //该消息避免屏幕大小的变化
        break;

这个消息的原理就是在窗口外的点击放置到窗口内,那么你就无法通过拖动和拉伸来改变窗口的大小了
* 移动窗口到正中央

        GetWindowRect(hWnd, &rect);
        //获取窗口的大小,原因坐标系在左上方
        wndx = rect.right - rect.left;  
        //矩形右边-矩形左边==窗口的长度
        wndy = rect.bottom - rect.top; 
        //矩形下边-矩形上边 == 窗口的高度

        //获取系统屏幕大小也就是我们的分辨率
        screenx = GetSystemMetrics(SM_CXSCREEN);
        screeny = GetSystemMetrics(SM_CYSCREEN);

        MoveWindow(hWnd, (screenx - wndx) / 2, (screeny - wndy) / 2, wndx, wndy, true);

实现原理:获取屏幕大小和窗口大小,将窗口的左上方放置到(屏幕-窗口)/2的位置上就可以了。

#include<windows.h>
#include<tchar.h>
#include "resource.h"
#define MAX 100
TCHAR className[MAX] = {0};
TCHAR wndTitle[MAX] = { 0 };
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void initString(HINSTANCE hInstance)
{
    LoadString(hInstance, IDS_CLASSNAME, className, MAX);   //加载字符串
    LoadString(hInstance, IDS_WNDNAME, wndTitle, MAX);
    //MessageBox(NULL, className, wndTitle, MB_OK);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    initString(hInstance);
    //窗口初始化
    WNDCLASS wndc;
    wndc.cbClsExtra = 0;
    wndc.cbWndExtra = 0;
    wndc.style = CS_HREDRAW | CS_VREDRAW;//可以横向和竖向拉伸
    //背景图片
    wndc.hbrBackground = (HBRUSH)LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
    //wndc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndc.hCursor = LoadCursor(NULL, IDC_CROSS);
    wndc.hIcon = LoadIcon(NULL, IDI_ASTERISK);
    wndc.hInstance = hInstance;
    wndc.lpfnWndProc = WndProc;
    wndc.lpszClassName = className;
    wndc.lpszMenuName = NULL;

    //注册窗口类
    if (!RegisterClass(&wndc))
    {

        return -1;
    }

    //创建窗口类获取句柄
    HWND hwnd = CreateWindow(className, wndTitle, WS_VISIBLE | WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
    //判断是否创建成功
    if (hwnd == NULL)
    {
        /*MessageBox(NULL, className, wndTitle, MB_OK);*/
        return -1;
    }
    //显示更新窗口
    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);

    /*MessageBox(NULL, className, wndTitle, MB_OK);*/
    //下面是消息循环
    MSG msg;
    while (GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    RECT rect;
    int wndx, wndy;
    int clx, cly;
    int screenx, screeny;
    switch (message)
    {
    case WM_CREATE:
        //获取窗口大小
        GetWindowRect(hWnd, &rect);
        //获取窗口的大小,原因坐标系在左上方
        wndx = rect.right - rect.left;  //矩形右边-矩形左边==窗口的长度
        wndy = rect.bottom - rect.top; //矩形下边-矩形上边 == 窗口的高度
        //获取客户区域
        GetClientRect(hWnd, &rect);
        clx = rect.right - rect.left;
        cly = rect.bottom - rect.top;
        //获取系统屏幕大小也就是我们的分辨率
        screenx = GetSystemMetrics(SM_CXSCREEN);
        screeny = GetSystemMetrics(SM_CYSCREEN);

        MoveWindow(hWnd, (screenx - wndx) / 2, (screeny - wndy) / 2, wndx, wndy, true);
        //SetWindowPos(hWnd, NULL, (screenx - wndx-900) / 2, (screeny - wndy-636) / 2, 900 + wndx - clx, 636 + wndy - cly, 0);
        break;
    case WM_SIZE:

        break;
    //case WM_CLOSE:
    //  ::DestoryWindow(hWnd);
    //  break;
    case WM_NCHITTEST:
        //该消息避免屏幕大小的变化
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值