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

来源:互联网 发布:绩效改进合力矩阵 编辑:程序博客网 时间:2024/05/16 09:04

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

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

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

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

[cpp] view plaincopyprint?
  1. protected:  // 控件条嵌入成员  
  2.     //CCommandBar m_wndCommandBar;  
  3.     //CChildView    m_wndView;  

 

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

[cpp] view plaincopyprint?
  1. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)  
  2. {  
  3.     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)  
  4.         return -1;  
  5. #if 0  
  6.     // 创建一个视图以占用框架的工作区  
  7.     if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,  
  8.         CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))  
  9.     {  
  10.         TRACE0("未能创建视图窗口\n");  
  11.         return -1;  
  12.     }  
  13.   
  14.   
  15.     if (!m_wndCommandBar.Create(this) ||  
  16.         !m_wndCommandBar.InsertMenuBar(IDR_MAINFRAME) ||  
  17.         !m_wndCommandBar.AddAdornments(dwAdornmentFlags))  
  18.     {  
  19.         TRACE0("未能创建 CommandBar\n");  
  20.         return -1;      // 未能创建  
  21.     }  
  22.   
  23.     m_wndCommandBar.SetBarStyle(m_wndCommandBar.GetBarStyle() | CBRS_SIZE_FIXED);  
  24. #endif  
  25.   
  26.   
  27.     return 0;  
  28. }  


 

[cpp] view plaincopyprint?
  1. void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)  
  2. {  
  3.     // 将焦点前移到视图窗口  
  4. #if 0  
  5.     m_wndView.SetFocus();  
  6. #endif  
  7. }  

[cpp] view plaincopyprint?
  1. BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)  
  2. {  
  3.     // 让视图第一次尝试该命令  
  4. #if 0  
  5.     if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))  
  6.         return TRUE;  
  7. #endif  
  8.   
  9.     // 否则,执行默认处理  
  10.     return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);  
  11. }  
注意:“return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);”这行代码不能删除,否则无法接收控件事件。

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

7.  代开 “stdafx.h”文件,在“#include <afxdisp.h>” 这行下面添加以下代码
[cpp] view plaincopyprint?
  1. #include <mstsax.h>  
  2.   
  3. #include <urlmon.h>  
  4.   
  5. #include <shlobj.h>  
  6.   
  7. #include <winnetwk.h>  

8. 打开"MainFrm.h"文件,在CMainFrame类中添加以下定义
[cpp] view plaincopyprint?
  1. public:  
  2.     IMsRdpClient  *m_pMsTsc;  
  3.     IMsRdpClientNonScriptable3 *pns;  
  4.     IMsRdpClientSecuredSettings *pss;  
  5.     IMsRdpClientAdvancedSettings *padv;  
  6.   
  7.     CWnd        m_wndMsTsc;  
  8.   
  9.     void RegisterMstscax();  
  10.     void UnRegisterMstscax();  
  11.     void OnConnecting();  
  12.     void OnDisconnected(long discReason);  
  13.     void OnEnterFullScreenMode();  
  14.     void OnLeaveFullScreenMode();  
  15.     void OnLoginComplete();  
  16.     void OnConnected();  
  17.     void OnRequestGoFullScreen();  
  18.     void OnRequestLeaveFullScreen();  
  19.     void OnLogonError(long lError);  
  20.     void ShowTaskBar(BOOL show);  
  21.     int MstscConnect(void);  
9. 修改CMainFrame类中的 “// 生成的消息映射函数” 注释下面的代码为
[cpp] view plaincopyprint?
  1. // 生成的消息映射函数  
  2. protected:  
  3.     afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);  
  4.     afx_msg void OnSetFocus(CWnd *pOldWnd);  
  5.     afx_msg void OnSize(UINT nType,int x,int y);  
  6.   
  7.     DECLARE_MESSAGE_MAP()  
  8.     DECLARE_EVENTSINK_MAP()   
添加了“OnSize”消息处理函数声明和“DECLARE_EVENTSINK_MAP() ”控件消息映射
10. 修改MainFrm.cpp,在消息映射宏里添加“ON_WM_SIZE()”
[cpp] view plaincopyprint?
  1. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)  
  2.     ON_WM_CREATE()  
  3.     ON_WM_SETFOCUS()  
  4.     ON_WM_SIZE()  
  5. END_MESSAGE_MAP()  
11. 在MainFrm.cpp中增加控件事件映射宏
[cpp] view plaincopyprint?
  1. BEGIN_EVENTSINK_MAP(CMainFrame, CFrameWnd)  
  2.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 1, CMainFrame::OnConnecting, VTS_NONE)  
  3.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 4, CMainFrame::OnDisconnected, VTS_I4)  
  4.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 5, CMainFrame::OnEnterFullScreenMode, VTS_NONE)  
  5.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 6, CMainFrame::OnLeaveFullScreenMode, VTS_NONE)  
  6.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 3, CMainFrame::OnLoginComplete, VTS_NONE)  
  7.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 2, CMainFrame::OnConnected, VTS_NONE)  
  8.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 8, CMainFrame::OnRequestGoFullScreen, VTS_NONE)  
  9.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 9, CMainFrame::OnRequestLeaveFullScreen, VTS_NONE)  
  10.     ON_EVENT(CMainFrame, AFX_IDW_PANE_FIRST, 22, CMainFrame::OnLogonError, VTS_I4)  
  11. END_EVENTSINK_MAP()  

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

[cpp] view plaincopyprint?
  1. CMainFrame::CMainFrame()  
  2. {  
  3.     // TODO: 在此添加成员初始化代码  
  4.     m_pMsTsc = NULL;  
  5. }  


 

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

[cpp] view plaincopyprint?
  1. CMainFrame::~CMainFrame()  
  2. {  
  3.     ShowTaskBar(TRUE);  
  4.     if(NULL != m_pMsTsc)  
  5.     {  
  6.         m_pMsTsc->Disconnect();  
  7.         m_pMsTsc->Release();  
  8.     }  
  9.     m_pMsTsc = NULL;  
  10. }  
14. 实现远程桌面控件事件处理函数
[cpp] view plaincopyprint?
  1. void CMainFrame::OnConnecting()  
  2. {  
  3. }  
  4.   
  5. void CMainFrame::OnEnterFullScreenMode()  
  6. {  
  7.     ShowTaskBar(FALSE);  
  8. }  
  9. void CMainFrame::OnLeaveFullScreenMode()  
  10. {  
  11.     ShowTaskBar(TRUE);  
  12. }  
  13.   
  14. void CMainFrame::OnRequestGoFullScreen()  
  15. {  
  16. }  
  17.   
  18. void CMainFrame::OnRequestLeaveFullScreen()  
  19. {  
  20. }  
  21.   
  22. void CMainFrame::OnLoginComplete()  
  23. {  
  24.     LONG style;  
  25.   
  26.     style = GetWindowLong(GetSafeHwnd(),GWL_STYLE);  
  27.     style |= WS_MAXIMIZEBOX;  
  28.     style |= WS_MINIMIZEBOX;  
  29.     SetWindowLong(GetSafeHwnd(),GWL_STYLE,style);  
  30.   
  31.     m_pMsTsc->put_FullScreen(TRUE);  
  32.     ShowTaskBar(FALSE);  
  33. }  
  34. void CMainFrame::OnConnected()  
  35. {  
  36. }  
  37.   
  38. void CMainFrame::OnLogonError(long lError)  
  39. {  
  40. }  
  41.   
  42. void CMainFrame::OnDisconnected(long discReason)  
  43. {  
  44.     ShowTaskBar(TRUE);  
  45.     DestroyWindow();  
  46.     if(NULL != m_pMsTsc)  
  47.     {  
  48.         m_pMsTsc->Disconnect();  
  49.         m_pMsTsc->Release();  
  50.     }  
  51.     m_pMsTsc = NULL;  
  52. }  
15. 实现OnSize函数
[cpp] view plaincopyprint?
  1. void CMainFrame::OnSize(UINT nType,int cx,int cy)  
  2. {  
  3.     int IsSet=0;  
  4.     if(nType==SIZE_MAXIMIZED)  
  5.     {  
  6.         m_pMsTsc->put_FullScreen(TRUE);  
  7.     }  
  8.     else  
  9.     {  
  10.         if(GetSystemMetrics(SM_CXSCREEN)<cx)  
  11.         {  
  12.             cx = GetSystemMetrics(SM_CXSCREEN);  
  13.             IsSet = 1;  
  14.         }  
  15.         if(GetSystemMetrics(SM_CYSCREEN)<cy)  
  16.         {  
  17.             cy = GetSystemMetrics(SM_CYSCREEN);  
  18.             IsSet = 1;  
  19.         }  
  20.         if(IsSet)  
  21.         {  
  22.             SetWindowPos(NULL,0,0,cx,cy,0);  
  23.         }  
  24.   
  25.         if(m_pMsTsc != NULL)  
  26.         {  
  27.             m_wndMsTsc.SetWindowPos(NULL,0,0,cx,cy,0);  
  28.         }  
  29.     }  
  30. }  
16. 实现控件注册、反注册和控件函数
[cpp] view plaincopyprint?
  1. void CMainFrame::UnRegisterMstscax()  
  2. {       //装载ActiveX控件  
  3.     LPCTSTR pszDllName= TEXT("\\windows\\mstscax.dll");   
  4.   
  5.     HINSTANCE hLib = LoadLibrary( pszDllName );   
  6.     if (hLib == NULL)   
  7.     {   
  8.         //AfxMessageBox( _T( "不能载入Dll文件!" ) );   
  9.         return;   
  10.     }   
  11.   
  12.     //获取反注册函数 DllUnregisterServer 地址   
  13.     FARPROC lpDllEntryPoint;   
  14.     lpDllEntryPoint = GetProcAddress (hLib,_T( "DllUnregisterServer" ));   
  15.   
  16.     //调用注册函数 DllUnregisterServer   
  17.     if( lpDllEntryPoint != NULL )   
  18.     {  
  19.         if( FAILED((*lpDllEntryPoint)()) )   
  20.         {   
  21.             //AfxMessageBox( _T( "调用 DllUnregisterServer 失败!" ) );   
  22.             FreeLibrary( hLib );   
  23.             return;   
  24.         }  
  25.     }  
  26.     //MessageBox(TEXT("调用DllRegisterServer成功!"),TEXT("结果"),MB_OK);   
  27. }  
  28. void CMainFrame::RegisterMstscax()   
  29. {   
  30.     //ActiveX控件的路径及文件名   
  31.     LPCTSTR pszDllName= TEXT("\\windows\\mstscax.dll");   
  32.     //装载ActiveX控件   
  33.     HINSTANCE hLib = LoadLibrary(pszDllName);   
  34.     if (hLib == NULL)   
  35.     {   
  36.         MessageBox(TEXT("不能载入Dll文件!"),TEXT("结果"),MB_OK);  
  37.         return;   
  38.     }   
  39.     //获取注册函数DllRegisterServer地址   
  40.     FARPROC lpDllEntryPoint;     
  41.     lpDllEntryPoint = GetProcAddress (hLib,TEXT( "DllRegisterServer"));   
  42.     //调用注册函数DllRegisterServer   
  43.     if(lpDllEntryPoint!=NULL)   
  44.     {   
  45.         if(FAILED((*lpDllEntryPoint)()))   
  46.         {   
  47.             MessageBox(TEXT("调用Dll Entry失败!"), TEXT("结果"),MB_OK);   
  48.             FreeLibrary(hLib);   
  49.             return;   
  50.         }  
  51.         //MessageBox(TEXT("注册成功"),TEXT("结果"),MB_OK);   
  52.     }   
  53.     else  
  54.     {   
  55.         MessageBox(TEXT("调用DllRegisterServer失败!"),TEXT("结果"),MB_OK);   
  56.     }  
  57. }   
  58.   
  59. void CMainFrame::ShowTaskBar(BOOL show)  
  60. {  
  61.     CWnd *pwndTaskBar;  
  62.     pwndTaskBar = FindWindow(TEXT("HHTaskBar"),NULL);  
  63.     if(show)  
  64.     {  
  65.         pwndTaskBar->ShowWindow(SW_NORMAL);  
  66.     }  
  67.     else  
  68.     {  
  69.         pwndTaskBar->ShowWindow(SW_HIDE);  
  70.     }  
  71.     pwndTaskBar->UpdateWindow();  
  72. }  
  73. #define COMMAND_HELP \  
  74.     TEXT("\  
  75. -host <host>\r\n\  
  76. -port <rdp port>\r\n\  
  77. -user <user name>\r\n\  
  78. -password <password>\r\n\  
  79. -domain <domain>\r\n\  
  80. -color <8/15/16>\r\n\  
  81. -mode <m/w/l>\r\n\  
  82. -audio\r\n\  
  83. -comport\r\n\  
  84. -printer\r\n\  
  85. -regmstsc\r\n\  
  86. ")  
  87. int CMainFrame::MstscConnect(void)  
  88. {  
  89.     CLSID CLSID_MsRdpClient5={0x4eb2f086,0xc818,0x447e,0xb3,0x2c,0xc5,0x1c,0xe2,0xb3,0x0d,0x31};  
  90.     IID IID_IMsRdpClient5={0x4eb5335b,0x6429,0x477d,0xb9,0x22,0xe0,0x6a,0x28,0xec,0xd8,0xbf};  
  91.   
  92.     IID IID_IMsRdpClientNonScriptable3={0xb3378d90,0x0728,0x45c7,0x8e,0xd7,0xb6,0x15,0x9f,0xb9,0x22,0x19};  
  93.   
  94.     TCHAR szServer[64];  // -host  
  95.     TCHAR szPort[6]={0,0,0,0,0,0}; // -port  
  96.     TCHAR szUserName[128]; // -user  
  97.     TCHAR szPassword[128]; // -password  
  98.     TCHAR szDomain[128];   // -domain  
  99.     TCHAR szColor[3]={0,0,0};// -color  
  100.     TCHAR szMode[2]={0,0};   // -mode  
  101.     int color=16;  
  102.     int port=3389;  
  103.     int audio=1;         // -audio 0,local,1 remote  
  104.     int comport=0;       // -comport  
  105.     int printer=0;       // -printer  
  106.     int mode=0x00;       // LAN  
  107.   
  108.     memset(szServer,0,sizeof(szServer));  
  109.     memset(szUserName,0,sizeof(szUserName));  
  110.     memset(szPassword,0,sizeof(szPassword));  
  111.     memset(szDomain,0,sizeof(szDomain));  
  112.   
  113.     LPWSTR Para,p,q=NULL;  
  114.     Para = GetCommandLine();  
  115.     if(wcslen(Para) < 2)  
  116.     {  
  117.         MessageBox(COMMAND_HELP,TEXT("参数信息"),MB_OK);   
  118.         EndModalLoop(IDOK);  
  119.         return FALSE;  
  120.     }  
  121.     p = Para;  
  122.     while(*p)  
  123.     {  
  124.         if(iswspace(*p))  
  125.         {  
  126.             p++;  
  127.             continue;  
  128.         }  
  129.   
  130.         if(q != NULL)  
  131.         {  
  132.             while(*p && !iswspace(*p))  
  133.             {  
  134.                 *q++ = *p++;  
  135.             }  
  136.             q = NULL;  
  137.             continue;  
  138.         }  
  139.   
  140.         if(0 == wcsncmp(p,TEXT("-host"),5))  
  141.         {  
  142.             q = szServer;  
  143.             p+=5;  
  144.         }  
  145.         else if(0 == wcsncmp(p,TEXT("-port"),5))  
  146.         {  
  147.             q = szPort;  
  148.             p+=5;  
  149.         }  
  150.         else if(0 == wcsncmp(p,TEXT("-user"),5))  
  151.         {  
  152.             q = szUserName;  
  153.             p+=5;  
  154.         }  
  155.         else if(0 == wcsncmp(p,TEXT("-password"),9))  
  156.         {  
  157.             q = szPassword;  
  158.             p+=9;  
  159.         }  
  160.         else if(0 == wcsncmp(p,TEXT("-domain"),7))  
  161.         {  
  162.             q = szDomain;  
  163.             p+=7;  
  164.         }  
  165.         else if(0 == wcsncmp(p,TEXT("-mode"),5))  
  166.         {  
  167.             q = szMode;  
  168.             p+=5;  
  169.         }  
  170.         else if(0 == wcsncmp(p,TEXT("-color"),6))  
  171.         {  
  172.             q = szColor;  
  173.             p+=6;  
  174.         }  
  175.         else if(0 == wcsncmp(p,TEXT("-audio"),6))  
  176.         {  
  177.             audio = 0;  
  178.             p+=6;  
  179.         }  
  180.         else if(0 == wcsncmp(p,TEXT("-comport"),8))  
  181.         {  
  182.             comport = 1;  
  183.             p+=8;  
  184.         }  
  185.         else if(0 == wcsncmp(p,TEXT("-printer"),8))  
  186.         {  
  187.             printer = 1;  
  188.             p+=8;  
  189.         }  
  190.         else if(0 == wcsncmp(p,TEXT("-regmstsc"),9))  
  191.         {  
  192.             RegisterMstscax();  
  193.             p+=9;  
  194.         }  
  195.         else  
  196.         {  
  197.             while(*p && !iswspace(*p))  
  198.             {  
  199.                 p++;  
  200.             }             
  201.         }  
  202.     }  
  203.   
  204.     if(0 == wcsncmp(szColor,TEXT("8"),1))  
  205.     {  
  206.         color = 8;  
  207.     }  
  208.     else if(0 == wcsncmp(szColor,TEXT("15"),2))  
  209.     {  
  210.         color = 15;  
  211.     }  
  212.   
  213.     port = _wtoi(szPort);  
  214.     if((port <= 0) || (port > 65535))  
  215.     {  
  216.         port = 3389;  
  217.     }  
  218.   
  219.     if(0 == wcsncmp(szMode,TEXT("m"),1))  
  220.     {  
  221.         mode = 0x1 + 0x2 + 0x4 + 0x8;  
  222.     }  
  223.     else if(0 == wcsncmp(szMode,TEXT("w"),1))  
  224.     {  
  225.         mode = 0x2 + 0x4;  
  226.     }  
  227.   
  228.     RECT rectClient;  
  229.     GetWindowRect(&rectClient);  
  230.     ///创建控件  
  231.     if (!m_wndMsTsc.CreateControl(CLSID_MsRdpClient5, NULL, WS_VISIBLE, rectClient,this, AFX_IDW_PANE_FIRST))  
  232.     {  
  233.         DestroyWindow();  
  234.         return FALSE;  
  235.     }  
  236.   
  237.     ///得到指针  
  238.     LPUNKNOWN lpUnk = m_wndMsTsc.GetControlUnknown();  
  239.     HRESULT hr = lpUnk->QueryInterface(IID_IMsRdpClient5, (void**) &m_pMsTsc);  
  240.     if (!SUCCEEDED(hr))  
  241.     {  
  242.         m_pMsTsc = NULL;  
  243.         m_wndMsTsc.DestroyWindow();  
  244.         DestroyWindow();  
  245.         return FALSE;  
  246.     }  
  247.   
  248.     lpUnk->QueryInterface(IID_IMsRdpClientNonScriptable3, (void**) &pns);  
  249.     m_pMsTsc->get_SecuredSettings2(&pss);  
  250.     m_pMsTsc->get_AdvancedSettings2(&padv);  
  251.   
  252.     m_pMsTsc->put_Server(szServer);  
  253.     padv->put_RDPPort(port);  
  254.     m_pMsTsc->put_UserName(szUserName);  
  255.     pns->put_ClearTextPassword(szPassword);  
  256.     m_pMsTsc->put_Domain(szDomain);  
  257.   
  258.     padv->put_RedirectPrinters(printer);  
  259.     padv->put_RedirectPorts(comport);  
  260.     m_pMsTsc->put_ColorDepth(color);  
  261.     pss->put_AudioRedirectionMode(audio);  
  262.     //padv->put_PerformanceFlags(mode);  
  263.   
  264.     padv->put_BitmapPersistence(1);  
  265.     padv->put_Compress(1);  
  266.     m_pMsTsc->put_DesktopWidth(GetSystemMetrics(SM_CXSCREEN));  
  267.     m_pMsTsc->put_DesktopHeight(GetSystemMetrics(SM_CYSCREEN));  
  268.     m_pMsTsc->put_FullScreen(FALSE);  
  269.     //padv->put_ContainerHandledFullScreen(TRUE);  
  270.     m_pMsTsc->Connect();  
  271.     return 0;  
  272. }  


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

[cpp] view plaincopyprint?
  1. // 唯一的一个窗口已初始化,因此显示它并对其进行更新  
  2. //pFrame->ShowWindow(SW_SHOWMAXIMIZED);  
  3. //pFrame->UpdateWindow();  
  4. pFrame->MstscConnect();  
  5. return TRUE;  


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


http://blog.csdn.net/ssmile/article/details/7642511