Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

778 lines
26 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. init.c
  5. ++*/
  6. #include <windows.h>
  7. #include <winerror.h>
  8. #include <memory.h>
  9. #include <immdev.h>
  10. #include <imedefs.h>
  11. #include <regstr.h>
  12. int strbytelen (LPTSTR);
  13. void PASCAL InitStatusUIData(
  14. int cxBorder,
  15. int cyBorder)
  16. {
  17. int iContentHi;
  18. // iContentHi is to get the maximum value of predefined STATUS_DIM_Y and
  19. // a real Chinese character's height in the current HDC.
  20. iContentHi = STATUS_DIM_Y;
  21. if ( iContentHi < sImeG.yChiCharHi )
  22. iContentHi = sImeG.yChiCharHi ;
  23. // right bottom of status
  24. sImeG.rcStatusText.left = 0;
  25. sImeG.rcStatusText.top = 0;
  26. sImeG.rcStatusText.right = sImeG.rcStatusText.left +
  27. strbytelen(szImeName) * sImeG.xChiCharWi/2 + STATUS_NAME_MARGIN + STATUS_DIM_X * 4;
  28. sImeG.rcStatusText.bottom = sImeG.rcStatusText.top + iContentHi;
  29. sImeG.xStatusWi = STATUS_DIM_X * 4 + STATUS_NAME_MARGIN +
  30. strbytelen(szImeName) * sImeG.xChiCharWi/2 + 6 * cxBorder;
  31. sImeG.yStatusHi = iContentHi + 6 * cxBorder;
  32. // left bottom of imeicon bar
  33. sImeG.rcImeIcon.left = sImeG.rcStatusText.left;
  34. sImeG.rcImeIcon.top = sImeG.rcStatusText.top;
  35. sImeG.rcImeIcon.right = sImeG.rcImeIcon.left + STATUS_DIM_X;
  36. sImeG.rcImeIcon.bottom = sImeG.rcImeIcon.top + iContentHi;
  37. // left bottom of imename bar
  38. sImeG.rcImeName.left = sImeG.rcImeIcon.right;
  39. sImeG.rcImeName.top = sImeG.rcStatusText.top;
  40. sImeG.rcImeName.right = sImeG.rcImeName.left +
  41. strbytelen(szImeName) * sImeG.xChiCharWi/2 + STATUS_NAME_MARGIN;
  42. sImeG.rcImeName.bottom = sImeG.rcImeName.top + iContentHi;
  43. // middle bottom of Shape bar
  44. sImeG.rcShapeText.left = sImeG.rcImeName.right;
  45. sImeG.rcShapeText.top = sImeG.rcStatusText.top;
  46. sImeG.rcShapeText.right = sImeG.rcShapeText.left + STATUS_DIM_X;
  47. sImeG.rcShapeText.bottom = sImeG.rcShapeText.top + iContentHi;
  48. // middle bottom of Symbol bar
  49. sImeG.rcSymbol.left = sImeG.rcShapeText.right;
  50. sImeG.rcSymbol.top = sImeG.rcStatusText.top;
  51. sImeG.rcSymbol.right = sImeG.rcSymbol.left + STATUS_DIM_X;
  52. sImeG.rcSymbol.bottom = sImeG.rcSymbol.top + iContentHi;
  53. // right bottom of SK bar
  54. sImeG.rcSKText.left = sImeG.rcSymbol.right;
  55. sImeG.rcSKText.top = sImeG.rcStatusText.top;
  56. sImeG.rcSKText.right = sImeG.rcSKText.left + STATUS_DIM_X;
  57. sImeG.rcSKText.bottom = sImeG.rcSKText.top + iContentHi;
  58. return;
  59. }
  60. void PASCAL InitCandUIData(
  61. int cxBorder,
  62. int cyBorder,
  63. int UIMode)
  64. {
  65. int iContentHi;
  66. // iContentHi is to get the maximum value of predefined COMP_TEXT_Y and
  67. // a real Chinese character's height in the current HDC.
  68. iContentHi = COMP_TEXT_Y;
  69. if ( iContentHi < sImeG.yChiCharHi )
  70. iContentHi = sImeG.yChiCharHi ;
  71. sImeG.cxCandBorder = cxBorder * 2;
  72. sImeG.cyCandBorder = cyBorder * 2;
  73. if(UIMode == LIN_UI) {
  74. sImeG.rcCandIcon.left = 0;
  75. sImeG.rcCandIcon.top = cyBorder + 2;
  76. sImeG.rcCandIcon.right = sImeG.rcCandIcon.left + UI_CANDICON;
  77. sImeG.rcCandIcon.bottom = sImeG.rcCandIcon.top + UI_CANDICON;
  78. sImeG.rcCandText.left = sImeG.rcCandIcon.right + 3;
  79. sImeG.rcCandText.top = cyBorder ;
  80. sImeG.rcCandText.right = sImeG.rcCandText.left + UI_CANDSTR;
  81. sImeG.rcCandText.bottom = sImeG.rcCandText.top + iContentHi;
  82. sImeG.rcCandBTH.top = cyBorder * 4;
  83. sImeG.rcCandBTH.left = sImeG.rcCandText.right + 5;
  84. sImeG.rcCandBTH.right = sImeG.rcCandBTH.left + UI_CANDBTW;
  85. sImeG.rcCandBTH.bottom = sImeG.rcCandBTH.top + UI_CANDBTH;
  86. sImeG.rcCandBTU.top = cyBorder * 4;
  87. sImeG.rcCandBTU.left = sImeG.rcCandBTH.right;
  88. sImeG.rcCandBTU.right = sImeG.rcCandBTU.left + UI_CANDBTW;
  89. sImeG.rcCandBTU.bottom = sImeG.rcCandBTU.top + UI_CANDBTH;
  90. sImeG.rcCandBTD.top = cyBorder * 4;
  91. sImeG.rcCandBTD.left = sImeG.rcCandBTU.right;
  92. sImeG.rcCandBTD.right = sImeG.rcCandBTD.left + UI_CANDBTW;
  93. sImeG.rcCandBTD.bottom = sImeG.rcCandBTD.top + UI_CANDBTH;
  94. sImeG.rcCandBTE.top = cyBorder * 4;
  95. sImeG.rcCandBTE.left = sImeG.rcCandBTD.right;
  96. sImeG.rcCandBTE.right = sImeG.rcCandBTE.left + UI_CANDBTW;
  97. sImeG.rcCandBTE.bottom = sImeG.rcCandBTE.top + UI_CANDBTH;
  98. sImeG.xCandWi = sImeG.rcCandBTE.right + sImeG.cxCandBorder * 2 + cxBorder * 4;
  99. sImeG.yCandHi = sImeG.rcCandText.bottom + sImeG.cyCandBorder * 2 + cyBorder * 4;
  100. } else {
  101. sImeG.rcCandText.left = cxBorder;
  102. sImeG.rcCandText.top = 2 * cyBorder + UI_CANDINF;
  103. if(sImeG.xChiCharWi*9 > (UI_CANDICON*6 + UI_CANDBTH*4))
  104. sImeG.rcCandText.right = sImeG.rcCandText.left + sImeG.xChiCharWi * 9;
  105. else
  106. sImeG.rcCandText.right = sImeG.rcCandText.left + (UI_CANDICON*6 + UI_CANDBTH*4);
  107. sImeG.rcCandText.bottom = sImeG.rcCandText.top + sImeG.yChiCharHi * CANDPERPAGE;
  108. sImeG.xCandWi = sImeG.rcCandText.right + sImeG.cxCandBorder * 2 + cxBorder * 4;
  109. sImeG.yCandHi = sImeG.rcCandText.bottom + sImeG.cyCandBorder * 2 + cyBorder * 4;
  110. sImeG.rcCandIcon.left = cxBorder;
  111. sImeG.rcCandIcon.top = cyBorder + 2;
  112. sImeG.rcCandIcon.right = sImeG.rcCandIcon.left + UI_CANDICON;
  113. sImeG.rcCandIcon.bottom = sImeG.rcCandIcon.top + UI_CANDICON;
  114. sImeG.rcCandInf.left = sImeG.rcCandIcon.right;
  115. sImeG.rcCandInf.top = cyBorder + 3;
  116. sImeG.rcCandInf.right = sImeG.rcCandInf.left + UI_CANDICON * 5;
  117. sImeG.rcCandInf.bottom = sImeG.rcCandInf.top + UI_CANDBTH;
  118. sImeG.rcCandBTE.top = cyBorder * 5;
  119. sImeG.rcCandBTE.right = sImeG.rcCandText.right + cxBorder;
  120. sImeG.rcCandBTE.bottom = sImeG.rcCandBTE.top + UI_CANDBTH;
  121. sImeG.rcCandBTE.left = sImeG.rcCandBTE.right - UI_CANDBTW;
  122. sImeG.rcCandBTD.top = cyBorder * 5;
  123. sImeG.rcCandBTD.right = sImeG.rcCandBTE.left;
  124. sImeG.rcCandBTD.bottom = sImeG.rcCandBTD.top + UI_CANDBTH;
  125. sImeG.rcCandBTD.left = sImeG.rcCandBTD.right - UI_CANDBTW;
  126. sImeG.rcCandBTU.top = cyBorder * 5;
  127. sImeG.rcCandBTU.right = sImeG.rcCandBTD.left;
  128. sImeG.rcCandBTU.bottom = sImeG.rcCandBTU.top + UI_CANDBTH;
  129. sImeG.rcCandBTU.left = sImeG.rcCandBTU.right - UI_CANDBTW;
  130. sImeG.rcCandBTH.top = cyBorder * 5;
  131. sImeG.rcCandBTH.right = sImeG.rcCandBTU.left;
  132. sImeG.rcCandBTH.bottom = sImeG.rcCandBTH.top + UI_CANDBTH;
  133. sImeG.rcCandBTH.left = sImeG.rcCandBTH.right - UI_CANDBTW;
  134. }
  135. }
  136. /**********************************************************************/
  137. /* InitImeGlobalData() */
  138. /**********************************************************************/
  139. void PASCAL InitImeGlobalData(
  140. HINSTANCE hInstance)
  141. {
  142. int cxBorder, cyBorder;
  143. int UI_MODE;
  144. HDC hDC;
  145. HGDIOBJ hOldFont;
  146. LOGFONT lfFont;
  147. TCHAR szChiChar[4];
  148. SIZE lTextSize;
  149. HGLOBAL hResData;
  150. int i;
  151. DWORD dwSize;
  152. HKEY hKeyIMESetting;
  153. LONG lRet;
  154. hInst = hInstance;
  155. LoadString(hInst, IDS_IMEREGNAME, szImeRegName, MAX_PATH);
  156. LoadString(hInst, IDS_IMENAME_QW, pszImeName[0], MAX_PATH);
  157. LoadString(hInst, IDS_IMENAME_NM, pszImeName[1], MAX_PATH);
  158. LoadString(hInst, IDS_IMENAME_UNI, pszImeName[2], MAX_PATH);
  159. // get the UI class name
  160. LoadString(hInst, IDS_IMEUICLASS, szUIClassName,
  161. CLASS_LEN);
  162. // get the composition class name
  163. LoadString(hInst, IDS_IMECOMPCLASS, szCompClassName,
  164. CLASS_LEN);
  165. // get the candidate class name
  166. LoadString(hInst, IDS_IMECANDCLASS, szCandClassName,
  167. CLASS_LEN);
  168. // get the status class name
  169. LoadString(hInst, IDS_IMESTATUSCLASS, szStatusClassName,
  170. CLASS_LEN);
  171. //get the ContextMenu class name
  172. LoadString(hInst, IDS_IMECMENUCLASS, szCMenuClassName,
  173. CLASS_LEN);
  174. //get the softkeyboard Menu class name
  175. LoadString(hInst, IDS_IMESOFTKEYMENUCLASS, szSoftkeyMenuClassName,
  176. CLASS_LEN);
  177. // work area
  178. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  179. // border
  180. cxBorder = GetSystemMetrics(SM_CXBORDER);
  181. cyBorder = GetSystemMetrics(SM_CYBORDER);
  182. // get the Chinese char
  183. LoadString(hInst, IDS_CHICHAR, szChiChar, sizeof(szChiChar)/sizeof(TCHAR));
  184. // get size of Chinese char
  185. hDC = GetDC(NULL);
  186. hOldFont = GetCurrentObject(hDC, OBJ_FONT);
  187. GetObject(hOldFont, sizeof(LOGFONT), &lfFont);
  188. sImeG.fDiffSysCharSet = TRUE;
  189. ZeroMemory(&lfFont, sizeof(lfFont));
  190. lfFont.lfHeight = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  191. lfFont.lfCharSet = NATIVE_CHARSET;
  192. lstrcpy(lfFont.lfFaceName, TEXT("Simsun"));
  193. SelectObject(hDC, CreateFontIndirect(&lfFont));
  194. if(!GetTextExtentPoint(hDC, (LPTSTR)szChiChar, lstrlen(szChiChar), &lTextSize))
  195. memset(&lTextSize, 0, sizeof(SIZE));
  196. if (sImeG.rcWorkArea.right < 2 * UI_MARGIN) {
  197. sImeG.rcWorkArea.left = 0;
  198. sImeG.rcWorkArea.right = GetDeviceCaps(hDC, HORZRES);
  199. }
  200. if (sImeG.rcWorkArea.bottom < 2 * UI_MARGIN) {
  201. sImeG.rcWorkArea.top = 0;
  202. sImeG.rcWorkArea.bottom = GetDeviceCaps(hDC, VERTRES);
  203. }
  204. if (sImeG.fDiffSysCharSet) {
  205. DeleteObject(SelectObject(hDC, hOldFont));
  206. }
  207. ReleaseDC(NULL, hDC);
  208. // get text metrics to decide the width & height of composition window
  209. // these IMEs always use system font to show
  210. sImeG.xChiCharWi = lTextSize.cx;
  211. sImeG.yChiCharHi = lTextSize.cy;
  212. if(sImeG.IC_Trace) {
  213. UI_MODE = BOX_UI;
  214. } else {
  215. UI_MODE = LIN_UI;
  216. }
  217. InitCandUIData(cxBorder, cyBorder, UI_MODE);
  218. InitStatusUIData(cxBorder, cyBorder);
  219. // load full ABC table
  220. hResData = LoadResource(hInst, FindResource(hInst,
  221. TEXT("FULLABC"), RT_RCDATA));
  222. *(LPFULLABC)sImeG.wFullABC = *(LPFULLABC)LockResource(hResData);
  223. UnlockResource(hResData);
  224. FreeResource(hResData);
  225. // full shape space
  226. sImeG.wFullSpace = sImeG.wFullABC[0];
  227. #ifndef UNICODE
  228. // reverse internal code to internal code, NT don't need it
  229. for (i = 0; i < (sizeof(sImeG.wFullABC) / 2); i++) {
  230. sImeG.wFullABC[i] = (sImeG.wFullABC[i] << 8) |
  231. (sImeG.wFullABC[i] >> 8);
  232. }
  233. #endif
  234. LoadString(hInst, IDS_STATUSERR, sImeG.szStatusErr,
  235. sizeof(sImeG.szStatusErr)/sizeof(TCHAR));
  236. sImeG.cbStatusErr = lstrlen(sImeG.szStatusErr);
  237. sImeG.iCandStart = CAND_START;
  238. // get the UI offset for near caret operation
  239. RegCreateKey(HKEY_CURRENT_USER, szRegIMESetting, &hKeyIMESetting);
  240. dwSize = sizeof(DWORD);
  241. lRet = RegQueryValueEx(hKeyIMESetting,
  242. szPara,
  243. NULL,
  244. NULL,
  245. (LPBYTE)&sImeG.iPara,
  246. &dwSize);
  247. if (lRet != ERROR_SUCCESS) {
  248. sImeG.iPara = 0;
  249. RegSetValueEx(hKeyIMESetting,
  250. szPara,
  251. (DWORD)0,
  252. REG_BINARY,
  253. (LPBYTE)&sImeG.iPara,
  254. sizeof(int));
  255. }
  256. dwSize = sizeof(DWORD);
  257. lRet = RegQueryValueEx(hKeyIMESetting,
  258. szPerp,
  259. NULL,
  260. NULL,
  261. (LPBYTE)&sImeG.iPerp,
  262. &dwSize);
  263. if (lRet != ERROR_SUCCESS) {
  264. sImeG.iPerp = sImeG.yChiCharHi;
  265. RegSetValueEx(hKeyIMESetting,
  266. szPerp,
  267. (DWORD)0,
  268. REG_BINARY,
  269. (LPBYTE)&sImeG.iPerp,
  270. sizeof(int));
  271. }
  272. dwSize = sizeof(DWORD);
  273. lRet = RegQueryValueEx(hKeyIMESetting,
  274. szParaTol,
  275. NULL,
  276. NULL,
  277. (LPBYTE)&sImeG.iParaTol,
  278. &dwSize);
  279. if (lRet != ERROR_SUCCESS) {
  280. sImeG.iParaTol = sImeG.xChiCharWi * 4;
  281. RegSetValueEx(hKeyIMESetting,
  282. szParaTol,
  283. (DWORD)0,
  284. REG_BINARY,
  285. (LPBYTE)&sImeG.iParaTol,
  286. sizeof(int));
  287. }
  288. dwSize = sizeof(DWORD);
  289. lRet = RegQueryValueEx(hKeyIMESetting,
  290. szPerpTol,
  291. NULL,
  292. NULL,
  293. (LPBYTE)&sImeG.iPerpTol,
  294. &dwSize);
  295. if (lRet != ERROR_SUCCESS) {
  296. sImeG.iPerpTol = lTextSize.cy;
  297. RegSetValueEx(hKeyIMESetting,
  298. szPerpTol,
  299. (DWORD)0,
  300. REG_BINARY,
  301. (LPBYTE)&sImeG.iPerpTol,
  302. sizeof(int));
  303. }
  304. RegCloseKey(hKeyIMESetting);
  305. return;
  306. }
  307. /**********************************************************************/
  308. /* InitImeLocalData() */
  309. /**********************************************************************/
  310. BOOL PASCAL InitImeLocalData(
  311. HINSTANCE hInstL)
  312. {
  313. int cxBorder, cyBorder;
  314. int iContentHi;
  315. // iContentHi is to get the maximum value of predefined COMP_TEXT_Y and
  316. // a real Chinese character's height in the current HDC.
  317. iContentHi = COMP_TEXT_Y;
  318. if ( iContentHi < sImeG.yChiCharHi )
  319. iContentHi = sImeG.yChiCharHi ;
  320. lpImeL->hInst = hInstL;
  321. lpImeL->nMaxKey = 4;
  322. // border + raising edge + sunken edge
  323. cxBorder = GetSystemMetrics(SM_CXBORDER);
  324. cyBorder = GetSystemMetrics(SM_CYBORDER);
  325. // text position relative to the composition window
  326. lpImeL->cxCompBorder = cxBorder * 2;
  327. lpImeL->cyCompBorder = cyBorder * 2;
  328. lpImeL->rcCompText.left = cxBorder;
  329. lpImeL->rcCompText.top = cyBorder;
  330. lpImeL->rcCompText.right = lpImeL->rcCompText.left + sImeG.xChiCharWi * ((lpImeL->nMaxKey + 2) / 2);
  331. lpImeL->rcCompText.bottom = lpImeL->rcCompText.top + iContentHi;
  332. // set the width & height for composition window
  333. lpImeL->xCompWi=lpImeL->rcCompText.right+lpImeL->cxCompBorder*2+cxBorder*4;
  334. lpImeL->yCompHi=lpImeL->rcCompText.bottom+lpImeL->cyCompBorder*2+cyBorder*4;
  335. // default position of composition window
  336. lpImeL->ptDefComp.x = sImeG.rcWorkArea.right -
  337. lpImeL->xCompWi - cxBorder * 2;
  338. lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom -
  339. lpImeL->yCompHi - cyBorder * 2;
  340. lpImeL->fModeConfig = MODE_CONFIG_QUICK_KEY|MODE_CONFIG_PREDICT;
  341. return (TRUE);
  342. }
  343. /**********************************************************************/
  344. /* RegisterIme() */
  345. /**********************************************************************/
  346. void PASCAL RegisterIme(
  347. HINSTANCE hInstance)
  348. {
  349. HKEY hKeyCurrVersion;
  350. HKEY hKeyGB;
  351. DWORD retCode;
  352. TCHAR Buf[LINE_LEN];
  353. DWORD ValueType;
  354. DWORD ValueSize;
  355. // init ime charact
  356. lstrcpy(sImeG.UsedCodes, TEXT("0123456789abcdef"));
  357. sImeG.wNumCodes = (WORD)lstrlen(sImeG.UsedCodes);
  358. sImeG.IC_Enter = 0;
  359. sImeG.IC_Trace = 0;
  360. retCode = OpenReg_PathSetup(&hKeyCurrVersion);
  361. if (retCode) {
  362. RegCreateKey(HKEY_CURRENT_USER, REGSTR_PATH_SETUP, &hKeyCurrVersion);
  363. }
  364. retCode = OpenReg_User (hKeyCurrVersion,
  365. szImeRegName,
  366. &hKeyGB);
  367. if (retCode != ERROR_SUCCESS) {
  368. DWORD dwDisposition;
  369. DWORD Value;
  370. retCode = RegCreateKeyEx (hKeyCurrVersion,
  371. szImeRegName,
  372. 0,
  373. 0,
  374. REG_OPTION_NON_VOLATILE,
  375. KEY_ALL_ACCESS,
  376. NULL,
  377. &hKeyGB,
  378. &dwDisposition);
  379. if ( retCode == ERROR_SUCCESS)
  380. {
  381. Value = 1;
  382. RegSetValueEx(hKeyGB,
  383. szTrace,
  384. (DWORD)0,
  385. REG_DWORD,
  386. (LPBYTE)&Value,
  387. sizeof(DWORD));
  388. }
  389. else
  390. {
  391. // error to create hKeyGB key.
  392. // return here;
  393. RegCloseKey(hKeyCurrVersion);
  394. return;
  395. }
  396. }
  397. ValueSize = sizeof(DWORD);
  398. if (RegQueryValueEx(hKeyGB,
  399. szTrace,
  400. NULL,
  401. (LPDWORD)&ValueType,
  402. (LPBYTE)&sImeG.IC_Trace,
  403. (LPDWORD)&ValueSize) != ERROR_SUCCESS)
  404. {
  405. DWORD Value = 1;
  406. RegSetValueEx(hKeyGB,
  407. szTrace,
  408. (DWORD)0,
  409. REG_DWORD,
  410. (LPBYTE)&Value,
  411. sizeof(DWORD));
  412. RegQueryValueEx(hKeyGB,
  413. szTrace,
  414. NULL,
  415. (LPDWORD)&ValueType,
  416. (LPBYTE)&sImeG.IC_Trace,
  417. (LPDWORD)&ValueSize);
  418. }
  419. #ifdef CROSSREF
  420. if(RegQueryValueEx(hKeyGB,
  421. szRegRevKL,
  422. NULL,
  423. NULL, // null-terminate string
  424. (LPBYTE)&sImeG.hRevKL, // &bData,
  425. &ValueSize) != ERROR_SUCCESS)
  426. sImeG.hRevKL = NULL;
  427. if(RegQueryValueEx (hKeyGB,
  428. szRegRevMaxKey,
  429. NULL,
  430. NULL, //null-terminate string
  431. (LPBYTE)&sImeG.nRevMaxKey, //&bData,
  432. &ValueSize) != ERROR_SUCCESS)
  433. sImeG.hRevKL = NULL;
  434. #endif
  435. RegCloseKey(hKeyGB);
  436. RegCloseKey(hKeyCurrVersion);
  437. return;
  438. }
  439. /**********************************************************************/
  440. /* RegisterImeClass() */
  441. /**********************************************************************/
  442. void PASCAL RegisterImeClass(
  443. HINSTANCE hInstance,
  444. HINSTANCE hInstL)
  445. {
  446. WNDCLASSEX wcWndCls;
  447. // IME UI class
  448. // Register IME UI class
  449. wcWndCls.cbSize = sizeof(WNDCLASSEX);
  450. wcWndCls.cbClsExtra = 0;
  451. wcWndCls.cbWndExtra = sizeof(INT_PTR) * 2;
  452. wcWndCls.hIcon = LoadImage(hInstL, MAKEINTRESOURCE(IDI_IME),
  453. IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
  454. wcWndCls.hInstance = hInstance;
  455. wcWndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
  456. wcWndCls.hbrBackground = GetStockObject(NULL_BRUSH);
  457. wcWndCls.lpszMenuName = (LPTSTR)NULL;
  458. wcWndCls.hIconSm = LoadImage(hInstL, MAKEINTRESOURCE(IDI_IME),
  459. IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
  460. // IME UI class
  461. if (!GetClassInfoEx(hInstance, szUIClassName, &wcWndCls)) {
  462. wcWndCls.style = CS_IME;
  463. wcWndCls.lpfnWndProc = UIWndProc;
  464. wcWndCls.lpszClassName = (LPTSTR)szUIClassName;
  465. RegisterClassEx(&wcWndCls);
  466. }
  467. wcWndCls.style = CS_IME|CS_HREDRAW|CS_VREDRAW;
  468. wcWndCls.hbrBackground = GetStockObject(LTGRAY_BRUSH);
  469. // IME composition class
  470. // register IME composition class
  471. if (!GetClassInfoEx(hInstance, szCompClassName, &wcWndCls)) {
  472. wcWndCls.lpfnWndProc = CompWndProc;
  473. wcWndCls.lpszClassName = (LPTSTR)szCompClassName;
  474. RegisterClassEx(&wcWndCls);
  475. }
  476. // IME candidate class
  477. // register IME candidate class
  478. if (!GetClassInfoEx(hInstance, szCandClassName, &wcWndCls)) {
  479. wcWndCls.lpfnWndProc = CandWndProc;
  480. wcWndCls.lpszClassName = (LPTSTR)szCandClassName;
  481. RegisterClassEx(&wcWndCls);
  482. }
  483. // IME status class
  484. // register IME status class
  485. if (!GetClassInfoEx(hInstance, szStatusClassName, &wcWndCls)) {
  486. wcWndCls.lpfnWndProc = StatusWndProc;
  487. wcWndCls.lpszClassName = (LPTSTR)szStatusClassName;
  488. RegisterClassEx(&wcWndCls);
  489. }
  490. // IME context menu class
  491. if (!GetClassInfoEx(hInstance, szCMenuClassName, &wcWndCls)) {
  492. wcWndCls.style = 0;
  493. wcWndCls.hbrBackground = GetStockObject(NULL_BRUSH);
  494. wcWndCls.lpfnWndProc = ContextMenuWndProc;
  495. wcWndCls.lpszClassName = (LPTSTR)szCMenuClassName;
  496. RegisterClassEx(&wcWndCls);
  497. }
  498. // IME softkeyboard menu class
  499. if (!GetClassInfoEx(hInstance, szSoftkeyMenuClassName, &wcWndCls)) {
  500. wcWndCls.style = 0;
  501. wcWndCls.hbrBackground = GetStockObject(NULL_BRUSH);
  502. wcWndCls.lpfnWndProc = SoftkeyMenuWndProc;
  503. wcWndCls.lpszClassName = (LPTSTR)szSoftkeyMenuClassName;
  504. RegisterClassEx(&wcWndCls);
  505. }
  506. return;
  507. }
  508. /**********************************************************************/
  509. /* ImeDllInit() */
  510. /* Return Value: */
  511. /* TRUE - successful */
  512. /* FALSE - failure */
  513. /**********************************************************************/
  514. BOOL CALLBACK ImeDllInit(
  515. HINSTANCE hInstance, // instance handle of this library
  516. DWORD fdwReason, // reason called
  517. LPVOID lpvReserve) // reserve pointer
  518. {
  519. switch (fdwReason) {
  520. case DLL_PROCESS_ATTACH:
  521. RegisterIme(hInstance);
  522. // init globaldata & load globaldata from resource
  523. #if defined(COMBO_IME)
  524. {
  525. HKEY hKeyCurrVersion;
  526. HKEY hKeyGB;
  527. LONG retCode;
  528. DWORD ValueType;
  529. DWORD ValueSize;
  530. retCode = OpenReg_PathSetup(&hKeyCurrVersion);
  531. if (retCode) {
  532. RegCreateKey(HKEY_CURRENT_USER,
  533. REGSTR_PATH_SETUP,
  534. &hKeyCurrVersion);
  535. }
  536. if ( hKeyCurrVersion )
  537. {
  538. retCode = RegCreateKeyEx(hKeyCurrVersion,
  539. szImeRegName,
  540. 0,
  541. NULL,
  542. REG_OPTION_NON_VOLATILE,
  543. KEY_ALL_ACCESS,
  544. NULL,
  545. &hKeyGB,
  546. NULL);
  547. ValueSize = sizeof(DWORD);
  548. if ( hKeyGB )
  549. {
  550. retCode = RegQueryValueEx(hKeyGB,
  551. szRegImeIndex,
  552. NULL,
  553. (LPDWORD)&ValueType,
  554. (LPBYTE)&sImeL.dwRegImeIndex,
  555. (LPDWORD)&ValueSize);
  556. if ( retCode != ERROR_SUCCESS ) {
  557. //set GB/QW as default
  558. sImeL.dwRegImeIndex = 0;
  559. RegSetValueEx (hKeyGB, szRegImeIndex,
  560. (DWORD)0,
  561. REG_DWORD,
  562. (LPBYTE)&sImeL.dwRegImeIndex,
  563. sizeof(DWORD));
  564. }
  565. //readout current ImeName
  566. szImeName = pszImeName[sImeL.dwRegImeIndex];
  567. RegCloseKey(hKeyGB);
  568. }
  569. RegCloseKey(hKeyCurrVersion);
  570. }
  571. }
  572. #endif //COMBO_IME
  573. if (!hInst) {
  574. InitImeGlobalData(hInstance);
  575. }
  576. if (!lpImeL) {
  577. lpImeL = &sImeL;
  578. InitImeLocalData(hInstance);
  579. }
  580. RegisterImeClass(hInstance, hInstance);
  581. break;
  582. case DLL_PROCESS_DETACH:
  583. {
  584. WNDCLASSEX wcWndCls;
  585. if (GetClassInfoEx(hInstance, szCMenuClassName, &wcWndCls)) {
  586. UnregisterClass(szCMenuClassName, hInstance);
  587. }
  588. if (GetClassInfoEx(hInstance, szSoftkeyMenuClassName, &wcWndCls)) {
  589. UnregisterClass(szSoftkeyMenuClassName, hInstance);
  590. }
  591. if (GetClassInfoEx(hInstance, szStatusClassName, &wcWndCls)) {
  592. UnregisterClass(szStatusClassName, hInstance);
  593. }
  594. if (GetClassInfoEx(hInstance, szCandClassName, &wcWndCls)) {
  595. UnregisterClass(szCandClassName, hInstance);
  596. }
  597. if (GetClassInfoEx(hInstance, szCompClassName, &wcWndCls)) {
  598. UnregisterClass(szCompClassName, hInstance);
  599. }
  600. if (!GetClassInfoEx(hInstance, szUIClassName, &wcWndCls)) {
  601. } else if (!UnregisterClass(szUIClassName, hInstance)) {
  602. } else {
  603. DestroyIcon(wcWndCls.hIcon);
  604. DestroyIcon(wcWndCls.hIconSm);
  605. }
  606. }
  607. break;
  608. default:
  609. break;
  610. }
  611. return (TRUE);
  612. }
  613. int strbytelen (LPTSTR lpStr)
  614. {
  615. #ifdef UNICODE
  616. int i, len, iRet;
  617. len = lstrlen(lpStr);
  618. for (i = 0, iRet = 0; i < len; i++, iRet++) {
  619. if (lpStr[i] > 0x100)
  620. iRet++;
  621. }
  622. return iRet;
  623. #else
  624. return lstrlen(lpStr);
  625. #endif
  626. }