• 0x02 译文:Windows桌面应用Win32第一个程序


    本节课我们将用C++ 写一个最简单的Windows 程序。

    目录:

    创建一个窗口

    窗口消息

    编写窗口过程

    绘制窗口

    关闭窗口

    管理应用程序状态

    代码如下:

    #ifndef UNICODE
    #define UNICODE
    #endif 
    
    #include <windows.h>
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
    {
        // Register the window class.
        const wchar_t CLASS_NAME[]  = L"Sample Window Class";
        
        WNDCLASS wc = { };
    
        wc.lpfnWndProc   = WindowProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = CLASS_NAME;
    
        RegisterClass(&wc);
    
        // Create the window.
    
        HWND hwnd = CreateWindowEx(
            0,                              // Optional window styles.
            CLASS_NAME,                     // Window class
            L"Learn to Program Windows",    // Window text
            WS_OVERLAPPEDWINDOW,            // Window style
    
            // Size and position
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    
            NULL,       // Parent window    
            NULL,       // Menu
            hInstance,  // Instance handle
            NULL        // Additional application data
            );
    
        if (hwnd == NULL)
        {
            return 0;
        }
    
        ShowWindow(hwnd, nCmdShow);
    
        // Run the message loop.
    
        MSG msg = { };
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return 0;
    }
    
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    
        case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hdc = BeginPaint(hwnd, &ps);
    
                FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
    
                EndPaint(hwnd, &ps);
            }
            return 0;
    
        }
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }

     1. wWinMain  是程序的入口点,当程序开始的时候,它注册一些信息关于窗口的一些行为,其中最重要的是函数的地址,

    在这个Demo中名字叫做 WindowProc,这个函数中定义了这个窗口的一些行为,比如它的外观,它如何与用户交互,等等。

    2. 接下来程序创建了一个window窗口以及接受一个句柄 handler来识别窗口。

    3. 如果这个窗口创建成功,程序将会进入一个循环,直到用户关闭这个窗口和退出这个应用程序。

    Tips:

    尽管我们说这个应用程序的大多数逻辑被定义了,但是这个程序没有很明显地调用这个windowProc 函数。

    Windows通过传递一系列消息与您的程序通信。while循环中的代码驱动此进程。

    每次程序调用DispatchMessage函数,它间接地使每一次的消息调用WindowProc函数。

    创建一个窗口

    window Classes

    一个窗口类定义了一些行为的设置和一些窗口公用的方法。

    例如:一个组合中的这些按钮,当用户单击某个按钮的时候每一个按钮都有一个简单的行为。

    当然,按钮并不是完全相同的,每个按钮显示自己的文本字符串,并且有自己的屏幕坐标。

    对于每个窗口来说唯一的数据称为实例数据。

    每个窗口都必须与一个窗口类相关联,即使您的程序只创建该类的一个实例。

    重要的是要明白,一个窗口类是不是在C++意义上的一个类。

    相反,它是由操作系统内部使用的数据结构。窗口类在运行时注册到系统中。

    登记一个新的窗口类,先填一个WNDCLASS数据结构:

     // Register the window class.
        const wchar_t CLASS_NAME[]  = L"Sample Window Class";
        
        WNDCLASS wc = { };
    
        wc.lpfnWndProc   = WindowProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = CLASS_NAME;

    你必须设置这些结构成员:

    lpfnWndProc:是指向一个应用程序定义的函数称为窗口程序或“window proc.”这个窗口程序定义了大部分的窗口行为。稍后我们将详细检查窗口过程。现在,把这个当作一个前向参考。

    hInstance:是应用程序实例句柄。从wWinMain的程序参数得到这个值

    lpszClassName:是一个字符串,标识窗口类

    类名对当前进程是局部的,因此名称只在进程中是惟一的。但是,标准Windows控件也有类。如果使用这些控件中的任何一个,则必须选择与控件类名不冲突的类名。例如,按钮控件的窗口类被命名为“按钮”。

    WNDCLASS 结构的其他成员不在这里。您可以将它们设置为零,如本例所示,或填充它们。MSDN文档的结构进行了详细描述。

    其次,通过RegisterClass函数的WNDCLASS结构的地址。这个函数用操作系统注册窗口类。

    RegisterClass(&wc);

    创建窗口

    要创建一个新的实例化窗口,调用CreateWindowEx 函数

    HWND hwnd = CreateWindowEx(
            0,                              // Optional window styles.
            CLASS_NAME,                     // Window class
            L"Learn to Program Windows",    // Window text
            WS_OVERLAPPEDWINDOW,            // Window style
    
            // Size and position
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    
            NULL,       // Parent window    
            NULL,       // Menu
            hInstance,  // Instance handle
            NULL        // Additional application data
            );
    
        if (hwnd == NULL)
        {
            return 0;
        }

    Tips:

    第一个参数:让你对这个窗口指定一些行为选项,设置为0指定默认的行为

    第二个参数:CLASS_NAME 是这个窗口的类,当你创建窗口的时候定义

    第三个参数:窗口文本使用不同类型的窗口以不同的方式使用。如果窗口有标题栏,则文本将显示在标题栏中。

    第四个参数:窗口样式是定义窗口外观的一组标志。静态不变的 WS_OVERLAPPEDWINDOW 实际上是几个标记结合位或。

    这些标志一起给窗口一个标题栏,一个边界,一个系统菜单,最小化和最大化按钮。这组标志是顶级应用程序窗口最常用的样式。

    第五个参数:位置和大小,CW_USEDEFAULT 表示使用默认位置和大小。

    第六个参数:下一个参数为新窗口设置父窗口或所有者窗口。如果您正在创建子窗口,则设置父级。对于顶级窗口,将此设置为null。

    第七个参数:对于一个应用程序窗口来说,下个参数为窗口定义菜单。这个例子中没有使用菜单,所以这个值是NULL

    第八个参数:hInstance 是程序的实例句柄,前面描述的

    第九个参数:最后一个参数是一个空类型的任意数据指针。你可以使用此值将数据结构传递给窗口过程。在管理应用程序状态的部分中,我们将展示一种可能的方法来使用这个参数。

    CreateWindowEx函数返回一个句柄到新窗口,如果函数失败则返回0。

    要使窗口可见通过窗口句柄的ShowWindow函数:

    ShowWindow(hwnd, nCmdShow);

    hwnd 参数是CreateWindowEx 函数返回的窗口句柄, 这个nCmdShow参数可用于最小化和最大化一个窗口。

    操作系统将该值传递给程序通过wWinMain函数

     下面是创建窗口的一个完整例子:

     记住,WindowProc 仍然只是一个函数声明。

    // Register the window class.
        const wchar_t CLASS_NAME[]  = L"Sample Window Class";
        
        WNDCLASS wc = { };
    
        wc.lpfnWndProc   = WindowProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = CLASS_NAME;
    
        RegisterClass(&wc);
    
        // Create the window.
    
        HWND hwnd = CreateWindowEx(
            0,                              // Optional window styles.
            CLASS_NAME,                     // Window class
            L"Learn to Program Windows",    // Window text
            WS_OVERLAPPEDWINDOW,            // Window style
    
            // Size and position
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    
            NULL,       // Parent window    
            NULL,       // Menu
            hInstance,  // Instance handle
            NULL        // Additional application data
            );
    
        if (hwnd == NULL)
        {
            return 0;
        }
    
        ShowWindow(hwnd, nCmdShow);

    恭喜你现在已经创建了一个窗口,这个窗口不包含任何内容也不包括任何用户交互。

    在真正的GUI应用程序中,窗口一般会响应来自用户和操作系统的事件。

    下一节将介绍窗口消息是如何提供这话总共交互的。

  • 相关阅读:
    div+css简写原则
    并发控制
    div+css之块级元素与内联元素
    window.event对象属性(转)
    SQL SERVER 架构管理
    关系的规范化
    js常用事件
    物联小白CoAP协议
    图片不停的横滚
    DropDownlist编程问题
  • 原文地址:https://www.cnblogs.com/xingyunblog/p/7148248.html
Copyright © 2020-2023  润新知