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