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

IP电话/视频会议

开发平台:

Visual C++

  1. // MainView.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Share.h"
  5. #include "MainView.h"
  6. #include "Buffer.h"
  7. #include "MainFrame.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. #pragma comment( lib , "vfw32.lib" )
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CMainView
  16. CMainView::CMainView( CMainFrame * mainFrame )
  17. {
  18. this->mainFrame = mainFrame;
  19. this->m_bCapture = false;
  20. this->m_bControl = false;
  21. this->canControl = true;
  22. this->hDraw = ::DrawDibOpen( );
  23. this->imglst.Create( IDB_ARROW_BITMAP , 11 , 1 , RGB( 255 , 0 , 0 ) );
  24. }
  25. CMainView::~CMainView()
  26. {
  27. this->StopCapture( );
  28. if( this->hDraw )
  29. {
  30. ::DrawDibClose( this->hDraw ); 
  31. this->hDraw = NULL;
  32. }
  33. }
  34. BEGIN_MESSAGE_MAP(CMainView, CScrollView)
  35. //{{AFX_MSG_MAP(CMainView)
  36. ON_WM_PAINT()
  37. ON_WM_SIZE()
  38. ON_WM_MOUSEACTIVATE()
  39. //}}AFX_MSG_MAP
  40. END_MESSAGE_MAP()
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CMainView drawing
  43. BOOL CMainView::PreCreateWindow(CREATESTRUCT& cs) 
  44. {
  45. cs.lpszClass = ::AfxRegisterWndClass( 0 , AfxGetApp( )->LoadStandardCursor( IDC_ARROW ) , ::CreateSolidBrush( ::GetSysColor( COLOR_APPWORKSPACE ) ) , NULL );
  46. return CScrollView::PreCreateWindow(cs);
  47. }
  48. void CMainView::OnSize(UINT nType, int cx, int cy) 
  49. {
  50. CScrollView::OnSize(nType, cx, cy);
  51. if( ! this->decode.IsInitDecode( ) )
  52. this->SetScrollSizes( MM_TEXT , CSize( cx , cy ) );
  53. }
  54. bool CMainView::StartCapture( void )
  55. {
  56. if( ! this->m_bCapture && ! this->decode.IsInitDecode( ) )
  57. {
  58. this->m_bCapture = true;
  59. this->m_bControl = false;
  60. this->canControl = true;
  61. ::AfxBeginThread( CMainView::OnCapture , this );
  62. return true;
  63. }
  64. return false;
  65. }
  66. void CMainView::StopCapture( void )
  67. {
  68. this->m_bCapture = false;
  69. if( ::IsWindow( this->GetSafeHwnd( ) ) )
  70. {
  71. ::Sleep( 100 );
  72. this->Invalidate( );
  73. }
  74. }
  75. UINT CMainView::OnCapture( void * pContext )
  76. {
  77. CMainView * pThis = ( CMainView * )pContext;
  78.     //取得桌面dc
  79. CWindowDC dc( CWnd::GetDesktopWindow( ) );
  80.     //创建内存dc
  81. CDC memDC;
  82.     
  83. memDC.CreateCompatibleDC( &dc );
  84. CBitmap bitmap , * oldBitmap;
  85. CRect rc;
  86. dc.GetClipBox( &rc );
  87.     //创建内存位图
  88. bitmap.CreateCompatibleBitmap( &dc , rc.Width( ) , rc.Height( ) );
  89. BITMAP bmp;
  90. bitmap.GetBitmap( &bmp );
  91. //设定位图无关信息
  92. BITMAPINFOHEADER h = 
  93. {
  94. sizeof( h ) , rc.Width( ) , rc.Height( ) , 1 , bmp.bmBitsPixel * bmp.bmPlanes , BI_RGB , ( 31 + h.biWidth * h.biHeight * h.biBitCount ) / 8 , 0 , 0 , 0 , 0 
  95. };//压缩数据
  96. CVideoCodec encode;
  97. BITMAPINFOHEADER * hdr = encode.InitEncode( h.biWidth , h.biHeight , h.biBitCount , "MP42" );
  98. if( ! hdr )
  99. {
  100. pThis->MessageBox( "视频压缩失败导致远程桌面共享失败" , "远程桌面共享" , MB_ICONSTOP | MB_OK );
  101. return 0;
  102. }
  103. CBuffer buffer;
  104.     //设定内存大小
  105. buffer.Resize( sizeof( int ) + sizeof( BITMAPINFOHEADER ) + h.biSizeImage );
  106. char * now = buffer.GetBuffer( );
  107.     //视频标志 
  108. *( int * )now = VIDEO; now += sizeof( int );
  109.     //位图头信息
  110. memcpy( now , hdr , sizeof( BITMAPINFOHEADER ) ); now += sizeof( BITMAPINFOHEADER );
  111. void * buf;
  112. int size;
  113. try
  114. {
  115. while( pThis->m_bCapture && ! pThis->decode.IsInitDecode( ) )
  116. {
  117. oldBitmap = memDC.SelectObject( &bitmap );
  118. //拷贝桌面
  119. memDC.BitBlt( 0 , 0 , rc.Width( ) , rc.Height( ) , &dc , 0 , 0 , SRCCOPY );
  120. if( pThis->canControl )
  121. { //显示鼠标
  122. CPoint pt;
  123. ::GetCursorPos( &pt );
  124. pThis->imglst.Draw( &memDC , 0 , pt , ILD_TRANSPARENT );
  125. }
  126. //取出位图
  127. ::GetDIBits( memDC.GetSafeHdc( ) , bitmap , 0 , rc.Height( ) , now , ( BITMAPINFO * )&h , DIB_RGB_COLORS );
  128. //压缩数据
  129. buf = encode.Encode( now , &size );
  130. //保存位图
  131. if( buf && size )
  132. {   //压缩后的数据
  133. memcpy( now + sizeof( int ) , buf , size );
  134. //压缩后的大小
  135. *( int * )now = size; 
  136. //通知外部程序 数据组合格式是 用户自动自定义的参数、本框架、缓冲区(位图头信息 + 压缩数据大小 + 压缩数据 )、缓冲区大小
  137. if( ! pThis->mainFrame->OnShare( pThis->mainFrame->pContext , pThis->mainFrame , buffer.GetBuffer( ) , sizeof( int ) + sizeof( BITMAPINFOHEADER ) + sizeof( int ) + size ) )
  138. break;
  139. }
  140. memDC.SelectObject( oldBitmap );
  141. ::Sleep( 200 );
  142. }//停止显示
  143. pThis->mainFrame->OnShare( pThis->mainFrame->pContext , pThis->mainFrame , buffer.GetBuffer( ) , sizeof( int ) );
  144. pThis->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_START_SHARE , TRUE );
  145. pThis->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_STOP_SHARE , FALSE );
  146. pThis->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_CLIENT_FULLSCREEN , FALSE );
  147. }
  148. catch( ... )
  149. {
  150. }
  151. return 0;
  152. }
  153. bool CMainView::DrawBitmap(  char * buffer , int size )
  154. {
  155. if( buffer && size > sizeof( BITMAPINFOHEADER ) && ::IsWindow( this->GetSafeHwnd( ) ) )
  156. {   //减去视频标志
  157. buffer += sizeof( int );
  158. try
  159. {
  160. CClientDC dc(this );
  161. //取出视频头 
  162. BITMAPINFOHEADER * h = ( BITMAPINFOHEADER * )buffer; buffer += sizeof( BITMAPINFOHEADER );
  163.             //解压数据
  164. if( ! this->decode.IsInitDecode( ) )
  165. {
  166. this->decode.InitDecode( h );
  167.                 //设定窗口的工作区大小
  168. this->SetScrollSizes( MM_TEXT , CSize( h->biWidth , h->biHeight ) );
  169. //屏蔽掉共享按钮,和使能
  170. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_START_SHARE , FALSE );
  171. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_STOP_SHARE , FALSE );
  172. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_CONTROL , TRUE );
  173. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_FULLSCREEN , TRUE );
  174. }
  175. h->biCompression = BI_RGB;
  176. ::DrawDibRealize( this->hDraw , dc.GetSafeHdc( ) , TRUE );
  177. //取得开始显示的点
  178. CPoint pt = this->GetScrollPosition( );
  179.             //解压  
  180. buffer = ( char * )this->decode.Decode( buffer + sizeof( int ) , *( int * )buffer );
  181. if( buffer )
  182. { //显示
  183. ::DrawDibDraw( this->hDraw , 
  184. dc.GetSafeHdc( ) ,
  185. 0 , 
  186. 0 ,
  187. h->biWidth - pt.x ,
  188. h->biHeight - pt.y ,
  189. h ,
  190. buffer ,
  191. pt.x , 
  192. pt.y , 
  193. h->biWidth - pt.x ,
  194. h->biHeight - pt.y ,
  195. DDF_BACKGROUNDPAL );
  196. }
  197. }
  198. catch( ... )
  199. {
  200. return false;
  201. }
  202. return true;
  203. }
  204. try
  205. {  //释放解压器
  206. this->decode.ReleaseDecode( );
  207. //把最大化的窗口去掉
  208. if( ! ( ( CFrameWnd * )this->GetParent( ) )->IsKindOf( RUNTIME_CLASS( CMainFrame ) ) )
  209. this->GetParent( )->SendMessage( WM_CLOSE );
  210. CRect rc;
  211. this->GetClientRect( &rc );
  212. this->SetScrollSizes( MM_TEXT , CSize( rc.Width( ) , rc.Height( ) ) );
  213. this->Invalidate( );
  214. //回复工具栏按钮
  215. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_START_SHARE , TRUE );
  216. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_STOP_SHARE , FALSE );
  217. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_CONTROL , FALSE );
  218. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).CheckButton( ID_CONTROL , FALSE );
  219. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_FULLSCREEN , FALSE );
  220. }
  221. catch( ... )
  222. {
  223. }
  224. return false;
  225. }
  226. LRESULT CMainView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  227. { //截获鼠标的单击和右击
  228. if( this->m_bControl && this->decode.IsInitDecode( ) )
  229. {
  230. CBuffer buffer;
  231. buffer.Resize( 4 * sizeof( int ) + this->mainFrame->userName.GetLength( ) + sizeof( char ) );
  232. char * now = buffer.GetBuffer( );
  233. //命令标志
  234. *( int * )now = COMMAND; now += sizeof( int );
  235. //消息标志
  236. *( int * )now = message; now += sizeof( int );
  237. //wParam
  238. *( int * )now = wParam;  now += sizeof( int );
  239. //lParam
  240. *( int * )now = lParam;  
  241. //用户名
  242. strcpy( now + sizeof( int ) , this->mainFrame->userName );
  243. bool canSend = false;
  244. switch( message )
  245. {
  246. case WM_MOUSEMOVE :
  247. case WM_LBUTTONDOWN :
  248. case WM_LBUTTONUP :
  249. case WM_RBUTTONDOWN :
  250. case WM_RBUTTONUP :
  251. case WM_MBUTTONDOWN :
  252. case WM_MBUTTONUP :
  253. {   //变换屏幕坐标
  254. CPoint pt = this->GetScrollPosition( );
  255. *( int * )now = MAKELPARAM ( LOWORD( lParam ) + pt.x , HIWORD( lParam ) + pt.y );
  256. canSend = true;
  257. }
  258. break;
  259. case WM_KEYDOWN :
  260. case WM_KEYUP :
  261. {
  262. canSend = true;
  263. }
  264. break;
  265. }//把消息通知外部程序 
  266. if( canSend )
  267. this->mainFrame->OnShare( this->mainFrame->pContext , this->mainFrame , buffer.GetBuffer( ) , buffer.GetSize( ) );
  268. }
  269. return CScrollView::WindowProc(message, wParam, lParam);
  270. }
  271. void CMainView::DoCommand( char * buffer , int size )
  272. {
  273. buffer += sizeof( int );
  274. UINT message = *( int * )buffer; buffer += sizeof( int );
  275. WPARAM wParam = *( int * )buffer; buffer += sizeof( int );
  276. LPARAM lParam = *( int * )buffer; buffer += sizeof( int );
  277. if( this->mainFrame->controlName != buffer )
  278. return;
  279. switch( message )
  280. {
  281. case WM_MOUSEMOVE :
  282. ::SetCursorPos( LOWORD( lParam ) , HIWORD( lParam ) );
  283. break;
  284. case WM_LBUTTONDOWN :
  285. ::SetCursorPos( LOWORD( lParam ) , HIWORD( lParam ) );
  286. ::mouse_event( MOUSEEVENTF_LEFTDOWN , 0 , 0 , 0 , 0 );
  287. break;
  288. case WM_LBUTTONUP :
  289. ::SetCursorPos( LOWORD( lParam ) , HIWORD( lParam ) );
  290. ::mouse_event( MOUSEEVENTF_LEFTUP , 0 , 0 , 0 , 0 );
  291. break;
  292. case WM_RBUTTONDOWN :
  293. ::SetCursorPos( LOWORD( lParam ) , HIWORD( lParam ) );
  294. ::mouse_event( MOUSEEVENTF_RIGHTDOWN , 0 , 0 , 0 , 0 );
  295. break;
  296. case WM_RBUTTONUP :
  297. ::SetCursorPos( LOWORD( lParam ) , HIWORD( lParam ) );
  298. ::mouse_event( MOUSEEVENTF_RIGHTUP , 0 , 0 , 0 , 0 );
  299. break;
  300. case WM_MBUTTONDOWN :
  301. ::SetCursorPos( LOWORD( lParam ) , HIWORD( lParam ) );
  302. ::mouse_event( MOUSEEVENTF_MIDDLEDOWN , 0 , 0 , 0 , 0 );
  303. break;
  304. case WM_MBUTTONUP :
  305. ::SetCursorPos( LOWORD( lParam ) , HIWORD( lParam ) );
  306. ::mouse_event( MOUSEEVENTF_MIDDLEUP , 0 , 0 , 0 , 0 );
  307. break;
  308. case WM_KEYDOWN :
  309. ::keybd_event( wParam , 0 , 0 , 0 );
  310. break;
  311. case WM_KEYUP :
  312. ::keybd_event( wParam , 0 , KEYEVENTF_KEYUP , 0 );
  313. break;
  314. }
  315. }
  316. void CMainView::DoControl( char * buffer , int size )
  317. {   
  318. buffer += sizeof( int );
  319. int type = *( int * )buffer; buffer += sizeof( int );
  320. CString userName = buffer;
  321. CBuffer b;
  322. b.Resize( 2 * sizeof( int ) + userName.GetLength( ) + sizeof( char ) );
  323. char * now = b.GetBuffer( );
  324.     //控制信息
  325. *( int * )now = CONTROL; now += sizeof( int );
  326.     //用户名
  327. strcpy( now + sizeof( int ) , userName );
  328. switch( type )
  329. {
  330. case 1 : //请求控制权
  331.         //如果我正在捕捉图像  
  332. if( this->m_bCapture )
  333. {
  334. *( int * )now = this->canControl && MessageBox( "用户 " + userName + " 请求控制桌面nn你是否允许改用户控制你的桌面" , "程序共享" , MB_ICONQUESTION | MB_YESNO ) == IDYES ? 2 : 3;
  335. this->mainFrame->OnShare( this->mainFrame->pContext , this->mainFrame , b.GetBuffer( ) , b.GetSize( ) );
  336. }
  337. break;
  338. case 2 : //请求控制权回复(接收)
  339. if( this->mainFrame->userName == userName )
  340. {
  341. CWnd * pWnd = CWnd::FindWindow( "#32770" , "程序共享" );
  342.             //发送控制信息
  343. if( pWnd )
  344. {
  345. *( int * )now = 4;
  346. if( this->mainFrame->OnShare( this->mainFrame->pContext , this->mainFrame , b.GetBuffer( ) , b.GetSize( ) ) )
  347. this->m_bControl = true;
  348. pWnd->SendMessage( WM_CLOSE );
  349. MessageBox( "你获得了控制远程桌面的权限" , "程序共享" , MB_ICONINFORMATION | MB_OK );
  350. }
  351. }
  352. break;
  353. case 3 : //请求控制权回复(拒绝)
  354. if( this->mainFrame->userName == userName )
  355. {
  356. this->m_bControl = false;
  357. CWnd * pWnd = CWnd::FindWindow( "#32770" , "程序共享" );
  358.             //发送控制信息
  359. if( pWnd )
  360. {
  361. pWnd->SendMessage( WM_CLOSE );
  362. MessageBox( "对方不允许你控制他的桌面" , "程序共享" , MB_ICONSTOP | MB_OK );
  363. }
  364. }
  365. break;
  366. case 4 : //控制
  367. if( this->m_bCapture )
  368. {
  369. this->canControl = false;
  370.             //保存当前控制的用户名  
  371. this->mainFrame->controlName = userName;
  372. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_CONTROL , TRUE );
  373. }
  374. break;
  375. case 5 : //取消控制
  376. if( this->m_bCapture )
  377. {
  378. this->canControl = true;
  379. MessageBox( this->mainFrame->controlName +  "取消控制你的桌面" , "程序共享" , MB_ICONSTOP | MB_OK );
  380. this->mainFrame->controlName = "";
  381. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).EnableButton( ID_CONTROL , FALSE );
  382. }
  383. else if( this->mainFrame->userName == userName )
  384. {
  385. this->m_bControl = false;
  386. this->mainFrame->controlName = "";
  387. this->mainFrame->GetToolBar( ).GetToolBarCtrl( ).CheckButton( ID_CONTROL , FALSE );
  388. }
  389. break;
  390. }
  391. }
  392. int CMainView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) 
  393. {
  394. CFrameWnd * pWnd = ( CFrameWnd * )this->GetParent( );
  395. if( ! pWnd->IsKindOf( RUNTIME_CLASS( CMainFrame ) ) )
  396. return CWnd::OnMouseActivate( pDesktopWnd , nHitTest , message );
  397. return CScrollView::OnMouseActivate(pDesktopWnd, nHitTest, message);
  398. }