📄 clientconnection.cpp
字号:
encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);
len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
se->nEncodings = Swap16IfLE(se->nEncodings);
WriteExact((char *) buf, len);
}
// Closing down the connection.
// Close the socket, kill the thread.
void ClientConnection::KillThread()
{
m_bKillThread = true;
m_running = false;
if (m_sock != INVALID_SOCKET) {
shutdown(m_sock, SD_BOTH);
closesocket(m_sock);
m_sock = INVALID_SOCKET;
}
}
// Get the RFB options from another connection.
void ClientConnection::CopyOptions(ClientConnection *source)
{
this->m_opts = source->m_opts;
}
ClientConnection::~ClientConnection()
{
if (m_hwnd1 != 0)
DestroyWindow(m_hwnd1);
if (m_connDlg != NULL)
delete m_connDlg;
if (m_sock != INVALID_SOCKET) {
shutdown(m_sock, SD_BOTH);
closesocket(m_sock);
m_sock = INVALID_SOCKET;
}
if (m_desktopName != NULL) delete [] m_desktopName;
delete [] m_netbuf;
delete m_pFileTransfer;
DeleteDC(m_hBitmapDC);
if (m_hBitmap != NULL)
DeleteObject(m_hBitmap);
if (m_hPalette != NULL)
DeleteObject(m_hPalette);
m_pApp->DeregisterConnection(this);
}
// You can specify a dx & dy outside the limits; the return value will
// tell you whether it actually scrolled.
bool ClientConnection::ScrollScreen(int dx, int dy)
{
dx = max(dx, -m_hScrollPos);
//dx = min(dx, m_hScrollMax-(m_cliwidth-1)-m_hScrollPos);
dx = min(dx, m_hScrollMax-(m_cliwidth)-m_hScrollPos);
dy = max(dy, -m_vScrollPos);
//dy = min(dy, m_vScrollMax-(m_cliheight-1)-m_vScrollPos);
dy = min(dy, m_vScrollMax-(m_cliheight)-m_vScrollPos);
if (dx || dy) {
m_hScrollPos += dx;
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 messages
LRESULT CALLBACK ClientConnection::ScrollProc(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);
switch (iMsg) {
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;
}
if (!_this->m_opts.m_FitWindow)
_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;
}
if (!_this->m_opts.m_FitWindow)
_this->ScrollScreen(0,dy);
return 0;
}
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
LRESULT CALLBACK ClientConnection::WndProc1(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);
switch (iMsg) {
case WM_NOTIFY:
{
LPTOOLTIPTEXT TTStr = (LPTOOLTIPTEXT)lParam;
if (TTStr->hdr.code != TTN_NEEDTEXT)
return 0;
switch (TTStr->hdr.idFrom) {
case IDC_OPTIONBUTTON:
TTStr->lpszText = "Connection options...";
break;
case ID_CONN_ABOUT:
TTStr->lpszText = "Connection info";
break;
case ID_FULLSCREEN:
TTStr->lpszText = "Full screen";
break;
case ID_REQUEST_REFRESH:
TTStr->lpszText = "Request screen refresh";
break;
case ID_CONN_CTLALTDEL:
TTStr->lpszText = "Send Ctrl-Alt-Del";
break;
case ID_CONN_CTLESC:
TTStr->lpszText = "Send Ctrl-Esc";
break;
case ID_CONN_CTLDOWN:
TTStr->lpszText = "Send Ctrl key press/release";
break;
case ID_CONN_ALTDOWN:
TTStr->lpszText = "Send Alt key press/release";
break;
case IDD_FILETRANSFER:
TTStr->lpszText = "Transfer files...";
break;
case ID_NEWCONN:
TTStr->lpszText = "New connection...";
break;
case ID_CONN_SAVE_AS:
TTStr->lpszText = "Save connection info as...";
break;
case ID_DISCONNECT:
TTStr->lpszText = "Disconnect";
break;
}
return 0;
}
case WM_SETFOCUS:
hotkeys.SetWindow(hwnd);
SetFocus(_this->m_hwnd);
return 0;
case WM_COMMAND:
case WM_SYSCOMMAND:
switch (LOWORD(wParam)) {
case SC_MINIMIZE:
_this->SetDormant(true);
break;
case SC_RESTORE:
_this->SetDormant(false);
break;
case ID_NEWCONN:
_this->m_pApp->NewConnection();
return 0;
case ID_DISCONNECT:
SendMessage(hwnd, WM_CLOSE, 0, 0);
return 0;
case ID_TOOLBAR:
if (GetMenuState(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_TOOLBAR,MF_BYCOMMAND) == MF_CHECKED) {
CheckMenuItem(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_TOOLBAR, MF_BYCOMMAND|MF_UNCHECKED);
} else {
CheckMenuItem(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_TOOLBAR, MF_BYCOMMAND|MF_CHECKED);
}
_this->SizeWindow(false);
return 0;
case ID_CONN_SAVE_AS:
_this->SaveConnection();
return 0;
case IDC_OPTIONBUTTON:
{
if (SetForegroundWindow(_this->m_opts.m_hParent) != 0) return 0;
int prev_scale_num = _this->m_opts.m_scale_num;
int prev_scale_den = _this->m_opts.m_scale_den;
if (_this->m_opts.DoDialog(true)) {
_this->m_pendingFormatChange = true;
if (_this->m_opts.m_FitWindow) {
_this->m_opts.m_scaling = true;
_this->PositionChildWindow();
} else {
if (prev_scale_num != _this->m_opts.m_scale_num ||
prev_scale_den != _this->m_opts.m_scale_den) {
// Resize the window if scaling factors were changed
_this->SizeWindow(false);
InvalidateRect(_this->m_hwnd, NULL, FALSE);
}
}
}
if (_this->m_serverInitiated) {
_this->m_opts.SaveOpt(".listen",
KEY_VNCVIEWER_HISTORI);
} else {
_this->m_opts.SaveOpt(_this->m_opts.m_display,
KEY_VNCVIEWER_HISTORI);
}
_this->EnableFullControlOptions();
return 0;
}
case IDD_APP_ABOUT:
ShowAboutBox();
return 0;
case IDD_FILETRANSFER:
if (_this->m_clientMsgCaps.IsEnabled(rfbFileListRequest)) {
if (!_this->m_fileTransferDialogShown) {
_this->m_fileTransferDialogShown = true;
_this->m_pFileTransfer->CreateFileTransferDialog();
}
}
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_CTLESC:
_this->SendKeyEvent(XK_Control_L, true);
_this->SendKeyEvent(XK_Escape, true);
_this->SendKeyEvent(XK_Escape, false);
_this->SendKeyEvent(XK_Control_L, false);
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:
if (GetMenuState(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_CONN_CTLDOWN, MF_BYCOMMAND) == MF_CHECKED) {
_this->SendKeyEvent(XK_Control_L, false);
CheckMenuItem(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_CONN_CTLDOWN, MF_BYCOMMAND|MF_UNCHECKED);
SendMessage(_this->m_hToolbar, TB_SETSTATE, (WPARAM)ID_CONN_CTLDOWN,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
} else {
CheckMenuItem(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_CONN_CTLDOWN, MF_BYCOMMAND|MF_CHECKED);
SendMessage(_this->m_hToolbar, TB_SETSTATE, (WPARAM)ID_CONN_CTLDOWN,
(LPARAM)MAKELONG(TBSTATE_CHECKED|TBSTATE_ENABLED, 0));
_this->SendKeyEvent(XK_Control_L, true);
}
return 0;
case ID_CONN_ALTDOWN:
if(GetMenuState(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_CONN_ALTDOWN,MF_BYCOMMAND) == MF_CHECKED) {
_this->SendKeyEvent(XK_Alt_L, false);
CheckMenuItem(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_CONN_ALTDOWN, MF_BYCOMMAND|MF_UNCHECKED);
SendMessage(_this->m_hToolbar, TB_SETSTATE, (WPARAM)ID_CONN_ALTDOWN,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
} else {
CheckMenuItem(GetSystemMenu(_this->m_hwnd1, FALSE),
ID_CONN_ALTDOWN, MF_BYCOMMAND|MF_CHECKED);
SendMessage(_this->m_hToolbar, TB_SETSTATE, (WPARAM)ID_CONN_ALTDOWN,
(LPARAM)MAKELONG(TBSTATE_CHECKED|TBSTATE_ENABLED, 0));
_this->SendKeyEvent(XK_Alt_L, true);
}
return 0;
case ID_CLOSEDAEMON:
if (MessageBox(NULL, _T("Are you sure you want to exit?"),
_T("Closing VNCviewer"),
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES){
PostQuitMessage(0);
}
return 0;
}
break;
case WM_KILLFOCUS:
if ( _this->m_opts.m_ViewOnly) return 0;
_this->SwitchOffKey();
return 0;
case WM_SIZE:
_this->PositionChildWindow();
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( _this->m_hwnd, _this->m_hwndNextViewer);
#endif
if (_this->m_serverInitiated) {
_this->m_opts.SaveOpt(".listen",
KEY_VNCVIEWER_HISTORI);
} else {
_this->m_opts.SaveOpt(_this->m_opts.m_display,
KEY_VNCVIEWER_HISTORI);
}
if (_this->m_waitingOnEmulateTimer) {
KillTimer(_this->m_hwnd, _this->m_emulate3ButtonsTimer);
_this->m_waitingOnEmulateTimer = false;
}
_this->m_hwnd1 = 0;
_this->m_hwnd = 0;
_this->m_opts.m_hWindow = 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) {
// The thread probably hasn't been started yet,
}
return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
LRESULT CALLBACK ClientConnection::Proc(HWND hwnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
LRESULT 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);
switch (iMsg) {
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(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_MOUSE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -