mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-21 23:13:08 +08:00
Feature: Add menu to switch screen for remote control
This commit is contained in:
@@ -133,6 +133,7 @@ public:
|
||||
int m_GOP; // <20>ؼ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
||||
bool m_SendKeyFrame; // <20><><EFBFBD>ؼ<CDB9>֡
|
||||
CX264Encoder *m_encoder; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int m_nScreenCount; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD>
|
||||
|
||||
ScreenCapture(int n = 32, BYTE algo = ALGORITHM_DIFF, BOOL all = FALSE) :
|
||||
m_ThreadPool(nullptr), m_FirstBuffer(nullptr), m_RectBuffer(nullptr),
|
||||
@@ -141,11 +142,11 @@ public:
|
||||
m_FrameID(0), m_GOP(DEFAULT_GOP), m_iScreenX(0), m_iScreenY(0), m_biBitCount(n),
|
||||
m_SendKeyFrame(false), m_encoder(nullptr)
|
||||
{
|
||||
|
||||
m_BlockNum = 8;
|
||||
m_ThreadPool = new ThreadPool(m_BlockNum);
|
||||
static auto monitors = GetAllMonitors();
|
||||
static int index = 0;
|
||||
m_nScreenCount = monitors.size();
|
||||
if (all && !monitors.empty()) {
|
||||
int idx = index++ % (monitors.size()+1);
|
||||
if (idx == 0) {
|
||||
@@ -207,6 +208,10 @@ public:
|
||||
SAFE_DELETE(m_encoder);
|
||||
}
|
||||
|
||||
virtual int GetScreenCount() const {
|
||||
return m_nScreenCount;
|
||||
}
|
||||
|
||||
virtual int SendQuality(int quality)
|
||||
{
|
||||
int old = m_SendQuality;
|
||||
|
||||
@@ -111,6 +111,18 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CMan
|
||||
m_hWorkThread = __CreateThread(NULL,0, WorkThreadProc,this,0,NULL);
|
||||
}
|
||||
|
||||
bool CScreenManager::SwitchScreen() {
|
||||
if (m_ScreenSpyObject == NULL || m_ScreenSpyObject->GetScreenCount() <= 1)
|
||||
return false;
|
||||
m_bIsWorking = FALSE;
|
||||
DWORD s = WaitForSingleObject(m_hWorkThread, 3000);
|
||||
if (s == WAIT_TIMEOUT) {
|
||||
TerminateThread(m_hWorkThread, -1);
|
||||
}
|
||||
m_bIsWorking = TRUE;
|
||||
m_hWorkThread = __CreateThread(NULL, 0, WorkThreadProc, this, 0, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::wstring ConvertToWString(const std::string& multiByteStr)
|
||||
{
|
||||
@@ -190,8 +202,8 @@ void CScreenManager::InitScreenSpy()
|
||||
DXGI = param->buffer[0];
|
||||
algo = param->length > 1 ? param->buffer[1] : algo;
|
||||
all = param->length > 2 ? param->buffer[2] : all;
|
||||
delete param;
|
||||
}
|
||||
m_pUserParam = param;
|
||||
} else {
|
||||
DXGI = (int)user;
|
||||
}
|
||||
@@ -224,7 +236,7 @@ void CScreenManager::InitScreenSpy()
|
||||
SetThreadDesktop(g_hDesk = hDesk);
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_DELETE(m_ScreenSpyObject);
|
||||
if ((USING_DXGI == DXGI && IsWindows8orHigher())) {
|
||||
m_isGDI = FALSE;
|
||||
auto s = new ScreenCapturerDXGI(algo, DEFAULT_GOP, all);
|
||||
@@ -355,6 +367,7 @@ CScreenManager::~CScreenManager()
|
||||
|
||||
delete m_ScreenSpyObject;
|
||||
m_ScreenSpyObject = NULL;
|
||||
SAFE_DELETE(m_pUserParam);
|
||||
}
|
||||
|
||||
void RunFileReceiver(CScreenManager *mgr, const std::string &folder)
|
||||
@@ -404,6 +417,10 @@ void FinishSend(void* user)
|
||||
VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
{
|
||||
switch(szBuffer[0]) {
|
||||
case COMMAND_SWITCH_SCREEN: {
|
||||
SwitchScreen();
|
||||
break;
|
||||
}
|
||||
case COMMAND_NEXT: {
|
||||
NotifyDialogIsOpen();
|
||||
break;
|
||||
|
||||
@@ -19,6 +19,8 @@ bool IsWindows8orHigher();
|
||||
|
||||
class IOCPClient;
|
||||
|
||||
struct UserParam;
|
||||
|
||||
class CScreenManager : public CManager
|
||||
{
|
||||
public:
|
||||
@@ -37,6 +39,7 @@ public:
|
||||
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;
|
||||
@@ -56,6 +59,8 @@ public:
|
||||
bool IsRunAsService() const {
|
||||
return m_conn ? m_conn->iStartup == Startup_GhostMsc : false;
|
||||
}
|
||||
bool SwitchScreen();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
BOOL m_virtual;
|
||||
POINT m_point;
|
||||
|
||||
@@ -195,6 +195,7 @@ enum {
|
||||
COMMAND_GET_FOLDER = 66, // <20><>ȡĿ¼
|
||||
COMMAND_GET_FILE = 67, // <20><>ȡ<EFBFBD>ļ<EFBFBD>
|
||||
COMMAND_SEND_FILE = 68, // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||
COMMAND_SWITCH_SCREEN = 69,
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><EFBFBD>ı<EFBFBD>ʶ
|
||||
TOKEN_AUTH = 100, // Ҫ<><D2AA><EFBFBD><EFBFBD>֤
|
||||
|
||||
@@ -26,6 +26,7 @@ enum {
|
||||
IDM_ADAPTIVE_SIZE,
|
||||
IDM_SAVEAVI,
|
||||
IDM_SAVEAVI_H264,
|
||||
IDM_SWITCHSCREEN,
|
||||
};
|
||||
|
||||
IMPLEMENT_DYNAMIC(CScreenSpyDlg, CDialog)
|
||||
@@ -83,6 +84,10 @@ extern "C" char* __imp_strtok(char* str, const char* delim)
|
||||
CScreenSpyDlg::CScreenSpyDlg(CWnd* Parent, Server* IOCPServer, CONTEXT_OBJECT* ContextObject)
|
||||
: DialogBase(CScreenSpyDlg::IDD, Parent, IOCPServer, ContextObject, 0)
|
||||
{
|
||||
m_hFullDC = NULL;
|
||||
m_hFullMemDC = NULL;
|
||||
m_BitmapHandle = NULL;
|
||||
|
||||
m_lastMouseMove = 0;
|
||||
m_lastMousePoint = {};
|
||||
m_pCodec = nullptr;
|
||||
@@ -194,27 +199,38 @@ void CScreenSpyDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
|
||||
CDialog::OnLButtonDblClk(nFlags, point);
|
||||
}
|
||||
|
||||
void CScreenSpyDlg::PrepareDrawing(const LPBITMAPINFO bmp) {
|
||||
if (m_hFullDC) ::ReleaseDC(m_hWnd, m_hFullDC);
|
||||
if (m_hFullMemDC) ::DeleteDC(m_hFullMemDC);
|
||||
if (m_BitmapHandle) ::DeleteObject(m_BitmapHandle);
|
||||
m_BitmapData_Full = NULL;
|
||||
|
||||
CString strString;
|
||||
strString.Format("%s - 远程桌面控制 %d×%d", m_IPAddress, bmp->bmiHeader.biWidth, bmp->bmiHeader.biHeight);
|
||||
SetWindowText(strString);
|
||||
|
||||
m_hFullDC = ::GetDC(m_hWnd);
|
||||
SetStretchBltMode(m_hFullDC, HALFTONE);
|
||||
SetBrushOrgEx(m_hFullDC, 0, 0, NULL);
|
||||
m_hFullMemDC = CreateCompatibleDC(m_hFullDC);
|
||||
m_BitmapHandle = CreateDIBSection(m_hFullDC, bmp, DIB_RGB_COLORS, &m_BitmapData_Full, NULL, NULL);
|
||||
|
||||
SelectObject(m_hFullMemDC, m_BitmapHandle);
|
||||
|
||||
SetScrollRange(SB_HORZ, 0, bmp->bmiHeader.biWidth);
|
||||
SetScrollRange(SB_VERT, 0, bmp->bmiHeader.biHeight);
|
||||
|
||||
GetClientRect(&m_CRect);
|
||||
m_wZoom = ((double)bmp->bmiHeader.biWidth) / ((double)(m_CRect.Width()));
|
||||
m_hZoom = ((double)bmp->bmiHeader.biHeight) / ((double)(m_CRect.Height()));
|
||||
}
|
||||
|
||||
BOOL CScreenSpyDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
SetIcon(m_hIcon,FALSE);
|
||||
|
||||
CString strString;
|
||||
strString.Format("%s - 远程桌面控制 %d×%d", m_IPAddress,
|
||||
m_BitmapInfor_Full->bmiHeader.biWidth, m_BitmapInfor_Full->bmiHeader.biHeight);
|
||||
SetWindowText(strString);
|
||||
|
||||
m_hFullDC = ::GetDC(m_hWnd);
|
||||
SetStretchBltMode(m_hFullDC, HALFTONE);
|
||||
SetBrushOrgEx(m_hFullDC, 0, 0, NULL);
|
||||
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);//择一对象到指定的设备上下文环境
|
||||
|
||||
SetScrollRange(SB_HORZ, 0, m_BitmapInfor_Full->bmiHeader.biWidth); //指定滚动条范围的最小值和最大值
|
||||
SetScrollRange(SB_VERT, 0, m_BitmapInfor_Full->bmiHeader.biHeight);//1366 768
|
||||
PrepareDrawing(m_BitmapInfor_Full);
|
||||
|
||||
CMenu* SysMenu = GetSystemMenu(FALSE);
|
||||
if (SysMenu != NULL) {
|
||||
@@ -231,7 +247,11 @@ BOOL CScreenSpyDlg::OnInitDialog()
|
||||
SysMenu->AppendMenu(MF_SEPARATOR);
|
||||
SysMenu->AppendMenu(MF_STRING, IDM_GET_CLIPBOARD, "获取剪贴板(&R)");
|
||||
SysMenu->AppendMenu(MF_STRING, IDM_SET_CLIPBOARD, "设置剪贴板(&L)");
|
||||
SysMenu->AppendMenu(MF_STRING, IDM_SWITCHSCREEN, "切换显示器(&M)");
|
||||
SysMenu->AppendMenu(MF_SEPARATOR);
|
||||
|
||||
BOOL all = THIS_CFG.GetInt("settings", "MultiScreen");
|
||||
SysMenu->EnableMenuItem(IDM_SWITCHSCREEN, all ? MF_ENABLED : MF_GRAYED);
|
||||
}
|
||||
|
||||
m_bIsCtrl = THIS_CFG.GetInt("settings", "DXGI") == USING_VIRTUAL;
|
||||
@@ -246,10 +266,6 @@ BOOL CScreenSpyDlg::OnInitDialog()
|
||||
SysMenu->CheckMenuItem(IDM_CONTROL, m_bIsCtrl ? MF_CHECKED : MF_UNCHECKED);
|
||||
SysMenu->CheckMenuItem(IDM_ADAPTIVE_SIZE, m_bAdaptiveSize ? MF_CHECKED : MF_UNCHECKED);
|
||||
SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO));
|
||||
|
||||
GetClientRect(&m_CRect);
|
||||
m_wZoom = ((double)m_BitmapInfor_Full->bmiHeader.biWidth) / ((double)(m_CRect.Width()));
|
||||
m_hZoom = ((double)m_BitmapInfor_Full->bmiHeader.biHeight) / ((double)(m_CRect.Height()));
|
||||
ShowScrollBar(SB_BOTH, !m_bAdaptiveSize);
|
||||
|
||||
SendNext();
|
||||
@@ -323,6 +339,14 @@ VOID CScreenSpyDlg::OnReceiveComplete()
|
||||
UpdateServerClipboard(str.c_str(), str.length());
|
||||
break;
|
||||
}
|
||||
case TOKEN_BITMAPINFO: {
|
||||
SAFE_DELETE(m_BitmapInfor_Full);
|
||||
ULONG ulBitmapInforLength = m_ContextObject->InDeCompressedBuffer.GetBufferLength() - 1;
|
||||
m_BitmapInfor_Full = (BITMAPINFO*) new BYTE[ulBitmapInforLength];
|
||||
m_ContextObject->InDeCompressedBuffer.CopyBuffer(m_BitmapInfor_Full, ulBitmapInforLength, 1);
|
||||
PrepareDrawing(m_BitmapInfor_Full);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
TRACE("CScreenSpyDlg unknown command: %d!!!\n", int(cmd));
|
||||
}
|
||||
@@ -611,7 +635,13 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case IDM_SWITCHSCREEN: {
|
||||
BYTE bToken[2] = { COMMAND_SWITCH_SCREEN };
|
||||
m_ContextObject->Send2Client(bToken, sizeof(bToken));
|
||||
break;
|
||||
}
|
||||
|
||||
case IDM_TRACE_CURSOR: { // 跟踪被控端鼠标
|
||||
m_bIsTraceCursor = !m_bIsTraceCursor; //这里在改变数据
|
||||
SysMenu->CheckMenuItem(IDM_TRACE_CURSOR, m_bIsTraceCursor ? MF_CHECKED : MF_UNCHECKED);//在菜单打钩不打钩
|
||||
|
||||
@@ -122,6 +122,7 @@ protected:
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
public:
|
||||
void PrepareDrawing(const LPBITMAPINFO bmp);
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnClose();
|
||||
afx_msg void OnPaint();
|
||||
|
||||
Reference in New Issue
Block a user