freepy.c
上传用户:szljw888
上传日期:2010-04-11
资源大小:124k
文件大小:15k
源码类别:

输入法编程

开发平台:

C/C++

  1. /* 大熊猫输入法(Free Chinese Input)  由YJMSIR(yjmsir@163.com)编写
  2.  * 协议: GPL
  3.  * freeinput( A Chinese Input Method) by YJMSIR(yjmsir@163.com)
  4.  * Licence: GPL 
  5.  */
  6. #include "freepy.h"
  7. #define CS_FREEPY (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS)
  8. /**********************************************************************/
  9. /*    DLLEntry                                                        */
  10. /**********************************************************************/
  11. BOOL WINAPI DllMain (
  12.  HINSTANCE    hInstDLL,
  13.  DWORD        dwFunction,
  14.  LPVOID       lpNot)
  15. {
  16.     switch(dwFunction)
  17.     {
  18. char szDirFile[MAX_PATH];
  19. case DLL_PROCESS_ATTACH:
  20. /* for debug ********************************/
  21. #ifdef _MY_DEBUG
  22. if(nDebugLevel){
  23. if( (DebugLogFile=_tfopen( DEBUGLOGFILE, "w"))==NULL)
  24. MessageBox(NULL,"can not open Debuglogfile","debug",MB_OK);
  25. DebugLog(1,(DebugLogFile,"Entry inn"));
  26. }
  27. #endif
  28. /********************************************/
  29. hInst = hInstDLL;
  30. ReadRegRecord();
  31. GetRelativeTableDirList();
  32. ReadGlobalIni();
  33. sprintf(szDirFile,"%swbx.mb",CurrentTableDir);
  34. if(!strcmp(CurrentTableDir,"") || !IsFileExist(szDirFile))
  35. sprintf(CurrentTableDir,"%smb\%s\",InstallFromDir,RelativeTableDirList[0]);
  36. ReadUserIni();
  37. if(wConversionSet & CONVERSION_SET_TENLINE) CAND_PAGESIZE=10;
  38. hUIFont = CreateFont(IsWindows98()?20:16, 0, 0, 0, FW_NORMAL,
  39. FALSE, FALSE, FALSE, ANSI_CHARSET,
  40. OUT_TT_PRECIS, CLIP_TT_ALWAYS, ANTIALIASED_QUALITY,
  41. DEFAULT_PITCH, _T("宋体"));
  42. if(!IMERegisterClass(hInst)) return FALSE;
  43. if(HaveInitDictionary) InitDictionary();//重要
  44. break;
  45. case DLL_PROCESS_DETACH:
  46. DeleteObject(hUIFont);
  47. UnregisterClass(UICLASSNAME,hInst);
  48. UnregisterClass(COMPCLASSNAME,hInst);
  49. UnregisterClass(STATUSCLASSNAME,hInst);
  50. DestroyDictionary();
  51. /* for debug ********************************/
  52. #ifdef _MY_DEBUG
  53. if(nDebugLevel){
  54. DebugLog(1,(DebugLogFile,"Entry outn"));
  55. if(DebugLogFile!=NULL)
  56. fclose(DebugLogFile);
  57. }
  58. #endif
  59. /********************************************/
  60. break;
  61. case DLL_THREAD_ATTACH:
  62. break;
  63. case DLL_THREAD_DETACH:
  64. break;
  65.     }
  66.     return TRUE;
  67. }
  68. BOOL IMERegisterClass( HANDLE hInstance )
  69. {
  70.     WNDCLASSEX wc;
  71.     //
  72.     // register class of UI window.
  73.     //
  74.     wc.cbSize         = sizeof(WNDCLASSEX);
  75.     wc.style          = CS_FREEPY | CS_IME; 
  76.     wc.lpfnWndProc    = UIWndProc;
  77.     wc.cbClsExtra     = 0;
  78.     wc.cbWndExtra     = 2 * sizeof(LONG);
  79.     wc.hInstance      = hInstance;
  80.     wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
  81.     wc.hIcon          = NULL;
  82.     wc.lpszMenuName   = (LPTSTR)NULL;
  83.     wc.lpszClassName  = UICLASSNAME;
  84.     wc.hbrBackground  = NULL;
  85.     wc.hIconSm        = NULL;
  86.     if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
  87.         return FALSE;
  88.     //
  89.     // register class of composition window.
  90.     //
  91.     wc.cbSize         = sizeof(WNDCLASSEX);
  92.     wc.style          = CS_FREEPY | CS_IME;
  93.     wc.lpfnWndProc    = CompWndProc;
  94.     wc.cbClsExtra     = 0;
  95.     wc.cbWndExtra     = UICHILDEXTRASIZE;
  96.     wc.hInstance      = hInstance;
  97.     wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
  98.     wc.hIcon          = NULL;
  99.     wc.lpszMenuName   = (LPSTR)NULL;
  100.     wc.lpszClassName  = COMPCLASSNAME;
  101.     wc.hbrBackground  = NULL;
  102.     wc.hIconSm        = NULL;
  103.     if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
  104.         return FALSE;
  105.     //
  106.     // register class of status window.
  107.     //
  108.     wc.cbSize         = sizeof(WNDCLASSEX);
  109.     wc.style          = CS_FREEPY | CS_IME;
  110.     wc.lpfnWndProc    = StatusWndProc;
  111.     wc.cbClsExtra     = 0;
  112.     wc.cbWndExtra     = UICHILDEXTRASIZE;
  113.     wc.hInstance      = hInstance;
  114.     wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
  115.     wc.hIcon          = NULL;
  116.     wc.lpszMenuName   = (LPSTR)NULL;
  117.     wc.lpszClassName  = STATUSCLASSNAME;
  118.     wc.hbrBackground  = NULL;
  119.     wc.hIconSm        = NULL;
  120.     if( !RegisterClassEx( (LPWNDCLASSEX)&wc))
  121.         return FALSE;
  122.     return TRUE;
  123. }
  124. /**********************************************************************/
  125. /*                                                                    */
  126. /* UIWndProc()                                                   */
  127. /*                                                                    */
  128. /* IME UI window procedure                                            */
  129. /*                                                                    */
  130. /**********************************************************************/
  131. LRESULT WINAPI UIWndProc(
  132. HWND hWnd,
  133. UINT message,
  134. WPARAM wParam,
  135. LPARAM lParam)
  136. {
  137.     HIMC           hUICurIMC;
  138.     LPINPUTCONTEXT lpIMC;
  139.     LPUIEXTRA      lpUIExtra;
  140.     HGLOBAL        hUIExtra;
  141.     LONG           lRet = 0L;
  142. DebugLog(1,(DebugLogFile,"UIWndn"));
  143.     hUICurIMC = (HIMC)GetWindowLong(hWnd,IMMGWL_IMC);
  144.     //
  145.     // Even if there is no current UI. these messages should not be pass to 
  146.     // DefWindowProc().
  147.     //
  148.     if (!hUICurIMC)
  149.     {
  150.         switch (message)
  151.         {
  152. case WM_IME_STARTCOMPOSITION:
  153. case WM_IME_ENDCOMPOSITION:
  154. case WM_IME_COMPOSITION:
  155. case WM_IME_NOTIFY:
  156. case WM_IME_CONTROL:
  157. case WM_IME_COMPOSITIONFULL:
  158. case WM_IME_SELECT:
  159. case WM_IME_CHAR:
  160. return 0L;
  161. default:
  162. break;
  163.         }
  164.     }
  165.     switch (message)
  166.     {
  167. case WM_CREATE:
  168. //DebugLog(1,(DebugLogFile,"UIWnd:WM_CREATEn"));
  169. //
  170. // Allocate UI's extra memory block.
  171. //
  172. hUIExtra = GlobalAlloc(GHND,sizeof(UIEXTRA));
  173. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  174. lpUIExtra->uiComp.pt.x = -1;//test
  175. lpUIExtra->uiComp.pt.y = -1;
  176. CreateCompWindow(hWnd,lpUIExtra);
  177. GlobalUnlock(hUIExtra);
  178. SetWindowLong(hWnd,IMMGWL_PRIVATE,(DWORD)hUIExtra);
  179. if(!HaveSetTimerForSpeed){
  180. SetTimer(hWnd,2,60000,NULL);//1分钟的平均值
  181. HaveSetTimerForSpeed=1;
  182. }
  183. if(!HaveInitDictionary)
  184. SetTimer(hWnd,3,500,NULL);//0.5秒钟
  185. break;
  186.      case WM_TIMER :
  187. if(!HaveInitDictionary){
  188. KillTimer (hWnd, 3);
  189. InitDictionary();
  190. HaveInitDictionary=1;
  191. //UpdateStatusByMessage(hUICurIMC);
  192. break;
  193. }
  194. else{
  195. WuBiSpeed=InputAccumulateNum/2;//前一分钟的输入数量
  196. InputAccumulateNum=0;
  197. //if(wConversionSet & CONVERSION_SET_WBSPEED)//) && (WuBiSpeed!=0)
  198. _stprintf(SpeedMessage,"(%d字/分)",WuBiSpeed);
  199. //else
  200. //_tcscpy(SpeedMessage,_T(""));
  201. }
  202. break;
  203. case WM_IME_SETCONTEXT:
  204. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_SETCONTEXTn"));
  205. if (wParam)
  206. {
  207. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  208. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  209. if (hUICurIMC)
  210. {
  211. //
  212. // input context was changed.
  213. // if there are the child windows, the diplay have to be
  214. // updated.
  215. //
  216. lpIMC = ImmLockIMC(hUICurIMC);
  217. if (lpIMC)
  218. {
  219. //DebugLog(8,(DebugLogFile,"(lpIMCn"));
  220. MoveCompWindow(hWnd,lpUIExtra,lpIMC);
  221. //if(!(wConversionSet &CONVERSION_SET_DOUBLELINE))
  222. //MoveCandWindow(hWnd,lpUIExtra,lpIMC);
  223. //else
  224. //HideCandWindow(lpUIExtra);
  225. }
  226. else
  227. {
  228. if(wConversionSet & CONVERSION_SET_AUTOHIDE){
  229. HideCompWindow(lpUIExtra);
  230. //HideCandWindow(lpUIExtra);
  231. }
  232. }
  233. ImmUnlockIMC(hUICurIMC);
  234. }
  235. else   // it is NULL input context.
  236. {
  237. if(wConversionSet & CONVERSION_SET_AUTOHIDE){
  238. HideCompWindow(lpUIExtra);
  239. //HideCandWindow(lpUIExtra);
  240. }
  241. }
  242. GlobalUnlock(hUIExtra);
  243. }
  244. break;
  245. case WM_IME_STARTCOMPOSITION:
  246. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_STARTCOMPOSITIONn"));
  247. //
  248. // Start composition! Ready to display the composition string.
  249. //
  250. break;
  251. case WM_IME_COMPOSITION:
  252. //DebugLog(8,(DebugLogFile,"UIWnd:WM_IME_COMPOSITIONn"));
  253. //
  254. // Update to display the composition string.
  255. //
  256. lpIMC = ImmLockIMC(hUICurIMC);
  257. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  258. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  259. //DebugLog(8,(DebugLogFile,"lpUIExtran"));
  260. MoveCompWindow(hWnd,lpUIExtra,lpIMC);
  261. GlobalUnlock(hUIExtra);
  262. ImmUnlockIMC(hUICurIMC);
  263. break;
  264. case WM_IME_ENDCOMPOSITION:
  265. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_ENDCOMPOSITIONn"));
  266. //
  267. // Finish to display the composition string.
  268. //
  269. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  270. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  271. if(wConversionSet & CONVERSION_SET_AUTOHIDE){
  272. HideCompWindow(lpUIExtra);
  273. }
  274. GlobalUnlock(hUIExtra);
  275. break;
  276. case WM_IME_COMPOSITIONFULL:
  277. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_COMPOSITIONFULLn"));
  278. break;
  279. case WM_IME_SELECT:
  280. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_SELECTn"));
  281. break;
  282. case WM_IME_CONTROL:
  283. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_CONTROLn"));
  284. lRet = ControlHandle(hUICurIMC, hWnd,message,wParam,lParam);
  285. break;
  286. case WM_IME_NOTIFY:
  287. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFYn"));
  288. lRet = NotifyHandle(hUICurIMC, hWnd,message,wParam,lParam);
  289. break;
  290. case WM_DESTROY:
  291. //DebugLog(1,(DebugLogFile,"UIWnd:WM_DESTROYn"));
  292. KillTimer (hWnd, 2);
  293. HaveSetTimerForSpeed=0;
  294. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  295. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  296. if (IsWindow(lpUIExtra->uiStatus.hWnd))
  297. DestroyWindow(lpUIExtra->uiStatus.hWnd);
  298. //if (IsWindow(lpUIExtra->uiCand.hWnd))
  299. // DestroyWindow(lpUIExtra->uiCand.hWnd);
  300. if (IsWindow(lpUIExtra->uiComp.hWnd))
  301. DestroyWindow(lpUIExtra->uiComp.hWnd);
  302. GlobalUnlock(hUIExtra);
  303. GlobalFree(hUIExtra);
  304. //PostQuitMessage (0) ;
  305. break;
  306. case WM_UI_COMPMOVE:
  307. hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  308. lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  309. lpUIExtra->uiComp.pt.x = (long)LOWORD(lParam);
  310. lpUIExtra->uiComp.pt.y = (long)HIWORD(lParam);
  311. GlobalUnlock(hUIExtra);
  312. break;
  313. default:
  314. return DefWindowProc(hWnd,message,wParam,lParam);
  315.     }
  316.     return lRet;
  317. }
  318. /**********************************************************************/
  319. /*                                                                    */
  320. /* NotifyHandle()                                                     */
  321. /*                                                                    */
  322. /* Handle WM_IME_NOTIFY messages.                                     */
  323. /*                                                                    */
  324. /**********************************************************************/
  325. LONG NotifyHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  326. {
  327. LONG lRet = 0L;
  328.     LPINPUTCONTEXT lpIMC;
  329.     HGLOBAL hUIExtra;
  330.     LPUIEXTRA lpUIExtra;
  331.     if (!(lpIMC = ImmLockIMC(hUICurIMC)))
  332.         return 0L;
  333.     hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
  334.     lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
  335.     switch (wParam)
  336.     {
  337. case IMN_CLOSESTATUSWINDOW:
  338. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CLOSESTATUSWINDOWn"));
  339. if (IsWindow(lpUIExtra->uiStatus.hWnd)) {
  340. ShowWindow(lpUIExtra->uiStatus.hWnd,SW_HIDE);
  341. }
  342. break;
  343. case IMN_OPENSTATUSWINDOW:
  344. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_OPENSTATUSWINDOWn"));
  345. CreateStatusWindow( hWnd, lpUIExtra);
  346. break;
  347. case IMN_OPENCANDIDATE:
  348. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_OPENCANDIDATEn"));
  349. break;
  350. case IMN_CHANGECANDIDATE:
  351. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CHANGECANDIDATEn"));
  352. break;
  353. case IMN_CLOSECANDIDATE:
  354. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CLOSECANDIDATEn"));
  355. break;
  356. case IMN_SETCONVERSIONMODE:
  357. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCONVERSIONMODEn"));
  358. UpdateStatusWindow(lpUIExtra);
  359. break;
  360. case IMN_SETSENTENCEMODE:
  361. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETSENTENCEMODEn"));
  362. break;
  363. case IMN_SETOPENSTATUS:
  364. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETOPENSTATUSn"));
  365. if(!IsIMEOpen(hUICurIMC)) {
  366. MakeResultString(hUICurIMC,FALSE);
  367. }
  368. UpdateStatusWindow(lpUIExtra);
  369. break;
  370. case IMN_SETCANDIDATEPOS:
  371. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCANDIDATEPOSn"));
  372. break;
  373. case IMN_SETCOMPOSITIONFONT:
  374. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONFONTn"));
  375. break;
  376. case IMN_SETCOMPOSITIONWINDOW:
  377. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONWINDOWn"));
  378. if(wConversionSet & CONVERSION_SET_FOLLOW) {
  379. POINT ptSrc;
  380. SIZE szOffset;
  381. HDC hDC;
  382. HFONT oldFont;
  383. RECT screenrc;
  384. ptSrc = lpIMC->cfCompForm.ptCurrentPos;
  385. //MessageBoxPrintf("cfCompForm","x:%d  y:%d",ptSrc.x,ptSrc.y);
  386. if(ptSrc.x==0 &&ptSrc.y==0){
  387. SystemParametersInfo(SPI_GETWORKAREA,
  388. 0,
  389. &screenrc,
  390. 0);
  391. ptSrc.x=(screenrc.right+screenrc.left)/3;
  392. ptSrc.y=screenrc.bottom+80;
  393. }
  394. else
  395. ClientToScreen(lpIMC->hWnd, &ptSrc);
  396. hDC = GetDC(lpIMC->hWnd);
  397. oldFont = SelectObject(hDC, hUIFont);
  398. GetTextExtentPoint(hDC,"A",1,&szOffset);
  399. SelectObject(hDC, oldFont);
  400. ReleaseDC(lpIMC->hWnd,hDC);
  401. lpUIExtra->uiComp.pt.x = ptSrc.x + szOffset.cx;
  402. lpUIExtra->uiComp.pt.y = ptSrc.y + szOffset.cy;
  403. }
  404. else{
  405. lpUIExtra->uiComp.pt.x = lpUIExtra->uiStatus.pt.x + lpUIExtra->uiStatus.sz.cx;
  406. lpUIExtra->uiComp.pt.y = lpUIExtra->uiStatus.pt.y;
  407. }
  408.     if (IsWindow(lpUIExtra->uiComp.hWnd))
  409. InvalidateRect(lpUIExtra->uiComp.hWnd,NULL,FALSE);
  410. break;
  411. case IMN_GUIDELINE:
  412. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_GUIDELINEn"));
  413. break;
  414. case IMN_SETSTATUSWINDOWPOS://yjm
  415. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETSTATUSWINDOWPOSn"));
  416. //MessageBox(NULL,_T("IMN_SETSTATUSWINDOWPOS"),_T("谢谢关注!"),MB_OK);
  417. if(wConversionSet & CONVERSION_SET_FOLLOW) {
  418. POINT ptSrc;
  419. RECT screenrc;
  420. ptSrc = lpIMC->ptStatusWndPos;
  421. //MessageBoxPrintf("ptStatusWndPos","x:%d  y:%d",ptSrc.x,ptSrc.y);
  422. GetClientRect(hWnd,&screenrc);
  423. ptSrc.x=screenrc.right-100;
  424. ptSrc.y=screenrc.top -20;
  425. ClientToScreen(lpIMC->hWnd, &ptSrc);
  426. lpUIExtra->uiStatus.pt.x = ptSrc.x;
  427. lpUIExtra->uiStatus.pt.y = ptSrc.y;
  428. }
  429.     if (IsWindow(lpUIExtra->uiStatus.hWnd))
  430. InvalidateRect(lpUIExtra->uiStatus.hWnd,NULL,FALSE);
  431. break;
  432. case IMN_PRIVATE:
  433. DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_PRIVATEn"));
  434. break;
  435. default:
  436. break;
  437.     }
  438.     GlobalUnlock(hUIExtra);
  439.     ImmUnlockIMC(hUICurIMC);
  440.     return lRet;
  441. }
  442. /**********************************************************************/
  443. /*                                                                    */
  444. /* ControlHandle()                                                    */
  445. /*                                                                    */
  446. /* Handle WM_IME_CONTROL messages.                                    */
  447. /*                                                                    */
  448. /**********************************************************************/
  449. LONG ControlHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  450. {
  451. return 0L;
  452. }