📄 vncclientcontrol.cpp
字号:
// Copyright (C) 2006 Teamviewer GmbH. All Rights Reserved.
//
// This file is part of the TeamViewer system.
//
// TeamViewer is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// If the source code for TeamViewer is not available from the place
// whence you received this file, check http://www.teamviewer.com
#include "stdhdrs.h"
#include "Localization.h"
#include "vncClientControl.h"
#include "global.h"
#include "vncmenu.h"
#include "HideDesktop.h"
#include <WindowsX.h>
#define BUTTON_WIDTH 26
typedef BOOL (*SetSingleWindowFn)(HWND hwnd);
DWORD threadid = NULL;
vncClientControl::vncClientControl()
{
m_closed = false;
m_fileTransferLog=NULL;
m_hTBImageList = NULL;
m_hTBHottrack = NULL;
m_hwndPointer = NULL;
m_fLastSingleWindow = false;
wf = NULL;
m_bmpToolbarBackground = (HBITMAP)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_BITMAP_TOOLBAR_BKGND),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
m_bmpToolbarHandleClosed = (HBITMAP)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_HANDLE_CLOSED),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
m_closeButton = (HBITMAP)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_CLOSE),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
m_minimizeButton = (HBITMAP)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_MINIMIZE),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
}
vncClientControl::~vncClientControl()
{
if (m_fileTransferLog!=NULL) { delete m_fileTransferLog; }
if (m_hTBImageList != NULL) { ImageList_Destroy(m_hTBImageList); m_hTBImageList = NULL; }
if (m_hTBHottrack != NULL) { ImageList_Destroy(m_hTBHottrack); m_hTBHottrack = NULL; }
if (m_bmpToolbarBackground != NULL) {DeleteObject(m_bmpToolbarBackground); m_bmpToolbarBackground = NULL; }
if (m_bmpToolbarHandleClosed != NULL) {DeleteObject(m_bmpToolbarHandleClosed); m_bmpToolbarHandleClosed = NULL; }
if (m_closeButton != NULL) {DeleteObject(m_closeButton); m_closeButton = NULL; }
if (m_minimizeButton != NULL) {DeleteObject(m_minimizeButton); m_minimizeButton = NULL; }
if (wf) delete wf;
InvalidateRect(0, 0, TRUE);
}
// Fenster schlie遝n
void vncClientControl::Kill()
{
PostMessage(m_hwndClientControl, WM_CLOSE, 0, 0);
}
//
//
//
BOOL vncClientControl::Init(vncClient* pClient, vncServer* pServer)
{
m_pClient = pClient;
m_pServer = pServer;
PaintBorder(NULL);
m_fileTransferLog=new FileTransferLog(m_pClient);
// Presentation: get property settings from global properties
if (m_pClient->m_ActiveMode == rfbMC_PresentationServer)
{
m_opts = VNCviewerApp32::Instance()->m_options; // copy options that may have been given by commandline
if(!m_opts.m_SetFromCommandLine)
{
m_opts.m_Quality = menu->m_properties.Presentation_Quality();
m_opts.m_Compression = menu->m_properties.Presentation_Compression();
m_opts.m_Use8Bit = menu->m_properties.Presentation_Colors();
}
m_opts.ApplyQuality();
m_opts.m_nServerScale = menu->m_properties.Presentation_ServerScale();
m_opts.m_RemoveWallpaper = menu->m_properties.Presentation_RemoveWallpaper();
if(menu->m_properties.Presentation_SingleWindow())
{
omni_mutex_lock l(m_pClient->m_encodemgr.m_buffer->m_desktop->GetUpdateLock());
m_pServer->SingleWindow(TRUE);
m_pServer->SetSingleWindowName(menu->m_properties.Presentation_WindowName());
m_pClient->m_encodemgr.m_buffer->m_desktop->SearchSingleWindowByName();
}
else
m_pServer->SingleWindow(FALSE);
ApplyOptions();
}
start_undetached();
return TRUE;
}
void vncClientControl::CreateButtons()
{
TBBUTTON ButtonEnd = {0,ID_BUTTON_END,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonRefresh = {1,ID_BUTTON_REFRESH,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonOptions = {2,ID_BUTTON_PROPERTIES,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonChat = {3,ID_BUTTON_TEXTCHAT,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonSingleWindow = {5,ID_BUTTON_SW,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonDirChange = {6,ID_BUTTON_DIRCHANGE,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonContinue = {8,ID_BUTTON_CONTINUE,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonPause = {9,ID_BUTTON_PAUSE,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonDesktop = {11,ID_BUTTON_DESKTOP,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonEnableInput = {12,ID_BUTTON_ENABLE_INPUT,TBSTATE_ENABLED,TBSTYLE_BUTTON};
TBBUTTON ButtonDisableInput = {13,ID_BUTTON_DISABLE_INPUT,TBSTATE_ENABLED,TBSTYLE_BUTTON};
// remove all buttons
while(SendMessage(m_hwndTB, (UINT)TB_DELETEBUTTON, 0, 0)) ;
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonEnd);
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonChat);
int nr_buttons = 2;
m_SW_Buttonpos = -1;
if (m_pClient->m_ActiveMode == rfbMC_PresentationServer)
{
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonOptions);
if(m_pClient->IsPointerEnabled())
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonDisableInput);
else
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonEnableInput);
if(m_pClient->m_encodemgr.m_buffer->m_desktop->m_Single_hWnd)
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonDesktop);
else
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonSingleWindow);
m_SW_Buttonpos = 5;
if(m_pClient->IsConnectionPaused())
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonContinue);
else
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonPause);
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonRefresh);
nr_buttons += 5;
}
if(m_pClient->ActiveMode() == rfbMC_TeamworkServer || m_pClient->ActiveMode() == rfbMC_PresentationServer)
{
SendMessage(m_hwndTB, (UINT) TB_ADDBUTTONS, 1, (LPARAM)&ButtonDirChange);
++nr_buttons;
}
// Place window in the bottom right corner of the screen
RECT rWork;
HRGN rgnToolbar, rgnHandle, rgn1, rgn2;
SystemParametersInfo( SPI_GETWORKAREA, 0, &rWork, 0 );
int width = nr_buttons * (BUTTON_WIDTH + 7) + 10;
int height = 67;
int left = rWork.right-width-10;
int top = rWork.bottom-height;
MoveWindow(m_hwndClientControl, left, top, width, height, TRUE);
MoveWindow(m_hwndTB, 5, 20, width, 28, TRUE);
rgn1 = CreateRoundRectRgn(0, 0, width, height+9, 9, 9);
SetWindowRgn(m_hwndClientControl, rgn1, TRUE);
MoveWindow(m_hwndHandleClosed, left, rWork.bottom-14, width, 14, TRUE);
rgnToolbar = CreateRoundRectRgn(0, 9, width, 14+9, 9, 9);
rgnHandle = CreateRoundRectRgn((width-43)/2, 0, (width+43)/2, 14, 6, 6);
rgn2 = CreateRectRgn(0,0,0,0);
CombineRgn(rgn2, rgnToolbar, rgnHandle, RGN_OR);
SetWindowRgn(m_hwndHandleClosed, rgn2, TRUE);
DeleteObject(rgnToolbar);
DeleteObject(rgnHandle);
ShowWindow(m_hwndClientControl, m_closed ? SW_HIDE:SW_SHOW);
ShowWindow(m_hwndHandleClosed, m_closed ? SW_SHOW:SW_HIDE);
InvalidateRect(m_hwndTB, NULL, TRUE);
InvalidateRect(m_hwndClientControl, NULL, TRUE);
UpdateWindow(m_hwndClientControl);
}
void *vncClientControl::run_undetached(void * arg)
{
// Control-Fenster f黵 die Serversession
WNDCLASS wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = vncClientControl::WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hAppInstance;
wndclass.hIcon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_ROVNC));
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = //(HBRUSH) (COLOR_WINDOW);
(HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.lpszMenuName = (const TCHAR *) NULL;
wndclass.lpszClassName = _T("CCONTROL_Win");
RegisterClass(&wndclass);
m_hwndClientControl =
CreateWindow(
_T("CCONTROL_Win"),
m_pClient->m_client_name,
WS_POPUP,
0, 0, 0, 0,
NULL, // parent
NULL, // Menu
hAppInstance,
NULL);
SetWindowLong(m_hwndClientControl, GWL_USERDATA, (LONG) this);
SendMessage(m_hwndClientControl,WM_SYSCOMMAND,MAKEWPARAM(ID_TOPMOST_TOOLBAR_WINDOW,0),0);
//DrawMenuBar(m_hwndClientControl);
InitCommonControls();
m_hwndTB = CreateWindowEx(0,
TOOLBARCLASSNAME,
_T("TeamViewer ClientControl Buttons"),
WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_NORESIZE | CCS_NOPARENTALIGN,
0, 0, 0, 0,
m_hwndClientControl,
(HMENU)IDR_TOOLBAR,
hAppInstance,
NULL);
SetWindowLong(m_hwndTB, GWL_USERDATA, (LONG) this);
SendMessage(m_hwndTB, (UINT) TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
// win2k: set color of hot tracking frame
COLORSCHEME scheme;
scheme.dwSize = sizeof(scheme);
scheme.clrBtnHighlight = RGB(175,175,175);
scheme.clrBtnShadow = RGB(175,175,175);
SendMessage(m_hwndTB, (UINT) TB_SETCOLORSCHEME, 0, (LPARAM)&scheme);
SendMessage(m_hwndTB, (UINT) TB_AUTOSIZE, 0, 0);
m_hTBImageList = ImageList_LoadImage(hAppInstance,
MAKEINTRESOURCE(IDB_BITMAP_ICONS), BUTTON_WIDTH, 1,
0, IMAGE_BITMAP, LR_CREATEDIBSECTION|LR_SHARED);
m_hTBHottrack = ImageList_LoadImage(hAppInstance,
MAKEINTRESOURCE(IDB_MOUSEOVER), BUTTON_WIDTH, 1,
0, IMAGE_BITMAP, LR_CREATEDIBSECTION|LR_SHARED);
SendMessage(m_hwndTB, (UINT) TB_SETIMAGELIST, 0, (LPARAM)m_hTBImageList);
SendMessage(m_hwndTB, (UINT) TB_SETHOTIMAGELIST, 0, (LPARAM)m_hTBHottrack);
// window class for toolbar minimize/maximize handle
WNDCLASS wndclassHandle;
wndclassHandle.style = 0;
wndclassHandle.lpfnWndProc = vncClientControl::WndProcHandle;
wndclassHandle.cbClsExtra = 0;
wndclassHandle.cbWndExtra = 0;
wndclassHandle.hInstance = hAppInstance;
wndclassHandle.hIcon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_ROVNC));
wndclassHandle.hCursor = LoadCursor(NULL, IDC_HAND);
wndclassHandle.hbrBackground = NULL;
wndclassHandle.lpszMenuName = (const TCHAR *) NULL;
wndclassHandle.lpszClassName = _T("ClientControl_WinHandle");
RegisterClass(&wndclassHandle);
// small stand alone handle window to maximize toolbar
m_hwndHandleClosed = CreateWindowEx(
0,
_T("ClientControl_WinHandle"),
m_pClient->m_client_name,
WS_POPUP,
0, 0, 0, 0,
m_hwndClientControl, // Parent handle
NULL, // Menu handle
hAppInstance,
NULL);
SetWindowLong(m_hwndHandleClosed, GWL_USERDATA, (LONG) this);
// window class for pointer during presentations
WNDCLASS wndclassPointer;
wndclassPointer.style = 0;
wndclassPointer.lpfnWndProc = vncClientControl::WndProcPointer;
wndclassPointer.cbClsExtra = 0;
wndclassPointer.cbWndExtra = 0;
wndclassPointer.hInstance = hAppInstance;
wndclassPointer.hIcon = 0;
wndclassPointer.hCursor = LoadCursor(NULL, IDC_HAND);
wndclassPointer.hbrBackground = NULL;
wndclassPointer.lpszMenuName = (const TCHAR *) NULL;
wndclassPointer.lpszClassName = _T("ClientControl_WinPointer");
RegisterClass(&wndclassPointer);
CreateButtons();
if(m_pClient->m_ActiveMode != rfbMC_FiletransferServer)
{
ShowWindow(m_hwndTB, SW_SHOW);
SetForegroundWindow(m_hwndClientControl);
SetWindowPos(m_hwndClientControl, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
SetWindowPos(m_hwndHandleClosed, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
oldWndProcTB = (WNDPROC)SetWindowLong(m_hwndTB, GWL_WNDPROC, (LONG)vncClientControl::WndProcTB);
wf = new WindowFinder(m_hwndTB);
}
else
{
ShowWindow(m_hwndClientControl,SW_HIDE);
ShowWindow(m_hwndHandleClosed, SW_HIDE);
}
// take care that the toolbar is updated after a short time
SetTimer(m_hwndClientControl, 1, 500, NULL);
// Now enter the message handling loop until told to quit!
try
{
MSG msg;
while (GetMessage(&msg, NULL, 0,0)) {
TranslateMessage(&msg); // convert key ups and downs to chars
DispatchMessage(&msg);
}
}
catch(...)
{
vnclog.Print(LL_INTERR, VNCLOG("ClientControl.CATCH"));
}
DestroyWindow(m_hwndTB);
DestroyWindow(m_hwndHandleClosed);
DestroyWindow(m_hwndClientControl);
return NULL;
}
//
//
//
LRESULT CALLBACK vncClientControl::WndProc(HWND hwnd, UINT uMsg, 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.
vncClientControl *_this = (vncClientControl *) GetWindowLong(hwnd, GWL_USERDATA);
if (_this == NULL)
return DefWindowProc(hwnd, uMsg, wParam, lParam);
if(_this->m_pClient && !_this->m_pClient->m_disable_protocol)
{
HWND sw = _this->m_pClient->m_encodemgr.m_buffer->m_desktop->m_Single_hWnd;
if(_this->m_fLastSingleWindow != sw)
{
RECT r;
_this->PaintBorder(sw);
GetWindowRect(_this->m_fLastSingleWindow, &r);
RedrawWindow(_this->m_fLastSingleWindow, &r, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
GetWindowRect(sw, &r);
RedrawWindow(sw, &r, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
_this->m_fLastSingleWindow = sw;
_this->CreateButtons();
}
}
switch (uMsg)
{
case WM_ERASEBKGND:
{
HDC dcDest,dcSrc;
HBRUSH oldBrush = NULL;
HPEN oldPen = NULL;
RECT r;
if(!_this->m_pClient || _this->m_pClient->m_deleting)
return TRUE;
dcDest = (HDC)wParam;
dcSrc = CreateCompatibleDC(dcDest);
if(dcSrc)
{
GetClientRect(hwnd, &r);
// fill background with grey brush
HBRUSH lightgrey = CreateSolidBrush(RGB(222, 222, 222));
if(lightgrey)
{
oldBrush = (HBRUSH)SelectObject(dcDest, lightgrey);
Rectangle(dcDest, r.left, r.top, r.right, r.bottom);
DeleteBrush(lightgrey);
}
// paint background
SelectObject(dcSrc, _this->m_bmpToolbarBackground);
StretchBlt(dcDest, r.left, r.top+20, r.right-r.left, 50, dcSrc, 0, 0, 1, 50, SRCCOPY);
//paint close button
SelectObject(dcSrc, _this->m_closeButton);
BitBlt(dcDest, r.right-21, r.top+4, 16, 14, dcSrc, 0, 0, SRCCOPY);
// paint minimize button
SelectObject(dcSrc, _this->m_minimizeButton);
BitBlt(dcDest, r.right-40, r.top+4, 16, 14, dcSrc, 0, 0, SRCCOPY);
// paint border
HPEN greyPen = CreatePen(PS_SOLID, 3, RGB(117, 117, 117));
if(greyPen)
oldPen = (HPEN)SelectObject(dcDest, greyPen);
SelectObject(dcDest, GetStockObject(HOLLOW_BRUSH));
RoundRect(dcDest, r.left, r.top, r.right-1, r.bottom + 9, 9, 9);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -