在WinCE 6.0上使用远程桌面控件

1 篇文章 0 订阅
1 篇文章 0 订阅

说明:这个程序是从命令行执行的,解析命令行传入的参数信息,执行远程桌面连接。只描述实现过程,不讨论实现原理。

1. 打开VS 2005,新建一个“MFC智能设备应用程序”项目

2. 在应用程序类型处选择“单文档”;取消“文档/视图结构支持”;选择“在共享库中使用MFC”
3. 在高级功能处选上“ActiveX控件”和“Windows套接字”
4. 项目新建完成后,从项目源文件中排除"ChildView.h"和“ChildView.cpp”

5. 打开"MainFrm.h",删除这两个成员变量

protected:  // 控件条嵌入成员
	//CCommandBar m_wndCommandBar;
	//CChildView    m_wndView;

 

6. 修改以下三个函数函数,注释掉无用的代码

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
#if 0
	// 创建一个视图以占用框架的工作区
	if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
		CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
	{
		TRACE0("未能创建视图窗口\n");
		return -1;
	}


	if (!m_wndCommandBar.Create(this) ||
	    !m_wndCommandBar.InsertMenuBar(IDR_MAINFRAME) ||
	    !m_wndCommandBar.AddAdornments(dwAdornmentFlags))
	{
		TRACE0("未能创建 CommandBar\n");
		return -1;      // 未能创建
	}

	m_wndCommandBar.SetBarStyle(m_wndCommandBar.GetBarStyle() | CBRS_SIZE_FIXED);
#endif


	return 0;
}


 

void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
{
	// 将焦点前移到视图窗口
#if 0
	m_wndView.SetFocus();
#endif
}

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
	// 让视图第一次尝试该命令
#if 0
	if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;
#endif

	// 否则,执行默认处理
	return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
注意:“return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);”这行代码不能删除,否则无法接收控件事件。

此时项目应该可以编译运行了。我们继续。

7.  代开 “stdafx.h”文件,在“#include <afxdisp.h>” 这行下面添加以下代码
#include <mstsax.h>

#include <urlmon.h>

#include <shlobj.h>

#include <winnetwk.h>

8. 打开"MainFrm.h"文件,在CMainFrame类中添加以下定义
public:
	IMsRdpClient  *m_pMsTsc;
	IMsRdpClientNonScriptable3 *pns;
	IMsRdpClientSecuredSettings *pss;
	IMsRdpClientAdvancedSettings *padv;

	CWnd		m_wndMsTsc;

	void RegisterMstscax();
	void UnRegisterMstscax();
	void OnConnecting();
	void OnDisconnected(long discReason);
	void OnEnterFullScreenMode();
	void OnLeaveFullScreenMode();
	void OnLoginComplete();
	void OnConnected();
	void OnRequestGoFullScreen();
	void OnRequestLeaveFullScreen();
	void OnLogonError(long lError);
	void ShowTaskBar(BOOL show);
	int MstscConnect(void);
9. 修改CMainFrame类中的 “// 生成的消息映射函数” 注释下面的代码为
// 生成的消息映射函数
protected:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnSetFocus(CWnd *pOldWnd);
	afx_msg void OnSize(UINT nType,int x,int y);

	DECLARE_MESSAGE_MAP()
	DECLARE_EVENTSINK_MAP() 
添加了“OnSize”消息处理函数声明和“DECLARE_EVENTSINK_MAP() ”控件消息映射
10. 修改MainFrm.cpp,在消息映射宏里添加“ON_WM_SIZE()”
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_SETFOCUS()
	ON_WM_SIZE()
END_MESSAGE_MAP()
11. 在MainFrm.cpp中增加控件事件映射宏
BEGIN_EVENTSINK_MAP(CMainFrame, CFrameWnd)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 1, CMainFrame::OnConnecting, VTS_NONE)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 4, CMainFrame::OnDisconnected, VTS_I4)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 5, CMainFrame::OnEnterFullScreenMode, VTS_NONE)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 6, CMainFrame::OnLeaveFullScreenMode, VTS_NONE)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 3, CMainFrame::OnLoginComplete, VTS_NONE)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 2, CMainFrame::OnConnected, VTS_NONE)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 8, CMainFrame::OnRequestGoFullScreen, VTS_NONE)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 9, CMainFrame::OnRequestLeaveFullScreen, VTS_NONE)
	ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 22, CMainFrame::OnLogonError, VTS_I4)
END_EVENTSINK_MAP()

12. 在CMainFrame构造函数中初始化m_pMsTsc为NULL

CMainFrame::CMainFrame()
{
	// TODO: 在此添加成员初始化代码
	m_pMsTsc = NULL;
}


 

13. 在CMainFrame析构函数中释放资源,显示任务栏

CMainFrame::~CMainFrame()
{
	ShowTaskBar(TRUE);
	if(NULL != m_pMsTsc)
	{
		m_pMsTsc->Disconnect();
		m_pMsTsc->Release();
	}
	m_pMsTsc = NULL;
}
14. 实现远程桌面控件事件处理函数
void CMainFrame::OnConnecting()
{
}

void CMainFrame::OnEnterFullScreenMode()
{
	ShowTaskBar(FALSE);
}
void CMainFrame::OnLeaveFullScreenMode()
{
	ShowTaskBar(TRUE);
}

void CMainFrame::OnRequestGoFullScreen()
{
}

void CMainFrame::OnRequestLeaveFullScreen()
{
}

void CMainFrame::OnLoginComplete()
{
	LONG style;

	style = GetWindowLong(GetSafeHwnd(),GWL_STYLE);
	style |= WS_MAXIMIZEBOX;
	style |= WS_MINIMIZEBOX;
	SetWindowLong(GetSafeHwnd(),GWL_STYLE,style);

	m_pMsTsc->put_FullScreen(TRUE);
	ShowTaskBar(FALSE);
}
void CMainFrame::OnConnected()
{
}

void CMainFrame::OnLogonError(long lError)
{
}

void CMainFrame::OnDisconnected(long discReason)
{
	ShowTaskBar(TRUE);
	DestroyWindow();
	if(NULL != m_pMsTsc)
	{
		m_pMsTsc->Disconnect();
		m_pMsTsc->Release();
	}
	m_pMsTsc = NULL;
}
15. 实现OnSize函数
void CMainFrame::OnSize(UINT nType,int cx,int cy)
{
	int IsSet=0;
	if(nType==SIZE_MAXIMIZED)
	{
		m_pMsTsc->put_FullScreen(TRUE);
	}
	else
	{
		if(GetSystemMetrics(SM_CXSCREEN)<cx)
		{
			cx = GetSystemMetrics(SM_CXSCREEN);
			IsSet = 1;
		}
		if(GetSystemMetrics(SM_CYSCREEN)<cy)
		{
			cy = GetSystemMetrics(SM_CYSCREEN);
			IsSet = 1;
		}
		if(IsSet)
		{
			SetWindowPos(NULL,0,0,cx,cy,0);
		}

		if(m_pMsTsc != NULL)
		{
			m_wndMsTsc.SetWindowPos(NULL,0,0,cx,cy,0);
		}
	}
}
16. 实现控件注册、反注册和控件函数
void CMainFrame::UnRegisterMstscax()
{       //装载ActiveX控件
	LPCTSTR pszDllName= TEXT("\\windows\\mstscax.dll"); 

	HINSTANCE hLib = LoadLibrary( pszDllName ); 
	if (hLib == NULL) 
	{ 
		//AfxMessageBox( _T( "不能载入Dll文件!" ) ); 
		return; 
	} 

	//获取反注册函数 DllUnregisterServer 地址 
	FARPROC lpDllEntryPoint; 
	lpDllEntryPoint = GetProcAddress (hLib,_T( "DllUnregisterServer" )); 

	//调用注册函数 DllUnregisterServer 
	if( lpDllEntryPoint != NULL ) 
	{
		if( FAILED((*lpDllEntryPoint)()) ) 
		{ 
			//AfxMessageBox( _T( "调用 DllUnregisterServer 失败!" ) ); 
			FreeLibrary( hLib ); 
			return; 
		}
	}
	//MessageBox(TEXT("调用DllRegisterServer成功!"),TEXT("结果"),MB_OK); 
}
void CMainFrame::RegisterMstscax() 
{ 
	//ActiveX控件的路径及文件名 
	LPCTSTR pszDllName= TEXT("\\windows\\mstscax.dll"); 
	//装载ActiveX控件 
	HINSTANCE hLib = LoadLibrary(pszDllName); 
	if (hLib == NULL) 
	{ 
		MessageBox(TEXT("不能载入Dll文件!"),TEXT("结果"),MB_OK);
		return; 
	} 
	//获取注册函数DllRegisterServer地址 
	FARPROC lpDllEntryPoint;   
	lpDllEntryPoint = GetProcAddress (hLib,TEXT( "DllRegisterServer")); 
	//调用注册函数DllRegisterServer 
	if(lpDllEntryPoint!=NULL) 
	{ 
		if(FAILED((*lpDllEntryPoint)())) 
		{ 
			MessageBox(TEXT("调用Dll Entry失败!"), TEXT("结果"),MB_OK); 
			FreeLibrary(hLib); 
			return; 
		}
		//MessageBox(TEXT("注册成功"),TEXT("结果"),MB_OK); 
	} 
	else
	{ 
		MessageBox(TEXT("调用DllRegisterServer失败!"),TEXT("结果"),MB_OK); 
	}
} 

void CMainFrame::ShowTaskBar(BOOL show)
{
	CWnd *pwndTaskBar;
	pwndTaskBar = FindWindow(TEXT("HHTaskBar"),NULL);
	if(show)
	{
		pwndTaskBar->ShowWindow(SW_NORMAL);
	}
	else
	{
		pwndTaskBar->ShowWindow(SW_HIDE);
	}
	pwndTaskBar->UpdateWindow();
}
#define COMMAND_HELP \
	TEXT("\
-host <host>\r\n\
-port <rdp port>\r\n\
-user <user name>\r\n\
-password <password>\r\n\
-domain <domain>\r\n\
-color <8/15/16>\r\n\
-mode <m/w/l>\r\n\
-audio\r\n\
-comport\r\n\
-printer\r\n\
-regmstsc\r\n\
")
int CMainFrame::MstscConnect(void)
{
	CLSID CLSID_MsRdpClient5={0x4eb2f086,0xc818,0x447e,0xb3,0x2c,0xc5,0x1c,0xe2,0xb3,0x0d,0x31};
	IID IID_IMsRdpClient5={0x4eb5335b,0x6429,0x477d,0xb9,0x22,0xe0,0x6a,0x28,0xec,0xd8,0xbf};

	IID IID_IMsRdpClientNonScriptable3={0xb3378d90,0x0728,0x45c7,0x8e,0xd7,0xb6,0x15,0x9f,0xb9,0x22,0x19};

	TCHAR szServer[64];  // -host
	TCHAR szPort[6]={0,0,0,0,0,0}; // -port
	TCHAR szUserName[128]; // -user
	TCHAR szPassword[128]; // -password
	TCHAR szDomain[128];   // -domain
	TCHAR szColor[3]={0,0,0};// -color
	TCHAR szMode[2]={0,0};   // -mode
	int color=16;
	int port=3389;
	int audio=1;         // -audio 0,local,1 remote
	int comport=0;       // -comport
	int printer=0;       // -printer
	int mode=0x00;       // LAN

	memset(szServer,0,sizeof(szServer));
	memset(szUserName,0,sizeof(szUserName));
	memset(szPassword,0,sizeof(szPassword));
	memset(szDomain,0,sizeof(szDomain));

	LPWSTR Para,p,q=NULL;
	Para = GetCommandLine();
	if(wcslen(Para) < 2)
	{
		MessageBox(COMMAND_HELP,TEXT("参数信息"),MB_OK); 
		EndModalLoop(IDOK);
		return FALSE;
	}
	p = Para;
	while(*p)
	{
		if(iswspace(*p))
		{
			p++;
			continue;
		}

		if(q != NULL)
		{
			while(*p && !iswspace(*p))
			{
				*q++ = *p++;
			}
			q = NULL;
			continue;
		}

		if(0 == wcsncmp(p,TEXT("-host"),5))
		{
			q = szServer;
			p+=5;
		}
		else if(0 == wcsncmp(p,TEXT("-port"),5))
		{
			q = szPort;
			p+=5;
		}
		else if(0 == wcsncmp(p,TEXT("-user"),5))
		{
			q = szUserName;
			p+=5;
		}
		else if(0 == wcsncmp(p,TEXT("-password"),9))
		{
			q = szPassword;
			p+=9;
		}
		else if(0 == wcsncmp(p,TEXT("-domain"),7))
		{
			q = szDomain;
			p+=7;
		}
		else if(0 == wcsncmp(p,TEXT("-mode"),5))
		{
			q = szMode;
			p+=5;
		}
		else if(0 == wcsncmp(p,TEXT("-color"),6))
		{
			q = szColor;
			p+=6;
		}
		else if(0 == wcsncmp(p,TEXT("-audio"),6))
		{
			audio = 0;
			p+=6;
		}
		else if(0 == wcsncmp(p,TEXT("-comport"),8))
		{
			comport = 1;
			p+=8;
		}
		else if(0 == wcsncmp(p,TEXT("-printer"),8))
		{
			printer = 1;
			p+=8;
		}
		else if(0 == wcsncmp(p,TEXT("-regmstsc"),9))
		{
			RegisterMstscax();
			p+=9;
		}
		else
		{
			while(*p && !iswspace(*p))
			{
				p++;
			}			
		}
	}

	if(0 == wcsncmp(szColor,TEXT("8"),1))
	{
		color = 8;
	}
	else if(0 == wcsncmp(szColor,TEXT("15"),2))
	{
		color = 15;
	}

	port = _wtoi(szPort);
	if((port <= 0) || (port > 65535))
	{
		port = 3389;
	}

	if(0 == wcsncmp(szMode,TEXT("m"),1))
	{
		mode = 0x1 + 0x2 + 0x4 + 0x8;
	}
	else if(0 == wcsncmp(szMode,TEXT("w"),1))
	{
		mode = 0x2 + 0x4;
	}

	RECT rectClient;
	GetWindowRect(&rectClient);
	///创建控件
	if (!m_wndMsTsc.CreateControl(CLSID_MsRdpClient5, NULL, WS_VISIBLE, rectClient,this, AFX_IDW_PANE_FIRST))
	{
		DestroyWindow();
		return FALSE;
	}

	///得到指针
	LPUNKNOWN lpUnk = m_wndMsTsc.GetControlUnknown();
	HRESULT hr = lpUnk->QueryInterface(IID_IMsRdpClient5, (void**) &m_pMsTsc);
	if (!SUCCEEDED(hr))
	{
		m_pMsTsc = NULL;
		m_wndMsTsc.DestroyWindow();
		DestroyWindow();
		return FALSE;
	}

	lpUnk->QueryInterface(IID_IMsRdpClientNonScriptable3, (void**) &pns);
	m_pMsTsc->get_SecuredSettings2(&pss);
	m_pMsTsc->get_AdvancedSettings2(&padv);

	m_pMsTsc->put_Server(szServer);
	padv->put_RDPPort(port);
	m_pMsTsc->put_UserName(szUserName);
	pns->put_ClearTextPassword(szPassword);
	m_pMsTsc->put_Domain(szDomain);

	padv->put_RedirectPrinters(printer);
	padv->put_RedirectPorts(comport);
	m_pMsTsc->put_ColorDepth(color);
	pss->put_AudioRedirectionMode(audio);
	//padv->put_PerformanceFlags(mode);

	padv->put_BitmapPersistence(1);
	padv->put_Compress(1);
	m_pMsTsc->put_DesktopWidth(GetSystemMetrics(SM_CXSCREEN));
	m_pMsTsc->put_DesktopHeight(GetSystemMetrics(SM_CYSCREEN));
	m_pMsTsc->put_FullScreen(FALSE);
	//padv->put_ContainerHandledFullScreen(TRUE);
	m_pMsTsc->Connect();
	return 0;
}


17. 在App的InitInstance函数中隐藏主窗口并执行控件连接

	// 唯一的一个窗口已初始化,因此显示它并对其进行更新
	//pFrame->ShowWindow(SW_SHOWMAXIMIZED);
	//pFrame->UpdateWindow();
	pFrame->MstscConnect();
	return TRUE;


到此代码基本准备完成,编译后放到WinCE6.0上应该可以执行远程桌面连接。在某些系统上需要先注册一下Mstscax控件,在命令参数中加入-regmstsc即可,反注册函数没有使用,一般情况下没有这必要。
Good Luck!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值