📄 clientconnection.cpp
字号:
m_vScrollPos += dy; RECT clirect; GetClientRect(m_hwnd, &clirect); ScrollWindowEx(m_hwnd, -dx, -dy, NULL, &clirect, NULL, NULL, SW_INVALIDATE); UpdateScrollbars(); UpdateWindow(m_hwnd); return true; } return false;}// Process windows messagesLRESULT CALLBACK ClientConnection::WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { // This is a static method, so we don't know which instantiation we're // dealing with. But we've stored a 'pseudo-this' in the window data. ClientConnection *_this = (ClientConnection *) GetWindowLong(hwnd, GWL_USERDATA); try { switch (iMsg) { case WM_CREATE: return 0; case WM_REGIONUPDATED: _this->DoBlit(); _this->SendAppropriateFramebufferUpdateRequest(); return 0; case WM_PAINT: _this->DoBlit(); return 0; case WM_TIMER: if (wParam == _this->m_emulate3ButtonsTimer) { _this->SubProcessPointerEvent( _this->m_emulateButtonPressedX, _this->m_emulateButtonPressedY, _this->m_emulateKeyFlags); KillTimer(_this->m_hwnd, _this->m_emulate3ButtonsTimer); _this->m_waitingOnEmulateTimer = false; } return 0; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MOUSEMOVE: { if (!_this->m_running) return 0; if (GetFocus() != hwnd) return 0; int x = LOWORD(lParam); int y = HIWORD(lParam); if (_this->InFullScreenMode()) { if (_this->BumpScroll(x,y)) return 0; } if ( _this->m_opts.m_ViewOnly) return 0; _this->ProcessPointerEvent(x,y, wParam, iMsg); return 0; } case WM_MOUSEWHEEL: if (!_this->m_opts.m_ViewOnly) _this->ProcessMouseWheel((SHORT)HIWORD(wParam)); return 0; case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: { if (!_this->m_running) return 0; if ( _this->m_opts.m_ViewOnly) return 0; _this->ProcessKeyEvent((int) wParam, (DWORD) lParam); return 0; } case WM_CHAR: case WM_SYSCHAR:#ifdef UNDER_CE { int key = wParam; log.Print(4,_T("CHAR msg : %02x\n"), key); // Control keys which are in the Keymap table will already // have been handled. if (key == 0x0D || // return key == 0x20 || // space key == 0x08) // backspace return 0; if (key < 32) key += 64; // map ctrl-keys onto alphabet if (key > 32 && key < 127) { _this->SendKeyEvent(wParam & 0xff, true); _this->SendKeyEvent(wParam & 0xff, false); } return 0; }#endif case WM_DEADCHAR: case WM_SYSDEADCHAR: return 0; case WM_SETFOCUS: if (_this->InFullScreenMode()) SetWindowPos(hwnd, HWND_TOPMOST, 0,0,100,100, SWP_NOMOVE | SWP_NOSIZE); return 0; // Cacnel modifiers when we lose focus case WM_KILLFOCUS: { if (!_this->m_running) return 0; if (_this->InFullScreenMode()) { // We must top being topmost, but we want to choose our // position carefully. HWND foreground = GetForegroundWindow(); HWND hwndafter = NULL; if ((foreground == NULL) || (GetWindowLong(foreground, GWL_EXSTYLE) & WS_EX_TOPMOST)) { hwndafter = HWND_NOTOPMOST; } else { hwndafter = GetNextWindow(foreground, GW_HWNDNEXT); } SetWindowPos(hwnd, hwndafter, 0,0,100,100, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } log.Print(6, _T("Losing focus - cancelling modifiers\n")); _this->SendKeyEvent(XK_Alt_L, false); _this->SendKeyEvent(XK_Control_L, false); _this->SendKeyEvent(XK_Shift_L, false); _this->SendKeyEvent(XK_Alt_R, false); _this->SendKeyEvent(XK_Control_R, false); _this->SendKeyEvent(XK_Shift_R, false); return 0; } case WM_CLOSE: { // Close the worker thread as well _this->KillThread(); DestroyWindow(hwnd); return 0; } case WM_DESTROY: {#ifndef UNDER_CE // Remove us from the clipboard viewer chain BOOL res = ChangeClipboardChain( hwnd, _this->m_hwndNextViewer);#endif if (_this->m_waitingOnEmulateTimer) { KillTimer(_this->m_hwnd, _this->m_emulate3ButtonsTimer); _this->m_waitingOnEmulateTimer = false; } _this->m_hwnd = 0; // We are currently in the main thread. // The worker thread should be about to finish if // it hasn't already. Wait for it. try { void *p; _this->join(&p); // After joining, _this is no longer valid } catch (omni_thread_invalid& e) { // The thread probably hasn't been started yet, } return 0; } case WM_WINDOWPOSCHANGED: case WM_SIZE: { // Calculate window dimensions RECT rect; GetWindowRect(hwnd, &rect); // update these for the record _this->m_winwidth = rect.right - rect.left; _this->m_winheight = rect.bottom - rect.top; // If the current window size would be large enough to hold the // whole screen without scrollbars, or if we're full-screen, // we turn them off. Under CE, the scroll bars are unchangeable. #ifndef UNDER_CE if (_this->InFullScreenMode() || _this->m_winwidth >= _this->m_fullwinwidth && _this->m_winheight >= _this->m_fullwinheight ) { ShowScrollBar(hwnd, SB_HORZ, FALSE); ShowScrollBar(hwnd, SB_VERT, FALSE); } else { ShowScrollBar(hwnd, SB_HORZ, TRUE); ShowScrollBar(hwnd, SB_VERT, TRUE); } #endif // Update these for the record // And consider that in full-screen mode the window // is actually bigger than the remote screen. GetClientRect(hwnd, &rect); _this->m_hScrollMax = _this->m_si.framebufferWidth * _this->m_opts.m_scale_num / _this->m_opts.m_scale_den; _this->m_vScrollMax = _this->m_si.framebufferHeight* _this->m_opts.m_scale_num / _this->m_opts.m_scale_den; _this->m_cliwidth = min( rect.right - rect.left, _this->m_hScrollMax ); _this->m_cliheight = min( rect.bottom - rect.top, _this->m_vScrollMax ); int newhpos, newvpos; newhpos = max(0, min(_this->m_hScrollPos, _this->m_hScrollMax - max(_this->m_cliwidth, 0))); newvpos = max(0, min(_this->m_vScrollPos, _this->m_vScrollMax - max(_this->m_cliheight, 0))); ScrollWindowEx(hwnd, _this->m_hScrollPos-newhpos, _this->m_vScrollPos-newvpos, NULL, &rect, NULL, NULL, SW_INVALIDATE); _this->m_hScrollPos = newhpos; _this->m_vScrollPos = newvpos; //_this->UpdateScrollbars();
//Added by: Lars Werner (http://lars.werner.no)
if(wParam==SIZE_MAXIMIZED&&_this->InFullScreenMode()==FALSE)
{
//ShowWindow(_this->m_hwnd,SW_RESTORE);
_this->SetFullScreenMode(!_this->InFullScreenMode());
return 0;
}
//Modified by: Lars Werner (http://lars.werner.no)
if(_this->InFullScreenMode()==TRUE)
return 0;
else
break;
} case WM_HSCROLL: { int dx = 0; int pos = HIWORD(wParam); switch (LOWORD(wParam)) { case SB_LINEUP: dx = -2; break; case SB_LINEDOWN: dx = 2; break; case SB_PAGEUP: dx = _this->m_cliwidth * -1/4; break; case SB_PAGEDOWN: dx = _this->m_cliwidth * 1/4; break; case SB_THUMBPOSITION: dx = pos - _this->m_hScrollPos; case SB_THUMBTRACK: dx = pos - _this->m_hScrollPos; } _this->ScrollScreen(dx,0); return 0; } case WM_VSCROLL: { int dy = 0; int pos = HIWORD(wParam); switch (LOWORD(wParam)) { case SB_LINEUP: dy = -2; break; case SB_LINEDOWN: dy = 2; break; case SB_PAGEUP: dy = _this->m_cliheight * -1/4; break; case SB_PAGEDOWN: dy = _this->m_cliheight * 1/4; break; case SB_THUMBPOSITION: dy = pos - _this->m_vScrollPos; case SB_THUMBTRACK: dy = pos - _this->m_vScrollPos; } _this->ScrollScreen(0,dy); return 0; } case WM_QUERYNEWPALETTE: { TempDC hDC(hwnd); // Select and realize hPalette PaletteSelector p(hDC, _this->m_hPalette); InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); return TRUE; } case WM_PALETTECHANGED: // If this application did not change the palette, select // and realize this application's palette if ((HWND) wParam != hwnd) { // Need the window's DC for SelectPalette/RealizePalette TempDC hDC(hwnd); PaletteSelector p(hDC, _this->m_hPalette); // When updating the colors for an inactive window, // UpdateColors can be called because it is faster than // redrawing the client area (even though the results are // not as good) #ifndef UNDER_CE UpdateColors(hDC); #else InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); #endif } break;#ifndef UNDER_CE case WM_SIZING: { // Don't allow sizing larger than framebuffer RECT *lprc = (LPRECT) lParam; switch (wParam) { case WMSZ_RIGHT: case WMSZ_TOPRIGHT: case WMSZ_BOTTOMRIGHT: lprc->right = min(lprc->right, lprc->left + _this->m_fullwinwidth+1); break; case WMSZ_LEFT: case WMSZ_TOPLEFT: case WMSZ_BOTTOMLEFT: lprc->left = max(lprc->left, lprc->right - _this->m_fullwinwidth); break; } switch (wParam) { case WMSZ_TOP: case WMSZ_TOPLEFT: case WMSZ_TOPRIGHT: lprc->top = max(lprc->top, lprc->bottom - _this->m_fullwinheight); break; case WMSZ_BOTTOM: case WMSZ_BOTTOMLEFT: case WMSZ_BOTTOMRIGHT: lprc->bottom = min(lprc->bottom, lprc->top + _this->m_fullwinheight); break; } return 0; } case WM_SETCURSOR: { // if we have the focus, let the cursor change as normal if (GetFocus() == hwnd) break; // if not, set to default system cursor SetCursor( LoadCursor(NULL, IDC_ARROW)); return 0; } case WM_SYSCOMMAND: { switch (LOWORD(wParam)) { case SC_MINIMIZE: _this->SetDormant(true); break; case SC_RESTORE: _this->SetDormant(false); break;
case SC_MAXIMIZE: //Added by: Lars Werner (http://lars.werner.no)
_this->SetFullScreenMode(!_this->InFullScreenMode());
break; case ID_NEWCONN: _this->m_pApp->NewConnection(); return 0; case ID_CONN_SAVE_AS: _this->SaveConnection(); return 0; case IDC_OPTIONBUTTON: if (_this->m_opts.DoDialog(true)) { _this->m_pendingFormatChange = true; // This isn't always needed _this->SizeWindow(); InvalidateRect(hwnd, NULL, TRUE); //_this->UpdateScrollbars(); //UpdateWindow(hwnd); // Make the window correspond to the requested state _this->RealiseFullScreenMode(); }; return 0; case IDD_APP_ABOUT: ShowAboutBox(); return 0; case ID_CONN_ABOUT: _this->ShowConnInfo(); return 0; case ID_FULLSCREEN: // Toggle full screen mode _this->SetFullScreenMode(!_this->InFullScreenMode()); return 0; case ID_REQUEST_REFRESH: // Request a full-screen update _this->SendFullFramebufferUpdateRequest(); return 0; case ID_CONN_CTLALTDEL: _this->SendKeyEvent(XK_Control_L, true); _this->SendKeyEvent(XK_Alt_L, true); _this->SendKeyEvent(XK_Delete, true); _this->SendKeyEvent(XK_Delete, false); _this->SendKeyEvent(XK_Alt_L, false); _this->SendKeyEvent(XK_Control_L, false); return 0; case ID_CONN_CTLDOWN: _this->SendKeyEvent(XK_Control_L, true); return 0; case ID_CONN_CTLUP: _this->SendKeyEvent(XK_Control_L, false); return 0; case ID_CONN_ALTDOWN: _this->SendKeyEvent(XK_Alt_L, true); return 0; case ID_CONN_ALTUP: _this->SendKeyEvent(XK_Alt_L, false); return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -