c++ - Windows C++ - 在类中创建窗口使其看起来不寻常

标签 c++ windows pointers

好的,所以我创建了一个创建 HWND 的类。

但是,创建的窗口显示出一些奇怪的属性:它不像其他窗口 - 它是非透明的,关闭-最小化-最大化按钮的位置与普通窗口不同。

但是指定的样式是默认的(WM_OVERLAPPEDWINDOW)。

而且,除非我稍微移动它,否则它无法关闭(似乎它在移动之前没有生成 WM_DESTROY 或 WM_CLOSE 消息)。

这可能是主 WinProc 的实现使用指针调用另一个消息处理器的问题。但是,我不知道为什么窗口看起来异常。

我的代码:

//mywind.h
class Window
{
private:
    HWND mHwnd;
    const char* className="Window";
    static LRESULT CALLBACK StartWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); //main WindowProc function
    LRESULT ThisWindowProc(UINT msg, WPARAM wParam, LPARAM lParam); //Another, object-specific message processing function
    bool isClassRegistered(HINSTANCE hinst);

public:
    Window() : mHwnd( 0 ) { }
    ~Window();

    int create(std::string title, int width, int height);
};

//mywind.cpp
Window::~Window()
{
    if( mHwnd ) DestroyWindow( mHwnd );
}

int Window::create(std::string title, int width, int height)
{
    WNDCLASS wincl;
    HINSTANCE hInst = NULL;
    hInst = GetModuleHandle(NULL);

    if(hInst==NULL)
    {
        printf("Failed to load hInstance\n");
        return -1;
    }

    if(!GetClassInfo(hInst, className, &wincl))
    {
        printf("Getting class info.\n");

        wincl.style = 0;
        wincl.hInstance = hInst;
        wincl.lpszClassName = className;
        wincl.lpfnWndProc = StartWindowProc;
        wincl.cbClsExtra = 0;
        wincl.cbWndExtra = 0;
        wincl.hIcon = NULL;
        wincl.hCursor = NULL;
        wincl.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
        wincl.lpszMenuName = NULL;

        if(!isClassRegistered(hInst))
        {
            if (RegisterClass(&wincl) == 0)
            {
                printf("The class failed to register.\n");
                return 0;
            }
        }
    }

    mHwnd = CreateWindow(className, title.c_str(), WS_VISIBLE | WS_OVERLAPPEDWINDOW,
                     CW_USEDEFAULT, CW_USEDEFAULT, width, height,
                     NULL, NULL, hInst, this);
    if(mHwnd==NULL)
    {
        printf("Failed to create HWND.\n");
        return -1;
    }

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

    printf("Destroying window.\n");

    if(mHwnd) DestroyWindow(mHwnd);
    mHwnd=NULL;

    printf("Returning.\n");

    return msg.wParam;
}

bool Window::isClassRegistered(HINSTANCE hinst)
{
    WNDCLASSEX clinf;
    if(!GetClassInfoEx(hinst, className, &clinf)) return false;
    return true;
}

LRESULT CALLBACK Window::StartWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    Window* winp = NULL;

    if(msg == WM_CREATE)
    {
        CREATESTRUCT* cs = (CREATESTRUCT*) lParam;
        winp = (Window*) cs->lpCreateParams;

        SetLastError(0);
        if(SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) winp) == 0)
        {
            if(GetLastError()!=0) return -1;
        }
    }
    else
    {
        winp = (Window*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
    }

    if(winp) return winp->ThisWindowProc(msg, wParam, lParam);

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

LRESULT Window::ThisWindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_PAINT:
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;

    default:
        return DefWindowProc(mHwnd, msg, wParam, lParam);
    }

    return 0;
}

//main.cpp

#include "mywind.h"

int main(int argc, char* argv[])
{
    Window mwnd;
    mwnd.create("Test", 200, 200);

    return 0;
}

最佳答案

请注意,在 CreateWindowEx 返回之前,您不会设置 mHwnd。这意味着在窗口创建期间发送的所有消息都将 0 传递给 DefWindowProc 而不是实际的窗口句柄。这会导致窗口管理器认为您正在绕过默认处理并执行自定义标题,这就是一切看起来都不对的原因。

TL;DR:在您的 WM_NCCREATE 处理程序中设置 mHwnd

关于c++ - Windows C++ - 在类中创建窗口使其看起来不寻常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33712230/

相关文章:

c++ - 如何在 VC++ 中获取 WPF 应用程序的屏幕截图?

windows - CSingleLock 实现在 Windows 7 上工作正常,但在 Win XP 上以死锁结束

c++ - 使用指针分配内存

c++ - 计算特定单词在 C++ 文本文件中出现的次数

c++ - 替换字符串中的单词,但忽略引号中的单词

c++ - 使用directshow压缩avi视频文件

windows - Powershell 正在失败 bamboo 任务,因为 -ExecutionPolicy bypass -Command 返回码是 134 而不是 0

C 指针和动态分配

c - 这行代码是什么意思(按位运算符)

c++ - 如何获取整数模板参数的值?