|
|
|
@ -33,95 +33,7 @@ |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <malloc.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Enable/disable minimize/restore animations
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
static int setMinMaxAnimations(int enable) |
|
|
|
|
{ |
|
|
|
|
ANIMATIONINFO AI; |
|
|
|
|
int old_enable; |
|
|
|
|
|
|
|
|
|
// Get old animation setting
|
|
|
|
|
AI.cbSize = sizeof(ANIMATIONINFO); |
|
|
|
|
SystemParametersInfo(SPI_GETANIMATION, AI.cbSize, &AI, 0); |
|
|
|
|
old_enable = AI.iMinAnimate; |
|
|
|
|
|
|
|
|
|
// If requested, change setting
|
|
|
|
|
if (old_enable != enable) |
|
|
|
|
{ |
|
|
|
|
AI.iMinAnimate = enable; |
|
|
|
|
SystemParametersInfo(SPI_SETANIMATION, AI.cbSize, &AI, |
|
|
|
|
SPIF_SENDCHANGE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return old_enable; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Focus the window and bring it to the top of the stack
|
|
|
|
|
// Due to some nastiness with how XP handles SetForegroundWindow we have
|
|
|
|
|
// to go through some really bizarre measures to achieve this
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
static void setForegroundWindow(HWND hWnd) |
|
|
|
|
{ |
|
|
|
|
int try_count = 0; |
|
|
|
|
int old_animate; |
|
|
|
|
|
|
|
|
|
// Try the standard approach first...
|
|
|
|
|
BringWindowToTop(hWnd); |
|
|
|
|
SetForegroundWindow(hWnd); |
|
|
|
|
|
|
|
|
|
// If it worked, return now
|
|
|
|
|
if (hWnd == GetForegroundWindow()) |
|
|
|
|
{ |
|
|
|
|
// Try to modify the system settings (since this is the foreground
|
|
|
|
|
// process, we are allowed to do this)
|
|
|
|
|
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID) 0, |
|
|
|
|
SPIF_SENDCHANGE); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// For other Windows versions than 95 & NT4.0, the standard approach
|
|
|
|
|
// may not work, so if we failed we have to "trick" Windows into
|
|
|
|
|
// making our window the foureground window: Iconify and restore
|
|
|
|
|
// again. It is ugly, but it seems to work (we turn off those annoying
|
|
|
|
|
// zoom animations to make it look a bit better at least).
|
|
|
|
|
|
|
|
|
|
// Turn off minimize/restore animations
|
|
|
|
|
old_animate = setMinMaxAnimations(0); |
|
|
|
|
|
|
|
|
|
// We try this a few times, just to be on the safe side of things...
|
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
// Iconify & restore
|
|
|
|
|
ShowWindow(hWnd, SW_HIDE); |
|
|
|
|
ShowWindow(hWnd, SW_SHOWMINIMIZED); |
|
|
|
|
ShowWindow(hWnd, SW_SHOWNORMAL); |
|
|
|
|
|
|
|
|
|
// Try to get focus
|
|
|
|
|
BringWindowToTop(hWnd); |
|
|
|
|
SetForegroundWindow(hWnd); |
|
|
|
|
|
|
|
|
|
// We do not want to keep going on forever, so we keep track of
|
|
|
|
|
// how many times we tried
|
|
|
|
|
try_count++; |
|
|
|
|
} |
|
|
|
|
while (hWnd != GetForegroundWindow() && try_count <= 3); |
|
|
|
|
|
|
|
|
|
// Restore the system minimize/restore animation setting
|
|
|
|
|
setMinMaxAnimations(old_animate); |
|
|
|
|
|
|
|
|
|
// Try to modify the system settings (since this is now hopefully the
|
|
|
|
|
// foreground process, we are probably allowed to do this)
|
|
|
|
|
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID) 0, |
|
|
|
|
SPIF_SENDCHANGE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#include <windowsx.h> |
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Hide mouse cursor
|
|
|
|
@ -393,37 +305,6 @@ static int translateKey(WPARAM wParam, LPARAM lParam) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Translates a Windows key to Unicode
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
static void translateChar(_GLFWwindow* window, DWORD wParam, DWORD lParam) |
|
|
|
|
{ |
|
|
|
|
BYTE keyboard_state[256]; |
|
|
|
|
WCHAR unicode_buf[10]; |
|
|
|
|
UINT scan_code; |
|
|
|
|
int i, num_chars; |
|
|
|
|
|
|
|
|
|
GetKeyboardState(keyboard_state); |
|
|
|
|
|
|
|
|
|
// Derive scan code from lParam and action
|
|
|
|
|
scan_code = (lParam & 0x01ff0000) >> 16; |
|
|
|
|
|
|
|
|
|
num_chars = ToUnicode( |
|
|
|
|
wParam, // virtual-key code
|
|
|
|
|
scan_code, // scan code
|
|
|
|
|
keyboard_state, // key-state array
|
|
|
|
|
unicode_buf, // buffer for translated key
|
|
|
|
|
10, // size of translated key buffer
|
|
|
|
|
0 // active-menu flag
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// Report characters
|
|
|
|
|
for (i = 0; i < num_chars; i++) |
|
|
|
|
_glfwInputChar(window, (int) unicode_buf[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Window callback function (handles window events)
|
|
|
|
|
//========================================================================
|
|
|
|
@ -507,6 +388,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case WM_SHOWWINDOW: |
|
|
|
|
{ |
|
|
|
|
_glfwInputWindowVisibility(window, wParam ? GL_TRUE : GL_FALSE); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case WM_SYSCOMMAND: |
|
|
|
|
{ |
|
|
|
|
switch (wParam & 0xfff0) |
|
|
|
@ -541,13 +428,15 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, |
|
|
|
|
case WM_SYSKEYDOWN: |
|
|
|
|
{ |
|
|
|
|
_glfwInputKey(window, translateKey(wParam, lParam), GLFW_PRESS); |
|
|
|
|
|
|
|
|
|
if (_glfwLibrary.charCallback) |
|
|
|
|
translateChar(window, (DWORD) wParam, (DWORD) lParam); |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case WM_CHAR: |
|
|
|
|
{ |
|
|
|
|
_glfwInputChar(window, wParam); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case WM_KEYUP: |
|
|
|
|
case WM_SYSKEYUP: |
|
|
|
|
{ |
|
|
|
@ -642,8 +531,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, |
|
|
|
|
int newCursorX, newCursorY; |
|
|
|
|
|
|
|
|
|
// Get signed (!) cursor position
|
|
|
|
|
newCursorX = (int)((short)LOWORD(lParam)); |
|
|
|
|
newCursorY = (int)((short)HIWORD(lParam)); |
|
|
|
|
newCursorX = GET_X_LPARAM(lParam); |
|
|
|
|
newCursorY = GET_Y_LPARAM(lParam); |
|
|
|
|
|
|
|
|
|
if (newCursorX != window->Win32.oldCursorX || |
|
|
|
|
newCursorY != window->Win32.oldCursorY) |
|
|
|
@ -836,7 +725,7 @@ static int createWindow(_GLFWwindow* window, |
|
|
|
|
WCHAR* wideTitle; |
|
|
|
|
|
|
|
|
|
// Set common window styles
|
|
|
|
|
dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; |
|
|
|
|
dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; |
|
|
|
|
dwExStyle = WS_EX_APPWINDOW; |
|
|
|
|
|
|
|
|
|
// Set window style, depending on fullscreen mode
|
|
|
|
@ -1067,13 +956,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, |
|
|
|
|
if (window->mode == GLFW_FULLSCREEN) |
|
|
|
|
{ |
|
|
|
|
// Place the window above all topmost windows
|
|
|
|
|
_glfwPlatformShowWindow(window); |
|
|
|
|
SetWindowPos(window->Win32.handle, HWND_TOPMOST, 0,0,0,0, |
|
|
|
|
SWP_NOMOVE | SWP_NOSIZE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
setForegroundWindow(window->Win32.handle); |
|
|
|
|
SetFocus(window->Win32.handle); |
|
|
|
|
|
|
|
|
|
return GL_TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1193,6 +1080,29 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Show or hide window
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
void _glfwPlatformShowWindow(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
ShowWindow(window->Win32.handle, SW_SHOWNORMAL); |
|
|
|
|
BringWindowToTop(window->Win32.handle); |
|
|
|
|
SetForegroundWindow(window->Win32.handle); |
|
|
|
|
SetFocus(window->Win32.handle); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Show or hide window
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
void _glfwPlatformHideWindow(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
ShowWindow(window->Win32.handle, SW_HIDE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Write back window parameters into GLFW window structure
|
|
|
|
|
//========================================================================
|
|
|
|
@ -1239,28 +1149,22 @@ void _glfwPlatformPollEvents(void) |
|
|
|
|
|
|
|
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) |
|
|
|
|
{ |
|
|
|
|
switch (msg.message) |
|
|
|
|
if (msg.message == WM_QUIT) |
|
|
|
|
{ |
|
|
|
|
case WM_QUIT: |
|
|
|
|
{ |
|
|
|
|
// Treat WM_QUIT as a close on all windows
|
|
|
|
|
|
|
|
|
|
window = _glfwLibrary.windowListHead; |
|
|
|
|
while (window) |
|
|
|
|
{ |
|
|
|
|
_glfwInputWindowCloseRequest(window); |
|
|
|
|
window = window->next; |
|
|
|
|
} |
|
|
|
|
// Treat WM_QUIT as a close on all windows
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
window = _glfwLibrary.windowListHead; |
|
|
|
|
while (window) |
|
|
|
|
{ |
|
|
|
|
DispatchMessage(&msg); |
|
|
|
|
break; |
|
|
|
|
_glfwInputWindowCloseRequest(window); |
|
|
|
|
window = window->next; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
TranslateMessage(&msg); |
|
|
|
|
DispatchMessage(&msg); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)
|
|
|
|
|