Srhword.c
上传用户:chzmdj
上传日期:2007-01-22
资源大小:135k
文件大小:34k
源码类别:

源码/资料

开发平台:

C/C++

  1. //**************************************************************
  2. // SrhWord.C 
  3. //
  4. // Copyright 1997 by ITC, PCB. All rights reserved.
  5. //
  6. // Author:        FengShuen Lu / Gang Fang / Gang Yan
  7. //
  8. // Date:          1997.5.30
  9. //
  10. // Description:   用於在打字/用字中取得指定位置处的单词,并返回光标位置.
  11. //              
  12. // Function:   
  13. //                LibMain()       : 该函数在 DLL 被 LOAD 时被自动调用,用於初始化数据·
  14. //                DllEntryPoint() : 该函数在 DLL 被 LOAD 时被自动调用,用於初始化Thunk过程·
  15. //                WEP()           : 该函数在 DLL 被释放时被自动调用·
  16. //
  17. // Notes:
  18. //
  19. // Update:
  20. //
  21. //  Date       Name         Description
  22. // =======    ======       ====================================
  23. // 97.5.30    闫  刚        version 1.0.
  24. //   
  25. // 97.11.13   闫  刚        将打字用字与查字合并·
  26. //                          主要是由於在实现32为拦截 API 後,对 IE4 等 UNICODE 
  27. //                          的代码不需要特殊处理,同时需要将打字/用字与查字切词的
  28. //                          代码进行统一·
  29. //                          主要改动师注册一个消息,用於在 FINDWORD.C 中在得到单
  30. //                          词後向查字助理发消息,以进行显示·
  31. //
  32. //                          由於不清楚在以後的版本中是否保留查字助理,所以与查字
  33. //                          助理有关的代码均进行条件编译,受 _DICTING_ 宏控制·
  34. //
  35. // 97.11.18   闫  刚        修改对 TA_CENTER 方式计算有误的BUG.
  36. //
  37. //**************************************************************
  38. #include <windows.h>
  39. #include <string.h>
  40. #include <assert.h>
  41. #include "srhword.h"
  42. #include "findword.h"
  43. #include "hookapi.h"
  44. #include "..pub3216.h"
  45. #ifdef _DEBUG
  46. #include "DbgFunc.h"
  47. #endif //_DEBUG
  48. // 定义 Thunk 中 16 位与 32 位 DLL 名·
  49. #define DLL32NAME "NHW32.DLL"
  50. #define DLL16NAME "NHW16.DLL"
  51. // API 拦截结构·
  52. // Gdi!TextOut
  53. APIHOOKSTRUCT g_TextOutHook = {
  54. "GDI", // The module name that the api in it.
  55. "TextOut", // The api name that it will be hooked.
  56. 0,
  57. NULL, // This api point.
  58. {0, 0, 0, 0, 0}, // Use to record five byte at begin of api.
  59. // these data is get from this program. 
  60. // the system may be already run the other 
  61. // program that these program change api too.
  62. NULL, // The module name that the hook api in it.
  63. "BlTextOut", // The hook api name that it will replace the api.
  64. NULL, // This hook api point.
  65. {0, 0, 0, 0, 0}, // Use to record five byte at begin of api.
  66. // these data is get from this program. 
  67. // the system may be already run the other 
  68. // program that these program change api too.
  69. 0,
  70. // Use to record five byte at begin of api.
  71. // these data is get from WINICE. it is pure.
  72. // Used when the BLIEA restart when BLIEA abort,
  73. // Use to restore this api data.
  74. {0X55, 0X8B, 0XEC, 0X68, 0XB7}
  75.   };
  76. // Gdi!ExtTextOut
  77. APIHOOKSTRUCT g_ExtTextOutHook = {
  78. "GDI",
  79. "ExtTextOut",
  80. 0,
  81. NULL,
  82. {0, 0, 0, 0, 0},
  83. NULL,
  84. "BlExtTextOut",
  85. NULL,
  86. {0, 0, 0, 0, 0},
  87. 0,
  88. {0xb8, 0xe7, 0x05, 0x45, 0x55}
  89.  };
  90. // Gdi!BitBlt
  91. // 由於有关 Text 的输出是采用先向 MemDC 中输出,在采用 BitBlt 输出到屏幕·
  92. // 因此需要拦截 BitBlt 来得到窗口与屏幕关连的 DC 的有关信息·
  93. APIHOOKSTRUCT g_BitBltHook = {
  94. "GDI",
  95. "BitBlt",
  96. 0,
  97. NULL,
  98. {0, 0, 0, 0, 0},
  99. NULL,
  100. "BLBitBlt",
  101. NULL,
  102. {0, 0, 0, 0, 0},
  103. 0,
  104. {0x55, 0x8b, 0xec, 0xb8, 0xf2}
  105.  };
  106. // 该函数在 16 位系统中属於未公开函数·
  107. WINDOWFROMDC_PROC WindowFromDC = NULL;
  108. // 完整词数据结构·
  109. int  g_nCurrWindowVer = CHINESE_PRC; // 用於记录当前语言种类,主要用於分别简体中文和反体中文·
  110. // 暂时不用·
  111. char g_szTotalWord[BUFFERLENGTH] = ""; // 完整词记录缓冲区·
  112. // 用於记录分几次输出的单词·
  113. RECT g_TotalWordRect; // 用於记录完整词的区域大小·
  114. int  g_CharType = CHAR_TYPE_OTHER; // 用於记录完整词的类型·
  115. // 在程序中主要用於判别新加入的串的类型是否予以有的单词类型相同·
  116. int  g_nCurCaretPlaceInTotalWord = -1; // 用於记录光标在完整词中的位置·
  117. int  g_bMouseInTotalWord = FALSE; // 用於记录光标是否在完整词中·
  118. // 在程序中该标示主要用於判断是否需要清空buffer.
  119. // 完整词数据结构·
  120. // 当前词数据结构·( 当前词:为由输入缓冲区中切出的单词 )
  121. char g_szCurWord[WORDMAXLEN] = ""; // 当前词缓冲区·
  122. RECT g_CurWordRect; // 记录当前词区域·
  123. int  g_nCurCaretPlace; // 记录当前光标位置·
  124. // 当前词数据结构·
  125. // 记录与 MemDC 有关的信息·
  126. // 由於有关 Text 的输出是采用先向 MemDC 中输出,在采用 BitBlt 输出到屏幕·
  127. // 因此需要将 Text 的所有信息全部记录·
  128. char szMemDCWordBuff[BUFFERLENGTH] = ""; // 用於记录所有 MemDC 中的 Text 文本·
  129. int  pnMemDCCharLeft[BUFFERLENGTH]; // 用於记录在 TextOut 中所有字的左相对值·
  130. int  pnMemDCCharRight[BUFFERLENGTH]; // 用於记录在 TextOut 中所有字的右相对值·
  131. WORDPARA WordBuffer[MEMDC_MAXNUM]; // 用於记录在 TextOut 中切词後所有词的信息·
  132. int nWordNum = 0; // 记录 MemDC 中单词的个数·
  133. // 记录与 MemDC 有关的信息·
  134. BOOL  g_bAllowGetCurWord = FALSE; // 是否取词判断标志,在 UnHook 没有成功时起作用·
  135. HWND  g_hNotifyWnd = NULL; // 记录取词所要通知的窗口句柄·
  136. POINT g_CurMousePos; // 记录当前光标位置·
  137. UINT         g_nTextAlign;
  138. DWORD        g_dwDCOrg;
  139. int          g_nExtra;
  140. POINT        g_CurPos;
  141. TEXTMETRIC   g_tm;
  142. ///////////////////////////////////////////////////////////////////////////
  143. // Modify by Yan/Gang 1997/11/18
  144. // 用於修改在计算 TA_CENTER 情况的失误。
  145. BOOL bRecAllRect = FALSE;
  146. RECT g_rcTotalRect;
  147. // End Modify
  148. ///////////////////////////////////////////////////////////////////////////
  149. //Added by XGL,Sep 29th,1998
  150. RECT g_rcFirstWordRect; // contains the rect of first word of phrase
  151. //Adding ends.
  152. ///////////////////////////////////////////////////////////////////////////
  153. #ifdef _DICTING_
  154. ///////////////////////////////////////////////////////////////////////////
  155. // Add by Yan/Gang   11/13/1997
  156. // 用於向查字助理通知取得所需要的单词·
  157. UINT BL_HASSTRING;
  158. // Add end.
  159. ///////////////////////////////////////////////////////////////////////////
  160. #endif
  161. #ifdef _DICTING_
  162. /////////////////////////////////////////////////////////////////////////////////
  163. // Modify by Yan/Gang 1997/11/19
  164. // 主要解决通配符的问题。
  165. int g_nGetWordStyle;
  166. // End Add.
  167. /////////////////////////////////////////////////////////////////////////////////
  168. //Added by XGL, Sep 17th, 1998
  169. int g_nWordsInPhrase = -1 ; //current word number in phrase
  170. BOOL g_bPhraseNeeded = FALSE ; //GETPHRASE_D(or TW)_ENABLE defined
  171. int g_nPhraseCharType = CHAR_TYPE_OTHER ;
  172. //Adding ends
  173. #endif
  174. BOOL FAR PASCAL __export DllEntryPoint (DWORD dwReason,
  175. WORD  hInst,
  176. WORD  wDS,
  177. WORD  wHeapSize,
  178. DWORD dwReserved1,
  179. WORD  wReserved2);
  180. BOOL FAR PASCAL thk_ThunkConnect16(LPSTR pszDll16,
  181.    LPSTR pszDll32,
  182.    WORD  hInst,
  183.    DWORD dwReason);
  184. HANDLE ghDLLInst;
  185. //*********************************************************************
  186. // Name :          LibMain()
  187. //
  188. // Descriptions:   该函数在 DLL 被 LOAD 时被自动调用,用於初始化数据·
  189. //
  190. // Arguments :     HINSTANCE   hinst       : Identifies the instance of the DLL. 
  191. //                 WORD        wDataSeg    : Specifies the value of the data segment 
  192. //                                           (DS) register. 
  193. //                 WORD        cbHeapSize  : Specifies the size of the heap defined
  194. //                                           in the module-definition file. 
  195. //                                           (The LibEntry routine in LIBENTRY.OBJ 
  196. //                                           uses this value to initialize the local heap.) 
  197. //                 LPSTR       lpszCmdLine : Points to a null-terminated string specifying 
  198. //                                           command-line information. This parameter is 
  199. //                                           rarely used by DLLs. 
  200. //
  201. // Return :        int   : The function should return 1 if it is successful. Otherwise, it should return 0.
  202. //
  203. // Notes :
  204. //
  205. // Update:
  206. //
  207. //  Date       Name         Description
  208. // =======    ======       ====================================
  209. // 97.5.30    闫  刚        version 1.0.
  210. //   
  211. // 97.11.13   闫  刚        加入一个注册消息·
  212. //
  213. //*********************************************************************
  214. int CALLBACK LibMain(HINSTANCE hInst,
  215.  WORD wDataSeg,
  216.  WORD cbHeapSize,
  217.  LPSTR lpszCmdLine)
  218. {
  219. HMODULE hUser16;
  220.                 
  221. // 得到 WindowFromDC 函数的句柄·
  222. hUser16 = LoadLibrary("USER.EXE");
  223. if (hUser16 != NULL)
  224. {
  225. WindowFromDC = (WINDOWFROMDC_PROC)GetProcAddress(hUser16, "WINDOWFROMDC");
  226. }
  227. else
  228. {
  229. WindowFromDC = NULL;
  230. }
  231. // 初始化数据·
  232. ghDLLInst = hInst;
  233. g_nCurCaretPlace = -1;
  234. g_CurMousePos.x  = 0;
  235. g_CurMousePos.y  = 0;
  236. g_TextOutHook.hInst    = hInst;
  237. g_ExtTextOutHook.hInst = hInst;
  238. g_BitBltHook.hInst     = hInst;
  239. #ifdef _DICTING_
  240. ///////////////////////////////////////////////////////////////////////////
  241. // Add by Yan/Gang   11/13/1997
  242. // 用於向查字助理通知取得所需要的单词·
  243. BL_HASSTRING = RegisterWindowMessage(MSG_HASSTRINGNAME);
  244. // Add end.
  245. ///////////////////////////////////////////////////////////////////////////
  246. #endif
  247. // HookAllTextOut();
  248. return (int)1;
  249. }                                        
  250. //*********************************************************************
  251. // Name :          DllEntryPoint()
  252. //
  253. // Descriptions:   该函数在 DLL 被 LOAD 时被自动调用,用於初始化 Thunk 过程·
  254. //
  255. // Notes :
  256. //
  257. // Update:
  258. //
  259. //*********************************************************************
  260. BOOL FAR PASCAL __export DllEntryPoint (DWORD dwReason,
  261. WORD  hInst,
  262. WORD  wDS,
  263. WORD  wHeapSize,
  264. DWORD dwReserved1,
  265. WORD  wReserved2)
  266. {
  267. // 初始化 Thunk 过程·
  268. if (!thk_ThunkConnect16(DLL16NAME,
  269. DLL32NAME,
  270. hInst,
  271. dwReason))
  272. {
  273. return FALSE;
  274. }
  275. return TRUE;
  276. }
  277. //*********************************************************************
  278. // Name :          WEP()
  279. //
  280. // Descriptions:   该函数在 DLL 被释放时被自动调用·
  281. //
  282. // Arguments :     int nExitType : Specifies whether all of Windows is shutting 
  283. //                                 down or only the individual library. This 
  284. //                                 parameter can be either WEP_FREE_DLL or 
  285. //                                 WEP_SYSTEM_EXIT. 
  286. //
  287. // Return :        int   : The function should return 1 if it is successful. Otherwise, it should return 0.
  288. //
  289. //  Date       Name         Description
  290. // =======    ======       ====================================
  291. // 97.5.30    闫  刚        version 1.0.
  292. //
  293. //*********************************************************************
  294. int CALLBACK WEP(int nExitType)
  295. {
  296. int i = 16 ;
  297.         UnHookAllTextOut();    
  298. #ifdef _DEBUG        
  299. DbgPrintf("This is %d bit dll", i) ;
  300. #endif
  301.         return 1;
  302. }
  303. // Use to set current language sytle.
  304. // Because file version functions do not work well in 16bit file.
  305. // So I get language version in 32bit file. and then use thunk to send item 
  306. // to 16 bit.
  307. DWORD FAR PASCAL _export BL_SetVer16(int nLangVer)
  308. {
  309.         g_nCurrWindowVer = nLangVer;
  310.         return BL_OK;
  311. }
  312. /////////////////////////////////////////////////////////////////////////////////
  313. // Add by Yan/Gang 1997/11/19
  314. // 主要解决通配符的问题。
  315. DWORD FAR PASCAL _export BL_SetGetWordStyle(int nGetWordStyle)
  316. {
  317. #ifdef _DICTING_
  318. g_nGetWordStyle = nGetWordStyle;
  319. //Added by XGL, Sep 17th,1997
  320. //if phrase was required
  321. if (nGetWordStyle == GETPHRASE_ENABLE)
  322. {
  323. g_nWordsInPhrase = -1 ;
  324. g_bPhraseNeeded = TRUE ;
  325. }
  326. else
  327. {
  328. g_nWordsInPhrase = -1 ;
  329. g_bPhraseNeeded = FALSE ;
  330. }
  331. //Adding ends.
  332. #endif
  333. return 0L;
  334. }
  335. // End Add.
  336. /////////////////////////////////////////////////////////////////////////////////
  337. // Use to record some parament. include wnd rect. and reset buffer.    
  338. DWORD FAR PASCAL _export BL_SetPara16(short hNotifyWnd, short MouseX, short MouseY)
  339. {
  340.         g_hNotifyWnd    = hNotifyWnd;
  341.         g_CurMousePos.x = MouseX;
  342.         g_CurMousePos.y = MouseY;
  343.         return BL_OK;
  344. }
  345. DWORD FAR PASCAL _export BL_GetBuffer16(LPSTR lpszBuffer, short nBufferSize, LPWORDRECT lpWr)
  346. {
  347.         int len;
  348. char* pcFirstSpacePos = NULL ; //position of first space
  349. char* pcTemp = NULL ;
  350. int nSrc = 0, nDest = 0 ;
  351.     
  352.         if (!g_bMouseInTotalWord)
  353.         {
  354. #ifdef _DEBUG
  355.         DbgPrintf("NhWSrh.DLL          GetBuffer: Caret not in word, clear buffer.");
  356. #endif
  357.                 g_szTotalWord[0] = 0x00;
  358.                 g_nCurCaretPlaceInTotalWord = -1;
  359.     }
  360.         if ((len = strlen(g_szTotalWord)) >= nBufferSize)
  361.         {
  362.                 len = nBufferSize - 1;
  363.         }  
  364. //Modified by XGL, Oct 28th, 1998
  365. //In IE4, cannot get correct Chinese word,
  366. //so we have to use former version for Chinese word
  367. /* //Added by XGL, Sep 29th, 1998
  368. if (g_nPhraseCharType == CHAR_TYPE_HZ)
  369. {
  370. //get the word before the first space
  371. if (pcFirstSpacePos = strchr(g_szTotalWord, ' '))
  372. {
  373. len = pcFirstSpacePos - g_szTotalWord ;
  374. }
  375. }
  376. */
  377. //remove tail space(s)
  378. while ((g_szTotalWord[len - 1] == ' ') && (len > 0))
  379. {
  380. len-- ;
  381. g_szTotalWord[len] == 0x00 ;
  382. }
  383. //Adding ends.
  384. //Modified by xgl, Oct 26th, 1998
  385. //for English, we combine spaces between words to one
  386. //we do it by copying chars one by one
  387. //strncpy will no longer be used
  388. if (g_szTotalWord[0] < 0)
  389. {
  390. strncpy(lpszBuffer, g_szTotalWord, len);
  391. lpszBuffer[len] = 0x00;
  392. lpWr->left   = g_TotalWordRect.left;
  393. lpWr->right  = g_TotalWordRect.right;
  394. lpWr->top    = g_TotalWordRect.top;
  395. lpWr->bottom = g_TotalWordRect.bottom;
  396. }
  397. else
  398. {
  399. if (g_szTotalWord[0] == ' ')
  400. {
  401. //this conditions should not happen.
  402. strncpy(lpszBuffer, g_szTotalWord, len);
  403. lpszBuffer[len] = 0x00;
  404. }
  405. else
  406. {
  407. while (nSrc < len)
  408. {
  409. lpszBuffer[nDest] = g_szTotalWord[nSrc] ;
  410. nDest++ ;
  411. nSrc++ ;
  412. if (g_szTotalWord[nSrc] == ' ' && nSrc < len)
  413. {
  414. lpszBuffer[nDest] = g_szTotalWord[nSrc] ;
  415. nDest++ ;
  416. nSrc++ ;
  417. while (g_szTotalWord[nSrc] == ' ' && nSrc < len)
  418. {
  419. nSrc++ ;
  420. }
  421. }
  422. }
  423. }
  424. //strncpy(lpszBuffer, g_szTotalWord, len);
  425. lpszBuffer[len] = 0x00;
  426. lpWr->left   = g_rcFirstWordRect.left;
  427. lpWr->right  = g_rcFirstWordRect.right;
  428. lpWr->top    = g_rcFirstWordRect.top;
  429. lpWr->bottom = g_rcFirstWordRect.bottom;
  430. }
  431.         //Modification ends. xgl, Oct 26th, 1998
  432. #ifdef _DEBUG
  433. //        DbgPrintf("NhWSrh.DLL          g_szCurWord: %s", g_szCurWord);
  434. //        DbgPrintf("NhWSrh.DLL          Rect l: %d, r: %d, t: %d, b: %d",
  435. //                          g_CurWordRect.left,
  436. //                          g_CurWordRect.right,
  437. //                          g_CurWordRect.top,
  438. //                          g_CurWordRect.bottom);
  439.         DbgPrintf("NhWSrh.DLL          return caret place: %d", g_nCurCaretPlaceInTotalWord);
  440.         DbgPrintf("NhWSrh.DLL          g_szTotalWord: %s", g_szTotalWord);
  441.         DbgPrintf("NhWSrh.DLL          Rect l: %d, r: %d, t: %d, b: %d",
  442.                           g_TotalWordRect.left,
  443.                           g_TotalWordRect.right,
  444.                           g_TotalWordRect.top,
  445.                           g_TotalWordRect.bottom);
  446. #endif
  447. #ifdef _DEBUG
  448.         DbgPrintf("NhWSrh.DLL ***************** End *****************************");
  449. #endif
  450.         return (DWORD)g_nCurCaretPlaceInTotalWord;    
  451. }
  452. // Hook TextOut and TextOutEx.
  453. DWORD FAR PASCAL _export BL_HookWinApi16()
  454. {
  455.         g_nCurCaretPlace = -1;
  456.         g_szCurWord[0] = 0x00;
  457.         g_szTotalWord[0] = 0x00;
  458.         g_nCurCaretPlaceInTotalWord = -1;
  459.         g_CharType = CHAR_TYPE_OTHER;
  460.         g_bMouseInTotalWord = FALSE;
  461.         g_bAllowGetCurWord = TRUE;
  462.         
  463.         nWordNum = 0;
  464.         szMemDCWordBuff[0] = 0x00;
  465.         
  466.         HookAllTextOut();
  467.         
  468.         return BL_OK;
  469. }
  470. // UnHook TextOut and TextOutEx.
  471. DWORD FAR PASCAL _export BL_UnHookWinApi16()
  472. {
  473.         g_bAllowGetCurWord = FALSE;
  474.         UnHookAllTextOut();
  475.                 
  476.         return BL_OK;
  477. }
  478. BOOL bHooked = FALSE;
  479. // Use to hook "TextOut" and "ExtTextOut"
  480. void HookAllTextOut()
  481. {
  482. #ifdef _DEBUG
  483.         DbgPrintf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`hookn");
  484. #endif
  485. if (bHooked)
  486. {
  487. return;
  488. }
  489.         bHooked = TRUE;
  490.         HookWinApi(&g_BitBltHook, HOOKANDBACK);
  491.         HookWinApi(&g_TextOutHook, HOOKANDBACK);
  492.         HookWinApi(&g_ExtTextOutHook, HOOKANDBACK);
  493. }
  494. // Use to restore "TextOut" and "ExtTextOut"
  495. void UnHookAllTextOut()
  496. {
  497. #ifdef _DEBUG
  498. DbgPrintf("|~~~~~~~~~~~~~~~~~~~~~~~unhook~~~~~~~~~n") ; 
  499. #endif
  500.         RestoreWinApi(&g_TextOutHook);
  501.         RestoreWinApi(&g_ExtTextOutHook);
  502.         RestoreWinApi(&g_BitBltHook);
  503.         bHooked = FALSE;
  504. }
  505. BOOL WINAPI _export BLTextOut(HDC hDC,int x,int y,LPCSTR lpStr,int cbLen)
  506. POINT pt ;
  507. HWND  hWDC ;
  508. HWND  hWPT ;
  509. #ifdef _DEBUG
  510.         DbgPrintf("NhWSrh.DLL     BLTextOut Begin");
  511.         DbgPrintf("NhWSrh.DLL     BLTextOut hDC: %d", hDC);
  512.         DbgPrintf("NhWSrh.DLL     BLTextOut hDC: %d, x: %d, y: %d, cbLen: %d", 
  513.            hDC,
  514.            x,
  515.            y,
  516.            cbLen);
  517. #endif
  518.         // restore the old textout.
  519.         RestoreWinApi(&g_TextOutHook);
  520. //Added by XGL, Nov 3rd, 1998
  521. //We cannot get corret word with Explorer as background window
  522. //in Windows98, so this situation must be dealt with.
  523. pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y ;
  524. hWDC = WindowFromDC(hDC) ;
  525. hWPT = WindowFromPoint(pt) ;
  526. if (hWDC == NULL || hWPT == hWDC
  527. || IsParentOrSelf(hWPT, hWDC)
  528. || IsParentOrSelf(hWDC, hWPT))
  529. {
  530. //Adding ends. XGL, Nov 3rd, 1998
  531.         if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpStr, cbLen)) && (cbLen > 0))
  532.         {
  533.                 g_nTextAlign = GetTextAlign(hDC);
  534.                 g_nExtra     = GetTextCharacterExtra(hDC);
  535.                 GetCurrentPositionEx(hDC, &g_CurPos);
  536.                 GetTextMetrics(hDC, &g_tm);
  537.         
  538. ///////////////////////////////////////////////////////////////////////////
  539. // Modify by Yan/Gang 1997/11/18
  540. // 用於修改在计算 TA_CENTER 情况的失误。
  541. g_dwDCOrg = 0;
  542. bRecAllRect = FALSE;
  543. GetStringRect(hDC, (LPSTR)lpStr, cbLen, x, y, &g_rcTotalRect, NULL);
  544. bRecAllRect = TRUE;
  545. // End Modify
  546. ///////////////////////////////////////////////////////////////////////////
  547.                 if ((WindowFromDC != NULL)&&(WindowFromDC(hDC) == NULL))
  548.                 {
  549. #ifdef _DEBUG
  550.                         DbgPrintf("NhWSrh.DLL     BLTextOut WindowFromDC() = NULL, string add to TextOutBuffer");
  551.                         DbgLPCSTR("NhWSrh.DLL     BLTextOut ", (LPSTR)lpStr, cbLen, TRUE);
  552. #endif
  553.                         // 赋零,用於避免MEMDC对串位置的影响·
  554.                         g_dwDCOrg = 0;
  555.                         AddToTextOutBuffer(hDC, (LPSTR)lpStr, cbLen, x, y, NULL);
  556.                 }
  557.                 else
  558.                 {
  559. #ifdef _DEBUG
  560.                         DbgPrintf("NhWSrh.DLL     BLTextOut WindowFromDC() != NULL, string add to TextOutBuffer");
  561.                         DbgLPCSTR("NhWSrh.DLL     BLTextOut ", (LPSTR)lpStr, cbLen, TRUE);
  562. #endif
  563.                         g_dwDCOrg    = GetDCOrg(hDC);
  564.         
  565.                         GetCurMousePosWord(hDC, (LPSTR)lpStr, cbLen, x, y, NULL);
  566.                 }
  567.         }
  568.         else
  569.         {
  570. #ifdef _DEBUG
  571.         DbgPrintf("NhWSrh.DLL     BLTextOut ((!g_bAllowGetCurWord) || (IsBadReadPtr(lpStr, cbLen)) && (cbLen <= 0))");
  572.         if (!g_bAllowGetCurWord)
  573.         {
  574.          DbgPrintf("NhWSrh.DLL     BLTextOut !g_bAllowGetCurWord");
  575.         }
  576.         if (IsBadReadPtr(lpStr, cbLen))
  577.         {
  578.          DbgPrintf("NhWSrh.DLL     BLTextOut IsBadReadPtr()");
  579.         }
  580.         if (cbLen <= 0)
  581.         {
  582.         DbgPrintf("NhWSrh.DLL     BLTextOut cbLen <= 0");
  583.         }
  584. #endif
  585.     }
  586.     }
  587.         // call old textout.
  588.         TextOut(hDC, x, y, lpStr, cbLen);
  589.         HookWinApi(&g_TextOutHook, ONLYHOOK);
  590. #ifdef _DEBUG
  591.         DbgPrintf("NhWSrh.DLL     BLTextOut End");
  592. #endif
  593.         return (TRUE);
  594. }         
  595. BOOL WINAPI _export BLExtTextOut(HDC hDC,
  596.                                  int x,
  597.                                  int y,
  598.                                  UINT fuOpt,
  599.                                  const RECT FAR* lprc,
  600.                                  LPCSTR lpStr,
  601.                                  UINT cbLen,
  602.                                  int FAR* lpDx)
  603. {
  604. POINT pt ;
  605. HWND hWDC ;
  606. HWND hWPT ;
  607. #ifdef _DEBUG
  608.     DbgPrintf("NhWSrh.DLL     BLExtTextOut Begin");
  609.     DbgPrintf("NhWSrh.DLL     BLExtTextOut hDC: %d, x: %d, y: %d, fuOpt: %d, cbLen: %d", 
  610.            hDC,
  611.            x,
  612.            y,
  613.            fuOpt,
  614.            cbLen);
  615. #endif
  616.         // restore the old textout.
  617.         RestoreWinApi(&g_ExtTextOutHook);
  618.     
  619. //Added by XGL, Nov 3rd, 1998
  620. //We cannot get corret word with Explorer as background window
  621. //in Windows98, so this situation must be dealt with.
  622. pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y ;
  623. hWDC = WindowFromDC(hDC) ;
  624. hWPT = WindowFromPoint(pt) ;
  625. if (hWDC == NULL || hWPT == hWDC
  626. || IsParentOrSelf(hWPT, hWDC)
  627. || IsParentOrSelf(hWDC, hWPT))
  628. {
  629. //Adding ends. XGL, Nov 3rd, 1998
  630. if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpStr, cbLen)) && (cbLen > 0))
  631.         {
  632.                 g_nTextAlign = GetTextAlign(hDC);
  633.                 g_nExtra     = GetTextCharacterExtra(hDC);
  634.                 GetCurrentPositionEx(hDC, &g_CurPos);
  635.                 GetTextMetrics(hDC, &g_tm);
  636. ///////////////////////////////////////////////////////////////////////////
  637. // Modify by Yan/Gang 1997/11/18
  638. // 用於修改在计算 TA_CENTER 情况的失误。
  639. g_dwDCOrg = 0;
  640. bRecAllRect = FALSE;
  641. GetStringRect(hDC, (LPSTR)lpStr, cbLen, x, y, &g_rcTotalRect, lpDx);
  642. bRecAllRect = TRUE;
  643. // End Modify
  644. ///////////////////////////////////////////////////////////////////////////
  645.                 if ((WindowFromDC != NULL)&&(WindowFromDC(hDC) == NULL))
  646.                 {
  647. #ifdef _DEBUG
  648.                         DbgPrintf("NhWSrh.DLL     BLTextOut WindowFromDC() == NULL");
  649.                         DbgLPCSTR("NhWSrh.DLL     BLTextOut: ", (LPSTR)lpStr, cbLen, TRUE);
  650. #endif
  651.                         // 赋零,用於避免MEMDC对串位置的影响·
  652.                         g_dwDCOrg = 0;
  653.                         
  654.                         AddToTextOutBuffer(hDC, (LPSTR)lpStr, cbLen, x, y, lpDx);
  655.                 }
  656.                 else
  657.                 {
  658. #ifdef _DEBUG
  659.                         DbgPrintf("NhWSrh.DLL     BLTextOut WindowFromDC() != NULL");
  660.                         DbgLPCSTR("NhWSrh.DLL     BLTextOut: ", (LPSTR)lpStr, cbLen, TRUE);
  661. #endif
  662.                         g_dwDCOrg    = GetDCOrg(hDC);
  663.         
  664.                         GetCurMousePosWord(hDC, (LPSTR)lpStr, cbLen, x, y, lpDx);
  665.                 }
  666. }
  667. else
  668. {
  669. #ifdef _DEBUG
  670. DbgPrintf("NhWSrh.DLL     BLExtTextOut ((!g_bAllowGetCurWord) || (IsBadReadPtr(lpStr, cbLen)) && (cbLen <= 0))");
  671. if (!g_bAllowGetCurWord)
  672. {
  673. DbgPrintf("NhWSrh.DLL     BLExtTextOut !g_bAllowGetCurWord");
  674. }
  675. if (IsBadReadPtr(lpStr, cbLen))
  676. {
  677. DbgPrintf("NhWSrh.DLL     BLExtTextOut IsBadReadPtr()");
  678. }
  679. if (cbLen <= 0)
  680. {
  681. DbgPrintf("NhWSrh.DLL     BLExtTextOut cbLen <= 0");
  682. }
  683. #endif
  684. }
  685.     }
  686.         // call old textout.
  687.         ExtTextOut(hDC, x, y, fuOpt, lprc, lpStr, cbLen, lpDx);
  688.         HookWinApi(&g_ExtTextOutHook, ONLYHOOK);
  689. #ifdef _DEBUG
  690.         DbgPrintf("NhWSrh.DLL     BLExtTextOut End");
  691. #endif
  692.         return (TRUE);
  693. }         
  694. BOOL WINAPI _export BLBitBlt(HDC hdcDest,
  695.                              int nXDest,
  696.                              int nYDest,
  697.                              int nWidth,
  698.                              int nHeight,
  699.                              HDC hdcSrc,
  700.                              int nXSrc,
  701.                              int nYSrc,
  702.                              DWORD dwRop)
  703. {
  704.         int x, y;
  705. #ifdef _DEBUG
  706.         DbgPrintf("NhWSrh.DLL     BLBitBlt Begin");
  707. #endif
  708.         // restore the old textout.
  709.         RestoreWinApi(&g_BitBltHook);
  710.     
  711. #ifdef _DEBUG
  712.         DbgPrintf("NhWSrh.DLL     BitBlt: hdcDest: %d, hdcSrc: %d, nXDest: %d, nYDest, %d, nWidth: %d, nHeight: %d",
  713.                           hdcDest,
  714.                           hdcSrc,
  715.                           nXDest,
  716.                           nYDest,
  717.                           nWidth,
  718.                           nHeight);
  719. #endif
  720.         
  721.         if (nWidth > 5)
  722.         {
  723.                 g_dwDCOrg = GetDCOrg(hdcDest);
  724.                 x = LOWORD(g_dwDCOrg);
  725.                 y = HIWORD(g_dwDCOrg);
  726.                 x += nXDest;
  727.                 y += nYDest;
  728.                 g_dwDCOrg = MAKELONG(x, y);
  729.                 
  730.                 CheckMemDCWordBuffer(hdcDest, hdcSrc);
  731.         }
  732. else
  733. {
  734. #ifdef _DICTING_
  735. if (CheckDCWndClassName(hdcDest))
  736. {
  737. #ifdef _DEBUG
  738. DbgPrintf("NhWSrh.DLL          In IE4");
  739. #endif
  740.                 g_dwDCOrg = GetDCOrg(hdcDest);
  741.                 x = LOWORD(g_dwDCOrg);
  742.                 y = HIWORD(g_dwDCOrg);
  743.                 x += nXDest;
  744.                 y += nYDest;
  745.                 g_dwDCOrg = MAKELONG(x, y);
  746.                 
  747.                 CheckMemDCWordBuffer(hdcDest, hdcSrc);
  748. }
  749. #endif
  750. }
  751.         
  752.         // call old textout.
  753.         BitBlt(hdcDest, 
  754.                    nXDest, 
  755.                    nYDest, 
  756.                    nWidth, 
  757.                    nHeight, 
  758.                    hdcSrc, 
  759.                    nXSrc,
  760.                    nYSrc,
  761.                    dwRop);
  762.         HookWinApi(&g_BitBltHook, ONLYHOOK);
  763. #ifdef _DEBUG
  764.         DbgPrintf("NhWSrh.DLL     BLBitBlt End");
  765. #endif
  766.         return (TRUE);
  767. }         
  768. void FAR PASCAL _export Nh16_AddToTotalWord(LPSTR  szBuff,
  769.                         int    cbLen,
  770.                         int    nBegin,
  771.                         int    nEnd,
  772.                          int    nCharType,
  773.                           LPRECT lpStringRect,
  774.                           BOOL   bInCurWord,
  775.                           int    nCurCaretPlace)
  776. {
  777. #ifdef _DEBUG
  778. DbgPrintf("NhW16.dll       ExtTextOutW: %s", szBuff);
  779. DbgPrintf("NhW16.dll       ExtTextOutW: Rect l: %d, r: %d, t: %d, b: %d",
  780.   lpStringRect->left,
  781.   lpStringRect->right,
  782.   lpStringRect->top,
  783.   lpStringRect->bottom);
  784. DbgPrintf("NhW16.dll       ExtTextOutW: Mouse point : x: %d, y: %d",
  785. g_CurMousePos.x,
  786. g_CurMousePos.y);
  787. #endif
  788. g_nCurCaretPlace = nCurCaretPlace;
  789. AddToTotalWord(szBuff, cbLen, nBegin, nEnd, nCharType, *lpStringRect, bInCurWord);
  790. }
  791. int FAR PASCAL _export Nh16_GetTempLen()
  792. {
  793. #ifdef _DEBUG
  794. DbgPrintf("NhW16.dll       ExtTextOutW: Nh16_GetTempLen: %s", szMemDCWordBuff);
  795. #endif
  796. return strlen(szMemDCWordBuff);
  797. }
  798. BOOL FAR PASCAL _export Nh16_AddToTempBuff(LPSTR  szBuff,
  799.                        int    cbLen)
  800. {
  801. int  nLen;
  802. #ifdef _DEBUG
  803. DbgPrintf("NhW16.dll       ExtTextOutW: Nh16_AddToTempBuff: Before Add: %s", szMemDCWordBuff);
  804. #endif
  805. if (cbLen >= (int)(BUFFERLENGTH - strlen(szMemDCWordBuff) - 2))
  806. {
  807. // buffer too small.
  808. return FALSE;
  809. }
  810. // Write string to buffer.
  811. nLen = strlen(szMemDCWordBuff);
  812. strncpy(szMemDCWordBuff + nLen, szBuff, cbLen);
  813. szMemDCWordBuff[nLen + cbLen    ] = ' ';
  814. szMemDCWordBuff[nLen + cbLen + 1] = 0x00;
  815. #ifdef _DEBUG
  816. DbgPrintf("NhW16.dll       ExtTextOutW: Nh16_AddToTempBuff: after Add: %s", szMemDCWordBuff);
  817. #endif
  818. return TRUE;
  819. }                        
  820. BOOL FAR PASCAL _export Nh16_AddToWordStruct(int nBegin,
  821.  int nEnd,
  822.  HDC hMemDC, 
  823.  int CharType, 
  824.  LPRECT lpStringRect)
  825. {
  826. #ifdef _DEBUG
  827. int i;
  828. DbgPrintf("NhW16.dll       ExtTextOutW: Nh16_AddToWordStruct begin.");
  829. #endif
  830. //////////////////////////////////////////////////////////////
  831. // Modified by Yan/gang 1998.02.20
  832. // Reason: 
  833. //         It cause the system destroy when the user run "WBLASTER"
  834. //         The reason is the the array is overflow.
  835. //         The WordBuffer array size is MEMDC_MAXNUM.
  836. //         But it's point (nWordNum) is large than MEMDC_MAXNUM,
  837. //         also, nWordNum is small than MAXNUM.
  838. // if (nWordNum >= MAXNUM)
  839. if (nWordNum >= MEMDC_MAXNUM)
  840. return FALSE;
  841. // Modify end.
  842. //////////////////////////////////////////////////////////////
  843. WordBuffer[nWordNum].nBegin = nBegin;
  844. WordBuffer[nWordNum].nEnd   = nEnd;
  845. WordBuffer[nWordNum].hMemDC = hMemDC;
  846. WordBuffer[nWordNum].CharType = CharType;
  847. WordBuffer[nWordNum].wordRect.left   = lpStringRect->left;
  848. WordBuffer[nWordNum].wordRect.right  = lpStringRect->right;
  849. WordBuffer[nWordNum].wordRect.top    = lpStringRect->top;
  850. WordBuffer[nWordNum].wordRect.bottom = lpStringRect->bottom;
  851. nWordNum++;
  852. #ifdef _DEBUG
  853. for (i = 0; i < nWordNum; i++)
  854. {
  855. DbgPrintf("NhW16.dll       nBegin: %d, nEnd: %d, l: %d, r: %d, t: %d, b: %d",
  856.   WordBuffer[i].nBegin,
  857.   WordBuffer[i].nEnd,
  858.   WordBuffer[i].wordRect.left,
  859.   WordBuffer[i].wordRect.right,
  860.   WordBuffer[i].wordRect.top,
  861.   WordBuffer[i].wordRect.bottom);
  862. }
  863. DbgPrintf("NhW16.dll       ExtTextOutW: Nh16_AddToWordStruct end.");
  864. #endif
  865. return TRUE;
  866. }  
  867. BOOL FAR PASCAL _export Nh16_AddToCharStruct(int nBeignPlace, int nLeft, int nRight)
  868. {
  869. #ifdef _DEBUG
  870. DbgPrintf("NhW16.dll       ExtTextOutW: Nh16_AddToCharStruct, nBeginPlace: %d, nleft: %d, nRight: %d",
  871.   nBeignPlace,
  872.   nLeft,
  873.   nRight);
  874. #endif
  875. pnMemDCCharLeft[nBeignPlace]  = nLeft;
  876. pnMemDCCharRight[nBeignPlace] = nRight;
  877. return TRUE;
  878. }
  879.                        
  880. //==================================
  881. // PHYS - Matt Pietrek 1995
  882. // FILE: PHYS16.C
  883. //==================================
  884. static char MS_DOS_STR[] = "MS-DOS";
  885. //
  886. // Return a far pointer to the LDT
  887. //
  888. unsigned short GetLDTAlias(void)
  889. {
  890.     unsigned short  LDT_alias;
  891.     unsigned short  (far * dpmiproc)(void);
  892.     //
  893.     // Use INT 2Fh, fn. 168A to get the "DPMI extensions
  894.     // entry point" function pointer
  895.     //
  896.     _asm     mov     si, offset MS_DOS_STR   // DS:SI = "MS-DOS"
  897.     _asm     mov     ax, 168Ah
  898.     _asm     int     2Fh
  899.     _asm     cmp     al, 8Ah
  900.     _asm     je      extensions_not_found
  901.     //
  902.     // The entry point is returned in ES:DI.  Save it
  903.     //
  904.     _asm     mov     word ptr [dpmiproc], di
  905.     _asm     mov     word ptr [dpmiproc+2], es
  906.     //
  907.     // Call the extensions with AX == 0x100.  The LDT alias
  908.     // selector is return in AX.  Carry flag is set on failure.
  909.     //
  910.     _asm     mov     ax, 100h
  911.     LDT_alias = dpmiproc();
  912.     _asm     jc      extensions_not_found;
  913.     return  LDT_alias;
  914. extensions_not_found:   // We get here if something failed
  915.     return  0;
  916. }
  917. WORD FAR PASCAL __loadds GetRing0Callgate( DWORD func_address,
  918. unsigned cParams )
  919. {
  920.     CALLGATE_DESCRIPTOR far *callgate_desc;
  921.     CODE_SEG_DESCRIPTOR far *ring0_desc;
  922.     unsigned short ldt_alias;
  923.     unsigned short ring_0_alias;
  924.     unsigned short callgate_selector;
  925.     if ( (ldt_alias = GetLDTAlias()) == 0 )
  926.         return 0;
  927.     //
  928.     // Grab a selector from Windows to use as the CS at ring 0
  929.     //
  930.     if ( !(ring_0_alias = AllocSelector(0)) )
  931.         return 0;
  932.     //
  933. // Set up the fields in the descriptor to be a ring 0, flat model seg
  934.     //
  935.     ring0_desc = MAKELP( ldt_alias, ring_0_alias & 0xFFF8 );
  936. ring0_desc->limit_0_15 = 0xFFFF;
  937. ring0_desc->base_0_15 = 0;
  938. ring0_desc->base_16_23 = 0;
  939. ring0_desc->readable = 1;
  940. ring0_desc->conforming = 0;
  941. ring0_desc->code_data = 1;
  942. ring0_desc->app_system = 1;
  943.     ring0_desc->dpl = 0;
  944.     ring0_desc->present = 1;
  945. ring0_desc->limit_16_19 = 0xF;
  946. ring0_desc->always_0 = 0;
  947. ring0_desc->seg_16_32 = 1;
  948. ring0_desc->granularity = 1;
  949. ring0_desc->base_24_31 = 0;
  950.     //
  951.     // Allocate the selector that'll be used for the call gate
  952.     //
  953.     if ( (callgate_selector= AllocSelector(0)) == 0 )
  954.     {
  955.         FreeSelector( ring_0_alias );
  956.         return 0;
  957.     }
  958.     //
  959.     // Create a pointer to the call gate descriptor
  960.     //
  961.     callgate_desc = MAKELP( ldt_alias, callgate_selector & 0xFFF8 );
  962.     //
  963.     // Fill in the fields of the call gate descriptor with the
  964.     // appropriate values for a 16 bit callgate.
  965.     //
  966.     callgate_desc->offset_0_15 = LOWORD( func_address );
  967.     callgate_desc->selector = ring_0_alias;
  968.     callgate_desc->param_count = cParams;
  969.     callgate_desc->some_bits = 0;
  970.     callgate_desc->type = 0xC;          // 386 call gate
  971.     callgate_desc->app_system = 0;      // A system descriptor
  972.     callgate_desc->dpl = 3;             // Ring 3 code can call
  973.     callgate_desc->present = 1;
  974.     callgate_desc->offset_16_31 = HIWORD(func_address);
  975.     return callgate_selector;
  976. }
  977. BOOL FAR PASCAL __loadds FreeRing0Callgate( WORD callgate )
  978. {
  979.     CALLGATE_DESCRIPTOR far *callgate_desc;
  980.     unsigned short ldt_alias;
  981.     if ( (ldt_alias = GetLDTAlias()) == 0 )
  982.         return FALSE;
  983.     //
  984.     // Create a pointer to the call gate descriptor
  985.     //
  986.     callgate_desc = MAKELP( ldt_alias, callgate & 0xFFF8 );
  987.     //
  988.     // First, free the ring 0 alias selector stored in the LDT
  989.     // call gate descriptor, then free the call gate selector.
  990.     //
  991.     FreeSelector( callgate_desc->selector );
  992.     FreeSelector( callgate );
  993. }
  994. //Added by XGL, Dec 8th, 1998
  995. BOOL IsParentOrSelf(HWND hParent, HWND hChild)
  996. {
  997. HWND hTemp = hChild;
  998. HWND hDesktop ;
  999. if (hParent == NULL || hChild == NULL)
  1000. {
  1001. return FALSE ;
  1002. }
  1003. hDesktop = GetDesktopWindow() ;
  1004. while (hTemp != NULL && hTemp != hDesktop)
  1005. {
  1006. if (hTemp == hParent)
  1007. {
  1008. return TRUE ;
  1009. }
  1010. hTemp = GetParent(hTemp) ;
  1011. }
  1012. return FALSE ;
  1013. }
  1014. //Adding ends.