HINT.CPP
上传用户:zhang8947
上传日期:2007-01-08
资源大小:1910k
文件大小:14k
源码类别:

多国语言处理

开发平台:

Visual C++

  1. // hint.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "cskernel.h"
  5. #include "cspublic.h"
  6. static int p_nHintWndFlag =0 ; //0没有,1显示临时窗口,2显示解释窗口,3显示提示窗口
  7. static HWND p_hHintWnd=NULL ;
  8. static COLORREF p_HintColor=0 ; //hint窗口的颜色
  9. //隐藏翻译结果
  10. void HideThisWin( void ) ;
  11. //详细解释指取结果
  12. void ShowHint1( int nXStart , int nYStart , 
  13. LPSTR lpsStr , int nLen ) ; //详细显示指取结果
  14. //简单显示解释结果
  15. void ShowHint2( int nXStart , int nYStart , 
  16. LPSTR lpsStr , int nLen ) ;
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. //设置HINT和临时显示窗口句柄
  21. void __export FAR PASCAL SetHintHwnd( HWND hHint )
  22. {
  23. p_hHintWnd =hHint ;
  24. }
  25. //显示一个临时窗口
  26. void __export FAR PASCAL ShowTempWin( int nXStart , int nYStart , 
  27. int nWidth , int nHeight )
  28. {
  29. if( !p_hHintWnd )
  30. return ;
  31. if( !p_nHintWndFlag && //已经显示
  32. p_nHintWndFlag!=1 ) //不是自己在显示
  33. HideThisWin() ;
  34. SetWindowPos( p_hHintWnd , HWND_TOPMOST , nXStart , nYStart , 
  35. nWidth , nHeight , 
  36.                      SWP_NOACTIVATE | SWP_SHOWWINDOW ) ;
  37. p_nHintWndFlag =1 ; //标记窗口已经显示                             
  38. }
  39. //隐藏临时窗口                
  40. void __export FAR PASCAL HideTempWin( void ) 
  41. {
  42. HideThisWin() ;
  43. }
  44. //显示hint
  45. static g_nFingerStatus =0 ;
  46. void __export FAR PASCAL ShowHint( int nXStart , int nYStart , 
  47. LPSTR lpsStr , int nLen )
  48. {
  49. if( !p_hHintWnd )
  50. return ;
  51. if( !p_nHintWndFlag && //已经显示
  52. p_nHintWndFlag!=2 ) //不是自己在显示
  53. HideThisWin() ;
  54. g_nFingerStatus =GetFingerTranslate() ;
  55. if( g_nFingerStatus )
  56. {
  57. HookFingerOff1() ; //指取翻译有效
  58. SetFingerTranslate( 0 ) ;
  59. }
  60. p_HintColor =RGB( 255 , 255 , 128 ) ;
  61. ShowHint2( nXStart , nYStart , lpsStr , nLen ) ;
  62. p_nHintWndFlag =2 ; //标记窗口已经显示                             
  63. }
  64. //隐藏hint
  65. void __export FAR PASCAL HideHint( void ) 
  66. {
  67. HideThisWin() ;
  68. if( g_nFingerStatus )
  69. {
  70. SetFingerTranslate( g_nFingerStatus ) ;
  71. g_nFingerStatus =0 ;
  72. HookFingerOn1() ; //指取翻译有效
  73. }
  74. }
  75. //显示翻译结果
  76. void __export FAR PASCAL ShowFinger( int nXStart , int nYStart , 
  77. LPSTR lpsStr , int nLen )
  78. {
  79. if( !p_hHintWnd )
  80. return ;
  81. if( !p_nHintWndFlag && //已经显示
  82. p_nHintWndFlag!=3 ) //不是自己在显示
  83. HideThisWin() ;
  84. CPoint CurrentPoint ;
  85. GetCursorPos( &CurrentPoint ) ; //得到当前点
  86. //得到当前点下的窗口
  87. HWND hParentWnd =::WindowFromPoint( CurrentPoint ) ;
  88. if( !hParentWnd )
  89. return ;
  90. //关闭窗口
  91. HWND closeWnd =::FindWindow( NULL , "Close Program" ) ;
  92. if( closeWnd==hParentWnd || ::IsChild( closeWnd , hParentWnd ) )
  93. return ; //不对关闭窗口及其子窗口处理
  94. HWND close1Wnd =::FindWindow( NULL , "关闭程序" ) ;
  95. if( close1Wnd==hParentWnd || ::IsChild( close1Wnd , hParentWnd ) )
  96. return ;
  97. //WIN切换窗口的窗口句柄
  98. HWND alt_tabWnd =::FindWindow( "#32771" , NULL ) ;
  99. if( alt_tabWnd==hParentWnd ) //不对切换窗口处理
  100. return ;
  101. //------------------------------------------------------------------//
  102. p_HintColor =RGB( 255 , 255 , 0 ) ;
  103. if( GetWinOrBar() ) //详细显示解释结果
  104. ShowHint1( nXStart , nYStart , lpsStr , nLen ) ;
  105. else //简单显示解释结果
  106. ShowHint2( nXStart , nYStart , lpsStr , nLen ) ;
  107. p_nHintWndFlag =3 ; //标记窗口已经显示                             
  108. }
  109. //隐藏翻译结果
  110. void __export FAR PASCAL HideFinger( void ) 
  111. {
  112. HideThisWin() ;
  113. }
  114. #ifdef __cplusplus
  115. }
  116. #endif
  117. //隐藏翻译结果
  118. void HideThisWin( void )
  119. {
  120. ShowWindow( p_hHintWnd , SW_HIDE ) ;
  121. p_nHintWndFlag =0 ;
  122. }
  123. //简单显示解释结果
  124. void ShowHint2( int nXStart , int nYStart , 
  125. LPSTR lpsStr , int nLen )
  126. {
  127. int nOldBkMode ;
  128. COLORREF oldColor ;
  129. HDC dc ;
  130. //得到字符串的宽度与高度
  131. DWORD WidthHeight ;
  132. int wWidth ;
  133. int wHeight ;
  134. //得到桌面窗口的宽度与高度
  135. RECT rectOfDesktop ;
  136. dc =GetDC( p_hHintWnd ) ;
  137. //创建所需要的字体
  138. HFONT hFont =::CreateFont( 16 , //高度
  139. 0 , 0 , 0 ,  //宽度等
  140. FW_NORMAL ,
  141. FALSE , FALSE , 0 ,
  142. ANSI_CHARSET ,
  143. OUT_DEFAULT_PRECIS ,
  144. CLIP_DEFAULT_PRECIS ,
  145. DEFAULT_QUALITY  ,
  146.   DEFAULT_PITCH , "Courier New" ) ;
  147. HFONT hOldFont =(HFONT)SelectObject( dc , hFont ) ;
  148. WidthHeight =GetHzTextExtent( dc , lpsStr , nLen ) ;
  149. wWidth =LOWORD( WidthHeight ) + 2 ;
  150. wHeight =HIWORD( WidthHeight ) + 2 ;
  151. //------------------------------------------------------------------------------//
  152. GetWindowRect( GetDesktopWindow() , &rectOfDesktop ) ;
  153. //计算显示位置
  154. nXStart =max( 0 , min( nXStart , rectOfDesktop.right-wWidth ) ) ;
  155. if( nYStart > rectOfDesktop.bottom-wHeight )
  156. {
  157. POINT p ;
  158. GetCursorPos ( &p ) ; //得到鼠标位置
  159. nYStart =p.y - wHeight - wHeight/2 ;
  160. // nYStart =rectOfDesktop.bottom-wHeight-wHeight ;
  161. }
  162. //设置窗口大小与位置
  163. SetWindowPos( p_hHintWnd , HWND_TOPMOST , nXStart , nYStart , 
  164. wWidth , wHeight , 
  165.                             SWP_NOACTIVATE | SWP_SHOWWINDOW ) ;
  166. //显示框
  167. RECT rect={ 0 , 0 , wWidth-1 , wHeight-1 } ;
  168. DrawOneLineBox( dc , rect , 1 , RGB( 192 , 192 , 192 ) ,
  169. RGB( 128 , 128 , 128 ) , p_HintColor ) ;
  170. //显示翻译结果
  171. nOldBkMode =SetBkMode( dc , TRANSPARENT ) ;
  172. oldColor =SetTextColor( dc , RGB( 0 , 0 , 0 ) ) ;
  173. TextOutString( dc , 1 , 1 , lpsStr , nLen ) ;
  174. SetTextColor( dc , oldColor ) ;
  175. SetBkMode( dc , nOldBkMode ) ;
  176. SelectObject( dc , hOldFont ) ;
  177. DeleteObject( hFont ) ;
  178. ReleaseDC( p_hHintWnd , dc ) ;
  179. }
  180. //详细解释指取结果
  181. #define MAX_HINT_CHAR 100 //一行最大字节数
  182. #define MAX_HINT_LINE 15 //提示最大行数
  183. #define TIP_HEIGHT 20 //尖高度
  184. #define TIP_WIDTH 10 //尖宽度
  185. #define SHADOW_WIDTH 5 //阴影宽度
  186. #define SHADOW_HEIGHT 5 //阴影高度
  187. static char sHintBuff[MAX_HINT_LINE][MAX_HINT_CHAR+1] ;
  188. void ShowHint1( int nXStart , int nYStart , 
  189. LPSTR lpsStr , int nLen ) //详细显示指取结果
  190. {
  191. HDC dc =GetDC( p_hHintWnd ) ;
  192. HFONT hFont1 , hFont2 , hOldFont2 ;
  193. //创建显示音标所需要的字体
  194. hFont1 =CreateFont( 16 , //高度
  195. 0 , 0 , 0 ,  //宽度等
  196. FW_NORMAL ,
  197. FALSE , FALSE , 0 ,
  198. ANSI_CHARSET ,
  199. OUT_DEFAULT_PRECIS ,
  200. CLIP_DEFAULT_PRECIS ,
  201. DEFAULT_QUALITY  ,
  202.   DEFAULT_PITCH , "liuy" ) ;
  203. //创建显示正文所需要的字体
  204. hFont2 =::CreateFont( 16 , //高度
  205. 0 , 0 , 0 ,  //宽度等
  206. FW_NORMAL ,
  207. FALSE , FALSE , 0 ,
  208. ANSI_CHARSET ,
  209. OUT_DEFAULT_PRECIS ,
  210. CLIP_DEFAULT_PRECIS ,
  211. DEFAULT_QUALITY  ,
  212.   DEFAULT_PITCH , "Courier New" ) ;
  213. hOldFont2 =(HFONT)::SelectObject( dc , hFont2 ) ;
  214. //-----------------------------------------------------------------------------//
  215. //得到桌面窗口的宽度与高度
  216. RECT rectOfDesktop ;
  217. GetWindowRect( GetDesktopWindow() , &rectOfDesktop ) ;
  218. DWORD WidthHeight ; //字符串的宽度与高度
  219. int nLineHeight ; //一行高度
  220. WidthHeight =GetHzTextExtent( dc , lpsStr , nLen ) ;
  221. nLineHeight =HIWORD( WidthHeight ) ; //一行的高度
  222. //--------------------------------------------------------------------------------//
  223. //hint缓冲区
  224. // char sHintBuff[MAX_HINT_LINE][MAX_HINT_CHAR+1] ;
  225. int nHintLineNum =0 ; //hint行数
  226. int nHintCharNum =0 ; //HINT中一行的字节数
  227. int nMaxWidth =0 ; //HINT窗口中内容的最大宽度
  228. //得到原单词的内容
  229. int nLineWidth ; //一行宽度
  230. int nSourceWordFlag=1 ; //原来单词标记
  231. for( int i=0 ; i<nLen ; )
  232. {
  233. nLineWidth =LOWORD(  //该行宽度
  234. GetHzTextExtent( dc , sHintBuff[nHintLineNum] , nHintCharNum ) ) ;
  235. if( i<nLen-1 ) //至少还有一个字符
  236. {
  237. if( (BYTE)lpsStr[i] & 0x80 ) //是一个汉字
  238. {
  239. if( nHintCharNum > MAX_HINT_CHAR-2 ||//至少能放两字节
  240. nLineWidth+LOWORD( GetHzTextExtent( dc , lpsStr+i , 2 ) ) +
  241. TIP_WIDTH+TIP_WIDTH+SHADOW_WIDTH>=
  242. rectOfDesktop.right/2 ) //宽度不超过屏幕宽度一半
  243. { //一行结束,另起一行
  244. if( nLineWidth > nMaxWidth ) //宽度超过最大宽度
  245. nMaxWidth =nLineWidth ; //记录最大宽度
  246. sHintBuff[nHintLineNum][nHintCharNum] ='' ; //结束标记
  247. nHintLineNum++ ;
  248. if( nHintLineNum >= MAX_HINT_LINE || //行数到头了
  249.  (nHintLineNum+1)*nLineHeight+TIP_HEIGHT+
  250.  3*SHADOW_HEIGHT>=rectOfDesktop.bottom/2 ) //高度超过屏幕高度一半
  251. break ;
  252. nHintCharNum =0 ; //该行字符数为0
  253. }
  254. //记录该汉字
  255. sHintBuff[nHintLineNum][nHintCharNum++] =lpsStr[i++] ;
  256. sHintBuff[nHintLineNum][nHintCharNum++] =lpsStr[i++] ;
  257. continue ;
  258. }
  259. if( (lpsStr[i]=='r' && lpsStr[i+1]=='n') || //一行结束
  260.  (lpsStr[i]==';' && lpsStr[i+1]==' ' ) )
  261. {
  262. if( nLineWidth > nMaxWidth ) //宽度超过最大宽度
  263. nMaxWidth =nLineWidth ; //记录最大宽度
  264. sHintBuff[nHintLineNum][nHintCharNum] ='' ; //结束标记
  265. nHintLineNum++ ; //增加行数
  266. if( nHintLineNum >= MAX_HINT_LINE || //行数到头了
  267.  (nHintLineNum+1)*nLineHeight+TIP_HEIGHT+
  268.  3*SHADOW_HEIGHT>=rectOfDesktop.bottom/2 ) //高度超过屏幕高度一半
  269. break ;
  270. nHintCharNum =0 ; //该行字符数为0
  271. i++ ; //去掉这两个行结束符
  272. i++ ;
  273. continue ;
  274. }
  275. }
  276. if( (lpsStr[i] == ':' && nSourceWordFlag ) || //是原单词结束符
  277.  lpsStr[i] ==';' )
  278. {
  279. if( lpsStr[i] == ':' )
  280. nSourceWordFlag =0 ; //取消标记
  281. if( nLineWidth > nMaxWidth ) //宽度超过最大宽度
  282. nMaxWidth =nLineWidth ; //记录最大宽度
  283. sHintBuff[nHintLineNum][nHintCharNum] ='' ; //结束标记
  284. nHintLineNum++ ; //增加行数
  285. if( nHintLineNum >= MAX_HINT_LINE || //行数到头了
  286.  (nHintLineNum+1)*nLineHeight+TIP_HEIGHT+
  287.  3*SHADOW_HEIGHT>=rectOfDesktop.bottom/2 ) //高度超过屏幕高度一半
  288. break ;
  289. nHintCharNum =0 ; //该行字符数为0
  290. i++ ; //去掉该字符
  291. continue ;
  292. }
  293.         //是普通西文字符
  294. if( nHintCharNum > MAX_HINT_CHAR-1 ||//至少能放一字节
  295. nLineWidth+LOWORD( GetHzTextExtent( dc , lpsStr+i , 2 ) ) +
  296. TIP_WIDTH+TIP_WIDTH+SHADOW_WIDTH>=
  297. rectOfDesktop.right/2 ) //宽度不超过屏幕宽度一半
  298. { //一行结束,另起一行
  299. if( nLineWidth > nMaxWidth ) //宽度超过最大宽度
  300. nMaxWidth =nLineWidth ; //记录最大宽度
  301. sHintBuff[nHintLineNum][nHintCharNum] ='' ; //结束标记
  302. nHintLineNum++ ; //增加行数
  303. if( nHintLineNum >= MAX_HINT_LINE || //行数到头了
  304.  (nHintLineNum+1)*nLineHeight+TIP_HEIGHT+
  305.  3*SHADOW_HEIGHT>=rectOfDesktop.bottom/2 ) //高度超过屏幕高度一半
  306. break ;
  307. nHintCharNum =0 ; //该行字符数为0
  308. }
  309. //记录该字符
  310. sHintBuff[nHintLineNum][nHintCharNum++] =lpsStr[i++] ;
  311. }
  312. if( i==nLen ) //扫遍所有字符
  313. {
  314. nLineWidth =LOWORD(  //该行宽度
  315. GetHzTextExtent( dc , sHintBuff[nHintLineNum] , nHintCharNum ) ) ;
  316. if( nLineWidth > nMaxWidth ) //宽度超过最大宽度
  317. nMaxWidth =nLineWidth ; //记录最大宽度
  318. sHintBuff[nHintLineNum][nHintCharNum] ='' ; //结束标记
  319. nHintLineNum++ ; //加上最后一行
  320. }
  321. //-------------------------------------------------------------------------------//
  322. //计算显示窗口的宽度与高度,包括阴影
  323. int nWidth =nMaxWidth+TIP_WIDTH*2+SHADOW_WIDTH ;
  324. int nHeight =nHintLineNum*nLineHeight+TIP_HEIGHT+
  325. SHADOW_HEIGHT*3 ;
  326. //计算显示位置
  327. int nXFlag =0 ;
  328. int nYFlag =0 ;
  329. if( nXStart > rectOfDesktop.right-nWidth ) //超过屏幕了
  330. {
  331. nXStart -=nWidth ; //X反向
  332. nXFlag =1 ;
  333. }
  334. if( nYStart > rectOfDesktop.bottom-nHeight )
  335. {
  336. POINT cursorPos ; //鼠标位置
  337. GetCursorPos( &cursorPos ) ;
  338. nYStart =cursorPos.y - nHeight - 
  339. GetSystemMetrics( SM_CYCURSOR )/3  ; //光标高度一半
  340. nYFlag =1 ;
  341. }
  342. //设置窗口大小与位置
  343. SetWindowPos( p_hHintWnd , HWND_TOPMOST , nXStart , nYStart , 
  344. nWidth , nHeight , 
  345.                             SWP_NOACTIVATE | SWP_SHOWWINDOW ) ;
  346. //---------------------------------------------------------------------------------//                             
  347. //设置笔与画刷
  348. HPEN hBlackPen =CreatePen( PS_SOLID , 0 , RGB( 0 , 0 , 0 ) ) ; //黑笔 ;
  349. HBRUSH hYellowBrush =CreateSolidBrush( RGB( 255 , 255 , 150 ) ) ; //黄刷
  350. HBRUSH hShadowBrush =CreateSolidBrush( RGB( 128,128,128));//165,165,165));//111,111,0 ) ) ; //阴影刷子
  351. HPEN pOldPen ;
  352. HBRUSH pOldBrush ;
  353. //设置笔与画刷
  354. pOldPen =(HPEN)::SelectObject( dc , hBlackPen ) ;
  355. pOldBrush =(HBRUSH)::SelectObject( dc , hShadowBrush ) ; //阴影刷子
  356. //画一个矩形阴影
  357. int nX , nY , nX1 , nY1 ;
  358. if( nXFlag ) //X反向了
  359. {
  360. nX =0 ;
  361. nX1 =nWidth-SHADOW_WIDTH ;
  362. }
  363. else
  364. {
  365. nX =SHADOW_WIDTH ;
  366. nX1 =nWidth ;
  367. }
  368. if( nYFlag ) //Y反向了
  369. {
  370. nY =0 ;
  371. nY1 =nHeight-TIP_HEIGHT-SHADOW_HEIGHT ;
  372. }
  373. else
  374. {
  375. nY =TIP_HEIGHT+SHADOW_HEIGHT ;
  376. nY1 =nHeight ;
  377. }
  378. Rectangle( dc , nX , nY , nX1 , nY1 ) ;
  379. POINT points[5] ; //HINT窗口的五个顶点
  380. if( nXFlag ) //X反向了
  381. {
  382. points[0].x =nWidth-1 ;
  383. points[1].x =nWidth-TIP_WIDTH ;
  384. points[2].x =SHADOW_WIDTH ;
  385. points[3].x =SHADOW_WIDTH ;
  386. points[4].x =nWidth-1 ;
  387. }
  388. else
  389. {
  390. points[0].x =0 ;
  391. points[1].x =TIP_WIDTH ;
  392. points[2].x =nWidth-SHADOW_WIDTH ;
  393. points[3].x =nWidth-SHADOW_WIDTH ;
  394. points[4].x =0 ;
  395. }
  396. if( nYFlag ) //Y反向了
  397. {
  398. points[0].y =nHeight ;
  399. points[1].y =nHeight-TIP_HEIGHT ;
  400. points[2].y =nHeight-TIP_HEIGHT ;
  401. points[3].y =SHADOW_HEIGHT ;
  402. points[4].y =SHADOW_HEIGHT ;
  403. }
  404. else
  405. {
  406. points[0].y =0 ;
  407. points[1].y =TIP_HEIGHT ;
  408. points[2].y =TIP_HEIGHT ;
  409. points[3].y =nHeight-SHADOW_HEIGHT ;
  410. points[4].y =nHeight-SHADOW_HEIGHT ;
  411. }
  412. ::SelectObject( dc , hYellowBrush ) ; //HINT窗口刷子
  413. Polygon( dc , points , 5 ) ; //HINT窗口
  414. //显示翻译结果
  415. int nOldBkMode =SetBkMode( dc , TRANSPARENT ) ;
  416. COLORREF oldColor =SetTextColor( dc , RGB( 0 , 0 , 0 ) ) ;
  417. if( nXFlag ) //X反向了
  418. nX =SHADOW_WIDTH+TIP_WIDTH ;
  419. else
  420. nX =TIP_WIDTH ;
  421. if( nYFlag ) //Y反向了
  422. nY =SHADOW_HEIGHT*2 ;
  423. else
  424. nY =TIP_HEIGHT+SHADOW_HEIGHT ;
  425.     
  426.     HFONT hOldFont1 ;
  427. for( i=0 ; i<nHintLineNum ; i++ )
  428. {
  429. nLineWidth =_fstrlen( sHintBuff[i] ) ;
  430. if( sHintBuff[i][0]=='[' && sHintBuff[i][nLineWidth-1]==']' )
  431. {
  432. //是音标
  433. hOldFont1 =(HFONT)::SelectObject( dc , hFont1 ) ;
  434. TextOutString( dc , nX , nY , sHintBuff[i] , nLineWidth ) ;
  435. SelectObject( dc , hOldFont1 ) ;
  436. }
  437. else
  438. TextOutString( dc , nX , nY , sHintBuff[i] , nLineWidth ) ;
  439. nY +=nLineHeight ;
  440. }
  441. SetTextColor( dc , oldColor ) ;
  442. SetBkMode( dc , nOldBkMode ) ;
  443. //恢复笔与画刷   
  444. SelectObject( dc , pOldPen ) ;
  445. SelectObject( dc , pOldBrush ) ;
  446. DeleteObject( hBlackPen ) ;
  447. DeleteObject( hShadowBrush ) ;
  448. DeleteObject( hYellowBrush ) ;
  449. SelectObject( dc , hOldFont2 ) ;
  450. DeleteObject( hFont1 ) ;
  451. DeleteObject( hFont2 ) ;
  452. ReleaseDC( p_hHintWnd , dc ) ;
  453. }