//////////////////////////////////////////////////////////// /// Register the window class //////////////////////////////////////////////////////////// void WindowImplWin32::RegisterWindowClass() { if (HasUnicodeSupport()) { WNDCLASSW WindowClass; WindowClass.style = 0; WindowClass.lpfnWndProc = &WindowImplWin32::GlobalOnEvent; WindowClass.cbClsExtra = 0; WindowClass.cbWndExtra = 0; WindowClass.hInstance = GetModuleHandle(NULL); WindowClass.hIcon = NULL; WindowClass.hCursor = 0; WindowClass.hbrBackground = 0; WindowClass.lpszMenuName = NULL; WindowClass.lpszClassName = ourClassNameW; RegisterClassW(&WindowClass); } else { WNDCLASSA WindowClass; WindowClass.style = 0; WindowClass.lpfnWndProc = &WindowImplWin32::GlobalOnEvent; WindowClass.cbClsExtra = 0; WindowClass.cbWndExtra = 0; WindowClass.hInstance = GetModuleHandle(NULL); WindowClass.hIcon = NULL; WindowClass.hCursor = 0; WindowClass.hbrBackground = 0; WindowClass.lpszMenuName = NULL; WindowClass.lpszClassName = ourClassNameA; RegisterClassA(&WindowClass); } }
//////////////////////////////////////////////////////////// /// Function called whenever one of our windows receives a message //////////////////////////////////////////////////////////// LRESULT CALLBACK WindowImplWin32::GlobalOnEvent(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam) { // Associate handle and Window instance when the creation message is received if (Message == WM_CREATE) { // Get WindowImplWin32 instance (it was passed as the last argument of CreateWindow) long This = reinterpret_cast<long>(reinterpret_cast<CREATESTRUCT*>(LParam)->lpCreateParams); // Set as the "user data" parameter of the window SetWindowLongPtr(Handle, GWLP_USERDATA, This); } // Get the WindowImpl instance corresponding to the window handle WindowImplWin32* Window = reinterpret_cast<WindowImplWin32*>(GetWindowLongPtr(Handle, GWLP_USERDATA)); // Forward the event to the appropriate function if (Window) { Window->ProcessEvent(Message, WParam, LParam); if (Window->myCallback) return CallWindowProc(reinterpret_cast<WNDPROC>(Window->myCallback), Handle, Message, WParam, LParam); } // We don't forward the WM_CLOSE message to prevent the OS from automatically destroying the window if (Message == WM_CLOSE) return 0; static const bool HasUnicode = HasUnicodeSupport(); return HasUnicode ? DefWindowProcW(Handle, Message, WParam, LParam) : DefWindowProcA(Handle, Message, WParam, LParam); }
//////////////////////////////////////////////////////////// /// Close (destroy) the window. //////////////////////////////////////////////////////////// void WindowClose() { // Destroy the custom icon, if any if (WindowIcon) DestroyIcon(WindowIcon); if (!WindowCallback) { // Destroy the window if (WindowhWnd) DestroyWindow(WindowhWnd); // Unregister window class if we were the last window if (HasUnicodeSupport()) { UnregisterClassW(WindowClassNameW, GetModuleHandle(NULL)); } else { UnregisterClassA(WindowClassNameA, GetModuleHandle(NULL)); } } else { // The window is external : remove the hook on its message callback SetWindowLongPtr(WindowhWnd, GWLP_WNDPROC, WindowCallback); } // Set window open state to false WindowIsOpened = false; // Destroy the event mutex MutexDestroy(&WindowEventMutex); }
//////////////////////////////////////////////////////////// /// Function called whenever one of our windows receives a message //////////////////////////////////////////////////////////// static LRESULT CALLBACK GlobalOnEvent(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam) { // Associate handle and Window instance when the creation message is received if (Message == WM_CREATE) { // Get instance (it was passed as the last argument of CreateWindow) LONG Instance = (LONG)((CREATESTRUCT *)LParam)->lpCreateParams; // Set as the "user data" parameter of the window SetWindowLongPtr(Handle, GWLP_USERDATA, Instance); } // Forward the event to the appropriate function if (WindowhWnd) { ProcessEvent(Message, WParam, LParam); if (WindowCallback) return CallWindowProc((WNDPROC)(WindowCallback), Handle, Message, WParam, LParam); } // We don't forward the WM_CLOSE message to prevent the OS from automatically destroying the window if (Message == WM_CLOSE) return 0; return HasUnicodeSupport() ? DefWindowProcW(Handle, Message, WParam, LParam) : DefWindowProcA(Handle, Message, WParam, LParam); }
//////////////////////////////////////////////////////////// /// Create (or recreate) the window //////////////////////////////////////////////////////////// bool WindowCreate(struct VideoMode * Mode, char * Title, unsigned long WindowStyle, struct WindowSettings * Params) { int Left, Top, Width, Height; bool FullScreen = false; DWORD Win32Style; RECT ActualRect; // Initialize the event mutex MutexInitialize(&WindowEventMutex); // Register the window class at first call RegisterWindowClass(); // Compute position and size Left = (GetDeviceCaps(GetDC(NULL), HORZRES) - Mode->Width) / 2; Top = (GetDeviceCaps(GetDC(NULL), VERTRES) - Mode->Height) / 2; Width = WindowWidth = Mode->Width; Height = WindowHeight = Mode->Height; // Choose the window style according to the Style parameter Win32Style = WS_VISIBLE; if (WindowStyle == NonStyle) { Win32Style |= WS_POPUP; } else { if (WindowStyle & Titlebar) Win32Style |= WS_CAPTION | WS_MINIMIZEBOX; if (WindowStyle & Resize) Win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX; if (WindowStyle & Close) Win32Style |= WS_SYSMENU; } // In windowed mode, adjust width and height so that window will have the requested client area FullScreen = ((WindowStyle & Fullscreen) != 0); if (!FullScreen) { RECT Rect = {0, 0, Width, Height}; AdjustWindowRect(&Rect, Win32Style, false); Width = Rect.right - Rect.left; Height = Rect.bottom - Rect.top; } // Create the window if (HasUnicodeSupport()) { wchar_t WTitle[256]; int NbChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)(Title), (int)(strlen(Title)), WTitle, sizeof(WTitle) / sizeof(*WTitle)); WTitle[NbChars] = L'\0'; WindowhWnd = CreateWindowW(WindowClassNameW, WTitle, Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), NULL); } else { WindowhWnd = CreateWindowA(WindowClassNameA, (LPCSTR)(Title), Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), NULL); } // Switch to fullscreen if requested if (FullScreen) SwitchToFullscreen(Mode); // Create the rendering context if (WindowhWnd) CreateContext(Mode, Params); // Get the actual size of the window, which can be smaller even after the call to AdjustWindowRect // This happens when the window is bigger than the desktop GetClientRect(WindowhWnd, &ActualRect); WindowWidth = ActualRect.right - ActualRect.left; WindowHeight = ActualRect.bottom - ActualRect.top; // Set window open state to true WindowIsOpened = true; // Key Repeat is enabled WindowKeyRepeatEnabled = false; // Resize the OpenGL scene OpenGLResizeScene(); return true; }