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

2173 lines
46 KiB

  1. // File: rtoolbar.cpp
  2. #include "precomp.h"
  3. #include "RToolbar.h"
  4. #include "GenContainers.h"
  5. #include "GenControls.h"
  6. #include "Conf.h"
  7. #include "ConfRoom.h"
  8. #include "RoomList.h"
  9. #include "particip.h"
  10. #include "VidView.h"
  11. #include "ProgressBar.h"
  12. #include "AudioCtl.h"
  13. #include "CallingBar.h"
  14. #include "resource.h"
  15. #include "topWindow.h"
  16. #include "dlgCall2.h"
  17. #include "ulswizrd.h"
  18. #include "audiowiz.h"
  19. #include "sdialdlg.h"
  20. #include "callto.h"
  21. #define ZeroArray(_a) ZeroMemory(_a, sizeof(_a))
  22. static void ShiftFocus(HWND hwndTop, BOOL bForward);
  23. class CRemoteVideo : public CVideoWindow
  24. {
  25. public:
  26. CRemoteVideo(BOOL bEmbedded = FALSE) :
  27. CVideoWindow(REMOTE, bEmbedded)
  28. {
  29. }
  30. // Stick the child in the lower-right corner of the window
  31. virtual void Layout()
  32. {
  33. CVideoWindow::Layout();
  34. HWND hwnd = GetWindow();
  35. HWND hwndLocal = GetFirstChild(hwnd);
  36. if (NULL != hwndLocal)
  37. {
  38. RECT rcRemote;
  39. GetClientRect(hwnd, &rcRemote);
  40. int left = rcRemote.right *5/8;
  41. int top = rcRemote.bottom *5/8;
  42. SetWindowPos(hwndLocal, NULL, left, top,
  43. rcRemote.right-left, rcRemote.bottom-top, SWP_NOZORDER);
  44. }
  45. }
  46. } ;
  47. // This just exists to send WM_NOTIFY messages back to the Roster
  48. class CRosterParent : public CFillWindow
  49. {
  50. private:
  51. CRoomListView *m_pRoster;
  52. void OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
  53. {
  54. POINT pt = { xPos, yPos };
  55. CRoomListView *pView = GetRoster();
  56. if ((NULL != pView) && (pView->GetHwnd() == hwndContext))
  57. {
  58. pView->OnPopup(pt);
  59. }
  60. FORWARD_WM_CONTEXTMENU(hwnd, hwndContext, xPos, yPos, CFillWindow::ProcessMessage);
  61. }
  62. inline LRESULT RosterNotify(CRoomListView *pRoster, UINT uMsg, WPARAM wParam, LPARAM lParam)
  63. {
  64. return(pRoster->OnNotify(wParam, lParam));
  65. }
  66. // Just forward to the Roster
  67. LRESULT OnNotify(HWND hwnd, int id, NMHDR *pHdr)
  68. {
  69. // pass on all notifications:
  70. if (ID_LISTVIEW == pHdr->idFrom)
  71. {
  72. CRoomListView *pView = GetRoster();
  73. if (NULL != pView)
  74. {
  75. // Forward to the roster
  76. return(FORWARD_WM_NOTIFY(pView, id, pHdr, RosterNotify));
  77. }
  78. }
  79. return(FORWARD_WM_NOTIFY(hwnd, id, pHdr, CFillWindow::ProcessMessage));
  80. }
  81. protected:
  82. ~CRosterParent()
  83. {
  84. // delete can handle NULL
  85. delete m_pRoster;
  86. }
  87. virtual LRESULT ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  88. {
  89. switch (uMsg)
  90. {
  91. HANDLE_MSG(hwnd, WM_NOTIFY, OnNotify);
  92. HANDLE_MSG(hwnd, WM_CONTEXTMENU, OnContextMenu);
  93. case WM_DESTROY:
  94. delete m_pRoster;
  95. m_pRoster = NULL;
  96. break;
  97. }
  98. return(CFillWindow::ProcessMessage(hwnd, uMsg, wParam, lParam));
  99. }
  100. public:
  101. CRosterParent() : m_pRoster(NULL) {}
  102. BOOL Create(HWND hwndParent)
  103. {
  104. m_pRoster = new CRoomListView();
  105. if (NULL == m_pRoster)
  106. {
  107. return(FALSE);
  108. }
  109. if (!CFillWindow::Create(hwndParent, 0))
  110. {
  111. return(FALSE);
  112. }
  113. return(m_pRoster->Create(GetWindow()));
  114. }
  115. CRoomListView *GetRoster() const
  116. {
  117. return(m_pRoster);
  118. }
  119. } ;
  120. CToolbar *CreateToolbar(
  121. CGenWindow *pParent,
  122. const Buttons buttons[]=NULL,
  123. int nButtons=0,
  124. LPARAM lHideModes=0,
  125. DWORD dwExStyle=0
  126. );
  127. #define ReleaseIt(pUnk) if (NULL != (pUnk)) { (pUnk)->Release(); (pUnk) = NULL; }
  128. enum CheckStates
  129. {
  130. Unchecked = 0,
  131. Checked = 1,
  132. } ;
  133. const static int MainHMargin = 8;
  134. const static int MainVMargin = 5;
  135. const static int MainGap = 4;
  136. const static int SunkenHMargin = 8;
  137. const static int SunkenVMargin = 2;
  138. const static int ButtonsGap = 12;
  139. const static int AudioMax = 100;
  140. const static int AudioVolMax = 0xffff;
  141. const static int AudioBump = 10;
  142. enum MainTimers
  143. {
  144. IDT_AUDIO = 1,
  145. } ;
  146. // Set these bits in the hide mode to hide in certain situations
  147. enum HideModes
  148. {
  149. Inherit = 0x0000,
  150. Normal = 0x0001,
  151. Compact = 0x0002,
  152. DataOnly = 0x0004,
  153. NoAVTB = 0x0008,
  154. Roster = 0x0010,
  155. AudioTuning = 0x0020,
  156. Dialing = 0x0040,
  157. Receiving = 0x0080,
  158. ReceivingWPiP = 0x0100,
  159. Previewing = 0x0200,
  160. Video = Receiving|ReceivingWPiP|Previewing,
  161. Ignore = 0x4000,
  162. IfNoChildren = 0x8000,
  163. } ;
  164. // Sets the hide mode bits on a window
  165. static inline void SetHideModes(CGenWindow *pWin, LPARAM modes)
  166. {
  167. if (NULL != pWin)
  168. {
  169. pWin->SetUserData(modes);
  170. }
  171. }
  172. // Gets the hide mode bits on a window
  173. static inline LPARAM GetHideModes(IGenWindow *pWin)
  174. {
  175. return(pWin->GetUserData());
  176. }
  177. CMainUI::CMainUI() :
  178. m_hbBack(NULL),
  179. m_eViewMode(ViewNormal),
  180. m_pLocalVideo(NULL),
  181. m_pRemoteVideo(NULL),
  182. m_pAudioMic(NULL),
  183. m_pAudioSpeaker(NULL),
  184. m_pRoster(NULL),
  185. m_pCalling(NULL),
  186. m_bDialing(FALSE),
  187. m_bAudioTuning(FALSE),
  188. m_bPreviewing(TRUE),
  189. m_bPicInPic(FALSE),
  190. m_bStateChanged(FALSE),
  191. m_bShowAVTB(FALSE)
  192. {
  193. }
  194. CMainUI::~CMainUI()
  195. {
  196. if (NULL != m_hbBack)
  197. {
  198. DeleteObject(m_hbBack);
  199. m_hbBack = NULL;
  200. }
  201. ReleaseIt(m_pLocalVideo);
  202. ReleaseIt(m_pRemoteVideo);
  203. ReleaseIt(m_pAudioMic);
  204. ReleaseIt(m_pAudioSpeaker);
  205. ReleaseIt(m_pRoster);
  206. ReleaseIt(m_pCalling);
  207. }
  208. void SplitBitmap(UINT nCols, UINT nRows, HBITMAP hbmSrc, HBITMAP hbmDst[])
  209. {
  210. BITMAP bm;
  211. GetObject(hbmSrc, sizeof(bm), &bm);
  212. int nWid = bm.bmWidth / nCols;
  213. int nHgt = bm.bmHeight / nRows;
  214. HDC hdcScreen = GetDC(NULL);
  215. HDC hdcSrc = CreateCompatibleDC(hdcScreen);
  216. HDC hdcDst = CreateCompatibleDC(hdcScreen);
  217. ReleaseDC(NULL, hdcScreen);
  218. if (NULL != hdcSrc && NULL != hdcDst)
  219. {
  220. SelectObject(hdcSrc, hbmSrc);
  221. for(UINT i=0; i<nRows; ++i)
  222. {
  223. for (UINT j=0; j<nCols; ++j)
  224. {
  225. HBITMAP hbmTemp = CreateCompatibleBitmap(hdcSrc, nWid, nHgt);
  226. if (NULL != hbmTemp)
  227. {
  228. SelectObject(hdcDst, hbmTemp);
  229. BitBlt(hdcDst, 0, 0, nWid, nHgt, hdcSrc, j*nWid, i*nHgt, SRCCOPY);
  230. }
  231. hbmDst[i*nCols + j] = hbmTemp;
  232. }
  233. }
  234. }
  235. DeleteDC(hdcSrc);
  236. DeleteDC(hdcDst);
  237. }
  238. // Helper function for adding a bunch of buttons to a parent window
  239. void AddButtons(
  240. CGenWindow *pParent, // The parent window
  241. const Buttons buttons[], // Array of structures describing the buttons
  242. int nButtons, // Number of buttons to create
  243. BOOL bTranslateColors, // Use system background colors
  244. CGenWindow *pCreated[], // Created CGenWindow's will be put here
  245. IButtonChange *pNotify // Notification of clicks
  246. )
  247. {
  248. if (NULL == buttons)
  249. {
  250. // Nothing to do
  251. return;
  252. }
  253. HWND hwnd = pParent->GetWindow();
  254. for (int i=0; i<nButtons; ++i)
  255. {
  256. if (NULL != pCreated)
  257. {
  258. // Init in case of error
  259. pCreated[i] = NULL;
  260. }
  261. CBitmapButton *pButton;
  262. pButton = new CBitmapButton();
  263. if (NULL == pButton)
  264. {
  265. continue;
  266. }
  267. // Create the actual window
  268. if (!pButton->Create(hwnd, buttons[i].idCommand, _Module.GetModuleInstance(),
  269. buttons[i].idbStates, bTranslateColors,
  270. buttons[i].nInputStates, buttons[i].nCustomStates, pNotify))
  271. {
  272. pButton->Release();
  273. continue;
  274. }
  275. // Save off the created button if requested
  276. if (NULL != pCreated)
  277. {
  278. // HACKHACK georgep: Not AddRef'ing; will let caller do that if interested
  279. pCreated[i] = pButton;
  280. }
  281. if (0 != buttons[i].idTooltip)
  282. {
  283. pButton->SetTooltip(RES2T(buttons[i].idTooltip));
  284. }
  285. // By default, do not hide individual buttons
  286. SetHideModes(pButton, Ignore);
  287. // Release our reference to the button
  288. pButton->Release();
  289. }
  290. }
  291. CToolbar *CreateToolbar(
  292. CGenWindow *pParent,
  293. const Buttons buttons[],
  294. int nButtons,
  295. LPARAM lHideModes,
  296. DWORD dwExStyle
  297. )
  298. {
  299. CToolbar *ret;
  300. ret = new CToolbar();
  301. if (NULL == ret)
  302. {
  303. return(NULL);
  304. }
  305. if (!ret->Create(pParent->GetWindow(), dwExStyle))
  306. {
  307. ret->Release();
  308. return(NULL);
  309. }
  310. SetHideModes(ret, lHideModes);
  311. AddButtons(ret, buttons, nButtons, TRUE);
  312. return(ret);
  313. }
  314. void CMainUI::CreateDialTB(CGenWindow *pParent)
  315. {
  316. // Create the toolbar
  317. m_pCalling = new CCallingBar();
  318. if (NULL != m_pCalling)
  319. {
  320. SetHideModes(m_pCalling, Compact);
  321. m_pCalling->Create(pParent, m_pConfRoom);
  322. // m_pCalling->Release();
  323. }
  324. }
  325. void CMainUI::CreateAppsTB(CGenWindow *pParent)
  326. {
  327. const static int AppsHMargin = 5;
  328. const static int AppsVMargin = 0;
  329. const static int AppsHGap = 11;
  330. static const Buttons appButtons[] =
  331. {
  332. { IDB_SHARE , CBitmapButton::Disabled+1, 1, ID_TB_SHARING , IDS_TT_TB_SHARING , },
  333. { IDB_CHAT , CBitmapButton::Disabled+1, 1, ID_TB_CHAT , IDS_TT_TB_CHAT , },
  334. { IDB_WHITEBOARD , CBitmapButton::Disabled+1, 1, ID_TB_NEWWHITEBOARD , IDS_TT_TB_NEWWHITEBOARD , },
  335. { IDB_FILE_TRANSFER , CBitmapButton::Disabled+1, 1, ID_TB_FILETRANSFER , IDS_TT_TB_FILETRANSFER , },
  336. } ;
  337. // Create the "data" buttons toolbar
  338. CToolbar *pApps = CreateToolbar(pParent, appButtons, ARRAY_ELEMENTS(appButtons), Compact);
  339. if (NULL != pApps)
  340. {
  341. // HACKHACK georgep: These numbers make it appear about right
  342. pApps->m_hMargin = AppsHMargin;
  343. pApps->m_vMargin = AppsVMargin;
  344. pApps->m_gap = AppsHGap;
  345. // pApps->m_bMinDesiredSize = TRUE;
  346. pApps->Release();
  347. }
  348. }
  349. void CMainUI::CreateVideoAndAppsTB(CGenWindow *pParent, CreateViewMode eMode, BOOL bEmbedded)
  350. {
  351. CLayeredView::LayoutStyle lVidDialStyle = CLayeredView::Center;
  352. switch (eMode)
  353. {
  354. case CreateFull:
  355. case CreatePreviewOnly:
  356. case CreateRemoteOnly:
  357. case CreateTelephone:
  358. break;
  359. case CreatePreviewNoPause:
  360. case CreateRemoteNoPause:
  361. lVidDialStyle = CLayeredView::Fill;
  362. break;
  363. default:
  364. return;
  365. }
  366. // Create the toolbar
  367. CBorderWindow *pVideoAndCalling = new CBorderWindow();
  368. if (NULL != pVideoAndCalling)
  369. {
  370. if (pVideoAndCalling->Create(pParent->GetWindow()))
  371. {
  372. SetHideModes(pVideoAndCalling, DataOnly);
  373. pVideoAndCalling->m_hGap = 4;
  374. pVideoAndCalling->m_vGap = 4;
  375. // This is the center part of the border window
  376. CLayeredView *pVidAndDial = new CLayeredView();
  377. if (NULL != pVidAndDial)
  378. {
  379. if (pVidAndDial->Create(pVideoAndCalling->GetWindow()))
  380. {
  381. pVideoAndCalling->m_uParts |= CBorderWindow::Center;
  382. pVidAndDial->m_lStyle = lVidDialStyle;
  383. CGenWindow *pLocalParent = pVidAndDial;
  384. if (CreateFull == eMode
  385. || CreateTelephone == eMode
  386. )
  387. {
  388. CreateDialingWindow(pVidAndDial);
  389. }
  390. if (CreateFull == eMode
  391. || CreateRemoteOnly == eMode
  392. || CreateRemoteNoPause == eMode
  393. )
  394. {
  395. // Create the remote video window
  396. m_pRemoteVideo = new CRemoteVideo(bEmbedded);
  397. if (NULL != m_pRemoteVideo)
  398. {
  399. SetHideModes(m_pRemoteVideo, Dialing|Previewing|DataOnly);
  400. m_pRemoteVideo->Create(pVidAndDial->GetWindow(), GetPalette(), this);
  401. pLocalParent = m_pRemoteVideo;
  402. }
  403. }
  404. if (CreateFull == eMode
  405. || CreatePreviewOnly == eMode
  406. || CreatePreviewNoPause == eMode
  407. )
  408. {
  409. // Create the local video window, even though we don't show it yet
  410. m_pLocalVideo = new CVideoWindow(CVideoWindow::LOCAL, bEmbedded);
  411. if (NULL != m_pLocalVideo)
  412. {
  413. SetHideModes(m_pLocalVideo, Dialing|Receiving|DataOnly);
  414. m_pLocalVideo->Create(pLocalParent->GetWindow(), GetPalette(), this);
  415. ShowWindow(m_pLocalVideo->GetWindow(), SW_HIDE);
  416. }
  417. }
  418. }
  419. pVidAndDial->Release();
  420. }
  421. if (CreateFull == eMode
  422. || CreateTelephone == eMode
  423. )
  424. {
  425. // create the toolbar
  426. static const Buttons abOsr2Calling[] =
  427. {
  428. { IDB_DIAL , CBitmapButton::Disabled+1, 1, ID_TB_NEW_CALL , IDS_TT_TB_NEW_CALL , },
  429. { IDB_HANGUP , CBitmapButton::Disabled+1, 1, IDM_FILE_HANGUP, IDS_TT_FILE_HANGUP, },
  430. { IDB_DIRECTORY, CBitmapButton::Disabled+1, 1, ID_TB_DIRECTORY, IDS_TT_TB_DIRECTORY, },
  431. { IDB_SHOWAV , CBitmapButton::Hot+1, Checked+1, ID_TB_SHOWAVTB , IDS_TT_TB_SHOWAVTB , },
  432. } ;
  433. CGenWindow *agwOsr2Calling[ARRAY_ELEMENTS(abOsr2Calling)];
  434. // This is the right-hand part of the border window
  435. CToolbar *ptbOsr2Calling = CreateToolbar(pVideoAndCalling, NULL, 0, DataOnly);
  436. if (NULL != ptbOsr2Calling)
  437. {
  438. pVideoAndCalling->m_uParts |= CBorderWindow::Right;
  439. ptbOsr2Calling->m_bVertical = TRUE;
  440. ptbOsr2Calling->m_nAlignment = Center;
  441. ZeroArray(agwOsr2Calling);
  442. AddButtons(ptbOsr2Calling, abOsr2Calling, ARRAY_ELEMENTS(abOsr2Calling),
  443. TRUE, agwOsr2Calling);
  444. SetHideModes(agwOsr2Calling[0], Normal);
  445. SetHideModes(agwOsr2Calling[3], Normal);
  446. ptbOsr2Calling->m_uRightIndex = 3;
  447. ptbOsr2Calling->Release();
  448. }
  449. }
  450. // This is the bottom part of the border window
  451. CreateAVTB(pVideoAndCalling, eMode);
  452. pVideoAndCalling->m_uParts |= CBorderWindow::Bottom;
  453. }
  454. pVideoAndCalling->Release();
  455. }
  456. }
  457. void CMainUI::CreateAVTB(CGenWindow *pParent, CreateViewMode eMode)
  458. {
  459. switch (eMode)
  460. {
  461. case CreateFull:
  462. case CreatePreviewOnly:
  463. case CreateRemoteOnly:
  464. break;
  465. default:
  466. return;
  467. }
  468. const static int AVHMargin = 10;
  469. const static int AVVMargin = 2;
  470. const static int AVHGap = ButtonsGap;
  471. // create the toolbar
  472. static const Buttons avButtons[] =
  473. {
  474. { IDB_PLAYPAUSE, CBitmapButton::Disabled+1, 2, ID_TB_PLAYPAUSE , IDS_TT_TB_PLAYPAUSE , },
  475. { IDB_PIP , CBitmapButton::Disabled+1, 1, ID_TB_PICINPIC , IDS_TT_TB_PICINPIC , },
  476. { IDB_AUDIO , CBitmapButton::Disabled+1, Checked+1, ID_TB_AUDIOTUNING, IDS_TT_TB_AUDIOTUNING, },
  477. } ;
  478. int nButtons = eMode == CreateFull ? ARRAY_ELEMENTS(avButtons) : 1;
  479. CToolbar *pAV = CreateToolbar(pParent, NULL, 0, NoAVTB|DataOnly);
  480. if (NULL != pAV)
  481. {
  482. CGenWindow *aButtons[ARRAY_ELEMENTS(avButtons)];
  483. ZeroArray(aButtons);
  484. AddButtons(pAV, avButtons, nButtons, TRUE, aButtons);
  485. CGenWindow *pAT;
  486. //
  487. // If video is completely disabled by policy, disable video buttons
  488. //
  489. if (!FIsSendVideoAllowed() && !FIsReceiveVideoAllowed())
  490. {
  491. pAT = aButtons[0];
  492. if (NULL != pAT)
  493. {
  494. EnableWindow(pAT->GetWindow(), FALSE);
  495. }
  496. pAT = aButtons[1];
  497. if (NULL != pAT)
  498. {
  499. EnableWindow(pAT->GetWindow(), FALSE);
  500. }
  501. }
  502. //
  503. // If audio is completely disabled by policy, disable audio buttons
  504. //
  505. pAT = aButtons[2];
  506. if (NULL != pAT)
  507. {
  508. ASSERT(ID_TB_AUDIOTUNING == GetDlgCtrlID(pAT->GetWindow()));
  509. if (!FIsAudioAllowed())
  510. {
  511. EnableWindow(pAT->GetWindow(), FALSE);
  512. }
  513. }
  514. pAV->m_hMargin = AVHMargin;
  515. pAV->m_vMargin = AVVMargin;
  516. pAV->m_gap = AVHGap;
  517. pAV->Release();
  518. }
  519. }
  520. #if FALSE // {
  521. void CMainUI::CreateCallsTB(CGenWindow *pParent)
  522. {
  523. // create the toolbar
  524. static const Buttons callsButtons[] =
  525. {
  526. { IDB_INCOMING , CBitmapButton::Hot+1, 1, ID_TB_INCOMING , IDS_TT_TB_INCOMING , },
  527. { IDB_HANGUP , CBitmapButton::Hot+1, 1, IDM_FILE_HANGUP , IDS_TT_FILE_HANGUP , },
  528. { IDB_CREDENTIALS, CBitmapButton::Hot+1, 1, ID_TB_CREDENTIALS, IDS_TT_TB_CREDENTIALS, },
  529. } ;
  530. CToolbar *pCalls = CreateToolbar(pParent, callsButtons, ARRAY_ELEMENTS(callsButtons),
  531. Compact);
  532. if (NULL != pCalls)
  533. {
  534. pCalls->Release();
  535. }
  536. }
  537. #endif // FALSE }
  538. void CMainUI::CreateDialingWindow(
  539. CGenWindow *pParent // The parent window
  540. )
  541. {
  542. const static int DialHMargin = 17;
  543. const static int DialVMargin = 4;
  544. const static int DialHGap = 5;
  545. const static int DialVGap = 0;
  546. CEdgedWindow *pEdge = new CEdgedWindow();
  547. if (NULL == pEdge)
  548. {
  549. return;
  550. }
  551. SetHideModes(pEdge, Video|DataOnly);
  552. if (pEdge->Create(pParent->GetWindow()))
  553. {
  554. CToolbar *pDialing = CreateToolbar(pEdge, NULL, 0, Ignore);
  555. if (NULL != pDialing)
  556. {
  557. pDialing->m_bVertical = TRUE;
  558. pDialing->m_gap = DialVGap;
  559. pDialing->m_hMargin = DialHMargin;
  560. pDialing->m_vMargin = DialVMargin;
  561. static const Buttons dialButtons[] =
  562. {
  563. { IDB_DIAL1 , CBitmapButton::Hot+1, 1, ID_TB_DIAL1 , IDS_TT_DIALPAD, },
  564. { IDB_DIAL2 , CBitmapButton::Hot+1, 1, ID_TB_DIAL2 , IDS_TT_DIALPAD, },
  565. { IDB_DIAL3 , CBitmapButton::Hot+1, 1, ID_TB_DIAL3 , IDS_TT_DIALPAD, },
  566. { IDB_DIAL4 , CBitmapButton::Hot+1, 1, ID_TB_DIAL4 , IDS_TT_DIALPAD, },
  567. { IDB_DIAL5 , CBitmapButton::Hot+1, 1, ID_TB_DIAL5 , IDS_TT_DIALPAD, },
  568. { IDB_DIAL6 , CBitmapButton::Hot+1, 1, ID_TB_DIAL6 , IDS_TT_DIALPAD, },
  569. { IDB_DIAL7 , CBitmapButton::Hot+1, 1, ID_TB_DIAL7 , IDS_TT_DIALPAD, },
  570. { IDB_DIAL8 , CBitmapButton::Hot+1, 1, ID_TB_DIAL8 , IDS_TT_DIALPAD, },
  571. { IDB_DIAL9 , CBitmapButton::Hot+1, 1, ID_TB_DIAL9 , IDS_TT_DIALPAD, },
  572. { IDB_DIALSTAR , CBitmapButton::Hot+1, 1, ID_TB_DIALSTAR , IDS_TT_DIALPAD, },
  573. { IDB_DIAL0 , CBitmapButton::Hot+1, 1, ID_TB_DIAL0 , IDS_TT_DIALPAD, },
  574. { IDB_DIALPOUND, CBitmapButton::Hot+1, 1, ID_TB_DIALPOUND, IDS_TT_DIALPAD, },
  575. } ;
  576. for (int row=0; row<4; ++row)
  577. {
  578. CToolbar *pRowTB = CreateToolbar(pDialing);
  579. if (NULL != pRowTB)
  580. {
  581. pRowTB->m_gap = DialHGap;
  582. AddButtons(pRowTB, &dialButtons[row*3], 3, TRUE, NULL, this);
  583. pRowTB->Release();
  584. }
  585. }
  586. pDialing->Release();
  587. }
  588. }
  589. pEdge->Release();
  590. }
  591. // Creates the audio-tuning window
  592. void CMainUI::CreateAudioTuningWindow(
  593. CGenWindow *pParent // The parent window
  594. )
  595. {
  596. static const int ATHMargin = 8;
  597. static const int ATVMargin = 6;
  598. static const int ATControlWidth = 170;
  599. CToolbar *pATWindow = CreateToolbar(pParent, NULL, 0, NoAVTB|Roster|DataOnly);
  600. if (NULL != pATWindow)
  601. {
  602. pATWindow->m_bVertical = TRUE;
  603. pATWindow->m_nAlignment = Fill;
  604. pATWindow->m_gap = MainGap;
  605. CEdgedWindow *pEdge;
  606. pEdge = new CEdgedWindow();
  607. if (NULL != pEdge)
  608. {
  609. pEdge->m_hMargin = ATHMargin;
  610. pEdge->m_vMargin = ATVMargin;
  611. if (pEdge->Create(pATWindow->GetWindow()))
  612. {
  613. SetHideModes(pEdge, Ignore);
  614. CButton *pButton = new CButton();
  615. if (NULL != pButton)
  616. {
  617. pButton->Create(pEdge->GetWindow(), ID_TB_TUNEMIC_UNMUTE, NULL,
  618. BS_CHECKBOX|BS_ICON|WS_TABSTOP, this);
  619. pButton->SetTooltip(RES2T(IDS_TT_MUTE_MIC));
  620. HICON hIcon = reinterpret_cast<HICON>(LoadImage(_Module.GetModuleInstance(),
  621. MAKEINTRESOURCE(IDI_MICFONE),
  622. IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
  623. LR_DEFAULTCOLOR));
  624. pButton->SetIcon(hIcon);
  625. pEdge->SetHeader(pButton);
  626. pButton->Release();
  627. }
  628. UpdateMuteState(FALSE, pButton);
  629. m_pAudioMic = new CProgressTrackbar();
  630. if (NULL != m_pAudioMic)
  631. {
  632. if (m_pAudioMic->Create(pEdge->GetWindow(), 0, this))
  633. {
  634. m_pAudioMic->SetTooltip(RES2T(IDS_TT_ADJUST_MIC));
  635. m_pAudioMic->SetMaxValue(AudioMax);
  636. SIZE size;
  637. m_pAudioMic->GetDesiredSize(&size);
  638. size.cx = ATControlWidth;
  639. m_pAudioMic->SetDesiredSize(&size);
  640. }
  641. // m_pAudioMic->Release();
  642. }
  643. }
  644. pEdge->Release();
  645. }
  646. pEdge = new CEdgedWindow();
  647. if (NULL != pEdge)
  648. {
  649. pEdge->m_hMargin = ATHMargin;
  650. pEdge->m_vMargin = ATVMargin;
  651. if (pEdge->Create(pATWindow->GetWindow()))
  652. {
  653. SetHideModes(pEdge, Ignore);
  654. CButton *pButton = new CButton();
  655. if (NULL != pButton)
  656. {
  657. pButton->Create(pEdge->GetWindow(), ID_TB_TUNESPEAKER_UNMUTE, NULL,
  658. BS_CHECKBOX|BS_ICON|WS_TABSTOP, this);
  659. pButton->SetTooltip(RES2T(IDS_TT_MUTE_SPK));
  660. HICON hIcon = reinterpret_cast<HICON>(LoadImage(_Module.GetModuleInstance(),
  661. MAKEINTRESOURCE(IDI_SPEAKER),
  662. IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
  663. LR_DEFAULTCOLOR));
  664. pButton->SetIcon(hIcon);
  665. pEdge->SetHeader(pButton);
  666. pButton->Release();
  667. }
  668. UpdateMuteState(TRUE, pButton);
  669. m_pAudioSpeaker = new CProgressTrackbar();
  670. if (NULL != m_pAudioSpeaker)
  671. {
  672. if (m_pAudioSpeaker->Create(pEdge->GetWindow(), 0, this))
  673. {
  674. m_pAudioSpeaker->SetTooltip(RES2T(IDS_TT_ADJUST_SPK));
  675. m_pAudioSpeaker->SetMaxValue(AudioMax);
  676. SIZE size;
  677. m_pAudioSpeaker->GetDesiredSize(&size);
  678. size.cx = ATControlWidth;
  679. m_pAudioSpeaker->SetDesiredSize(&size);
  680. }
  681. // m_pAudioSpeaker->Release();
  682. }
  683. }
  684. pEdge->Release();
  685. }
  686. pATWindow->Release();
  687. }
  688. CAudioControl *pAudioControl = GetAudioControl();
  689. if (NULL != pAudioControl)
  690. {
  691. // Force an update of the controls
  692. OnAudioLevelChange(TRUE , pAudioControl->GetSpeakerVolume());
  693. OnAudioLevelChange(FALSE, pAudioControl->GetRecorderVolume());
  694. }
  695. }
  696. void CMainUI::CreateRosterArea(CGenWindow *pParent, CreateViewMode eMode)
  697. {
  698. switch (eMode)
  699. {
  700. case CreateFull:
  701. case CreateDataOnly:
  702. case CreateTelephone:
  703. break;
  704. default:
  705. return;
  706. }
  707. CLayeredView *pView = new CLayeredView();
  708. if (NULL == pView)
  709. {
  710. // Pretty bad
  711. return;
  712. }
  713. if (pView->Create(pParent->GetWindow()))
  714. {
  715. SetHideModes(pView, IfNoChildren);
  716. pView->m_lStyle = CLayeredView::Fill;
  717. if (eMode != CreateDataOnly)
  718. {
  719. CreateAudioTuningWindow(pView);
  720. }
  721. if (eMode != CreateTelephone)
  722. {
  723. CToolbar *pRosterAndCall = CreateToolbar(pView);
  724. if (NULL != pRosterAndCall)
  725. {
  726. pRosterAndCall->m_nAlignment = CToolbar::Fill;
  727. m_pRoster = new CRosterParent();
  728. if (NULL != m_pRoster)
  729. {
  730. m_pRoster->Create(pRosterAndCall->GetWindow());
  731. // HACKHACK georgep: Just calling SetUserData directly for now
  732. SetHideModes(m_pRoster, Compact|AudioTuning);
  733. }
  734. if (CreateDataOnly != eMode)
  735. {
  736. CToolbar *pCalling = CreateToolbar(pRosterAndCall);
  737. if (NULL != pCalling)
  738. {
  739. SetHideModes(pCalling, Normal|Compact);
  740. pCalling->m_bVertical = TRUE;
  741. static const Buttons abCalling[] =
  742. {
  743. { IDB_HANGUP , CBitmapButton::Disabled+1, 1, IDM_FILE_HANGUP, IDS_TT_FILE_HANGUP, },
  744. { IDB_DIRECTORY, CBitmapButton::Disabled+1, 1, ID_TB_DIRECTORY, IDS_TT_TB_DIRECTORY, },
  745. } ;
  746. AddButtons(pCalling, abCalling, ARRAY_ELEMENTS(abCalling),
  747. TRUE, NULL, this);
  748. pCalling->Release();
  749. }
  750. }
  751. pRosterAndCall->m_uRightIndex = 1;
  752. pRosterAndCall->m_bHasCenterChild = TRUE;
  753. pRosterAndCall->Release();
  754. }
  755. }
  756. }
  757. pView->Release();
  758. }
  759. BOOL CMainUI::Create(
  760. HWND hwndParent,
  761. CConfRoom *pConfRoom,
  762. CreateViewMode eMode,
  763. BOOL bEmbedded
  764. )
  765. {
  766. // Store this away so we can call some methods in it later
  767. m_pConfRoom = pConfRoom;
  768. ASSERT(m_pConfRoom);
  769. if (NULL == m_pConfRoom)
  770. {
  771. return(FALSE);
  772. }
  773. // Create the window
  774. if (!CToolbar::Create(hwndParent))
  775. {
  776. return(FALSE);
  777. }
  778. // Try to remain a little bit abstract
  779. CToolbar *pMain = this;
  780. m_pConfRoom->AddConferenceChangeHandler(this);
  781. // A vertical toolbar that fills all its area
  782. pMain->m_hMargin = MainHMargin;
  783. pMain->m_vMargin = MainVMargin;
  784. pMain->m_gap = MainGap;
  785. if (CreateRemoteNoPause == eMode
  786. || CreatePreviewNoPause == eMode
  787. )
  788. {
  789. pMain->m_hMargin = 0;
  790. pMain->m_vMargin = 0;
  791. pMain->m_bHasCenterChild = TRUE;
  792. //HACKHACK This only works because all these views have only 1 window
  793. pMain->m_uRightIndex = 1;
  794. }
  795. pMain->m_bVertical = TRUE;
  796. pMain->m_nAlignment = Fill;
  797. m_hbBack = CGenWindow::GetStandardBrush();
  798. // Create all the sub toolbars
  799. if (CreateFull == eMode
  800. || CreateTelephone == eMode
  801. )
  802. {
  803. CreateDialTB(pMain);
  804. }
  805. CreateVideoAndAppsTB(pMain, eMode, bEmbedded);
  806. CreateRosterArea(pMain, eMode);
  807. if (CreateFull == eMode
  808. || CreateDataOnly == eMode
  809. )
  810. {
  811. CreateAppsTB(pMain);
  812. }
  813. // Now we need to update to the current state of the conference
  814. if (m_pConfRoom->FIsConferenceActive())
  815. {
  816. OnCallStarted();
  817. CSimpleArray<CParticipant*>& lMembers = m_pConfRoom->GetParticipantList();
  818. for (int i=lMembers.GetSize()-1; i>=0; --i)
  819. {
  820. OnChangeParticipant(lMembers[i], NM_MEMBER_ADDED);
  821. }
  822. // Need to tell everybody what the active channels are
  823. INmConference2 *pNmConf = m_pConfRoom->GetActiveConference();
  824. if (NULL != pNmConf)
  825. {
  826. // Just in case
  827. pNmConf->AddRef();
  828. IEnumNmChannel *pEnumCh;
  829. if (SUCCEEDED(pNmConf->EnumChannel(&pEnumCh)))
  830. {
  831. INmChannel *pChannel;
  832. ULONG uGot;
  833. while (S_OK == pEnumCh->Next(1, &pChannel, &uGot) && 1 == uGot)
  834. {
  835. OnVideoChannelChanged(NM_CHANNEL_ADDED, pChannel);
  836. pChannel->Release();
  837. }
  838. pEnumCh->Release();
  839. }
  840. pNmConf->Release();
  841. }
  842. }
  843. if (CreateDataOnly == eMode)
  844. {
  845. SetDataOnly(TRUE);
  846. }
  847. if (CreateTelephone == eMode)
  848. {
  849. SetDialing(TRUE);
  850. SetAudioTuning(TRUE);
  851. }
  852. OnChangePermissions();
  853. UpdateViewState();
  854. UpdatePlayPauseState();
  855. return(TRUE);
  856. }
  857. HBRUSH CMainUI::GetBackgroundBrush()
  858. {
  859. return(m_hbBack);
  860. }
  861. // REVIEW georgep: Should this loop until it gets an IGenWindow?
  862. HPALETTE CMainUI::GetPalette()
  863. {
  864. return(m_pConfRoom->GetPalette());
  865. }
  866. // Recursive function to hide/show windows for the current view
  867. // Returns whether any of the children are visible
  868. BOOL ShowWindows(
  869. HWND hwndParent, // The parent window to start from
  870. LPARAM lDefMode, // The hide mode to use if Inherit
  871. LPARAM hideMode // The current hide mode
  872. )
  873. {
  874. BOOL bRet = FALSE;
  875. for (HWND hwndChild=::GetWindow(hwndParent, GW_CHILD); NULL!=hwndChild;
  876. hwndChild=::GetWindow(hwndChild, GW_HWNDNEXT))
  877. {
  878. IGenWindow *pChild = IGenWindow::FromHandle(hwndChild);
  879. if (NULL == pChild)
  880. {
  881. continue;
  882. }
  883. LPARAM lMode = GetHideModes(pChild);
  884. if (Ignore == lMode)
  885. {
  886. if ((GetWindowStyle(hwndChild)&WS_VISIBLE) != 0)
  887. {
  888. bRet = TRUE;
  889. }
  890. continue;
  891. }
  892. if (Inherit == lMode)
  893. {
  894. lMode = lDefMode;
  895. }
  896. // recurse to child windows first to avoid flicker
  897. LPARAM lNoChildren = ShowWindows(hwndChild, lMode, hideMode) ? 0 : IfNoChildren;
  898. // If any of the hide mode bits are set, then hide the window
  899. // otherwise show it
  900. BOOL bShow = ((lMode&(hideMode|lNoChildren)) == 0);
  901. if (bShow)
  902. {
  903. bRet = TRUE;
  904. }
  905. ShowWindow(hwndChild, bShow ? SW_SHOW : SW_HIDE);
  906. }
  907. return(bRet);
  908. }
  909. BOOL CMainUI::CanPreview()
  910. {
  911. HWND hwndLocal = GetVideoWindow(TRUE);
  912. return(NULL!=hwndLocal && GetLocalVideo()->IsXferAllowed());
  913. }
  914. void CMainUI::UpdateViewState()
  915. {
  916. // Put together all the modes we ARE in, and hide any windows that want
  917. // to be hidden while in one of those modes
  918. // The default mode
  919. LPARAM hideModes;
  920. if (IsCompact())
  921. {
  922. hideModes = Compact;
  923. if (!IsShowAVTB())
  924. {
  925. hideModes |= NoAVTB;
  926. }
  927. }
  928. else if (IsDataOnly())
  929. {
  930. hideModes = DataOnly;
  931. }
  932. else
  933. {
  934. hideModes = Normal;
  935. }
  936. if (IsDialing())
  937. {
  938. hideModes |= Dialing;
  939. }
  940. else
  941. {
  942. // hwndRemote will be NULL for PreviewOnly mode
  943. HWND hwndRemote = GetVideoWindow(FALSE);
  944. if (NULL == hwndRemote)
  945. {
  946. hideModes |= Previewing;
  947. }
  948. else
  949. {
  950. HWND hwndLocal = GetVideoWindow(TRUE);
  951. BOOL bPreviewing = IsPreviewing();
  952. HWND parent = NULL;
  953. BOOL bZoomable;
  954. LONG style = GetWindowLong(hwndLocal, GWL_EXSTYLE);
  955. if (bPreviewing)
  956. {
  957. hideModes |= Previewing;
  958. parent = GetParent(hwndRemote);
  959. style |= WS_EX_CLIENTEDGE;
  960. bZoomable = TRUE;
  961. }
  962. else
  963. {
  964. hideModes |= (m_bPicInPic && CanPreview()) ? ReceivingWPiP : Receiving;
  965. parent = hwndRemote;
  966. style &= ~WS_EX_CLIENTEDGE;
  967. bZoomable = FALSE;
  968. }
  969. if (GetParent(hwndLocal) != parent)
  970. {
  971. SetWindowLong(hwndLocal, GWL_EXSTYLE, style);
  972. SetParent(hwndLocal, parent);
  973. SetWindowPos(hwndLocal, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
  974. CVideoWindow *pVideo = GetLocalVideo();
  975. if (NULL != pVideo)
  976. {
  977. pVideo->SetZoomable(bZoomable);
  978. }
  979. }
  980. }
  981. }
  982. // Enable/disable the PiP window
  983. IGenWindow *pPiP = FindControl(ID_TB_PICINPIC);
  984. if (NULL != pPiP)
  985. {
  986. CComPtr<CGenWindow> spButton = com_cast<CGenWindow>(pPiP);
  987. BOOL bEnable = !IsPreviewing() && CanPreview() && !IsDialing();
  988. EnableWindow(spButton->GetWindow(), bEnable);
  989. }
  990. hideModes |= IsAudioTuning() && !IsDataOnly() ? AudioTuning : Roster;
  991. HWND hwnd = GetWindow();
  992. ShowWindows(hwnd, 0, hideModes);
  993. // If the focus is on a child window which is now not visible, but we are,
  994. // then change the focus to this window
  995. if (!IsWindowVisible(GetFocus()) && IsWindowActive(hwnd) && IsWindowVisible(hwnd))
  996. {
  997. SetFocus(hwnd);
  998. }
  999. IGenWindow *pButton = FindControl(ID_TB_AUDIOTUNING);
  1000. CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(pButton);
  1001. if (spButton)
  1002. {
  1003. BOOL bAudioTuning = IsAudioTuning() && !IsCompact();
  1004. spButton->SetCustomState(bAudioTuning ? Checked : Unchecked);
  1005. spButton->SetTooltip(RES2T(bAudioTuning ? IDS_TT_TB_SHOWROSTER : IDS_TT_TB_AUDIOTUNING));
  1006. }
  1007. OnDesiredSizeChanged();
  1008. }
  1009. void CMainUI::SetCompact(BOOL bCompact)
  1010. {
  1011. bCompact = bCompact != FALSE;
  1012. if (IsCompact() == bCompact)
  1013. {
  1014. // Nothing to do
  1015. return;
  1016. }
  1017. m_eViewMode = bCompact ? ViewCompact : ViewNormal;
  1018. UpdateViewState();
  1019. }
  1020. void CMainUI::SetDataOnly(BOOL bDataOnly)
  1021. {
  1022. bDataOnly = bDataOnly != FALSE;
  1023. if (IsDataOnly() == bDataOnly)
  1024. {
  1025. // Nothing to do
  1026. return;
  1027. }
  1028. m_eViewMode = bDataOnly ? ViewDataOnly : ViewNormal;
  1029. UpdateViewState();
  1030. }
  1031. void CMainUI::SetDialing(BOOL bDialing)
  1032. {
  1033. bDialing = bDialing != FALSE;
  1034. if (IsDialing() == bDialing)
  1035. {
  1036. // Nothing to do
  1037. return;
  1038. }
  1039. m_bDialing = bDialing;
  1040. UpdateViewState();
  1041. }
  1042. void CMainUI::SetPicInPic(BOOL bPicInPic)
  1043. {
  1044. bPicInPic = bPicInPic != FALSE;
  1045. if (IsPicInPic() == bPicInPic)
  1046. {
  1047. // Nothing to do
  1048. return;
  1049. }
  1050. m_bPicInPic = bPicInPic;
  1051. UpdateViewState();
  1052. }
  1053. BOOL CMainUI::IsPicInPicAllowed()
  1054. {
  1055. return(!IsDataOnly() && !m_bPreviewing && CanPreview());
  1056. }
  1057. void CMainUI::SetAudioTuning(BOOL bAudioTuning)
  1058. {
  1059. if ((IsAudioTuning() && bAudioTuning) || (!IsAudioTuning() && !bAudioTuning))
  1060. {
  1061. // Nothing to do
  1062. return;
  1063. }
  1064. m_bAudioTuning = bAudioTuning;
  1065. if (IsAudioTuning())
  1066. {
  1067. SetTimer(GetWindow(), IDT_AUDIO, AUDIODLG_MIC_TIMER_PERIOD, NULL);
  1068. }
  1069. else
  1070. {
  1071. KillTimer(GetWindow(), IDT_AUDIO);
  1072. }
  1073. UpdateViewState();
  1074. }
  1075. void CMainUI::SetShowAVTB(BOOL bShowAVTB)
  1076. {
  1077. if ((IsShowAVTB() && bShowAVTB) || (!IsShowAVTB() && !bShowAVTB))
  1078. {
  1079. // Nothing to do
  1080. return;
  1081. }
  1082. m_bShowAVTB = bShowAVTB;
  1083. UpdateViewState();
  1084. }
  1085. LRESULT CMainUI::ProcessMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  1086. {
  1087. static const UINT c_uMsgMSWheel = ::IsWindowsNT() ? WM_MOUSEWHEEL :
  1088. ::RegisterWindowMessage(_TEXT("MSWHEEL_ROLLMSG"));
  1089. switch (message)
  1090. {
  1091. HANDLE_MSG(hwnd, WM_TIMER , OnTimer);
  1092. HANDLE_MSG(hwnd, WM_DESTROY , OnDestroy);
  1093. case WM_CREATE:
  1094. {
  1095. // Allow dialog-like keyboard support
  1096. HACCEL hAccel = LoadAccelerators(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDR_MAINUI));
  1097. if (NULL != hAccel)
  1098. {
  1099. m_pAccel = new CTranslateAccelTable(hwnd, hAccel);
  1100. if (NULL != m_pAccel)
  1101. {
  1102. AddTranslateAccelerator(m_pAccel);
  1103. }
  1104. }
  1105. break;
  1106. }
  1107. case WM_SETFOCUS:
  1108. ShiftFocus(GetWindow(), TRUE);
  1109. break;
  1110. default:
  1111. if (message == c_uMsgMSWheel)
  1112. {
  1113. CRoomListView *pView = GetRoster();
  1114. if (NULL != pView)
  1115. {
  1116. ::SendMessage(pView->GetHwnd(), message, wParam, lParam);
  1117. }
  1118. break;
  1119. }
  1120. break;
  1121. }
  1122. return(CToolbar::ProcessMessage(hwnd, message, wParam, lParam));
  1123. }
  1124. void CMainUI::OnScroll(CProgressTrackbar *pTrackbar, UINT code, int pos)
  1125. {
  1126. BOOL bSpeaker = FALSE;
  1127. if (m_pAudioSpeaker == pTrackbar)
  1128. {
  1129. bSpeaker = TRUE;
  1130. }
  1131. else if (m_pAudioMic == pTrackbar)
  1132. {
  1133. }
  1134. else
  1135. {
  1136. // I don't think we should get here
  1137. return;
  1138. }
  1139. // Can't trust the pos passed in
  1140. pos = pTrackbar->GetTrackValue();
  1141. CAudioControl *pAudioControl = GetAudioControl();
  1142. if (NULL == pAudioControl)
  1143. {
  1144. return;
  1145. }
  1146. DWORD dwVolume = (pos*AudioVolMax + AudioMax/2)/AudioMax;
  1147. dwVolume = min(max(dwVolume, 0), AudioVolMax);
  1148. if (bSpeaker)
  1149. {
  1150. pAudioControl->SetSpeakerVolume(dwVolume);
  1151. }
  1152. else
  1153. {
  1154. pAudioControl->SetRecorderVolume(dwVolume);
  1155. }
  1156. }
  1157. HWND CMainUI::GetVideoWindow(BOOL bLocal)
  1158. {
  1159. CVideoWindow *pVideo = bLocal ? GetLocalVideo() : GetRemoteVideo();
  1160. return(NULL == pVideo ? NULL : pVideo->GetWindow());
  1161. }
  1162. void CMainUI::ToggleMute(BOOL bSpeaker)
  1163. {
  1164. CAudioControl *pAudioControl = GetAudioControl();
  1165. if (NULL != pAudioControl)
  1166. {
  1167. BOOL bMuted = bSpeaker ? pAudioControl->IsSpkMuted() : pAudioControl->IsRecMuted();
  1168. pAudioControl->MuteAudio(bSpeaker, !bMuted);
  1169. }
  1170. }
  1171. void CMainUI::UpdateMuteState(BOOL bSpeaker, CButton *pButton)
  1172. {
  1173. CAudioControl *pAudioControl = GetAudioControl();
  1174. if (NULL != pAudioControl)
  1175. {
  1176. BOOL bMuted = bSpeaker ? pAudioControl->IsSpkMuted() : pAudioControl->IsRecMuted();
  1177. pButton->SetChecked(!bMuted);
  1178. }
  1179. }
  1180. void CMainUI::BumpAudio(BOOL bSpeaker, int pct)
  1181. {
  1182. CAudioControl *pAudioControl = GetAudioControl();
  1183. if (NULL != pAudioControl)
  1184. {
  1185. int dwVolume = static_cast<int>(bSpeaker ?
  1186. pAudioControl->GetSpeakerVolume() : pAudioControl->GetRecorderVolume());
  1187. dwVolume += (pct*AudioVolMax/100);
  1188. dwVolume = min(max(dwVolume, 0), AudioVolMax);
  1189. if (bSpeaker)
  1190. {
  1191. pAudioControl->SetSpeakerVolume(dwVolume);
  1192. }
  1193. else
  1194. {
  1195. pAudioControl->SetRecorderVolume(dwVolume);
  1196. }
  1197. }
  1198. }
  1199. void CMainUI::SetAudioProperty(BOOL bSpeaker, NM_AUDPROP uID, ULONG uValue)
  1200. {
  1201. CAudioControl *pAudioControl = GetAudioControl();
  1202. if (NULL != pAudioControl)
  1203. {
  1204. pAudioControl->SetProperty(bSpeaker, uID, uValue);
  1205. }
  1206. }
  1207. // IButtonChange
  1208. void CMainUI::OnClick(CButton *pButton)
  1209. {
  1210. HWND hwndCtl = pButton->GetWindow();
  1211. OnCommand(GetWindow(), GetWindowLong(hwndCtl, GWL_ID), hwndCtl, BN_CLICKED);
  1212. }
  1213. void CMainUI::OnInitMenu(HMENU hMenu)
  1214. {
  1215. CVideoWindow *pVideo = IsPreviewing() ? GetLocalVideo() : GetRemoteVideo();
  1216. if (NULL != pVideo)
  1217. {
  1218. pVideo->UpdateVideoMenu(hMenu);
  1219. pVideo = GetLocalVideo();
  1220. EnableMenuItem(hMenu, IDM_VIDEO_UNDOCK,
  1221. MF_BYCOMMAND|(NULL != pVideo && pVideo->IsXferAllowed() ? MF_ENABLED : MF_GRAYED|MF_DISABLED));
  1222. }
  1223. }
  1224. static void AppendText(CCallingBar *pCalling, TCHAR cAdd)
  1225. {
  1226. if (NULL != pCalling)
  1227. {
  1228. // I don't want to change a string that you can't see
  1229. if (IsWindowVisible(pCalling->GetWindow()))
  1230. {
  1231. TCHAR szText[] = TEXT("0");
  1232. szText[0] = cAdd;
  1233. TCHAR szTemp[MAX_PATH];
  1234. int nLen = pCalling->GetText(szTemp, ARRAY_ELEMENTS(szTemp));
  1235. if (nLen + lstrlen(szText) <= ARRAY_ELEMENTS(szTemp) - 1)
  1236. {
  1237. lstrcat(szTemp, szText);
  1238. pCalling->SetText(szTemp);
  1239. }
  1240. }
  1241. }
  1242. }
  1243. static BOOL ShouldTry(HWND child)
  1244. {
  1245. // REVIEW georgep: I could look at WS_EX_CONTROLPARENT also
  1246. return((WS_VISIBLE) == (GetWindowStyle(child) & (WS_DISABLED|WS_VISIBLE)));
  1247. }
  1248. static BOOL IsTabbable(HWND child)
  1249. {
  1250. return((WS_TABSTOP|WS_VISIBLE) == (GetWindowStyle(child) & (WS_TABSTOP|WS_DISABLED|WS_VISIBLE)));
  1251. }
  1252. // BUGBUG georgep: I should move this into CGenWindow
  1253. // Determine the next control in the tab order
  1254. static HWND NextControl(HWND hwndTop, HWND hwndFocus)
  1255. {
  1256. // Loop detection stuff
  1257. BOOL bGotToTop = FALSE;
  1258. // We'll loop to avoid really deep recursion
  1259. while (TRUE)
  1260. {
  1261. // First try the children of hwndFocus
  1262. if (hwndFocus == hwndTop || ShouldTry(hwndFocus))
  1263. {
  1264. HWND next = GetFirstChild(hwndFocus);
  1265. if (NULL != next)
  1266. {
  1267. if (IsTabbable(next))
  1268. {
  1269. return(next);
  1270. }
  1271. hwndFocus = next;
  1272. continue;
  1273. }
  1274. }
  1275. if (hwndFocus == hwndTop)
  1276. {
  1277. // Apparently hwndTop has no children
  1278. return(NULL);
  1279. }
  1280. HWND next;
  1281. while (NULL == (next = GetNextSibling(hwndFocus)))
  1282. {
  1283. hwndFocus = GetParent(hwndFocus);
  1284. if (NULL == hwndFocus)
  1285. {
  1286. // Invalid params
  1287. return(NULL);
  1288. }
  1289. if (hwndTop == hwndFocus)
  1290. {
  1291. break;
  1292. }
  1293. }
  1294. if (hwndTop == hwndFocus)
  1295. {
  1296. // Detect if we have looped back to the top again
  1297. if (bGotToTop)
  1298. {
  1299. return(NULL);
  1300. }
  1301. bGotToTop = TRUE;
  1302. continue;
  1303. }
  1304. if (IsTabbable(next))
  1305. {
  1306. return(next);
  1307. }
  1308. hwndFocus = next;
  1309. }
  1310. // We looped back to the beginning, so I guess nobody can take the focus
  1311. return(NULL);
  1312. }
  1313. // Determine the previous control in the tab order
  1314. static HWND PrevControl(HWND hwndTop, HWND hwndFocus)
  1315. {
  1316. // LAZYLAZY georgep: It's hard to do this directly, so I'll just loop
  1317. // on the NextControl. It should be fast enough.
  1318. // In case hwndFocus is not focusable for some reason, we still need to
  1319. // detect the loop
  1320. HWND hwndStart = NextControl(hwndTop, hwndFocus);
  1321. // HACK for combo boxes: go from the edit control to the combo box control
  1322. while (NULL != hwndFocus
  1323. && hwndTop != hwndFocus
  1324. && !IsTabbable(hwndFocus)
  1325. )
  1326. {
  1327. hwndFocus = GetParent(hwndFocus);
  1328. }
  1329. HWND ret = hwndStart;
  1330. while (TRUE)
  1331. {
  1332. HWND next = NextControl(hwndTop, ret);
  1333. if (NULL == next)
  1334. {
  1335. // Oops!
  1336. return(NULL);
  1337. }
  1338. if (hwndFocus == next
  1339. || hwndStart == next
  1340. )
  1341. {
  1342. break;
  1343. }
  1344. ret = next;
  1345. }
  1346. return(ret);
  1347. }
  1348. static void ShiftFocus(HWND hwndTop, BOOL bForward)
  1349. {
  1350. HWND hwndFocus = GetFocus();
  1351. if (!IsWindowActive(hwndTop))
  1352. {
  1353. hwndFocus = hwndTop;
  1354. }
  1355. HWND next = bForward ? NextControl(hwndTop, hwndFocus) : PrevControl(hwndTop, hwndFocus);
  1356. if (NULL != next)
  1357. {
  1358. SetFocus(next);
  1359. }
  1360. else
  1361. {
  1362. MessageBeep(MB_ICONHAND);
  1363. }
  1364. }
  1365. void CMainUI::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  1366. {
  1367. switch (id)
  1368. {
  1369. case ID_NAV_TAB:
  1370. ShiftFocus(hwnd, TRUE);
  1371. break;
  1372. case ID_NAV_SHIFT_TAB:
  1373. ShiftFocus(hwnd, FALSE);
  1374. break;
  1375. case IDM_VIEW_DIALPAD:
  1376. SetDialing(!IsDialing());
  1377. break;
  1378. case ID_TB_PICINPIC:
  1379. SetPicInPic(!IsPicInPic());
  1380. break;
  1381. case ID_TB_REJECT:
  1382. case ID_TB_CREDENTIALS:
  1383. break;
  1384. case ID_TB_AUDIOTUNING:
  1385. {
  1386. m_bStateChanged = TRUE;
  1387. SetAudioTuning(!IsAudioTuning());
  1388. break;
  1389. }
  1390. case ID_TB_SHOWAVTB:
  1391. {
  1392. m_bStateChanged = TRUE;
  1393. SetShowAVTB(!IsShowAVTB());
  1394. CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(IGenWindow::FromHandle(hwndCtl));
  1395. if (spButton)
  1396. {
  1397. BOOL bShow = IsShowAVTB();
  1398. spButton->SetCustomState(bShow ? Checked : Unchecked);
  1399. spButton->SetTooltip(RES2T(bShow ? IDS_TT_TB_HIDEAVTB : IDS_TT_TB_SHOWAVTB));
  1400. }
  1401. break;
  1402. }
  1403. case ID_TB_TUNEMIC_UNMUTE:
  1404. ToggleMute(FALSE);
  1405. break;
  1406. case ID_TB_TUNESPEAKER_UNMUTE:
  1407. ToggleMute(TRUE);
  1408. break;
  1409. case ID_TB_DIAL0:
  1410. case ID_TB_DIAL1:
  1411. case ID_TB_DIAL2:
  1412. case ID_TB_DIAL3:
  1413. case ID_TB_DIAL4:
  1414. case ID_TB_DIAL5:
  1415. case ID_TB_DIAL6:
  1416. case ID_TB_DIAL7:
  1417. case ID_TB_DIAL8:
  1418. case ID_TB_DIAL9:
  1419. SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, id-ID_TB_DIAL0);
  1420. AppendText(m_pCalling, '0'+id-ID_TB_DIAL0);
  1421. break;
  1422. case ID_TB_DIALSTAR:
  1423. SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, 10);
  1424. AppendText(m_pCalling, '*');
  1425. break;
  1426. case ID_TB_DIALPOUND:
  1427. SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, 11);
  1428. AppendText(m_pCalling, '#');
  1429. break;
  1430. case ID_TB_DIRECTORY:
  1431. {
  1432. CFindSomeone::findSomeone(m_pConfRoom);
  1433. }
  1434. break;
  1435. case ID_TB_PLAYPAUSE:
  1436. TogglePlayPause();
  1437. break;
  1438. case IDM_VIDEO_ZOOM1:
  1439. case IDM_VIDEO_ZOOM2:
  1440. case IDM_VIDEO_ZOOM3:
  1441. case IDM_VIDEO_ZOOM4:
  1442. case IDM_VIDEO_UNDOCK:
  1443. case IDM_VIDEO_GETACAMERA:
  1444. {
  1445. CVideoWindow *pVideo = IsPreviewing() ? GetLocalVideo() : GetRemoteVideo();
  1446. if (NULL != pVideo)
  1447. {
  1448. pVideo->OnCommand(id);
  1449. }
  1450. break;
  1451. }
  1452. case IDM_POPUP_EJECT:
  1453. case IDM_POPUP_PROPERTIES:
  1454. case IDM_POPUP_SPEEDDIAL:
  1455. case IDM_POPUP_ADDRESSBOOK:
  1456. case IDM_POPUP_GIVECONTROL:
  1457. case IDM_POPUP_CANCELGIVECONTROL:
  1458. {
  1459. CRoomListView *pView = GetRoster();
  1460. if (NULL != pView)
  1461. {
  1462. CParticipant * pPart = pView->GetParticipant();
  1463. if (NULL != pPart)
  1464. {
  1465. pPart->OnCommand(hwnd, (WORD)id);
  1466. }
  1467. }
  1468. break;
  1469. }
  1470. case ID_FILE_CREATE_SPEED_DIAL:
  1471. {
  1472. TCHAR szAddress[MAX_EMAIL_NAME_LENGTH + MAX_SERVER_NAME_LENGTH + 1];
  1473. LPCTSTR pszAddress = NULL;
  1474. CRoomListView *pView = GetRoster();
  1475. if (NULL != pView)
  1476. {
  1477. CParticipant * pPart = pView->GetParticipant();
  1478. if (NULL != pPart)
  1479. {
  1480. if (S_OK == pPart->GetUlsAddr(szAddress, CCHMAX(szAddress)))
  1481. {
  1482. pszAddress = szAddress;
  1483. }
  1484. }
  1485. }
  1486. CSpeedDialDlg sdd(hwnd, NM_ADDR_ULS);
  1487. sdd.DoModal(pszAddress);
  1488. break;
  1489. }
  1490. case ID_TB_CHAT:
  1491. case ID_TB_NEWWHITEBOARD:
  1492. case ID_TB_SHARING:
  1493. case ID_TB_NEW_CALL:
  1494. default:
  1495. m_pConfRoom->OnCommand(hwnd, id, hwndCtl, codeNotify);
  1496. break;
  1497. }
  1498. }
  1499. void CMainUI::OnDestroy(HWND hwnd)
  1500. {
  1501. if (NULL != m_pConfRoom)
  1502. {
  1503. m_pConfRoom->RemoveConferenceChangeHandler(this);
  1504. }
  1505. if (NULL != m_pAccel)
  1506. {
  1507. RemoveTranslateAccelerator(m_pAccel);
  1508. m_pAccel->Release();
  1509. m_pAccel = NULL;
  1510. }
  1511. }
  1512. BOOL CMainUI::OnQueryEndSession()
  1513. {
  1514. CMainUI::OnClose();
  1515. return(TRUE);
  1516. }
  1517. void CMainUI::OnClose()
  1518. {
  1519. CVideoWindow *pLocal = GetLocalVideo();
  1520. if (NULL != pLocal)
  1521. {
  1522. pLocal->Pause(TRUE);
  1523. }
  1524. }
  1525. VOID CMainUI::SaveSettings()
  1526. {
  1527. CVideoWindow *pVideo;
  1528. pVideo = GetLocalVideo();
  1529. if (NULL != pVideo)
  1530. {
  1531. pVideo->SaveSettings();
  1532. }
  1533. pVideo = GetRemoteVideo();
  1534. if (NULL != pVideo)
  1535. {
  1536. pVideo->SaveSettings();
  1537. }
  1538. }
  1539. VOID CMainUI::ForwardSysChangeMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1540. {
  1541. CVideoWindow *pVideo;
  1542. pVideo = GetLocalVideo();
  1543. if (NULL != pVideo)
  1544. {
  1545. pVideo->ForwardSysChangeMsg(uMsg, wParam, lParam);
  1546. }
  1547. pVideo = GetRemoteVideo();
  1548. if (NULL != pVideo)
  1549. {
  1550. pVideo->ForwardSysChangeMsg(uMsg, wParam, lParam);
  1551. }
  1552. CRoomListView *pView = GetRoster();
  1553. if (NULL != pView)
  1554. {
  1555. pView->ForwardSysChangeMsg(uMsg, wParam, lParam);
  1556. }
  1557. switch (uMsg)
  1558. {
  1559. case WM_PALETTECHANGED:
  1560. ::RedrawWindow(GetWindow(), NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
  1561. break;
  1562. }
  1563. }
  1564. void CMainUI::OnTimer(HWND hwnd, UINT id)
  1565. {
  1566. if (IDT_AUDIO == id)
  1567. {
  1568. CAudioControl *pAudioControl = GetAudioControl();
  1569. if (NULL != pAudioControl)
  1570. {
  1571. DWORD dwLevel;
  1572. dwLevel = pAudioControl->GetAudioSignalLevel(FALSE /*fSpeaker*/); // This level ranges from 0-100
  1573. m_pAudioMic->SetProgressValue(dwLevel);
  1574. dwLevel = pAudioControl->GetAudioSignalLevel(TRUE /*fSpeaker*/); // This level ranges from 0-100
  1575. m_pAudioSpeaker->SetProgressValue(dwLevel);
  1576. }
  1577. }
  1578. }
  1579. // Get the associated audion control object
  1580. CAudioControl *CMainUI::GetAudioControl()
  1581. {
  1582. return(m_pConfRoom->GetAudioControl());
  1583. }
  1584. static void EnableControl(IGenWindow *pControl, BOOL bEnable)
  1585. {
  1586. if (NULL == pControl)
  1587. {
  1588. return;
  1589. }
  1590. CComPtr<CGenWindow> spControl = com_cast<CGenWindow>(pControl);
  1591. if (spControl)
  1592. {
  1593. HWND hwnd = spControl->GetWindow();
  1594. if (NULL != hwnd)
  1595. {
  1596. EnableWindow(hwnd, bEnable);
  1597. }
  1598. }
  1599. }
  1600. void CMainUI::OnChangePermissions()
  1601. {
  1602. EnableControl(FindControl(ID_TB_NEW_CALL ), m_pConfRoom->IsNewCallAllowed());
  1603. EnableControl(FindControl(ID_TB_SHARING ), m_pConfRoom->IsSharingAllowed());
  1604. EnableControl(FindControl(ID_TB_CHAT ), m_pConfRoom->IsChatAllowed());
  1605. EnableControl(FindControl(ID_TB_NEWWHITEBOARD), m_pConfRoom->IsNewWhiteboardAllowed());
  1606. EnableControl(FindControl(ID_TB_FILETRANSFER ), m_pConfRoom->IsFileTransferAllowed());
  1607. }
  1608. void CMainUI::OnCallStarted()
  1609. {
  1610. m_bPreviewing = FALSE;
  1611. UpdateViewState();
  1612. UpdatePlayPauseState();
  1613. }
  1614. void CMainUI::OnCallEnded()
  1615. {
  1616. m_bPreviewing = TRUE;
  1617. UpdateViewState();
  1618. UpdatePlayPauseState();
  1619. }
  1620. void CMainUI::OnAudioLevelChange(BOOL fSpeaker, DWORD dwVolume)
  1621. {
  1622. CProgressTrackbar *pBar = fSpeaker ? m_pAudioSpeaker : m_pAudioMic;
  1623. if (NULL != pBar)
  1624. {
  1625. pBar->SetTrackValue((dwVolume*AudioMax + AudioVolMax/2) / AudioVolMax);
  1626. }
  1627. }
  1628. void CMainUI::OnAudioMuteChange(BOOL fSpeaker, BOOL fMute)
  1629. {
  1630. IGenWindow *pButton = FindControl(fSpeaker ? ID_TB_TUNESPEAKER_UNMUTE : ID_TB_TUNEMIC_UNMUTE);
  1631. if (NULL != pButton)
  1632. {
  1633. CComPtr<CButton> spButton = com_cast<CButton>(pButton);
  1634. if (spButton)
  1635. {
  1636. UpdateMuteState(fSpeaker, spButton);
  1637. }
  1638. }
  1639. }
  1640. BOOL CMainUI::GetPlayPauseState()
  1641. {
  1642. BOOL bMuted = TRUE;
  1643. // We're just going to show the state for the "big" window
  1644. if (IsPreviewing())
  1645. {
  1646. if (NULL != m_pLocalVideo)
  1647. {
  1648. bMuted = bMuted && m_pLocalVideo->IsPaused();
  1649. }
  1650. }
  1651. else
  1652. {
  1653. if (NULL != m_pRemoteVideo)
  1654. {
  1655. bMuted = bMuted && m_pRemoteVideo->IsPaused();
  1656. }
  1657. }
  1658. return(bMuted);
  1659. }
  1660. void CMainUI::UpdatePlayPauseState()
  1661. {
  1662. BOOL bMuted = GetPlayPauseState();
  1663. IGenWindow *pButton = FindControl(ID_TB_PLAYPAUSE);
  1664. if (NULL != pButton)
  1665. {
  1666. CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(pButton);
  1667. if (spButton)
  1668. {
  1669. spButton->SetCustomState(bMuted ? 0 : 1);
  1670. spButton->SetTooltip(RES2T(bMuted ? IDS_TT_TB_PLAYPAUSE : IDS_TT_TB_PAUSE));
  1671. }
  1672. }
  1673. }
  1674. void CMainUI::TogglePlayPause()
  1675. {
  1676. // We're going to apply the current state to both videos
  1677. BOOL bMute = !GetPlayPauseState();
  1678. if (NULL != m_pRemoteVideo)
  1679. {
  1680. m_pRemoteVideo->Pause(bMute);
  1681. }
  1682. if (NULL != m_pLocalVideo)
  1683. {
  1684. m_pLocalVideo->Pause(bMute);
  1685. }
  1686. UpdatePlayPauseState();
  1687. }
  1688. void CMainUI::OnChangeParticipant(CParticipant *pPart, NM_MEMBER_NOTIFY uNotify)
  1689. {
  1690. CRoomListView *pView = GetRoster();
  1691. if (NULL != pView)
  1692. {
  1693. pView->OnChangeParticipant(pPart, uNotify);
  1694. }
  1695. }
  1696. void CMainUI::OnVideoChannelChanged(NM_CHANNEL_NOTIFY uNotify, INmChannel *pChannel)
  1697. {
  1698. // BUGBUG georgep: This really should only go to one or the other,
  1699. // depending on if it is incoming, but I'm sending to both
  1700. CVideoWindow *pVideo;
  1701. pVideo = GetRemoteVideo();
  1702. if (NULL != pVideo)
  1703. {
  1704. pVideo->OnChannelChanged(uNotify, pChannel);
  1705. }
  1706. pVideo = GetLocalVideo();
  1707. if (NULL != pVideo)
  1708. {
  1709. pVideo->OnChannelChanged(uNotify, pChannel);
  1710. }
  1711. }
  1712. void CMainUI::StateChange(CVideoWindow *pVideo, NM_VIDEO_STATE uState)
  1713. {
  1714. UpdatePlayPauseState();
  1715. }
  1716. CFrame *CMainUI::s_pVideoFrame = NULL;
  1717. class CVideoFrame : public CFrame
  1718. {
  1719. protected:
  1720. virtual LRESULT ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1721. {
  1722. switch (uMsg)
  1723. {
  1724. case WM_DESTROY:
  1725. {
  1726. RECT rc;
  1727. ::GetWindowRect(hwnd, &rc);
  1728. RegEntry reVideo( VIDEO_LOCAL_KEY, HKEY_CURRENT_USER );
  1729. reVideo.SetValue(REGVAL_VIDEO_XPOS, rc.left);
  1730. reVideo.SetValue(REGVAL_VIDEO_YPOS, rc.top);
  1731. break;
  1732. }
  1733. }
  1734. return(CFrame::ProcessMessage(hwnd, uMsg, wParam, lParam));
  1735. }
  1736. } ;
  1737. BOOL CMainUI::NewVideoWindow(CConfRoom *pConfRoom)
  1738. {
  1739. if (NULL == s_pVideoFrame)
  1740. {
  1741. s_pVideoFrame = new CVideoFrame();
  1742. if (NULL == s_pVideoFrame)
  1743. {
  1744. // Could not initialize
  1745. return(FALSE);
  1746. }
  1747. }
  1748. HWND hwnd = s_pVideoFrame->GetWindow();
  1749. if (NULL != hwnd)
  1750. {
  1751. return(s_pVideoFrame->SetForeground());
  1752. }
  1753. TCHAR szTitle[256];
  1754. LoadString(::GetInstanceHandle(), IDS_MYVIDEO, szTitle, ARRAY_ELEMENTS(szTitle));
  1755. HICON hiBig = LoadIcon(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDI_CONFROOM));
  1756. if (!s_pVideoFrame->Create(
  1757. NULL, // Window owner
  1758. szTitle, // Window name
  1759. (WS_OVERLAPPEDWINDOW&~(WS_THICKFRAME|WS_MAXIMIZEBOX)), // Window style
  1760. 0, // Extended window style
  1761. 0, // Window pos: x
  1762. 0, // Window pos: y
  1763. 500, // Window size: width
  1764. 500, // Window size: height
  1765. _Module.GetModuleInstance(), // The hInstance to create the window on
  1766. hiBig, // The icon for the window
  1767. NULL // Window menu
  1768. ))
  1769. {
  1770. return(FALSE);
  1771. }
  1772. BOOL bRet = FALSE;
  1773. CMainUI *pMainUI = new CMainUI();
  1774. if (NULL != pMainUI)
  1775. {
  1776. if (pMainUI->Create(s_pVideoFrame->GetWindow(), pConfRoom, CreatePreviewOnly))
  1777. {
  1778. // Make sure it is the right size before showing the window
  1779. s_pVideoFrame->Resize();
  1780. RegEntry reVideo( VIDEO_LOCAL_KEY, HKEY_CURRENT_USER );
  1781. int x = reVideo.GetNumber(
  1782. REGVAL_VIDEO_XPOS, 0x7fff );
  1783. int y = reVideo.GetNumber(
  1784. REGVAL_VIDEO_YPOS, 0x7fff );
  1785. s_pVideoFrame->MoveEnsureVisible(x, y);
  1786. bRet = s_pVideoFrame->SetForeground();
  1787. }
  1788. pMainUI->Release();
  1789. }
  1790. if (!bRet)
  1791. {
  1792. DestroyWindow(s_pVideoFrame->GetWindow());
  1793. }
  1794. return(bRet);
  1795. }
  1796. void CMainUI::CleanUpVideoWindow()
  1797. {
  1798. if (NULL != s_pVideoFrame)
  1799. {
  1800. HWND hwnd = s_pVideoFrame->GetWindow();
  1801. if (NULL != hwnd)
  1802. {
  1803. DestroyWindow(hwnd);
  1804. }
  1805. s_pVideoFrame->Release();
  1806. s_pVideoFrame = NULL;
  1807. }
  1808. }
  1809. CRoomListView *CMainUI::GetRoster() const
  1810. {
  1811. return(NULL == m_pRoster ? NULL : m_pRoster->GetRoster());
  1812. }