/** Adds a Window to the Event Manager */ void EventMgr::AddWindow(Window* win) { unsigned int i; if (win == NULL) { return; } bool found = false; for (i = 0; i < windows.size(); i++) { if (windows[i] == win) { goto ok; } if(windows[i]==NULL) { windows[i] = win; ok: SetOnTop( i ); found = true; break; } } if (!found) { windows.push_back( win ); if (windows.size() == 1) topwin.push_back( 0 ); else SetOnTop( ( int ) windows.size() - 1 ); } SetDefaultFocus(win); }
LRESULT CContainerWnd::WndProc(unsigned int msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_INVALIDATEPARENT: OnInvalidateParent(wParam); break; case WM_SETFOCUS: if(m_pFocusComp) { m_pFocusComp->ChangeFocus(false, NULL); m_pFocusComp = NULL; } SetDefaultFocus(); break; case WM_KILLFOCUS: if(m_pFocusComp) { m_pFocusComp->ChangeFocus(false, NULL); m_pFocusComp = NULL; } break; case WM_REQUESTFOCUS: { if(GetFocus() != m_hwnd)SetFocus(m_hwnd); CComponent *pComp = reinterpret_cast<CComponent *>(lParam); if(m_pFocusComp)m_pFocusComp->ChangeFocus(false, pComp); pComp->ChangeFocus(true, m_pFocusComp); m_pFocusComp = pComp; } break; case WM_RELEASEFOCUS: if(m_pFocusComp) { CComponent *pComp = reinterpret_cast<CComponent *>(lParam); m_pFocusComp->ChangeFocus(false, pComp); m_pFocusComp = NULL; } break; case WM_KEYDOWN: case WM_KEYUP: case WM_CHAR: case WM_DEADCHAR: case WM_SYSKEYDOWN: case WM_SYSDEADCHAR: case WM_SYSKEYUP: if(m_pFocusComp)return m_pFocusComp->ComponentProc(msg, wParam, lParam); return ContainerProc(msg, wParam, lParam); case WM_SETCURSOR: { bool b = false; POINT pt; if(GetCursorPos(&pt)) { for(int i = m_components.size() - 1; i >= 0; i--) { if(m_components[i]->containsScreenPt(pt)) { b = m_components[i]->OnSetCursor(pt); break; } } } if(!b)return ContainerProc(msg, wParam, lParam); } break; case WM_CAPTURECHANGED: m_pCapturingComp = NULL; break; case WM_CAPTUREMOUSE: if(wParam) { //if(pCapturingComp) --do something to notify component SetCapture(m_hwnd); m_pCapturingComp = reinterpret_cast<CComponent *>(lParam); return TRUE; } else { ReleaseCapture(); } break; case WM_MOUSELEAVE: if(m_pTargetComp) { m_pTargetComp->MouseExited(); m_pTargetComp = NULL; m_bTracking = false; } break; case WM_MOUSEMOVE: if(m_pCapturingComp)return m_pCapturingComp->ComponentProc(msg, wParam, lParam); else { if(!m_bTracking) { TRACKMOUSEEVENT tme; ZeroMemory(&tme, sizeof(TRACKMOUSEEVENT)); tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.hwndTrack = m_hwnd; tme.dwFlags = TME_LEAVE; m_bTracking = TrackMouseEvent(&tme)?true:false; } POINT p = { static_cast<short>(LOWORD(lParam)), static_cast<short>(HIWORD(lParam)) }; // if(m_pTargetComp && m_pTargetComp->contains(p)) // return m_pTargetComp->ComponentProc(msg, wParam, lParam); // else // { for(int i = m_components.size() - 1; i >= 0; i--) { if(m_components[i]->contains(p)) { if(m_pTargetComp != m_components[i]) { if(m_pTargetComp) { m_pTargetComp->MouseExited(); m_pTargetComp = NULL; } m_pTargetComp = m_components[i]; m_pTargetComp->MouseEntered(); } return m_pTargetComp->ComponentProc(msg, wParam, lParam); } } if(m_pTargetComp) { m_pTargetComp->MouseExited(); m_pTargetComp = NULL; } // } } return ContainerProc(msg, wParam, lParam); case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: SetFocus(m_hwnd); case WM_LBUTTONDBLCLK: case WM_LBUTTONUP: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP: // case WM_XBUTTONDBLCLK: // case WM_XBUTTONDOWN: // case WM_XBUTTONUP: { POINT p = { static_cast<short>(LOWORD(lParam)), static_cast<short>(HIWORD(lParam)) }; if(m_pCapturingComp)return m_pCapturingComp->ComponentProc(msg, wParam, lParam); else if(m_pTargetComp && m_pTargetComp->contains(p)) return m_pTargetComp->ComponentProc(msg, wParam, lParam); else { for(int i = m_components.size() - 1; i >= 0; i--) { if(m_components[i]->contains(p)) return m_components[i]->ComponentProc(msg, wParam, lParam); } } } default: return ContainerProc(msg, wParam, lParam); } return 0; }
int WndForm::ShowModal() { #ifndef USE_WINUSER ContainerWindow *root = GetRootOwner(); WindowReference old_focus_reference = root->GetFocusedWindowReference(); #else HWND oldFocusHwnd; #endif /* USE_WINUSER */ PeriodClock enter_clock; if (IsEmbedded()) enter_clock.Update(); ShowOnTop(); modal_result = 0; SingleWindow &main_window = GetMainWindow(); main_window.CancelMode(); #ifdef USE_WINUSER oldFocusHwnd = ::GetFocus(); #endif /* USE_WINUSER */ SetDefaultFocus(); bool hastimed = false; main_window.AddDialog(this); #ifndef USE_GDI main_window.Refresh(); #endif #if defined(ANDROID) || defined(USE_POLL_EVENT) || defined(ENABLE_SDL) EventLoop loop(*event_queue, main_window); #else DialogEventLoop loop(*event_queue, *this); #endif Event event; while ((modal_result == 0 || force) && loop.Get(event)) { if (!main_window.FilterEvent(event, this)) { if (modeless && event.IsMouseDown()) break; else continue; } // hack to stop exiting immediately if (IsEmbedded() && !hastimed && event.IsUserInput()) { if (!enter_clock.Check(200)) /* ignore user input in the first 200ms */ continue; else hastimed = true; } if (event.IsKeyDown()) { if (OnAnyKeyDown(event.GetKeyCode())) continue; #ifdef ENABLE_SDL if (event.GetKeyCode() == SDLK_TAB) { /* the Tab key moves the keyboard focus */ #if SDL_MAJOR_VERSION >= 2 const Uint8 *keystate = ::SDL_GetKeyboardState(nullptr); event.event.key.keysym.sym = keystate[SDL_SCANCODE_LSHIFT] || keystate[SDL_SCANCODE_RSHIFT] ? SDLK_UP : SDLK_DOWN; #else const Uint8 *keystate = ::SDL_GetKeyState(nullptr); event.event.key.keysym.sym = keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT] ? SDLK_UP : SDLK_DOWN; #endif } #endif if ( #ifdef USE_WINUSER IdentifyDescendant(event.msg.hwnd) && #endif (event.GetKeyCode() == KEY_UP || event.GetKeyCode() == KEY_DOWN)) { /* KEY_UP and KEY_DOWN move the focus only within the current control group - but we want it to behave like Shift-Tab and Tab */ if (!CheckKey(this, event)) { /* this window doesn't handle KEY_UP/KEY_DOWN */ if (event.GetKeyCode() == KEY_DOWN) FocusNextControl(); else FocusPreviousControl(); continue; } } #ifndef USE_WINUSER if (event.GetKeyCode() == KEY_ESCAPE) { modal_result = mrCancel; continue; } #endif #ifdef USE_LINUX_INPUT if (event.GetKeyCode() == KEY_POWER) { /* the Kobo power button closes the modal dialog */ modal_result = mrCancel; continue; } #endif } if (character_function && (event.GetCharacterCount() > 0)) { bool handled = false; for (size_t i = 0; i < event.GetCharacterCount(); ++i) handled = character_function(event.GetCharacter(i)) || handled; if (handled) continue; } loop.Dispatch(event); } // End Modal Loop main_window.RemoveDialog(this); #ifdef USE_WINUSER ::SetFocus(oldFocusHwnd); #else if (old_focus_reference.Defined()) { Window *old_focus = old_focus_reference.Get(*root); if (old_focus != nullptr) old_focus->SetFocus(); } #endif /* !USE_WINUSER */ return modal_result; }