Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

602 lines
11 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. RemoteDesktopClientSession
  5. Abstract:
  6. RemoteDesktopClientSession manages the client side GUI for the application
  7. hostiving the Salem ActiveX control.
  8. Author:
  9. Marc Reyhner 7/11/2000
  10. --*/
  11. #include "stdafx.h"
  12. #ifdef TRC_FILE
  13. #undef TRC_FILE
  14. #endif
  15. #define TRC_FILE "rcrdcs"
  16. #include "RemoteDesktopClientSession.h"
  17. #include "RemoteDesktopClientEventSink.h"
  18. #include "resource.h"
  19. #include "exception.h"
  20. //
  21. // The guid for the ActiveX control we are creating the child window for.
  22. //
  23. #define REMOTEDESKTOPHOST_TEXTGUID TEXT("{299BE050-E83E-4DB7-A7DA-D86FDEBFE6D0}")
  24. CRemoteDesktopClientSession::CRemoteDesktopClientSession(
  25. IN OUT HINSTANCE hInstance
  26. )
  27. /*++
  28. Routine Description:
  29. The only thing the constructor does is to save hInstance and to
  30. set gm_Session to be this class.
  31. Arguments:
  32. hInstance - The instance for this module.
  33. Return value:
  34. None.
  35. --*/
  36. {
  37. DC_BEGIN_FN("CRemoteDesktopClientSession::CRemoteDesktopClientSession");
  38. m_hWnd = NULL;
  39. m_hRdcHostWnd = NULL;
  40. m_RemDeskClient = NULL;
  41. m_Sink = NULL;
  42. m_hInstance = hInstance;
  43. DC_END_FN();
  44. }
  45. CRemoteDesktopClientSession::~CRemoteDesktopClientSession(
  46. )
  47. /*++
  48. Routine Description:
  49. We just NULL the gm_Session pointer here since everything else
  50. was already cleaned up.
  51. Arguments:
  52. None.
  53. Return value:
  54. None.
  55. --*/
  56. {
  57. DC_BEGIN_FN("CRemoteDesktopClientSession::~CRemoteDesktopClientSession");
  58. DC_END_FN();
  59. }
  60. VOID
  61. CRemoteDesktopClientSession::DoClientSession(
  62. IN BSTR parms
  63. )
  64. /*++
  65. Routine Description:
  66. Here we start and manage the entire client GUI.
  67. Arguments:
  68. parms - The string needed for Salem to connect to the remote server.
  69. Return value:
  70. None.
  71. --*/
  72. {
  73. DC_BEGIN_FN("CRemoteDesktopClientSession::DoClientSession");
  74. HRESULT hr;
  75. ATOM atom;
  76. TCHAR wndTitle[MAX_STR_LEN];
  77. HICON wndIcon = (HICON)LoadImage(m_hInstance,MAKEINTRESOURCE(IDI_TRAYICON),
  78. IMAGE_ICON,0,0,0);
  79. WNDCLASS wndClass = { CS_PARENTDC, _WindowProc, 0, 0, m_hInstance, wndIcon, NULL,
  80. (HBRUSH)COLOR_WINDOWFRAME,MAKEINTRESOURCE(IDR_CLIENTMENU),TEXT("RdcWndClass") };
  81. AtlAxWinInit();
  82. atom = RegisterClass(&wndClass);
  83. if (!atom) {
  84. TRC_ERR((TB,TEXT("Error registering window class for main frame.")));
  85. goto FAILURE;
  86. }
  87. LoadStringSimple(IDS_CLIENTWNDTITLE,wndTitle);
  88. m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,(LPCTSTR)atom,wndTitle,
  89. WS_VISIBLE|WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
  90. 50,50,690,530,NULL,NULL,m_hInstance,this);
  91. if (!m_hWnd) {
  92. TRC_ERR((TB,TEXT("Error creating main frame.")));
  93. goto FAILURE;
  94. }
  95. SetForegroundWindow(m_hWnd);
  96. m_Sink = new CRemoteDesktopClientEventSink(this);
  97. if (!m_Sink) {
  98. TRC_ERR((TB,TEXT("Error creating client event sink.")));
  99. goto FAILURE;
  100. }
  101. hr = m_Sink->DispEventAdvise(m_RemDeskClient);
  102. if (hr != S_OK) {
  103. goto FAILURE;
  104. }
  105. hr = m_RemDeskClient->put_ConnectParms(parms);
  106. if (hr != S_OK) {
  107. goto FAILURE;
  108. }
  109. hr = m_RemDeskClient->ConnectToServer(NULL);
  110. if (hr != S_OK) {
  111. goto FAILURE;
  112. }
  113. DoMessageLoop();
  114. delete m_Sink;
  115. m_Sink = NULL;
  116. DestroyIcon(wndIcon);
  117. DC_END_FN();
  118. return;
  119. FAILURE:
  120. throw CException(IDS_CLIENTERRORCREATE);
  121. }
  122. LRESULT CALLBACK
  123. CRemoteDesktopClientSession::_WindowProc(
  124. IN OUT HWND hWnd,
  125. IN UINT uMsg,
  126. IN WPARAM wParam,
  127. IN LPARAM lParam
  128. )
  129. /*++
  130. Routine Description:
  131. The window proc calls the appropriate message handler for the messages
  132. that we care about.
  133. Arguments:
  134. hWnd - The window the message is for.
  135. uMsg - The message.
  136. wParam - WPARAM for the message.
  137. lParam - LPARAM for the message.
  138. Return value:
  139. LRESULT - The message specific return code. See MSDN for details.
  140. --*/
  141. {
  142. LRESULT retValue = 0;
  143. CRemoteDesktopClientSession *session;
  144. DC_BEGIN_FN("CRemoteDesktopClientSession::_WindowProc");
  145. if (uMsg != WM_CREATE) {
  146. session = (CRemoteDesktopClientSession*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
  147. }
  148. switch (uMsg) {
  149. case WM_CREATE:
  150. session = (CRemoteDesktopClientSession*)
  151. ((LPCREATESTRUCT)lParam)->lpCreateParams;
  152. SetWindowLongPtr(hWnd,GWLP_USERDATA,(long)session);
  153. retValue = session->OnCreate(hWnd);
  154. break;
  155. case WM_COMMAND:
  156. if (session) {
  157. retValue = session->OnCommand(wParam,lParam);
  158. }
  159. break;
  160. case WM_DESTROY:
  161. if (session) {
  162. session->OnDestroy();
  163. }
  164. break;
  165. case WM_SETFOCUS:
  166. if (session) {
  167. session->OnSetFocus();
  168. }
  169. break;
  170. case WM_SIZE:
  171. if (session) {
  172. session->OnSize(LOWORD(lParam),HIWORD(lParam));
  173. }
  174. break;
  175. default:
  176. retValue = DefWindowProc(hWnd,uMsg,wParam,lParam);
  177. }
  178. DC_END_FN();
  179. return retValue;
  180. }
  181. VOID
  182. CRemoteDesktopClientSession::DoMessageLoop(
  183. )
  184. /*++
  185. Routine Description:
  186. This runs through your normal event loop until we get a WM_QUIT.
  187. Any dialogs that messages should be caught for need to be inserted
  188. into this function.
  189. Arguments:
  190. None.
  191. Return value:
  192. None.
  193. --*/
  194. {
  195. MSG msg;
  196. DC_BEGIN_FN("CRemoteDesktopClientSession::DoMessageLoop");
  197. while (GetMessage(&msg,NULL,0,0)>0) {
  198. if (!m_AboutDlg.DialogMessage(&msg) && !m_ApprovalDlg.DialogMessage(&msg)) {
  199. TranslateMessage(&msg);
  200. DispatchMessage(&msg);
  201. }
  202. }
  203. DC_END_FN();
  204. }
  205. LRESULT
  206. CRemoteDesktopClientSession::OnCreate(
  207. IN OUT HWND hWnd
  208. )
  209. /*++
  210. Routine Description:
  211. When the window is being created we create the child window and get a pointer
  212. to the IRemoteDesktopClient for the control. If there is a problem we return
  213. -1 and the window is not created.
  214. Arguments:
  215. hWnd - The window being created.
  216. Return value:
  217. 0 - The window was created correctly.
  218. -1 - There was an error creating the window.
  219. --*/
  220. {
  221. HRESULT hr;
  222. IUnknown *pUnk = NULL;
  223. ISAFRemoteDesktopClientHost *remClientHost = NULL;
  224. DC_BEGIN_FN("CRemoteDesktopClientSession::OnCreate");
  225. m_hRdcHostWnd = CreateWindow(TEXT("AtlAxWin"),REMOTEDESKTOPHOST_TEXTGUID,
  226. WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,0,0,0,0,hWnd,NULL,m_hInstance,NULL);
  227. if (!m_hRdcHostWnd) {
  228. TRC_ERR((TB,TEXT("Error creating Salem window.")));
  229. goto FAILURE;
  230. }
  231. hr = AtlAxGetControl(m_hRdcHostWnd,&pUnk);
  232. if (hr != S_OK) {
  233. TRC_ERR((TB,TEXT("Error getting IUnknown from salem window.")));
  234. goto FAILURE;
  235. }
  236. hr = pUnk->QueryInterface(__uuidof(ISAFRemoteDesktopClientHost),(LPVOID*)&remClientHost);
  237. if (hr != S_OK) {
  238. TRC_ERR((TB,TEXT("Error getting IRemoteDesktopClientHost from Salem control.")));
  239. goto FAILURE;
  240. }
  241. pUnk->Release();
  242. pUnk = NULL;
  243. hr = remClientHost->GetRemoteDesktopClient(&m_RemDeskClient);
  244. if (hr != S_OK) {
  245. TRC_ERR((TB,TEXT("Error gettin IRemoteDesktopClient from host.")));
  246. goto FAILURE;
  247. }
  248. remClientHost->Release();
  249. remClientHost = NULL;
  250. DC_END_FN();
  251. return 0;
  252. FAILURE:
  253. if (m_hRdcHostWnd) {
  254. DestroyWindow(m_hRdcHostWnd);
  255. m_hRdcHostWnd = NULL;
  256. }
  257. if (pUnk) {
  258. pUnk->Release();
  259. pUnk = NULL;
  260. }
  261. if (remClientHost) {
  262. remClientHost->Release();
  263. remClientHost = NULL;
  264. }
  265. return -1;
  266. }
  267. VOID
  268. CRemoteDesktopClientSession::OnSize(
  269. IN WORD width,
  270. IN WORD height
  271. )
  272. /*++
  273. Routine Description:
  274. We keep the child window the same as our new size.
  275. Arguments:
  276. None.
  277. Return value:
  278. None.
  279. --*/
  280. {
  281. DC_BEGIN_FN("CRemoteDesktopClientSession::OnSize");
  282. SetWindowPos(m_hRdcHostWnd,NULL,0,0,width,height,SWP_NOZORDER);
  283. DC_END_FN();
  284. }
  285. VOID
  286. CRemoteDesktopClientSession::ConnectRemoteDesktop(
  287. )
  288. /*++
  289. Routine Description:
  290. We initiate a request to control the remote desktop and pop up the
  291. approval warning dialog.
  292. Arguments:
  293. None.
  294. Return value:
  295. None.
  296. --*/
  297. {
  298. DC_BEGIN_FN("CRemoteDesktopClientSession::ConnectRemoteDesktop");
  299. m_RemDeskClient->ConnectRemoteDesktop();
  300. m_ApprovalDlg.m_rObj = this;
  301. m_ApprovalDlg.Create(m_hInstance,IDD_APPROVALWAIT,m_hWnd);
  302. DC_END_FN();
  303. }
  304. VOID
  305. CRemoteDesktopClientSession::OnAbout(
  306. )
  307. /*++
  308. Routine Description:
  309. We either create or bring to the foreground the about box.
  310. Arguments:
  311. None.
  312. Return value:
  313. None.
  314. --*/
  315. {
  316. DC_BEGIN_FN("CRemoteDesktopClientSession::OnAbout");
  317. if (m_AboutDlg.IsCreated()) {
  318. m_AboutDlg.Activate();
  319. } else {
  320. m_AboutDlg.Create(m_hInstance,IDD_ABOUT,m_hWnd);
  321. }
  322. DC_END_FN();
  323. }
  324. LRESULT
  325. CRemoteDesktopClientSession::OnCommand(
  326. IN WPARAM wParam,
  327. IN LPARAM lParam
  328. )
  329. /*++
  330. Routine Description:
  331. When the window is destroyed we disconnect from the remote host and then
  332. send a quit message to exit the event loop.
  333. Arguments:
  334. wParam - The command which was triggered.
  335. lParam - The control the command came from.
  336. Return value:
  337. 0 - We handled the command.
  338. 1 - We did not handle the command.
  339. --*/
  340. {
  341. LRESULT retValue = 0;
  342. DC_BEGIN_FN("CRemoteDesktopClientSession::OnCommand");
  343. switch (wParam) {
  344. case ID_EXIT:
  345. DestroyWindow(m_hWnd);
  346. break;
  347. case ID_ABOUT:
  348. OnAbout();
  349. break;
  350. default:
  351. retValue = 1;
  352. }
  353. DC_END_FN();
  354. return retValue;
  355. }
  356. VOID
  357. CRemoteDesktopClientSession::OnDestroy(
  358. )
  359. /*++
  360. Routine Description:
  361. When the window is destroyed we disconnect from the remote host and then
  362. send a quit message to exit the event loop.
  363. Arguments:
  364. None.
  365. Return value:
  366. None.
  367. --*/
  368. {
  369. BOOL isConnected;
  370. HRESULT hr;
  371. DC_BEGIN_FN("CRemoteDesktopClientSession::OnDestroy");
  372. if(m_RemDeskClient) {
  373. hr = m_RemDeskClient->get_IsRemoteDesktopConnected(&isConnected);
  374. if (hr == S_OK && isConnected) {
  375. m_RemDeskClient->DisconnectRemoteDesktop();
  376. }
  377. m_RemDeskClient->DisconnectFromServer();
  378. }
  379. PostQuitMessage(0);
  380. DC_END_FN();
  381. }
  382. VOID
  383. CRemoteDesktopClientSession::ShowRemdeskControl(
  384. )
  385. /*++
  386. Routine Description:
  387. This makes our child window visible.
  388. Arguments:
  389. None.
  390. Return value:
  391. None.
  392. --*/
  393. {
  394. DC_BEGIN_FN("CRemoteDesktopClientSession::ShowRemdeskControl");
  395. ShowWindow(m_hRdcHostWnd,SW_SHOW);
  396. DC_END_FN();
  397. }
  398. VOID
  399. CRemoteDesktopClientSession::OnSetFocus(
  400. )
  401. /*++
  402. Routine Description:
  403. When we get focus we pass it off to our child window.
  404. Arguments:
  405. None.
  406. Return value:
  407. None.
  408. --*/
  409. {
  410. DC_BEGIN_FN("CRemoteDesktopClientSession::OnSetFocus");
  411. SetFocus(m_hRdcHostWnd);
  412. DC_END_FN();
  413. }