int WndForm::ShowModal() { assert_none_locked(); #define OPENCLOSESUPPRESSTIME 500 #ifndef USE_GDI ContainerWindow *root = get_root_owner(); WindowReference old_focus_reference = root->GetFocusedWindowReference(); #else HWND oldFocusHwnd; #endif /* USE_GDI */ PeriodClock enter_clock; if (is_embedded() && !is_altair()) enter_clock.update(); show_on_top(); mModalResult = 0; #ifdef USE_GDI oldFocusHwnd = ::GetFocus(); if (oldFocusHwnd != NULL) ::SendMessage(oldFocusHwnd, WM_CANCELMODE, 0, 0); #endif /* USE_GDI */ set_focus(); focus_first_control(); bool hastimed = false; WndForm::timeAnyOpenClose.update(); // when current dlg opens or child closes main_window.add_dialog(this); #ifndef USE_GDI main_window.refresh(); #endif #ifdef ANDROID EventLoop loop(*event_queue, main_window); Event event; #elif defined(ENABLE_SDL) EventLoop loop(main_window); SDL_Event event; #else DialogEventLoop loop(*this); MSG event; #endif while ((mModalResult == 0 || force) && loop.get(event)) { #if defined(ENABLE_SDL) && !defined(ANDROID) if (event.type == SDL_QUIT) { mModalResult = mrCancel; continue; } #endif if (!main_window.FilterEvent(event, this)) continue; // hack to stop exiting immediately if (is_embedded() && !is_altair() && !hastimed && is_user_input(event)) { if (!enter_clock.check(200)) /* ignore user input in the first 200ms */ continue; else hastimed = true; } if (is_embedded() && is_mouse_up(event) && !timeAnyOpenClose.check(OPENCLOSESUPPRESSTIME)) /* prevents child click from being repeat-handled by parent if buttons overlap */ continue; if (mOnKeyDownNotify != NULL && is_key_down(event) && #ifdef USE_GDI identify_descendant(event.hwnd) && #endif !check_special_key(this, event) && mOnKeyDownNotify(*this, get_key_code(event))) continue; #if defined(ENABLE_SDL) && !defined(ANDROID) if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_TAB) { /* the Tab key moves the keyboard focus */ const Uint8 *keystate = ::SDL_GetKeyState(NULL); event.key.keysym.sym = keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT] ? SDLK_UP : SDLK_DOWN; } #endif if (is_key_down(event) && #ifdef USE_GDI identify_descendant(event.hwnd) && #endif (get_key_code(event) == VK_UP || get_key_code(event) == VK_DOWN)) { /* VK_UP and VK_DOWN move the focus only within the current control group - but we want it to behave like Shift-Tab and Tab */ if (!check_key(this, event)) { /* this window doesn't handle VK_UP/VK_DOWN */ if (get_key_code(event) == VK_DOWN) focus_next_control(); else focus_previous_control(); continue; } } #ifndef USE_GDI if (is_key_down(event) && get_key_code(event) == VK_ESCAPE) { mModalResult = mrCancel; continue; } #endif /* map VK_ESCAPE to mrOK on Altair, because the Escape key is expected to be the one that saves and closes a dialog */ if (is_altair() && is_key_down(event) && get_key_code(event) == VK_ESCAPE) { mModalResult = mrOK; continue; } loop.dispatch(event); } // End Modal Loop main_window.remove_dialog(this); // static. this is current open/close or child open/close WndForm::timeAnyOpenClose.update(); #ifdef USE_GDI SetFocus(oldFocusHwnd); #else if (old_focus_reference.Defined()) { Window *old_focus = old_focus_reference.Get(*root); if (old_focus != NULL) old_focus->set_focus(); } #endif /* !USE_GDI */ return mModalResult; }
int WndForm::ShowModal(bool bEnableMap) { assert_none_locked(); #define OPENCLOSESUPPRESSTIME 500 #ifndef ENABLE_SDL MSG msg; HWND oldFocusHwnd; #endif /* !ENABLE_SDL */ PeriodClock enter_clock; if (is_embedded() && !is_altair()) enter_clock.update(); show_on_top(); mModalResult = 0; #ifndef ENABLE_SDL oldFocusHwnd = ::GetFocus(); if (oldFocusHwnd != NULL) ::SendMessage(oldFocusHwnd, WM_CANCELMODE, 0, 0); #endif /* !ENABLE_SDL */ set_focus(); focus_first_control(); #ifndef ENABLE_SDL bool hastimed = false; #endif /* !ENABLE_SDL */ WndForm::timeAnyOpenClose.update(); // when current dlg opens or child closes main_window.add_dialog(this); #ifdef ENABLE_SDL update(); SDL_Event event; while (mModalResult == 0 && SDL_WaitEvent(&event)) { if (event.type == SDL_QUIT) break; if (event.type >= SDL_USEREVENT && event.type <= SDL_NUMEVENTS-1 && event.user.data1 != NULL) { Window *window = (Window *)event.user.data1; window->on_user(event.type - SDL_USEREVENT); } else parent->on_event(event); } #else /* !ENABLE_SDL */ while ((mModalResult == 0) && GetMessage(&msg, NULL, 0, 0)) { //hack! // JMW update display timeout so we don't get blanking /* if (msg.message == WM_KEYDOWN) { if (!Debounce()) { continue; } } */ if (msg.message == WM_KEYDOWN) { XCSoarInterface::InterfaceTimeoutReset(); } if (is_user_input(msg.message) && !identify_descendant(msg.hwnd) // not current window or child && !is_allowed_map(msg.hwnd, msg.message, bEnableMap)) continue; // make it modal // hack to stop exiting immediately if (is_embedded() && !is_altair() && !hastimed && is_user_input(msg.message)) { if (!enter_clock.check(200)) /* ignore user input in the first 200ms */ continue; else hastimed = true; } if (is_embedded() && msg.message == WM_LBUTTONUP && !timeAnyOpenClose.check(OPENCLOSESUPPRESSTIME)) /* prevents child click from being repeat-handled by parent if buttons overlap */ continue; if (msg.message == WM_KEYDOWN && mOnKeyDownNotify != NULL && mOnKeyDownNotify(this, msg.wParam)) continue; if (msg.message == WM_KEYDOWN && identify_descendant(msg.hwnd) && (msg.wParam == VK_UP || msg.wParam == VK_DOWN)) { /* VK_UP and VK_DOWN move the focus only within the current control group - but we want it to behave like Shift-Tab and Tab */ LRESULT r = ::SendMessage(msg.hwnd, WM_GETDLGCODE, msg.wParam, (LPARAM)&msg); if ((r & DLGC_WANTMESSAGE) == 0) { /* this window doesn't handle VK_UP/VK_DOWN */ if (msg.wParam == VK_DOWN) focus_next_control(); else focus_previous_control(); continue; } } /* let the WIN32 dialog manager handle hot keys like Tab */ if (::IsDialogMessage(hWnd, &msg)) continue; TranslateMessage(&msg); assert_none_locked(); DispatchMessage(&msg); assert_none_locked(); } // End Modal Loop #endif /* !ENABLE_SDL */ main_window.remove_dialog(this); // static. this is current open/close or child open/close WndForm::timeAnyOpenClose.update(); #ifndef ENABLE_SDL SetFocus(oldFocusHwnd); #endif /* !ENABLE_SDL */ return mModalResult; }