LRESULT CALLBACK Window::WndProc(HWND _hWnd, UINT message, WPARAM wParam, LPARAM lParam) { enum { #ifndef _WIN32_WCE WM_VERY_FIRST = WM_NCCREATE, #else WM_VERY_FIRST = WM_CREATE, #endif }; assert_none_locked(); if (message == WM_GETMINMAXINFO) /* WM_GETMINMAXINFO is called before WM_CREATE, and we havn't set a Window pointer yet - let DefWindowProc() handle it */ return ::DefWindowProc(_hWnd, message, wParam, lParam); Window *window; if (message == WM_VERY_FIRST) { LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam; window = (Window *)cs->lpCreateParams; window->created(_hWnd); window->set_userdata(window); } else { window = get_unchecked(_hWnd); } LRESULT result = window->on_message(_hWnd, message, wParam, lParam); assert_none_locked(); return result; }
void EventLoop::Dispatch(const MSG &msg) { assert_none_locked(); ::TranslateMessage(&msg); ::DispatchMessage(&msg); assert_none_locked(); }
void set_text(const TCHAR *_text) { assert_none_locked(); assert_thread(); text = _text; invalidate(); }
void EditWindow::set_text(const TCHAR *text) { assert_none_locked(); if ((get_window_style() & ES_MULTILINE) == 0) { ::SetWindowText(hWnd, text); return; } // Replace \n by \r\r\n to enable usage of line-breaks in edit control unsigned size = _tcslen(text); TCHAR buffer[size * sizeof(TCHAR) * 3]; const TCHAR* p2 = text; TCHAR* p3 = buffer; for (; *p2 != _T('\0'); p2++) { if (*p2 == _T('\n')) { *p3 = _T('\r'); p3++; *p3 = _T('\r'); p3++; *p3 = _T('\n'); } else if (*p2 == _T('\r')) { continue; } else { *p3 = *p2; } p3++; } *p3 = _T('\0'); ::SetWindowText(hWnd, buffer); }
void EventQueue::HandlePaintMessages() { assert_none_locked(); HandleMessages(WM_SIZE, WM_SIZE); HandleMessages(WM_PAINT, WM_PAINT); }
void close() { assert_none_locked(); #ifndef USE_GDI on_close(); #else /* ENABLE_SDL */ ::SendMessage(hWnd, WM_CLOSE, 0, 0); #endif }
void set_active() { assert_none_locked(); #ifdef ENABLE_SDL // XXX #else ::SetActiveWindow(hWnd); #endif }
void set_selection(int start, int end) { assert_none_locked(); #ifndef USE_GDI // XXX #else ::SendMessage(hWnd, EM_SETSEL, (WPARAM)start, (LPARAM)end); #endif }
void set_capture() { assert_none_locked(); assert_thread(); #ifdef ENABLE_SDL // XXX #else ::SetCapture(hWnd); #endif }
void set_read_only(bool value) { assert_none_locked(); #ifndef USE_GDI read_only = value; invalidate(); #else ::SendMessage(hWnd, EM_SETREADONLY, (WPARAM)(BOOL)value, 0L); #endif }
void release_capture() { assert_none_locked(); assert_thread(); #ifdef ENABLE_SDL // XXX #else ::ReleaseCapture(); #endif }
void send_command(const Window &from) { assert_none_locked(); assert_thread(); #ifdef ENABLE_SDL // XXX #else /* !ENABLE_SDL */ ::SendMessage(hWnd, WM_COMMAND, (WPARAM)0, (LPARAM)from.hWnd); #endif /* !ENABLE_SDL */ }
void DialogEventLoop::Dispatch(MSG &msg) { assert_none_locked(); if (AllowDialogMessage(msg) && ::IsDialogMessage(dialog, &msg)) { assert_none_locked(); return; } if (IsAltair() && msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) { /* the Windows CE dialog manager does not handle VK_ESCAPE, but the Altair needs it - let's roll our own */ ::SendMessage(dialog, WM_COMMAND, IDCANCEL, 0); return; } EventLoop::Dispatch(msg); }
bool EventLoop::Get(MSG &msg) { assert_none_locked(); if (!::GetMessage(&msg, NULL, 0, 0)) return false; return true; }
void set_font(const Font &font) { assert_none_locked(); assert_thread(); #ifdef ENABLE_SDL // XXX #else ::SendMessage(hWnd, WM_SETFONT, (WPARAM)font.native(), MAKELPARAM(TRUE,0)); #endif }
/** * Like move(), but does not trigger a synchronous redraw. The * caller is responsible for redrawing. */ void fast_move(int left, int top, unsigned width, unsigned height) { assert_none_locked(); assert_thread(); #ifdef ENABLE_SDL move(left, top, width, height); #else /* !ENABLE_SDL */ ::SetWindowPos(hWnd, NULL, left, top, width, height, SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_DEFERERASE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER); #endif }
void move(int left, int top, unsigned width, unsigned height) { assert_none_locked(); assert_thread(); #ifdef ENABLE_SDL // XXX #else /* !ENABLE_SDL */ ::SetWindowPos(hWnd, NULL, left, top, width, height, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER); // XXX store new size? #endif }
void show_on_top() { assert_none_locked(); assert_thread(); #ifdef ENABLE_SDL bring_to_top(); show(); #else ::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE); #endif }
static void handle_paint_messages() { assert_none_locked(); #ifdef WIN32 MSG msg; while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } #endif }
void move(int left, int top) { assert_none_locked(); assert_thread(); #ifdef ENABLE_SDL this->left = left; this->top = top; #else ::SetWindowPos(hWnd, NULL, left, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER); #endif }
void EventQueue::HandlePaintMessages() { assert_none_locked(); #ifdef WIN32 MSG msg; while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } #endif }
void set_text(const TCHAR *_text) { assert_none_locked(); assert_thread(); #ifndef USE_GDI if (_text != NULL) text = _text; else text.clear(); invalidate(); #else /* USE_GDI */ ::SetWindowText(hWnd, _text); #endif /* USE_GDI */ }
unsigned get_row_count() const { assert_none_locked(); #ifndef USE_GDI const TCHAR *str = value.c_str(); int row_count = 1; while ((str = strchr(str, _T('\n'))) != NULL) { str++; row_count++; } return row_count; #else /* USE_GDI */ return ::SendMessage(hWnd, EM_GETLINECOUNT, 0, 0); #endif /* USE_GDI */ }
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; }
void set_text(const TCHAR *text) { assert_none_locked(); assert_thread(); ::SetWindowText(hWnd, text); }
bool is_down() const { assert_none_locked(); assert_thread(); return (Button_GetState(hWnd) & BST_PUSHED) != 0; }
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; }
void set_focus() { assert_none_locked(); assert_thread(); ::SetFocus(hWnd); }
void bring_to_top() { assert_none_locked(); assert_thread(); ::BringWindowToTop(hWnd); }