⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcahelper.cpp

📁 远程控制软件源代码
💻 CPP
字号:

#include "stdafx.h"

BOOL 
WINAPI 
DecodeFromJPEGBuffer(
 	BYTE *	lpJpgBuffer,
 	DWORD 	dwJpgBufferSize,
 	BYTE**	lppRgbBuffer,
 	DWORD*	lpdwWidth,
 	DWORD*	lpdwHeight,
 	DWORD*	lpdwNumberOfChannels
 	)
 {
 	
	BOOL 	bres;
	IJLERR 	jerr;
	DWORD 	dwWholeImageSize;
	BYTE* 	lpTemp = NULL;

	// Allocate the IJL JPEG_CORE_PROPERTIES structure.
	JPEG_CORE_PROPERTIES jcprops;

	bres = TRUE;

	__try
	{
	// Initialize the Intel(R) JPEG Library.
		jerr = ijlInit(&jcprops);
		if(IJL_OK != jerr)
		{
			bres = FALSE;
			__leave;
		} 	
 		
		// Get information on the JPEG image
		// (i.e., width, height, and channels).

		jcprops.JPGFile = NULL;
		jcprops.JPGBytes = lpJpgBuffer;
		jcprops.JPGSizeBytes = dwJpgBufferSize;
		jerr = ijlRead(&jcprops, IJL_JBUFF_READPARAMS);
		if(IJL_OK != jerr)
		{
			bres = FALSE;
			__leave;
		}
		// Set the JPG color space ... this will always be
		// somewhat of an educated guess at best because JPEG
		// is "color blind" (i.e., nothing in the bit stream
		// tells you what color space the data was encoded from).
		// However, in this example we assume that we are
		// reading JFIF files which means that 3 channel images
		// are in the YCbCr color space and 1 channel images are
		// in the Y color space.
		switch(jcprops.JPGChannels)
		{
		case 1:
			{
				jcprops.JPGColor = IJL_G;
				jcprops.DIBColor = IJL_RGB;
				jcprops.DIBChannels = 3;
				break;
			}
		case 3:
			{
				jcprops.JPGColor = IJL_YCBCR;
				jcprops.DIBColor = IJL_RGB;
				jcprops.DIBChannels = 3;
				break;
			}
		default:
			{
				// This catches everything else, but no
				// color twist will be performed by the IJL.

				jcprops.JPGColor = IJL_OTHER;
				jcprops.DIBColor = IJL_OTHER;
				jcprops.DIBChannels = jcprops.JPGChannels;
				break;
			}
		}
		// Compute size of desired pixel buffer.
		dwWholeImageSize = jcprops.JPGWidth * jcprops.JPGHeight *
			jcprops.DIBChannels;
		// Allocate memory to hold the decompressed image data.
		lpTemp = new BYTE [dwWholeImageSize];
		if(NULL == lpTemp)
		{
			bres = FALSE;
			__leave;
		}
		// Set up the info on the desired DIB properties.
		jcprops.DIBWidth = jcprops.JPGWidth;
		jcprops.DIBHeight = jcprops.JPGHeight;
		jcprops.DIBPadBytes = 0;
		jcprops.DIBBytes = lpTemp;
		// Now get the actual JPEG image data into the pixel buffer.
		jerr = ijlRead(&jcprops, IJL_JBUFF_READWHOLEIMAGE);
		if(IJL_OK != jerr)
		{
			bres = FALSE;
			__leave;
		}
	} // __try
	__finally
	{
		if(FALSE == bres)
		{
			if(NULL != lpTemp)
			{
				delete [] lpTemp;
				lpTemp = NULL;
			}
		}

		// Clean up the Intel(R) JPEG Library.
		ijlFree(&jcprops);
		*lpdwWidth = jcprops.DIBWidth;
		*lpdwHeight = jcprops.DIBHeight;
		*lpdwNumberOfChannels = jcprops.DIBChannels;
		*lppRgbBuffer = lpTemp;

	} // __finally


	return bres;
 } // DecodeFromJPEGBuffer()


 //----------------------------------------------------------
 // An example using the Intel(R) JPEG Library:
 // -- Encode Windows DIB to JPEG buffer.
 //----------------------------------------------------------
 BOOL WINAPI EncodeToJPEGBuffer(
	 BYTE* lpRgbBuffer,
	 DWORD dwWidth,
	 DWORD dwHeight,
	 BYTE** lppJpgBuffer,
	 DWORD* lpdwJpgBufferSize,
	 int	iQuality
)
{
	 BOOL bres;
	 IJLERR jerr;
	 DWORD dwRgbBufferSize;
	 BYTE* lpTemp;

	 // Allocate the IJL JPEG_CORE_PROPERTIES structure.
	 JPEG_CORE_PROPERTIES jcprops;
	 bres = TRUE;
	 __try
	 {
		 // Initialize the Intel(R) JPEG Library.

		 jerr = ijlInit(&jcprops);
		 if(IJL_OK != jerr)
		 {
			 bres = FALSE;
			 __leave;
		 }
		 dwRgbBufferSize = dwWidth * dwHeight * 3;
		 lpTemp = new BYTE [dwRgbBufferSize];
		 if(NULL == lpTemp)
		 {
			 bres = FALSE;
			 __leave;
		 }
		 // Set up information to write from the pixel buffer.
		 jcprops.DIBWidth = dwWidth;
		 jcprops.DIBHeight = dwHeight; // Implies a bottom-up DIB.
		 jcprops.DIBBytes = lpRgbBuffer;
		 jcprops.DIBPadBytes = 0;
		 jcprops.DIBChannels = 3;
		 jcprops.DIBColor = IJL_RGB;
		 jcprops.JPGWidth = dwWidth;
		 jcprops.JPGHeight = dwHeight;
		 jcprops.JPGFile = NULL;
		 jcprops.JPGBytes = lpTemp;
		 jcprops.JPGSizeBytes = dwRgbBufferSize;
		 jcprops.JPGChannels = 3;
		 jcprops.JPGColor = IJL_YCBCR;
		 jcprops.JPGSubsampling = IJL_411; // 4:1:1 subsampling.
		 jcprops.jquality = (iQuality>=0)&&(iQuality<=100) ? iQuality : 50; // Select "good" image quality
		 // Write the actual JPEG image from the pixel buffer.
		 jerr = ijlWrite(&jcprops,IJL_JBUFF_WRITEWHOLEIMAGE);
		 if(IJL_OK != jerr)
		 {
			 bres = FALSE;
			 __leave;
		 }
	 } // __try
	 __finally
	 {
		 if(FALSE == bres)
		 {
			 if(NULL != lpTemp)
			 {
				 delete[] lpTemp;
				 lpTemp = NULL;
			 }
		 }
		 *lppJpgBuffer = lpTemp;
		 *lpdwJpgBufferSize = jcprops.JPGSizeBytes;
		 // Clean up the Intel(R) JPEG Library.
		 ijlFree(&jcprops);
	 }
	 return bres;
 } // EncodeToJPEGBuffer()


////////////////////////////////////////
//
//	SOCKET 异步 IO 帮助函数, 异步模型为 "事件选择模型"
//	
//	参数:
//	SOCKET s:	
//		套接字 s 是一个已成功连接的套接字, 并至少使用 FD_READ 标志作为
//		参数 lNetworkEvents 调用了 WSAEventSelect 成功地将套接字置为异步事件选择模型
//				
//	HANDLE hEvent: 
//		一个用于网络 IO 事件通知的事件句柄. 
//	
//	char * buf:
//		接收数据缓冲
//
//	int	len:
//		接收数据缓冲总长度
//
//	BOOL * bExit:
//		BOOL 变量的指针, 应用程序可以修改这个值. 这个函数调用 WaitForSingleObject 等待 
//		dwMilliseconds 毫秒后, 将检测 bExit 的值, 若为 bExit 为 TRUE, 函数将立即返回.
//		返回时是不管等待是否成功的,或说不论等待结果是 WAIT_TIMEOUT 或者 WAIT_OBJECT_0,
//		都会返回, 只要 bExit 为 TRUE
//	
//
//	DWORD dwMilliseconds:
//		函数将使用这个值作为第二个参数,调用 WaitForSingleObject. 以毫秒为单位
//		INFINITE 为无限等待
//
//	返回值:
//		若第一次调用接收函数时, 连接出现问题, 则返回 0 
//
//		若第一次调用接收函数成功后,以后无论发生任何错误都返回一个整型值,
//		描述已接收了多少数据
//
//		如果返回值与参数 len 相等, 说明成功发送出了所有数据, 若不等,可能是网络错误造成, 
//		也可能是 bExit 被设为 TRUE 后接收操作被强制中断
INT
WINAPI RCARecv_EventSelectIO( 
		SOCKET	s, 
		HANDLE	hEventArray[2],
		char*	buf,
const	int		len
)
{
	if( (buf == NULL) || (len==0) )
		return FALSE;
	
	int					ret;
	DWORD				dwret;
	int					count	= len;
	int					index	= 0;
	WSANETWORKEVENTS	ns;

	while( count > 0 )
	{
		ret = recv( s, &(buf[index]), count, 0 );

		if( ret == SOCKET_ERROR )
		{
			// 如果发送错误,并且错误代码不是"被阻塞", 则返回 FALSE ( 发生了网络错误 )
			if( WSAGetLastError() != WSAEWOULDBLOCK )
				return len - count;

		} else if( ret == 0 )
		{
			return len - count ;

		} else 
		{
			// 如果成功发送, 则更新缓冲偏移字节数和待发总字节数
			index += ret;
			count -= ret;
			continue;
		}

		dwret = WaitForMultipleObjects( 
			2, hEventArray, FALSE, INFINITE );

		switch ( dwret )
		{
		case WAIT_FAILED:
			return len - count;
		
		case WAIT_OBJECT_0:
			break;

		case WAIT_OBJECT_0 + 1:
			return len - count;

		case WAIT_TIMEOUT:
			break;
		}

		ret = WSAEnumNetworkEvents( s, hEventArray[0], &ns );

		if( ret == SOCKET_ERROR )
		{
			return len - count;
		}
		
		if( ns.lNetworkEvents & FD_READ )
		{
			if( ns.iErrorCode[ FD_READ_BIT] != 0 )
			{
				return len - count;
			}
			else
			{
				continue; // 回到循环开始处,再次接收数据(此时,绝对可以接收数据)
			}
		}

		if( ns.lNetworkEvents & FD_CLOSE )
		{
			return len - count;
		}
	}
	
	return len - count;
}




////////////////////////////////////////
//
//	SOCKET 异步 IO 帮助函数, 异步模型 事件选择模型
//	
//	参数:
//	SOCKET s:	
//		套接字 s 是一个已成功连接的套接字, 并至少使用 FD_WRITE 标志作为
//		参数 lNetworkEvents 调用了 WSAEventSelect 成功地将套接字置为异步事件选择模型
//				
//	HANDLE hEvent: 
//		一个用于网络 IO 事件通知的事件句柄. 
//	
//	char * buf:
//		待发数据缓冲
//
//	int	len:
//		待发数据缓冲总长度
//
//	BOOL * bExit:
//		BOOL 变量的指针, 应用程序可以修改这个值. 这个函数调用 WaitForSingleObject 等待 
//		dwMilliseconds 毫秒后, 将检测 bExit 的值, 若为 bExit 为 TRUE, 函数将立即返回.
//		返回时是不管等待是否成功的,或说不论等待结果是 WAIT_TIMEOUT 或者 WAIT_OBJECT_0,
//		都会返回, 只要 bExit 为 TRUE
//	
//
//	DWORD dwMilliseconds:
//		函数将使用这个值作为第二个参数,调用 WaitForSingleObject. 以毫秒为单位
//		INFINITE 为无限等待
//
//	返回值:
//		若第一次调用发送函数时, 连接出现问题, 则返回 0 
//
//		若第一次调用发送函数成功后,以后无论发生任何错误都返回一个整型值,
//		描述已发送了多少数据
//
//		如果返回值与参数 len 相等, 说明成功发送出了所有数据, 若不等,可能是网络错误造成, 
//		也可能是 bExit 被设为 TRUE 后发送操作被强制中断
INT 
WINAPI RCASend_EventSelectIO( 
		SOCKET	s, 
		HANDLE	hEventArray[2],
		char*	buf,
const	int		len
)
{
	if( (buf == NULL) || (len==0) )
		return FALSE;
	
	int					ret;
	int					count	= (int)len;
	int					index	=0;
	DWORD				dwret;
	WSANETWORKEVENTS	ns;

	while( count > 0 )
	{
		
		ret = send( s, &(buf[index]), count, 0 );
			
		if( ret == SOCKET_ERROR )
		{
			// 如果发送错误,并且错误代码不是"被阻塞", 则返回 FALSE ( 发生了网络错误 )
			if( WSAGetLastError() != WSAEWOULDBLOCK )
				return len - count;
		}
		else
		{
			// 如果成功发送, 则更新缓冲偏移字节数和待发总字节数
			index += ret;
			count -= ret;
			continue;
		}

		// 到这里,说明没而待发缓冲区可供使用, 在 AsyncEvent IO 模型中, 可以等待事件通知的到来
		// 现在根据 dwMilliseconds 来待待事件通知
		dwret = WaitForMultipleObjects( 
			2,  hEventArray, FALSE, INFINITE );
		switch( dwret )
		{
		case WAIT_FAILED:
		case WAIT_OBJECT_0 + 1:
			return len - count;

		case WAIT_OBJECT_0:
			break;

		case WAIT_TIMEOUT:
			continue;
		}

		ret = WSAEnumNetworkEvents( s, hEventArray[0], &ns );

		if( ns.lNetworkEvents & FD_WRITE )
		{
			if( ns.iErrorCode[ FD_WRITE_BIT] != 0 )
				return (len - count);
			else
				continue; // 回到前边,再次发送数据(此时,绝对可以发送数据)
		}

		if( ret == SOCKET_ERROR )
			return (len - count);
		
		if( ns.lNetworkEvents & FD_CLOSE )
			return (len - count);
	}

	return len - count;
}





///////////////////////////////////////////
//
//	获得整个屏幕的象素信息
//	
//	参数: 
//
//	pbmi[in,out] -- BITMAPINFO 结构指针, 函数成功调用后会填充这个结构,这个结构反映了象素信息
//
//	x, y, w, h;  矩形的左上角座标, 以及宽高. 如果这些参数不合法,将被修整为合法参数
//
//	pBits[in,out]	-- void 指针, 函数调用成功后,pBits 将被象素值填充. 如果 pBits 为NULL,
//					函数将修改 dwBufferSize 参数, 指明需要多少缓冲存放象素值
//
//  dwBufferSize -- [in, out] 指明 pBits 的大小. 如果函数成功调用后, dwBufferSize 将会被修改, 
//					指明实际拷贝的象素字节数
// 返回值:
//		 BOOL 类型, 函数调用成功后, 将返回 TRUE; 失败,将返回 FALSE;
// 
HBITMAP 
WINAPI GetDCPixel_BMP (
	HDC			hdc,
	int 		x,
	int 		y,
	int 		w,
	int 		h,
	int			zw,
	int			zh,
	WORD		wBitCount,
	VOID **		pBits,
	BITMAPINFOHEADER	* pbmih,		// 当色深为 8 时, 包含颜色表
	DWORD *		pdwBitmapInfoSize
)
{
	int width = 0;
	int height;

	// 确定 DC 是而效的, 并获得 DC 的宽高(以像素为单位)
	width = GetDeviceCaps( hdc, HORZRES);
	if( width == 0 )
		return NULL;
	height = GetDeviceCaps( hdc, VERTRES);
	
	// 修整请求的矩形
	x = (x<0)||(x>(width-1)) ? 0 : x;
	y = (y<0)||(y>(height-1)) ? 0 : y;

	w = (w>(width-x)) || (w<1) ?  width - x : w;
	h = (h>(height-y)) || (h<1) ?  height - y : h;

	zw = zw <= 0 ? w : zw;
	zh = zh <= 0 ? h : zh;

	// 修整请求的色深
	if( wBitCount <= 8 )
		wBitCount = 8;
	else if( wBitCount <=16 )
		wBitCount = 16;
	else if( wBitCount <= 24 )
		wBitCount = 24;
	else if( wBitCount >=32 )
		wBitCount = 32;


	// 计算存储图象所需空间的大小
	//DWORD tmp = (((w * wBitCount) +31) & ~31) / 8 * h;

	
	if( pbmih != NULL )
	{
		if( wBitCount == 8 )
		{
			if( *pdwBitmapInfoSize < (sizeof(RGBQUAD)*256 + sizeof(BITMAPINFOHEADER) ))
			{
				return NULL;
			}
		} 
		else 
		{
			if( *pdwBitmapInfoSize < sizeof( BITMAPINFOHEADER) )
			{
				return NULL;
			}
		}

	} 
	else
	{
		*pdwBitmapInfoSize = (sizeof(RGBQUAD)*256 + sizeof(BITMAPINFOHEADER) );
		return NULL;
	}


	HBITMAP		bmp;
	PVOID		pTmp = NULL;
	BITMAPINFO	bmi;
	bmi.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth			= zw;
	bmi.bmiHeader.biHeight			= zh;
	bmi.bmiHeader.biPlanes			= 1;
	bmi.bmiHeader.biBitCount		= wBitCount;
	bmi.bmiHeader.biCompression		= BI_RGB;
	bmi.bmiHeader.biSizeImage		= 0;
	bmi.bmiHeader.biXPelsPerMeter	= 0;
	bmi.bmiHeader.biYPelsPerMeter	= 0;
	bmi.bmiHeader.biClrUsed			= 0;
	bmi.bmiHeader.biClrImportant	= 0;


	// create a DIB section bitmap;
	if( wBitCount == 8 )
		bmp = CreateDIBSection( hdc, &bmi, DIB_PAL_COLORS, &pTmp, NULL, 0 );
	else
		bmp = CreateDIBSection( hdc, &bmi, DIB_RGB_COLORS, &pTmp, NULL, 0 );

	if( bmp == NULL )
	{
		return NULL;
	}

	// set the out param pBits to image buffer pTmp;
	*pBits = pTmp;

	HDC hdcMem = CreateCompatibleDC( hdc );
	if( hdcMem == NULL)
	{
		DeleteObject(bmp);
		return NULL;
	}
	
	SelectObject( hdcMem, bmp );
	StretchBlt( hdcMem, 0, 0, zw, zh, hdc, x, y, w, h, SRCCOPY );
	//BitBlt( hdc, 0, 0,w, h, hdcMem, 0, 0, SRCCOPY );	

	DIBSECTION ds;
	GetObject( bmp, sizeof(ds), (PVOID)&ds );

	
	if( ds.dsBm.bmBitsPixel == 8 )
	{
		
		int clrGetNum;
		SelectObject( hdcMem, bmp );
		clrGetNum = GetDIBColorTable( hdcMem, 0, ds.dsBmih.biClrUsed, 
			(RGBQUAD*)(sizeof(BITMAPINFOHEADER) +(char*)pbmih ) ); 
		if(  0 == clrGetNum )
		{
			DeleteDC( hdcMem );
			DeleteObject( bmp );
			return NULL;
		}

	}

	CopyMemory( (void*)pbmih, &(ds.dsBmih), sizeof(BITMAPINFOHEADER) );	

	DeleteDC( hdcMem );
	return bmp;
}


VOID
WINAPI InitResponseHead(
	PRCARESPONSEHEADER prresh,
	DWORD dwStatusCode,
	DWORD dwSize
)
{
	lstrcpy( prresh->rcaID, "RCA" );
	prresh->dwStatusCode = dwStatusCode;
	prresh->dwTotalBytes = dwSize;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -