freepy.c
上传用户:shdz666
上传日期:2007-01-03
资源大小:566k
文件大小:14k
源码类别:

输入法编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 1999.4  Li ZhenChun
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License; or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that is will be useful, but
  10.  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12.  * General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 675 Mass Ave, Cambridge, M A 02139, USA.
  17.  *
  18.  * Author: Li ZhenChun  email: zhchli@163.net or zhchli@126.com
  19.  * 
  20.  */
  21. #include "freepy.h"
  22. #define CS_FREEPY (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS)
  23. /**********************************************************************/
  24. /*    DLLEntry                                                        */
  25. /**********************************************************************/
  26. BOOL WINAPI DllMain (
  27.  HINSTANCE    hInstDLL,
  28.  DWORD        dwFunction,
  29.  LPVOID       lpNot)
  30. {
  31.     switch(dwFunction)
  32.     {
  33. case DLL_PROCESS_ATTACH:
  34. /* for debug ********************************/
  35. #ifdef _MY_DEBUG
  36. if(nDebugLevel){
  37. if( (DebugLogFile=_tfopen( DEBUGLOGFILE, "w"))==NULL)
  38. MessageBox(NULL,"can not open Debuglogfile","debug",MB_OK);
  39. DebugLog(1,(DebugLogFile,"Entry inn"));
  40. }
  41. #endif
  42. /********************************************/
  43. InitDictionary();
  44. hInst = hInstDLL;
  45. IMERegisterClass( hInst );
  46. break;
  47. case DLL_PROCESS_DETACH:
  48. UnregisterClass(UICLASSNAME,hInst);
  49. UnregisterClass(COMPCLASSNAME,hInst);
  50. UnregisterClass(CANDCLASSNAME,hInst);
  51. UnregisterClass(STATUSCLASSNAME,hInst);
  52. DestroyDictionary();
  53. /* for debug ********************************/
  54. #ifdef _MY_DEBUG
  55. if(nDebugLevel){
  56. DebugLog(1,(DebugLogFile,"Entry outn"));
  57. if(DebugLogFile!=NULL)
  58. fclose(DebugLogFile);
  59. }
  60. #endif
  61. /********************************************/
  62. break;
  63. case DLL_THREAD_ATTACH:
  64. break;
  65. case DLL_THREAD_DETACH:
  66. break;
  67.     }
  68.     return TRUE;
  69. }
  70. BOOL IMERegisterClass( HANDLE hInstance )
  71. {
  72.     WNDCLASSEX wc;
  73.     //
  74.     // register class of UI window.
  75.     //
  76.     wc.cbSize         = sizeof(WNDCLASSEX);
  77.     wc.style          = CS_FREEPY | CS_IME;
  78.     wc.lpfnWndProc    = UIWndProc;
  79.     wc.cbClsExtra     = 0;
  80.     wc.cbWndExtra     = 2 * sizeof(LONG);
  81.     wc.hInstance      = hInstance;
  82.     wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
  83.     wc.hIcon          = NULL;
  84.     wc.lpszMenuName   = (LPTSTR)NULL;
  85.     wc.lpszClassName  = UICLASSNAME;
  86.     wc.hbrBackground  = NULL;
  87.     wc.hIconSm        = NULL;
  88.     if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
  89.         return FALSE;
  90.     //
  91.     // register class of composition window.
  92.     //
  93.     wc.cbSize         = sizeof(WNDCLASSEX);
  94.     wc.style          = CS_FREEPY | CS_IME;
  95.     wc.lpfnWndProc    = CompWndProc;
  96.     wc.cbClsExtra     = 0;
  97.     wc.cbWndExtra     = UICHILDEXTRASIZE;
  98.     wc.hInstance      = hInstance;
  99.     wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
  100.     wc.hIcon          = NULL;
  101.     wc.lpszMenuName   = (LPSTR)NULL;
  102.     wc.lpszClassName  = COMPCLASSNAME;
  103.     wc.hbrBackground  = NULL;
  104.     wc.hIconSm        = NULL;
  105.     if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
  106.         return FALSE;
  107.     //
  108.     // register class of candadate window.
  109.     //
  110.     wc.cbSize         = sizeof(WNDCLASSEX);
  111.     wc.style          = CS_FREEPY | CS_IME;
  112.     wc.lpfnWndProc    = CandWndProc;
  113.     wc.cbClsExtra     = 0;
  114.     wc.cbWndExtra     = UICHILDEXTRASIZE;
  115.     wc.hInstance      = hInstance;
  116.     wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
  117.     wc.hIcon          = NULL;
  118.     wc.lpszMenuName   = (LPSTR)NULL;
  119.     wc.lpszClassName  = CANDCLASSNAME;
  120.     wc.hbrBackground  = NULL;
  121.     wc.hIconSm        = NULL;
  122.     if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
  123.         return FALSE;
  124.     //
  125.     // register class of status window.
  126.     //
  127.     wc.cbSize         = sizeof(WNDCLASSEX);
  128.     wc.style          = CS_FREEPY | CS_IME;
  129.     wc.lpfnWndProc    = StatusWndProc;
  130.     wc.cbClsExtra     = 0;
  131.     wc.cbWndExtra     = UICHILDEXTRASIZE;
  132.     wc.hInstance      = hInstance;
  133.     wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
  134.     wc.hIcon          = NULL;
  135.     wc.lpszMenuName   = (LPSTR)NULL;
  136.     wc.lpszClassName  = STATUSCLASSNAME;
  137.     wc.hbrBackground  = NULL;
  138.     wc.hIconSm        = NULL;
  139.     if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
  140.         return FALSE;
  141.     return TRUE;
  142. }
  143. /**********************************************************************/
  144. /*                                                                    */
  145. /* UIWndProc()                                                   */
  146. /*                                                                    */
  147. /* IME UI window procedure                                            */
  148. /*                                                                    */
  149. /**********************************************************************/
  150. LRESULT WINAPI UIWndProc(
  151. HWND hWnd,
  152. UINT message,
  153. WPARAM wParam,
  154. LPARAM lParam)
  155. {
  156.     HIMC           hUICurIMC;
  157.     LPINPUTCONTEXT lpIMC;
  158.     LPUIEXTRA      lpUIExtra;
  159.     HGLOBAL        hUIExtra;
  160.     LONG           lRet = 0L;
  161. DebugLog(1,(DebugLogFile,"UIWndn"));
  162.     hUICurIMC = (HIMC)GetWindowLong(hWnd,IMMGWL_IMC);
  163.     //
  164.     // Even if there is no current UI. these messages should not be pass to 
  165.     // DefWindowProc().
  166.     //
  167.     if (!hUICurIMC)
  168.     {
  169.         switch (message)
  170.         {
  171. case WM_IME_STARTCOMPOSITION:
  172. case WM_IME_ENDCOMPOSITION:
  173. case WM_IME_COMPOSITION:
  174. case WM_IME_NOTIFY:
  175. case WM_IME_CONTROL:
  176. case WM_IME_COMPOSITIONFULL:
  177. case WM_IME_SELECT:
  178. case WM_IME_CHAR:
  179. return 0L;
  180. default:
  181. break;
  182.         }
  183.     }
  184.     switch (message)
  185.     {
  186. case WM_CREATE:
  187. DebugLog(1,(DebugLogFile,"UIWnd:WM_CREATEn"));
  188. //
  189. // Allocate UI's extra memory block.
  190. //
  191. hUIExtra = GlobalAlloc(GHND,sizeof(UIEXTRA));
  192. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  193. lpUIExtra->uiComp.pt.x = -1;
  194. lpUIExtra->uiComp.pt.y = -1;
  195. CreateCompWindow(hWnd,lpUIExtra);
  196. CreateCandWindow(hWnd,lpUIExtra);
  197. GlobalUnlock(hUIExtra);
  198. SetWindowLong(hWnd,IMMGWL_PRIVATE,(DWORD)hUIExtra);
  199. break;
  200. case WM_IME_SETCONTEXT:
  201. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_SETCONTEXTn"));
  202. if (wParam)
  203. {
  204. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  205. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  206. if (hUICurIMC)
  207. {
  208. //
  209. // input context was chenged.
  210. // if there are the child windows, the diplay have to be
  211. // updated.
  212. //
  213. lpIMC = ImmLockIMC(hUICurIMC);
  214. if (lpIMC)
  215. {
  216. MoveCandWindow(hWnd,lpUIExtra,lpIMC);
  217. MoveCompWindow(hWnd,lpUIExtra,lpIMC);
  218. }
  219. else
  220. {
  221. HideCandWindow(lpUIExtra);
  222. HideCompWindow(lpUIExtra);
  223. }
  224. ImmUnlockIMC(hUICurIMC);
  225. }
  226. else   // it is NULL input context.
  227. {
  228. HideCandWindow(lpUIExtra);
  229. HideCompWindow(lpUIExtra);
  230. }
  231. GlobalUnlock(hUIExtra);
  232. }
  233. break;
  234. case WM_IME_STARTCOMPOSITION:
  235. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_STARTCOMPOSITIONn"));
  236. //
  237. // Start composition! Ready to display the composition string.
  238. //
  239. break;
  240. case WM_IME_COMPOSITION:
  241. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_COMPOSITIONn"));
  242. //
  243. // Update to display the composition string.
  244. //
  245. lpIMC = ImmLockIMC(hUICurIMC);
  246. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  247. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  248. MoveCompWindow(hWnd,lpUIExtra,lpIMC);
  249. MoveCandWindow(hWnd,lpUIExtra,lpIMC);
  250. GlobalUnlock(hUIExtra);
  251. ImmUnlockIMC(hUICurIMC);
  252. break;
  253. case WM_IME_ENDCOMPOSITION:
  254. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_ENDCOMPOSITIONn"));
  255. //
  256. // Finish to display the composition string.
  257. //
  258. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  259. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  260. HideCompWindow(lpUIExtra);
  261. HideCandWindow(lpUIExtra);
  262. GlobalUnlock(hUIExtra);
  263. break;
  264. case WM_IME_COMPOSITIONFULL:
  265. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_COMPOSITIONFULLn"));
  266. break;
  267. case WM_IME_SELECT:
  268. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_SELECTn"));
  269. break;
  270. case WM_IME_CONTROL:
  271. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_CONTROLn"));
  272. lRet = ControlHandle(hUICurIMC, hWnd,message,wParam,lParam);
  273. break;
  274. case WM_IME_NOTIFY:
  275. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFYn"));
  276. lRet = NotifyHandle(hUICurIMC, hWnd,message,wParam,lParam);
  277. break;
  278. case WM_DESTROY:
  279. DebugLog(1,(DebugLogFile,"UIWnd:WM_DESTROYn"));
  280. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  281. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  282. if (IsWindow(lpUIExtra->uiStatus.hWnd))
  283. DestroyWindow(lpUIExtra->uiStatus.hWnd);
  284. if (IsWindow(lpUIExtra->uiCand.hWnd))
  285. DestroyWindow(lpUIExtra->uiCand.hWnd);
  286. if (IsWindow(lpUIExtra->uiComp.hWnd))
  287. DestroyWindow(lpUIExtra->uiComp.hWnd);
  288. GlobalUnlock(hUIExtra);
  289. GlobalFree(hUIExtra);
  290. break;
  291. case WM_UI_COMPMOVE:
  292. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  293. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  294. lpUIExtra->uiComp.pt.x = (long)LOWORD(lParam);
  295. lpUIExtra->uiComp.pt.y = (long)HIWORD(lParam);
  296. GlobalUnlock(hUIExtra);
  297. break;
  298. default:
  299. return DefWindowProc(hWnd,message,wParam,lParam);
  300.     }
  301.     return lRet;
  302. }
  303. /**********************************************************************/
  304. /*                                                                    */
  305. /* NotifyHandle()                                                     */
  306. /*                                                                    */
  307. /* Handle WM_IME_NOTIFY messages.                                     */
  308. /*                                                                    */
  309. /**********************************************************************/
  310. LONG NotifyHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  311. {
  312. LONG lRet = 0L;
  313.     LPINPUTCONTEXT lpIMC;
  314.     HGLOBAL hUIExtra;
  315.     LPUIEXTRA lpUIExtra;
  316.     if (!(lpIMC = ImmLockIMC(hUICurIMC)))
  317.         return 0L;
  318.     hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  319.     lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  320.     switch (wParam)
  321.     {
  322. case IMN_CLOSESTATUSWINDOW:
  323. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CLOSESTATUSWINDOWn"));
  324. if (IsWindow(lpUIExtra->uiStatus.hWnd)) {
  325. ShowWindow(lpUIExtra->uiStatus.hWnd,SW_HIDE);
  326. }
  327. break;
  328. case IMN_OPENSTATUSWINDOW:
  329. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_OPENSTATUSWINDOWn"));
  330. CreateStatusWindow( hWnd, lpUIExtra);
  331. break;
  332. case IMN_OPENCANDIDATE:
  333. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_OPENCANDIDATEn"));
  334. break;
  335. case IMN_CHANGECANDIDATE:
  336. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CHANGECANDIDATEn"));
  337. break;
  338. case IMN_CLOSECANDIDATE:
  339. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CLOSECANDIDATEn"));
  340. break;
  341. case IMN_SETCONVERSIONMODE:
  342. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCONVERSIONMODEn"));
  343. UpdateStatusWindow(lpUIExtra);
  344. break;
  345. case IMN_SETSENTENCEMODE:
  346. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETSENTENCEMODEn"));
  347. break;
  348. case IMN_SETOPENSTATUS:
  349. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETOPENSTATUSn"));
  350. UpdateStatusWindow(lpUIExtra);
  351. break;
  352. case IMN_SETCANDIDATEPOS:
  353. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCANDIDATEPOSn"));
  354. break;
  355. case IMN_SETCOMPOSITIONFONT:
  356. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONFONTn"));
  357. break;
  358. case IMN_SETCOMPOSITIONWINDOW:
  359. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONWINDOWn"));
  360. if(wConversionSet & CONVERSION_SET_FOLLOW) {
  361. POINT ptSrc;
  362. SIZE szOffset;
  363. HDC hDC;
  364. ptSrc = lpIMC->cfCompForm.ptCurrentPos;
  365. ClientToScreen(lpIMC->hWnd, &ptSrc);
  366. hDC = GetDC(lpIMC->hWnd);
  367. GetTextExtentPoint(hDC,"A",1,&szOffset);
  368. ReleaseDC(lpIMC->hWnd,hDC);
  369. lpUIExtra->uiComp.pt.x = ptSrc.x + szOffset.cx;
  370. lpUIExtra->uiComp.pt.y = ptSrc.y + szOffset.cy;
  371. }
  372.     if (IsWindow(lpUIExtra->uiComp.hWnd))
  373. InvalidateRect(lpUIExtra->uiComp.hWnd,NULL,FALSE);
  374. break;
  375. case IMN_GUIDELINE:
  376. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_GUIDELINEn"));
  377. break;
  378. case IMN_SETSTATUSWINDOWPOS:
  379. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETSTATUSWINDOWPOSn"));
  380. break;
  381. case IMN_PRIVATE:
  382. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_PRIVATEn"));
  383. break;
  384. default:
  385. break;
  386.     }
  387.     GlobalUnlock(hUIExtra);
  388.     ImmUnlockIMC(hUICurIMC);
  389.     return lRet;
  390. }
  391. /**********************************************************************/
  392. /*                                                                    */
  393. /* ControlHandle()                                                    */
  394. /*                                                                    */
  395. /* Handle WM_IME_CONTROL messages.                                    */
  396. /*                                                                    */
  397. /**********************************************************************/
  398. LONG ControlHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  399. {
  400. return 0L;
  401. }