MainFrame.cpp
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:34k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. // MainFrame.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Conference.h"
  5. #include "MainFrame.h"
  6. #include "CreateConferenceDlg.h"
  7. #include "LoginDlg.h"
  8. #include "ShowBroadcastDialog.h"
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. extern CConferenceApp theApp;
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CMainFrame
  17. CMainFrame::CMainFrame( ) : btmdlg( this )
  18. {
  19. this->m_view = new CMainView( );
  20. this->canTip = false;
  21. if( ! this->Create( NULL , "视频会议系统 - 用户名: " + ( CString )theApp.GetClient( ).GetUserName( ) + "  会议名:    时间: " , WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE , CRect( 0 , 0 , ::GetSystemMetrics( SM_CXSCREEN ) , ::GetSystemMetrics( SM_CYSCREEN ) ) , NULL , 0 ) )
  22. {
  23. delete this->m_view ; this->m_view = NULL;
  24. }
  25. }
  26. CMainFrame::~CMainFrame( )
  27. {
  28. }
  29. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  30. //{{AFX_MSG_MAP(CMainFrame)
  31. ON_WM_CREATE()
  32. ON_BN_CLICKED(IDC_CREATE_CONFERENCE_BUTTON, OnCreateConferenceButton)
  33. ON_BN_CLICKED(IDC_JOIN_CONFERENCE_BUTTON, OnJoinConferenceButton)
  34. ON_COMMAND(ID_WND_CONFERENCE_LIST, OnWndConferenceList)
  35. ON_COMMAND(ID_WND_CONFERENCE_ROOM, OnWndConferenceRoom)
  36. ON_WM_SHOWWINDOW()
  37. ON_WM_NCHITTEST()
  38. ON_WM_SYSCOMMAND()
  39. ON_WM_DESTROY()
  40. ON_WM_TIMER()
  41. ON_WM_CLOSE()
  42. //}}AFX_MSG_MAP
  43. ON_MESSAGE( CClient::MSG , OnPackageMessage )
  44. ON_COMMAND_RANGE( ID_CONFERENCE_CREATE , ID_CONFERENCE_EXIT , OnConference )
  45. ON_COMMAND_RANGE( ID_WND_1_VIDEO , ID_WND_1_VIDEO + VIDEO_WND_NUMBER , OnVideoWnd )
  46. ON_MESSAGE( WM_TRACER_MESSAGE , OnTrace )
  47. ON_MESSAGE( WM_ADD_USER , OnAddUser )
  48. END_MESSAGE_MAP()
  49. /////////////////////////////////////////////////////////////////////////////
  50. // CMainFrame message handlers
  51. int CMainFrame::OnCreate( LPCREATESTRUCT lpCreateStruct ) 
  52. {
  53. if ( CFrameWnd::OnCreate( lpCreateStruct ) == -1 )
  54. return -1;
  55. //增加底部窗口
  56. this->btmdlg.Create( CBottomDialog::IDD );
  57. this->myBar.Create( this , RBS_AUTOSIZE , WS_CHILD | WS_VISIBLE | CBRS_BOTTOM );
  58. this->myBar.AddBar( &this->btmdlg , RGB( 214 , 239 , 255 ) , RGB( 214 , 239 , 255 ) , NULL , RBBS_NOGRIPPER );
  59. /*
  60.     //设定菜单
  61. CMenu menu; 
  62. menu.LoadMenu( IDR_MAIN_MENU ); 
  63. this->SetMenu( &menu ); 
  64. menu.Detach( );
  65. */
  66. //删除系统菜单的移动项
  67. this->GetSystemMenu( FALSE )->RemoveMenu( 1 , MF_BYPOSITION );
  68.     //创建视图
  69. if( ! this->m_view->Create( NULL , NULL , AFX_WS_DEFAULT_VIEW , CRect( 0 , 0 , 0 , 0 ) , this , AFX_IDW_PANE_FIRST , NULL ) )
  70. return -1;
  71.     //框架允许停靠在左边或者右边
  72. this->EnableDocking( CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT );
  73. //创建会议列表窗口停靠栏
  74. if( this->sizeDlgBar.Create( "会议列表" , this , CSize( ::GetSystemMetrics( SM_CXSCREEN ) / 4  , ::GetSystemMetrics( SM_CYSCREEN ) * 3 / 4 ) , FALSE , 1 , WS_CHILD | WS_VISIBLE | CBRS_LEFT ) )
  75. {
  76. this->sizeDlgBar.SetSCBStyle( SCBS_SIZECHILD );
  77. this->sizeDlgBar.SetBarStyle( this->sizeDlgBar.GetBarStyle( ) | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC );
  78. this->sizeDlgBar.EnableDocking( CBRS_ALIGN_LEFT );
  79. this->dlgBar.Create( CConferenceDialog::IDD , &this->sizeDlgBar );
  80. this->dlgBar.mainFrame = this;
  81. this->DockControlBar( &this->sizeDlgBar , AFX_IDW_DOCKBAR_LEFT );
  82. }//停靠的矩形窗口
  83. CRect rc;
  84.     //创建5个视频窗口
  85. for( int i = 0; i < VIDEO_WND_NUMBER ; i ++ )
  86. {
  87. this->videoBar[ i ].Create( "视频窗口" , this , CSize( ::GetSystemMetrics( SM_CXSCREEN ) / 4  , ::GetSystemMetrics( SM_CYSCREEN ) / 4 ) , FALSE , 2 + i , WS_CHILD | WS_VISIBLE | ( ! i ? CBRS_LEFT : CBRS_RIGHT ) );
  88. this->videoBar[ i ].SetSCBStyle( SCBS_SIZECHILD );
  89. this->videoBar[ i ].SetBarStyle( this->videoBar[ i ].GetBarStyle( ) | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC );
  90. this->videoDlg[ i ].Create( CVideoDialog::IDD , &this->videoBar[ i ] );
  91.         //第一个视频窗口
  92. if( i == 0 )
  93. {
  94. this->RecalcLayout( );
  95. this->dlgBar.GetWindowRect( &rc );
  96. rc.OffsetRect( 0 , 1 );
  97. this->videoBar[ i ].EnableDocking( CBRS_ALIGN_LEFT );
  98. this->DockControlBar( &this->videoBar[ i ] , AFX_IDW_DOCKBAR_LEFT , &rc );
  99. }//第二个视频窗口
  100. else if( i == 1 )
  101. {
  102. this->videoBar[ i ].EnableDocking( CBRS_ALIGN_RIGHT );
  103. this->DockControlBar( &this->videoBar[ i ] , AFX_IDW_DOCKBAR_RIGHT );
  104. }
  105. else //其他的视频窗口
  106. {
  107. this->RecalcLayout( );
  108. this->videoBar[ i - 1 ].GetWindowRect( &rc );
  109. rc.OffsetRect( 0 , 1 );
  110. this->videoBar[ i ].EnableDocking( CBRS_ALIGN_RIGHT );
  111. this->DockControlBar( &this->videoBar[ i ] , AFX_IDW_DOCKBAR_RIGHT , &rc );
  112. }
  113. }//载入窗口的排列状态
  114. CSizingControlBar::GlobalLoadState( this , "video_window" );
  115. //初始化窗口
  116. theApp.GetClient( ).InitVideo( this->videoDlg[ 0 ].GetSafeHwnd( ) );
  117.     //预览
  118. theApp.GetClient( ).GetVideo( ).StartPreview( );
  119. //标记本地视频窗口
  120. if( theApp.GetClient( ).GetVideo( ) )
  121. {
  122. this->videoDlg[ 0 ].SetWindowText( "本地视频" );
  123. //通过设置窗口的属性保存该用户的id
  124. ::SetWindowLong( this->videoDlg[ 0 ].GetSafeHwnd( ) , GWL_USERDATA , true );
  125. }//消息处理句柄
  126. theApp.GetClient( ).AttachMsgHandler( this->GetSafeHwnd( ) );
  127. //请求在线用户状态
  128. theApp.GetClient( ).SendOnlineUserREQ( );
  129.     //启动定时器为2分钟
  130. // this->SetTimer( 1 , 120000 , NULL );
  131. return 0;
  132. }
  133. //创建会议
  134. void CMainFrame::OnCreateConferenceButton( ) 
  135. {
  136. switch( this->dlgBar.m_tab.GetCurSel( ) )
  137. {
  138. case 0 : //邀请用户
  139. {   //没有加入会议
  140. if( theApp.GetClient( ).GetConferenceName( ).empty( ) )
  141. {
  142. MessageBox( "你还没有创建会议,不可以邀请用户" , "视频会议" , MB_ICONSTOP | MB_OK );
  143. return;
  144. }//不是主持人
  145. if( ! theApp.GetClient( ).IsCharement( ) ) 
  146. {
  147. MessageBox( "你不是主持人,不可以邀请用户加入你的会议" , "视频会议" , MB_ICONSTOP | MB_OK );
  148. return;
  149. }
  150. POSITION pos = this->dlgBar.m_olist.GetFirstSelectedItemPosition( ) ; 
  151. if( pos == NULL )
  152. {
  153. MessageBox( "请在在线用户列表中选择你要邀请的用户" , "视频会议" , MB_ICONSTOP | MB_OK );
  154. return;
  155. }
  156. int nItem = 0 , user_id;
  157. CString status , name;
  158.             //循环邀请用户加入会议
  159. while( pos )
  160. {
  161. nItem = this->dlgBar.m_olist.GetNextSelectedItem( pos );
  162. status = this->dlgBar.m_olist.GetItemText( nItem , 1 );
  163. if( status.Find( "空闲" ) == -1 )
  164. {
  165. if( this->dlgBar.m_olist.GetItemData( nItem ) != theApp.GetClient( ).GetUserID( ) )
  166. name += this->dlgBar.m_olist.GetItemText( nItem , 0 ) + "、";
  167. }
  168. else //发送邀请用户
  169. {
  170. user_id = this->dlgBar.m_olist.GetItemData( nItem );
  171. //强制邀请用户加入会议. 
  172. theApp.GetClient( ).SendInviteUserREQ( user_id , false );
  173.                     //邀请加入会议,没有提示信息
  174. this->canTip = false;
  175. this->SetTimer( 3 , 60000 , NULL );
  176. }
  177. }//提示没有邀请到用户的原因
  178. if( ! name.IsEmpty( ) )
  179. MessageBox( "无法邀请 " + name + "因为他们在开会中" , "视频会议" , MB_ICONINFORMATION | MB_OK );
  180. }
  181. break;
  182. case 1 : //创建会议
  183. if( theApp.GetClient( ).GetConferenceName( ).empty( ) )
  184. {
  185. if( theApp.GetClient( ).IsBroadcast( ) )
  186. {
  187. MessageBox( "你目前在处于广播状态,无法创建会议nn要创建会议,请退出广播" , "视频会议" , MB_ICONSTOP | MB_OK );
  188. return;
  189. }
  190. CCreateConferenceDlg dlg;
  191. if( dlg.DoModal( ) == IDOK )
  192. theApp.GetClient( ).SendCreateDataNode( dlg.m_name );
  193. }
  194. else
  195. MessageBox( "你已经在会议中,无法再次创建会议" , "视频会议客户端" , MB_ICONSTOP | MB_OK );
  196. break;
  197. case 2 : //退出会议
  198. if( theApp.GetClient( ).GetConferenceName( ).empty( ) )
  199. MessageBox( "你没有加入任何会议" , "视频会议" , MB_ICONSTOP | MB_OK );
  200.         //发送退出会议
  201. else if( MessageBox( "你确定要退出会议吗?" , "视频会议" ,MB_ICONQUESTION |MB_OKCANCEL ) == IDOK )
  202. {
  203. theApp.GetClient( ).SendExitDataNode( );
  204.             //退出会议,会议室清空
  205. this->dlgBar.m_rlist.DeleteAllItems( );
  206.             //图像清空
  207. for( int i = theApp.GetClient( ).GetVideo( ) ? 1 : 0 ; i < VIDEO_WND_NUMBER; i ++ )
  208. {
  209. this->videoDlg[ i ].SetWindowText( "" );
  210. ::SetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ), GWL_USERDATA , 0 );
  211. this->videoDlg[ i ].Invalidate( );
  212. }
  213. }
  214. break;
  215. }
  216. }
  217. //加入会议
  218. void CMainFrame::OnJoinConferenceButton( ) 
  219. {   //上课
  220. if( this->dlgBar.m_tab.GetCurSel( ) == 0 )
  221. {
  222. if( theApp.GetClient( ).GetConferenceName( ).empty( ) )
  223. {
  224. MessageBox( "你还没有创建会议,不可以邀请用户" , "视频会议" , MB_ICONSTOP | MB_OK );
  225. return;
  226. }
  227. if( ! theApp.GetClient( ).IsCharement( ) ) 
  228. {
  229. MessageBox( "你不是主持人,不可以邀请用户加入你的会议" , "视频会议" , MB_ICONSTOP | MB_OK );
  230. return;
  231. }
  232. POSITION pos = this->dlgBar.m_olist.GetFirstSelectedItemPosition( ) ; 
  233. if( pos == NULL )
  234. {
  235. MessageBox( "请在在线用户列表中选择你要邀请的用户" , "视频会议" , MB_ICONSTOP | MB_OK );
  236. return;
  237. }
  238. int nItem = 0 , user_id;
  239. CString status , name;
  240. while( pos )
  241. {
  242. nItem = this->dlgBar.m_olist.GetNextSelectedItem( pos );
  243. status = this->dlgBar.m_olist.GetItemText( nItem , 1 );
  244. if( status.Find( "空闲" ) == -1 )
  245. name += this->dlgBar.m_olist.GetItemText( nItem , 0 ) + "、";
  246. else //发送邀请用户
  247. {
  248. user_id = this->dlgBar.m_olist.GetItemData( nItem );
  249. theApp.GetClient( ).SendInviteUserREQ( user_id , false );
  250. }
  251. }
  252. if( ! name.IsEmpty( ) )
  253. MessageBox( "无法邀请 " + name + "因为他们在开会中" , "视频会议" , MB_ICONINFORMATION | MB_OK );
  254. }//加入会议
  255. if( this->dlgBar.m_tab.GetCurSel( ) == 1 )
  256. {
  257. POSITION  pos = this->dlgBar.m_clist.GetFirstSelectedItemPosition( );
  258. if( pos )
  259. {
  260. if( ! theApp.GetClient( ).GetConferenceName( ).empty( ) )
  261. MessageBox( "你已经在会议中,无法再次加入会议" , "视频会议" , MB_ICONSTOP | MB_OK );
  262. else
  263. {
  264. int index = this->dlgBar.m_clist.GetNextSelectedItem( pos );
  265. theApp.GetClient( ).SendJoinDataNodeREQ( this->dlgBar.m_clist.GetItemText( index , 0 ) );
  266.                 //等待主持人回复
  267. CInitDialog dlg( "等待主持人的回复,请等待..." );
  268.                 //用户点击取消按钮,取消等待加入会议
  269. if( dlg.DoModal( ) != IDOK )
  270. theApp.GetClient( ).GetConferenceName( ) = "";
  271. }
  272. }
  273. else
  274. MessageBox( "请在会议列表中选择一个会议" , "视频会议" , MB_ICONSTOP | MB_OK );
  275. }//请求发言 或者 停止发言 或者 点名发言
  276. else if( this->dlgBar.m_tab.GetCurSel( ) == 2 )
  277. {
  278. if( theApp.GetClient( ).GetConferenceName( ).empty( ) )
  279. {
  280. MessageBox( "你没有加入任何会议" , "视频会议" , MB_ICONSTOP | MB_OK );
  281. return;
  282. }
  283. CString name;
  284. this->dlgBar.m_btn2.GetWindowText( name );
  285.         //如果是主持人
  286. if( theApp.GetClient( ).IsCharement( ) )
  287.         {
  288. POSITION pos = this->dlgBar.m_rlist.GetFirstSelectedItemPosition( );
  289. if( pos )
  290. {   //取出用户id
  291. int user_id = this->dlgBar.m_rlist.GetItemData( this->dlgBar.m_rlist.GetNextSelectedItem( pos ) );
  292.                 //点中自己的节点
  293. if( user_id == theApp.GetClient( ).GetUserID( ) )
  294. {
  295. MessageBox( "你是主持人,不可以停止发言" , "视频会议" , MB_ICONSTOP | MB_OK ); 
  296. return;
  297. }//点名发言
  298. if( name.Find( "点名发言" ) != -1 )
  299. { //判断窗口号是否可用
  300. for( int i = 0; i < VIDEO_WND_NUMBER; i ++ )
  301. if( ! ::GetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA ) )
  302. break;
  303. if( i>= VIDEO_WND_NUMBER )
  304. MessageBox( "没有空闲的视频窗口显示发言人图像,请停止其他人的发言再试一试" , "视频会议" , MB_ICONSTOP | MB_OK );
  305. else 
  306. theApp.GetClient( ).SendRecvAudioREQ( user_id );
  307. }//停止发言
  308. else if( name.Find( "停止发言" ) != -1 && MessageBox( "你确定要停止该用户的发言吗" , "视频会议" , MB_ICONQUESTION | MB_OKCANCEL ) == IDOK )
  309. theApp.GetClient( ).SendStopAudioREQ( user_id );
  310. }
  311. else 
  312. MessageBox( "请选择你要" + name + "的用户" , "视频会议" , MB_ICONSTOP | MB_OK );
  313. }
  314. else
  315. {   //申请发言
  316. if( name.Find( "申请发言" ) != -1 )
  317. {
  318. if( theApp.GetClient( ).GetSoundIn( ).IsRecording( ) )
  319. MessageBox( "你目前已经可以发言了" , "视频会议" , MB_ICONSTOP | MB_OK );
  320. else
  321. {   //先判断视频窗口是否够用
  322. for( int i = 0 ; i < VIDEO_WND_NUMBER ; i ++ )
  323. if( ! ::GetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA ) ) 
  324. break;
  325. if( i >= VIDEO_WND_NUMBER )
  326. MessageBox( "会议中有某个成员的视频窗口不够显示您的视频图像,无法请求发言" , "视频会议" , MB_ICONSTOP | MB_OK );
  327. else 
  328. {
  329. theApp.GetClient( ).SendSendAudioREQ( );
  330. //等待主持人回复
  331. CInitDialog dlg( "等待主持人的回复,请等待..." );
  332. dlg.DoModal( );
  333. }
  334. }
  335. }//停止发言
  336. else if( name.Find( "停止发言" ) != -1 )
  337. {
  338. if( ! theApp.GetClient( ).GetSoundIn( ).IsRecording( ) )
  339. {
  340. MessageBox( "你目前没有发言" , "视频会议" , MB_ICONSTOP | MB_OK );
  341. return;
  342. }
  343. else if( MessageBox( "你确定要停止发言吗" , "视频会议" , MB_ICONQUESTION | MB_OKCANCEL ) == IDOK )
  344. theApp.GetClient( ).SendStopAudioREQ( );
  345. }
  346. }
  347. }
  348. }
  349. //取得主持人视频
  350. CWnd * CMainFrame::GetCharentWnd( void )
  351. {
  352. if( theApp.GetClient( ).GetConferenceName( ).empty( ) )
  353. {
  354. CTipDialog::ShowTip( "你没有加入任何会议,没有主持人视频" );
  355. return NULL;
  356. }
  357. else
  358. { //返回主持人窗口
  359. if( theApp.GetClient( ).IsCharement( ) )
  360. {
  361. if( theApp.GetClient( ).GetVideo( ) )
  362. return &this->videoDlg[ 0 ];
  363. CTipDialog::ShowTip( "主持人没有视频" );
  364. //主持人没有图像
  365. return  NULL;
  366. }//查找用户
  367. LVFINDINFO info;
  368. memset( &info , 0 , sizeof( info ) );
  369. info.flags = LVFI_STRING;
  370. info.psz = theApp.GetClient( ).GetConferenceName( ).c_str( );
  371. int id = 0;
  372.         //提示
  373. if( ( id = this->dlgBar.m_clist.FindItem( &info ) ) < 0 )
  374. {
  375. CTipDialog::ShowTip( "你没有加入任何会议,没有主持人视频" );
  376. return NULL;
  377. }
  378. id = this->dlgBar.m_clist.GetItemData( id );
  379. for( int i = 0; i <  VIDEO_WND_NUMBER ; i ++ )
  380. if( ::GetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA ) == id )
  381. return &this->videoDlg[ i ];
  382.         //提示
  383. CTipDialog::ShowTip( "主持人没有视频" );
  384. return NULL;
  385. }
  386. }
  387. //取得本地图像
  388. CWnd * CMainFrame::GetLocalVideo( void )
  389. {
  390. return theApp.GetClient( ).GetVideo( ) ? &theApp.GetClient( ).GetVideo( ) : NULL;
  391. }
  392. //会议菜单响应函数
  393. void CMainFrame::OnConference( UINT nID )
  394. {
  395. switch( nID )
  396. { //创建会议
  397. case ID_CONFERENCE_CREATE : 
  398. this->dlgBar.m_tab.SetCurSel( 1 );
  399. this->OnCreateConferenceButton( );
  400. break;
  401.     //加入会议
  402. case ID_CONFERENCE_JOIN : 
  403. this->dlgBar.m_tab.SetCurSel( 1 );
  404. this->OnJoinConferenceButton( ); 
  405. break;
  406.     //退出会议
  407. case ID_CONFERENCE_EXIT :
  408. this->dlgBar.m_tab.SetCurSel( 2 );
  409. this->OnCreateConferenceButton( );
  410. break;
  411. }
  412. }
  413. //显示会议列表窗口
  414. void CMainFrame::OnWndConferenceList( ) 
  415. {
  416. this->ShowControlBar( &this->sizeDlgBar , true , false );
  417. this->dlgBar.m_tab.SetCurSel( 1 );
  418. }
  419. //显示会议室窗口
  420. void CMainFrame::OnWndConferenceRoom( )
  421. {
  422. this->ShowControlBar( &this->sizeDlgBar , true , false );
  423. this->dlgBar.m_tab.SetCurSel( 2 );
  424. }
  425. //视频数据窗口
  426. void CMainFrame::OnVideoWnd( UINT nID )
  427. {
  428. this->ShowControlBar( &this->videoBar[ nID - ID_WND_1_VIDEO ] , true , false );
  429. }
  430. //窗口刚要显示时
  431. void CMainFrame::OnShowWindow(BOOL bShow, UINT nStatus) 
  432. {
  433. CFrameWnd::OnShowWindow(bShow, nStatus);
  434. //关闭初始化的窗口
  435. if( bShow && theApp.initdlg.GetSafeHwnd( ) )
  436. theApp.initdlg.SendMessage( WM_CLOSE );
  437. }
  438. //窗口不可以移动
  439. UINT CMainFrame::OnNcHitTest(CPoint point) 
  440. {
  441. UINT hitTest = CFrameWnd::OnNcHitTest( point );
  442. return hitTest == HTCAPTION ? HTCLIENT : hitTest;
  443. }
  444. //数据包的解析
  445. int CMainFrame::OnPackageMessage( WPARAM wParam , LPARAM lParam )
  446. {
  447. CDataPackage * package = ( CDataPackage * )wParam;
  448. if( ! package )
  449. {   //设置提示信息为无效
  450. this->canTip = false;
  451.         //清除列表
  452. this->dlgBar.m_olist.DeleteAllItems( );
  453. this->dlgBar.m_clist.DeleteAllItems( );
  454. this->dlgBar.m_rlist.DeleteAllItems( );
  455.         //清除窗口
  456. for( int i = theApp.GetClient( ).GetVideo( ) ? 1 : 0 ; i < VIDEO_WND_NUMBER; i ++ )
  457. {
  458. this->videoDlg[ i ].SetWindowText( "" );
  459. ::SetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA , 0 );
  460. this->videoDlg[ i ].Invalidate( );
  461. }//自动连接服务器
  462. CLoginDlg dlg( true );
  463. if( dlg.DoModal( ) != IDOK )
  464. this->PostMessage( WM_CLOSE );
  465. else
  466. { //发送视频头信息
  467. theApp.GetClient( ).SendVideoHeader( );
  468. //请求在线用户状态
  469. theApp.GetClient( ).SendOnlineUserREQ( );
  470. }
  471. return 0;
  472. }
  473. switch( package->Tag )
  474. {//在线用户状态,包括登录、离线、创建会议、加入会议、退出会议
  475. case POnlineUserRESTAG : this->OnlineUser( package ); break;
  476.     //加入会议请求
  477. case PJoinDataNodeREQTAG : return  this->OnJoinDataNodeREQ( package ); 
  478.     //加入会议回复
  479. case PJoinDataNodeRESTAG : return this->OnJoinDataNodeRES( package ); 
  480.     //邀请用户请求
  481. case PInviteUserREQTAG : return ( int )this->OnInviteUserREQ( package );
  482.     //邀请用户回复
  483. case PInviteUserRESTAG : this->OnInviteUserRES( package ); break;
  484.     //申请发言
  485. case PSendAudioRESTAG : return this->OnSendAudioRES( package ); 
  486.     //视频信息
  487. case PVideoDataTAG : return this->OnVideoData( package ); 
  488.     //发送音频请求
  489. case PSendAudioREQTAG : return this->OnSendAudioREQ( package );
  490. //主持人点名发言
  491. case PRecvAudioREQTAG : CTipDialog::ShowTip( "主持人点名了你发言,你可以发言了" ); break;
  492. //主持人点名发言回复
  493. case PRecvAudioRESTAG :
  494. {
  495. PRecvAudioRES * res = ( PRecvAudioRES * )package;
  496. if( ! res->success )
  497. { //查找用户
  498. LVFINDINFO info;
  499. memset( &info , 0 , sizeof( info ) );
  500. info.flags = LVFI_PARAM;
  501. info.lParam = res->user_id;
  502. int index = this->dlgBar.m_rlist.FindItem( &info );
  503. if( index >= 0 )
  504. CTipDialog::ShowTip( "点名" + this->dlgBar.m_rlist.GetItemText( index , 0 ) + " 发言失败n可能对方没有声卡" );
  505. }
  506. }break;
  507.     //模块信息
  508. case PModulePackageTAG : 
  509. {
  510. PModulePackage * m = ( PModulePackage * )package;
  511. this->GetView( )->SetModulePackage( m->module , m->module_buffer , m->module_size );
  512. }
  513. break;
  514. //会议同步命令包
  515. case PSynCommandTAG : 
  516. this->btmdlg.PostMessage( WM_FULLWND , ( ( PSynCommand * )package )->syncommand , ( ( PSynCommand * )package )->full_screen );
  517. break;
  518. //广播信息
  519. case PBroadcastREQTAG :
  520. {
  521. PBroadcastREQ * req = ( PBroadcastREQ * )package;
  522. //查找用户
  523. LVFINDINFO info;
  524. memset( &info , 0 , sizeof( info ) );
  525. info.flags = LVFI_PARAM;
  526. info.lParam = req->broadcast_user_id;
  527. int index = this->dlgBar.m_olist.FindItem( &info );
  528. if( index >= 0 )
  529. {   
  530. HWND hWnd = NULL;
  531. if( req->header && req->header_size )
  532. {   //创建视频广播窗口
  533. CShowBroadcastDialog * dlg = new CShowBroadcastDialog( );
  534. dlg->Create( this );
  535. hWnd = dlg->GetSafeHwnd( );
  536. dlg->SetWindowText( "广播者: " + this->dlgBar.m_olist.GetItemText( index , 0 ) + " (按 Esc 退出广播)");
  537.                 }//提示    
  538. CTipDialog::ShowTip( "用户 " + this->dlgBar.m_olist.GetItemText( index , 0 ) + " 给你发送广播消息" );
  539. return ( int )hWnd;
  540. }
  541. return NULL;
  542. }
  543. break;
  544.     //广播回复
  545. case PBroadcastRESTAG :
  546.         //如果目前还在广播中
  547. if( theApp.GetClient( ).IsBroadcast( ) )
  548. {
  549. PBroadcastRES * res = ( PBroadcastRES * )package;
  550. //查找用户
  551. LVFINDINFO info;
  552. memset( &info , 0 , sizeof( info ) );
  553. info.flags = LVFI_PARAM;
  554. info.lParam = res->user_id;
  555. int index = this->dlgBar.m_olist.FindItem( &info );
  556.             //提示    
  557. if( index >= 0 )
  558. CTipDialog::ShowTip( "发送广播给用户 " + this->dlgBar.m_olist.GetItemText( index , 0 ) + ( res->success ? " 成功" : " 失败可能原因是n1、对方已经在别的广播中n2、对方关闭了你的广播" ) );
  559. }
  560. break;
  561. }
  562. return 0;
  563. }
  564. //在线用户状态
  565. void CMainFrame::OnlineUser( void * package )
  566. {
  567. POnlineUserRES * res = ( POnlineUserRES * )package;
  568. if( ! this->dlgBar.GetSafeHwnd( ) ) return;
  569. //查找用户
  570. LVFINDINFO info;
  571. memset( &info , 0 , sizeof( info ) );
  572. info.flags = LVFI_PARAM;
  573. info.lParam = res->user_id;
  574. int index = -1;
  575.     //用户名为空,表示该用户退出系统
  576. if( res->user_name.empty( ) )
  577. {   //在线用户
  578. if( ( index = this->dlgBar.m_olist.FindItem( &info ) ) >= 0 )
  579. {   //提示退出系统
  580. CTipDialog::ShowTip( "用户 " + this->dlgBar.m_olist.GetItemText( index , 0 ) + " 下线了" );
  581. this->dlgBar.m_olist.DeleteItem( index );
  582. }//会议列表
  583. if( ( index = this->dlgBar.m_clist.FindItem( &info ) ) >= 0 )
  584. this->dlgBar.m_clist.DeleteItem( index );
  585.         //会议室列表
  586. if( ( index = this->dlgBar.m_rlist.FindItem( &info ) ) >= 0 )
  587. this->dlgBar.m_rlist.DeleteItem( index );
  588. }//用户名不空,表明在线
  589. else
  590. {   //在线用户列表
  591. if( ( index = this->dlgBar.m_olist.FindItem( &info ) ) < 0 )
  592. {    //用户上线
  593. if( res->user_id != theApp.GetClient( ).GetUserID( ) && this->canTip )
  594.                 //提示上线
  595. CTipDialog::ShowTip( "用户 " + ( CString )res->user_name.c_str( ) + " 上线了" );
  596.             //增加该用户
  597. index = this->dlgBar.m_olist.InsertItem( 0 , res->user_name.c_str( ) );
  598. //用户id
  599.     this->dlgBar.m_olist.SetItemData( index , res->user_id );
  600. }//用户状态
  601. this->dlgBar.m_olist.SetItemText( index , 1 , res->data_name.empty( ) ? "空闲" : "开会" );
  602. //如果会议名为空
  603. if( res->data_name.empty( ) )
  604. { //会议列表,退出会议
  605. if( res->isCharement && ( index = this->dlgBar.m_clist.FindItem( &info ) ) >= 0 )
  606. { //如果是主持人退出了会议,那么发送退出会议命令包 
  607. if( ! theApp.GetClient( ).GetConferenceName( ).empty( ) && this->dlgBar.m_clist.GetItemText( index , 0 ) == theApp.GetClient( ).GetConferenceName( ).c_str( ) )
  608. { //发送退出会议
  609. theApp.GetClient( ).SendExitDataNode( );
  610. //清除所有会议成员
  611. this->dlgBar.m_rlist.DeleteAllItems( );
  612.                     //还原窗口状态
  613. for( int i = theApp.GetClient( ).GetVideo( ) ? 1 : 0 ; i < VIDEO_WND_NUMBER ; i ++ )
  614. {
  615. ::SetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA , 0 );
  616. this->videoDlg[ i ].SetWindowText( "" );
  617. this->videoDlg[ i ].Invalidate( );
  618. }//寻找会议同步的全屏窗口
  619. try
  620. {
  621. CDialog * dlg = ( CDialog * )CWnd::FindWindow( "#32770" , "全屏窗口" );
  622. if( ::IsWindow( dlg->GetSafeHwnd( ) ) )
  623. dlg->EndDialog( IDOK );
  624. }
  625. catch( ... )
  626. {
  627. }//提示信息
  628. CTipDialog::ShowTip( "主持人退出了会议,会议结束" );
  629. }//从会议列表中删除该会议
  630. this->dlgBar.m_clist.DeleteItem( index );
  631. }//会议室列表
  632. if( ( index = this->dlgBar.m_rlist.FindItem( &info ) ) >= 0 )
  633. {
  634. CString text = this->dlgBar.m_rlist.GetItemText( index , 0 );
  635. this->dlgBar.m_rlist.DeleteItem( index );
  636. CTipDialog::ShowTip( "用户 " + text + "退出了会议" );
  637. }
  638. }//否则
  639. else
  640. {   //有人加入了我的会议
  641. if( ! theApp.GetClient( ).GetConferenceName( ).empty( ) && res->data_name == theApp.GetClient( ).GetConferenceName(  ) )
  642. {   //会议室中没有该用户
  643. if( ( index = this->dlgBar.m_rlist.FindItem( &info ) ) < 0 )
  644. { //增加该用户 
  645. index  = this->dlgBar.m_rlist.InsertItem( 0 , res->user_name.c_str( ) );
  646.                     //提示加入了会议
  647. if( res->user_id != theApp.GetClient( ).GetUserID( ) && this->canTip )
  648. CTipDialog::ShowTip( "用户 " + ( CString )res->user_name.c_str( ) + "加入了会议" );
  649. }//停止发言 
  650. if( res->user_id == theApp.GetClient( ).GetUserID( ) && ! res->isSpeeking && this->dlgBar.m_rlist.GetItemText( index , 1 ) == "是" )
  651. CTipDialog::ShowTip( "主持人停止了你发言" );
  652. //设定名称
  653. this->dlgBar.m_rlist.SetItemText( index , 1 , ( res->isCharement || res->isSpeeking ) ? "是" : "否" );
  654. //设定id
  655. this->dlgBar.m_rlist.SetItemData( index , res->user_id );
  656. }
  657. memset( &info , 0 , sizeof( info ) );
  658. info.flags = LVFI_STRING;
  659. info.psz = res->data_name.c_str( );
  660.             //如果是新增会议,那么在会议列表中添加信息
  661. if( res->isCharement && this->dlgBar.m_clist.FindItem( &info ) < 0 )
  662. {
  663. index = this->dlgBar.m_clist.InsertItem( 0 , res->data_name.c_str( ) );
  664. this->dlgBar.m_clist.SetItemText( index , 1 , res->user_name.c_str( ) );
  665. this->dlgBar.m_clist.SetItemData( index , res->user_id );
  666.                 //如果是我创建会议的,那么最后一个视频窗口不可以显示图像
  667. if( res->user_id == theApp.GetClient( ).GetUserID( ) )
  668. ::SetWindowLong( this->videoDlg[ VIDEO_WND_NUMBER - 1 ].GetSafeHwnd( ) , GWL_USERDATA , true );
  669.                 //否则如果我是空闲的
  670. else if( theApp.GetClient( ).GetConferenceName( ).empty( ) && this->canTip )
  671. CTipDialog::ShowTip( "会议" + ( CString )res->data_name.c_str( ) + "刚刚创建" );
  672. }
  673. }
  674. }//只有我在会议中才可以
  675. if( ! theApp.GetClient( ).GetConferenceName( ).empty( ) )
  676. {   //如果停止发言
  677. if( ! res->isSpeeking )
  678. {
  679. PVideoData vd;
  680. vd.user_id = res->user_id;
  681. vd.video = "停止发言";
  682. vd.size = strlen( vd.video );
  683. vd.type = PVideoData::VIDEO_DATA;
  684. //停止发言
  685. this->OnVideoData( &vd );
  686. }//通知会议成员发生了改变
  687. if( this->dlgBar.m_tab.GetCurSel( ) == 2 )
  688. this->dlgBar.OnItemchangedRecipientList( NULL , NULL );
  689. }
  690. }
  691. //加入会议请求
  692. bool CMainFrame::OnJoinDataNodeREQ( void * package )
  693. {
  694. PJoinDataNodeREQ * req = ( PJoinDataNodeREQ * )package;
  695. this->ShowWindow( SW_SHOW );
  696. this->ShowWindow( SW_SHOWMAXIMIZED );
  697. this->SetForegroundWindow( );
  698. CString text;
  699. text.Format( "用户 %s 请求加入会议nn你是否同意他加入你的会议?" , req->user_name.c_str( ) );
  700. return MessageBox( text , "视频会议" , MB_ICONINFORMATION | MB_YESNO ) == IDYES;
  701. }
  702. //加入会议回复
  703. bool CMainFrame::OnJoinDataNodeRES( void * package )
  704. {
  705. PJoinDataNodeRES * res = ( PJoinDataNodeRES * )package;
  706.     //查找等待窗口
  707. CDialog * dlg = ( CDialog * )CWnd::FindWindow( "#32770" , "等待主持人的回复,请等待..." );
  708. if( dlg )
  709. {
  710. dlg->EndDialog( IDOK );
  711. if( ! res->success )
  712. MessageBox( "主持人拒绝你加入他的会议,请在会议列表中另选会议" , "视频会议" , MB_ICONINFORMATION | MB_OK );
  713. else
  714. {
  715. this->canTip = false;
  716.             //一分钟之后才会有提示窗口
  717. this->SetTimer( 3 , 60000 , NULL );
  718. return true;
  719. }
  720. }
  721. return false;
  722. }
  723. //邀请用户加入会议请求
  724. const char * CMainFrame::OnInviteUserREQ( void * package )
  725. {
  726. PInviteUserREQ * req = ( PInviteUserREQ * )package;
  727.     //找出主持人的信息
  728. LVFINDINFO info; 
  729. memset( &info , 0 , sizeof( info ) );
  730. info.flags = LVFI_PARAM;
  731.     
  732. info.lParam = req->charement_id;
  733. int index = this->dlgBar.m_clist.FindItem( &info );
  734.     //邀请加入
  735. if( index >= 0 )
  736. {
  737. static CString s;
  738. s = this->dlgBar.m_clist.GetItemText( index , 0 );
  739. if( req->prompt )
  740. return MessageBox( "用户  " + this->dlgBar.m_olist.GetItemText( index , 0 ) + "  邀请你加入他的会议n你是否要加入?" , "视频会议" , MB_ICONINFORMATION | MB_OKCANCEL ) == IDOK ? ( const char * )s : "";
  741. else
  742. {
  743. CTipDialog::ShowTip( "用户  " + this->dlgBar.m_olist.GetItemText( index , 0 ) + "  邀请你加入他的会议n你加入了他的会议" );
  744. this->canTip = false;
  745.             //一分钟之后才会有提示窗口
  746. this->SetTimer( 3 , 60000 , NULL );
  747. return ( const char * )s;
  748. }
  749. }
  750. return "";
  751. }
  752. //邀请用户加入会议回复
  753. void CMainFrame::OnInviteUserRES( void * package )
  754. {
  755. PInviteUserRES * res = ( PInviteUserRES * )package;
  756. if( ! res->ireturn )
  757. { //找出该用户信息
  758. LVFINDINFO info; 
  759. memset( &info , 0 , sizeof( info ) );
  760. info.flags = LVFI_PARAM;
  761. info.lParam = res->user_id;
  762. int index = this->dlgBar.m_olist.FindItem( &info );
  763. if( index >= 0 )
  764. CTipDialog::ShowTip( "邀请用户" + this->dlgBar.m_olist.GetItemText( index , 0 ) + "失败,对方正在接收广播或者已经在别的会议中" );
  765. }
  766. }
  767. //申请发言
  768. int CMainFrame::OnSendAudioREQ( void * package )
  769. {
  770. PSendAudioREQ * req = ( PSendAudioREQ * )package;
  771.     
  772. LVFINDINFO info; 
  773. memset( &info , 0 , sizeof( info ) );
  774. info.flags = LVFI_PARAM;
  775. info.lParam = req->user_id;
  776. int index = this->dlgBar.m_rlist.FindItem( &info );
  777. if( index >= 0 )
  778. {  
  779. CString name = this->dlgBar.m_rlist.GetItemText( index , 0 );
  780. //先判断视频窗口是否够用且该用户是否已经获得了发言权
  781. int id = 0;
  782. bool ret = false;
  783. for( int i = 0 ; i < VIDEO_WND_NUMBER ; i ++ )
  784. {
  785. id = ::GetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA );
  786.             //该用户已经获得了发言权 
  787. if( id == req->user_id ) 
  788. return -1;
  789. else if( id == 0 )
  790. ret = true;
  791. }
  792. if( ! ret )
  793. {
  794. CTipDialog::ShowTip( "会议成员" + name  + "申请发言,但是因为视频窗口不够显示而失败nn想要让该用户发言,请先停止某个正在发言的用户" );
  795. return 0;
  796. }
  797. return MessageBox( "用户 " + name + " 申请发言,你是否同意其发言?" , "视频会议" , MB_ICONQUESTION | MB_YESNO ) == IDYES;
  798. }
  799. return 0;
  800. }
  801. //申请发言回复
  802. bool CMainFrame::OnSendAudioRES( void * package )
  803. {
  804. PSendAudioRES * res = ( PSendAudioRES * )package;
  805. //查找等待窗口
  806. CDialog * dlg = ( CDialog * )CWnd::FindWindow( "#32770" , "等待主持人的回复,请等待..." );
  807. if( ::IsWindow( dlg->GetSafeHwnd( ) ) )
  808. {
  809. dlg->EndDialog( IDOK );
  810. if( ! res->success )
  811. CTipDialog::ShowTip( "主持人拒绝你发言" );
  812. else
  813. CTipDialog::ShowTip( "主持人同意你发言,你可以发言了" );
  814. return res->success;
  815. }
  816. return false;
  817. }
  818. //视频窗口
  819. int CMainFrame::OnVideoData( void * package )
  820. {
  821. if( ! ::IsWindow( this->dlgBar.GetSafeHwnd( ) ) )  return NULL;
  822. PVideoData * vd = ( PVideoData * )package;
  823.     //查找窗口名称
  824. CString wnd_name;
  825. //查找用户
  826. LVFINDINFO info;
  827. memset( &info , 0 , sizeof( info ) );
  828. info.flags = LVFI_PARAM;
  829. info.lParam = vd->user_id;
  830.     //从在线用户查找用户名
  831. int index = this->dlgBar.m_olist.FindItem( &info );
  832. if( index >= 0 )
  833. wnd_name = this->dlgBar.m_olist.GetItemText( index , 0 );
  834. //视频信息
  835. if( vd->video )
  836. {   //给窗口句柄显示图像
  837. if( vd->type == PVideoData::VIDEO_HEADER )
  838. {
  839. CWnd * pWnd = NULL;
  840. for( int i = 0; i < VIDEO_WND_NUMBER ; i ++ )
  841. if( ! ::GetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA ) )
  842. {
  843. pWnd = &this->videoDlg[ i ]; break;
  844. }
  845. if( pWnd )
  846. {
  847. ::SetWindowLong( pWnd->GetSafeHwnd( ) , GWL_USERDATA , vd->user_id );
  848. pWnd->SetWindowText( wnd_name );
  849. return ( int )pWnd->GetSafeHwnd( );
  850. }
  851. CTipDialog::ShowTip( "没有足够的视频窗口供显示用户"+ wnd_name +"的视频,请先停止掉其他用户的视频数据再试" );
  852. return NULL;
  853. }//清除窗口句柄
  854. else if( vd->type == PVideoData::VIDEO_DATA )
  855. {
  856. for( int i = 0 ; i < VIDEO_WND_NUMBER ; i ++ )
  857. if( ::GetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA ) == vd->user_id )
  858. {
  859. this->videoDlg[ i ].SetWindowText( "" );
  860. ::SetWindowLong( this->videoDlg[ i ].GetSafeHwnd( ) , GWL_USERDATA , 0 );
  861. this->videoDlg[ i ].Invalidate( );
  862. break;
  863. }
  864. }
  865. }
  866. else
  867. CTipDialog::ShowTip( wnd_name + "没有视频数据" );
  868.     return NULL;
  869. }
  870. // 窗口最小化时使用托盘
  871. void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam) 
  872. {
  873. CFrameWnd::OnSysCommand( nID, lParam );
  874. NOTIFYICONDATA tnd;
  875. tnd.cbSize = sizeof( NOTIFYICONDATA );
  876.     tnd.hWnd=this->m_hWnd;
  877. tnd.uID = IDR_MAINFRAME;
  878. tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
  879. tnd.uCallbackMessage = WM_TRACER_MESSAGE;
  880.     tnd.hIcon = LoadIcon( AfxGetInstanceHandle() , MAKEINTRESOURCE( IDR_MAINFRAME ) );
  881. strcpy( tnd.szTip , "视频会议客户端" );
  882. //最小化,向任务栏添加图标
  883. if( nID == SC_MINIMIZE )
  884. {
  885. this->ShowWindow( SW_HIDE );
  886. Shell_NotifyIcon( NIM_ADD , &tnd );
  887. ::SetProp( this->GetSafeHwnd( ) , "__hide_window__" , ( void * )1 );
  888. }
  889.     //最大化
  890. else
  891. {
  892. ::SetProp( this->GetSafeHwnd( ) , "__hide_window__" , 0 );
  893. Shell_NotifyIcon( NIM_DELETE , &tnd );
  894. }
  895. }
  896. //托盘处理
  897. void CMainFrame::OnTrace( WPARAM wParam , LPARAM lParam )
  898. {
  899. if( lParam == WM_LBUTTONDOWN )
  900. {
  901. if( ::GetProp( this->GetSafeHwnd( ) , "__hide_window__" ) )
  902. {
  903. ::SetProp( this->GetSafeHwnd( ) , "__hide_window__" , 0 );
  904. this->ShowWindow( SW_SHOW );
  905. this->ShowWindow( SW_SHOWMAXIMIZED );
  906. this->SetForegroundWindow( );
  907. }
  908. else
  909. this->SendMessage( WM_SYSCOMMAND , SC_MINIMIZE );
  910. }
  911. }
  912. void CMainFrame::OnAddUser( WPARAM wParam , LPARAM lParam )
  913. {
  914. for( int i = 0; i < this->dlgBar.m_rlist.GetItemCount( ) ; i ++ )
  915. AddUser( ( CWnd * )wParam , ( char * )( const char * )this->dlgBar.m_rlist.GetItemText( i , 0 ) , this->dlgBar.m_rlist.GetItemData( i ) );
  916. }
  917. //关闭窗口
  918. void CMainFrame::OnDestroy() 
  919. {
  920. NOTIFYICONDATA tnd;
  921. tnd.cbSize = sizeof( NOTIFYICONDATA );
  922.     tnd.hWnd=this->m_hWnd;
  923. tnd.uID = IDR_MAINFRAME;
  924. tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
  925. tnd.uCallbackMessage = WM_TRACER_MESSAGE;
  926.     tnd.hIcon = LoadIcon( AfxGetInstanceHandle() , MAKEINTRESOURCE( IDR_MAINFRAME ) );
  927. strcpy( tnd.szTip , "视频会议客户端" );
  928. Shell_NotifyIcon( NIM_DELETE , &tnd );
  929. if( ! theApp.GetClient( ).GetConferenceName().empty( ) )
  930.         //发送退出会议
  931. theApp.GetClient( ).SendExitDataNode( );
  932. CFrameWnd::OnDestroy( );
  933. }
  934. //定时发包
  935. void CMainFrame::OnTimer(UINT nIDEvent) 
  936. {
  937. CFrameWnd::OnTimer(nIDEvent);
  938.     //每隔2分钟发送一次测试网络连接的数据包
  939. if( nIDEvent == 1 )
  940. {
  941. // theApp.GetClient( ).SendTestConnect( );
  942. }
  943. else if( nIDEvent == 2 )
  944. {
  945. static time_t i = 0;
  946. CTimeSpan tm( i ++ );
  947. CString text;
  948. text.Format( "视频会议系统 - 用户名: %s 会议名: %s 时间: %s" , theApp.GetClient( ).GetUserName( ) , theApp.GetClient( ).GetConferenceName( ).c_str( ) , theApp.GetClient( ).GetConferenceName( ).empty( ) ? "" : tm.Format( "%H:%M:%S") );
  949. if( theApp.GetClient( ).GetConferenceName( ).empty( ) )
  950. {
  951. i = 0; this->KillTimer( 2 );
  952. }
  953. this->SetWindowText( text );
  954. }
  955. else if( nIDEvent == 3 )
  956. {
  957. this->KillTimer( 3 );
  958. this->canTip = true;
  959. }
  960. }
  961. // 关闭窗口
  962. void CMainFrame::OnClose() 
  963. {
  964. if( theApp.GetClient( ).GetTCP( false ).IsConnected( ) && MessageBox( "你确定要退出视频会议系统吗?" , "视频会议客户端" , MB_ICONINFORMATION | MB_YESNO ) == IDNO )
  965. return;
  966. CTipDialog::canShow = false;
  967. CSizingControlBar::GlobalSaveState( this , "video_window" );
  968. CFrameWnd::OnClose( );
  969. }