So as the title says, I get memory corruptions when I create window frames, specificly when I make the frame visible.
Once I make the window visible, either using the ShowWindow function, or setting the WS_VISIBLE style flag, it somehow corrupts memory, and can cause crashes in classes I used before that.
It doesnt seem to have anything to do with the OpenGL context either.
Everything works perfectly right until I make the window visible.
I am no expert in the windows API, so I have no idea what I am doing wrong.
I hope I just forgot to set something somewhere, because this bug has been haunting me for a while.
Or maybe you can give me some tips on tracking down the source of the problem.
Window class code:
#include <set>
#include <Windows.h>
#include <GL/GL.h>
#include <GL/wglext.h>
#include "eventmanager.h"
#include "windowflag.h"
#include "window.h"
using namespace Core;
using namespace Base;
using namespace Gfx;
using namespace Wnd;
struct Window::Window_Impl
{
Window_Impl(Window* a_Window);
~Window_Impl();
bool CreateFrame(const vector2i& a_Position, const vector2i& a_Size, const char8* a_Caption, uint32 a_Flags);
bool DestroyFrame();
bool CreateWindowClass();
bool DestroyWindowClass();
bool CreateContext(const GraphicsLibrary& a_GraphicsLibrary);
bool CreateContextOpenGL2(const GraphicsLibrary& a_GraphicsLibrary);
bool CreateContextOpenGL3(const GraphicsLibrary& a_GraphicsLibrary);
bool CreateContextOpenGL4(const GraphicsLibrary& a_GraphicsLibrary);
bool CreateContextDirectX9(const GraphicsLibrary& a_GraphicsLibrary);
bool CreateContextDirectX10(const GraphicsLibrary& a_GraphicsLibrary);
bool CreateContextDirectX11(const GraphicsLibrary& a_GraphicsLibrary);
static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
RECT CalculateFrameRectangle(const vector2i& a_Position, const vector2i& a_Size, uint32 a_Flags) const;
DWORD GetStyleFromFlags(uint32 a_Flags) const;
DWORD GetStyleExFromFlags(uint32 a_Flags) const;
uint32 GetFlagsFromStyle(DWORD a_Style, DWORD a_StyleEx) const;
HINSTANCE m_HINSTANCE;
HWND m_HWND;
HDC m_HDC;
HGLRC m_HGLRC;
static std::set<HGLRC> m_HGLRCList;
Window* m_Window;
char8 m_CaptionBuffer[0xFF];
GraphicsLibrary m_GraphicsLibrary;
static uint32 m_WindowCounter;
static char8* m_WindowClassName;
};
uint32 Window::Window_Impl::m_WindowCounter = 0;
char8* Window::Window_Impl::m_WindowClassName = 0;
std::set<HGLRC> Window::Window_Impl::m_HGLRCList = std::set<HGLRC>();
Window::Window(const vector2i& a_Position, const vector2i& a_Size, const char8* a_Caption, uint32 a_Flags, const GraphicsLibrary& a_GraphicsLibrary)
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Creating Window...");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating private implementation...");
m_Impl = new Window_Impl(this);
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Private implementation created.");
if (!m_Impl->CreateFrame(a_Position, a_Size, a_Caption, a_Flags))
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Failed to create Window.");
return;
}
if (!m_Impl->CreateContext(a_GraphicsLibrary))
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Failed to create Window.");
return;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Window created.");
}
Window::~Window()
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Destroying Window...");
m_Impl->DestroyFrame();
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Deleting private implementation...");
delete m_Impl;
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Private implementation deleted.");
Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Window destroyed.");
}
vector2i Window::GetPosition() const
{
if (m_Impl->m_HWND != NULL)
{
POINT point;
point.x = 0;
point.y = 0;
if (!ClientToScreen(m_Impl->m_HWND, &point))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to get Window position.", GetLastError());
return vector2i();
}
return vector2i(point.x, point.y);
}
else
{
return vector2i();
}
}
vector2i Window::GetSize() const
{
if (m_Impl->m_HWND != NULL)
{
RECT rect;
if (!GetClientRect(m_Impl->m_HWND, &rect))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to get Window size.", GetLastError());
return vector2i();
}
return vector2i(rect.right - rect.left, rect.bottom - rect.top);
}
else
{
return vector2i();
}
}
const char8* Window::GetCaption() const
{
if (m_Impl->m_HWND != NULL)
{
if (GetWindowText(m_Impl->m_HWND, m_Impl->m_CaptionBuffer, 0xFF) == 0)
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to get Window caption.", GetLastError());
return 0;
}
return m_Impl->m_CaptionBuffer;
}
return 0;
}
uint32 Window::GetFlags() const
{
if (m_Impl->m_HWND != NULL)
{
LONG style = GetWindowLong(m_Impl->m_HWND, GWL_STYLE);
LONG exstyle = GetWindowLong(m_Impl->m_HWND, GWL_EXSTYLE);
return m_Impl->GetFlagsFromStyle(style, exstyle);
}
else
{
return 0;
}
}
const GraphicsLibrary& Window::GetGraphicsLibrary() const
{
return m_Impl->m_GraphicsLibrary;
}
void Window::SetPosition(const vector2i& a_Position)
{
if (m_Impl->m_HWND != 0)
{
RECT rect = m_Impl->CalculateFrameRectangle(a_Position, GetSize(), GetFlags());
if (!SetWindowPos(m_Impl->m_HWND, 0, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to set Window size.", GetLastError());
}
}
}
void Window::SetSize(const vector2i& a_Size)
{
if (m_Impl->m_HWND != NULL)
{
RECT rect = m_Impl->CalculateFrameRectangle(GetPosition(), a_Size, GetFlags());
if (!SetWindowPos(m_Impl->m_HWND, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to set Window size.", GetLastError());
}
}
}
void Window::SetCaption(const char8* a_Caption)
{
if (m_Impl->m_HWND != NULL)
{
if (!SetWindowText(m_Impl->m_HWND, a_Caption))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to set Window caption.", GetLastError());
}
}
}
void Window::SetFlags(uint32 a_Flags)
{
if (m_Impl->m_HWND != NULL)
{
vector2i position = GetPosition();
vector2i size = GetSize();
SetWindowLong(m_Impl->m_HWND, GWL_STYLE, m_Impl->GetStyleFromFlags(a_Flags));
SetWindowLong(m_Impl->m_HWND, GWL_EXSTYLE, m_Impl->GetStyleExFromFlags(a_Flags));
SetPosition(position);
SetSize(size);
ShowWindow(m_Impl->m_HWND, SW_SHOW);
UpdateWindow(m_Impl->m_HWND);
}
}
void Window::SetAsRenderTarget()
{
if (m_Impl->m_HWND == NULL)
{
return;
}
switch (m_Impl->m_GraphicsLibrary.m_Type)
{
case GLT_NONE:
break;
case GLT_OPENGL:
if (!wglMakeCurrent(m_Impl->m_HDC, m_Impl->m_HGLRC))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to set Window as target.", GetLastError());
return;
}
break;
case GLT_DIRECTX:
#define CORE_COMPILER_MESSAGE "TODO: SetAsTarget DirectX"
#include "compilermessage.h"
break;
default:
Logger::Error(CORE_WINDOW_CHANNEL, "Failed to set Window as target", "Unknown or unsupported Graphics Library (%i).", m_Impl->m_GraphicsLibrary.m_Type);
break;
}
}
void Window::Update()
{
if (m_Impl->m_HWND == 0)
{
return;
}
MSG msg;
while (PeekMessage(&msg, m_Impl->m_HWND, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return;
}
void Window::SwapBuffers()
{
switch (m_Impl->m_GraphicsLibrary.m_Type)
{
case GLT_NONE:
break;
case GLT_OPENGL:
if (!::SwapBuffers(m_Impl->m_HDC))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to swap buffers.", GetLastError());
return;
}
break;
case GLT_DIRECTX:
#define CORE_COMPILER_MESSAGE "TODO: implement SwapBuffers for DirectX"
#include "compilermessage.h"
break;
default:
Logger::Error(CORE_WINDOW_CHANNEL, "Failed to swap buffers", "Unknown or unsupported Graphics Library (%i).", m_Impl->m_GraphicsLibrary.m_Type);
break;
}
}
Window::Window_Impl::Window_Impl(Window* a_Window):
m_Window(a_Window),
m_HWND(NULL)
{
m_HINSTANCE = GetModuleHandle(NULL);
}
Window::Window_Impl::~Window_Impl()
{
}
bool Window::Window_Impl::CreateFrame(const vector2i& a_Position, const vector2i& a_Size, const char8* a_Caption, uint32 a_Flags)
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating Window frame...");
if (!CreateWindowClass())
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Failed to create Window frame.");
return false;
}
RECT rect = CalculateFrameRectangle(a_Position, a_Size, a_Flags);
m_HWND = CreateWindowEx(GetStyleExFromFlags(a_Flags), m_WindowClassName, a_Caption, GetStyleFromFlags(a_Flags),
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, m_HINSTANCE, this);
if (m_HWND == NULL)
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create Windows frame.", GetLastError());
return false;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window frame created.");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Getting device context..");
m_HDC = GetDC(m_HWND);
if (m_HDC == NULL)
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to get device context.", GetLastError());
return false;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Device context received.");
return true;
}
bool Window::Window_Impl::DestroyFrame()
{
if (m_HWND != NULL)
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Destroying Window frame...");
if (!DestroyWindow(m_HWND))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to destroy Window frame", GetLastError());
return false;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window frame destroyed.");
}
return DestroyWindowClass();
}
bool Window::Window_Impl::CreateWindowClass()
{
if (m_WindowCounter == 0)
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating Window class...");
const uint32 classnamesize = strlen("windowclass") + 1;
m_WindowClassName = new char8[classnamesize];
strcpy_s(m_WindowClassName, classnamesize, "windowclass");
WNDCLASSEX windowclass;
memset(&windowclass, 0, sizeof(WNDCLASSEX));
windowclass.cbSize = sizeof(WNDCLASSEX);
windowclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_GLOBALCLASS;
windowclass.lpfnWndProc = StaticWndProc;
windowclass.hInstance = m_HINSTANCE;
windowclass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowclass.lpszClassName = m_WindowClassName;
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Registering Window class...");
if (!RegisterClassEx(&windowclass))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to register Window class", GetLastError());
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Failed to create Window class");
return false;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window class registered.");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window class created.");
}
m_WindowCounter++;
return true;
}
bool Window::Window_Impl::DestroyWindowClass()
{
m_WindowCounter--;
bool result = true;
if (m_WindowCounter == 0)
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Destroying Window class...");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Unregistering Window class");
if (UnregisterClass(m_WindowClassName, m_HINSTANCE) == 0)
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to unregister Window class.", GetLastError());
result = false;
}
else
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window class unregistered.");
}
delete[] m_WindowClassName;
m_WindowClassName = 0;
if (result)
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window class destroyed.");
return true;
}
else
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Failed to destroy Window class.");
return false;
}
}
return true;
}
bool Window::Window_Impl::CreateContext(const GraphicsLibrary& a_GraphicsLibrary)
{
switch (a_GraphicsLibrary.m_Type)
{
case GLT_NONE:
return true;
case GLT_OPENGL:
switch (a_GraphicsLibrary.m_VersionMajor)
{
case 4:
if (CreateContextOpenGL4(a_GraphicsLibrary))
{
return true;
}
Logger::Warning(CORE_WINDOW_CHANNEL, "Failed to initialize OpenGL 4.x.", "Failed to initialize OpenGL 4.x. Falling back to OpenGL 3.x.");
case 3:
if (CreateContextOpenGL3(a_GraphicsLibrary))
{
return true;
}
Logger::Warning(CORE_WINDOW_CHANNEL, "Failed to initialize OpenGL 3.x.", "Failed to initialize OpenGL 3.x. Falling back to OpenGL 2.x or lower.");
case 2:
case 1:
case 0:
return CreateContextOpenGL2(a_GraphicsLibrary);
default:
Logger::Error(CORE_WINDOW_CHANNEL, "Failed to create OpenGL context.", "Unknown OpenGL version: %i.%i", a_GraphicsLibrary.m_VersionMajor, a_GraphicsLibrary.m_VersionMinor);
return false;
}
case GLT_DIRECTX:
switch (a_GraphicsLibrary.m_VersionMajor)
{
case 11:
if (CreateContextDirectX11(a_GraphicsLibrary))
{
return true;
}
Logger::Warning(CORE_WINDOW_CHANNEL, "Failed to initialize DirectX 11.", "Failed to initialize DirectX 11.x. Falling back to DirectX 10.x.");
case 10:
if (CreateContextDirectX10(a_GraphicsLibrary))
{
return true;
}
Logger::Warning(CORE_WINDOW_CHANNEL, "Failed to initialize DirectX 10.", "Failed to initialize DirectX 10.x. Falling back to DirectX 9.x.");
case 9:
return CreateContextDirectX9(a_GraphicsLibrary);
default:
Logger::Error(CORE_WINDOW_CHANNEL, "Failed to create DirectX context.", "Unknown DirectX version: %i.%i", a_GraphicsLibrary.m_VersionMajor, a_GraphicsLibrary.m_VersionMinor);
return false;
}
break;
default:
Logger::Error(CORE_WINDOW_CHANNEL, "Unknown or unsupported Graphics Library. (%i)", "Failed to create context", a_GraphicsLibrary.m_Type);
return false;
}
}
bool Window::Window_Impl::CreateContextOpenGL2(const GraphicsLibrary& a_GraphicsLibrary)
{
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating OpenGL 2.x or lower context...");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Choosing pixel format...");
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24,
8,
0,
PFD_MAIN_PLANE,
0, 0, 0, 0
};
int32 pfn = ChoosePixelFormat(m_HDC, &pfd);
if (pfn == 0)
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create an OpenGL 2.x or lower context", GetLastError());
return false;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Pixel format chosen.");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Setting pixel format...");
if (!SetPixelFormat(m_HDC, pfn, &pfd))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create an OpenGL 2.x or lower context", GetLastError());
return false;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Pixel format set.");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating OpenGL context...");
m_HGLRC = wglCreateContext(m_HDC);
if (m_HGLRC == 0)
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create an OpenGL 2.x or lower context", GetLastError());
return false;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "OpenGL context created.");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Making OpenGL context current...");
if (!wglMakeCurrent(m_HDC, m_HGLRC))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create an OpenGL 2.x or lower context", GetLastError());
return false;
}
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "OpenGL made current.");
Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "OpenGL %i.%i context created.", a_GraphicsLibrary.m_VersionMajor, a_GraphicsLibrary.m_VersionMinor);
m_GraphicsLibrary = a_GraphicsLibrary;
if (m_HGLRCList.size() != 0)
{
wglShareLists(*(m_HGLRCList.begin()), m_HGLRC);
}
m_HGLRCList.insert(m_HGLRC);
return true;
}
bool Window::Window_Impl::CreateContextOpenGL3(const GraphicsLibrary& a_GraphicsLibrary)
{
#define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextOpenGL3"
#include "compilermessage.h"
return false;
}
bool Window::Window_Impl::CreateContextOpenGL4(const GraphicsLibrary& a_GraphicsLibrary)
{
#define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextOpenGL4"
#include "compilermessage.h"
return false;
}
bool Window::Window_Impl::CreateContextDirectX9(const GraphicsLibrary& a_GraphicsLibrary)
{
#define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextDirectX9"
#include "compilermessage.h"
return false;
}
bool Window::Window_Impl::CreateContextDirectX10(const GraphicsLibrary& a_GraphicsLibrary)
{
#define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextDirextX10"
#include "compilermessage.h"
return false;
}
bool Window::Window_Impl::CreateContextDirectX11(const GraphicsLibrary& a_GraphicsLibrary)
{
#define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextDirextX11"
#include "compilermessage.h"
return false;
}
LRESULT CALLBACK Window::Window_Impl::StaticWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
Window_Impl* wnd_impl = NULL;
if (msg == WM_CREATE)
{
wnd_impl = (Window_Impl*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
#if CORE_PLATFORM_BITS == 32
SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)wnd_impl);
#endif
#if CORE_PLATFORM_BITS == 64
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)wnd_impl);
#endif
}
else
{
#if CORE_PLATFORM_BITS == 32
wnd_impl = (Window_Impl*)GetWindowLongPtr(hwnd, GWL_USERDATA);
#endif
#if CORE_PLATFORM_BITS == 64
wnd_impl = (Window_Impl*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
#endif
if (!wnd_impl)
{
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
return wnd_impl->WndProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK Window::Window_Impl::WndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_SIZE:
EventManager::Event("window", "resize", m_Window);
break;
case WM_MOVE:
EventManager::Event("window", "move", m_Window);
break;
case WM_CLOSE:
EventManager::Event("window", "close", m_Window);
return 0;
case WM_INPUT:
EventManager::Event("window", "input", ((HRAWINPUT)lParam));
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
RECT Window::Window_Impl::CalculateFrameRectangle(const vector2i& a_Position, const vector2i& a_Size, uint32 a_Flags) const
{
RECT rect;
rect.left = a_Position.x;
rect.top = a_Position.y;
rect.right = a_Position.x + a_Size.x;
rect.bottom = a_Position.y + a_Size.y;
if (!AdjustWindowRectEx(&rect, GetStyleFromFlags(a_Flags), false, GetStyleExFromFlags(a_Flags)))
{
Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to adjust window rect.", GetLastError());
}
return rect;
}
DWORD Window::Window_Impl::GetStyleFromFlags(uint32 a_Flags) const
{
DWORD style = WS_VISIBLE;
if ((a_Flags & WF_NOFRAME) != 0)
{
style |= WS_POPUP;
}
if ((a_Flags & WF_RESIZE) != 0)
{
style |= WS_MAXIMIZEBOX;
style |= WS_THICKFRAME;
}
if ((a_Flags & WF_NOFRAME) == 0)
{
style |= WS_CAPTION;
if ((a_Flags & WF_NOSYSMENU) == 0)
{
style |= WS_SYSMENU;
style |= WS_MINIMIZEBOX;
}
}
return style;
}
DWORD Window::Window_Impl::GetStyleExFromFlags(uint32 a_Flags) const
{
DWORD style = 0;
if ((a_Flags & WF_WINDOWS_TOOL) != 0)
{
style |= WS_EX_TOOLWINDOW;
}
if ((a_Flags & WF_TOPMOST) != 0)
{
style |= WS_EX_TOPMOST;
}
return style;
}
uint32 Window::Window_Impl::GetFlagsFromStyle(DWORD a_Style, DWORD a_StyleEx) const
{
uint32 flags = 0;
if ((a_Style & WS_THICKFRAME) != 0)
{
flags |= WF_RESIZE;
}
if ((a_Style & WS_CAPTION) == 0)
{
flags |= WF_NOFRAME;
}
if ((a_Style & WS_SYSMENU) == 0)
{
flags |= WF_NOSYSMENU;
}
if ((a_StyleEx & WS_EX_TOOLWINDOW) != 0)
{
flags |= WF_WINDOWS_TOOL;
}
if ((a_StyleEx & WS_EX_TOPMOST) != 0)
{
flags |= WF_TOPMOST;
}
return flags;
}
I've had this bug for a while and mostly worked around it, but I really want to get rid of it.
Right now I just do as little as possible before creating the window and then hope it doesn't crash.