SFML logo
  • Main Page
  • Namespaces
  • Classes
  • Files
  • File List

WindowImplWin32.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #define _WIN32_WINDOWS 0x0501
00029 #define _WIN32_WINNT   0x0501
00030 #include <SFML/Window/Win32/WindowImplWin32.hpp>
00031 #include <SFML/Window/WindowStyle.hpp>
00032 #include <GL/gl.h>
00033 #include <SFML/Window/glext/wglext.h>
00034 #include <SFML/Window/glext/glext.h>
00035 #include <SFML/System/Err.hpp>
00036 #include <vector>
00037 
00038 // MinGW lacks the definition of some Win32 constants
00039 #ifndef XBUTTON1
00040     #define XBUTTON1 0x0001
00041 #endif
00042 #ifndef XBUTTON2
00043     #define XBUTTON2 0x0002
00044 #endif
00045 #ifndef MAPVK_VK_TO_VSC
00046     #define MAPVK_VK_TO_VSC (0)
00047 #endif
00048 
00049 
00051 // Private data
00053 namespace
00054 {
00055     unsigned int               WindowCount      = 0;
00056     const char*                ClassNameA       = "SFML_Window";
00057     const wchar_t*             ClassNameW       = L"SFML_Window";
00058     sf::priv::WindowImplWin32* FullscreenWindow = NULL;
00059 }
00060 
00061 namespace sf
00062 {
00063 namespace priv
00064 {
00066 WindowImplWin32::WindowImplWin32(WindowHandle handle) :
00067 myHandle          (NULL),
00068 myCallback        (0),
00069 myCursor          (NULL),
00070 myIcon            (NULL),
00071 myKeyRepeatEnabled(true),
00072 myIsCursorIn      (false)
00073 {
00074     // Save window handle
00075     myHandle = static_cast<HWND>(handle);
00076 
00077     if (myHandle)
00078     {
00079         // Get window client size
00080         RECT rectangle;
00081         GetClientRect(myHandle, &rectangle);
00082         myWidth  = rectangle.right - rectangle.left;
00083         myHeight = rectangle.bottom - rectangle.top;
00084 
00085         // We change the event procedure of the control (it is important to save the old one)
00086         SetWindowLongPtr(myHandle, GWLP_USERDATA, reinterpret_cast<long>(this));
00087         myCallback = SetWindowLongPtr(myHandle, GWLP_WNDPROC, reinterpret_cast<long>(&WindowImplWin32::GlobalOnEvent));
00088     }
00089 }
00090 
00091 
00093 WindowImplWin32::WindowImplWin32(VideoMode mode, const std::string& title, unsigned long style) :
00094 myHandle          (NULL),
00095 myCallback        (0),
00096 myCursor          (NULL),
00097 myIcon            (NULL),
00098 myKeyRepeatEnabled(true),
00099 myIsCursorIn      (false)
00100 {
00101     // Register the window class at first call
00102     if (WindowCount == 0)
00103         RegisterWindowClass();
00104 
00105     // Compute position and size
00106     HDC screenDC = GetDC(NULL);
00107     int left   = (GetDeviceCaps(screenDC, HORZRES) - mode.Width)  / 2;
00108     int top    = (GetDeviceCaps(screenDC, VERTRES) - mode.Height) / 2;
00109     int width  = myWidth  = mode.Width;
00110     int height = myHeight = mode.Height;
00111     ReleaseDC(NULL, screenDC);
00112 
00113     // Choose the window style according to the Style parameter
00114     DWORD win32Style = WS_VISIBLE;
00115     if (style == Style::None)
00116     {
00117         win32Style |= WS_POPUP;
00118     }
00119     else
00120     {
00121         if (style & Style::Titlebar) win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
00122         if (style & Style::Resize)   win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
00123         if (style & Style::Close)    win32Style |= WS_SYSMENU;
00124     }
00125 
00126     // In windowed mode, adjust width and height so that window will have the requested client area
00127     bool fullscreen = (style & Style::Fullscreen) != 0;
00128     if (!fullscreen)
00129     {
00130         RECT rectangle = {0, 0, width, height};
00131         AdjustWindowRect(&rectangle, win32Style, false);
00132         width  = rectangle.right - rectangle.left;
00133         height = rectangle.bottom - rectangle.top;
00134     }
00135 
00136     // Create the window
00137     if (HasUnicodeSupport())
00138     {
00139         wchar_t wTitle[256];
00140         int count = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, title.c_str(), static_cast<int>(title.size()), wTitle, sizeof(wTitle) / sizeof(*wTitle));
00141         wTitle[count] = L'\0';
00142         myHandle = CreateWindowW(ClassNameW, wTitle, win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
00143     }
00144     else
00145     {
00146         myHandle = CreateWindowA(ClassNameA, title.c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
00147     }
00148 
00149     // Switch to fullscreen if requested
00150     if (fullscreen)
00151         SwitchToFullscreen(mode);
00152 
00153     // Increment window count
00154     WindowCount++;
00155 
00156     // Get the actual size of the window, which can be smaller even after the call to AdjustWindowRect
00157     // This happens when the window is bigger than the desktop
00158     RECT actualRectangle;
00159     GetClientRect(myHandle, &actualRectangle);
00160     myWidth  = actualRectangle.right - actualRectangle.left;
00161     myHeight = actualRectangle.bottom - actualRectangle.top;
00162 }
00163 
00164 
00166 WindowImplWin32::~WindowImplWin32()
00167 {
00168     // Destroy the custom icon, if any
00169     if (myIcon)
00170         DestroyIcon(myIcon);
00171 
00172     if (!myCallback)
00173     {
00174         // Destroy the window
00175         if (myHandle)
00176             DestroyWindow(myHandle);
00177 
00178         // Decrement the window count
00179         WindowCount--;
00180 
00181         // Unregister window class if we were the last window
00182         if (WindowCount == 0)
00183         {
00184             if (HasUnicodeSupport())
00185             {
00186                 UnregisterClassW(ClassNameW, GetModuleHandle(NULL));
00187             }
00188             else
00189             {
00190                 UnregisterClassA(ClassNameA, GetModuleHandle(NULL));
00191             }
00192         }
00193     }
00194     else
00195     {
00196         // The window is external : remove the hook on its message callback
00197         SetWindowLongPtr(myHandle, GWLP_WNDPROC, myCallback);
00198     }
00199 }
00200 
00201 
00203 WindowHandle WindowImplWin32::GetHandle() const
00204 {
00205     return myHandle;
00206 }
00207 
00208 
00210 void WindowImplWin32::ProcessEvents(bool block)
00211 {
00212     // We process the window events only if we own it
00213     if (!myCallback)
00214     {
00215         if (block)
00216             WaitMessage();
00217 
00218         MSG message;
00219         while (PeekMessage(&message, myHandle, 0, 0, PM_REMOVE))
00220         {
00221             TranslateMessage(&message);
00222             DispatchMessage(&message);
00223         }
00224     }
00225 }
00226 
00227 
00229 void WindowImplWin32::ShowMouseCursor(bool show)
00230 {
00231     if (show)
00232         myCursor = LoadCursor(NULL, IDC_ARROW);
00233     else
00234         myCursor = NULL;
00235 
00236     SetCursor(myCursor);
00237 }
00238 
00239 
00241 void WindowImplWin32::SetCursorPosition(unsigned int left, unsigned int top)
00242 {
00243     POINT position = {left, top};
00244     ClientToScreen(myHandle, &position);
00245     SetCursorPos(position.x, position.y);
00246 }
00247 
00248 
00250 void WindowImplWin32::SetPosition(int left, int top)
00251 {
00252     SetWindowPos(myHandle, NULL, left, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
00253 }
00254 
00255 
00257 void WindowImplWin32::SetSize(unsigned int width, unsigned int height)
00258 {
00259     // SetWindowPos wants the total size of the window (including title bar and borders),
00260     // so we have to compute it
00261     RECT rectangle = {0, 0, width, height};
00262     AdjustWindowRect(&rectangle, GetWindowLong(myHandle, GWL_STYLE), false);
00263     width  = rectangle.right - rectangle.left;
00264     height = rectangle.bottom - rectangle.top;
00265 
00266     SetWindowPos(myHandle, NULL, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER);
00267 }
00268 
00269 
00271 void WindowImplWin32::Show(bool show)
00272 {
00273     ShowWindow(myHandle, show ? SW_SHOW : SW_HIDE);
00274 }
00275 
00276 
00278 void WindowImplWin32::EnableKeyRepeat(bool enabled)
00279 {
00280     myKeyRepeatEnabled = enabled;
00281 }
00282 
00283 
00285 void WindowImplWin32::SetIcon(unsigned int width, unsigned int height, const Uint8* pixels)
00286 {
00287     // First destroy the previous one
00288     if (myIcon)
00289         DestroyIcon(myIcon);
00290 
00291     // Windows wants BGRA pixels : swap red and blue channels
00292     std::vector<Uint8> iconPixels(width * height * 4);
00293     for (std::size_t i = 0; i < iconPixels.size() / 4; ++i)
00294     {
00295         iconPixels[i * 4 + 0] = pixels[i * 4 + 2];
00296         iconPixels[i * 4 + 1] = pixels[i * 4 + 1];
00297         iconPixels[i * 4 + 2] = pixels[i * 4 + 0];
00298         iconPixels[i * 4 + 3] = pixels[i * 4 + 3];
00299     }
00300 
00301     // Create the icon from the pixels array
00302     myIcon = CreateIcon(GetModuleHandle(NULL), width, height, 1, 32, NULL, &iconPixels[0]);
00303 
00304     // Set it as both big and small icon of the window
00305     if (myIcon)
00306     {
00307         SendMessage(myHandle, WM_SETICON, ICON_BIG,   (LPARAM)myIcon);
00308         SendMessage(myHandle, WM_SETICON, ICON_SMALL, (LPARAM)myIcon);
00309     }
00310     else
00311     {
00312         Err() << "Failed to set the window's icon" << std::endl;
00313     }
00314 }
00315 
00316 
00318 void WindowImplWin32::RegisterWindowClass()
00319 {
00320     if (HasUnicodeSupport())
00321     {
00322         WNDCLASSW WindowClass;
00323         WindowClass.style         = 0;
00324         WindowClass.lpfnWndProc   = &WindowImplWin32::GlobalOnEvent;
00325         WindowClass.cbClsExtra    = 0;
00326         WindowClass.cbWndExtra    = 0;
00327         WindowClass.hInstance     = GetModuleHandle(NULL);
00328         WindowClass.hIcon         = NULL;
00329         WindowClass.hCursor       = 0;
00330         WindowClass.hbrBackground = 0;
00331         WindowClass.lpszMenuName  = NULL;
00332         WindowClass.lpszClassName = ClassNameW;
00333         RegisterClassW(&WindowClass);
00334     }
00335     else
00336     {
00337         WNDCLASSA WindowClass;
00338         WindowClass.style         = 0;
00339         WindowClass.lpfnWndProc   = &WindowImplWin32::GlobalOnEvent;
00340         WindowClass.cbClsExtra    = 0;
00341         WindowClass.cbWndExtra    = 0;
00342         WindowClass.hInstance     = GetModuleHandle(NULL);
00343         WindowClass.hIcon         = NULL;
00344         WindowClass.hCursor       = 0;
00345         WindowClass.hbrBackground = 0;
00346         WindowClass.lpszMenuName  = NULL;
00347         WindowClass.lpszClassName = ClassNameA;
00348         RegisterClassA(&WindowClass);
00349     }
00350 }
00351 
00352 
00354 void WindowImplWin32::SwitchToFullscreen(const VideoMode& mode)
00355 {
00356     DEVMODE devMode;
00357     devMode.dmSize       = sizeof(devMode);
00358     devMode.dmPelsWidth  = mode.Width;
00359     devMode.dmPelsHeight = mode.Height;
00360     devMode.dmBitsPerPel = mode.BitsPerPixel;
00361     devMode.dmFields     = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
00362 
00363     // Apply fullscreen mode
00364     if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
00365     {
00366         Err() << "Failed to change display mode for fullscreen" << std::endl;
00367         return;
00368     }
00369 
00370     // Make the window flags compatible with fullscreen mode
00371     SetWindowLong(myHandle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
00372     SetWindowLong(myHandle, GWL_EXSTYLE, WS_EX_APPWINDOW);
00373 
00374     // Resize the window so that it fits the entire screen
00375     SetWindowPos(myHandle, HWND_TOP, 0, 0, mode.Width, mode.Height, SWP_FRAMECHANGED);
00376     ShowWindow(myHandle, SW_SHOW);
00377 
00378     // Set "this" as the current fullscreen window
00379     FullscreenWindow = this;
00380 }
00381 
00382 
00384 void WindowImplWin32::Cleanup()
00385 {
00386     // Restore the previous video mode (in case we were running in fullscreen)
00387     if (FullscreenWindow == this)
00388     {
00389         ChangeDisplaySettings(NULL, 0);
00390         FullscreenWindow = NULL;
00391     }
00392 
00393     // Unhide the mouse cursor (in case it was hidden)
00394     ShowMouseCursor(true);
00395 }
00396 
00397 
00399 void WindowImplWin32::ProcessEvent(UINT message, WPARAM wParam, LPARAM lParam)
00400 {
00401     // Don't process any message until window is created
00402     if (myHandle == NULL)
00403         return;
00404 
00405     switch (message)
00406     {
00407         // Destroy event
00408         case WM_DESTROY :
00409         {
00410             // Here we must cleanup resources !
00411             Cleanup();
00412             break;
00413         }
00414 
00415         // Set cursor event
00416         case WM_SETCURSOR :
00417         {
00418             // The mouse has moved, if the cursor is in our window we must refresh the cursor
00419             if (LOWORD(lParam) == HTCLIENT)
00420                 SetCursor(myCursor);
00421 
00422             break;
00423         }
00424 
00425         // Close event
00426         case WM_CLOSE :
00427         {
00428             Event event;
00429             event.Type = Event::Closed;
00430             PushEvent(event);
00431             break;
00432         }
00433 
00434         // Resize event
00435         case WM_SIZE :
00436         {
00437             // Update window size
00438             RECT rectangle;
00439             GetClientRect(myHandle, &rectangle);
00440             myWidth  = rectangle.right - rectangle.left;
00441             myHeight = rectangle.bottom - rectangle.top;
00442 
00443             Event event;
00444             event.Type        = Event::Resized;
00445             event.Size.Width  = myWidth;
00446             event.Size.Height = myHeight;
00447             PushEvent(event);
00448             break;
00449         }
00450 
00451         // Gain focus event
00452         case WM_SETFOCUS :
00453         {
00454             Event event;
00455             event.Type = Event::GainedFocus;
00456             PushEvent(event);
00457             break;
00458         }
00459 
00460         // Lost focus event
00461         case WM_KILLFOCUS :
00462         {
00463             Event event;
00464             event.Type = Event::LostFocus;
00465             PushEvent(event);
00466             break;
00467         }
00468 
00469         // Text event
00470         case WM_CHAR :
00471         {
00472             if (myKeyRepeatEnabled || ((lParam & (1 << 30)) == 0))
00473             {
00474                 Event event;
00475                 event.Type = Event::TextEntered;
00476                 event.Text.Unicode = static_cast<Uint32>(wParam);
00477                 PushEvent(event);
00478             }
00479             break;
00480         }
00481 
00482         // Keydown event
00483         case WM_KEYDOWN :
00484         case WM_SYSKEYDOWN :
00485         {
00486             if (myKeyRepeatEnabled || ((HIWORD(lParam) & KF_REPEAT) == 0))
00487             {
00488                 Event event;
00489                 event.Type        = Event::KeyPressed;
00490                 event.Key.Alt     = HIWORD(GetAsyncKeyState(VK_MENU))    != 0;
00491                 event.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
00492                 event.Key.Shift   = HIWORD(GetAsyncKeyState(VK_SHIFT))   != 0;
00493                 event.Key.Code    = VirtualKeyCodeToSF(wParam, lParam);
00494                 PushEvent(event);
00495             }
00496             break;
00497         }
00498 
00499         // Keyup event
00500         case WM_KEYUP :
00501         case WM_SYSKEYUP :
00502         {
00503             Event event;
00504             event.Type        = Event::KeyReleased;
00505             event.Key.Alt     = HIWORD(GetAsyncKeyState(VK_MENU))    != 0;
00506             event.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
00507             event.Key.Shift   = HIWORD(GetAsyncKeyState(VK_SHIFT))   != 0;
00508             event.Key.Code    = VirtualKeyCodeToSF(wParam, lParam);
00509             PushEvent(event);
00510             break;
00511         }
00512 
00513         // Mouse wheel event
00514         case WM_MOUSEWHEEL :
00515         {
00516             // Mouse position is in screen coordinates, convert it to window coordinates
00517             POINT position;
00518             position.x = LOWORD(lParam);
00519             position.y = HIWORD(lParam);
00520             ScreenToClient(myHandle, &position);
00521 
00522             Event event;
00523             event.Type = Event::MouseWheelMoved;
00524             event.MouseWheel.Delta = static_cast<Int16>(HIWORD(wParam)) / 120;
00525             event.MouseButton.X    = position.x;
00526             event.MouseButton.Y    = position.y;
00527             PushEvent(event);
00528             break;
00529         }
00530 
00531         // Mouse left button down event
00532         case WM_LBUTTONDOWN :
00533         {
00534             Event event;
00535             event.Type               = Event::MouseButtonPressed;
00536             event.MouseButton.Button = Mouse::Left;
00537             event.MouseButton.X      = LOWORD(lParam);
00538             event.MouseButton.Y      = HIWORD(lParam);
00539             PushEvent(event);
00540             break;
00541         }
00542 
00543         // Mouse left button up event
00544         case WM_LBUTTONUP :
00545         {
00546             Event event;
00547             event.Type               = Event::MouseButtonReleased;
00548             event.MouseButton.Button = Mouse::Left;
00549             event.MouseButton.X      = LOWORD(lParam);
00550             event.MouseButton.Y      = HIWORD(lParam);
00551             PushEvent(event);
00552             break;
00553         }
00554 
00555         // Mouse right button down event
00556         case WM_RBUTTONDOWN :
00557         {
00558             Event event;
00559             event.Type               = Event::MouseButtonPressed;
00560             event.MouseButton.Button = Mouse::Right;
00561             event.MouseButton.X      = LOWORD(lParam);
00562             event.MouseButton.Y      = HIWORD(lParam);
00563             PushEvent(event);
00564             break;
00565         }
00566 
00567         // Mouse right button up event
00568         case WM_RBUTTONUP :
00569         {
00570             Event event;
00571             event.Type               = Event::MouseButtonReleased;
00572             event.MouseButton.Button = Mouse::Right;
00573             event.MouseButton.X      = LOWORD(lParam);
00574             event.MouseButton.Y      = HIWORD(lParam);
00575             PushEvent(event);
00576             break;
00577         }
00578 
00579         // Mouse wheel button down event
00580         case WM_MBUTTONDOWN :
00581         {
00582             Event event;
00583             event.Type               = Event::MouseButtonPressed;
00584             event.MouseButton.Button = Mouse::Middle;
00585             event.MouseButton.X      = LOWORD(lParam);
00586             event.MouseButton.Y      = HIWORD(lParam);
00587             PushEvent(event);
00588             break;
00589         }
00590 
00591         // Mouse wheel button up event
00592         case WM_MBUTTONUP :
00593         {
00594             Event event;
00595             event.Type               = Event::MouseButtonReleased;
00596             event.MouseButton.Button = Mouse::Middle;
00597             event.MouseButton.X      = LOWORD(lParam);
00598             event.MouseButton.Y      = HIWORD(lParam);
00599             PushEvent(event);
00600             break;
00601         }
00602 
00603         // Mouse X button down event
00604         case WM_XBUTTONDOWN :
00605         {
00606             Event event;
00607             event.Type               = Event::MouseButtonPressed;
00608             event.MouseButton.Button = HIWORD(wParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
00609             event.MouseButton.X      = LOWORD(lParam);
00610             event.MouseButton.Y      = HIWORD(lParam);
00611             PushEvent(event);
00612             break;
00613         }
00614 
00615         // Mouse X button up event
00616         case WM_XBUTTONUP :
00617         {
00618             Event event;
00619             event.Type               = Event::MouseButtonReleased;
00620             event.MouseButton.Button = HIWORD(wParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
00621             event.MouseButton.X      = LOWORD(lParam);
00622             event.MouseButton.Y      = HIWORD(lParam);
00623             PushEvent(event);
00624             break;
00625         }
00626 
00627         // Mouse move event
00628         case WM_MOUSEMOVE :
00629         {
00630             // Check if we need to generate a MouseEntered event
00631             if (!myIsCursorIn)
00632             {
00633                 TRACKMOUSEEVENT mouseEvent;
00634                 mouseEvent.cbSize    = sizeof(TRACKMOUSEEVENT);
00635                 mouseEvent.hwndTrack = myHandle;
00636                 mouseEvent.dwFlags   = TME_LEAVE;
00637                 TrackMouseEvent(&mouseEvent);
00638 
00639                 myIsCursorIn = true;
00640 
00641                 Event event;
00642                 event.Type = Event::MouseEntered;
00643                 PushEvent(event);
00644             }
00645 
00646             Event event;
00647             event.Type        = Event::MouseMoved;
00648             event.MouseMove.X = LOWORD(lParam);
00649             event.MouseMove.Y = HIWORD(lParam);
00650             PushEvent(event);
00651             break;
00652         }
00653 
00654         // Mouse leave event
00655         case WM_MOUSELEAVE :
00656         {
00657             myIsCursorIn = false;
00658 
00659             Event event;
00660             event.Type = Event::MouseLeft;
00661             PushEvent(event);
00662             break;
00663         }
00664     }
00665 }
00666 
00667 
00669 Key::Code WindowImplWin32::VirtualKeyCodeToSF(WPARAM key, LPARAM flags)
00670 {
00671     switch (key)
00672     {
00673         // Check the scancode to distinguish between left and right shift
00674         case VK_SHIFT :
00675         {
00676             static UINT lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
00677             UINT scancode = static_cast<UINT>((flags & (0xFF << 16)) >> 16);
00678             return scancode == lShift ? Key::LShift : Key::RShift;
00679         }
00680 
00681         // Check the "extended" flag to distinguish between left and right alt
00682         case VK_MENU : return (HIWORD(flags) & KF_EXTENDED) ? Key::RAlt : Key::LAlt;
00683 
00684         // Check the "extended" flag to distinguish between left and right control
00685         case VK_CONTROL : return (HIWORD(flags) & KF_EXTENDED) ? Key::RControl : Key::LControl;
00686 
00687         // Other keys are reported properly
00688         case VK_LWIN :       return Key::LSystem;
00689         case VK_RWIN :       return Key::RSystem;
00690         case VK_APPS :       return Key::Menu;
00691         case VK_OEM_1 :      return Key::SemiColon;
00692         case VK_OEM_2 :      return Key::Slash;
00693         case VK_OEM_PLUS :   return Key::Equal;
00694         case VK_OEM_MINUS :  return Key::Dash;
00695         case VK_OEM_4 :      return Key::LBracket;
00696         case VK_OEM_6 :      return Key::RBracket;
00697         case VK_OEM_COMMA :  return Key::Comma;
00698         case VK_OEM_PERIOD : return Key::Period;
00699         case VK_OEM_7 :      return Key::Quote;
00700         case VK_OEM_5 :      return Key::BackSlash;
00701         case VK_OEM_3 :      return Key::Tilde;
00702         case VK_ESCAPE :     return Key::Escape;
00703         case VK_SPACE :      return Key::Space;
00704         case VK_RETURN :     return Key::Return;
00705         case VK_BACK :       return Key::Back;
00706         case VK_TAB :        return Key::Tab;
00707         case VK_PRIOR :      return Key::PageUp;
00708         case VK_NEXT :       return Key::PageDown;
00709         case VK_END :        return Key::End;
00710         case VK_HOME :       return Key::Home;
00711         case VK_INSERT :     return Key::Insert;
00712         case VK_DELETE :     return Key::Delete;
00713         case VK_ADD :        return Key::Add;
00714         case VK_SUBTRACT :   return Key::Subtract;
00715         case VK_MULTIPLY :   return Key::Multiply;
00716         case VK_DIVIDE :     return Key::Divide;
00717         case VK_PAUSE :      return Key::Pause;
00718         case VK_F1 :         return Key::F1;
00719         case VK_F2 :         return Key::F2;
00720         case VK_F3 :         return Key::F3;
00721         case VK_F4 :         return Key::F4;
00722         case VK_F5 :         return Key::F5;
00723         case VK_F6 :         return Key::F6;
00724         case VK_F7 :         return Key::F7;
00725         case VK_F8 :         return Key::F8;
00726         case VK_F9 :         return Key::F9;
00727         case VK_F10 :        return Key::F10;
00728         case VK_F11 :        return Key::F11;
00729         case VK_F12 :        return Key::F12;
00730         case VK_F13 :        return Key::F13;
00731         case VK_F14 :        return Key::F14;
00732         case VK_F15 :        return Key::F15;
00733         case VK_LEFT :       return Key::Left;
00734         case VK_RIGHT :      return Key::Right;
00735         case VK_UP :         return Key::Up;
00736         case VK_DOWN :       return Key::Down;
00737         case VK_NUMPAD0 :    return Key::Numpad0;
00738         case VK_NUMPAD1 :    return Key::Numpad1;
00739         case VK_NUMPAD2 :    return Key::Numpad2;
00740         case VK_NUMPAD3 :    return Key::Numpad3;
00741         case VK_NUMPAD4 :    return Key::Numpad4;
00742         case VK_NUMPAD5 :    return Key::Numpad5;
00743         case VK_NUMPAD6 :    return Key::Numpad6;
00744         case VK_NUMPAD7 :    return Key::Numpad7;
00745         case VK_NUMPAD8 :    return Key::Numpad8;
00746         case VK_NUMPAD9 :    return Key::Numpad9;
00747         case 'A' :           return Key::A;
00748         case 'Z' :           return Key::Z;
00749         case 'E' :           return Key::E;
00750         case 'R' :           return Key::R;
00751         case 'T' :           return Key::T;
00752         case 'Y' :           return Key::Y;
00753         case 'U' :           return Key::U;
00754         case 'I' :           return Key::I;
00755         case 'O' :           return Key::O;
00756         case 'P' :           return Key::P;
00757         case 'Q' :           return Key::Q;
00758         case 'S' :           return Key::S;
00759         case 'D' :           return Key::D;
00760         case 'F' :           return Key::F;
00761         case 'G' :           return Key::G;
00762         case 'H' :           return Key::H;
00763         case 'J' :           return Key::J;
00764         case 'K' :           return Key::K;
00765         case 'L' :           return Key::L;
00766         case 'M' :           return Key::M;
00767         case 'W' :           return Key::W;
00768         case 'X' :           return Key::X;
00769         case 'C' :           return Key::C;
00770         case 'V' :           return Key::V;
00771         case 'B' :           return Key::B;
00772         case 'N' :           return Key::N;
00773         case '0' :           return Key::Num0;
00774         case '1' :           return Key::Num1;
00775         case '2' :           return Key::Num2;
00776         case '3' :           return Key::Num3;
00777         case '4' :           return Key::Num4;
00778         case '5' :           return Key::Num5;
00779         case '6' :           return Key::Num6;
00780         case '7' :           return Key::Num7;
00781         case '8' :           return Key::Num8;
00782         case '9' :           return Key::Num9;
00783     }
00784 
00785     return Key::Code(0);
00786 }
00787 
00788 
00790 bool WindowImplWin32::HasUnicodeSupport()
00791 {
00792     OSVERSIONINFO version;
00793     ZeroMemory(&version, sizeof(version));
00794     version.dwOSVersionInfoSize = sizeof(version);
00795 
00796     if (GetVersionEx(&version))
00797     {
00798         return version.dwPlatformId == VER_PLATFORM_WIN32_NT;
00799     }
00800     else
00801     {
00802         return false;
00803     }
00804 }
00805 
00806 
00808 LRESULT CALLBACK WindowImplWin32::GlobalOnEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
00809 {
00810     // Associate handle and Window instance when the creation message is received
00811     if (message == WM_CREATE)
00812     {
00813         // Get WindowImplWin32 instance (it was passed as the last argument of CreateWindow)
00814         long window = reinterpret_cast<long>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);
00815 
00816         // Set as the "user data" parameter of the window
00817         SetWindowLongPtr(handle, GWLP_USERDATA, window);
00818     }
00819 
00820     // Get the WindowImpl instance corresponding to the window handle
00821     WindowImplWin32* window = reinterpret_cast<WindowImplWin32*>(GetWindowLongPtr(handle, GWLP_USERDATA));
00822 
00823     // Forward the event to the appropriate function
00824     if (window)
00825     {
00826         window->ProcessEvent(message, wParam, lParam);
00827 
00828         if (window->myCallback)
00829             return CallWindowProc(reinterpret_cast<WNDPROC>(window->myCallback), handle, message, wParam, lParam);
00830     }
00831 
00832     // We don't forward the WM_CLOSE message to prevent the OS from automatically destroying the window
00833     if (message == WM_CLOSE)
00834         return 0;
00835 
00836     static const bool hasUnicode = HasUnicodeSupport();
00837     return hasUnicode ? DefWindowProcW(handle, message, wParam, lParam) :
00838                         DefWindowProcA(handle, message, wParam, lParam);
00839 }
00840 
00841 } // namespace priv
00842 
00843 } // namespace sf

 ::  Copyright © 2007-2008 Laurent Gomila, all rights reserved  ::  Documentation generated by doxygen 1.5.2  ::