Leaked source code of windows server 2003
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.

3777 lines
112 KiB

  1. //
  2. // contwnd.cpp
  3. //
  4. // Implementation of CContainerWnd
  5. // TS Client Shell Top-Level ActiveX container window
  6. //
  7. // Copyright(C) Microsoft Corporation 2000
  8. // Author: Nadim Abdo (nadima)
  9. //
  10. //
  11. #include "stdafx.h"
  12. #define TRC_GROUP TRC_GROUP_UI
  13. #define TRC_FILE "contwnd"
  14. #include <atrcapi.h>
  15. #include "contwnd.h"
  16. #include "maindlg.h"
  17. #include "discodlg.h"
  18. #include "aboutdlg.h"
  19. #include "shutdowndlg.h"
  20. #ifdef DC_DEBUG
  21. #include "mallocdbgdlg.h"
  22. #include "thruputdlg.h"
  23. #endif //DC_DEBUG
  24. #include "cachewrndlg.h"
  25. #include "tscsetting.h"
  26. #include "commctrl.h"
  27. #include "security.h"
  28. //
  29. // COMPILE_MULTIMON_STUBS must be defined in only one
  30. // file. Any other file that wants to use multimon
  31. // enabled functions should re-include multimon.h
  32. //
  33. #ifdef OS_WINNT
  34. #define COMPILE_MULTIMON_STUBS
  35. #include <multimon.h>
  36. #endif
  37. #ifdef OS_WINCE
  38. #include <ceconfig.h>
  39. #endif
  40. //
  41. // maximum string length for menu strings
  42. //
  43. #define UI_MENU_STRING_MAX_LENGTH 256
  44. CContainerWnd::CContainerWnd()
  45. {
  46. DC_BEGIN_FN("CContainerWnd");
  47. _pTsClient = NULL;
  48. _hwndMainDialog = NULL;
  49. _hwndStatusDialog = NULL;
  50. _fLoginComplete = FALSE;
  51. _bContainerIsFullScreen = FALSE;
  52. _fPreventClose = FALSE;
  53. _fBeenThroughDestroy = FALSE;
  54. _fBeenThroughNCDestroy = FALSE;
  55. _PostedQuit=0;
  56. _pWndView = NULL;
  57. _fFirstTimeToLogonDlg = TRUE;
  58. _cInEventHandlerCount = 0;
  59. _fInOnCloseHandler = FALSE;
  60. _pMainDlg = NULL;
  61. _pTscSet = NULL;
  62. _pSh = NULL;
  63. memset(_szAppName, 0, sizeof(_szAppName));
  64. _fHaveConnected = FALSE;
  65. _fClosePending = FALSE;
  66. #ifndef OS_WINCE
  67. _pTaskBarList2 = NULL;
  68. _fQueriedForTaskBarList2 = FALSE;
  69. #endif
  70. _fInSizeMove = FALSE;
  71. _maxMainWindowSize.width = 100;
  72. _maxMainWindowSize.height = 100;
  73. SetCurrentDesktopWidth(DEFAULT_DESKTOP_WIDTH);
  74. SetCurrentDesktopHeight(DEFAULT_DESKTOP_HEIGHT);
  75. _fClientWindowIsUp = FALSE;
  76. _successConnectCount = 0;
  77. _fRunningOnWin9x = FALSE;
  78. SET_CONTWND_STATE(stateNotInitialized);
  79. ResetConnectionSuccessFlag();
  80. DC_END_FN();
  81. }
  82. CContainerWnd::~CContainerWnd()
  83. {
  84. //
  85. // Release our cached interface ptr to the taskbar
  86. //
  87. #ifndef OS_WINCE
  88. if (_pTaskBarList2)
  89. {
  90. _pTaskBarList2->Release();
  91. _pTaskBarList2 = NULL;
  92. }
  93. #endif
  94. delete _pMainDlg;
  95. if (_pWndView)
  96. {
  97. _pWndView->Cleanup();
  98. delete _pWndView;
  99. _pWndView = NULL;
  100. }
  101. }
  102. DCBOOL CContainerWnd::Init(HINSTANCE hInstance, CTscSettings* pTscSet, CSH* pSh)
  103. {
  104. HRESULT hr;
  105. DC_BEGIN_FN("Init");
  106. TRC_ASSERT(hInstance && pTscSet && pSh,
  107. (TB,_T("Invalid param(s)")));
  108. if (!(hInstance && pTscSet && pSh))
  109. {
  110. return FALSE;
  111. }
  112. _fRunningOnWin9x = CSH::SH_IsRunningOn9x();
  113. TRC_NRM((TB,_T("Running on 9x :%d"), _fRunningOnWin9x));
  114. _pSh = pSh;
  115. _hInst = hInstance;
  116. //
  117. // Window is created with dummy size, it is resized before
  118. // connection
  119. //
  120. RECT rcNormalizedPos = {0,0,1,1};
  121. INITCOMMONCONTROLSEX cmCtl;
  122. cmCtl.dwSize = sizeof(INITCOMMONCONTROLSEX);
  123. #ifndef OS_WINCE
  124. //Load ComboBoxEx class
  125. cmCtl.dwICC = ICC_USEREX_CLASSES;
  126. if (!InitCommonControlsEx( &cmCtl))
  127. {
  128. TRC_ABORT((TB, _T("InitCommonControlsEx failed")));
  129. return FALSE;
  130. }
  131. #endif
  132. _pTscSet = pTscSet;
  133. if (!LoadString(hInstance,
  134. UI_IDS_APP_NAME,
  135. _szAppName,
  136. SIZECHAR(_szAppName)))
  137. {
  138. TRC_ERR((TB,_T("LoadString UI_IDS_APP_NAME failed")));
  139. }
  140. //
  141. // Cache the path to the default file
  142. //
  143. #ifndef OS_WINCE
  144. _pSh->SH_GetPathToDefaultFile(_szPathToDefaultFile,
  145. SIZECHAR(_szPathToDefaultFile));
  146. #else
  147. _tcscpy(_szPathToDefaultFile, _T(""));
  148. #endif
  149. //Create invisible top level container window
  150. if(!CreateWnd(hInstance, NULL,
  151. MAIN_CLASS_NAME,
  152. _pSh->_fullFrameTitleStr,
  153. #ifndef OS_WINCE
  154. WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  155. WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,
  156. #else
  157. WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_EX_WINDOWEDGE,
  158. #endif
  159. &rcNormalizedPos,
  160. _pSh->GetAppIcon()))
  161. {
  162. TRC_ERR((TB,_T("Failed to create top level window")));
  163. return FALSE;
  164. }
  165. //
  166. // Load the Ax control
  167. //
  168. // CreateTsControl pops message boxes to indicate
  169. // common failures
  170. //
  171. hr = CreateTsControl();
  172. if (FAILED(hr))
  173. {
  174. TRC_ERR((TB, _T("Failed to create control\n")));
  175. DestroyWindow();
  176. return FALSE;
  177. }
  178. TRC_ASSERT(_pTsClient, (TB,_T(" _pTsClient not created")));
  179. if (!_pTsClient)
  180. {
  181. DestroyWindow();
  182. return FALSE;
  183. }
  184. if (!_pSh->SH_ReadControlVer( _pTsClient))
  185. {
  186. _pTsClient->Release();
  187. _pTsClient=NULL;
  188. DestroyWindow();
  189. return FALSE;
  190. }
  191. IMsRdpClientAdvancedSettings* pAdvSettings;
  192. hr = _pTsClient->get_AdvancedSettings2( &pAdvSettings);
  193. if (FAILED(hr) || !pAdvSettings)
  194. {
  195. _pTsClient->Release();
  196. _pTsClient=NULL;
  197. DestroyWindow();
  198. return FALSE;
  199. }
  200. //
  201. // Set the container handled fullscreen prop
  202. //
  203. hr = pAdvSettings->put_ContainerHandledFullScreen( TRUE);
  204. if (FAILED(hr))
  205. {
  206. _pTsClient->Release();
  207. pAdvSettings->Release();
  208. _pTsClient=NULL;
  209. DestroyWindow();
  210. return FALSE;
  211. }
  212. pAdvSettings->Release();
  213. SetupSystemMenu();
  214. SET_CONTWND_STATE(stateNotConnected);
  215. if (_pSh->GetAutoConnect() && _pSh->SH_ValidateParams(_pTscSet))
  216. {
  217. //Auto connect
  218. if (!StartConnection())
  219. {
  220. //
  221. // Autoconnection failed, this could have been because
  222. // the user cancelled out of a security warning dialog
  223. // in which case we brought up the main UI - in that
  224. // case do not exit, all other cases bail out.
  225. //
  226. if (!IsUsingDialogUI())
  227. {
  228. TRC_ERR((TB,_T("StartConnection failed")));
  229. DestroyWindow();
  230. return FALSE;
  231. }
  232. }
  233. }
  234. else
  235. {
  236. //Start the main dialog
  237. TRC_NRM((TB, _T("Bringing up connection dialog")));
  238. //
  239. // Start the dialog in the expanded state if the file
  240. // was opened for edit (first parameter)
  241. //
  242. if (!StartConnectDialog(_pSh->SH_GetCmdFileForEdit(), TAB_GENERAL_IDX))
  243. {
  244. TRC_ERR((TB,_T("Error bringing up connect dialog")));
  245. DestroyWindow();
  246. return FALSE;
  247. }
  248. }
  249. DC_END_FN();
  250. return TRUE;
  251. }
  252. //
  253. // Exit and quit the app
  254. //
  255. void CContainerWnd::ExitAndQuit()
  256. {
  257. DC_BEGIN_FN("ExitAndQuit");
  258. if (_pTsClient)
  259. {
  260. _pTsClient->Release();
  261. _pTsClient = NULL;
  262. }
  263. if (::IsWindow(_hwndMainDialog))
  264. {
  265. ::DestroyWindow(_hwndMainDialog);
  266. _hwndMainDialog = NULL;
  267. }
  268. _PostedQuit=2;
  269. ::PostQuitMessage(0);
  270. DC_END_FN();
  271. }
  272. BOOL CContainerWnd::SetupSystemMenu()
  273. {
  274. HRESULT hr = E_FAIL;
  275. #ifndef OS_WINCE
  276. HMENU hHelpMenu;
  277. DCTCHAR menuStr[UI_MENU_STRING_MAX_LENGTH];
  278. #if DC_DEBUG
  279. HMENU hDebugMenu;
  280. #endif // DC_DEBUG
  281. #endif // OS_WINCE
  282. DC_BEGIN_FN("SetupSystemMenu");
  283. #ifndef OS_WINCE // These won't work in full screen anyway
  284. // Set up the main window's menu information.
  285. _hSystemMenu = GetSystemMenu(GetHwnd(), FALSE);
  286. if (_hSystemMenu)
  287. {
  288. // Update the System Menu Alt-F4 menu text
  289. if (LoadString(_hInst,
  290. UI_MENU_APPCLOSE,
  291. menuStr,
  292. UI_MENU_STRING_MAX_LENGTH) != 0)
  293. {
  294. if (!ModifyMenu(_hSystemMenu, SC_CLOSE, MF_BYCOMMAND |
  295. MF_STRING, SC_CLOSE, menuStr))
  296. {
  297. TRC_ERR((TB, _T("Unable to ModifyMenu")));
  298. }
  299. }
  300. else
  301. {
  302. TRC_ERR((TB, _T("Unable to Load App close text")));
  303. }
  304. // Add Help Menu to the System Menu
  305. hHelpMenu = CreateMenu();
  306. if (hHelpMenu)
  307. {
  308. //load the string from the resources
  309. if (LoadString(_hInst,
  310. UI_MENU_MAINHELP,
  311. menuStr,
  312. UI_MENU_STRING_MAX_LENGTH) != 0)
  313. {
  314. AppendMenu(_hSystemMenu, MF_POPUP | MF_STRING,
  315. (INT_PTR)hHelpMenu, menuStr);
  316. //load the string for the client help sub menu
  317. if (LoadString(_hInst,
  318. UI_MENU_CLIENTHELP,
  319. menuStr,
  320. UI_MENU_STRING_MAX_LENGTH) != 0)
  321. {
  322. AppendMenu(hHelpMenu, MF_UNCHECKED|MF_STRING,
  323. UI_IDM_HELP_ON_CLIENT,
  324. menuStr);
  325. }
  326. else
  327. {
  328. //failed to load the sub menu string
  329. TRC_ERR((TB, _T("Failed to load Client Help Sub Menu string ID:%u"),
  330. UI_MENU_CLIENTHELP));
  331. }
  332. //load the string for the about help sub menu
  333. if (LoadString(_hInst,
  334. UI_MENU_ABOUT,
  335. menuStr,
  336. UI_MENU_STRING_MAX_LENGTH) != 0)
  337. {
  338. AppendMenu(hHelpMenu, MF_UNCHECKED|MF_STRING, UI_IDM_ABOUT,
  339. menuStr);
  340. }
  341. else
  342. {
  343. //failed to load the sub menu string
  344. TRC_ERR((TB, _T("Failed to load About Help Sub Menu string ID:%u"),
  345. UI_MENU_ABOUT));
  346. }
  347. }
  348. else
  349. {
  350. //load string for the main help menu failed
  351. TRC_ERR((TB, _T("Failed to load Main Help Menu string ID:%u"),
  352. UI_MENU_MAINHELP));
  353. }
  354. _hHelpMenu = hHelpMenu;
  355. }
  356. // Add Debug Menu to the System Menu
  357. #ifdef DC_DEBUG
  358. hDebugMenu = CreateMenu();
  359. if (hDebugMenu)
  360. {
  361. //load the string for the DEBUG menu
  362. if (LoadString(_hInst,
  363. UI_MENU_DEBUG,
  364. menuStr,
  365. UI_MENU_STRING_MAX_LENGTH) != 0)
  366. {
  367. AppendMenu(_hSystemMenu, MF_POPUP | MF_STRING,
  368. (INT_PTR)hDebugMenu, menuStr);
  369. //load the string for the hatch Bitmap pdu debug menu
  370. if (LoadString(_hInst,
  371. UI_MENU_BITMAPPDU,
  372. menuStr,
  373. UI_MENU_STRING_MAX_LENGTH) != 0)
  374. {
  375. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  376. UI_IDM_HATCHBITMAPPDUDATA,
  377. menuStr);
  378. }
  379. else
  380. {
  381. //failed to load the sub menu string
  382. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  383. UI_MENU_BITMAPPDU));
  384. }
  385. //load the string for the hatch SS Border data debug menu
  386. if (LoadString(_hInst,
  387. UI_MENU_SSBORDER,
  388. menuStr,
  389. UI_MENU_STRING_MAX_LENGTH) != 0)
  390. {
  391. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  392. UI_IDM_HATCHSSBORDERDATA,
  393. menuStr);
  394. }
  395. else
  396. {
  397. //failed to load the sub menu string
  398. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  399. UI_MENU_SSBORDER));
  400. }
  401. //load the string for the Hatch MemBlt order data debug menu
  402. if (LoadString(_hInst,
  403. UI_MENU_HATCHMEMBIT,
  404. menuStr,
  405. UI_MENU_STRING_MAX_LENGTH) != 0)
  406. {
  407. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  408. UI_IDM_HATCHMEMBLTORDERDATA,
  409. menuStr);
  410. }
  411. else
  412. {
  413. //failed to load the sub menu string
  414. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  415. UI_MENU_HATCHMEMBIT));
  416. }
  417. //load the string for the hatch index pdu debug menu
  418. if (LoadString(_hInst,
  419. UI_MENU_INDEXPDU,
  420. menuStr,
  421. UI_MENU_STRING_MAX_LENGTH) != 0)
  422. {
  423. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  424. UI_IDM_HATCHINDEXPDUDATA,
  425. menuStr);
  426. }
  427. else
  428. {
  429. //failed to load the sub menu string
  430. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  431. UI_MENU_INDEXPDU));
  432. }
  433. //load the string for the label Membit data debug menu
  434. if (LoadString(_hInst,
  435. UI_MENU_LABELMEMBIT,
  436. menuStr,
  437. UI_MENU_STRING_MAX_LENGTH) != 0)
  438. {
  439. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  440. UI_IDM_LABELMEMBLTORDERS,
  441. menuStr);
  442. }
  443. else
  444. {
  445. //failed to load the sub menu string
  446. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  447. UI_MENU_LABELMEMBIT));
  448. }
  449. //load the string for the hatch Bitmap Cahche Monitor debug menu
  450. if (LoadString(_hInst,
  451. UI_MENU_CACHE,
  452. menuStr,
  453. UI_MENU_STRING_MAX_LENGTH) != 0)
  454. {
  455. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  456. UI_IDM_BITMAPCACHEMONITOR,
  457. menuStr);
  458. }
  459. else
  460. {
  461. //failed to load the sub menu string
  462. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  463. UI_MENU_CACHE));
  464. }
  465. //load the string for the malloc Failure debug menu
  466. if (LoadString(_hInst,
  467. UI_MENU_MALLOC,
  468. menuStr,
  469. UI_MENU_STRING_MAX_LENGTH) != 0)
  470. {
  471. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  472. UI_IDM_MALLOCFAILURE,
  473. menuStr);
  474. }
  475. else
  476. {
  477. //failed to load the sub menu string
  478. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  479. UI_MENU_MALLOC));
  480. }
  481. //load the string for the Malloc Huge Failure debug menu
  482. if (LoadString(_hInst,
  483. UI_MENU_MALLOCHUGE,
  484. menuStr,
  485. UI_MENU_STRING_MAX_LENGTH) != 0)
  486. {
  487. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  488. UI_IDM_MALLOCHUGEFAILURE,
  489. menuStr);
  490. }
  491. else
  492. {
  493. //failed to load the sub menu string
  494. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  495. UI_MENU_MALLOCHUGE));
  496. }
  497. //load the string for the network Throughput.. debug menu
  498. if (LoadString(_hInst,
  499. UI_MENU_NETWORK,
  500. menuStr,
  501. UI_MENU_STRING_MAX_LENGTH) != 0)
  502. {
  503. AppendMenu(hDebugMenu, MF_UNCHECKED|MF_STRING,
  504. UI_IDM_NETWORKTHROUGHPUT,
  505. menuStr);
  506. }
  507. else
  508. {
  509. //failed to load the sub menu string
  510. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  511. UI_MENU_NETWORK));
  512. }
  513. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  514. #ifdef SMART_SIZING
  515. //load the string for the SmartSize debug menu
  516. if (LoadString(_hInst,
  517. UI_MENU_SMARTSIZING,
  518. menuStr,
  519. UI_MENU_STRING_MAX_LENGTH) != 0)
  520. {
  521. UINT flags;
  522. flags = MF_STRING;
  523. if (_fRunningOnWin9x) {
  524. flags |= MF_GRAYED;
  525. }
  526. AppendMenu(hDebugMenu, flags,
  527. UI_IDM_SMARTSIZING,
  528. menuStr);
  529. }
  530. else
  531. {
  532. //failed to load the sub menu string
  533. TRC_ERR((TB, _T("Failed to load Debug Sub Menu string ID:%u"),
  534. UI_MENU_HATCHMEMBIT));
  535. }
  536. #endif // SMART_SIZING
  537. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  538. if (!_pTsClient)
  539. {
  540. return FALSE;
  541. }
  542. IMsTscDebug* pDebugger = NULL;
  543. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  544. if(SUCCEEDED(hr) && pDebugger)
  545. {
  546. //
  547. // Now check the menu items as needed
  548. //
  549. BOOL bEnabled;
  550. TRACE_HR(pDebugger->get_HatchBitmapPDU(&bEnabled));
  551. if(SUCCEEDED(hr))
  552. {
  553. CheckMenuItem(hDebugMenu,
  554. UI_IDM_HATCHBITMAPPDUDATA,
  555. bEnabled ? MF_CHECKED :
  556. MF_UNCHECKED);
  557. }
  558. TRACE_HR(pDebugger->get_HatchIndexPDU(&bEnabled));
  559. if(SUCCEEDED(hr))
  560. {
  561. CheckMenuItem(hDebugMenu,
  562. UI_IDM_HATCHINDEXPDUDATA,
  563. bEnabled ? MF_CHECKED :
  564. MF_UNCHECKED);
  565. }
  566. TRACE_HR(pDebugger->get_HatchSSBOrder(&bEnabled));
  567. if(SUCCEEDED(hr))
  568. {
  569. CheckMenuItem(hDebugMenu,
  570. UI_IDM_HATCHSSBORDERDATA,
  571. bEnabled ? MF_CHECKED :
  572. MF_UNCHECKED);
  573. }
  574. TRACE_HR(pDebugger->get_HatchMembltOrder(&bEnabled));
  575. if(SUCCEEDED(hr))
  576. {
  577. CheckMenuItem(hDebugMenu,
  578. UI_IDM_HATCHMEMBLTORDERDATA,
  579. bEnabled ? MF_CHECKED :
  580. MF_UNCHECKED);
  581. }
  582. TRACE_HR(pDebugger->get_LabelMemblt(&bEnabled));
  583. if(SUCCEEDED(hr))
  584. {
  585. CheckMenuItem(hDebugMenu,
  586. UI_IDM_LABELMEMBLTORDERS,
  587. bEnabled ? MF_CHECKED :
  588. MF_UNCHECKED);
  589. }
  590. TRACE_HR(pDebugger->get_BitmapCacheMonitor(&bEnabled));
  591. if(SUCCEEDED(hr))
  592. {
  593. CheckMenuItem(hDebugMenu,
  594. UI_IDM_BITMAPCACHEMONITOR,
  595. bEnabled ? MF_CHECKED :
  596. MF_UNCHECKED);
  597. }
  598. pDebugger->Release();
  599. }
  600. }
  601. else
  602. {
  603. //failed to load the debug menu string
  604. TRC_ERR((TB, _T("Failed to load Debug menu string ID:%u"),
  605. UI_MENU_DEBUG));
  606. }
  607. _hDebugMenu = hDebugMenu;
  608. }
  609. #endif // DC_DEBUG
  610. }
  611. #endif // OS_WINCE
  612. DC_END_FN();
  613. return TRUE;
  614. }
  615. LRESULT CContainerWnd::OnCreate(UINT uMsg, WPARAM wParam,
  616. LPARAM lParam)
  617. {
  618. UNREFERENCED_PARAMETER(uMsg);
  619. UNREFERENCED_PARAMETER(wParam);
  620. UNREFERENCED_PARAMETER(lParam);
  621. DC_BEGIN_FN("OnCreate");
  622. SetCursor(LoadCursor(NULL, IDC_WAIT));
  623. DC_END_FN();
  624. return 0;
  625. }
  626. //
  627. // Create TS Control Window.
  628. //
  629. HRESULT CContainerWnd::CreateTsControl()
  630. {
  631. HRESULT hr = S_OK;
  632. DC_BEGIN_FN("CreateTsControl");
  633. if (_pWndView)
  634. {
  635. return E_FAIL;
  636. }
  637. _pWndView = new CAxHostWnd(this);
  638. if (!_pWndView)
  639. {
  640. return E_OUTOFMEMORY;
  641. }
  642. if (!_pWndView->Init())
  643. {
  644. TRC_ABORT((TB,_T("Init of AxHostWnd failed")));
  645. return E_FAIL;
  646. }
  647. //
  648. // CreateControl is the crucial part that goes
  649. // and loads the control dll.
  650. //
  651. INT rc = _pWndView->CreateControl(&_pTsClient);
  652. if (AXHOST_SUCCESS == rc)
  653. {
  654. if (!_pWndView->CreateHostWnd(GetHwnd(), _hInst))
  655. {
  656. TRC_ABORT((TB,_T("CreateHostWnd failed")));
  657. return E_FAIL;
  658. }
  659. }
  660. else
  661. {
  662. TRC_ERR((TB,_T("CreateControl failed")));
  663. //
  664. // Pop meaningful errmsg boxes to the user
  665. // as this is a fatal error and we can't go on
  666. //
  667. INT errStringID;
  668. switch (rc)
  669. {
  670. case ERR_AXHOST_DLLNOTFOUND:
  671. errStringID = UI_IDS_ERR_DLLNOTFOUND;
  672. break;
  673. case ERR_AXHOST_VERSIONMISMATCH:
  674. errStringID = UI_IDS_ERR_DLLBADVERSION;
  675. break;
  676. default:
  677. errStringID = UI_IDS_ERR_LOADINGCONTROL;
  678. break;
  679. }
  680. TCHAR errLoadingControl[MAX_PATH];
  681. if (LoadString(_hInst,
  682. errStringID,
  683. errLoadingControl,
  684. SIZECHAR(errLoadingControl)) != 0)
  685. {
  686. MessageBox(GetHwnd(), errLoadingControl, _szAppName,
  687. MB_ICONERROR | MB_OK);
  688. }
  689. return E_FAIL;
  690. }
  691. DC_END_FN();
  692. return hr;
  693. }
  694. //
  695. // Kick off a connection with the current settings
  696. //
  697. BOOL CContainerWnd::StartConnection()
  698. {
  699. DC_BEGIN_FN("StartConnection");
  700. USES_CONVERSION;
  701. HRESULT hr;
  702. PWINDOWPLACEMENT pwndplc;
  703. BOOL fResult = FALSE;
  704. IMsTscDebug* pDebugger = NULL;
  705. TCHAR szPlainServerName[TSC_MAX_ADDRESS_LENGTH];
  706. TRC_ASSERT(_pTsClient, (TB,_T(" Ts client control does not exist!\n")));
  707. if (!_pTsClient)
  708. {
  709. return FALSE;
  710. }
  711. TRC_ASSERT(_pTscSet, (TB,_T(" tsc settings does not exist!\n")));
  712. TRC_ASSERT(_state != stateConnecting &&
  713. _state != stateConnected,
  714. (TB,_T("Can't connect in connecting state: 0x%d"),
  715. _state));
  716. ResetConnectionSuccessFlag();
  717. pwndplc = _pTscSet->GetWindowPlacement();
  718. //
  719. // Positition the window before connecting
  720. // so that if it's a fullscreen connection
  721. // we can determine the correct resolution to connect at.
  722. // This has to be set before the connection starts
  723. //
  724. #ifndef OS_WINCE
  725. TRC_ASSERT(pwndplc->rcNormalPosition.right - pwndplc->rcNormalPosition.left,
  726. (TB,_T("0 width")));
  727. TRC_ASSERT(pwndplc->rcNormalPosition.bottom - pwndplc->rcNormalPosition.top,
  728. (TB,_T("0 height")));
  729. #endif
  730. //
  731. // For fullscreen force the deskwidth/height
  732. // to match the monitor we're going to connect on
  733. //
  734. if (_pTscSet->GetStartFullScreen())
  735. {
  736. RECT rcMonitor;
  737. int deskX,deskY;
  738. CSH::MonitorRectFromNearestRect(&pwndplc->rcNormalPosition,
  739. &rcMonitor);
  740. deskX = min(rcMonitor.right - rcMonitor.left,MAX_DESKTOP_WIDTH);
  741. deskY = min(rcMonitor.bottom - rcMonitor.top,MAX_DESKTOP_HEIGHT);
  742. _pTscSet->SetDesktopWidth( deskX );
  743. _pTscSet->SetDesktopHeight( deskY );
  744. }
  745. //
  746. // Do security checks on the plain server name (no port, no params)
  747. //
  748. hr = _pTscSet->GetConnectString().GetServerNamePortion(
  749. szPlainServerName,
  750. SIZE_TCHARS(szPlainServerName)
  751. );
  752. if (FAILED(hr)) {
  753. TRC_ERR((TB,_T("Failed to get plain server name 0x%x"), hr));
  754. DC_QUIT;
  755. }
  756. if (!CTSSecurity::AllowConnection(_hwndMainDialog, _hInst,
  757. szPlainServerName,
  758. _pTscSet->GetDriveRedirection(),
  759. _pTscSet->GetCOMPortRedirection()))
  760. {
  761. TRC_ERR((TB,_T("AllowConnection check returned FALSE. Skip connect")));
  762. fResult = FALSE;
  763. //
  764. // If this was an autoconnection then start the dialog
  765. // up at the LocalResources tab so the user can easily change
  766. // device redirection options
  767. //
  768. if (_pSh->GetAutoConnect())
  769. {
  770. //
  771. // From now on this is not an autoconnection
  772. //
  773. _pSh->SetAutoConnect(FALSE);
  774. #ifdef OS_WINCE //dont bring up mstsc ui on WBT.
  775. if (g_CEConfig == CE_CONFIG_WBT)
  776. DC_QUIT;
  777. #endif
  778. //
  779. // Start the dialog expanded at the local resources tab
  780. //
  781. if (!StartConnectDialog(TRUE, TAB_LOCAL_RESOURCES_IDX))
  782. {
  783. TRC_ERR((TB,_T("Error bringing up connect dialog")));
  784. DestroyWindow();
  785. fResult = FALSE;
  786. }
  787. }
  788. DC_QUIT;
  789. }
  790. hr = _pTscSet->ApplyToControl(_pTsClient);
  791. if (FAILED(hr))
  792. {
  793. TRC_ERR((TB,_T("Failed ApplyToControl: %d"), hr));
  794. fResult = FALSE;
  795. DC_QUIT;
  796. }
  797. //The desktop size from the settings can
  798. //change during the connection..e.g when a shadow happens.
  799. //CurrentDesktopWidth/Height stores the instantaneous values
  800. SetCurrentDesktopWidth( _pTscSet->GetDesktopWidth());
  801. SetCurrentDesktopHeight( _pTscSet->GetDesktopHeight());
  802. RecalcMaxWindowSize();
  803. //Now apply settings that don't come from the settings collection
  804. hr = _pTsClient->get_Debugger(&pDebugger);
  805. if (FAILED(hr) || !pDebugger)
  806. {
  807. fResult = FALSE;
  808. DC_QUIT;
  809. }
  810. hr = pDebugger->put_CLXCmdLine( T2OLE(_pSh->GetClxCmdLine()));
  811. if (FAILED(hr))
  812. {
  813. TRC_ERR((TB,_T("Failed put_CLXCmdLine: %d"), hr));
  814. fResult = FALSE;
  815. DC_QUIT;
  816. }
  817. pDebugger->Release();
  818. pDebugger = NULL;
  819. //Reset the login complete flag (login event occurs after connect)
  820. _fLoginComplete = FALSE;
  821. //Initiate the connection
  822. hr = _pTsClient->Connect();
  823. if (SUCCEEDED(hr))
  824. {
  825. SET_CONTWND_STATE(stateConnecting);
  826. }
  827. else
  828. {
  829. TRC_ERR((TB,_T("Connect method failed: %d"), hr));
  830. TCHAR errConnecting[MAX_PATH];
  831. if (LoadString(_hInst,
  832. UI_IDS_ERR_CONNECTCALLFAILED,
  833. errConnecting,
  834. SIZECHAR(errConnecting)) != 0)
  835. {
  836. MessageBox(GetHwnd(), errConnecting, _szAppName,
  837. MB_ICONERROR | MB_OK);
  838. }
  839. fResult = FALSE;
  840. DC_QUIT;
  841. }
  842. //Bring up the connecting dialog and wait for the Connected event
  843. SetCursor(LoadCursor(NULL, IDC_WAIT));
  844. if(!IsUsingDialogUI())
  845. {
  846. //
  847. // Only bring this up if we're not using the
  848. // dialog UI. E.g for autolaunched connections.
  849. //
  850. // The dialog UI displays it's own progress indicator
  851. //
  852. TCHAR szServerName[TSC_MAX_ADDRESS_LENGTH];
  853. _pTscSet->GetConnectString().GetServerPortion(
  854. szServerName,
  855. SIZE_TCHARS(szServerName)
  856. );
  857. CConnectingDlg connectingDlg(
  858. _hwndMainDialog, _hInst,
  859. this, szServerName
  860. );
  861. connectingDlg.DoModal();
  862. }
  863. fResult = TRUE;
  864. DC_EXIT_POINT:
  865. if (pDebugger)
  866. {
  867. pDebugger->Release();
  868. pDebugger = NULL;
  869. }
  870. DC_END_FN();
  871. return fResult;
  872. }
  873. DCBOOL CContainerWnd::Disconnect()
  874. {
  875. HRESULT hr;
  876. short connectionState = 0;
  877. DC_BEGIN_FN("Disconnect");
  878. TRC_ASSERT(_pTsClient, (TB,_T(" Ts client control does not exist!\n")));
  879. if (!_pTsClient)
  880. {
  881. return FALSE;
  882. }
  883. TRC_NRM((TB,_T("Container calling control's disconnect")));
  884. //
  885. // In some cases the control might already be disconnected
  886. // check for that
  887. //
  888. // NOTE that becasue we are in a STA the connected state
  889. // of the control can't change after the get_Connected call
  890. // (untill we go back to pumping messages) so there are no
  891. // timing issues here.
  892. //
  893. TRACE_HR(_pTsClient->get_Connected( & connectionState ));
  894. if(SUCCEEDED(hr))
  895. {
  896. if( connectionState )
  897. {
  898. // Still connected disconnect
  899. hr = _pTsClient->Disconnect();
  900. if(SUCCEEDED(hr))
  901. {
  902. //
  903. // Successfully initiated disconnect (note it is async)
  904. // need to wait for OnDisconnected
  905. //
  906. return TRUE;
  907. }
  908. else
  909. {
  910. TRC_ERR((TB,_T("Disconnect() failed 0x%x\n"), hr));
  911. return FALSE;
  912. }
  913. }
  914. else
  915. {
  916. TRC_NRM((TB,_T("Not calling disconnected because already discon")));
  917. return TRUE; // success
  918. }
  919. }
  920. else
  921. {
  922. return FALSE;
  923. }
  924. DC_END_FN();
  925. }
  926. LRESULT CContainerWnd::OnDestroy(HWND hWnd, UINT uMsg,
  927. WPARAM wParam, LPARAM lParam)
  928. {
  929. DC_BEGIN_FN("OnDestroy");
  930. UNREFERENCED_PARAMETER(uMsg);
  931. UNREFERENCED_PARAMETER(wParam);
  932. UNREFERENCED_PARAMETER(lParam);
  933. BOOL fShouldDestroy = FALSE;
  934. if (_fBeenThroughDestroy)
  935. {
  936. TRC_ERR((TB,_T("Been through WM_DESTROY before!!!")));
  937. return 0;
  938. }
  939. _fBeenThroughDestroy = TRUE;
  940. if (InControlEventHandler())
  941. {
  942. //
  943. // Don't allow the close. We are in a code path that fired
  944. // from the control. Without this, we sometimes see the client
  945. // receiving close notifications from tclient while a disconnected
  946. // dialog is up (i.e in an OnDicsconnected handler) - destroying
  947. // the control at this time causes bad things to happen during
  948. // the return into the control (which has now been deleted).
  949. //
  950. TRC_ERR((TB,_T("OnDestroy called during a control event handler")));
  951. return 0;
  952. }
  953. else
  954. {
  955. fShouldDestroy = TRUE;
  956. }
  957. #ifdef OS_WINCE
  958. LRESULT lResult = 0;
  959. #endif
  960. if(fShouldDestroy)
  961. {
  962. //Terminate the app
  963. _PostedQuit=1;
  964. #ifdef OS_WINCE
  965. lResult = DefWindowProc( hWnd, uMsg, wParam, lParam);
  966. #else
  967. return DefWindowProc( hWnd, uMsg, wParam, lParam);
  968. #endif
  969. }
  970. #ifdef OS_WINCE //CE does not support WM_NCDESTROY. So destroy the activex control and send a WM_NCDESTROY
  971. if (_pWndView)
  972. {
  973. HWND hwndCtl = _pWndView->GetHwnd();
  974. ::DestroyWindow(hwndCtl);
  975. SendMessage(hWnd, WM_NCDESTROY, 0, 0L);
  976. }
  977. #endif
  978. DC_END_FN();
  979. #ifdef OS_WINCE
  980. return lResult;
  981. #else
  982. return 0;
  983. #endif
  984. }
  985. LRESULT CContainerWnd::OnNCDestroy(HWND hWnd, UINT uMsg,
  986. WPARAM wParam, LPARAM lParam)
  987. {
  988. DC_BEGIN_FN("OnNCDestroy");
  989. //This is the right time to call postquit message.
  990. //As the child windows (e.g the control) have been
  991. //completely destroyed and cleaned up by this point
  992. if(_fBeenThroughNCDestroy)
  993. {
  994. TRC_ERR((TB,_T("Been through WM_NCDESTROY before!!!")));
  995. return 1L;
  996. }
  997. _fBeenThroughNCDestroy = TRUE;
  998. ExitAndQuit();
  999. DC_END_FN();
  1000. return 0L;
  1001. }
  1002. //
  1003. // Name: SetMinMaxPlacement
  1004. //
  1005. // Purpose: Reset the minimized / maximized placement
  1006. //
  1007. // Returns: None
  1008. //
  1009. // Params: windowplacement structure to update
  1010. //
  1011. // Operation: Allow for the window border width.
  1012. //
  1013. //
  1014. VOID CContainerWnd::SetMinMaxPlacement(WINDOWPLACEMENT& windowPlacement)
  1015. {
  1016. DC_BEGIN_FN("UISetMinMaxPlacement");
  1017. //
  1018. // Set the maximized position to the top left - allow for the window
  1019. // frame width.
  1020. //
  1021. #if !defined(OS_WINCE) || defined(OS_WINCE_NONFULLSCREEN)
  1022. windowPlacement.ptMaxPosition.x = -GetSystemMetrics(SM_CXFRAME);
  1023. windowPlacement.ptMaxPosition.y = -GetSystemMetrics(SM_CYFRAME);
  1024. #else // !defined(OS_WINCE) || defined(OS_WINCE_NONFULLSCREEN)
  1025. windowPlacement.ptMaxPosition.x = 0;
  1026. windowPlacement.ptMaxPosition.y = 0;
  1027. #endif // !defined(OS_WINCE) || defined(OS_WINCE_NONFULLSCREEN)
  1028. //
  1029. // Minimized position is 0, 0
  1030. //
  1031. windowPlacement.ptMinPosition.x = 0;
  1032. windowPlacement.ptMinPosition.y = 0;
  1033. #ifndef OS_WINCE
  1034. if (IsZoomed(GetHwnd()))
  1035. {
  1036. windowPlacement.flags |= WPF_RESTORETOMAXIMIZED;
  1037. }
  1038. #endif
  1039. DC_END_FN();
  1040. return;
  1041. } // UISetMinMaxPlacement
  1042. //
  1043. // Name: RecalcMaxWindowSize
  1044. //
  1045. // Purpose: Recalculates _maxMainWindowSize given the current remote desktop
  1046. // size and frame style. The maximum main window size is the
  1047. // size of window needed such that the client area is the same
  1048. // size as the container.
  1049. //
  1050. // Params: None
  1051. //
  1052. // Returns: Nothing
  1053. //
  1054. //
  1055. VOID CContainerWnd::RecalcMaxWindowSize(DCVOID)
  1056. {
  1057. #ifndef OS_WINCE
  1058. RECT rect;
  1059. #ifdef OS_WIN32
  1060. BOOL errorRc;
  1061. #endif
  1062. #endif
  1063. DC_BEGIN_FN("RecalcMaxWindowSize");
  1064. //
  1065. // If current mode is full screen, then the maximum window size is the
  1066. // same as the screen size - unless the container is larger still,
  1067. // which is possible if we're shadowing a session larger than
  1068. // ourselves.
  1069. //
  1070. // In this case, or if the current mode is not full screen then we want
  1071. // the size of window which is required for a client area of the size
  1072. // of the container. Passing the container size to AdjustWindowRect
  1073. // returns this window size. Such a window may be bigger than the
  1074. // screen, eg server and client are 640x480, container is 640x480.
  1075. // AdjustWindowRect adds on the border, title bar and menu sizes and
  1076. // returns something like 648x525. So, UI.maxMainWindowSize can only
  1077. // match the actual window size when the client screen is bigger than
  1078. // the server screen or when operating in full screen mode. This means
  1079. // that UI.maxMainWindowSize should *never* be used to set the window
  1080. // size, eg by passing it to SetWindowPos. It can be used to determine
  1081. // whether scroll bars are required, ie they are needed if the current
  1082. // window size is less than UI.maxMainWindowSize (in other words,
  1083. // always unless in full screen mode or client screen is larger than
  1084. // server screen).
  1085. //
  1086. // To set the window size, calculate a value based on:
  1087. // - the desired window size given the container size
  1088. // - the size of the client screen.
  1089. //
  1090. #ifndef OS_WINCE
  1091. //
  1092. // Recalc window size based on container
  1093. //
  1094. rect.left = 0;
  1095. rect.right = GetCurrentDesktopWidth();
  1096. rect.top = 0;
  1097. rect.bottom = GetCurrentDesktopHeight();
  1098. #ifdef OS_WIN32
  1099. errorRc = AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
  1100. TRC_ASSERT((errorRc != 0), (TB, _T("AdjustWindowRect failed")));
  1101. #else
  1102. AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
  1103. #endif
  1104. _maxMainWindowSize.width = rect.right - rect.left;
  1105. _maxMainWindowSize.height = rect.bottom - rect.top;
  1106. #endif
  1107. TRC_NRM((TB, _T("Main Window maxSize (%d,%d)"),
  1108. _maxMainWindowSize.width,
  1109. _maxMainWindowSize.height));
  1110. DC_END_FN();
  1111. return;
  1112. }
  1113. //
  1114. // Name: GetMaximizedWindowSize
  1115. //
  1116. // Purpose: Calculates the size to which the main window should be
  1117. // maximized, base on the screen size and the size of window
  1118. // which would have a client area the same size as the
  1119. // container (UI.maxMainWindowSize).
  1120. //
  1121. // Returns: The calculated size.
  1122. //
  1123. // Params: None.
  1124. //
  1125. //
  1126. DCSIZE CContainerWnd::GetMaximizedWindowSize(DCSIZE& maximizedSize)
  1127. {
  1128. DCUINT xSize;
  1129. DCUINT ySize;
  1130. RECT rc;
  1131. DC_BEGIN_FN("UIGetMaximizedWindowSize");
  1132. //
  1133. // The maximum size we set a window to is the smaller of:
  1134. // - UI.maxMainWindowSize
  1135. // - the screen size plus twice the border width (so the borders are
  1136. // not visible).
  1137. // Always query the monitor rect as it may change
  1138. // width, as these can change dynamically.
  1139. //
  1140. CSH::MonitorRectFromHwnd(GetHwnd(), &rc);
  1141. xSize = rc.right - rc.left;
  1142. ySize = rc.bottom - rc.top;
  1143. #ifdef OS_WINCE
  1144. maximizedSize.width = DC_MIN(_maxMainWindowSize.width,xSize);
  1145. maximizedSize.height = DC_MIN(_maxMainWindowSize.height,ySize);
  1146. #else // This section NOT OS_WINCE
  1147. maximizedSize.width = DC_MIN(_maxMainWindowSize.width,
  1148. xSize + (2 * GetSystemMetrics(SM_CXFRAME)));
  1149. maximizedSize.height = DC_MIN(_maxMainWindowSize.height,
  1150. ySize + (2 * GetSystemMetrics(SM_CYFRAME)));
  1151. #endif // OS_WINCE
  1152. TRC_NRM((TB, _T("Main Window maxSize (%d,%d) maximizedSize (%d,%d) "),
  1153. _maxMainWindowSize.width,
  1154. _maxMainWindowSize.height,
  1155. maximizedSize.width,
  1156. maximizedSize.height));
  1157. DC_END_FN();
  1158. return(maximizedSize);
  1159. }
  1160. LRESULT CContainerWnd::OnMove(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1161. {
  1162. DC_BEGIN_FN("OnMove");
  1163. UNREFERENCED_PARAMETER(uMsg);
  1164. UNREFERENCED_PARAMETER(wParam);
  1165. UNREFERENCED_PARAMETER(lParam);
  1166. #ifndef OS_WINCE
  1167. //No-op when fullscreen
  1168. if (!_bContainerIsFullScreen)
  1169. {
  1170. WINDOWPLACEMENT* pWindowPlacement = NULL;
  1171. pWindowPlacement = _pTscSet->GetWindowPlacement();
  1172. TRC_ASSERT(pWindowPlacement, (TB, _T("pWindowPlacement is NULL\n")));
  1173. if (pWindowPlacement)
  1174. {
  1175. GetWindowPlacement(GetHwnd(), pWindowPlacement);
  1176. }
  1177. }
  1178. #endif
  1179. DC_END_FN();
  1180. DC_EXIT_POINT:
  1181. return 0;
  1182. }
  1183. LRESULT CContainerWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1184. {
  1185. HRESULT hr = E_FAIL;
  1186. DC_BEGIN_FN("OnSize");
  1187. UNREFERENCED_PARAMETER(uMsg);
  1188. UNREFERENCED_PARAMETER(wParam);
  1189. UNREFERENCED_PARAMETER(lParam);
  1190. WINDOWPLACEMENT* pWindowPlacement = NULL;
  1191. #ifndef OS_WINCE
  1192. if (!_bContainerIsFullScreen)
  1193. {
  1194. // We're non-fullscreen, so keep the window placement structure
  1195. // up-to-date
  1196. pWindowPlacement = _pTscSet->GetWindowPlacement();
  1197. TRC_ASSERT(pWindowPlacement, (TB, _T("pWindowPlacement is NULL\n")));
  1198. if (!pWindowPlacement)
  1199. {
  1200. return 0;
  1201. }
  1202. //
  1203. // Update ShellUtil's current windowplacement info
  1204. //
  1205. GetWindowPlacement(GetHwnd(), pWindowPlacement);
  1206. TRC_DBG((TB, _T("Got window placement in WM_SIZE")));
  1207. if (wParam == SIZE_MAXIMIZED)
  1208. {
  1209. TRC_DBG((TB, _T("Maximize")));
  1210. #if !defined(OS_WINCE) || defined(OS_WINCE_WINDOWPLACEMENT)
  1211. //
  1212. // Override the maximized / minimized positions with our
  1213. // hardcoded valued - required if the maximized window is
  1214. // moved.
  1215. //
  1216. if (pWindowPlacement)
  1217. {
  1218. SetMinMaxPlacement(*pWindowPlacement);
  1219. SetWindowPlacement(GetHwnd(), pWindowPlacement);
  1220. }
  1221. #endif // !defined(OS_WINCE) || defined(OS_WINCE_WINDOWPLACEMENT)
  1222. //
  1223. // We need to be accurate about the maximized window size.
  1224. // It is not possible to use UI.maxMainWindowSize as this
  1225. // may be greater than screen size, eg server and client
  1226. // are 640x480, container is 640x480 then UI.maxWindowSize
  1227. // (obtained via AdjustWindowRect in UIRecalcMaxMainWindow)
  1228. // is something like 648x525.
  1229. // Passing this value to SetWindowPos has results which
  1230. // vary with different shells:
  1231. // Win95/NT4.0: the resulting window is 648x488 at -4, -4,
  1232. // ie all the window, except the border, is
  1233. // on-screen
  1234. // Win31/NT3.51: the resulting window is 648x525 at -4, -4,
  1235. // ie the size passed to SetWindowPos, so
  1236. // the bottom 40 pixels are off-screen.
  1237. // To avoid such differences calculate a maximized window
  1238. // size value which takes account of both the physical
  1239. // screen size and the ideal window size.
  1240. //
  1241. RecalcMaxWindowSize();
  1242. DCSIZE maximized;
  1243. GetMaximizedWindowSize(maximized);
  1244. SetWindowPos( GetHwnd(),
  1245. NULL,
  1246. 0, 0,
  1247. maximized.width,
  1248. maximized.height,
  1249. SWP_NOZORDER | SWP_NOMOVE |
  1250. SWP_NOACTIVATE | SWP_NOOWNERZORDER );
  1251. }
  1252. }
  1253. #endif
  1254. //
  1255. // Size the child window (activeX control) accordingly
  1256. //
  1257. RECT rcClient;
  1258. GetClientRect(GetHwnd(), &rcClient);
  1259. if (_pWndView)
  1260. {
  1261. HWND hwndCtl = _pWndView->GetHwnd();
  1262. ::MoveWindow(hwndCtl,rcClient.left, rcClient.top,
  1263. rcClient.right, rcClient.bottom,
  1264. TRUE);
  1265. }
  1266. DC_END_FN();
  1267. DC_EXIT_POINT:
  1268. return 0;
  1269. }
  1270. LRESULT CContainerWnd::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1271. {
  1272. DC_BEGIN_FN("OnCommand");
  1273. UNREFERENCED_PARAMETER(uMsg);
  1274. UNREFERENCED_PARAMETER(lParam);
  1275. switch (DC_GET_WM_COMMAND_ID(wParam))
  1276. {
  1277. case UI_IDM_CONNECT:
  1278. {
  1279. if (!StartConnectDialog())
  1280. {
  1281. return 1;
  1282. }
  1283. }
  1284. break;
  1285. }
  1286. DC_END_FN();
  1287. return 0;
  1288. }
  1289. //
  1290. // StartConnectionDialog
  1291. // Params: fStartExpanded - startup the dialog in the expanded state
  1292. // nStartTabIndex - index of the tab to show on startup (only applies
  1293. // if fStartExpanded is set)
  1294. //
  1295. //
  1296. BOOL CContainerWnd::StartConnectDialog(BOOL fStartExpanded,
  1297. INT nStartTabIndex)
  1298. {
  1299. DC_BEGIN_FN("StartConnectDialog");
  1300. TRC_DBG((TB, _T("Connect selected")));
  1301. SetCursor(LoadCursor(NULL, IDC_WAIT));
  1302. //Show the dialog box only if auto connect is not enabled or
  1303. //if UIValidateCurrentParams fails.
  1304. if (!_pSh->GetAutoConnect() || !_pSh->SH_ValidateParams(_pTscSet))
  1305. {
  1306. if (!_pMainDlg)
  1307. {
  1308. _pMainDlg = new CMainDlg( NULL, _hInst, _pSh,
  1309. this,
  1310. _pTscSet,
  1311. fStartExpanded,
  1312. nStartTabIndex);
  1313. }
  1314. TRC_ASSERT(_pMainDlg, (TB,_T("Could not create main dialog")));
  1315. if (_pMainDlg)
  1316. {
  1317. if (_fFirstTimeToLogonDlg)
  1318. {
  1319. TRC_ASSERT(_hwndMainDialog == NULL,
  1320. (TB,(_T("Dialog exists before first time create!!!\n"))));
  1321. _pSh->SH_AutoFillBlankSettings(_pTscSet);
  1322. _hwndMainDialog = _pMainDlg->StartModeless();
  1323. ::ShowWindow( _hwndMainDialog, SW_RESTORE);
  1324. }
  1325. else
  1326. {
  1327. //
  1328. // Just show the dialog
  1329. //
  1330. TRC_ASSERT(_hwndMainDialog,
  1331. (TB,_T("_hwndMainDialog is not present")));
  1332. ::ShowWindow( _hwndMainDialog, SW_RESTORE);
  1333. SetForegroundWindow(_hwndMainDialog);
  1334. }
  1335. _fFirstTimeToLogonDlg = FALSE;
  1336. }
  1337. else
  1338. {
  1339. #ifdef OS_WINCE
  1340. SetCursor(LoadCursor(NULL, IDC_ARROW));
  1341. #endif
  1342. return FALSE;
  1343. }
  1344. }
  1345. #ifdef OS_WINCE
  1346. SetCursor(LoadCursor(NULL, IDC_ARROW));
  1347. #endif
  1348. DC_END_FN();
  1349. return TRUE;
  1350. }
  1351. LRESULT CContainerWnd::OnSysCommand(UINT uMsg, WPARAM wParam,
  1352. LPARAM lParam)
  1353. {
  1354. HRESULT hr = E_FAIL;
  1355. ULONG scCode = 0;
  1356. DC_BEGIN_FN("OnSysCommand");
  1357. #ifndef OS_WINCE
  1358. scCode = (LOWORD(wParam) & 0xFFF0);
  1359. if (scCode == SC_MAXIMIZE)
  1360. {
  1361. //
  1362. // If the remote resolution matches
  1363. // the current monitor then maximize
  1364. // becomes 'go fullscreen'
  1365. //
  1366. if ( IsRemoteResMatchMonitorSize() )
  1367. {
  1368. hr = _pTsClient->put_FullScreen( VARIANT_TRUE );
  1369. if (FAILED(hr))
  1370. {
  1371. TRC_ERR((TB,_T("put_FullScreen failed 0x%x\n"),
  1372. hr));
  1373. }
  1374. return 0;
  1375. }
  1376. else
  1377. {
  1378. //
  1379. // Default maximize behavior
  1380. //
  1381. return DefWindowProc( GetHwnd(), uMsg, wParam, lParam);
  1382. }
  1383. }
  1384. else if (scCode == SC_MINIMIZE)
  1385. {
  1386. //
  1387. // If we are minimizing while still fullscreen tell the shell
  1388. // we are no longer fullscreen otherwise it treats us as a rude
  1389. // app and nasty stuff happens. E.g. we get switched to and maximized
  1390. // on a timer.
  1391. //
  1392. if (_bContainerIsFullScreen) {
  1393. CUT::NotifyShellOfFullScreen( GetHwnd(),
  1394. FALSE,
  1395. &_pTaskBarList2,
  1396. &_fQueriedForTaskBarList2 );
  1397. }
  1398. }
  1399. else if (scCode == SC_RESTORE)
  1400. {
  1401. //
  1402. // If we are restoring and going back to Fscreen
  1403. // tell the shell to mark us
  1404. //
  1405. if (_bContainerIsFullScreen) {
  1406. CUT::NotifyShellOfFullScreen( GetHwnd(),
  1407. TRUE,
  1408. &_pTaskBarList2,
  1409. &_fQueriedForTaskBarList2 );
  1410. }
  1411. }
  1412. #endif
  1413. switch (DC_GET_WM_COMMAND_ID(wParam))
  1414. {
  1415. case UI_IDM_ABOUT:
  1416. {
  1417. // Show the about box dialog
  1418. CAboutDlg aboutDialog( GetHwnd(),
  1419. _hInst,
  1420. _pSh->GetCipherStrength(),
  1421. _pSh->GetControlVersionString());
  1422. aboutDialog.DoModal();
  1423. }
  1424. break;
  1425. case UI_IDM_HELP_ON_CLIENT:
  1426. {
  1427. //
  1428. // Display help for the connect dialog.
  1429. //
  1430. #ifndef OS_WINCE
  1431. TRC_NRM((TB, _T("Display the appropriate help page")));
  1432. if (GetHwnd() && _pSh)
  1433. {
  1434. _pSh->SH_DisplayClientHelp(
  1435. GetHwnd(),
  1436. HH_DISPLAY_TOPIC);
  1437. }
  1438. #endif
  1439. }
  1440. break;
  1441. #ifdef DC_DEBUG
  1442. case UI_IDM_BITMAPCACHEMONITOR:
  1443. {
  1444. //
  1445. // Toggle the Bitmap Cache Monitor setting.
  1446. //
  1447. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1448. if (_pTsClient)
  1449. {
  1450. IMsTscDebug* pDebugger = NULL;
  1451. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1452. if(SUCCEEDED(hr))
  1453. {
  1454. BOOL bmpCacheMonitor;
  1455. TRACE_HR(pDebugger->get_BitmapCacheMonitor(&bmpCacheMonitor));
  1456. if(SUCCEEDED(hr))
  1457. {
  1458. bmpCacheMonitor = !bmpCacheMonitor;
  1459. TRACE_HR(pDebugger->put_BitmapCacheMonitor(bmpCacheMonitor));
  1460. if(SUCCEEDED(hr))
  1461. {
  1462. CheckMenuItem(_hSystemMenu,
  1463. UI_IDM_BITMAPCACHEMONITOR,
  1464. bmpCacheMonitor ? MF_CHECKED : MF_UNCHECKED);
  1465. }
  1466. }
  1467. pDebugger->Release();
  1468. }
  1469. }
  1470. }
  1471. break;
  1472. case UI_IDM_HATCHBITMAPPDUDATA:
  1473. {
  1474. //
  1475. // Toggle the hatch bitmap PDU data setting.
  1476. //
  1477. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1478. if (_pTsClient)
  1479. {
  1480. IMsTscDebug* pDebugger = NULL;
  1481. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1482. if(SUCCEEDED(hr))
  1483. {
  1484. BOOL hatchBitmapPDU;
  1485. TRACE_HR(pDebugger->get_HatchBitmapPDU(&hatchBitmapPDU));
  1486. if(SUCCEEDED(hr))
  1487. {
  1488. hatchBitmapPDU = !hatchBitmapPDU;
  1489. TRACE_HR(pDebugger->put_HatchBitmapPDU(hatchBitmapPDU));
  1490. if(SUCCEEDED(hr))
  1491. {
  1492. CheckMenuItem(_hSystemMenu,
  1493. UI_IDM_HATCHBITMAPPDUDATA,
  1494. hatchBitmapPDU ? MF_CHECKED : MF_UNCHECKED);
  1495. }
  1496. }
  1497. pDebugger->Release();
  1498. }
  1499. }
  1500. }
  1501. break;
  1502. case UI_IDM_HATCHINDEXPDUDATA:
  1503. {
  1504. //
  1505. // Toggle the hatch index PDU data setting.
  1506. //
  1507. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1508. if (_pTsClient)
  1509. {
  1510. IMsTscDebug* pDebugger = NULL;
  1511. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1512. if(SUCCEEDED(hr))
  1513. {
  1514. BOOL hatchIndexPDU;
  1515. TRACE_HR(pDebugger->get_HatchIndexPDU(&hatchIndexPDU));
  1516. if(SUCCEEDED(hr))
  1517. {
  1518. hatchIndexPDU = !hatchIndexPDU;
  1519. TRACE_HR(pDebugger->put_HatchIndexPDU(hatchIndexPDU));
  1520. if(SUCCEEDED(hr))
  1521. {
  1522. CheckMenuItem(_hSystemMenu,
  1523. UI_IDM_HATCHINDEXPDUDATA,
  1524. hatchIndexPDU ? MF_CHECKED : MF_UNCHECKED);
  1525. }
  1526. }
  1527. pDebugger->Release();
  1528. }
  1529. }
  1530. }
  1531. break;
  1532. case UI_IDM_HATCHSSBORDERDATA:
  1533. {
  1534. //
  1535. // Toggle the hatch SSB order data setting.
  1536. //
  1537. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1538. if (_pTsClient)
  1539. {
  1540. IMsTscDebug* pDebugger = NULL;
  1541. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1542. if(SUCCEEDED(hr))
  1543. {
  1544. BOOL hatchSSBorder;
  1545. TRACE_HR(pDebugger->get_HatchSSBOrder(&hatchSSBorder));
  1546. if(SUCCEEDED(hr))
  1547. {
  1548. hatchSSBorder = !hatchSSBorder;
  1549. TRACE_HR(pDebugger->put_HatchSSBOrder(hatchSSBorder));
  1550. if(SUCCEEDED(hr))
  1551. {
  1552. CheckMenuItem(_hSystemMenu,
  1553. UI_IDM_HATCHSSBORDERDATA,
  1554. hatchSSBorder ? MF_CHECKED : MF_UNCHECKED);
  1555. }
  1556. }
  1557. pDebugger->Release();
  1558. }
  1559. }
  1560. }
  1561. break;
  1562. case UI_IDM_HATCHMEMBLTORDERDATA:
  1563. {
  1564. //
  1565. // Toggle the hatch memblt order data setting.
  1566. //
  1567. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1568. if (_pTsClient)
  1569. {
  1570. IMsTscDebug* pDebugger = NULL;
  1571. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1572. if(SUCCEEDED(hr))
  1573. {
  1574. BOOL hatchMemBlt;
  1575. TRACE_HR(pDebugger->get_HatchMembltOrder(&hatchMemBlt));
  1576. if(SUCCEEDED(hr))
  1577. {
  1578. hatchMemBlt = !hatchMemBlt;
  1579. hr = pDebugger->put_HatchMembltOrder(hatchMemBlt);
  1580. if(SUCCEEDED(hr))
  1581. {
  1582. CheckMenuItem(_hSystemMenu,
  1583. UI_IDM_HATCHMEMBLTORDERDATA,
  1584. hatchMemBlt ? MF_CHECKED : MF_UNCHECKED);
  1585. }
  1586. }
  1587. pDebugger->Release();
  1588. }
  1589. }
  1590. }
  1591. break;
  1592. case UI_IDM_LABELMEMBLTORDERS:
  1593. {
  1594. //
  1595. // Toggle the label memblt orders setting.
  1596. //
  1597. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1598. if (_pTsClient)
  1599. {
  1600. IMsTscDebug* pDebugger = NULL;
  1601. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1602. if(SUCCEEDED(hr))
  1603. {
  1604. BOOL labelMemBltOrders;
  1605. TRACE_HR(pDebugger->get_LabelMemblt(&labelMemBltOrders));
  1606. if(SUCCEEDED(hr))
  1607. {
  1608. labelMemBltOrders = !labelMemBltOrders;
  1609. hr = pDebugger->put_LabelMemblt(labelMemBltOrders);
  1610. if(SUCCEEDED(hr))
  1611. {
  1612. CheckMenuItem(_hSystemMenu,
  1613. UI_IDM_LABELMEMBLTORDERS,
  1614. labelMemBltOrders ? MF_CHECKED : MF_UNCHECKED);
  1615. }
  1616. }
  1617. pDebugger->Release();
  1618. }
  1619. }
  1620. }
  1621. break;
  1622. case UI_IDM_MALLOCFAILURE:
  1623. {
  1624. //
  1625. // Malloc failures dialog box
  1626. //
  1627. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1628. if (_pTsClient)
  1629. {
  1630. IMsTscDebug* pDebugger = NULL;
  1631. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1632. if(SUCCEEDED(hr))
  1633. {
  1634. LONG failPercent;
  1635. TRACE_HR(pDebugger->get_MallocFailuresPercent(&failPercent));
  1636. if(SUCCEEDED(hr))
  1637. {
  1638. CMallocDbgDlg mallocFailDialog(GetHwnd(), _hInst, (DCINT)failPercent,
  1639. FALSE); //don't use malloc huge dialog
  1640. if (IDOK == mallocFailDialog.DoModal())
  1641. {
  1642. failPercent = mallocFailDialog.GetFailPercent();
  1643. TRC_NRM((TB,_T("Setting malloc FAILURE PERCENT to:%d"), failPercent));
  1644. TRACE_HR(pDebugger->put_MallocFailuresPercent(failPercent));
  1645. }
  1646. }
  1647. pDebugger->Release();
  1648. }
  1649. }
  1650. }
  1651. break;
  1652. case UI_IDM_MALLOCHUGEFAILURE:
  1653. {
  1654. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1655. if (_pTsClient)
  1656. {
  1657. IMsTscDebug* pDebugger = NULL;
  1658. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1659. if(SUCCEEDED(hr))
  1660. {
  1661. LONG failPercent;
  1662. TRACE_HR(pDebugger->get_MallocHugeFailuresPercent(&failPercent));
  1663. if(SUCCEEDED(hr))
  1664. {
  1665. CMallocDbgDlg mallocFailDialog(GetHwnd(), _hInst, (DCINT)failPercent,
  1666. TRUE); //use malloc huge dialog
  1667. if (IDOK == mallocFailDialog.DoModal())
  1668. {
  1669. failPercent = mallocFailDialog.GetFailPercent();
  1670. TRC_NRM((TB,_T("Setting malloc FAILURE PERCENT to:%d"), failPercent));
  1671. TRACE_HR(pDebugger->put_MallocHugeFailuresPercent(failPercent));
  1672. }
  1673. }
  1674. pDebugger->Release();
  1675. }
  1676. }
  1677. }
  1678. break;
  1679. case UI_IDM_NETWORKTHROUGHPUT:
  1680. {
  1681. //
  1682. // Limit net thruput
  1683. //
  1684. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1685. if (_pTsClient)
  1686. {
  1687. IMsTscDebug* pDebugger = NULL;
  1688. TRACE_HR(_pTsClient->get_Debugger(&pDebugger));
  1689. if(SUCCEEDED(hr))
  1690. {
  1691. LONG netThruPut;
  1692. TRACE_HR(pDebugger->get_NetThroughput(&netThruPut));
  1693. if(SUCCEEDED(hr))
  1694. {
  1695. CThruPutDlg thruPutDialog(GetHwnd(), _hInst, (DCINT)netThruPut);
  1696. if (IDOK == thruPutDialog.DoModal())
  1697. {
  1698. netThruPut = thruPutDialog.GetNetThruPut();
  1699. TRC_NRM((TB,_T("Setting thruput to:%d"), netThruPut));
  1700. TRACE_HR(pDebugger->put_NetThroughput(netThruPut));
  1701. }
  1702. }
  1703. pDebugger->Release();
  1704. }
  1705. }
  1706. }
  1707. break;
  1708. #ifdef SMART_SIZING
  1709. case UI_IDM_SMARTSIZING:
  1710. {
  1711. TRC_ASSERT(_pTsClient,(TB, _T("_pTsClient is NULL on syscommand")));
  1712. if (_pTsClient)
  1713. {
  1714. IMsRdpClientAdvancedSettings* pAdvSettings = NULL;
  1715. HRESULT hr = _pTsClient->get_AdvancedSettings2(&pAdvSettings);
  1716. VARIANT_BOOL fSmartSizing;
  1717. if (SUCCEEDED(hr)) {
  1718. hr = pAdvSettings->get_SmartSizing(&fSmartSizing);
  1719. }
  1720. if (SUCCEEDED(hr)) {
  1721. fSmartSizing = !fSmartSizing;
  1722. hr = pAdvSettings->put_SmartSizing(fSmartSizing);
  1723. }
  1724. if (SUCCEEDED(hr)) {
  1725. #ifndef OS_WINCE // no menus available
  1726. CheckMenuItem(_hSystemMenu,
  1727. UI_IDM_SMARTSIZING,
  1728. fSmartSizing ? MF_CHECKED : MF_UNCHECKED);
  1729. #endif
  1730. _pTscSet->SetSmartSizing(fSmartSizing);
  1731. }
  1732. if (pAdvSettings != NULL) {
  1733. pAdvSettings->Release();
  1734. }
  1735. }
  1736. }
  1737. break;
  1738. #endif // SMART_SIZING
  1739. #endif //DC_DEBUG
  1740. default:
  1741. {
  1742. DefWindowProc(GetHwnd(), uMsg, wParam, lParam);
  1743. }
  1744. break;
  1745. }
  1746. DC_END_FN();
  1747. return 0;
  1748. }
  1749. #ifndef OS_WINCE
  1750. LRESULT CContainerWnd::OnInitMenu(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1751. {
  1752. ::EnableMenuItem((HMENU)wParam, SC_MOVE ,
  1753. _bContainerIsFullScreen ? MF_GRAYED : MF_ENABLED);
  1754. return 0;
  1755. }
  1756. LRESULT CContainerWnd::OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1757. {
  1758. DC_BEGIN_FN("OnGetMinMaxInfo");
  1759. LPMINMAXINFO pinfo = (LPMINMAXINFO)lParam;
  1760. DCSIZE maxTrack;
  1761. RECT rc;
  1762. GetClientRect( GetHwnd(), &rc);
  1763. CalcTrackingMaxWindowSize( rc.right - rc.left,
  1764. rc.bottom - rc.top,
  1765. &maxTrack.width,
  1766. &maxTrack.height );
  1767. pinfo->ptMaxTrackSize.x = maxTrack.width;
  1768. pinfo->ptMaxTrackSize.y = maxTrack.height;
  1769. DC_END_FN();
  1770. return 0;
  1771. }
  1772. #endif //OS_WINCE
  1773. LRESULT CContainerWnd::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1774. {
  1775. UNREFERENCED_PARAMETER(uMsg);
  1776. UNREFERENCED_PARAMETER(wParam);
  1777. UNREFERENCED_PARAMETER(lParam);
  1778. DC_BEGIN_FN("OnSetFocus");
  1779. //
  1780. // Give focus to the control when we get activated
  1781. // Except when we are in a size/move modal loop
  1782. //
  1783. if (IsOkToToggleFocus() && !_fInSizeMove)
  1784. {
  1785. TRC_NRM((TB,_T("Passing focus to control")));
  1786. ::SetFocus(_pWndView->GetHwnd());
  1787. }
  1788. DC_END_FN();
  1789. return 0;
  1790. }
  1791. LRESULT CContainerWnd::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1792. {
  1793. UNREFERENCED_PARAMETER(uMsg);
  1794. UNREFERENCED_PARAMETER(lParam);
  1795. DC_BEGIN_FN("OnActivate");
  1796. if (WA_INACTIVE != wParam)
  1797. {
  1798. //Give focus to the control when we get activated
  1799. if (IsOkToToggleFocus() && !_fInSizeMove)
  1800. {
  1801. TRC_NRM((TB,_T("Passing focus to control")));
  1802. ::SetFocus(_pWndView->GetHwnd());
  1803. }
  1804. }
  1805. #ifdef OS_WINCE
  1806. AutoHideCE(_pWndView->GetHwnd(), wParam);
  1807. #endif
  1808. DC_END_FN();
  1809. return 0;
  1810. }
  1811. LRESULT CContainerWnd::OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1812. {
  1813. DC_BEGIN_FN("OnWindowPosChanging");
  1814. #ifndef OS_WINCE
  1815. LPWINDOWPOS lpwp;
  1816. DCUINT maxWidth;
  1817. DCUINT maxHeight;
  1818. DCUINT cliWidth, cliHeight;
  1819. if (_bContainerIsFullScreen)
  1820. {
  1821. TRC_DBG((TB, _T("WM_WINDOWPOSCHANGING; no-op when fullscreen")));
  1822. DC_QUIT;
  1823. }
  1824. lpwp = (LPWINDOWPOS)lParam;
  1825. if (lpwp->flags & SWP_NOSIZE)
  1826. {
  1827. //
  1828. // We're not sizing so we don't care.
  1829. //
  1830. TRC_DBG((TB, _T("WM_WINDOWPOSCHANGING, but no sizing")));
  1831. DC_QUIT;
  1832. }
  1833. TRC_DBG((TB, _T("WM_WINDOWPOSCHANGING, new size %dx%d"),
  1834. lpwp->cx, lpwp->cy));
  1835. //
  1836. // Max size of the window changes depending on w/not scroll bars are
  1837. // visible. The control has properties for scroll bar visibility but
  1838. // we can't use these because the control is a child window so there is
  1839. // no guarantee that it has update it's scroll bar visilibity in response
  1840. // to this message yet.
  1841. // which means there could be a moment where a gray border appears around the
  1842. // client container window.
  1843. // instead we just compute if scroll bars would be visible in the core.
  1844. //
  1845. cliWidth = lpwp->cx;
  1846. cliHeight = lpwp->cy;
  1847. CalcTrackingMaxWindowSize( cliWidth, cliHeight, &maxWidth, &maxHeight);
  1848. //
  1849. // Restrict size of window
  1850. //
  1851. if ((DCUINT)lpwp->cx > maxWidth)
  1852. {
  1853. RECT rect;
  1854. //
  1855. // Clip the width - reset SWP_NOSIZE as a size change is
  1856. // required.
  1857. //
  1858. TRC_NRM((TB, _T("Clip cx from %u to %u"), lpwp->cx, maxWidth));
  1859. lpwp->cx = maxWidth;
  1860. lpwp->flags &= ~SWP_NOSIZE;
  1861. GetWindowRect(GetHwnd(), &rect);
  1862. if (lpwp->x < rect.left)
  1863. {
  1864. //
  1865. // If dragging left then we need to stop at the point
  1866. // where the window is maxWidth wide. Reset SWP_NOMOVE
  1867. // as a move is required.
  1868. //
  1869. TRC_NRM((TB, _T("Reset x from %d to %d"),
  1870. lpwp->x, rect.right-maxWidth));
  1871. lpwp->x = rect.right - maxWidth;
  1872. lpwp->flags &= ~SWP_NOMOVE;
  1873. }
  1874. }
  1875. if ((DCUINT)lpwp->cy > maxHeight)
  1876. {
  1877. RECT rect;
  1878. //
  1879. // Clip the height - reset SWP_NOSIZE as a size change is
  1880. // required.
  1881. //
  1882. TRC_NRM((TB, _T("Clip cy from %u to %u"), lpwp->cy, maxHeight));
  1883. lpwp->cy = maxHeight;
  1884. lpwp->flags &= ~SWP_NOSIZE;
  1885. GetWindowRect( GetHwnd(),&rect);
  1886. if (lpwp->y < rect.top)
  1887. {
  1888. //
  1889. // If dragging upward then we need to stop at the point
  1890. // where the window is maxHeight high. Reset SWP_NOMOVE
  1891. // as a move is required.
  1892. //
  1893. TRC_NRM((TB, _T("Reset y from %d to %d"),
  1894. lpwp->y, rect.bottom-maxHeight));
  1895. lpwp->y = rect.bottom - maxHeight;
  1896. lpwp->flags &= ~SWP_NOMOVE;
  1897. }
  1898. }
  1899. #endif //OS_WINCE
  1900. DC_EXIT_POINT:
  1901. DC_END_FN();
  1902. return 0;
  1903. }
  1904. DCVOID CContainerWnd::OnConnected()
  1905. {
  1906. USES_CONVERSION;
  1907. HRESULT hr;
  1908. BOOL fFullScreen = FALSE;
  1909. VARIANT_BOOL vbfFScreen = VARIANT_FALSE;
  1910. DC_BEGIN_FN("OnConnected");
  1911. EnterEventHandler();
  1912. //Signal that we've connected at least once
  1913. _fHaveConnected = TRUE;
  1914. SET_CONTWND_STATE(stateConnected);
  1915. _successConnectCount++;
  1916. SetConnectionSuccessFlag();
  1917. //
  1918. /// Make sure the 'connecting...' dialog is gone.
  1919. //
  1920. if (!IsUsingDialogUI() && ::IsWindow(_hwndStatusDialog))
  1921. {
  1922. PostMessage( _hwndStatusDialog, WM_CLOSE, __LINE__, 0xBEEBBAAB);
  1923. }
  1924. if (::IsWindow(_hwndMainDialog))
  1925. {
  1926. //
  1927. //Inform the dialog that connection has happened
  1928. //
  1929. PostMessage(_hwndMainDialog, WM_TSC_CONNECTED, 0, 0);
  1930. ShowWindow( _hwndMainDialog, SW_HIDE);
  1931. }
  1932. TCHAR fullFrameTitleStr[SH_FRAME_TITLE_RESOURCE_MAX_LENGTH +
  1933. SH_REGSESSION_MAX_LENGTH];
  1934. TCHAR frameTitleString[SH_FRAME_TITLE_RESOURCE_MAX_LENGTH];
  1935. //
  1936. // Set the window title.
  1937. // include the session name (unless we're on the default file)
  1938. //
  1939. if (_tcscmp(_szPathToDefaultFile,
  1940. _pTscSet->GetFileName()))
  1941. {
  1942. if (LoadString( _hInst,
  1943. UI_IDS_FRAME_TITLE_CONNECTED,
  1944. frameTitleString,
  1945. SH_FRAME_TITLE_RESOURCE_MAX_LENGTH ))
  1946. {
  1947. TCHAR szSessionName[MAX_PATH];
  1948. if (!_pSh->GetRegSessionSpecified())
  1949. {
  1950. //
  1951. // Session name is parsed from the current
  1952. // connection file.
  1953. //
  1954. CSH::SH_GetNameFromPath(_pTscSet->GetFileName(),
  1955. szSessionName,
  1956. SIZECHAR(szSessionName));
  1957. }
  1958. else
  1959. {
  1960. _tcsncpy(szSessionName, _pSh->GetRegSession(),
  1961. SIZECHAR(szSessionName));
  1962. }
  1963. DC_TSPRINTF(fullFrameTitleStr,
  1964. frameTitleString,
  1965. szSessionName,
  1966. _pTscSet->GetFlatConnectString());
  1967. }
  1968. else
  1969. {
  1970. TRC_ERR((TB,_T("Failed to find UI frame title")));
  1971. fullFrameTitleStr[0] = (DCTCHAR) 0;
  1972. }
  1973. }
  1974. else
  1975. {
  1976. // Title does not include session name
  1977. if (LoadString( _hInst,
  1978. UI_IDS_FRAME_TITLE_CONNECTED_DEFAULT,
  1979. frameTitleString,
  1980. SH_FRAME_TITLE_RESOURCE_MAX_LENGTH ))
  1981. {
  1982. DC_TSPRINTF(fullFrameTitleStr,
  1983. frameTitleString,
  1984. _pTscSet->GetFlatConnectString());
  1985. }
  1986. else
  1987. {
  1988. TRC_ERR((TB,_T("Failed to find UI frame title")));
  1989. fullFrameTitleStr[0] = (DCTCHAR) 0;
  1990. }
  1991. }
  1992. SetWindowText( GetHwnd(), fullFrameTitleStr);
  1993. //
  1994. // Inform the control of the window title (used when it goes fullscreen)
  1995. //
  1996. OLECHAR* poleTitle = T2OLE(fullFrameTitleStr);
  1997. TRC_ASSERT( poleTitle, (TB, _T("T2OLE failed on poleTitle\n")));
  1998. if (poleTitle)
  1999. {
  2000. hr = _pTsClient->put_FullScreenTitle( poleTitle);
  2001. if (FAILED(hr))
  2002. {
  2003. TRC_ABORT((TB,_T("put_FullScreenTitle failed\n")));
  2004. }
  2005. }
  2006. hr = _pTsClient->get_FullScreen( &vbfFScreen);
  2007. if (SUCCEEDED(hr))
  2008. {
  2009. fFullScreen = (vbfFScreen != VARIANT_FALSE);
  2010. }
  2011. else
  2012. {
  2013. TRC_ABORT((TB,_T("get_FullScreen failed\n")));
  2014. }
  2015. PWINDOWPLACEMENT pwndplc = _pTscSet->GetWindowPlacement();
  2016. if (pwndplc)
  2017. {
  2018. #ifndef OS_WINCE
  2019. EnsureWindowIsCompletelyOnScreen( &pwndplc->rcNormalPosition );
  2020. TRC_ASSERT(pwndplc->rcNormalPosition.right -
  2021. pwndplc->rcNormalPosition.left,
  2022. (TB,_T("0 width")));
  2023. TRC_ASSERT(pwndplc->rcNormalPosition.bottom -
  2024. pwndplc->rcNormalPosition.top,
  2025. (TB,_T("0 height")));
  2026. #endif
  2027. }
  2028. #ifndef OS_WINCE
  2029. if (!fFullScreen)
  2030. {
  2031. if (!SetWindowPlacement( GetHwnd(), pwndplc))
  2032. {
  2033. TRC_ABORT((TB,_T("Failed to set window placement")));
  2034. }
  2035. }
  2036. #endif
  2037. #ifndef OS_WINCE
  2038. WINDOWPLACEMENT* pWndPlc = _pTscSet->GetWindowPlacement();
  2039. INT defaultShowWindowFlag = SW_SHOWNORMAL;
  2040. if(1 == _successConnectCount)
  2041. {
  2042. //On first connection, override the
  2043. //window placement with startup info (if specified)
  2044. //Use the 'A' version to avoid wrapping
  2045. //we only care about numeric fields anyway
  2046. STARTUPINFOA si;
  2047. GetStartupInfoA(&si);
  2048. if((si.dwFlags & STARTF_USESHOWWINDOW) &&
  2049. si.wShowWindow != SW_SHOWNORMAL)
  2050. {
  2051. defaultShowWindowFlag = si.wShowWindow;
  2052. }
  2053. }
  2054. if (pWndPlc)
  2055. {
  2056. if(SW_SHOWNORMAL != defaultShowWindowFlag)
  2057. {
  2058. pWndPlc->showCmd = defaultShowWindowFlag;
  2059. }
  2060. ShowWindow( GetHwnd(), pWndPlc->showCmd);
  2061. }
  2062. else
  2063. {
  2064. ShowWindow( GetHwnd(), defaultShowWindowFlag);
  2065. }
  2066. #else //OS_WINCE
  2067. ShowWindow( GetHwnd(), SW_SHOWNORMAL);
  2068. #endif //OS_WINCE
  2069. _fClientWindowIsUp = TRUE;
  2070. LeaveEventHandler();
  2071. DC_END_FN();
  2072. }
  2073. DCVOID CContainerWnd::OnLoginComplete()
  2074. {
  2075. DC_BEGIN_FN("OnLoginComplete");
  2076. EnterEventHandler();
  2077. _fLoginComplete = TRUE;
  2078. LeaveEventHandler();
  2079. DC_END_FN();
  2080. }
  2081. DCVOID CContainerWnd::OnDisconnected(DCUINT discReason)
  2082. {
  2083. DC_BEGIN_FN("OnDisconnected");
  2084. #ifndef OS_WINCE
  2085. HRESULT hr;
  2086. #endif
  2087. UINT mainDiscReason;
  2088. ExtendedDisconnectReasonCode extendedDiscReason;
  2089. EnterEventHandler();
  2090. if(FAILED(_pTsClient->get_ExtendedDisconnectReason(&extendedDiscReason)))
  2091. {
  2092. extendedDiscReason = exDiscReasonNoInfo;
  2093. }
  2094. //
  2095. // We just got disconnected as part of the connection
  2096. //
  2097. SET_CONTWND_STATE(stateNotConnected);
  2098. //
  2099. // Once we've been disconnected can go through
  2100. // close again
  2101. //
  2102. _fPreventClose = FALSE;
  2103. //
  2104. // Make sure the 'connecting...' dialog is gone.
  2105. //
  2106. if (!IsUsingDialogUI() && ::IsWindow(_hwndStatusDialog))
  2107. {
  2108. ::PostMessage(_hwndStatusDialog, WM_CLOSE, 0, 0);
  2109. }
  2110. if (IsUsingDialogUI() && ::IsWindow(_hwndMainDialog))
  2111. {
  2112. //Inform dialog of disconnection
  2113. PostMessage(_hwndMainDialog, WM_TSC_DISCONNECTED, 0, 0);
  2114. }
  2115. //
  2116. // If this is a user-initiated disconnect, don't do a popup.
  2117. //
  2118. mainDiscReason = NL_GET_MAIN_REASON_CODE(discReason);
  2119. if (((discReason != UI_MAKE_DISCONNECT_ERR(UI_ERR_NORMAL_DISCONNECT)) &&
  2120. (mainDiscReason != NL_DISCONNECT_REMOTE_BY_USER) &&
  2121. (mainDiscReason != NL_DISCONNECT_LOCAL)) ||
  2122. (exDiscReasonReplacedByOtherConnection == extendedDiscReason))
  2123. {
  2124. TRC_ERR((TB, _T("Unexpected disconnect - inform user")));
  2125. //Normal disconnect dialog displayed
  2126. if (!_fClientWindowIsUp && ::IsWindow(_hwndMainDialog))
  2127. {
  2128. // If the connection dialog is around, we need to get that to
  2129. // display the error popup, otherwise the popup won't be modal
  2130. // and could get left lying around. That can cause state
  2131. // problems with the client.
  2132. //
  2133. // It would be nice to use SendMessage here, so that we always
  2134. // block at this point when displaying the dialog. However,
  2135. // using SendMessage results in a disconnect dialog that is not
  2136. // modal with respect to the connect dialog.
  2137. //
  2138. // However, because PostMessage is asynchronous, the dialog box
  2139. // procedure calls back into CContainerWnd to finish the disconnection
  2140. // process.
  2141. TRC_NRM((TB, _T("Connection dialog present - use it to show popup")));
  2142. ::PostMessage(_hwndMainDialog, UI_SHOW_DISC_ERR_DLG,
  2143. discReason,
  2144. (LPARAM)extendedDiscReason);
  2145. }
  2146. else
  2147. {
  2148. TRC_NRM((TB, _T("Connection dialog not present - do popup here")));
  2149. CDisconnectedDlg disconDlg(GetHwnd(), _hInst, this);
  2150. disconDlg.SetDisconnectReason( discReason);
  2151. disconDlg.SetExtendedDiscReason( extendedDiscReason);
  2152. disconDlg.DoModal();
  2153. }
  2154. }
  2155. else
  2156. {
  2157. //
  2158. // Pickup settings that the server may have updated
  2159. //
  2160. HRESULT hr = _pTscSet->GetUpdatesFromControl(_pTsClient);
  2161. if (FAILED(hr))
  2162. {
  2163. TRC_ERR((TB,_T("GetUpdatesFromControl failed")));
  2164. }
  2165. if( GetConnectionSuccessFlag() )
  2166. {
  2167. //
  2168. // Update the MRU list if we just
  2169. // disconnected from a successful connect
  2170. //
  2171. _pTscSet->UpdateRegMRU((LPTSTR)_pTscSet->GetFlatConnectString());
  2172. }
  2173. if (::IsWindow(_hwndMainDialog))
  2174. {
  2175. ::SendMessage( _hwndMainDialog, WM_UPDATEFROMSETTINGS,0,0);
  2176. }
  2177. //
  2178. // If login has completed then we should exit the app on
  2179. // disconnection.
  2180. //
  2181. FinishDisconnect(_fLoginComplete);
  2182. }
  2183. _fClientWindowIsUp = FALSE;
  2184. LeaveEventHandler();
  2185. DC_END_FN();
  2186. }
  2187. LRESULT CContainerWnd::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam)
  2188. {
  2189. DC_BEGIN_FN("OnClose");
  2190. HRESULT hr;
  2191. BOOL fShouldClose = FALSE;
  2192. //Don't allow more than one close
  2193. //This mainly fixes problem in stress where
  2194. //we get posted more than one close message
  2195. if (_fPreventClose)
  2196. {
  2197. fShouldClose = FALSE;
  2198. TRC_ERR((TB,_T("More than one WM_CLOSE msg was received!!!")));
  2199. return 0;
  2200. }
  2201. _fPreventClose = TRUE;
  2202. if (InControlEventHandler())
  2203. {
  2204. //
  2205. // Don't allow the close we are in a code path that fired
  2206. // from the control. Without this, we sometimes see the client
  2207. // receiving close notifications from tclient while a disconnected
  2208. // dialog is up (i.e in an OnDicsconnected handler) - destroying
  2209. // the control at this time causes bad things to happen during
  2210. // the return into the control (which has now been deleted).
  2211. //
  2212. TRC_ERR((TB,_T("OnClose called during a control event handler")));
  2213. fShouldClose = FALSE;
  2214. return 0;
  2215. }
  2216. if (_fInOnCloseHandler)
  2217. {
  2218. //
  2219. // STRESS fix:
  2220. // Don't allow nested Closes
  2221. // can happen if the main window receives a WM_CLOSE
  2222. // message while a dialog is up... Somehow the stress dll
  2223. // sends us repeated WM_CLOSE
  2224. //
  2225. //
  2226. TRC_ERR((TB,_T("Nested OnClose detected, bailing out")));
  2227. fShouldClose = FALSE;
  2228. return 0;
  2229. }
  2230. _fInOnCloseHandler = TRUE;
  2231. if (_pTsClient)
  2232. {
  2233. ControlCloseStatus ccs;
  2234. hr = _pTsClient->RequestClose( &ccs );
  2235. if(SUCCEEDED(hr))
  2236. {
  2237. if (controlCloseCanProceed == ccs)
  2238. {
  2239. //Immediate close
  2240. fShouldClose = TRUE;
  2241. }
  2242. else if (controlCloseWaitForEvents == ccs)
  2243. {
  2244. // Wait for events from control
  2245. // e.g ConfirmClose
  2246. fShouldClose = FALSE;
  2247. _fClosePending = TRUE;
  2248. }
  2249. }
  2250. }
  2251. else
  2252. {
  2253. //
  2254. // Allow close to prevent hang if client load failed
  2255. //
  2256. TRC_ERR((TB,_T("No _pTsClient loaded, allow close anyway")));
  2257. fShouldClose = TRUE;
  2258. }
  2259. if (fShouldClose)
  2260. {
  2261. //
  2262. // Only save out MRU if last connection
  2263. // was successful
  2264. //
  2265. if (GetConnectionSuccessFlag())
  2266. {
  2267. DCBOOL bRet = _pTscSet->SaveRegSettings();
  2268. TRC_ASSERT(bRet, (TB, _T("SaveRegSettings\n")));
  2269. }
  2270. //Proceed with the close.
  2271. return DefWindowProc( GetHwnd(), uMsg, wParam, lParam);
  2272. }
  2273. _fInOnCloseHandler = FALSE;
  2274. DC_END_FN();
  2275. return 0;
  2276. }
  2277. //
  2278. // This handles the tail end of the disconnection.
  2279. // it may be called back from the Disconnecting dialog box
  2280. //
  2281. // Params:
  2282. // fExit - If true exit the app otherwise go back
  2283. // to the connection UI
  2284. //
  2285. DCBOOL CContainerWnd::FinishDisconnect(BOOL fExit)
  2286. {
  2287. DC_BEGIN_FN("FinishDisconnect");
  2288. //
  2289. // Hide the main window, do this twice because the first ShowWindow
  2290. // may be ignored if the window is maximized
  2291. //
  2292. if (GetHwnd())
  2293. {
  2294. ShowWindow( GetHwnd(),SW_HIDE);
  2295. ShowWindow( GetHwnd(),SW_HIDE);
  2296. }
  2297. //
  2298. // Just exit if:
  2299. // 1) we autoconnected
  2300. // or
  2301. // 2) A close is pending e.g we got disconnected
  2302. // because the user hit the close button
  2303. // or
  2304. // 3) The caller has determined that the client should exit
  2305. //
  2306. if (_pSh->GetAutoConnect() || _fClosePending || fExit)
  2307. {
  2308. PostMessage( GetHwnd(),WM_CLOSE, __LINE__, 0xBEEBBEEB);
  2309. }
  2310. else if (::IsWindow(_hwndMainDialog))
  2311. {
  2312. //
  2313. // Bring up the connect dialog for
  2314. // the next connections
  2315. //
  2316. ::ShowWindow( _hwndMainDialog, SW_SHOWNORMAL);
  2317. SetForegroundWindow(_hwndMainDialog);
  2318. //
  2319. // Trigger an update
  2320. //
  2321. InvalidateRect(_hwndMainDialog, NULL, TRUE);
  2322. UpdateWindow(_hwndMainDialog);
  2323. SendMessage(_hwndMainDialog, WM_TSC_RETURNTOCONUI,
  2324. 0L, 0L);
  2325. }
  2326. else
  2327. {
  2328. //If we get here it means we didn't autoconnect
  2329. //i.e we started with the connect UI, but somehow the
  2330. //connect UI has now disappeared
  2331. TRC_ABORT((TB,_T("Connect dialog is gone")));
  2332. }
  2333. DC_END_FN();
  2334. return TRUE;
  2335. }
  2336. //
  2337. // Handle event from control requesting
  2338. // we go fullscreen
  2339. //
  2340. //
  2341. DCVOID CContainerWnd::OnEnterFullScreen()
  2342. {
  2343. DCUINT32 style;
  2344. LONG wID;
  2345. WINDOWPLACEMENT* pWindowPlacement = NULL;
  2346. HRESULT hr = E_FAIL;
  2347. // multi-monitor support
  2348. RECT screenRect;
  2349. DC_BEGIN_FN("OnEnterFullScreen");
  2350. //
  2351. //Go full screen
  2352. //
  2353. EnterEventHandler();
  2354. //Save setting for next connection
  2355. _pTscSet->SetStartFullScreen(TRUE);
  2356. if (_bContainerIsFullScreen)
  2357. {
  2358. //Nothing to do
  2359. DC_QUIT;
  2360. }
  2361. #ifndef OS_WINCE
  2362. ::LockWindowUpdate(GetHwnd());
  2363. #endif
  2364. _bContainerIsFullScreen = TRUE;
  2365. #if !defined(OS_WINCE)
  2366. if (_hSystemMenu)
  2367. {
  2368. //
  2369. // We need to show the system menu so that the ts icon
  2370. // appears in the taskbar. But we need MOVE to be disabled
  2371. // when fullscreen
  2372. //
  2373. //EnableMenuItem(_hSystemMenu, SC_MOVE, MF_GRAYED);
  2374. }
  2375. #endif
  2376. #ifndef OS_WINCE
  2377. pWindowPlacement = _pTscSet->GetWindowPlacement();
  2378. TRC_ASSERT(pWindowPlacement, (TB, _T("pWindowPlacement is NULL\n")));
  2379. //
  2380. // Store the current window state (only if the client window is up)
  2381. //
  2382. if (pWindowPlacement && _fClientWindowIsUp)
  2383. {
  2384. GetWindowPlacement(GetHwnd(), pWindowPlacement);
  2385. }
  2386. #endif
  2387. //
  2388. // Take away the title bar and borders
  2389. //
  2390. style = GetWindowLong( GetHwnd(),GWL_STYLE );
  2391. #if !defined(OS_WINCE) || defined(OS_WINCE_NONFULLSCREEN)
  2392. style &= ~(WS_DLGFRAME |
  2393. WS_THICKFRAME | WS_BORDER |
  2394. WS_MAXIMIZEBOX);
  2395. #else // !defined(OS_WINCE) || defined(OS_WINCE_NONFULLSCREEN)
  2396. style &= ~(WS_DLGFRAME | WS_SYSMENU | WS_BORDER);
  2397. #endif // !defined(OS_WINCE) || defined(OS_WINCE_NONFULLSCREEN)
  2398. SetWindowLong( GetHwnd(),GWL_STYLE, style );
  2399. //
  2400. // Set the window ID (to remove the menu titles).
  2401. //
  2402. wID = SetWindowLong( GetHwnd(),GWL_ID, 0 );
  2403. //
  2404. // Note that two calls to SetWindowPos are required here in order to
  2405. // adjust the position to allow for frame removal and also to correctly
  2406. // set the Z-ordering.
  2407. //
  2408. // default screen size
  2409. CSH::MonitorRectFromNearestRect(
  2410. &pWindowPlacement->rcNormalPosition, &screenRect );
  2411. //
  2412. // Reposition and size the window with the frame changes, and place at
  2413. // the top of the Z-order (by not setting SWP_NOOWNERZORDER or
  2414. // SWP_NOZORDER and specifying HWND_TOP).
  2415. //
  2416. SetWindowPos( GetHwnd(),
  2417. HWND_TOP,
  2418. screenRect.left, screenRect.top,
  2419. screenRect.right - screenRect.left,
  2420. screenRect.bottom - screenRect.top,
  2421. SWP_NOACTIVATE | SWP_FRAMECHANGED );
  2422. //
  2423. // Reposition the window again - otherwise the fullscreen window is
  2424. // positioned as if it still had borders.
  2425. //
  2426. SetWindowPos( GetHwnd(),
  2427. NULL,
  2428. screenRect.left, screenRect.top,
  2429. 0, 0,
  2430. SWP_NOZORDER | SWP_NOACTIVATE |
  2431. SWP_NOOWNERZORDER | SWP_NOSIZE );
  2432. #ifndef OS_WINCE
  2433. ::LockWindowUpdate(NULL);
  2434. //Notify the shell that we've gone fullscreen
  2435. CUT::NotifyShellOfFullScreen( GetHwnd(),
  2436. TRUE,
  2437. &_pTaskBarList2,
  2438. &_fQueriedForTaskBarList2 );
  2439. #endif //OS_WINCE
  2440. DC_EXIT_POINT:
  2441. LeaveEventHandler();
  2442. DC_END_FN();
  2443. }
  2444. DCVOID CContainerWnd::OnLeaveFullScreen()
  2445. {
  2446. DC_BEGIN_FN("OnLeaveFullScreen");
  2447. #ifndef OS_WINCE
  2448. DCUINT32 style;
  2449. RECT rect;
  2450. DCUINT width;
  2451. DCUINT height;
  2452. WINDOWPLACEMENT* pWindowPlacement = NULL;
  2453. TRC_NRM((TB, _T("Entering Windowed Mode")));
  2454. EnterEventHandler();
  2455. //Save setting for next connection
  2456. _pTscSet->SetStartFullScreen(FALSE);
  2457. if (!_bContainerIsFullScreen)
  2458. {
  2459. //Nothing to do
  2460. DC_QUIT;
  2461. }
  2462. ::LockWindowUpdate(GetHwnd());
  2463. _bContainerIsFullScreen = FALSE;
  2464. RecalcMaxWindowSize();
  2465. //
  2466. // Check that the saved window placement values aren't too big for the
  2467. // client size we're using, and set the window placement accordingly.
  2468. //
  2469. pWindowPlacement = _pTscSet->GetWindowPlacement();
  2470. TRC_ASSERT(pWindowPlacement, (TB, _T("pWindowPlacement is NULL\n")));
  2471. if (!pWindowPlacement)
  2472. {
  2473. DC_QUIT;
  2474. }
  2475. width = pWindowPlacement->rcNormalPosition.right -
  2476. pWindowPlacement->rcNormalPosition.left;
  2477. height = pWindowPlacement->rcNormalPosition.bottom -
  2478. pWindowPlacement->rcNormalPosition.top;
  2479. if (width > _maxMainWindowSize.width)
  2480. {
  2481. pWindowPlacement->rcNormalPosition.right =
  2482. pWindowPlacement->rcNormalPosition.left +
  2483. _maxMainWindowSize.width;
  2484. }
  2485. if (height > _maxMainWindowSize.height)
  2486. {
  2487. pWindowPlacement->rcNormalPosition.bottom =
  2488. pWindowPlacement->rcNormalPosition.top +
  2489. _maxMainWindowSize.height;
  2490. }
  2491. if (!::SetWindowPlacement( GetHwnd(), pWindowPlacement))
  2492. {
  2493. TRC_ABORT((TB,_T("Failed to set window placement")));
  2494. }
  2495. //
  2496. // In case the window is maximised make sure it knows what size to be
  2497. //
  2498. GetWindowRect( GetHwnd(),&rect);
  2499. //
  2500. // Reset the style
  2501. //
  2502. style = GetWindowLong( GetHwnd(),GWL_STYLE );
  2503. style |= (WS_DLGFRAME |
  2504. WS_THICKFRAME | WS_BORDER |
  2505. WS_MAXIMIZEBOX);
  2506. SetWindowLong( GetHwnd(),GWL_STYLE,
  2507. style );
  2508. #if !defined(OS_WINCE)
  2509. if (_hSystemMenu)
  2510. {
  2511. //
  2512. // We need to show the system menu so that the ts icon
  2513. // appears in the taskbar. But we need MOVE to be disabled
  2514. // when fullscreen
  2515. //
  2516. //EnableMenuItem(_hSystemMenu, SC_MOVE, MF_ENABLED);
  2517. }
  2518. #endif
  2519. //
  2520. // Tell the window frame to recalculate its size.
  2521. // Position below any topmost windows (but above any non-topmost
  2522. // windows.
  2523. //
  2524. SetWindowPos( GetHwnd(),
  2525. HWND_NOTOPMOST,
  2526. 0, 0,
  2527. rect.right - rect.left,
  2528. rect.bottom - rect.top,
  2529. SWP_NOMOVE | SWP_NOACTIVATE | SWP_FRAMECHANGED );
  2530. //
  2531. // If we are in res match mode
  2532. // then after a leave full screen
  2533. // restore the window so the next state
  2534. // is 'maximize' i.e get back in fullscreen
  2535. //
  2536. if(IsRemoteResMatchMonitorSize())
  2537. {
  2538. ShowWindow( GetHwnd(), SW_SHOWNORMAL);
  2539. }
  2540. ::LockWindowUpdate(NULL);
  2541. // Notify shell that we've left fullscreen
  2542. //Notify the shell that we've gone fullscreen
  2543. CUT::NotifyShellOfFullScreen( GetHwnd(),
  2544. FALSE,
  2545. &_pTaskBarList2,
  2546. &_fQueriedForTaskBarList2 );
  2547. DC_EXIT_POINT:
  2548. LeaveEventHandler();
  2549. #else //OS_WINCE
  2550. TRC_ABORT((TB,_T("clshell can't leave fullscreen in CE")));
  2551. #endif
  2552. DC_END_FN();
  2553. return;
  2554. }
  2555. //
  2556. // Notify the server a device change, either a new device comes online
  2557. // or an existing redirected device goes away
  2558. //
  2559. LRESULT CContainerWnd::OnDeviceChange(HWND hWnd,
  2560. UINT uMsg,
  2561. WPARAM wParam,
  2562. LPARAM lParam)
  2563. {
  2564. HRESULT hr;
  2565. IMsRdpClientNonScriptable *pNonScriptable;
  2566. UNREFERENCED_PARAMETER(hWnd);
  2567. DC_BEGIN_FN("OnDeviceChange");
  2568. if(_pTsClient)
  2569. {
  2570. hr = _pTsClient->QueryInterface(IID_IMsRdpClientNonScriptable,
  2571. (PVOID *)&pNonScriptable);
  2572. if (SUCCEEDED(hr)) {
  2573. pNonScriptable->NotifyRedirectDeviceChange(wParam, lParam);
  2574. pNonScriptable->Release();
  2575. }
  2576. }
  2577. else
  2578. {
  2579. TRC_NRM((TB,_T("Got OnDeviceChange but _pTsClient not available")));
  2580. }
  2581. DC_END_FN();
  2582. return 0;
  2583. }
  2584. //
  2585. // Invoked to handle WM_HELP (i.e F1 key)
  2586. //
  2587. LRESULT CContainerWnd::OnHelp(HWND hWnd,
  2588. UINT uMsg,
  2589. WPARAM wParam,
  2590. LPARAM lParam)
  2591. {
  2592. DC_BEGIN_FN("OnHelp");
  2593. //
  2594. // Don't pop help if we are connected
  2595. // as the F1 should then go to the session. Otherwise
  2596. // you get both local and remote help. Note the user can
  2597. // still launch help while connected but they need to
  2598. // select it from the system menu.
  2599. //
  2600. if (GetHwnd() && _pSh && !IsConnected())
  2601. {
  2602. _pSh->SH_DisplayClientHelp(
  2603. GetHwnd(),
  2604. HH_DISPLAY_TOPIC);
  2605. }
  2606. DC_END_FN();
  2607. return 0L;
  2608. }
  2609. //
  2610. // Forward the palette change to the control
  2611. //
  2612. LRESULT CContainerWnd::OnPaletteChange(UINT uMsg,
  2613. WPARAM wParam,
  2614. LPARAM lParam)
  2615. {
  2616. DC_BEGIN_FN("OnPaletteChange");
  2617. if (_pWndView) {
  2618. HWND hwndCtl = _pWndView->GetHwnd();
  2619. return SendMessage(hwndCtl, uMsg, wParam, lParam);
  2620. }
  2621. DC_END_FN();
  2622. return 0;
  2623. }
  2624. //
  2625. // Give focus back to the control
  2626. // when the system menu is dismissed
  2627. //
  2628. LRESULT CContainerWnd::OnExitMenuLoop(UINT uMsg,
  2629. WPARAM wParam,
  2630. LPARAM lParam)
  2631. {
  2632. DC_BEGIN_FN("OnExitMenuLoop");
  2633. //Give focus to the control when we get activated
  2634. if (IsOkToToggleFocus())
  2635. {
  2636. TRC_NRM((TB,_T("Setting focus to control")));
  2637. ::SetFocus(_pWndView->GetHwnd());
  2638. }
  2639. DC_END_FN();
  2640. return 0;
  2641. }
  2642. LRESULT CContainerWnd::OnCaptureChanged(UINT uMsg,
  2643. WPARAM wParam,
  2644. LPARAM lParam)
  2645. {
  2646. DC_BEGIN_FN("OnCaptureChanged");
  2647. //
  2648. // We don't always get WM_EXITSIZE move but we seem
  2649. // to always get WM_CAPTURECHANGED so go on that
  2650. //
  2651. if (_fInSizeMove)
  2652. {
  2653. TRC_NRM((TB, _T("Capture Changed when in Size/Move")));
  2654. _fInSizeMove = FALSE;
  2655. if (IsOkToToggleFocus())
  2656. {
  2657. TRC_NRM((TB,_T("Setting focus to control")));
  2658. ::SetFocus(_pWndView->GetHwnd());
  2659. }
  2660. }
  2661. DC_END_FN();
  2662. return 0;
  2663. }
  2664. LRESULT CContainerWnd::OnEnterSizeMove(UINT uMsg,
  2665. WPARAM wParam,
  2666. LPARAM lParam)
  2667. {
  2668. DC_BEGIN_FN("OnEnterSizeMove");
  2669. //
  2670. // We're entering the modal size/move loop
  2671. // need to give the focus back to the frame window
  2672. // otherwise win9x will not move the window because
  2673. // the IH is on another thread and the modal loop on 9x
  2674. // will never see the arrow keystrokes
  2675. //
  2676. _fInSizeMove = TRUE;
  2677. //
  2678. // Note: Only do this toggle on 9x as that is
  2679. // where it is needed. NT can handle the async modal
  2680. // size/move loop and so there is no problem with ALT-SPACE.
  2681. //
  2682. // The reason for not doing this toggle on NT is that
  2683. // it causes multiple a flurry of focus gain/loses
  2684. // that rapidly hide/unhide the Cicero language bar.
  2685. //
  2686. if (IsOkToToggleFocus() && _fRunningOnWin9x)
  2687. {
  2688. TRC_NRM((TB,_T("Setting focus to frame")));
  2689. ::SetFocus(GetHwnd());
  2690. }
  2691. DC_END_FN();
  2692. return 0;
  2693. }
  2694. LRESULT CContainerWnd::OnExitSizeMove(UINT uMsg,
  2695. WPARAM wParam,
  2696. LPARAM lParam)
  2697. {
  2698. DC_BEGIN_FN("OnExitSizeMove");
  2699. _fInSizeMove = FALSE;
  2700. //
  2701. // Note: Only do this toggle on 9x as that is
  2702. // where it is needed. NT can handle the async modal
  2703. // size/move loop and so there is no problem with ALT-SPACE.
  2704. //
  2705. // The reason for not doing this toggle on NT is that
  2706. // it causes multiple a flurry of focus gain/loses
  2707. // that rapidly hide/unhide the Cicero language bar.
  2708. //
  2709. if (IsOkToToggleFocus() && _fRunningOnWin9x)
  2710. {
  2711. TRC_NRM((TB,_T("Setting focus to control")));
  2712. ::SetFocus(_pWndView->GetHwnd());
  2713. }
  2714. DC_END_FN();
  2715. return 0;
  2716. }
  2717. //
  2718. // Handle system color change notifications
  2719. //
  2720. LRESULT CContainerWnd::OnSysColorChange(UINT uMsg,
  2721. WPARAM wParam,
  2722. LPARAM lParam)
  2723. {
  2724. DC_BEGIN_FN("OnSysColorChange");
  2725. //
  2726. // Foward the message to the ActiveX control
  2727. //
  2728. if (_pWndView && _pWndView->GetHwnd())
  2729. {
  2730. return SendMessage(_pWndView->GetHwnd(), uMsg, wParam, lParam);
  2731. }
  2732. DC_END_FN();
  2733. return 0;
  2734. }
  2735. //
  2736. // Predicate that returns true if it's ok to toggle
  2737. // focus between the control and the frame
  2738. //
  2739. BOOL CContainerWnd::IsOkToToggleFocus()
  2740. {
  2741. DC_BEGIN_FN("IsOkToToggleFocus");
  2742. BOOL fDialogIsUp = ::IsWindow(_hwndMainDialog);
  2743. if (_fClientWindowIsUp &&
  2744. (!fDialogIsUp ||
  2745. (fDialogIsUp && !::IsWindowVisible(_hwndMainDialog))))
  2746. {
  2747. return TRUE;
  2748. }
  2749. else
  2750. {
  2751. return FALSE;
  2752. }
  2753. DC_END_FN();
  2754. }
  2755. //
  2756. // Notification from control that a fatal error has occurred
  2757. //
  2758. DCVOID CContainerWnd::OnFatalError(LONG errorCode)
  2759. {
  2760. DC_BEGIN_FN("OnFatalError");
  2761. EnterEventHandler();
  2762. DisplayFatalError(GetFatalString(errorCode), errorCode);
  2763. LeaveEventHandler();
  2764. DC_END_FN();
  2765. }
  2766. //
  2767. // Warning notifcation from control
  2768. // e.g if bitmap cache is corrutpted a warning is fired
  2769. // these are non-fatal errors
  2770. //
  2771. DCVOID CContainerWnd::OnWarning(LONG warnCode)
  2772. {
  2773. DC_BEGIN_FN("OnWarning");
  2774. EnterEventHandler();
  2775. TRC_ERR((TB, _T("WARNING recevived from core: %d"), warnCode));
  2776. switch (warnCode)
  2777. {
  2778. case DC_WARN_BITMAPCACHE_CORRUPTED:
  2779. {
  2780. //
  2781. // Display the bitmap cache warning dialog
  2782. //
  2783. CCacheWrnDlg bmpCacheWrn(GetHwnd(), _hInst);
  2784. bmpCacheWrn.DoModal();
  2785. }
  2786. break;
  2787. }
  2788. LeaveEventHandler();
  2789. DC_END_FN();
  2790. }
  2791. //Notification from the control
  2792. //of new width/height of the desktop
  2793. //this can change from the requested width/height in the event
  2794. //of a shadow operation
  2795. DCVOID CContainerWnd::OnRemoteDesktopSizeNotify(long width, long height)
  2796. {
  2797. DC_BEGIN_FN("OnRemoteDesktopSizeNotify");
  2798. EnterEventHandler();
  2799. TRC_NRM((TB, _T("OnRemoteDesktopSizeNotify: width %d. height %d"), width, height));
  2800. SetCurrentDesktopWidth(width);
  2801. SetCurrentDesktopHeight(height);
  2802. RecalcMaxWindowSize();
  2803. //
  2804. //Trigger an update of the window size
  2805. //in response to the shadow
  2806. //but only do this if the client window is up otherwise the following
  2807. //bug can happen:
  2808. // -Launch connection
  2809. // -As part of initial connection but before OnConnected is fired we
  2810. // get a RemoteDesktopSizeNotify. This causes us to update the
  2811. // windowplacement
  2812. // -thrashing user selected options
  2813. //
  2814. if(_fClientWindowIsUp && !_bContainerIsFullScreen)
  2815. {
  2816. SetWindowPos( GetHwnd(),
  2817. NULL,
  2818. 0, 0,
  2819. width,
  2820. height,
  2821. SWP_NOZORDER | SWP_NOMOVE |
  2822. SWP_NOACTIVATE | SWP_NOOWNERZORDER );
  2823. }
  2824. LeaveEventHandler();
  2825. DC_END_FN();
  2826. }
  2827. //
  2828. // Calculate the current maximum tracking
  2829. // size limits for the window's client area given
  2830. // a current client area size (cliWidth, cliHeight).
  2831. //
  2832. // Returns the maxX, maxY values in *pMaxX, *pMaxY
  2833. //
  2834. // The max is not static because we have logic that
  2835. // expands the width/height if only one scroll bar
  2836. // is visible.
  2837. //
  2838. // This value is _not_ the same as the Maximized size
  2839. // of the window
  2840. //
  2841. void CContainerWnd::CalcTrackingMaxWindowSize(UINT /*in*/ cliWidth,
  2842. UINT /*in*/ cliHeight,
  2843. UINT* /*out*/ pMaxWidth,
  2844. UINT* /*out*/ pMaxHeight)
  2845. {
  2846. BOOL fHScroll, fVScroll;
  2847. DC_BEGIN_FN("CalcTrackingMaxWindowSize");
  2848. //
  2849. // Calculate the neccessity for the scrollbars
  2850. //
  2851. fHScroll = fVScroll = FALSE;
  2852. if ( (cliWidth >= GetCurrentDesktopWidth()) &&
  2853. (cliHeight >= GetCurrentDesktopHeight()) )
  2854. {
  2855. fHScroll = fVScroll = FALSE;
  2856. }
  2857. else if ( (cliWidth < GetCurrentDesktopWidth()) &&
  2858. (cliHeight >=
  2859. (GetCurrentDesktopHeight() + GetSystemMetrics(SM_CYHSCROLL))) )
  2860. {
  2861. fHScroll = TRUE;
  2862. }
  2863. else if ( (cliHeight < GetCurrentDesktopHeight()) &&
  2864. (cliWidth >=
  2865. (GetCurrentDesktopWidth() + GetSystemMetrics(SM_CXVSCROLL))) )
  2866. {
  2867. fVScroll = TRUE;
  2868. }
  2869. else
  2870. {
  2871. fHScroll = fVScroll = TRUE;
  2872. }
  2873. *pMaxWidth = _maxMainWindowSize.width;
  2874. *pMaxHeight = _maxMainWindowSize.height;
  2875. if (fHScroll)
  2876. {
  2877. *pMaxHeight += GetSystemMetrics(SM_CYHSCROLL);
  2878. }
  2879. if (fVScroll)
  2880. {
  2881. *pMaxWidth += GetSystemMetrics(SM_CXVSCROLL);
  2882. }
  2883. TRC_NRM((TB,_T("Calculated max width/height - %d,%d"),
  2884. *pMaxWidth, *pMaxHeight));
  2885. DC_END_FN();
  2886. }
  2887. //
  2888. // Name: GetFatalString
  2889. //
  2890. // Purpose: Return the specified error string
  2891. //
  2892. // Returns: Error string
  2893. //
  2894. // Params: IN errorID - error code
  2895. //
  2896. //
  2897. LPTSTR CContainerWnd::GetFatalString(DCINT errorID)
  2898. {
  2899. DC_BEGIN_FN("GetFatalString");
  2900. DC_IGNORE_PARAMETER(errorID);
  2901. //
  2902. // Load the fatal error string from resources - this is more specific
  2903. // for a debug build.
  2904. //
  2905. if (LoadString(_hInst,
  2906. #ifdef DC_DEBUG
  2907. UI_ERR_STRING_ID(errorID),
  2908. #else
  2909. UI_FATAL_ERROR_MESSAGE,
  2910. #endif
  2911. _errorString,
  2912. UI_ERR_MAX_STRLEN) == 0)
  2913. {
  2914. TRC_ABORT((TB, _T("Missing resource string (Fatal Error) %d"),
  2915. errorID));
  2916. DC_TSTRCPY(_errorString, _T("Invalid resources"));
  2917. }
  2918. DC_END_FN();
  2919. return(_errorString);
  2920. } // UI_GetFatalString
  2921. //
  2922. // Name: UI_DisplayFatalError
  2923. //
  2924. // Purpose: Display a fatal error popup
  2925. //
  2926. // Returns: None
  2927. //
  2928. // Params: IN errorString - error text
  2929. //
  2930. //
  2931. VOID CContainerWnd::DisplayFatalError(PDCTCHAR errorString, DCINT error)
  2932. {
  2933. DCINT action;
  2934. DCTCHAR titleString[UI_ERR_MAX_STRLEN];
  2935. DCTCHAR fullTitleString[UI_ERR_MAX_STRLEN];
  2936. DC_BEGIN_FN("UI_DisplayFatalError");
  2937. //
  2938. // Load the title string from resources.
  2939. //
  2940. if (LoadString(_hInst,
  2941. UI_FATAL_ERR_TITLE_ID,
  2942. titleString,
  2943. UI_ERR_MAX_STRLEN) == 0)
  2944. {
  2945. //
  2946. // Continue to display the error anyway on retail build.
  2947. //
  2948. TRC_ABORT((TB, _T("Missing resource string (Fatal Error title)")));
  2949. DC_TSTRCPY(titleString, _T("Fatal Error"));
  2950. }
  2951. DC_TSPRINTF(fullTitleString, titleString, error);
  2952. action = MessageBox( GetHwnd(), errorString,
  2953. fullTitleString,
  2954. #ifdef DC_DEBUG
  2955. MB_ABORTRETRYIGNORE |
  2956. #else
  2957. MB_OK |
  2958. #endif
  2959. MB_ICONSTOP |
  2960. MB_APPLMODAL |
  2961. MB_SETFOREGROUND );
  2962. TRC_NRM((TB, _T("Action %d selected"), action));
  2963. switch (action)
  2964. {
  2965. case IDOK:
  2966. case IDABORT:
  2967. {
  2968. #ifdef OS_WIN32
  2969. TerminateProcess(GetCurrentProcess(), 0);
  2970. #else //OS_WIN32
  2971. exit(1);
  2972. #endif //OS_WIN32
  2973. }
  2974. break;
  2975. case IDRETRY:
  2976. {
  2977. DebugBreak();
  2978. }
  2979. break;
  2980. case IDIGNORE:
  2981. default:
  2982. {
  2983. TRC_ALT((TB, _T("User chose to ignore fatal error!")));
  2984. }
  2985. break;
  2986. }
  2987. DC_END_FN();
  2988. return;
  2989. } // UI_DisplayFatalError
  2990. //
  2991. // Called to flag entry into an event handler
  2992. // Does not need to use InterlockedIncrement
  2993. // only called on the STA thread.
  2994. //
  2995. LONG CContainerWnd::EnterEventHandler()
  2996. {
  2997. return ++_cInEventHandlerCount;
  2998. }
  2999. //
  3000. // Called to flag leaving an event handler
  3001. // Does not need to use InterlockedIncrement
  3002. // only called on the STA thread.
  3003. //
  3004. LONG CContainerWnd::LeaveEventHandler()
  3005. {
  3006. DC_BEGIN_FN("LeaveEventHandler");
  3007. _cInEventHandlerCount--;
  3008. TRC_ASSERT(_cInEventHandlerCount >= 0,
  3009. (TB,_T("_cInEventHandlerCount went negative %d"),
  3010. _cInEventHandlerCount));
  3011. DC_END_FN();
  3012. return _cInEventHandlerCount;
  3013. }
  3014. //
  3015. // Tests if we are in an event handler
  3016. //
  3017. BOOL CContainerWnd::InControlEventHandler()
  3018. {
  3019. return _cInEventHandlerCount;
  3020. }
  3021. //
  3022. // Return TRUE if we're using the connection UI
  3023. // note that when autoconnecting to a connectoid, we
  3024. // don't use the UI
  3025. //
  3026. BOOL CContainerWnd::IsUsingDialogUI()
  3027. {
  3028. return _hwndMainDialog ? TRUE : FALSE;
  3029. }
  3030. VOID CContainerWnd::OnRequestMinimize()
  3031. {
  3032. HWND hwnd = GetHwnd();
  3033. if(::IsWindow(hwnd))
  3034. {
  3035. #ifndef OS_WINCE
  3036. //
  3037. // Mimimize the window (don't just use CloseWindow() as
  3038. // that doesn't pass the focus on to the next app
  3039. //
  3040. PostMessage( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0L);
  3041. #else
  3042. ShowWindow(hwnd, SW_MINIMIZE);
  3043. #endif
  3044. }
  3045. }
  3046. //
  3047. // Event handler from control
  3048. // prompt user if they really want to close their session
  3049. //
  3050. //
  3051. HRESULT CContainerWnd::OnConfirmClose(BOOL* pfConfirmClose)
  3052. {
  3053. EnterEventHandler();
  3054. CShutdownDlg shutdownDlg(GetHwnd(), _hInst, _pSh);
  3055. INT dlgRetVal = shutdownDlg.DoModal();
  3056. //If the message is not handled then the default proc destroys the window
  3057. if ( IDCANCEL == dlgRetVal )
  3058. {
  3059. *pfConfirmClose = FALSE; //reset this
  3060. _fPreventClose = FALSE;
  3061. _fClosePending = FALSE;
  3062. }
  3063. else
  3064. {
  3065. *pfConfirmClose = TRUE;
  3066. //
  3067. // Allow close to go thru
  3068. // we will receive an OnDisconnected when it
  3069. // has completed
  3070. //
  3071. }
  3072. LeaveEventHandler();
  3073. return S_OK;
  3074. }
  3075. //
  3076. // Check if the remote desktop size
  3077. // matches the current monitor's size
  3078. // return TRUE on match
  3079. //
  3080. //
  3081. BOOL CContainerWnd::IsRemoteResMatchMonitorSize()
  3082. {
  3083. RECT rc;
  3084. DC_BEGIN_FN("IsRemoteResMatchMonitorSize");
  3085. CSH::MonitorRectFromHwnd(GetHwnd(),&rc);
  3086. if( (rc.right - rc.left) == (LONG)GetCurrentDesktopWidth() &&
  3087. (rc.bottom - rc.top) == (LONG)GetCurrentDesktopHeight() )
  3088. {
  3089. return TRUE;
  3090. }
  3091. else
  3092. {
  3093. return FALSE;
  3094. }
  3095. DC_END_FN();
  3096. }
  3097. #ifndef OS_WINCE
  3098. BOOL CALLBACK GetDesktopRegionEnumProc (HMONITOR hMonitor, HDC hdcMonitor,
  3099. RECT* prc, LPARAM lpUserData)
  3100. {
  3101. MONITORINFO monitorInfo;
  3102. monitorInfo.cbSize = sizeof(monitorInfo);
  3103. if (GetMonitorInfo(hMonitor, &monitorInfo) != 0)
  3104. {
  3105. HRGN hRgnDesktop;
  3106. CRGN rgnMonitorWork(monitorInfo.rcWork);
  3107. hRgnDesktop = *reinterpret_cast<CRGN*>(lpUserData);
  3108. CombineRgn(hRgnDesktop, hRgnDesktop, rgnMonitorWork, RGN_OR);
  3109. }
  3110. return(TRUE);
  3111. }
  3112. #endif
  3113. #ifndef OS_WINCE
  3114. //
  3115. // This code shamelessley modified from shell code
  3116. // \shell\browseui\shbrows2.cpp
  3117. //
  3118. // from vtan: This function exists because user32 only determines
  3119. // whether ANY part of the window is visible on the screen. It's possible to
  3120. // place a window without an accessible title. Pretty useless when using the
  3121. // mouse and forces the user to use the VERY un-intuitive alt-space.
  3122. //
  3123. void CContainerWnd::EnsureWindowIsCompletelyOnScreen(RECT *prc)
  3124. {
  3125. HMONITOR hMonitor;
  3126. MONITORINFO monitorInfo;
  3127. DC_BEGIN_FN("EnsureWindowIsCompletelyOnScreen");
  3128. // First find the monitor that the window resides on using GDI.
  3129. hMonitor = MonitorFromRect(prc, MONITOR_DEFAULTTONEAREST);
  3130. TRC_ASSERT(hMonitor, (TB,_T("hMonitor is null")));
  3131. monitorInfo.cbSize = sizeof(monitorInfo);
  3132. if (GetMonitorInfo(hMonitor, &monitorInfo) != 0)
  3133. {
  3134. LONG lOffsetX, lOffsetY;
  3135. RECT *prcWorkArea, rcIntersect;
  3136. CRGN rgnDesktop, rgnIntersect, rgnWindow;
  3137. // Because the WINDOWPLACEMENT rcNormalPosition field is in WORKAREA
  3138. // co-ordinates this causes a displacement problem. If the taskbar is
  3139. // at the left or top of the primary monitor the RECT passed even though
  3140. // at (0, 0) may be at (100, 0) on the primary monitor in GDI co-ordinates
  3141. // and GetMonitorInfo() will return a MONITORINFO in GDI co-ordinates.
  3142. // The safest generic algorithm is to offset the WORKAREA RECT into GDI
  3143. // co-ordinates and apply the algorithm in that system. Then offset the
  3144. // WORKAREA RECT back into WORKAREA co-ordinates.
  3145. prcWorkArea = &monitorInfo.rcWork;
  3146. if (EqualRect(&monitorInfo.rcMonitor, &monitorInfo.rcWork) == 0)
  3147. {
  3148. // Taskbar is on this monitor - offset required.
  3149. lOffsetX = prcWorkArea->left - monitorInfo.rcMonitor.left;
  3150. lOffsetY = prcWorkArea->top - monitorInfo.rcMonitor.top;
  3151. }
  3152. else
  3153. {
  3154. // Taskbar is NOT on this monitor - no offset required.
  3155. lOffsetX = lOffsetY = 0;
  3156. }
  3157. OffsetRect(prc, lOffsetX, lOffsetY);
  3158. // WORKAREA RECT is in GDI co-ordinates. Apply the algorithm.
  3159. // Check to see if this window already fits the current visible screen
  3160. // area. This is a direct region comparison.
  3161. // This enumeration may cause a performance problem. In the event that
  3162. // a cheap and simple solution is required it would be best to do a
  3163. // RECT intersection with the monitor and the window before resorting
  3164. // to the more expensive region comparison. Get vtan if necessary.
  3165. EnumDisplayMonitors(NULL, NULL, GetDesktopRegionEnumProc,
  3166. reinterpret_cast<LPARAM>(&rgnDesktop));
  3167. rgnWindow.SetRegion(*prc);
  3168. CombineRgn(rgnIntersect, rgnDesktop, rgnWindow, RGN_AND);
  3169. if (EqualRgn(rgnIntersect, rgnWindow) == 0)
  3170. {
  3171. LONG lDeltaX, lDeltaY;
  3172. // Some part of the window is not within the visible desktop region
  3173. // Move it until it all fits. Size it if it's too big.
  3174. lDeltaX = lDeltaY = 0;
  3175. if (prc->left < prcWorkArea->left)
  3176. lDeltaX = prcWorkArea->left - prc->left;
  3177. if (prc->top < prcWorkArea->top)
  3178. lDeltaY = prcWorkArea->top - prc->top;
  3179. if (prc->right > prcWorkArea->right)
  3180. lDeltaX = prcWorkArea->right - prc->right;
  3181. if (prc->bottom > prcWorkArea->bottom)
  3182. lDeltaY = prcWorkArea->bottom - prc->bottom;
  3183. OffsetRect(prc, lDeltaX, lDeltaY);
  3184. IntersectRect(&rcIntersect, prc, prcWorkArea);
  3185. CopyRect(prc, &rcIntersect);
  3186. }
  3187. // Put WORKAREA RECT back into WORKAREA co-ordinates.
  3188. OffsetRect(prc, -lOffsetX, -lOffsetY);
  3189. }
  3190. DC_END_FN();
  3191. }
  3192. #endif
  3193. //
  3194. // Predicate returns TRUE if connected
  3195. //
  3196. BOOL CContainerWnd::IsConnected()
  3197. {
  3198. BOOL fConnected = FALSE;
  3199. HRESULT hr = E_FAIL;
  3200. short connectionState = 0;
  3201. DC_BEGIN_FN("IsConnected");
  3202. if (_pTsClient)
  3203. {
  3204. TRACE_HR(_pTsClient->get_Connected( & connectionState ));
  3205. if(SUCCEEDED(hr))
  3206. {
  3207. fConnected = (connectionState != 0);
  3208. }
  3209. }
  3210. DC_END_FN();
  3211. return fConnected;
  3212. }
  3213. //
  3214. // Main window procedure for the top-level window
  3215. //
  3216. LRESULT CALLBACK CContainerWnd::WndProc(HWND hwnd,UINT uMsg,
  3217. WPARAM wParam, LPARAM lParam)
  3218. {
  3219. switch(uMsg)
  3220. {
  3221. case WM_CREATE:
  3222. return OnCreate( uMsg, wParam, lParam);
  3223. break;
  3224. case WM_DESTROY:
  3225. return OnDestroy( hwnd, uMsg, wParam, lParam);
  3226. break;
  3227. case WM_SIZE:
  3228. return OnSize( uMsg, wParam, lParam);
  3229. break;
  3230. case WM_MOVE:
  3231. return OnMove( uMsg, wParam, lParam);
  3232. break;
  3233. case WM_COMMAND:
  3234. return OnCommand( uMsg, wParam, lParam);
  3235. break;
  3236. #ifndef OS_WINCE
  3237. case WM_WINDOWPOSCHANGING:
  3238. return OnWindowPosChanging(uMsg, wParam, lParam);
  3239. break;
  3240. #endif
  3241. case WM_CLOSE:
  3242. return OnClose(uMsg, wParam, lParam);
  3243. break;
  3244. case WM_SETFOCUS:
  3245. return OnSetFocus(uMsg, wParam, lParam);
  3246. break;
  3247. case WM_ACTIVATE:
  3248. return OnActivate(uMsg, wParam, lParam);
  3249. break;
  3250. case WM_SYSCOMMAND:
  3251. return OnSysCommand(uMsg, wParam, lParam);
  3252. break;
  3253. #ifndef OS_WINCE
  3254. case WM_INITMENU:
  3255. return OnInitMenu(uMsg, wParam, lParam);
  3256. break;
  3257. case WM_GETMINMAXINFO:
  3258. return OnGetMinMaxInfo(uMsg, wParam, lParam);
  3259. break;
  3260. #endif
  3261. case WM_NCDESTROY:
  3262. return OnNCDestroy(hwnd, uMsg, wParam, lParam);
  3263. break;
  3264. #ifndef OS_WINCE
  3265. case WM_DEVICECHANGE:
  3266. return OnDeviceChange(hwnd, uMsg, wParam, lParam);
  3267. break;
  3268. #endif
  3269. case WM_HELP:
  3270. return OnHelp(hwnd, uMsg, wParam, lParam);
  3271. break;
  3272. #ifdef OS_WINCE
  3273. case WM_QUERYNEWPALETTE: //intentional fall through. OnPaletteChange only calls SendMessage
  3274. #endif
  3275. case WM_PALETTECHANGED:
  3276. return OnPaletteChange(uMsg, wParam, lParam);
  3277. break;
  3278. case WM_EXITMENULOOP:
  3279. return OnExitMenuLoop(uMsg, wParam, lParam);
  3280. break;
  3281. #ifndef OS_WINCE
  3282. case WM_ENTERSIZEMOVE:
  3283. return OnEnterSizeMove(uMsg, wParam, lParam);
  3284. break;
  3285. case WM_EXITSIZEMOVE:
  3286. return OnExitSizeMove(uMsg, wParam, lParam);
  3287. break;
  3288. #endif
  3289. case WM_CAPTURECHANGED:
  3290. return OnCaptureChanged(uMsg, wParam, lParam);
  3291. break;
  3292. case WM_SYSCOLORCHANGE:
  3293. return OnSysColorChange(uMsg, wParam, lParam);
  3294. break;
  3295. default:
  3296. return DefWindowProc (hwnd, uMsg, wParam, lParam);
  3297. }
  3298. }