📄 soguigameviewer.cpp
字号:
switch (msg->message) { case WM_MOVE: { // const int c = listOfGameViewers.getLength(); int i; for (i=0; i<c; i++) { SoGuiGameViewer *gv = listOfGameViewers[i]->parent; HWND h = gv->getNormalWidget(); if (h == msg->hwnd) break; do { h = GetParent(h); } while (msg->hwnd != h && h != NULL); if (msg->hwnd == h) { gv->THIS->wndActive = gv->THIS->isInForeground();#ifdef DEBUG_FOCUS printf("Move, focus is %s\n", gv->THIS->wndActive ? "TRUE" : "FALSE");#endif gv->pimpl->updateDeltaMouseActivation(); break; } } //if (!wndActive) break; // try to find the target window among normalWidget and its parent windows#if 0 // FIXME: shall this be activated or not? PCJohn 2005-08-27 HWND h = normalWidget; while (msg->hwnd != h && h != NULL) h = GetParent(h); // process message only if it was sent to normalWidget or some of its parents if (h) { updateWindowRect(normalWidget, windowRect); updateMouseCenter(mouseCenter, windowRect); resetMousePos(); }#endif break; } // workaround for SIM's SoWin bug (atleast version 1.2.0) // (Alt-Tab switching from and back to the application will incorrectly // give focus to the parent window (renderArea->getParentWidget()).) case WM_SETFOCUS: { const int c = listOfGameViewers.getLength(); int i; for (i=0; i<c; i++) { SoGuiGameViewer *gv = listOfGameViewers[i]->parent; HWND h = gv->getNormalWidget(); if (h == msg->hwnd) break; do { h = GetParent(h); } while (msg->hwnd != h && h != NULL); if (msg->hwnd == h) { PostMessage(gv->getNormalWidget(), focusMessageId, 0, 0); break; } } break; }#if 1 case WM_ACTIVATEAPP: { SoGuiGameViewer *gv = getViewerByHandle((HWND)wParam, TRUE);#ifdef DEBUG_FOCUS printf("ActivatingApp, focus by wParam is %i, real focus: %s.\n", wParam, gv ? !gv->THIS->isInForeground() ? "FALSE" : "TRUE" : "NULL");#endif break; } case WM_ACTIVATE: { SoGuiGameViewer *gv = getViewerByHandle(msg->hwnd, TRUE);#ifdef DEBUG_FOCUS printf("Activating, focus by wParam is %i, real focus %s.\n", LOWORD(wParam), gv ? !gv->THIS->isInForeground() ? "FALSE" : "TRUE" : "NULL");#endif#if 0 // this looks like not useful, but when SoWin implementation changes, it may change. if (gv) { gv->THIS->wndActive = FALSE; HWND h = gv->getNormalWidget(); while (msg->hwnd != h && h != NULL) { if (fg == h) { gv->THIS->wndActive = TRUE; break; } h = GetParent(h); } gv->THIS->updateDeltaMouseActivation(); printf("focus is %s\n", gv->THIS->wndActive ? "TRUE" : "FALSE"); }#endif break; }#endif#if 0 // this looks like not useful, but when SoWin implementation changes, it may change. case WM_SHOWWINDOW: SoGuiGameViewer *gv = getViewerByHandle(msg->hwnd, TRUE); if (gv) printf("ShowWindow, focus is %s\n", (GetForegroundWindow() == gv->getParentWidget()) ? "TRUE" : "FALSE"); break;#endif#if 0 // this looks like not useful, but when SoWin implementation changes, it may change. case WM_SHOWWINDOW: HWND fg = GetForegroundWindow(); SoGuiGameViewer *gv = getViewerByHandle(msg->hwnd, TRUE); if (gv) { gv->THIS->wndActive = FALSE; HWND h = gv->getNormalWidget(); while (msg->hwnd != h && h != NULL) { if (fg == h) { gv->THIS->wndActive = TRUE; break; } h = GetParent(h); } gv->THIS->updateDeltaMouseActivation(); printf("focus is %s\n", gv->THIS->wndActive ? "TRUE" : "FALSE"); } break;#endif } } return CallNextHookEx(hookHandle, nCode, wParam, lParam);}extern SbBool standalone;extern SbBool server;LRESULT CALLBACK SoGuiGameViewerP::shellHook(int nCode, WPARAM wParam, LPARAM lParam){#if 0 // this looks like not useful, but when SoWin implementation changes, it may change. switch (nCode) { case HSHELL_WINDOWACTIVATED: { //printf("hshellactivate\n"); SoGuiGameViewer *gv = getViewerByHandle((HWND)wParam, TRUE); assert(gv); //if (gv != NULL && gv->getNormalWidget() != GetFocus()) //PostMessage(gv->getNormalWidget(), focusMessageId, 0, 0); //gv->THIS->wndActive = gv->THIS->isInForeground(); printf("hshellactivate, realFocus is %s\n", gv->THIS->isInForeground ? "TRUE" : "FALSE"); //gv->THIS->updateDeltaMouseActivation(); break; } case HSHELL_WINDOWCREATED: { printf("hshellcreate\n"); SoGuiGameViewer *gv = getViewerByHandle((HWND)wParam, TRUE); //if (gv != NULL && gv->getNormalWidget() != GetFocus()) //PostMessage(gv->getNormalWidget(), focusMessageId, 0, 0); } }#endif return CallNextHookEx(shellHookHandle, nCode, wParam, lParam);}void SoGuiGameViewerP::activateMouseDeltaMode(){ if (mouseDeltaModeActive) return; // perform window setup#ifdef DEBUG_FOCUS printf("ActivateMouse\n");#endif topLevelWnd = parent->getParentWidget(); SetWindowPos(topLevelWnd, HWND_TOPMOST, 0,0, 0,0, SWP_NOMOVE | SWP_NOSIZE); // perform mouse initialization mouseSavedPos = getMousePos(); updateWindowRect(parent->getNormalWidget(), windowRect); updateMouseCenter(mouseCenter, windowRect); setMousePos(mouseCenter); clipMouse(windowRect); mouseDeltaModeActive = TRUE;}void SoGuiGameViewerP::deactivateMouseDeltaMode(){ if (!mouseDeltaModeActive) return;#ifdef DEBUG_FOCUS printf("DeactivateMouse\n");#endif // perform window setup SetWindowPos(topLevelWnd, HWND_NOTOPMOST, 0,0, 0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); // mouse stuff when resuming from DELTA mode unclipMouse(); if (windowRect.intersect(getMousePos())) // debugging convenience: if mouse already leaved setMousePos(mouseSavedPos); // the window, do not restore original mouse position mouseDeltaModeActive = FALSE;}void SoGuiGameViewerP::updateDeltaMouseActivation(){ if (wndActive) { if (mouseDeltaMode != mouseDeltaModeActive ) { if (mouseDeltaMode) activateMouseDeltaMode(); else deactivateMouseDeltaMode(); } } else { if (mouseDeltaModeActive) deactivateMouseDeltaMode(); }}static SbVec2s getMousePos(){ POINT p; if (GetCursorPos(&p) == 0) { SoDebugError::post("SgMouse.cpp: getMousePos", "GetCursorPos() failed. Invenstigate!"); assert(0); return SbVec2s(0,0); } return SbVec2s(short(p.x), short(p.y));}static void setMousePos(const SbVec2s &pos){ // position mouse cursor if (SetCursorPos(pos[0], pos[1]) == 0) { static SbBool first = TRUE; if (first) { first = FALSE; SoDebugError::postWarning("SgMouse.cpp:setMousePos", "SetCursorPos() failed."); } }}static void updateMouseCenter(SbVec2s &mouseCenter, const SbBox2s &windowRect){ // new window center point const SbVec2s& min = windowRect.getMin(); const SbVec2s& max = windowRect.getMax(); mouseCenter.setValue((max[0]+min[0])/2, (max[1]+min[1])/2);}static void updateWindowRect(HWND h, SbBox2s &box){ RECT r; int e = GetWindowRect(h, &r); if (e == 0) { SoDebugError::post("SgMouse.cpp: updateWindowRect", "GetWindowRect() failed. Invenstigate!"); assert(0); return; } box.setBounds((short)r.left, (short)r.top, (short)r.right, (short)r.bottom);}void SoGuiGameViewerP::clipMouse(const SbBox2s &box){ if (clipMode == SoGuiGameViewer::NO_CLIP) return;#ifndef NDEBUG if (clipMode == SoGuiGameViewer::CLIP_RELEASE_ONLY) // in DEBUG mode, clipping will not be applied return;#endif // fill RECT structure const SbVec2s& min = windowRect.getMin(); const SbVec2s& max = windowRect.getMax(); RECT r; r.left = min[0]; r.top = min[1]; r.right = max[0]; r.bottom = max[1]; // clip cursor if (ClipCursor(&r) == 0) { static SbBool first = TRUE; if (first) { first = FALSE; SoDebugError::postWarning("SgMouse.cpp:clipMouse", "ClipCursor() failed. Investigate!"); } }}void SoGuiGameViewerP::unclipMouse(){ if (clipMode == SoGuiGameViewer::NO_CLIP) return;#ifndef NDEBUG if (clipMode == SoGuiGameViewer::CLIP_RELEASE_ONLY) // in DEBUG mode, clipping will not be applied return;#endif // remove cursor clip if (ClipCursor(NULL) == 0) { static SbBool first = TRUE; if (first) { first = FALSE; SoDebugError::postWarning("SgMouse.cpp:unclipMouse", "ClipCursor() failed. Investigate!"); } }}#elsevoid SoGuiGameViewerP::activateMouseDeltaMode(){}void SoGuiGameViewerP::deactivateMouseDeltaMode(){}void SoGuiGameViewerP::updateDeltaMouseActivation(){}#endif /* !__WIN32__ && !_WIN32 */SoGuiGameViewerP::SoGuiGameViewerP(SoGuiGameViewer *parent){ this->parent = parent;#if defined(__WIN32__) || defined(_WIN32) listOfGameViewers.append(this); handle2viewerp.enter((unsigned long)parent->getNormalWidget(), this); locationEvent = new SoLocation2Event; // new window message procedure prevWndProc = (WNDPROC)SetWindowLong(parent->getNormalWidget(), GWL_WNDPROC, (LONG)wndProc); if (!prevWndProc) { SoDebugError::post("SoGuiGameViewerP::SoGuiGameViewerP", "SetWindowLong() failed. Invenstigate!"); assert(0); return; } // hook window if (listOfGameViewers.getLength() == 1) { hookHandle = SetWindowsHookEx(WH_CALLWNDPROC, &messageHook, NULL, GetCurrentThreadId()); if (hookHandle == NULL) { SoDebugError::post("SoGuiGameViewerP::SoGuiGameViewerP", "SetWindowsHookEx() failed. Invenstigate!"); assert(0); } shellHookHandle = SetWindowsHookEx(WH_SHELL, &shellHook, NULL, GetCurrentThreadId()); if (shellHookHandle == NULL) { SoDebugError::post("SoGuiGameViewerP::SoGuiGameViewerP", "SetWindowsHookEx() failed. Invenstigate!"); assert(0); } } if (focusMessageId == -1) focusMessageId = RegisterWindowMessage("SoGuiGameViewer_private_set_focus_message"); // note: // windows will unregister message automatically#endif /* __WIN32__ || _WIN32 */}SoGuiGameViewerP::~SoGuiGameViewerP(){#if defined(__WIN32__) || defined(_WIN32) // delete SoGuiGameViewerP listOfGameViewers.removeItem(this); handle2viewerp.remove((unsigned long)parent->getNormalWidget()); delete locationEvent; if (SoGuiGameViewerP::listOfGameViewers.getLength() == 0) { // free memory (for the sake of memory leak detectors) SoGuiGameViewerP::listOfGameViewers.truncate(0,1); // unhook window if (hookHandle != NULL) { if (UnhookWindowsHookEx(hookHandle) == 0) SoDebugError::post("SoGuiGameViewerP::~SoGuiGameViewerP", "UnhookWindowsHookEx() failed. Invenstigate!"); } if (shellHookHandle != NULL) { if (UnhookWindowsHookEx(shellHookHandle) == 0) SoDebugError::post("SoGuiGameViewerP::~SoGuiGameViewerP", "UnhookWindowsHookEx() failed. Invenstigate!"); } }#endif /* __WIN32__ || _WIN32 */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -