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

问题描述 投票:1回答:2

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

但是,创建的窗口显示了一些奇怪的属性:它不像其他窗口 - 它是不透明的,close-minimize-maximize按钮的位置与普通窗口不同。

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

更重要的是,它不能被关闭,除非我稍微移动它(似乎它在移动之前没有生成WM_DESTROY或WM_CLOSE消息)。

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

我的代码:

//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;
}
c++ windows pointers
2个回答
5
投票

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

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


0
投票

我90%确定您的问题是缺少清单,使WinXP / 7看起来。现在您处于兼容模式,窗口框架适用于Windows 98/2000样式。有关更多详细信息,请阅读此链接(或其他许多相同问题):http://www.mctainsh.com/Articles/Csharp/XpControlsInCS.aspx

© www.soinside.com 2019 - 2024. All rights reserved.