📄 rcaclient.cpp
字号:
// RCAClient.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "resource.h"
typedef enum _ThreadWorkState
{
UNINIT =0,
WAIT_CONNECT,
WAIT_REQUEST,
CONNECTING,
REQUESTING,
} THREAD_WORK_STATE;
typedef struct _ThreadCommun {
HANDLE hExitEvent;
HANDLE hBeginConnectEvent;
HANDLE hBeginRequest;
HWND hwnd;
UINT msg;
} THREAD_COMMUN, *PTHREAD_COMMUN;
HWND g_hWnd;
HINSTANCE g_hInstance;
HIMAGELIST g_hImageList;
SOCKET g_hSocket1 = NULL;
SOCKET g_hSocket2 = NULL;
sockaddr_in g_addr;
sockaddr_in g_addr2;
HANDLE g_hThread1 = NULL;
HANDLE g_hThread2 = NULL;
HANDLE g_hEvent1;
HANDLE g_hEvent2;
HBITMAP g_hRemoteBitmap = NULL;
THREAD_COMMUN g_tc;
THREAD_WORK_STATE g_ThreadState = UNINIT;
RCAGETIMAGEDATA g_gm;
BOOL g_bMustExit = FALSE;
DWORD g_dwServerIP = 0;
u_short g_usPort = 0;
INT g_hWidth;
INT g_hHeight;
// 主窗口的子窗口标识符
#define ID_TOOLBAR 1 // 工具栏窗口
#define WM_THREADWORKSTATE (WM_USER+100)
#define CANNOT_WAIT 0
#define CANNOT_CREATESOCKET 1
#define CANNOT_CONNECT 2
#define CANNOT_REQUEST 3
#define RESPONSE_ERROR 4
#define WORK_SUCCEEDED 5
#define CONNECTED 6
INT WINAPI AddToolbarString( HWND tb, char * string )
{
char tmp[256];
lstrcpy( tmp, string );
tmp[ lstrlen(string) +1 ] = 0;
return (INT)SendMessage( tb, TB_ADDSTRING, 0, (LPARAM)(LPSTR)tmp );
}
/////////////////////////////////////////////////////
///
// 获取远程计算机图象函数, 由 创建的一个工作线程运行
//
DWORD WINAPI ThreadFunc1( PVOID p )
{
DWORD dwret;
RCAREQUESTHEADER rreqh;
RCAGETIMAGEDATA gm;
RECT rect;
PTHREAD_COMMUN ptc = (PTHREAD_COMMUN)p;
HANDLE hEventArray[2] = { NULL, ptc->hExitEvent };
HANDLE hWaitConnectArray[2] = { ptc->hBeginConnectEvent, ptc->hExitEvent };
HANDLE hWaitRequestArray[3] = { ptc->hBeginRequest, ptc->hExitEvent, ptc->hBeginConnectEvent };
InitRCARequestHead( &rreqh, 1, 0, 0X20, sizeof(rreqh) + sizeof(gm) );
rreqh.wMajorVersion = 1;
rreqh.wMinorVersion = 0;
gm.x = 0;
gm.y = 0;
gm.w = 0;
gm.h = 0;
gm.zh = 0;
gm.zw = 0;
gm.iBitCount = 8;
gm.dwFlagEx1 = 50; // 图象质量
gm.dwImageFormat = IMAGE_FORMAT_JPEG;
g_gm.dwImageFormat = IMAGE_FORMAT_JPEG;
g_gm.iBitCount = 8;
g_gm.dwFlagEx1 = 50;
while(1)
{
// 线程进入等待, 准备连接服务器
g_ThreadState = WAIT_CONNECT;
dwret = WaitForMultipleObjects( 2, hWaitConnectArray, FALSE, INFINITE );
g_ThreadState = CONNECTING;
if( dwret == (WAIT_OBJECT_0 +1))
{
return 0;
}
if( dwret == WAIT_FAILED)
{
PostMessage( ptc->hwnd, ptc->msg, CANNOT_WAIT, 0 );
g_ThreadState = UNINIT;
return 0;
}
///////////////////////////////////////////////////////////
if( !CreateEventSelectSocket( &g_hSocket1, &(hEventArray[0]),
FD_CONNECT | FD_WRITE | FD_READ | FD_CLOSE ) )
{
PostMessage( ptc->hwnd, ptc->msg, CANNOT_CREATESOCKET, 0 );
continue;
}
g_addr.sin_addr.S_un.S_addr = g_dwServerIP;
g_addr.sin_family = AF_INET;
g_addr.sin_port = g_usPort;
if( TRUE != RCAConnect_EventSelectIO( g_hSocket1, hEventArray,
(sockaddr*)&g_addr, sizeof(sockaddr) ) )
{
CloseHandle( g_hEvent1 );
closesocket( g_hSocket1 );
PostMessage( ptc->hwnd, ptc->msg, CANNOT_CONNECT, 0 );
continue;
}
PostMessage( ptc->hwnd, ptc->msg, CONNECTED , 0 );
////////////////////////////
// 请求开始
while(1)
{
g_ThreadState = WAIT_REQUEST;
dwret = WaitForMultipleObjects( 3, hWaitRequestArray, FALSE, INFINITE );
g_ThreadState = REQUESTING;
if( dwret != (WAIT_OBJECT_0 ) )
{
if( dwret == (WAIT_OBJECT_0 +1) )
{
break;
} else if( dwret == (WAIT_OBJECT_0 +2 ))
{
break;
} else if( dwret == WAIT_FAILED )
{
PostMessage(ptc->hwnd, ptc->msg, CANNOT_WAIT, 0 );
break;
}
// never run to here
}
GetClientRect( ptc->hwnd, &rect );
gm.zw = rect.right;
gm.zh = rect.bottom;
gm.dwFlagEx1 = g_gm.dwFlagEx1;
gm.dwImageFormat = g_gm.dwImageFormat;
gm.iBitCount = g_gm.iBitCount;
// now dwret==WAIT_OBJECT, start request server
if( TRUE != RCASendRequest_0X20_EventSelectIO( g_hSocket1, hEventArray,
&gm ) )
{
PostMessage(ptc->hwnd, ptc->msg, CANNOT_REQUEST, 0 );
break;
}
HBITMAP bm = RCARecvImageData( g_hSocket1, hEventArray, gm.dwImageFormat );
if( bm == NULL )
{
PostMessage( ptc->hwnd, ptc->msg, CANNOT_REQUEST, 0 );
break;
}
PostMessage( ptc->hwnd, ptc->msg, WORK_SUCCEEDED, (LPARAM)bm );
}
if( g_bMustExit )
break;
else
{
closesocket( g_hSocket1 );
CloseHandle( hEventArray[0] );
}
}
closesocket( g_hSocket1 );
CloseHandle( hEventArray[0] );
return 0;
}
DWORD WINAPI ThreadFunc2( PVOID p )
{
while(1)
{
SuspendThread( GetCurrentThread());
}
return 0;
}
VOID WINAPI OnPaint( HWND hwnd, HDC hdc )
{
if( g_hRemoteBitmap )
{
DIBSECTION ds;
RECT rect;
GetClientRect( hwnd, &rect );
GetObject( g_hRemoteBitmap, sizeof(ds), (LPVOID)&ds );
HDC hdcmem = CreateCompatibleDC(hdc);
SelectObject( hdcmem, g_hRemoteBitmap );
StretchBlt( hdc, 0, 0, rect.right, rect.bottom,
hdcmem, 0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight, SRCCOPY );
SelectObject( hdcmem, (HBITMAP)NULL );
DeleteDC( hdcmem );
}
}
VOID WINAPI OnThreadWorkState( HWND hwnd, WPARAM w, LPARAM l )
{
switch( w )
{
case WORK_SUCCEEDED:
if(g_hRemoteBitmap != NULL )
DeleteObject( g_hRemoteBitmap );
g_hRemoteBitmap = (HBITMAP)l;
InvalidateRect( hwnd, NULL, FALSE );
break;
}
return;
}
BOOL WINAPI InitWorkThread( HWND hwnd )
{
// 确保 WIN98 的支持
DWORD tmp;
g_tc.hBeginConnectEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
g_tc.hBeginRequest = CreateEvent( NULL, FALSE, FALSE, NULL );
g_tc.hExitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
g_tc.hwnd = hwnd;
g_tc.msg = WM_THREADWORKSTATE;
g_hRemoteBitmap = NULL;
g_hThread1 = CreateThread( NULL, 0, ThreadFunc1, (LPVOID)&g_tc, 0, &tmp );
if( g_hThread1 != NULL )
return TRUE;
return TRUE;
}
VOID WINAPI DestroyWorkThreadResource()
{
if( g_ThreadState == UNINIT )
return;
// 通知线程退出;
SetEvent( g_tc.hExitEvent );
if( g_hSocket2 != NULL )
closesocket( g_hSocket2 );
if( g_hThread1 )
{
if ( WAIT_TIMEOUT == WaitForSingleObject( g_hThread1, 3000 ) )
TerminateThread( g_hThread1, 0);
CloseHandle( g_hThread1 );
g_hThread1 = NULL;
}
// 关闭用于通信的所有事件句柄
CloseHandle( g_tc.hBeginConnectEvent );
CloseHandle( g_tc.hBeginRequest );
CloseHandle( g_tc.hExitEvent );
if( g_hRemoteBitmap )
{
DeleteObject( g_hRemoteBitmap );
g_hRemoteBitmap = NULL;
}
}
BOOL WINAPI OnCreate( HWND hwnd, PAINTSTRUCT * pps )
{
WSADATA data;
if( SOCKET_ERROR == WSAStartup( MAKEWORD(2,2), &data ) )
return FALSE;
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(icex);
icex.dwICC = ICC_WIN95_CLASSES;
if( !InitWorkThread( hwnd) )
return FALSE;
return TRUE;
}
VOID WINAPI OnDestroy()
{
WSACleanup();
DestroyWorkThreadResource();
}
BOOL CALLBACK ConnectDialogProc( HWND dlg, UINT msg, WPARAM w, LPARAM l )
{
char str[256];
int ret;
switch( msg )
{
case WM_INITDIALOG:
SetFocus( GetDlgItem( dlg, IDC_SERVERNAME ) );
return TRUE;
case WM_COMMAND:
switch( w )
{
case IDOK:
GetWindowText( GetDlgItem(dlg, IDC_SERVERNAME), str, 255 );
g_dwServerIP = inet_addr( str );
GetWindowText( GetDlgItem( dlg, IDC_PORT), str, 255 );
g_usPort = htons( atoi(str));
if( g_ThreadState == WAIT_CONNECT )
{
g_addr2.sin_addr.S_un.S_addr = g_dwServerIP;
g_addr2.sin_family = AF_INET;
g_addr2.sin_port = g_usPort;
g_hSocket2 = socket( AF_INET, SOCK_STREAM, 0 );
if( g_hSocket2 == INVALID_SOCKET )
{
MessageBox( dlg, "资源不足, 无法创建套接字", "RCA Client Error" , MB_ICONERROR );
g_hSocket2 = NULL;
return TRUE;
}
if( g_ThreadState == WAIT_CONNECT )
SetEvent( g_tc.hBeginConnectEvent );
ret = connect( g_hSocket2, (sockaddr*)&g_addr2, sizeof(sockaddr) );
if( ret == SOCKET_ERROR )
{
MessageBox( dlg, WSAERRORSTRING, "RCA Client Error", MB_ICONERROR );
closesocket( g_hSocket2 );
g_hSocket2 = NULL;
return TRUE;
}
MSG msg;
while(1)
{
GetMessage( &msg, NULL, NULL, NULL );
if( (msg.hwnd == g_hWnd) && (msg.message==WM_THREADWORKSTATE))
{
if( msg.wParam != CONNECTED )
{
MessageBox( dlg, WSAERRORSTRING, "RCA Client Error", MB_ICONERROR );
return FALSE;
}
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -