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 ::