149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang//
249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang// Use of this source code is governed by a BSD-style license that can be
449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang// found in the LICENSE file.
549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang//
649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang#include "win32/Win32Window.h"
849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff LangKey VirtualKeyCodeToKey(WPARAM key, LPARAM flags)
1049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
1149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    switch (key)
1249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    {
1349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        // Check the scancode to distinguish between left and right shift
1449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_SHIFT:
1549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        {
1649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            static unsigned int lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
1749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            unsigned int scancode = static_cast<unsigned int>((flags & (0xFF << 16)) >> 16);
1849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            return scancode == lShift ? KEY_LSHIFT : KEY_RSHIFT;
1949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        }
2049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
2149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        // Check the "extended" flag to distinguish between left and right alt
2249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_MENU:       return (HIWORD(flags) & KF_EXTENDED) ? KEY_RALT : KEY_LALT;
2349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
2449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        // Check the "extended" flag to distinguish between left and right control
2549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_CONTROL:    return (HIWORD(flags) & KF_EXTENDED) ? KEY_RCONTROL : KEY_LCONTROL;
2649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
2749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        // Other keys are reported properly
2849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_LWIN:       return KEY_LSYSTEM;
2949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_RWIN:       return KEY_RSYSTEM;
3049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_APPS:       return KEY_MENU;
3149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_1:      return KEY_SEMICOLON;
3249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_2:      return KEY_SLASH;
3349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_PLUS:   return KEY_EQUAL;
3449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_MINUS:  return KEY_DASH;
3549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_4:      return KEY_LBRACKET;
3649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_6:      return KEY_RBRACKET;
3749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_COMMA:  return KEY_COMMA;
3849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_PERIOD: return KEY_PERIOD;
3949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_7:      return KEY_QUOTE;
4049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_5:      return KEY_BACKSLASH;
4149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_OEM_3:      return KEY_TILDE;
4249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_ESCAPE:     return KEY_ESCAPE;
4349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_SPACE:      return KEY_SPACE;
4449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_RETURN:     return KEY_RETURN;
4549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_BACK:       return KEY_BACK;
4649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_TAB:        return KEY_TAB;
4749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_PRIOR:      return KEY_PAGEUP;
4849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NEXT:       return KEY_PAGEDOWN;
4949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_END:        return KEY_END;
5049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_HOME:       return KEY_HOME;
5149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_INSERT:     return KEY_INSERT;
5249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_DELETE:     return KEY_DELETE;
5349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_ADD:        return KEY_ADD;
5449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_SUBTRACT:   return KEY_SUBTRACT;
5549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_MULTIPLY:   return KEY_MULTIPLY;
5649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_DIVIDE:     return KEY_DIVIDE;
5749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_PAUSE:      return KEY_PAUSE;
5849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F1:         return KEY_F1;
5949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F2:         return KEY_F2;
6049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F3:         return KEY_F3;
6149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F4:         return KEY_F4;
6249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F5:         return KEY_F5;
6349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F6:         return KEY_F6;
6449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F7:         return KEY_F7;
6549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F8:         return KEY_F8;
6649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F9:         return KEY_F9;
6749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F10:        return KEY_F10;
6849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F11:        return KEY_F11;
6949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F12:        return KEY_F12;
7049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F13:        return KEY_F13;
7149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F14:        return KEY_F14;
7249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_F15:        return KEY_F15;
7349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_LEFT:       return KEY_LEFT;
7449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_RIGHT:      return KEY_RIGHT;
7549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_UP:         return KEY_UP;
7649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_DOWN:       return KEY_DOWN;
7749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD0:    return KEY_NUMPAD0;
7849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD1:    return KEY_NUMPAD1;
7949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD2:    return KEY_NUMPAD2;
8049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD3:    return KEY_NUMPAD3;
8149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD4:    return KEY_NUMPAD4;
8249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD5:    return KEY_NUMPAD5;
8349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD6:    return KEY_NUMPAD6;
8449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD7:    return KEY_NUMPAD7;
8549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD8:    return KEY_NUMPAD8;
8649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case VK_NUMPAD9:    return KEY_NUMPAD9;
8749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'A':           return KEY_A;
8849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'Z':           return KEY_Z;
8949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'E':           return KEY_E;
9049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'R':           return KEY_R;
9149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'T':           return KEY_T;
9249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'Y':           return KEY_Y;
9349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'U':           return KEY_U;
9449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'I':           return KEY_I;
9549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'O':           return KEY_O;
9649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'P':           return KEY_P;
9749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'Q':           return KEY_Q;
9849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'S':           return KEY_S;
9949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'D':           return KEY_D;
10049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'F':           return KEY_F;
10149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'G':           return KEY_G;
10249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'H':           return KEY_H;
10349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'J':           return KEY_J;
10449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'K':           return KEY_K;
10549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'L':           return KEY_L;
10649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'M':           return KEY_M;
10749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'W':           return KEY_W;
10849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'X':           return KEY_X;
10949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'C':           return KEY_C;
11049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'V':           return KEY_V;
11149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'B':           return KEY_B;
11249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case 'N':           return KEY_N;
11349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '0':           return KEY_NUM0;
11449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '1':           return KEY_NUM1;
11549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '2':           return KEY_NUM2;
11649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '3':           return KEY_NUM3;
11749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '4':           return KEY_NUM4;
11849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '5':           return KEY_NUM5;
11949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '6':           return KEY_NUM6;
12049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '7':           return KEY_NUM7;
12149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '8':           return KEY_NUM8;
12249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case '9':           return KEY_NUM9;
12349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    }
12449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
12549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    return Key(0);
12649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
12749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
12849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff LangLRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
12949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
13049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    switch(message)
13149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    {
13249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      case WM_NCCREATE:
13349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        {
13449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            LPCREATESTRUCT pCreateStruct = (LPCREATESTRUCT)lParam;
13549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pCreateStruct->lpCreateParams);
13649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            return DefWindowProcA(hWnd, message, wParam, lParam);
13749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        }
13849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    }
13949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
1401cfaaf8a3ba7c0ca6cb1a8dff7c1037467555bddJamie Madill    OSWindow *window = (OSWindow*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
14149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    if (window)
14249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    {
14349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        switch (message)
14449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        {
14549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_DESTROY:
14649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_CLOSE:
14749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
14849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
14949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type = Event::EVENT_CLOSED;
15049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
15149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
15249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
15349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
15449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_MOVE:
15549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
15649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                RECT winRect;
15749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                GetClientRect(hWnd, &winRect);
15849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
15949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                POINT topLeft;
16049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                topLeft.x = winRect.left;
16149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                topLeft.y = winRect.top;
16249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                ClientToScreen(hWnd, &topLeft);
16349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
16449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
16549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type        = Event::EVENT_MOVED;
16649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Move.X      = topLeft.x;
16749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Move.Y      = topLeft.y;
16849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
16949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
17049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
17149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
17249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
17349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_SIZE:
17449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
17549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                RECT winRect;
17649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                GetClientRect(hWnd, &winRect);
17749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
17849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                POINT topLeft;
17949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                topLeft.x = winRect.left;
18049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                topLeft.y = winRect.top;
18149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                ClientToScreen(hWnd, &topLeft);
18249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
18349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                POINT botRight;
18449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                botRight.x = winRect.right;
18549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                botRight.y = winRect.bottom;
18649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                ClientToScreen(hWnd, &botRight);
18749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
18849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
18949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type        = Event::EVENT_RESIZED;
19049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Size.Width  = botRight.x - topLeft.x;
19149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Size.Height = botRight.y - topLeft.y;
19249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
19349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
19449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
19549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
19649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
19749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_SETFOCUS:
19849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
19949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
20049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type = Event::EVENT_GAINED_FOCUS;
20149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
20249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
20349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
20449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
20549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_KILLFOCUS:
20649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
20749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
20849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type = Event::EVENT_LOST_FOCUS;
20949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
21049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
21149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
21249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
21349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_KEYDOWN:
21449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_SYSKEYDOWN:
21549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_KEYUP:
21649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_SYSKEYUP:
21749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
21849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                bool down = (message == WM_KEYDOWN || message == WM_SYSKEYDOWN);
21949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
22049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
22149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type        = down ? Event::EVENT_KEY_PRESSED : Event::EVENT_KEY_RELEASED;
22249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Key.Alt     = HIWORD(GetAsyncKeyState(VK_MENU))    != 0;
22349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
22449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Key.Shift   = HIWORD(GetAsyncKeyState(VK_SHIFT))   != 0;
22549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Key.System  = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
22649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Key.Code    = VirtualKeyCodeToKey(wParam, lParam);
22749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
22849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
22949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
23049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
23149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
23249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_MOUSEWHEEL:
23349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
23449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
23549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type = Event::EVENT_MOUSE_WHEEL_MOVED;
23649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseWheel.Delta = static_cast<short>(HIWORD(wParam)) / 120;
23749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
23849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
23949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
24049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
24149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_LBUTTONDOWN:
24249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_LBUTTONDBLCLK:
24349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
24449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
24549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
24649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Button = MOUSEBUTTON_LEFT;
24749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
24849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
24949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
25049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
25149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
25249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
25349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_LBUTTONUP:
25449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
25549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
25649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
25749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Button = MOUSEBUTTON_LEFT;
25849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
25949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
26049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
26149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
26249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
26349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
26449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_RBUTTONDOWN:
26549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_RBUTTONDBLCLK:
26649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
26749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
26849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
26949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Button = MOUSEBUTTON_RIGHT;
27049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
27149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
27249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
27349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
27449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
27549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
27649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            // Mouse right button up event
27749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_RBUTTONUP:
27849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
27949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
28049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
28149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Button = MOUSEBUTTON_RIGHT;
28249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
28349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
28449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
28549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
28649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
28749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
28849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            // Mouse wheel button down event
28949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_MBUTTONDOWN:
29049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_MBUTTONDBLCLK:
29149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
29249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
29349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
29449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
29549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
29649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
29749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
29849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
29949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
30049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
30149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            // Mouse wheel button up event
30249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_MBUTTONUP:
30349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
30449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
30549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
30649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
30749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
30849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
30949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
31049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
31149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
31249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
31349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            // Mouse X button down event
31449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_XBUTTONDOWN:
31549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_XBUTTONDBLCLK:
31649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
31749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
31849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
31949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Button = (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
32049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
32149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
32249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
32349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
32449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
32549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
32649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            // Mouse X button up event
32749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_XBUTTONUP:
32849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
32949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
33049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
33149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Button = (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
33249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
33349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
33449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
33549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
33649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
33749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
33849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_MOUSEMOVE:
33949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
34049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                int mouseX = static_cast<short>(LOWORD(lParam));
34149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                int mouseY = static_cast<short>(HIWORD(lParam));
34249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
34349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
34449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type        = Event::EVENT_MOUSE_MOVED;
34549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseMove.X = mouseX;
34649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.MouseMove.Y = mouseY;
34749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
34849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
34949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
35049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
35149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang          case WM_MOUSELEAVE:
35249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            {
35349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                Event event;
35449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                event.Type = Event::EVENT_MOUSE_LEFT;
35549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                window->pushEvent(event);
35649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                break;
35749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang            }
35849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        }
35949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
36049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    }
36149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    return DefWindowProcA(hWnd, message, wParam, lParam);
36249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
36349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
36449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff LangWin32Window::Win32Window()
3659e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    : mNativeWindow(0),
3669e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill      mParentWindow(0),
36749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang      mNativeDisplay(0)
36849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
36949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
37049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
37149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff LangWin32Window::~Win32Window()
37249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
37349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    destroy();
37449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
37549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
376f0955f1585d2f28acb11664f2d9eb3a1aa684577Geoff Langbool Win32Window::initialize(const std::string &name, size_t width, size_t height)
37749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
37849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    destroy();
37949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
3809e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    mParentClassName = name;
3819e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    mChildClassName = name + "Child";
3829e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill
3839e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    WNDCLASSEXA parentWindowClass = { 0 };
3849e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.cbSize = sizeof(WNDCLASSEXA);
3859e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.style = 0;
3869e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.lpfnWndProc = WndProc;
3879e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.cbClsExtra = 0;
3889e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.cbWndExtra = 0;
3899e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.hInstance = GetModuleHandle(NULL);
3909e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.hIcon = NULL;
3919e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
3929e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.hbrBackground = 0;
3939e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.lpszMenuName = NULL;
3949e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    parentWindowClass.lpszClassName = mParentClassName.c_str();
3959e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    if (!RegisterClassExA(&parentWindowClass))
39649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    {
39749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        return false;
39849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    }
39949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
4009e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    WNDCLASSEXA childWindowClass = { 0 };
4019e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.cbSize = sizeof(WNDCLASSEXA);
4029e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.style = CS_OWNDC;
4039e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.lpfnWndProc = WndProc;
4049e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.cbClsExtra = 0;
4059e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.cbWndExtra = 0;
4069e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.hInstance = GetModuleHandle(NULL);
4079e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.hIcon = NULL;
4089e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
4099e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.hbrBackground = 0;
4109e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.lpszMenuName = NULL;
4119e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    childWindowClass.lpszClassName = mChildClassName.c_str();
4129e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    if (!RegisterClassExA(&childWindowClass))
4139e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    {
4149e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill        return false;
4159e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    }
4169e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill
4179e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    DWORD parentStyle = WS_VISIBLE | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
4189e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    DWORD parentExtendedStyle = WS_EX_APPWINDOW;
41949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
42049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    RECT sizeRect = { 0, 0, width, height };
4219e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    AdjustWindowRectEx(&sizeRect, parentStyle, FALSE, parentExtendedStyle);
42249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
4239e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    mParentWindow = CreateWindowExA(parentExtendedStyle, mParentClassName.c_str(), name.c_str(), parentStyle, CW_USEDEFAULT, CW_USEDEFAULT,
42449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                                    sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top, NULL, NULL,
42549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang                                    GetModuleHandle(NULL), this);
42649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
4279e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    mNativeWindow = CreateWindowExA(0, mChildClassName.c_str(), name.c_str(), WS_VISIBLE | WS_CHILD, 0, 0, width, height,
4289e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill                                    mParentWindow, NULL, GetModuleHandle(NULL), this);
42949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
43049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    mNativeDisplay = GetDC(mNativeWindow);
43149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    if (!mNativeDisplay)
43249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    {
43349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        destroy();
43449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        return false;
43549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    }
43649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
43749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    return true;
43849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
43949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
44049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Langvoid Win32Window::destroy()
44149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
44249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    if (mNativeDisplay)
44349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    {
44449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        ReleaseDC(mNativeWindow, mNativeDisplay);
44549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        mNativeDisplay = 0;
44649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    }
44749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
44849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    if (mNativeWindow)
44949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    {
45049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        DestroyWindow(mNativeWindow);
45149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        mNativeWindow = 0;
45249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    }
45349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
4549e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    if (mParentWindow)
4559e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    {
4569e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill        DestroyWindow(mParentWindow);
4579e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill        mParentWindow = 0;
4589e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    }
4599e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill
4609e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    UnregisterClassA(mParentClassName.c_str(), NULL);
4619e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    UnregisterClassA(mChildClassName.c_str(), NULL);
46249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
46349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
46449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff LangEGLNativeWindowType Win32Window::getNativeWindow() const
46549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
46649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    return mNativeWindow;
46749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
46849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
46949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff LangEGLNativeDisplayType Win32Window::getNativeDisplay() const
47049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
47149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    return mNativeDisplay;
47249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
47349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
47449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Langvoid Win32Window::messageLoop()
47549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
47649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    MSG msg;
47749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
47849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    {
47949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        TranslateMessage(&msg);
48049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang        DispatchMessage(&msg);
48149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    }
48249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
48349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
48449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Langvoid Win32Window::setMousePosition(int x, int y)
48549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang{
48649be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    RECT winRect;
48749be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    GetClientRect(mNativeWindow, &winRect);
48849be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
48949be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    POINT topLeft;
49049be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    topLeft.x = winRect.left;
49149be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    topLeft.y = winRect.top;
49249be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    ClientToScreen(mNativeWindow, &topLeft);
49349be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang
49449be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang    SetCursorPos(topLeft.x + x, topLeft.y + y);
49549be2ad9f863f5b238997e740aa35adc40ba66e3Geoff Lang}
4968def9aac0e28bdbc9e05264eb90e0455526fcb76Geoff Lang
4971cfaaf8a3ba7c0ca6cb1a8dff7c1037467555bddJamie MadillOSWindow *CreateOSWindow()
4988def9aac0e28bdbc9e05264eb90e0455526fcb76Geoff Lang{
4998def9aac0e28bdbc9e05264eb90e0455526fcb76Geoff Lang    return new Win32Window();
5008def9aac0e28bdbc9e05264eb90e0455526fcb76Geoff Lang}
50125f0e5e389b782a102182f216b92861898a2dc11Jamie Madill
50225f0e5e389b782a102182f216b92861898a2dc11Jamie Madillbool Win32Window::resize(int width, int height)
50325f0e5e389b782a102182f216b92861898a2dc11Jamie Madill{
5049e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    if (width == mWidth && height == mHeight)
5059e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    {
5069e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill        return true;
5079e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    }
5089e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill
50925f0e5e389b782a102182f216b92861898a2dc11Jamie Madill    RECT windowRect;
5109e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    if (!GetWindowRect(mParentWindow, &windowRect))
5119e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    {
5129e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill        return false;
5139e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    }
5149e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill
5159e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    RECT clientRect;
5169e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    if (!GetClientRect(mParentWindow, &clientRect))
51725f0e5e389b782a102182f216b92861898a2dc11Jamie Madill    {
51825f0e5e389b782a102182f216b92861898a2dc11Jamie Madill        return false;
51925f0e5e389b782a102182f216b92861898a2dc11Jamie Madill    }
52025f0e5e389b782a102182f216b92861898a2dc11Jamie Madill
5219e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    LONG diffX = (windowRect.right - windowRect.left) - clientRect.right;
5229e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    LONG diffY = (windowRect.bottom - windowRect.top) - clientRect.bottom;
5239e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    if (!MoveWindow(mParentWindow, windowRect.left, windowRect.top, width + diffX, height + diffY, FALSE))
52425f0e5e389b782a102182f216b92861898a2dc11Jamie Madill    {
52525f0e5e389b782a102182f216b92861898a2dc11Jamie Madill        return false;
52625f0e5e389b782a102182f216b92861898a2dc11Jamie Madill    }
52725f0e5e389b782a102182f216b92861898a2dc11Jamie Madill
5289e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    if (!MoveWindow(mNativeWindow, 0, 0, width, height, FALSE))
5299e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    {
5309e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill        return false;
5319e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    }
53225f0e5e389b782a102182f216b92861898a2dc11Jamie Madill
53325f0e5e389b782a102182f216b92861898a2dc11Jamie Madill    return true;
53425f0e5e389b782a102182f216b92861898a2dc11Jamie Madill}
53583da0ec52f330f7e1972929654ea6e98ab450521Jamie Madill
53683da0ec52f330f7e1972929654ea6e98ab450521Jamie Madillbool Win32Window::setVisible(bool isVisible)
53783da0ec52f330f7e1972929654ea6e98ab450521Jamie Madill{
5389e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    int flag = (isVisible ? SW_SHOW : SW_HIDE);
5399e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill
5409e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    return (ShowWindow(mNativeWindow, flag) == TRUE) &&
5419e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill           (ShowWindow(mParentWindow, flag) == TRUE);
5429e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill}
5439e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill
5449e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madillvoid Win32Window::pushEvent(Event event)
5459e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill{
5469e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    OSWindow::pushEvent(event);
5479e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill
5489e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    switch (event.Type)
5499e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    {
5509e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill      case Event::EVENT_RESIZED:
5519e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill        MoveWindow(mNativeWindow, 0, 0, mWidth, mHeight, FALSE);
5529e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill        break;
5539e16d40de399d1a99958b4a22f72b325a7d3403bJamie Madill    }
55483da0ec52f330f7e1972929654ea6e98ab450521Jamie Madill}
555