Improve: Support multiple screen desktop monitoring

This commit is contained in:
yuanyuanxiang
2025-08-02 23:41:02 +08:00
parent f531933952
commit f95d30e0e6
4 changed files with 68 additions and 26 deletions

View File

@@ -593,6 +593,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
UserParam* user = new UserParam{ ulLength > 1 ? new BYTE[ulLength - 1] : nullptr, int(ulLength-1) };
if (ulLength > 1) {
memcpy(user->buffer, szBuffer + 1, ulLength - 1);
if (ulLength > 2 && !m_conn->IsVerified()) user->buffer[2] = 0;
}
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType());
m_hThread[m_ulThreadCount].user = user;

View File

@@ -84,6 +84,25 @@ private:
class ScreenCapture
{
private:
static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
std::vector<MONITORINFOEX>* monitors = reinterpret_cast<std::vector<MONITORINFOEX>*>(dwData);
MONITORINFOEX mi;
mi.cbSize = sizeof(MONITORINFOEX);
if (GetMonitorInfo(hMonitor, &mi))
{
monitors->push_back(mi); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>Ϣ
}
return TRUE;
}
std::vector<MONITORINFOEX> GetAllMonitors()
{
std::vector<MONITORINFOEX> monitors;
EnumDisplayMonitors(nullptr, nullptr, MonitorEnumProc, (LPARAM)&monitors);
return monitors;
}
public:
ThreadPool* m_ThreadPool; // <20>̳߳<DFB3>
BYTE* m_FirstBuffer; // <20><>һ֡<D2BB><D6A1><EFBFBD><EFBFBD>
@@ -119,13 +138,24 @@ public:
m_BlockNum = 8;
m_ThreadPool = new ThreadPool(m_BlockNum);
if (all)
static auto monitors = GetAllMonitors();
static int index = 0;
if (all && !monitors.empty())
{
m_iScreenX = GetSystemMetrics(SM_XVIRTUALSCREEN);
m_iScreenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
m_ulFullWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
m_ulFullHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
int idx = index++ % (monitors.size()+1);
if (idx == 0) {
m_iScreenX = GetSystemMetrics(SM_XVIRTUALSCREEN);
m_iScreenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
m_ulFullWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
m_ulFullHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
else {
RECT rt = monitors[idx-1].rcMonitor;
m_iScreenX = rt.left;
m_iScreenY = rt.top;
m_ulFullWidth = rt.right - rt.left;
m_ulFullHeight = rt.bottom - rt.top;
}
} else {
//::GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN)<29><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><C4BB>С<EFBFBD><D0A1>׼
//<2F><><EFBFBD><EFBFBD><E7B5B1>Ļ<EFBFBD><C4BB>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>Ϊ125%ʱ<><CAB1><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>С<EFBFBD><D0A1>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>1.25<EFBFBD>Ŷ<EFBFBD>
@@ -411,6 +441,8 @@ public:
pt.x *= m_wZoom;
pt.y *= m_hZoom;
}
pt.x += m_iScreenX;
pt.y += m_iScreenY;
}
// <20><>ȡλͼ<CEBB><EFBFBD><E1B9B9>Ϣ

View File

@@ -9,6 +9,7 @@
#include <d3d11.h>
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")
// author: ChatGPT
// update: 962914132@qq.com
@@ -24,7 +25,7 @@ private:
public:
ScreenCapturerDXGI(BYTE algo, int gop = DEFAULT_GOP, BOOL all = FALSE) : ScreenCapture(32, algo, all) {
m_GOP = gop;
InitDXGI();
InitDXGI(all);
Mprintf("Capture screen with DXGI: GOP= %d\n", m_GOP);
}
@@ -36,26 +37,38 @@ public:
SAFE_DELETE_ARRAY(m_RectBuffer);
}
void InitDXGI() {
void InitDXGI(BOOL all) {
m_iScreenX = 0;
m_iScreenY = 0;
// 1. <20><><EFBFBD><EFBFBD> D3D11 <20>
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext);
IDXGIDevice * dxgiDevice = nullptr;
IDXGIAdapter* dxgiAdapter = nullptr;
IDXGIFactory1* pFactory = nullptr;
IDXGIAdapter1* dxgiAdapter = nullptr;
IDXGIOutput* dxgiOutput = nullptr;
IDXGIOutput1* dxgiOutput1 = nullptr;
do {
// 2. <20><>ȡ DXGI <20>
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
if(!dxgiDevice)break;
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
if (!pFactory) return;
// 3. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
dxgiDevice->GetAdapter(&dxgiAdapter);
do {
// 3. <20><>ȡ<EFBFBD>
static UINT idx = 0;
idx = pFactory->EnumAdapters1(idx, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND ? 0 : idx;
if (!dxgiAdapter) pFactory->EnumAdapters1(idx, &dxgiAdapter);
if (!dxgiAdapter)break;
// 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>
dxgiAdapter->EnumOutputs(0, &dxgiOutput);
static UINT screen = 0;
HRESULT r = dxgiAdapter->EnumOutputs(screen++, &dxgiOutput);
if (r == DXGI_ERROR_NOT_FOUND && all) {
screen = 0;
idx ++;
dxgiAdapter->Release();
dxgiAdapter = nullptr;
continue;
}
if (!dxgiOutput)break;
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
@@ -99,13 +112,15 @@ public:
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
} while (false);
break;
} while (true);
// <20>ͷ<EFBFBD> DXGI <20><>Դ
if (dxgiOutput1) dxgiOutput1->Release();
if (dxgiOutput) dxgiOutput->Release();
if (dxgiAdapter) dxgiAdapter->Release();
if (dxgiDevice) dxgiDevice->Release();
if (pFactory) pFactory->Release();
}
bool IsInitSucceed() const {

View File

@@ -829,12 +829,6 @@ void CScreenSpyDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bMouseTracking)
{
// 第一次进入,开始追踪 WM_MOUSELEAVE
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
TrackMouseEvent(&tme);
m_bMouseTracking = true;
SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO));
}