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.

2045 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. 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. USES_RES2T
  284. pButton->SetTooltip(RES2T(buttons[i].idTooltip));
  285. pButton->SetWindowtext(RES2T(buttons[i].idTooltip));
  286. }
  287. // By default, do not hide individual buttons
  288. SetHideModes(pButton, Ignore);
  289. // Release our reference to the button
  290. pButton->Release();
  291. }
  292. }
  293. CToolbar *CreateToolbar(
  294. CGenWindow *pParent,
  295. const Buttons buttons[],
  296. int nButtons,
  297. LPARAM lHideModes,
  298. DWORD dwExStyle
  299. )
  300. {
  301. CToolbar *ret;
  302. ret = new CToolbar();
  303. if (NULL == ret)
  304. {
  305. return(NULL);
  306. }
  307. if (!ret->Create(pParent->GetWindow(), dwExStyle))
  308. {
  309. ret->Release();
  310. return(NULL);
  311. }
  312. SetHideModes(ret, lHideModes);
  313. AddButtons(ret, buttons, nButtons, TRUE);
  314. return(ret);
  315. }
  316. void CMainUI::CreateDialTB(CGenWindow *pParent)
  317. {
  318. // Create the toolbar
  319. m_pCalling = new CCallingBar();
  320. if (NULL != m_pCalling)
  321. {
  322. SetHideModes(m_pCalling, Compact);
  323. m_pCalling->Create(pParent, m_pConfRoom);
  324. // m_pCalling->Release();
  325. }
  326. }
  327. void CMainUI::CreateAppsTB(CGenWindow *pParent)
  328. {
  329. const static int AppsHMargin = 5;
  330. const static int AppsVMargin = 0;
  331. const static int AppsHGap = 11;
  332. static const Buttons appButtons[] =
  333. {
  334. { IDB_SHARE , CBitmapButton::Disabled+1, 1, ID_TB_SHARING , IDS_TT_TB_SHARING , },
  335. { IDB_CHAT , CBitmapButton::Disabled+1, 1, ID_TB_CHAT , IDS_TT_TB_CHAT , },
  336. { IDB_WHITEBOARD , CBitmapButton::Disabled+1, 1, ID_TB_NEWWHITEBOARD , IDS_TT_TB_NEWWHITEBOARD , },
  337. { IDB_FILE_TRANSFER , CBitmapButton::Disabled+1, 1, ID_TB_FILETRANSFER , IDS_TT_TB_FILETRANSFER , },
  338. } ;
  339. // Create the "data" buttons toolbar
  340. CToolbar *pApps = CreateToolbar(pParent, appButtons, ARRAY_ELEMENTS(appButtons), Compact);
  341. if (NULL != pApps)
  342. {
  343. // HACKHACK georgep: These numbers make it appear about right
  344. pApps->m_hMargin = AppsHMargin;
  345. pApps->m_vMargin = AppsVMargin;
  346. pApps->m_gap = AppsHGap;
  347. // pApps->m_bMinDesiredSize = TRUE;
  348. pApps->Release();
  349. }
  350. }
  351. void CMainUI::CreateVideoAndAppsTB(CGenWindow *pParent, CreateViewMode eMode, BOOL bEmbedded)
  352. {
  353. CLayeredView::LayoutStyle lVidDialStyle = CLayeredView::Center;
  354. switch (eMode)
  355. {
  356. case CreateFull:
  357. case CreatePreviewOnly:
  358. case CreateRemoteOnly:
  359. case CreateTelephone:
  360. break;
  361. case CreatePreviewNoPause:
  362. case CreateRemoteNoPause:
  363. lVidDialStyle = CLayeredView::Fill;
  364. break;
  365. default:
  366. return;
  367. }
  368. // Create the toolbar
  369. CBorderWindow *pVideoAndCalling = new CBorderWindow();
  370. if (NULL != pVideoAndCalling)
  371. {
  372. if (pVideoAndCalling->Create(pParent->GetWindow()))
  373. {
  374. SetHideModes(pVideoAndCalling, DataOnly);
  375. pVideoAndCalling->m_hGap = 4;
  376. pVideoAndCalling->m_vGap = 4;
  377. // This is the center part of the border window
  378. CLayeredView *pVidAndDial = new CLayeredView();
  379. if (NULL != pVidAndDial)
  380. {
  381. if (pVidAndDial->Create(pVideoAndCalling->GetWindow()))
  382. {
  383. pVideoAndCalling->m_uParts |= CBorderWindow::Center;
  384. pVidAndDial->m_lStyle = lVidDialStyle;
  385. CGenWindow *pLocalParent = pVidAndDial;
  386. if (CreateFull == eMode
  387. || CreateTelephone == eMode
  388. )
  389. {
  390. CreateDialingWindow(pVidAndDial);
  391. }
  392. if (CreateFull == eMode
  393. || CreateRemoteOnly == eMode
  394. || CreateRemoteNoPause == eMode
  395. )
  396. {
  397. // Create the remote video window
  398. m_pRemoteVideo = new CRemoteVideo(bEmbedded);
  399. if (NULL != m_pRemoteVideo)
  400. {
  401. SetHideModes(m_pRemoteVideo, Dialing|Previewing|DataOnly);
  402. m_pRemoteVideo->Create(pVidAndDial->GetWindow(), GetPalette(), this);
  403. pLocalParent = m_pRemoteVideo;
  404. }
  405. }
  406. if (CreateFull == eMode
  407. || CreatePreviewOnly == eMode
  408. || CreatePreviewNoPause == eMode
  409. )
  410. {
  411. // Create the local video window, even though we don't show it yet
  412. m_pLocalVideo = new CVideoWindow(CVideoWindow::LOCAL, bEmbedded);
  413. if (NULL != m_pLocalVideo)
  414. {
  415. SetHideModes(m_pLocalVideo, Dialing|Receiving|DataOnly);
  416. m_pLocalVideo->Create(pLocalParent->GetWindow(), GetPalette(), this);
  417. ShowWindow(m_pLocalVideo->GetWindow(), SW_HIDE);
  418. }
  419. }
  420. }
  421. pVidAndDial->Release();
  422. }
  423. if (CreateFull == eMode
  424. || CreateTelephone == eMode
  425. )
  426. {
  427. // create the toolbar
  428. static const Buttons abOsr2Calling[] =
  429. {
  430. { IDB_DIAL , CBitmapButton::Disabled+1, 1, ID_TB_NEW_CALL , IDS_TT_TB_NEW_CALL , },
  431. { IDB_HANGUP , CBitmapButton::Disabled+1, 1, IDM_FILE_HANGUP, IDS_TT_FILE_HANGUP, },
  432. { IDB_DIRECTORY, CBitmapButton::Disabled+1, 1, ID_TB_DIRECTORY, IDS_TT_TB_DIRECTORY, },
  433. { IDB_SHOWAV , CBitmapButton::Hot+1, Checked+1, ID_TB_SHOWAVTB , IDS_TT_TB_SHOWAVTB , },
  434. } ;
  435. CGenWindow *agwOsr2Calling[ARRAY_ELEMENTS(abOsr2Calling)];
  436. // This is the right-hand part of the border window
  437. CToolbar *ptbOsr2Calling = CreateToolbar(pVideoAndCalling, NULL, 0, DataOnly);
  438. if (NULL != ptbOsr2Calling)
  439. {
  440. pVideoAndCalling->m_uParts |= CBorderWindow::Right;
  441. ptbOsr2Calling->m_bVertical = TRUE;
  442. ptbOsr2Calling->m_nAlignment = Center;
  443. ZeroArray(agwOsr2Calling);
  444. AddButtons(ptbOsr2Calling, abOsr2Calling, ARRAY_ELEMENTS(abOsr2Calling),
  445. TRUE, agwOsr2Calling);
  446. SetHideModes(agwOsr2Calling[0], Normal);
  447. SetHideModes(agwOsr2Calling[3], Normal);
  448. ptbOsr2Calling->m_uRightIndex = 3;
  449. ptbOsr2Calling->Release();
  450. }
  451. }
  452. // This is the bottom part of the border window
  453. CreateAVTB(pVideoAndCalling, eMode);
  454. pVideoAndCalling->m_uParts |= CBorderWindow::Bottom;
  455. }
  456. pVideoAndCalling->Release();
  457. }
  458. }
  459. void CMainUI::CreateAVTB(CGenWindow *pParent, CreateViewMode eMode)
  460. {
  461. switch (eMode)
  462. {
  463. case CreateFull:
  464. case CreatePreviewOnly:
  465. case CreateRemoteOnly:
  466. break;
  467. default:
  468. return;
  469. }
  470. const static int AVHMargin = 10;
  471. const static int AVVMargin = 2;
  472. const static int AVHGap = ButtonsGap;
  473. // create the toolbar
  474. static const Buttons avButtons[] =
  475. {
  476. { IDB_PLAYPAUSE, CBitmapButton::Disabled+1, 2, ID_TB_PLAYPAUSE , IDS_TT_TB_PLAYPAUSE , },
  477. { IDB_PIP , CBitmapButton::Disabled+1, 1, ID_TB_PICINPIC , IDS_TT_TB_PICINPIC , },
  478. { IDB_AUDIO , CBitmapButton::Disabled+1, Checked+1, ID_TB_AUDIOTUNING, IDS_TT_TB_AUDIOTUNING, },
  479. } ;
  480. int nButtons = eMode == CreateFull ? ARRAY_ELEMENTS(avButtons) : 1;
  481. CToolbar *pAV = CreateToolbar(pParent, NULL, 0, NoAVTB|DataOnly);
  482. if (NULL != pAV)
  483. {
  484. CGenWindow *aButtons[ARRAY_ELEMENTS(avButtons)];
  485. ZeroArray(aButtons);
  486. AddButtons(pAV, avButtons, nButtons, TRUE, aButtons);
  487. CGenWindow *pAT;
  488. //
  489. // If video is completely disabled by policy, disable video buttons
  490. //
  491. if (!FIsSendVideoAllowed() && !FIsReceiveVideoAllowed())
  492. {
  493. pAT = aButtons[0];
  494. if (NULL != pAT)
  495. {
  496. EnableWindow(pAT->GetWindow(), FALSE);
  497. }
  498. pAT = aButtons[1];
  499. if (NULL != pAT)
  500. {
  501. EnableWindow(pAT->GetWindow(), FALSE);
  502. }
  503. }
  504. //
  505. // If audio is completely disabled by policy, disable audio buttons
  506. //
  507. pAT = aButtons[2];
  508. if (NULL != pAT)
  509. {
  510. ASSERT(ID_TB_AUDIOTUNING == GetDlgCtrlID(pAT->GetWindow()));
  511. if (!FIsAudioAllowed())
  512. {
  513. EnableWindow(pAT->GetWindow(), FALSE);
  514. }
  515. }
  516. pAV->m_hMargin = AVHMargin;
  517. pAV->m_vMargin = AVVMargin;
  518. pAV->m_gap = AVHGap;
  519. pAV->Release();
  520. }
  521. }
  522. #if FALSE // {
  523. void CMainUI::CreateCallsTB(CGenWindow *pParent)
  524. {
  525. // create the toolbar
  526. static const Buttons callsButtons[] =
  527. {
  528. { IDB_INCOMING , CBitmapButton::Hot+1, 1, ID_TB_INCOMING , IDS_TT_TB_INCOMING , },
  529. { IDB_HANGUP , CBitmapButton::Hot+1, 1, IDM_FILE_HANGUP , IDS_TT_FILE_HANGUP , },
  530. { IDB_CREDENTIALS, CBitmapButton::Hot+1, 1, ID_TB_CREDENTIALS, IDS_TT_TB_CREDENTIALS, },
  531. } ;
  532. CToolbar *pCalls = CreateToolbar(pParent, callsButtons, ARRAY_ELEMENTS(callsButtons),
  533. Compact);
  534. if (NULL != pCalls)
  535. {
  536. pCalls->Release();
  537. }
  538. }
  539. #endif // FALSE }
  540. void CMainUI::CreateDialingWindow(
  541. CGenWindow *pParent // The parent window
  542. )
  543. {
  544. const static int DialHMargin = 17;
  545. const static int DialVMargin = 4;
  546. const static int DialHGap = 5;
  547. const static int DialVGap = 0;
  548. CEdgedWindow *pEdge = new CEdgedWindow();
  549. if (NULL == pEdge)
  550. {
  551. return;
  552. }
  553. SetHideModes(pEdge, Video|DataOnly);
  554. if (pEdge->Create(pParent->GetWindow()))
  555. {
  556. CToolbar *pDialing = CreateToolbar(pEdge, NULL, 0, Ignore);
  557. if (NULL != pDialing)
  558. {
  559. pDialing->m_bVertical = TRUE;
  560. pDialing->m_gap = DialVGap;
  561. pDialing->m_hMargin = DialHMargin;
  562. pDialing->m_vMargin = DialVMargin;
  563. static const Buttons dialButtons[] =
  564. {
  565. { IDB_DIAL1 , CBitmapButton::Hot+1, 1, ID_TB_DIAL1 , IDS_TT_DIALPAD, },
  566. { IDB_DIAL2 , CBitmapButton::Hot+1, 1, ID_TB_DIAL2 , IDS_TT_DIALPAD, },
  567. { IDB_DIAL3 , CBitmapButton::Hot+1, 1, ID_TB_DIAL3 , IDS_TT_DIALPAD, },
  568. { IDB_DIAL4 , CBitmapButton::Hot+1, 1, ID_TB_DIAL4 , IDS_TT_DIALPAD, },
  569. { IDB_DIAL5 , CBitmapButton::Hot+1, 1, ID_TB_DIAL5 , IDS_TT_DIALPAD, },
  570. { IDB_DIAL6 , CBitmapButton::Hot+1, 1, ID_TB_DIAL6 , IDS_TT_DIALPAD, },
  571. { IDB_DIAL7 , CBitmapButton::Hot+1, 1, ID_TB_DIAL7 , IDS_TT_DIALPAD, },
  572. { IDB_DIAL8 , CBitmapButton::Hot+1, 1, ID_TB_DIAL8 , IDS_TT_DIALPAD, },
  573. { IDB_DIAL9 , CBitmapButton::Hot+1, 1, ID_TB_DIAL9 , IDS_TT_DIALPAD, },
  574. { IDB_DIALSTAR , CBitmapButton::Hot+1, 1, ID_TB_DIALSTAR , IDS_TT_DIALPAD, },
  575. { IDB_DIAL0 , CBitmapButton::Hot+1, 1, ID_TB_DIAL0 , IDS_TT_DIALPAD, },
  576. { IDB_DIALPOUND, CBitmapButton::Hot+1, 1, ID_TB_DIALPOUND, IDS_TT_DIALPAD, },
  577. } ;
  578. for (int row=0; row<4; ++row)
  579. {
  580. CToolbar *pRowTB = CreateToolbar(pDialing);
  581. if (NULL != pRowTB)
  582. {
  583. pRowTB->m_gap = DialHGap;
  584. AddButtons(pRowTB, &dialButtons[row*3], 3, TRUE, NULL, this);
  585. pRowTB->Release();
  586. }
  587. }
  588. pDialing->Release();
  589. }
  590. }
  591. pEdge->Release();
  592. }
  593. // Creates the audio-tuning window
  594. void CMainUI::CreateAudioTuningWindow(
  595. CGenWindow *pParent // The parent window
  596. )
  597. {
  598. static const int ATHMargin = 8;
  599. static const int ATVMargin = 6;
  600. static const int ATControlWidth = 170;
  601. CToolbar *pATWindow = CreateToolbar(pParent, NULL, 0, NoAVTB|Roster|DataOnly);
  602. if (NULL != pATWindow)
  603. {
  604. USES_RES2T
  605. pATWindow->m_bVertical = TRUE;
  606. pATWindow->m_nAlignment = Fill;
  607. pATWindow->m_gap = MainGap;
  608. CEdgedWindow *pEdge;
  609. pEdge = new CEdgedWindow();
  610. if (NULL != pEdge)
  611. {
  612. pEdge->m_hMargin = ATHMargin;
  613. pEdge->m_vMargin = ATVMargin;
  614. if (pEdge->Create(pATWindow->GetWindow()))
  615. {
  616. SetHideModes(pEdge, Ignore);
  617. CButton *pButton = new CButton();
  618. if (NULL != pButton)
  619. {
  620. pButton->Create(pEdge->GetWindow(), ID_TB_TUNEMIC_UNMUTE, NULL,
  621. BS_CHECKBOX|BS_ICON|WS_TABSTOP, this);
  622. pButton->SetTooltip(RES2T(IDS_TT_MUTE_MIC));
  623. pButton->SetWindowtext(RES2T(IDS_TT_MUTE_MIC));
  624. HICON hIcon = reinterpret_cast<HICON>(LoadImage(_Module.GetModuleInstance(),
  625. MAKEINTRESOURCE(IDI_MICFONE),
  626. IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
  627. LR_DEFAULTCOLOR));
  628. pButton->SetIcon(hIcon);
  629. pEdge->SetHeader(pButton);
  630. pButton->Release();
  631. }
  632. UpdateMuteState(FALSE, pButton);
  633. m_pAudioMic = new CProgressTrackbar();
  634. if (NULL != m_pAudioMic)
  635. {
  636. if (m_pAudioMic->Create(pEdge->GetWindow(), 0, this))
  637. {
  638. m_pAudioMic->SetTooltip(RES2T(IDS_TT_ADJUST_MIC));
  639. m_pAudioMic->SetWindowtext(RES2T(IDS_TT_ADJUST_MIC));
  640. m_pAudioMic->SetMaxValue(AudioMax);
  641. SIZE size;
  642. m_pAudioMic->GetDesiredSize(&size);
  643. size.cx = ATControlWidth;
  644. m_pAudioMic->SetDesiredSize(&size);
  645. }
  646. // m_pAudioMic->Release();
  647. }
  648. }
  649. pEdge->Release();
  650. }
  651. pEdge = new CEdgedWindow();
  652. if (NULL != pEdge)
  653. {
  654. pEdge->m_hMargin = ATHMargin;
  655. pEdge->m_vMargin = ATVMargin;
  656. if (pEdge->Create(pATWindow->GetWindow()))
  657. {
  658. SetHideModes(pEdge, Ignore);
  659. CButton *pButton = new CButton();
  660. if (NULL != pButton)
  661. {
  662. pButton->Create(pEdge->GetWindow(), ID_TB_TUNESPEAKER_UNMUTE, NULL,
  663. BS_CHECKBOX|BS_ICON|WS_TABSTOP, this);
  664. pButton->SetTooltip(RES2T(IDS_TT_MUTE_SPK));
  665. pButton->SetWindowtext(RES2T(IDS_TT_MUTE_SPK));
  666. HICON hIcon = reinterpret_cast<HICON>(LoadImage(_Module.GetModuleInstance(),
  667. MAKEINTRESOURCE(IDI_SPEAKER),
  668. IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
  669. LR_DEFAULTCOLOR));
  670. pButton->SetIcon(hIcon);
  671. pEdge->SetHeader(pButton);
  672. pButton->Release();
  673. }
  674. UpdateMuteState(TRUE, pButton);
  675. m_pAudioSpeaker = new CProgressTrackbar();
  676. if (NULL != m_pAudioSpeaker)
  677. {
  678. if (m_pAudioSpeaker->Create(pEdge->GetWindow(), 0, this))
  679. {
  680. m_pAudioSpeaker->SetTooltip(RES2T(IDS_TT_ADJUST_SPK));
  681. m_pAudioSpeaker->SetWindowtext(RES2T(IDS_TT_ADJUST_SPK));
  682. m_pAudioSpeaker->SetMaxValue(AudioMax);
  683. SIZE size;
  684. m_pAudioSpeaker->GetDesiredSize(&size);
  685. size.cx = ATControlWidth;
  686. m_pAudioSpeaker->SetDesiredSize(&size);
  687. }
  688. // m_pAudioSpeaker->Release();
  689. }
  690. }
  691. pEdge->Release();
  692. }
  693. pATWindow->Release();
  694. }
  695. CAudioControl *pAudioControl = GetAudioControl();
  696. if (NULL != pAudioControl)
  697. {
  698. // Force an update of the controls
  699. OnAudioLevelChange(TRUE , pAudioControl->GetSpeakerVolume());
  700. OnAudioLevelChange(FALSE, pAudioControl->GetRecorderVolume());
  701. }
  702. }
  703. void CMainUI::CreateRosterArea(CGenWindow *pParent, CreateViewMode eMode)
  704. {
  705. switch (eMode)
  706. {
  707. case CreateFull:
  708. case CreateDataOnly:
  709. case CreateTelephone:
  710. break;
  711. default:
  712. return;
  713. }
  714. CLayeredView *pView = new CLayeredView();
  715. if (NULL == pView)
  716. {
  717. // Pretty bad
  718. return;
  719. }
  720. if (pView->Create(pParent->GetWindow()))
  721. {
  722. SetHideModes(pView, IfNoChildren);
  723. pView->m_lStyle = CLayeredView::Fill;
  724. if (eMode != CreateDataOnly)
  725. {
  726. CreateAudioTuningWindow(pView);
  727. }
  728. if (eMode != CreateTelephone)
  729. {
  730. CToolbar *pRosterAndCall = CreateToolbar(pView);
  731. if (NULL != pRosterAndCall)
  732. {
  733. pRosterAndCall->m_nAlignment = CToolbar::Fill;
  734. m_pRoster = new CRosterParent();
  735. if (NULL != m_pRoster)
  736. {
  737. m_pRoster->Create(pRosterAndCall->GetWindow());
  738. // HACKHACK georgep: Just calling SetUserData directly for now
  739. SetHideModes(m_pRoster, Compact|AudioTuning);
  740. }
  741. if (CreateDataOnly != eMode)
  742. {
  743. CToolbar *pCalling = CreateToolbar(pRosterAndCall);
  744. if (NULL != pCalling)
  745. {
  746. SetHideModes(pCalling, Normal|Compact);
  747. pCalling->m_bVertical = TRUE;
  748. static const Buttons abCalling[] =
  749. {
  750. { IDB_HANGUP , CBitmapButton::Disabled+1, 1, IDM_FILE_HANGUP, IDS_TT_FILE_HANGUP, },
  751. { IDB_DIRECTORY, CBitmapButton::Disabled+1, 1, ID_TB_DIRECTORY, IDS_TT_TB_DIRECTORY, },
  752. } ;
  753. AddButtons(pCalling, abCalling, ARRAY_ELEMENTS(abCalling),
  754. TRUE, NULL, this);
  755. pCalling->Release();
  756. }
  757. }
  758. pRosterAndCall->m_uRightIndex = 1;
  759. pRosterAndCall->m_bHasCenterChild = TRUE;
  760. pRosterAndCall->Release();
  761. }
  762. }
  763. }
  764. pView->Release();
  765. }
  766. BOOL CMainUI::Create(
  767. HWND hwndParent,
  768. CConfRoom *pConfRoom,
  769. CreateViewMode eMode,
  770. BOOL bEmbedded
  771. )
  772. {
  773. // Store this away so we can call some methods in it later
  774. m_pConfRoom = pConfRoom;
  775. ASSERT(m_pConfRoom);
  776. if (NULL == m_pConfRoom)
  777. {
  778. return(FALSE);
  779. }
  780. // Create the window
  781. if (!CToolbar::Create(hwndParent))
  782. {
  783. return(FALSE);
  784. }
  785. // Try to remain a little bit abstract
  786. CToolbar *pMain = this;
  787. m_pConfRoom->AddConferenceChangeHandler(this);
  788. // A vertical toolbar that fills all its area
  789. pMain->m_hMargin = MainHMargin;
  790. pMain->m_vMargin = MainVMargin;
  791. pMain->m_gap = MainGap;
  792. if (CreateRemoteNoPause == eMode
  793. || CreatePreviewNoPause == eMode
  794. )
  795. {
  796. pMain->m_hMargin = 0;
  797. pMain->m_vMargin = 0;
  798. pMain->m_bHasCenterChild = TRUE;
  799. //HACKHACK This only works because all these views have only 1 window
  800. pMain->m_uRightIndex = 1;
  801. }
  802. pMain->m_bVertical = TRUE;
  803. pMain->m_nAlignment = Fill;
  804. m_hbBack = CGenWindow::GetStandardBrush();
  805. // Create all the sub toolbars
  806. if (CreateFull == eMode
  807. || CreateTelephone == eMode
  808. )
  809. {
  810. CreateDialTB(pMain);
  811. }
  812. CreateVideoAndAppsTB(pMain, eMode, bEmbedded);
  813. CreateRosterArea(pMain, eMode);
  814. if (CreateFull == eMode
  815. || CreateDataOnly == eMode
  816. )
  817. {
  818. CreateAppsTB(pMain);
  819. }
  820. // Now we need to update to the current state of the conference
  821. if (m_pConfRoom->FIsConferenceActive())
  822. {
  823. OnCallStarted();
  824. CSimpleArray<CParticipant*>& lMembers = m_pConfRoom->GetParticipantList();
  825. for (int i=lMembers.GetSize()-1; i>=0; --i)
  826. {
  827. OnChangeParticipant(lMembers[i], NM_MEMBER_ADDED);
  828. }
  829. // Need to tell everybody what the active channels are
  830. INmConference2 *pNmConf = m_pConfRoom->GetActiveConference();
  831. if (NULL != pNmConf)
  832. {
  833. // Just in case
  834. pNmConf->AddRef();
  835. IEnumNmChannel *pEnumCh;
  836. if (SUCCEEDED(pNmConf->EnumChannel(&pEnumCh)))
  837. {
  838. INmChannel *pChannel;
  839. ULONG uGot;
  840. while (S_OK == pEnumCh->Next(1, &pChannel, &uGot) && 1 == uGot)
  841. {
  842. OnVideoChannelChanged(NM_CHANNEL_ADDED, pChannel);
  843. pChannel->Release();
  844. }
  845. pEnumCh->Release();
  846. }
  847. pNmConf->Release();
  848. }
  849. }
  850. if (CreateDataOnly == eMode)
  851. {
  852. SetDataOnly(TRUE);
  853. }
  854. if (CreateTelephone == eMode)
  855. {
  856. SetDialing(TRUE);
  857. SetAudioTuning(TRUE);
  858. }
  859. OnChangePermissions();
  860. UpdateViewState();
  861. UpdatePlayPauseState();
  862. return(TRUE);
  863. }
  864. HBRUSH CMainUI::GetBackgroundBrush()
  865. {
  866. return(m_hbBack);
  867. }
  868. // REVIEW georgep: Should this loop until it gets an IGenWindow?
  869. HPALETTE CMainUI::GetPalette()
  870. {
  871. return(m_pConfRoom->GetPalette());
  872. }
  873. // Recursive function to hide/show windows for the current view
  874. // Returns whether any of the children are visible
  875. BOOL ShowWindows(
  876. HWND hwndParent, // The parent window to start from
  877. LPARAM lDefMode, // The hide mode to use if Inherit
  878. LPARAM hideMode // The current hide mode
  879. )
  880. {
  881. BOOL bRet = FALSE;
  882. for (HWND hwndChild=::GetWindow(hwndParent, GW_CHILD); NULL!=hwndChild;
  883. hwndChild=::GetWindow(hwndChild, GW_HWNDNEXT))
  884. {
  885. IGenWindow *pChild = IGenWindow::FromHandle(hwndChild);
  886. if (NULL == pChild)
  887. {
  888. continue;
  889. }
  890. LPARAM lMode = GetHideModes(pChild);
  891. if (Ignore == lMode)
  892. {
  893. if ((GetWindowStyle(hwndChild)&WS_VISIBLE) != 0)
  894. {
  895. bRet = TRUE;
  896. }
  897. continue;
  898. }
  899. if (Inherit == lMode)
  900. {
  901. lMode = lDefMode;
  902. }
  903. // recurse to child windows first to avoid flicker
  904. LPARAM lNoChildren = ShowWindows(hwndChild, lMode, hideMode) ? 0 : IfNoChildren;
  905. // If any of the hide mode bits are set, then hide the window
  906. // otherwise show it
  907. BOOL bShow = ((lMode&(hideMode|lNoChildren)) == 0);
  908. if (bShow)
  909. {
  910. bRet = TRUE;
  911. }
  912. ShowWindow(hwndChild, bShow ? SW_SHOW : SW_HIDE);
  913. }
  914. return(bRet);
  915. }
  916. BOOL CMainUI::CanPreview()
  917. {
  918. HWND hwndLocal = GetVideoWindow(TRUE);
  919. return(NULL!=hwndLocal && GetLocalVideo()->IsXferAllowed());
  920. }
  921. void CMainUI::UpdateViewState()
  922. {
  923. // Put together all the modes we ARE in, and hide any windows that want
  924. // to be hidden while in one of those modes
  925. // The default mode
  926. LPARAM hideModes;
  927. if (IsCompact())
  928. {
  929. hideModes = Compact;
  930. if (!IsShowAVTB())
  931. {
  932. hideModes |= NoAVTB;
  933. }
  934. }
  935. else if (IsDataOnly())
  936. {
  937. hideModes = DataOnly;
  938. }
  939. else
  940. {
  941. hideModes = Normal;
  942. }
  943. if (IsDialing())
  944. {
  945. hideModes |= Dialing;
  946. }
  947. else
  948. {
  949. // hwndRemote will be NULL for PreviewOnly mode
  950. HWND hwndRemote = GetVideoWindow(FALSE);
  951. if (NULL == hwndRemote)
  952. {
  953. hideModes |= Previewing;
  954. }
  955. else
  956. {
  957. HWND hwndLocal = GetVideoWindow(TRUE);
  958. BOOL bPreviewing = IsPreviewing();
  959. HWND parent = NULL;
  960. BOOL bZoomable;
  961. LONG style = GetWindowLong(hwndLocal, GWL_EXSTYLE);
  962. if (bPreviewing)
  963. {
  964. hideModes |= Previewing;
  965. parent = GetParent(hwndRemote);
  966. style |= WS_EX_CLIENTEDGE;
  967. bZoomable = TRUE;
  968. }
  969. else
  970. {
  971. hideModes |= (m_bPicInPic && CanPreview()) ? ReceivingWPiP : Receiving;
  972. parent = hwndRemote;
  973. style &= ~WS_EX_CLIENTEDGE;
  974. bZoomable = FALSE;
  975. }
  976. if (GetParent(hwndLocal) != parent)
  977. {
  978. SetWindowLong(hwndLocal, GWL_EXSTYLE, style);
  979. SetParent(hwndLocal, parent);
  980. SetWindowPos(hwndLocal, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
  981. CVideoWindow *pVideo = GetLocalVideo();
  982. if (NULL != pVideo)
  983. {
  984. pVideo->SetZoomable(bZoomable);
  985. }
  986. }
  987. }
  988. }
  989. // Enable/disable the PiP window
  990. IGenWindow *pPiP = FindControl(ID_TB_PICINPIC);
  991. if (NULL != pPiP)
  992. {
  993. CComPtr<CGenWindow> spButton = com_cast<CGenWindow>(pPiP);
  994. BOOL bEnable = !IsPreviewing() && CanPreview() && !IsDialing();
  995. EnableWindow(spButton->GetWindow(), bEnable);
  996. }
  997. hideModes |= IsAudioTuning() && !IsDataOnly() ? AudioTuning : Roster;
  998. HWND hwnd = GetWindow();
  999. ShowWindows(hwnd, 0, hideModes);
  1000. // If the focus is on a child window which is now not visible, but we are,
  1001. // then change the focus to this window
  1002. if (!IsWindowVisible(GetFocus()) && IsWindowActive(hwnd) && IsWindowVisible(hwnd))
  1003. {
  1004. SetFocus(hwnd);
  1005. }
  1006. IGenWindow *pButton = FindControl(ID_TB_AUDIOTUNING);
  1007. CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(pButton);
  1008. if (spButton)
  1009. {
  1010. BOOL bAudioTuning = IsAudioTuning() && !IsCompact();
  1011. spButton->SetCustomState(bAudioTuning ? Checked : Unchecked);
  1012. USES_RES2T
  1013. spButton->SetTooltip(RES2T(bAudioTuning ? IDS_TT_TB_SHOWROSTER : IDS_TT_TB_AUDIOTUNING));
  1014. spButton->SetWindowtext(RES2T(bAudioTuning ? IDS_TT_TB_SHOWROSTER : IDS_TT_TB_AUDIOTUNING));
  1015. }
  1016. OnDesiredSizeChanged();
  1017. }
  1018. void CMainUI::SetCompact(BOOL bCompact)
  1019. {
  1020. bCompact = bCompact != FALSE;
  1021. if (IsCompact() == bCompact)
  1022. {
  1023. // Nothing to do
  1024. return;
  1025. }
  1026. m_eViewMode = bCompact ? ViewCompact : ViewNormal;
  1027. UpdateViewState();
  1028. }
  1029. void CMainUI::SetDataOnly(BOOL bDataOnly)
  1030. {
  1031. bDataOnly = bDataOnly != FALSE;
  1032. if (IsDataOnly() == bDataOnly)
  1033. {
  1034. // Nothing to do
  1035. return;
  1036. }
  1037. m_eViewMode = bDataOnly ? ViewDataOnly : ViewNormal;
  1038. UpdateViewState();
  1039. }
  1040. void CMainUI::SetDialing(BOOL bDialing)
  1041. {
  1042. bDialing = bDialing != FALSE;
  1043. if (IsDialing() == bDialing)
  1044. {
  1045. // Nothing to do
  1046. return;
  1047. }
  1048. m_bDialing = bDialing;
  1049. UpdateViewState();
  1050. }
  1051. void CMainUI::SetPicInPic(BOOL bPicInPic)
  1052. {
  1053. bPicInPic = bPicInPic != FALSE;
  1054. if (IsPicInPic() == bPicInPic)
  1055. {
  1056. // Nothing to do
  1057. return;
  1058. }
  1059. m_bPicInPic = bPicInPic;
  1060. UpdateViewState();
  1061. }
  1062. BOOL CMainUI::IsPicInPicAllowed()
  1063. {
  1064. return(!IsDataOnly() && !m_bPreviewing && CanPreview());
  1065. }
  1066. void CMainUI::SetAudioTuning(BOOL bAudioTuning)
  1067. {
  1068. if ((IsAudioTuning() && bAudioTuning) || (!IsAudioTuning() && !bAudioTuning))
  1069. {
  1070. // Nothing to do
  1071. return;
  1072. }
  1073. m_bAudioTuning = bAudioTuning;
  1074. if (IsAudioTuning())
  1075. {
  1076. SetTimer(GetWindow(), IDT_AUDIO, AUDIODLG_MIC_TIMER_PERIOD, NULL);
  1077. }
  1078. else
  1079. {
  1080. KillTimer(GetWindow(), IDT_AUDIO);
  1081. }
  1082. UpdateViewState();
  1083. }
  1084. void CMainUI::SetShowAVTB(BOOL bShowAVTB)
  1085. {
  1086. if ((IsShowAVTB() && bShowAVTB) || (!IsShowAVTB() && !bShowAVTB))
  1087. {
  1088. // Nothing to do
  1089. return;
  1090. }
  1091. m_bShowAVTB = bShowAVTB;
  1092. UpdateViewState();
  1093. }
  1094. LRESULT CMainUI::ProcessMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  1095. {
  1096. static const UINT c_uMsgMSWheel = ::IsWindowsNT() ? WM_MOUSEWHEEL :
  1097. ::RegisterWindowMessage(_TEXT("MSWHEEL_ROLLMSG"));
  1098. switch (message)
  1099. {
  1100. HANDLE_MSG(hwnd, WM_TIMER , OnTimer);
  1101. HANDLE_MSG(hwnd, WM_DESTROY , OnDestroy);
  1102. case WM_CREATE:
  1103. {
  1104. // Allow dialog-like keyboard support
  1105. HACCEL hAccel = LoadAccelerators(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDR_MAINUI));
  1106. if (NULL != hAccel)
  1107. {
  1108. m_pAccel = new CTranslateAccelTable(hwnd, hAccel);
  1109. if (NULL != m_pAccel)
  1110. {
  1111. AddTranslateAccelerator(m_pAccel);
  1112. }
  1113. }
  1114. break;
  1115. }
  1116. case WM_SETFOCUS:
  1117. ShiftFocus(GetWindow(), TRUE);
  1118. break;
  1119. default:
  1120. if (message == c_uMsgMSWheel)
  1121. {
  1122. CRoomListView *pView = GetRoster();
  1123. if (NULL != pView)
  1124. {
  1125. ::SendMessage(pView->GetHwnd(), message, wParam, lParam);
  1126. }
  1127. break;
  1128. }
  1129. break;
  1130. }
  1131. return(CToolbar::ProcessMessage(hwnd, message, wParam, lParam));
  1132. }
  1133. void CMainUI::OnScroll(CProgressTrackbar *pTrackbar, UINT code, int pos)
  1134. {
  1135. BOOL bSpeaker = FALSE;
  1136. if (m_pAudioSpeaker == pTrackbar)
  1137. {
  1138. bSpeaker = TRUE;
  1139. }
  1140. else if (m_pAudioMic == pTrackbar)
  1141. {
  1142. }
  1143. else
  1144. {
  1145. // I don't think we should get here
  1146. return;
  1147. }
  1148. // Can't trust the pos passed in
  1149. pos = pTrackbar->GetTrackValue();
  1150. CAudioControl *pAudioControl = GetAudioControl();
  1151. if (NULL == pAudioControl)
  1152. {
  1153. return;
  1154. }
  1155. DWORD dwVolume = (pos*AudioVolMax + AudioMax/2)/AudioMax;
  1156. dwVolume = min(max(dwVolume, 0), AudioVolMax);
  1157. if (bSpeaker)
  1158. {
  1159. pAudioControl->SetSpeakerVolume(dwVolume);
  1160. }
  1161. else
  1162. {
  1163. pAudioControl->SetRecorderVolume(dwVolume);
  1164. }
  1165. }
  1166. HWND CMainUI::GetVideoWindow(BOOL bLocal)
  1167. {
  1168. CVideoWindow *pVideo = bLocal ? GetLocalVideo() : GetRemoteVideo();
  1169. return(NULL == pVideo ? NULL : pVideo->GetWindow());
  1170. }
  1171. void CMainUI::ToggleMute(BOOL bSpeaker)
  1172. {
  1173. CAudioControl *pAudioControl = GetAudioControl();
  1174. if (NULL != pAudioControl)
  1175. {
  1176. BOOL bMuted = bSpeaker ? pAudioControl->IsSpkMuted() : pAudioControl->IsRecMuted();
  1177. pAudioControl->MuteAudio(bSpeaker, !bMuted);
  1178. }
  1179. }
  1180. void CMainUI::UpdateMuteState(BOOL bSpeaker, CButton *pButton)
  1181. {
  1182. CAudioControl *pAudioControl = GetAudioControl();
  1183. if (NULL != pAudioControl)
  1184. {
  1185. BOOL bMuted = bSpeaker ? pAudioControl->IsSpkMuted() : pAudioControl->IsRecMuted();
  1186. pButton->SetChecked(!bMuted);
  1187. }
  1188. }
  1189. void CMainUI::BumpAudio(BOOL bSpeaker, int pct)
  1190. {
  1191. CAudioControl *pAudioControl = GetAudioControl();
  1192. if (NULL != pAudioControl)
  1193. {
  1194. int dwVolume = static_cast<int>(bSpeaker ?
  1195. pAudioControl->GetSpeakerVolume() : pAudioControl->GetRecorderVolume());
  1196. dwVolume += (pct*AudioVolMax/100);
  1197. dwVolume = min(max(dwVolume, 0), AudioVolMax);
  1198. if (bSpeaker)
  1199. {
  1200. pAudioControl->SetSpeakerVolume(dwVolume);
  1201. }
  1202. else
  1203. {
  1204. pAudioControl->SetRecorderVolume(dwVolume);
  1205. }
  1206. }
  1207. }
  1208. void CMainUI::SetAudioProperty(BOOL bSpeaker, NM_AUDPROP uID, ULONG uValue)
  1209. {
  1210. CAudioControl *pAudioControl = GetAudioControl();
  1211. if (NULL != pAudioControl)
  1212. {
  1213. pAudioControl->SetProperty(bSpeaker, uID, uValue);
  1214. }
  1215. }
  1216. // IButtonChange
  1217. void CMainUI::OnClick(CButton *pButton)
  1218. {
  1219. HWND hwndCtl = pButton->GetWindow();
  1220. OnCommand(GetWindow(), GetWindowLong(hwndCtl, GWL_ID), hwndCtl, BN_CLICKED);
  1221. }
  1222. void CMainUI::OnInitMenu(HMENU hMenu)
  1223. {
  1224. CVideoWindow *pVideo = IsPreviewing() ? GetLocalVideo() : GetRemoteVideo();
  1225. if (NULL != pVideo)
  1226. {
  1227. pVideo->UpdateVideoMenu(hMenu);
  1228. pVideo = GetLocalVideo();
  1229. EnableMenuItem(hMenu, IDM_VIDEO_UNDOCK,
  1230. MF_BYCOMMAND|(NULL != pVideo && pVideo->IsXferAllowed() ? MF_ENABLED : MF_GRAYED|MF_DISABLED));
  1231. }
  1232. }
  1233. static void AppendText(CCallingBar *pCalling, TCHAR cAdd)
  1234. {
  1235. if (NULL != pCalling)
  1236. {
  1237. // I don't want to change a string that you can't see
  1238. if (IsWindowVisible(pCalling->GetWindow()))
  1239. {
  1240. TCHAR szText[] = TEXT("0");
  1241. szText[0] = cAdd;
  1242. TCHAR szTemp[MAX_PATH];
  1243. int nLen = pCalling->GetText(szTemp, ARRAY_ELEMENTS(szTemp));
  1244. if (nLen + lstrlen(szText) <= ARRAY_ELEMENTS(szTemp) - 1)
  1245. {
  1246. lstrcat(szTemp, szText);
  1247. pCalling->SetText(szTemp);
  1248. }
  1249. }
  1250. }
  1251. }
  1252. void CMainUI::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  1253. {
  1254. switch (id)
  1255. {
  1256. case ID_NAV_TAB:
  1257. ShiftFocus(hwnd, TRUE);
  1258. break;
  1259. case ID_NAV_SHIFT_TAB:
  1260. ShiftFocus(hwnd, FALSE);
  1261. break;
  1262. case IDM_VIEW_DIALPAD:
  1263. SetDialing(!IsDialing());
  1264. break;
  1265. case ID_TB_PICINPIC:
  1266. SetPicInPic(!IsPicInPic());
  1267. break;
  1268. case ID_TB_REJECT:
  1269. case ID_TB_CREDENTIALS:
  1270. break;
  1271. case ID_TB_AUDIOTUNING:
  1272. {
  1273. m_bStateChanged = TRUE;
  1274. SetAudioTuning(!IsAudioTuning());
  1275. break;
  1276. }
  1277. case ID_TB_SHOWAVTB:
  1278. {
  1279. m_bStateChanged = TRUE;
  1280. SetShowAVTB(!IsShowAVTB());
  1281. if( 0 == hwndCtl )
  1282. break;
  1283. CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(IGenWindow::FromHandle(hwndCtl));
  1284. if (spButton)
  1285. {
  1286. BOOL bShow = IsShowAVTB();
  1287. spButton->SetCustomState(bShow ? Checked : Unchecked);
  1288. USES_RES2T
  1289. spButton->SetTooltip(RES2T(bShow ? IDS_TT_TB_HIDEAVTB : IDS_TT_TB_SHOWAVTB));
  1290. spButton->SetWindowtext(RES2T(bShow ? IDS_TT_TB_HIDEAVTB : IDS_TT_TB_SHOWAVTB));
  1291. }
  1292. break;
  1293. }
  1294. case ID_TB_TUNEMIC_UNMUTE:
  1295. ToggleMute(FALSE);
  1296. break;
  1297. case ID_TB_TUNESPEAKER_UNMUTE:
  1298. ToggleMute(TRUE);
  1299. break;
  1300. case ID_TB_DIAL0:
  1301. case ID_TB_DIAL1:
  1302. case ID_TB_DIAL2:
  1303. case ID_TB_DIAL3:
  1304. case ID_TB_DIAL4:
  1305. case ID_TB_DIAL5:
  1306. case ID_TB_DIAL6:
  1307. case ID_TB_DIAL7:
  1308. case ID_TB_DIAL8:
  1309. case ID_TB_DIAL9:
  1310. SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, id-ID_TB_DIAL0);
  1311. AppendText(m_pCalling, '0'+id-ID_TB_DIAL0);
  1312. break;
  1313. case ID_TB_DIALSTAR:
  1314. SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, 10);
  1315. AppendText(m_pCalling, '*');
  1316. break;
  1317. case ID_TB_DIALPOUND:
  1318. SetAudioProperty(FALSE, NM_AUDPROP_DTMF_DIGIT, 11);
  1319. AppendText(m_pCalling, '#');
  1320. break;
  1321. case ID_TB_DIRECTORY:
  1322. {
  1323. CFindSomeone::findSomeone(m_pConfRoom);
  1324. }
  1325. break;
  1326. case ID_TB_PLAYPAUSE:
  1327. TogglePlayPause();
  1328. break;
  1329. case IDM_VIDEO_ZOOM1:
  1330. case IDM_VIDEO_ZOOM2:
  1331. case IDM_VIDEO_ZOOM3:
  1332. case IDM_VIDEO_ZOOM4:
  1333. case IDM_VIDEO_UNDOCK:
  1334. case IDM_VIDEO_GETACAMERA:
  1335. {
  1336. CVideoWindow *pVideo = IsPreviewing() ? GetLocalVideo() : GetRemoteVideo();
  1337. if (NULL != pVideo)
  1338. {
  1339. pVideo->OnCommand(id);
  1340. }
  1341. break;
  1342. }
  1343. case IDM_POPUP_EJECT:
  1344. case IDM_POPUP_PROPERTIES:
  1345. case IDM_POPUP_SPEEDDIAL:
  1346. case IDM_POPUP_ADDRESSBOOK:
  1347. case IDM_POPUP_GIVECONTROL:
  1348. case IDM_POPUP_CANCELGIVECONTROL:
  1349. {
  1350. CRoomListView *pView = GetRoster();
  1351. if (NULL != pView)
  1352. {
  1353. CParticipant * pPart = pView->GetParticipant();
  1354. if (NULL != pPart)
  1355. {
  1356. pPart->OnCommand(hwnd, (WORD)id);
  1357. }
  1358. }
  1359. break;
  1360. }
  1361. case ID_FILE_CREATE_SPEED_DIAL:
  1362. {
  1363. TCHAR szAddress[MAX_EMAIL_NAME_LENGTH + MAX_SERVER_NAME_LENGTH + 1];
  1364. LPCTSTR pszAddress = NULL;
  1365. CRoomListView *pView = GetRoster();
  1366. if (NULL != pView)
  1367. {
  1368. CParticipant * pPart = pView->GetParticipant();
  1369. if (NULL != pPart)
  1370. {
  1371. if (S_OK == pPart->GetUlsAddr(szAddress, CCHMAX(szAddress)))
  1372. {
  1373. pszAddress = szAddress;
  1374. }
  1375. }
  1376. }
  1377. CSpeedDialDlg sdd(hwnd, NM_ADDR_ULS);
  1378. sdd.DoModal(pszAddress);
  1379. break;
  1380. }
  1381. case ID_TB_CHAT:
  1382. case ID_TB_NEWWHITEBOARD:
  1383. case ID_TB_SHARING:
  1384. case ID_TB_NEW_CALL:
  1385. default:
  1386. m_pConfRoom->OnCommand(hwnd, id, hwndCtl, codeNotify);
  1387. break;
  1388. }
  1389. }
  1390. void CMainUI::OnDestroy(HWND hwnd)
  1391. {
  1392. if (NULL != m_pConfRoom)
  1393. {
  1394. m_pConfRoom->RemoveConferenceChangeHandler(this);
  1395. }
  1396. if (NULL != m_pAccel)
  1397. {
  1398. RemoveTranslateAccelerator(m_pAccel);
  1399. m_pAccel->Release();
  1400. m_pAccel = NULL;
  1401. }
  1402. }
  1403. BOOL CMainUI::OnQueryEndSession()
  1404. {
  1405. CMainUI::OnClose();
  1406. return(TRUE);
  1407. }
  1408. void CMainUI::OnClose()
  1409. {
  1410. CVideoWindow *pLocal = GetLocalVideo();
  1411. if (NULL != pLocal)
  1412. {
  1413. pLocal->Pause(TRUE);
  1414. }
  1415. }
  1416. VOID CMainUI::SaveSettings()
  1417. {
  1418. CVideoWindow *pVideo;
  1419. pVideo = GetLocalVideo();
  1420. if (NULL != pVideo)
  1421. {
  1422. pVideo->SaveSettings();
  1423. }
  1424. pVideo = GetRemoteVideo();
  1425. if (NULL != pVideo)
  1426. {
  1427. pVideo->SaveSettings();
  1428. }
  1429. }
  1430. VOID CMainUI::ForwardSysChangeMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1431. {
  1432. CVideoWindow *pVideo;
  1433. pVideo = GetLocalVideo();
  1434. if (NULL != pVideo)
  1435. {
  1436. pVideo->ForwardSysChangeMsg(uMsg, wParam, lParam);
  1437. }
  1438. pVideo = GetRemoteVideo();
  1439. if (NULL != pVideo)
  1440. {
  1441. pVideo->ForwardSysChangeMsg(uMsg, wParam, lParam);
  1442. }
  1443. CRoomListView *pView = GetRoster();
  1444. if (NULL != pView)
  1445. {
  1446. pView->ForwardSysChangeMsg(uMsg, wParam, lParam);
  1447. }
  1448. switch (uMsg)
  1449. {
  1450. case WM_PALETTECHANGED:
  1451. ::RedrawWindow(GetWindow(), NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
  1452. break;
  1453. }
  1454. }
  1455. void CMainUI::OnTimer(HWND hwnd, UINT id)
  1456. {
  1457. if (IDT_AUDIO == id)
  1458. {
  1459. CAudioControl *pAudioControl = GetAudioControl();
  1460. if (NULL != pAudioControl)
  1461. {
  1462. DWORD dwLevel;
  1463. dwLevel = pAudioControl->GetAudioSignalLevel(FALSE /*fSpeaker*/); // This level ranges from 0-100
  1464. m_pAudioMic->SetProgressValue(dwLevel);
  1465. dwLevel = pAudioControl->GetAudioSignalLevel(TRUE /*fSpeaker*/); // This level ranges from 0-100
  1466. m_pAudioSpeaker->SetProgressValue(dwLevel);
  1467. }
  1468. }
  1469. }
  1470. // Get the associated audion control object
  1471. CAudioControl *CMainUI::GetAudioControl()
  1472. {
  1473. return(m_pConfRoom->GetAudioControl());
  1474. }
  1475. static void EnableControl(IGenWindow *pControl, BOOL bEnable)
  1476. {
  1477. if (NULL == pControl)
  1478. {
  1479. return;
  1480. }
  1481. CComPtr<CGenWindow> spControl = com_cast<CGenWindow>(pControl);
  1482. if (spControl)
  1483. {
  1484. HWND hwnd = spControl->GetWindow();
  1485. if (NULL != hwnd)
  1486. {
  1487. EnableWindow(hwnd, bEnable);
  1488. }
  1489. }
  1490. }
  1491. void CMainUI::OnChangePermissions()
  1492. {
  1493. EnableControl(FindControl(ID_TB_NEW_CALL ), m_pConfRoom->IsNewCallAllowed());
  1494. EnableControl(FindControl(ID_TB_SHARING ), m_pConfRoom->IsSharingAllowed());
  1495. EnableControl(FindControl(ID_TB_CHAT ), m_pConfRoom->IsChatAllowed());
  1496. EnableControl(FindControl(ID_TB_NEWWHITEBOARD), m_pConfRoom->IsNewWhiteboardAllowed());
  1497. EnableControl(FindControl(ID_TB_FILETRANSFER ), m_pConfRoom->IsFileTransferAllowed());
  1498. }
  1499. void CMainUI::OnCallStarted()
  1500. {
  1501. m_bPreviewing = FALSE;
  1502. UpdateViewState();
  1503. UpdatePlayPauseState();
  1504. }
  1505. void CMainUI::OnCallEnded()
  1506. {
  1507. m_bPreviewing = TRUE;
  1508. UpdateViewState();
  1509. UpdatePlayPauseState();
  1510. }
  1511. void CMainUI::OnAudioLevelChange(BOOL fSpeaker, DWORD dwVolume)
  1512. {
  1513. CProgressTrackbar *pBar = fSpeaker ? m_pAudioSpeaker : m_pAudioMic;
  1514. if (NULL != pBar)
  1515. {
  1516. pBar->SetTrackValue((dwVolume*AudioMax + AudioVolMax/2) / AudioVolMax);
  1517. }
  1518. }
  1519. void CMainUI::OnAudioMuteChange(BOOL fSpeaker, BOOL fMute)
  1520. {
  1521. IGenWindow *pButton = FindControl(fSpeaker ? ID_TB_TUNESPEAKER_UNMUTE : ID_TB_TUNEMIC_UNMUTE);
  1522. if (NULL != pButton)
  1523. {
  1524. CComPtr<CButton> spButton = com_cast<CButton>(pButton);
  1525. if (spButton)
  1526. {
  1527. UpdateMuteState(fSpeaker, spButton);
  1528. }
  1529. }
  1530. }
  1531. BOOL CMainUI::GetPlayPauseState()
  1532. {
  1533. BOOL bMuted = TRUE;
  1534. // We're just going to show the state for the "big" window
  1535. if (IsPreviewing())
  1536. {
  1537. if (NULL != m_pLocalVideo)
  1538. {
  1539. bMuted = bMuted && m_pLocalVideo->IsPaused();
  1540. }
  1541. }
  1542. else
  1543. {
  1544. if (NULL != m_pRemoteVideo)
  1545. {
  1546. bMuted = bMuted && m_pRemoteVideo->IsPaused();
  1547. }
  1548. }
  1549. return(bMuted);
  1550. }
  1551. void CMainUI::UpdatePlayPauseState()
  1552. {
  1553. BOOL bMuted = GetPlayPauseState();
  1554. IGenWindow *pButton = FindControl(ID_TB_PLAYPAUSE);
  1555. if (NULL != pButton)
  1556. {
  1557. CComPtr<CBitmapButton> spButton = com_cast<CBitmapButton>(pButton);
  1558. if (spButton)
  1559. {
  1560. spButton->SetCustomState(bMuted ? 0 : 1);
  1561. USES_RES2T
  1562. spButton->SetTooltip(RES2T(bMuted ? IDS_TT_TB_PLAYPAUSE : IDS_TT_TB_PAUSE));
  1563. spButton->SetWindowtext(RES2T(bMuted ? IDS_TT_TB_PLAYPAUSE : IDS_TT_TB_PAUSE));
  1564. }
  1565. }
  1566. }
  1567. void CMainUI::TogglePlayPause()
  1568. {
  1569. // We're going to apply the current state to both videos
  1570. BOOL bMute = !GetPlayPauseState();
  1571. if (NULL != m_pRemoteVideo)
  1572. {
  1573. m_pRemoteVideo->Pause(bMute);
  1574. }
  1575. if (NULL != m_pLocalVideo)
  1576. {
  1577. m_pLocalVideo->Pause(bMute);
  1578. }
  1579. UpdatePlayPauseState();
  1580. }
  1581. void CMainUI::OnChangeParticipant(CParticipant *pPart, NM_MEMBER_NOTIFY uNotify)
  1582. {
  1583. CRoomListView *pView = GetRoster();
  1584. if (NULL != pView)
  1585. {
  1586. pView->OnChangeParticipant(pPart, uNotify);
  1587. }
  1588. }
  1589. void CMainUI::OnVideoChannelChanged(NM_CHANNEL_NOTIFY uNotify, INmChannel *pChannel)
  1590. {
  1591. // BUGBUG georgep: This really should only go to one or the other,
  1592. // depending on if it is incoming, but I'm sending to both
  1593. CVideoWindow *pVideo;
  1594. pVideo = GetRemoteVideo();
  1595. if (NULL != pVideo)
  1596. {
  1597. pVideo->OnChannelChanged(uNotify, pChannel);
  1598. }
  1599. pVideo = GetLocalVideo();
  1600. if (NULL != pVideo)
  1601. {
  1602. pVideo->OnChannelChanged(uNotify, pChannel);
  1603. }
  1604. }
  1605. void CMainUI::StateChange(CVideoWindow *pVideo, NM_VIDEO_STATE uState)
  1606. {
  1607. UpdatePlayPauseState();
  1608. }
  1609. CFrame *CMainUI::s_pVideoFrame = NULL;
  1610. class CVideoFrame : public CFrame
  1611. {
  1612. protected:
  1613. virtual LRESULT ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1614. {
  1615. switch (uMsg)
  1616. {
  1617. case WM_DESTROY:
  1618. {
  1619. RECT rc;
  1620. ::GetWindowRect(hwnd, &rc);
  1621. RegEntry reVideo( VIDEO_LOCAL_KEY, HKEY_CURRENT_USER );
  1622. reVideo.SetValue(REGVAL_VIDEO_XPOS, rc.left);
  1623. reVideo.SetValue(REGVAL_VIDEO_YPOS, rc.top);
  1624. break;
  1625. }
  1626. }
  1627. return(CFrame::ProcessMessage(hwnd, uMsg, wParam, lParam));
  1628. }
  1629. } ;
  1630. BOOL CMainUI::NewVideoWindow(CConfRoom *pConfRoom)
  1631. {
  1632. if (NULL == s_pVideoFrame)
  1633. {
  1634. s_pVideoFrame = new CVideoFrame();
  1635. if (NULL == s_pVideoFrame)
  1636. {
  1637. // Could not initialize
  1638. return(FALSE);
  1639. }
  1640. }
  1641. HWND hwnd = s_pVideoFrame->GetWindow();
  1642. if (NULL != hwnd)
  1643. {
  1644. return(s_pVideoFrame->SetForeground());
  1645. }
  1646. TCHAR szTitle[256];
  1647. LoadString(::GetInstanceHandle(), IDS_MYVIDEO, szTitle, ARRAY_ELEMENTS(szTitle));
  1648. HICON hiBig = LoadIcon(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDI_CONFROOM));
  1649. if (!s_pVideoFrame->Create(
  1650. NULL, // Window owner
  1651. szTitle, // Window name
  1652. (WS_OVERLAPPEDWINDOW&~(WS_THICKFRAME|WS_MAXIMIZEBOX)), // Window style
  1653. 0, // Extended window style
  1654. 0, // Window pos: x
  1655. 0, // Window pos: y
  1656. 500, // Window size: width
  1657. 500, // Window size: height
  1658. _Module.GetModuleInstance(), // The hInstance to create the window on
  1659. hiBig, // The icon for the window
  1660. NULL // Window menu
  1661. ))
  1662. {
  1663. return(FALSE);
  1664. }
  1665. BOOL bRet = FALSE;
  1666. CMainUI *pMainUI = new CMainUI();
  1667. if (NULL != pMainUI)
  1668. {
  1669. if (pMainUI->Create(s_pVideoFrame->GetWindow(), pConfRoom, CreatePreviewOnly))
  1670. {
  1671. // Make sure it is the right size before showing the window
  1672. s_pVideoFrame->Resize();
  1673. RegEntry reVideo( VIDEO_LOCAL_KEY, HKEY_CURRENT_USER );
  1674. int x = reVideo.GetNumber(
  1675. REGVAL_VIDEO_XPOS, 0x7fff );
  1676. int y = reVideo.GetNumber(
  1677. REGVAL_VIDEO_YPOS, 0x7fff );
  1678. s_pVideoFrame->MoveEnsureVisible(x, y);
  1679. bRet = s_pVideoFrame->SetForeground();
  1680. }
  1681. pMainUI->Release();
  1682. }
  1683. if (!bRet)
  1684. {
  1685. DestroyWindow(s_pVideoFrame->GetWindow());
  1686. }
  1687. return(bRet);
  1688. }
  1689. void CMainUI::CleanUpVideoWindow()
  1690. {
  1691. if (NULL != s_pVideoFrame)
  1692. {
  1693. HWND hwnd = s_pVideoFrame->GetWindow();
  1694. if (NULL != hwnd)
  1695. {
  1696. DestroyWindow(hwnd);
  1697. }
  1698. s_pVideoFrame->Release();
  1699. s_pVideoFrame = NULL;
  1700. }
  1701. }
  1702. CRoomListView *CMainUI::GetRoster() const
  1703. {
  1704. return(NULL == m_pRoster ? NULL : m_pRoster->GetRoster());
  1705. }