www.pudn.com > 智能内码识别,支持屏幕取词翻译的程序.zip > HINT.CPP


// hint.cpp : implementation file 
// 
 
#include	"stdafx.h" 
#include	"cskernel.h" 
#include	"cspublic.h" 
 
static int		p_nHintWndFlag	=0 ;	//0没有,1显示临时窗口,2显示解释窗口,3显示提示窗口 
static HWND	p_hHintWnd=NULL ; 
static	COLORREF	p_HintColor=0 ;	//hint窗口的颜色 
//隐藏翻译结果 
void	HideThisWin( void ) ; 
//详细解释指取结果 
void ShowHint1( int nXStart , int nYStart ,  
				LPSTR lpsStr , int nLen ) ;	//详细显示指取结果 
//简单显示解释结果 
void ShowHint2( int nXStart , int nYStart ,  
				LPSTR lpsStr , int nLen ) ; 
 
#ifdef __cplusplus 
extern "C" { 
#endif 
 
//设置HINT和临时显示窗口句柄 
void __export FAR PASCAL SetHintHwnd( HWND hHint ) 
{ 
	p_hHintWnd	=hHint ; 
}	 
 
//显示一个临时窗口 
void __export FAR PASCAL	ShowTempWin( int nXStart , int nYStart ,  
										int nWidth , int nHeight ) 
{ 
	if( !p_hHintWnd ) 
		return ; 
	if( !p_nHintWndFlag &&	//已经显示 
		p_nHintWndFlag!=1 )	//不是自己在显示 
		HideThisWin() ; 
		 
	SetWindowPos( p_hHintWnd , HWND_TOPMOST , nXStart , nYStart ,  
						nWidth , nHeight ,  
        			            SWP_NOACTIVATE | SWP_SHOWWINDOW ) ; 
	p_nHintWndFlag	=1 ;	//标记窗口已经显示		                             
} 
 
//隐藏临时窗口                 
void __export FAR PASCAL	HideTempWin( void )  
{ 
	HideThisWin() ; 
} 
 
//显示hint 
static	g_nFingerStatus	=0 ; 
void __export FAR PASCAL	ShowHint( int nXStart , int nYStart ,  
				LPSTR lpsStr , int nLen ) 
{ 
	if( !p_hHintWnd ) 
		return ; 
	if( !p_nHintWndFlag &&	//已经显示 
		p_nHintWndFlag!=2 )	//不是自己在显示 
		HideThisWin() ; 
 
	g_nFingerStatus	=GetFingerTranslate() ; 
	if( g_nFingerStatus ) 
	{ 
		HookFingerOff1() ;	//指取翻译有效 
		SetFingerTranslate( 0 ) ; 
	} 
 
	p_HintColor	=RGB( 255 , 255 , 128 ) ; 
	ShowHint2( nXStart , nYStart , lpsStr , nLen ) ; 
	p_nHintWndFlag	=2 ;	//标记窗口已经显示		                             
} 
				 
//隐藏hint 
void __export FAR PASCAL	HideHint( void )  
{ 
	HideThisWin() ; 
 
	if( g_nFingerStatus ) 
	{ 
		SetFingerTranslate( g_nFingerStatus ) ; 
		g_nFingerStatus	=0 ; 
		HookFingerOn1() ;	//指取翻译有效 
	} 
} 
 
//显示翻译结果 
void __export FAR PASCAL	ShowFinger( int nXStart , int nYStart ,  
				LPSTR lpsStr , int nLen ) 
{ 
	if( !p_hHintWnd ) 
		return ; 
	if( !p_nHintWndFlag &&	//已经显示 
		p_nHintWndFlag!=3 )	//不是自己在显示 
		HideThisWin() ; 
 
	CPoint	CurrentPoint ; 
	GetCursorPos( &CurrentPoint ) ;	//得到当前点 
	//得到当前点下的窗口 
	HWND	hParentWnd	=::WindowFromPoint( CurrentPoint ) ; 
	if( !hParentWnd ) 
		return ; 
	//关闭窗口 
	HWND	closeWnd	=::FindWindow( NULL , "Close Program" ) ; 
	if( closeWnd==hParentWnd || ::IsChild( closeWnd , hParentWnd ) ) 
		return ;	//不对关闭窗口及其子窗口处理 
	HWND	close1Wnd	=::FindWindow( NULL , "关闭程序" ) ; 
	if( close1Wnd==hParentWnd || ::IsChild( close1Wnd , hParentWnd ) ) 
		return ; 
	//WIN切换窗口的窗口句柄 
	HWND	alt_tabWnd	=::FindWindow( "#32771" , NULL ) ; 
	if( alt_tabWnd==hParentWnd )	//不对切换窗口处理 
		return ; 
//------------------------------------------------------------------//	 
	p_HintColor	=RGB( 255 , 255 , 0 ) ; 
	if( GetWinOrBar() )	//详细显示解释结果 
		ShowHint1( nXStart , nYStart , lpsStr , nLen ) ; 
	else	//简单显示解释结果 
		ShowHint2( nXStart , nYStart , lpsStr , nLen ) ; 
 
	p_nHintWndFlag	=3 ;	//标记窗口已经显示		                             
} 
 
//隐藏翻译结果 
void __export FAR PASCAL	HideFinger( void )  
{ 
	HideThisWin() ; 
} 
 
#ifdef __cplusplus 
} 
#endif 
 
//隐藏翻译结果 
void	HideThisWin( void ) 
{ 
	ShowWindow( p_hHintWnd , SW_HIDE ) ; 
	p_nHintWndFlag	=0 ; 
} 
 
//简单显示解释结果 
void ShowHint2( int nXStart , int nYStart ,  
									LPSTR lpsStr , int nLen ) 
{ 
	int		nOldBkMode ; 
	COLORREF	oldColor ; 
	HDC		dc ; 
	//得到字符串的宽度与高度 
	DWORD	WidthHeight ; 
	int		wWidth ; 
	int		wHeight ; 
	//得到桌面窗口的宽度与高度 
	RECT	rectOfDesktop ; 
 
	dc	=GetDC( p_hHintWnd ) ; 
						 
	//创建所需要的字体	 
	HFONT	hFont	=::CreateFont( 16 ,			//高度 
					0 , 0 , 0 , 						//宽度等 
					FW_NORMAL , 
					FALSE , FALSE , 0 , 
					ANSI_CHARSET , 
					OUT_DEFAULT_PRECIS , 
					CLIP_DEFAULT_PRECIS , 
					DEFAULT_QUALITY  , 
				 	DEFAULT_PITCH , "Courier New" ) ; 
	HFONT	hOldFont	=(HFONT)SelectObject( dc , hFont ) ; 
 
	WidthHeight	=GetHzTextExtent( dc , lpsStr , nLen ) ; 
	wWidth	=LOWORD( WidthHeight ) + 2 ; 
	wHeight	=HIWORD( WidthHeight ) + 2 ; 
//------------------------------------------------------------------------------// 
 
	GetWindowRect( GetDesktopWindow() , &rectOfDesktop ) ;	 
	 
	//计算显示位置 
	nXStart	=max( 0 , min( nXStart , rectOfDesktop.right-wWidth ) ) ; 
	if( nYStart > rectOfDesktop.bottom-wHeight ) 
	{ 
		POINT	p ; 
		GetCursorPos ( &p ) ;	//得到鼠标位置 
		nYStart	=p.y - wHeight - wHeight/2 ; 
//		nYStart	=rectOfDesktop.bottom-wHeight-wHeight ; 
	} 
 
	//设置窗口大小与位置	 
	SetWindowPos( p_hHintWnd , HWND_TOPMOST , nXStart , nYStart ,  
								wWidth , wHeight ,  
	                            SWP_NOACTIVATE | SWP_SHOWWINDOW ) ; 
 
	//显示框 
	RECT	rect={ 0 , 0 , wWidth-1 , wHeight-1 } ; 
	DrawOneLineBox( dc , rect , 1 , RGB( 192 , 192 , 192 ) , 
		RGB( 128 , 128 , 128 ) , p_HintColor ) ; 
 
	//显示翻译结果 
	nOldBkMode	=SetBkMode( dc , TRANSPARENT ) ;	 
	oldColor	=SetTextColor( dc , RGB( 0 , 0 , 0 ) ) ; 
	TextOutString( dc , 1 , 1 , lpsStr , nLen ) ; 
	SetTextColor( dc , oldColor ) ; 
	SetBkMode( dc , nOldBkMode ) ; 
 
	SelectObject( dc , hOldFont ) ;	 
	DeleteObject( hFont ) ; 
 
	ReleaseDC( p_hHintWnd , dc ) ; 
} 
 
//详细解释指取结果 
#define	MAX_HINT_CHAR	100			//一行最大字节数		 
#define	MAX_HINT_LINE	15			//提示最大行数 
#define	TIP_HEIGHT	20		//尖高度 
#define	TIP_WIDTH	10		//尖宽度 
#define	SHADOW_WIDTH	5		//阴影宽度 
#define	SHADOW_HEIGHT	5		//阴影高度 
static	char	sHintBuff[MAX_HINT_LINE][MAX_HINT_CHAR+1] ; 
void ShowHint1( int nXStart , int nYStart ,  
				LPSTR lpsStr , int nLen )	//详细显示指取结果 
{ 
	HDC	dc	=GetDC( p_hHintWnd ) ; 
 
	HFONT	hFont1 , hFont2 , hOldFont2 ; 
	//创建显示音标所需要的字体	 
	hFont1	=CreateFont( 16 ,			//高度 
								0 , 0 , 0 , 						//宽度等 
								FW_NORMAL , 
								FALSE , FALSE , 0 , 
								ANSI_CHARSET , 
								OUT_DEFAULT_PRECIS , 
								CLIP_DEFAULT_PRECIS , 
								DEFAULT_QUALITY  , 
							 	DEFAULT_PITCH , "liuy" ) ; 
	//创建显示正文所需要的字体	 
	hFont2	=::CreateFont( 16 ,			//高度 
					0 , 0 , 0 , 						//宽度等 
					FW_NORMAL , 
					FALSE , FALSE , 0 , 
					ANSI_CHARSET , 
					OUT_DEFAULT_PRECIS , 
					CLIP_DEFAULT_PRECIS , 
					DEFAULT_QUALITY  , 
				 	DEFAULT_PITCH , "Courier New" ) ; 
	hOldFont2	=(HFONT)::SelectObject( dc , hFont2 ) ; 
//-----------------------------------------------------------------------------// 
	//得到桌面窗口的宽度与高度 
	RECT	rectOfDesktop ; 
	GetWindowRect( GetDesktopWindow() , &rectOfDesktop ) ;	 
 
	DWORD	WidthHeight ;		//字符串的宽度与高度 
	int		nLineHeight ;	//一行高度 
	WidthHeight	=GetHzTextExtent( dc , lpsStr , nLen ) ; 
	nLineHeight	=HIWORD( WidthHeight ) ;	//一行的高度 
//--------------------------------------------------------------------------------//	 
 
	//hint缓冲区 
//	char	sHintBuff[MAX_HINT_LINE][MAX_HINT_CHAR+1] ; 
	int			nHintLineNum	=0 ;	//hint行数 
	int			nHintCharNum	=0 ;	//HINT中一行的字节数 
	int			nMaxWidth	=0 ;		//HINT窗口中内容的最大宽度 
	 
	//得到原单词的内容 
	int	nLineWidth ;	//一行宽度 
	int	nSourceWordFlag=1 ;		//原来单词标记 
	for( int i=0 ; i MAX_HINT_CHAR-2 ||//至少能放两字节 
					nLineWidth+LOWORD( GetHzTextExtent( dc , lpsStr+i , 2 ) ) + 
					TIP_WIDTH+TIP_WIDTH+SHADOW_WIDTH>= 
						rectOfDesktop.right/2 )	//宽度不超过屏幕宽度一半 
				{	//一行结束,另起一行 
					if( nLineWidth > nMaxWidth )	//宽度超过最大宽度 
						nMaxWidth	=nLineWidth ;	//记录最大宽度 
 
					sHintBuff[nHintLineNum][nHintCharNum]	='\0' ;	//结束标记						 
					nHintLineNum++ ; 
					if( nHintLineNum >= MAX_HINT_LINE ||	//行数到头了 
						 (nHintLineNum+1)*nLineHeight+TIP_HEIGHT+ 
						 3*SHADOW_HEIGHT>=rectOfDesktop.bottom/2 )	//高度超过屏幕高度一半 
						break ; 
 
					nHintCharNum	=0 ;	//该行字符数为0 
				} 
				//记录该汉字 
				sHintBuff[nHintLineNum][nHintCharNum++]	=lpsStr[i++] ; 
				sHintBuff[nHintLineNum][nHintCharNum++]	=lpsStr[i++] ; 
				 
				continue ; 
			} 
			 
			if( (lpsStr[i]=='\r' && lpsStr[i+1]=='\n') ||	//一行结束 
				 (lpsStr[i]==';' && lpsStr[i+1]==' ' ) ) 
			{ 
				if( nLineWidth > nMaxWidth )	//宽度超过最大宽度 
					nMaxWidth	=nLineWidth ;	//记录最大宽度 
 
				sHintBuff[nHintLineNum][nHintCharNum]	='\0' ;	//结束标记 
				nHintLineNum++ ;	//增加行数 
				if( nHintLineNum >= MAX_HINT_LINE ||	//行数到头了 
					 (nHintLineNum+1)*nLineHeight+TIP_HEIGHT+ 
					 3*SHADOW_HEIGHT>=rectOfDesktop.bottom/2 )	//高度超过屏幕高度一半 
					break ; 
 
				nHintCharNum	=0 ;	//该行字符数为0 
				i++ ;		//去掉这两个行结束符 
				i++ ; 
				 
				continue ; 
			} 
		} 
											 
		if( (lpsStr[i] == ':' && nSourceWordFlag ) ||	//是原单词结束符 
			 lpsStr[i] ==';' ) 
		{ 
			if( lpsStr[i] == ':' ) 
				nSourceWordFlag	=0 ;	//取消标记 
			if( nLineWidth > nMaxWidth )	//宽度超过最大宽度 
				nMaxWidth	=nLineWidth ;	//记录最大宽度 
 
			sHintBuff[nHintLineNum][nHintCharNum]	='\0' ;	//结束标记 
			nHintLineNum++ ;	//增加行数 
			if( nHintLineNum >= MAX_HINT_LINE ||	//行数到头了 
				 (nHintLineNum+1)*nLineHeight+TIP_HEIGHT+ 
				 3*SHADOW_HEIGHT>=rectOfDesktop.bottom/2 )	//高度超过屏幕高度一半 
				break ; 
 
			nHintCharNum	=0 ;	//该行字符数为0 
			i++ ;		//去掉该字符 
				 
			continue ; 
		} 
 
        //是普通西文字符 
		if( nHintCharNum > MAX_HINT_CHAR-1 ||//至少能放一字节 
			nLineWidth+LOWORD( GetHzTextExtent( dc , lpsStr+i , 2 ) ) + 
			TIP_WIDTH+TIP_WIDTH+SHADOW_WIDTH>= 
			rectOfDesktop.right/2 )	//宽度不超过屏幕宽度一半 
		{	//一行结束,另起一行 
			if( nLineWidth > nMaxWidth )	//宽度超过最大宽度 
				nMaxWidth	=nLineWidth ;	//记录最大宽度 
 
			sHintBuff[nHintLineNum][nHintCharNum]	='\0' ;	//结束标记						 
			nHintLineNum++ ;	//增加行数 
			if( nHintLineNum >= MAX_HINT_LINE ||	//行数到头了 
				 (nHintLineNum+1)*nLineHeight+TIP_HEIGHT+ 
				 3*SHADOW_HEIGHT>=rectOfDesktop.bottom/2 )	//高度超过屏幕高度一半 
				break ; 
 
			nHintCharNum	=0 ;	//该行字符数为0 
		} 
		//记录该字符 
		sHintBuff[nHintLineNum][nHintCharNum++]	=lpsStr[i++] ; 
	} 
	if( i==nLen )	//扫遍所有字符 
	{ 
		nLineWidth	=LOWORD( 		//该行宽度 
			GetHzTextExtent( dc , sHintBuff[nHintLineNum] , nHintCharNum ) ) ; 
		if( nLineWidth > nMaxWidth )	//宽度超过最大宽度 
			nMaxWidth	=nLineWidth ;	//记录最大宽度 
 
		sHintBuff[nHintLineNum][nHintCharNum]	='\0' ;	//结束标记						 
		nHintLineNum++ ;	//加上最后一行 
	} 
//-------------------------------------------------------------------------------// 
	//计算显示窗口的宽度与高度,包括阴影 
	int		nWidth	=nMaxWidth+TIP_WIDTH*2+SHADOW_WIDTH ; 
	int		nHeight	=nHintLineNum*nLineHeight+TIP_HEIGHT+ 
							SHADOW_HEIGHT*3 ; 
	 
	//计算显示位置 
	int	nXFlag	=0 ; 
	int	nYFlag	=0 ; 
	if( nXStart > rectOfDesktop.right-nWidth )	//超过屏幕了 
	{ 
		nXStart	-=nWidth ;	//X反向 
		nXFlag	=1 ; 
	} 
	if( nYStart > rectOfDesktop.bottom-nHeight ) 
	{ 
		POINT	cursorPos ;	//鼠标位置 
		GetCursorPos( &cursorPos ) ; 
 
		nYStart	=cursorPos.y - nHeight -  
						GetSystemMetrics( SM_CYCURSOR )/3  ;	//光标高度一半 
		nYFlag	=1 ; 
	} 
		 
	//设置窗口大小与位置 
	SetWindowPos( p_hHintWnd , HWND_TOPMOST , nXStart , nYStart ,  
								nWidth , nHeight ,  
	                            SWP_NOACTIVATE | SWP_SHOWWINDOW ) ; 
//---------------------------------------------------------------------------------//	                             
	//设置笔与画刷 
	HPEN	hBlackPen	=CreatePen( PS_SOLID , 0 , RGB( 0 , 0 , 0 ) ) ;	//黑笔 ; 
	HBRUSH	hYellowBrush	=CreateSolidBrush( RGB( 255 , 255 , 150 ) ) ;	//黄刷 
	HBRUSH	hShadowBrush	=CreateSolidBrush( RGB( 128,128,128));//165,165,165));//111,111,0 ) ) ;	//阴影刷子 
	HPEN	pOldPen ; 
	HBRUSH	pOldBrush ; 
				 
	//设置笔与画刷 
	pOldPen		=(HPEN)::SelectObject( dc , hBlackPen ) ; 
	pOldBrush	=(HBRUSH)::SelectObject( dc , hShadowBrush ) ;	//阴影刷子 
	//画一个矩形阴影 
	int	nX , nY , nX1 , nY1 ; 
	if( nXFlag )	//X反向了 
	{ 
		nX	=0 ; 
		nX1	=nWidth-SHADOW_WIDTH ; 
	} 
	else 
	{ 
		nX	=SHADOW_WIDTH ; 
		nX1	=nWidth ; 
	} 
	if( nYFlag )	//Y反向了 
	{ 
		nY	=0 ; 
		nY1	=nHeight-TIP_HEIGHT-SHADOW_HEIGHT ; 
	} 
	else 
	{ 
		nY	=TIP_HEIGHT+SHADOW_HEIGHT ; 
		nY1	=nHeight ; 
	} 
	Rectangle( dc , nX , nY , nX1 , nY1 ) ; 
 
	POINT	points[5] ;	//HINT窗口的五个顶点 
	if( nXFlag )	//X反向了 
	{ 
		points[0].x	=nWidth-1 ; 
		points[1].x	=nWidth-TIP_WIDTH ; 
		points[2].x	=SHADOW_WIDTH ; 
		points[3].x	=SHADOW_WIDTH ; 
		points[4].x	=nWidth-1 ; 
	} 
	else 
	{ 
		points[0].x	=0 ; 
		points[1].x	=TIP_WIDTH ; 
		points[2].x	=nWidth-SHADOW_WIDTH ; 
		points[3].x	=nWidth-SHADOW_WIDTH ; 
		points[4].x	=0 ; 
	} 
	if( nYFlag )	//Y反向了 
	{ 
		points[0].y	=nHeight ; 
		points[1].y	=nHeight-TIP_HEIGHT ; 
		points[2].y	=nHeight-TIP_HEIGHT ; 
		points[3].y	=SHADOW_HEIGHT ; 
		points[4].y	=SHADOW_HEIGHT ; 
	} 
	else 
	{ 
		points[0].y	=0 ; 
		points[1].y	=TIP_HEIGHT ; 
		points[2].y	=TIP_HEIGHT ; 
		points[3].y	=nHeight-SHADOW_HEIGHT ; 
		points[4].y	=nHeight-SHADOW_HEIGHT ; 
	} 
	::SelectObject( dc , hYellowBrush ) ;	//HINT窗口刷子 
	Polygon( dc , points , 5 ) ;	//HINT窗口 
 
	//显示翻译结果 
	int	nOldBkMode	=SetBkMode( dc , TRANSPARENT ) ;	 
	COLORREF	oldColor	=SetTextColor( dc , RGB( 0 , 0 , 0 ) ) ; 
	if( nXFlag )	//X反向了 
		nX	=SHADOW_WIDTH+TIP_WIDTH ; 
	else 
		nX	=TIP_WIDTH ; 
	if( nYFlag )	//Y反向了 
		nY	=SHADOW_HEIGHT*2 ; 
	else 
		nY	=TIP_HEIGHT+SHADOW_HEIGHT ; 
     
    HFONT	hOldFont1 ; 
	for( i=0 ; i