繁体   English   中英

创建响应式Windows WinAPI C ++

[英]Creating Responsive Windows winapi c++

我只是在学习使用winapi创建gui,但是遇到了问题。 我可以这样创建一个窗口

#include "stdafx.h"
#include <windows.h>

int main()
{
    HWND hwnd = CreateWindow(L"STATIC",NULL,WS_VISIBLE|WS_SYSMENU|WS_CAPTION,0,0,600,600,NULL,NULL,NULL,NULL);
    UpdateWindow(hwnd);
    MSG msg;

    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    _gettch();
}

但是,单击关闭按钮后,窗口将不会关闭,并且无法拖动或移动窗口。 我想知道如何启用窗口的这些功能。

静态窗口没有普通窗口,您应该尝试查找如何使用RegisterWindowEx注册和处理自己的类,然后使用相同的类名创建一个窗口。 您必须具有自己的窗口过程才能处理消息。 由系统注册的所有窗口类均运行其自己的默认窗口过程,据我所知,它们都不处理WM_CLOSE(即关闭按钮),这就是为什么您无法关闭它的原因。

对于您的主窗口,请始终使用WS_OVERLAPPEDWINDOW之类的名称,这样就可以确定是否可以正常运行,并从中消除不需要的标志。

如何设置:

WNDCLASSEX wndcls;
HWND hMainWnd;

// Register your own window class
    ZeroMemory(&wndcls,sizeof(WNDCLASSEX));
    wndcls.cbSize=sizeof(WNDCLASSEX);
    wndcls.style=CS_VREDRAW+CS_HREDRAW;
    wndcls.lpfnWndProc=&appWndFunc;
    wndcls.hInstance=hInstance;
    wndcls.hIcon=hMainIcon;     // or just LoadIcon(hInstance,MAKEINTRESOURCE(IDI_MAIN_ICON))
    wndcls.hIconSm=hMainIcon;
    wndcls.hCursor=LoadCursor((HINSTANCE)NULL,IDC_ARROW);
    wndcls.hbrBackground=(HBRUSH)COLOR_APPWORKSPACE;
    wndcls.lpszClassName="myWndClass";
    if (RegisterClassEx(&wndcls)==0)
    {
        // failed to register class name
        return false;
    }

// Create window with your own class
    hMainWnd=CreateWindowEx(0,\
                            "myWndClass","widnow title",\
                            WS_OVERLAPPEDWINDOW|WS_VISIBLE,\
                            0,\
                            0,\
                            250,\
                            250,\
                            hMainWnd,NULL,hInstance,NULL);

    if (hMainWnd==(HWND)NULL)
    {
        // failed to create main window
        return false;
    }

然后你的主循环:

bool bAppMainLoop=false
while(!bAppMainLoop)
{
    WaitMessage();
    while(PeekMessage(&emsg,NULL,0,0,PM_NOREMOVE))
    {
        if(GetMessage(&emsg,NULL,0,0)==0)
        {
            bAppMainLoop=true;
            break;
        }
        TranslateMessage(&emsg);
        DispatchMessage(&emsg);
    }
}

这比通常的设置要多一点,所以让我解释一下,为了不烧坏CPU,您用WaitMessage等待一条消息,它将一直阻塞直到发生诸如移动窗口,单击,绘制等操作。PeekMessage将返回true如果有消息,那么在while循环中调用它可以确保它耗尽消息队列,如果GetMessage返回0,则它会获取消息,这意味着您的应用程序称为PostQuitMessage(0),因此在消息中找到了WM_QUIT循环,这意味着该退出消息循环了。 其余的Translate and Dispatch会按其名称所述。

最后,您需要自己的窗口过程:

LRESULT CALLBACK appWndFunc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    if (uMsg==WM_CLOSE)
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

DefWindowProc是处理系统中所有常见消息的必不可少的工具,因此您无需在此处处理这些消息。 您只需响应要关闭窗口时发送的WM_CLOSE消息,然后将退出消息发布到要捕获并退出的消息循环中即可。

附加信息:由于Windows会为您执行释放操作,因此不需要释放您的内容,因此下次启动程序时不会将其锁定,但这是一个好习惯,至少在主循环后注销窗口类。

顺便说一句,主要功能是错误的: WinMain是正确的功能。 另外,为避免出现更多错误,请确保您编译Windows GUI应用程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM