Иногда моя ручка окон хороша, иногда плоха - PullRequest
1 голос
/ 23 июня 2010

Я в замешательстве.Иногда, когда я открываю свое окно, возвращаемый дескриптор - это хорошо.а иногда его нет.Вот мой код

void GXRenderManager::InitWindows()
{
    WNDCLASSEX wndcex;

    wndcex.cbSize   = sizeof(WNDCLASSEX);
    wndcex.style    = CS_HREDRAW | CS_VREDRAW;
    wndcex.lpfnWndProc = GXRenderManager::WndProc;
    wndcex.cbClsExtra = 0;
    wndcex.cbWndExtra = 0;
    wndcex.hInstance = *GXRenderManager::hinstance;
    wndcex.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wndcex.hCursor  =   LoadCursor(NULL,IDC_ARROW);
    wndcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wndcex.lpszMenuName = NULL;
    wndcex.lpszClassName = L"GXRenderClass";
    wndcex.hIconSm  =   LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wndcex))
        throw GXWindowsException(L"Failed To Register Window");

    //EDIT AREA: This is a static size for window. Needs to be changed for dynamic size
    RECT rectangle = {0,0,GXRenderManager::width,GXRenderManager::height};
    AdjustWindowRect(&rectangle, WS_OVERLAPPEDWINDOW, FALSE);

    HWND tempWin;

    tempWin = CreateWindowEx(WS_EX_CLIENTEDGE,L"GXRenderClass",L"GXRender Engine",
        WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT, 
        (rectangle.right - rectangle.left),
        (rectangle.bottom - rectangle.top), NULL, NULL,*GXRenderManager::hinstance, NULL);

    if(!tempWin)
        GXWindowsException(L"GX had an issue creating a window.");

    GXRenderManager::mainWindow = &tempWin;

    ShowWindow(*GXRenderManager::mainWindow, *GXRenderManager::nCmdShow);

}

Иногда GXRenderManager :: mainWindow возвращает число, но большую часть времени возвращает «выражение не может быть оценено. Любые желающие ??

[править]

заголовок

#ifndef GXRM
#define GXRM
#include <windows.h>
#include "DeviceEnum.h"
#include "GXRenderDevice.h"
#include "GXExceptions.h"

class GXRenderManager {

public:
    static int Ignite(HINSTANCE*, int*, GXDEVICE , int w = 800, int h = 600);
    static GXRenderer* Device();
    static void InitWindows();
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

    static int Run();

private:
    bool running;
    static GXRenderer *renderDevice;

protected:
    static HINSTANCE * hinstance;
    static int *nCmdShow;
    static HWND mainWindow;
    static int width;
    static int height;

};

#endif

.cpp

GXRenderManager :: mainWindow является статическим членом. До ответов ниже. Я обновил код до следующего ...

void GXRenderManager::InitWindows()
{
    WNDCLASSEX wndcex;

    wndcex.cbSize   = sizeof(WNDCLASSEX);
    wndcex.style    = CS_HREDRAW | CS_VREDRAW;
    wndcex.lpfnWndProc = GXRenderManager::WndProc;
    wndcex.cbClsExtra = 0;
    wndcex.cbWndExtra = 0;
    wndcex.hInstance = *GXRenderManager::hinstance;
    wndcex.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wndcex.hCursor  =   LoadCursor(NULL,IDC_ARROW);
    wndcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wndcex.lpszMenuName = NULL;
    wndcex.lpszClassName = L"GXRenderClass";
    wndcex.hIconSm  =   LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wndcex))
        throw GXWindowsException(L"Failed To Register Window");

    //EDIT AREA: This is a static size for window. Needs to be changed for dynamic size
    RECT rectangle = {0,0,GXRenderManager::width,GXRenderManager::height};
    AdjustWindowRect(&rectangle, WS_OVERLAPPEDWINDOW, FALSE);

    HWND tempWin;

    tempWin = CreateWindowEx(WS_EX_CLIENTEDGE,L"GXRenderClass",L"GXRender Engine",
        WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT, 
        (rectangle.right - rectangle.left),
        (rectangle.bottom - rectangle.top), NULL, NULL,*GXRenderManager::hinstance, NULL);

    if(!tempWin)
        GXWindowsException(L"GX had an issue creating a window.");

    GXRenderManager::mainWindow = tempWin;

    ShowWindow(GXRenderManager::mainWindow, *GXRenderManager::nCmdShow);

}

Тем не менее я вижу ту же проблему.

Ответы [ 2 ]

1 голос
/ 23 июня 2010

Вы сохраняете указатель на локальную переменную (tempWin) и ожидаете, что он будет действительным после возврата из функции InitWindows(). Вместо создания GXRenderManager::mainWindow указателя, объявите его как фактический элемент данных. Итак:

class GXRenderManager {
    ...
    HWND mainWindow; // not a pointer
    ...
};

GXRenderManager::mainWindow = tempWin;

ShowWindow(GXRenderManager::mainWindow, *GXRenderManager::nCmdShow);

Я подозреваю, что у вас может быть похожая проблема с nCmdShow, но вы не показали достаточно кода, чтобы сказать.

0 голосов
/ 23 июня 2010

Hai

Проблема заключается в дескрипторе HWND tempWin;, это локальная переменная функции, что означает, что она очищается от стека после выхода из функции. он потеряет свою память ...

GXRenderManager :: mainWindow = & tempWin; поэтому вместо сохранения ссылки на переменную stakc лучше хранить ее значение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...