PageRenderTime 47ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/ime/imm.c

https://bitbucket.org/ryo_on/skkime-1.5-a
C | 1352 lines | 750 code | 78 blank | 524 comment | 175 complexity | 2914c19431e7b42f18a229f98ac15f0c MD5 | raw file
Possible License(s): GPL-2.0
  1. /* # SKKIME1.0 (Simple Kana-Kanji Input Method Editor for Windows2000)
  2. * imm.c
  3. * This file is part of skkime1.0.
  4. * Copyright (C) 1999
  5. * Takashi SAKAMOTO (tatari_sakamoto@nifty.ne.jp)
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2, or (at your option)
  10. * any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with skkinput; see the file COPYING. If not, write to
  19. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include "windows.h"
  22. #include "tchar.h"
  23. #include "immdev.h"
  24. #include "skki1_5.h"
  25. #include "resource.h"
  26. #include "ImeDoc.h"
  27. #include "TSearchSession.h"
  28. #include "TLispSession.h"
  29. #include "skkui.h"
  30. #include "jstring.h"
  31. #include "ImeConfig.h"
  32. /*
  33. * Private Prototypes
  34. */
  35. static DWORD PASCAL getImeLeftMenuItems (HIMC, DWORD, DWORD, LPMYIMEMENUITEMINFO, LPMYIMEMENUITEMINFO, DWORD) ;
  36. static DWORD PASCAL getImeRightMenuItems (HIMC, DWORD, DWORD, LPMYIMEMENUITEMINFO, LPMYIMEMENUITEMINFO, DWORD) ;
  37. static DWORD PASCAL getImeRightSubMenuItems (HIMC, DWORD, DWORD, LPMYIMEMENUITEMINFO, LPMYIMEMENUITEMINFO, DWORD) ;
  38. static long PASCAL insertStringMenuItem (LPMYIMEMENUITEMINFO, const LPMYSTRTYPEPAIR, UINT) ;
  39. static long PASCAL insertStringMenuItemEx (LPMYIMEMENUITEMINFO, const LPMYSTRTYPEPAIREX, UINT) ;
  40. static long PASCAL insertSeparatorMenuItem (LPMYIMEMENUITEMINFO) ;
  41. static long PASCAL insertInputModeMenuItems(HIMC, LPMYIMEMENUITEMINFO) ;
  42. /***********************************************************************
  43. * ImeInquire ()
  44. * For Windows 95, Windows 98, and Windows NT 3.51
  45. * ImeInquire 関数は IME の初期化を取り扱う。また、ImeInquire 関数は
  46. * IMEINFO 構造体及び IME の UI class name も又返す。
  47. * BOOL
  48. * ImeInquire(
  49. * LPIMEINFO lpIMEInfo,
  50. * LPTSTR lpszWndClass,
  51. * LPCTSTR lpszData
  52. * )
  53. * Parameters
  54. * lpIMEInfo
  55. * IME info 構造体を指すポインタ。
  56. * lpszWndClass
  57. * IME によって window class 名が詰められる。この名前が IME の UI
  58. * class 名である。
  59. * lpszData
  60. * IME オプションブロック。このバージョンでは NULL。
  61. *
  62. * For Windows NT 4.0 and Windows 2000
  63. * BOOL
  64. * ImeInquire(
  65. * LPIMEINFO lpIMEInfo,
  66. * LPTSTRlpszWndClass,
  67. * DWORD dwSystemInfoFlags
  68. * )
  69. * Parameters
  70. * lpIMEInfo
  71. * IME info 構造体を指すポインタ。
  72. * lpszWndClass
  73. * IME によって window class 名が詰められる。この名前が IME の UI
  74. * class 名である。
  75. * dwSystemInfoFlags
  76. * システムによって提供されるシステム情報を変更する。次のようなフラグ
  77. * が与えられる。
  78. * IME_SYSINFO_WINLOGON
  79. * IME にクライアントプロセスが Winlogon プロセスであることを IME
  80. * に知らせる。IME はこのフラグが指定された時 IME の設定をユーザに
  81. * 許すべきではない。
  82. * IME_SYSINFO_WOW16
  83. * IME にクライアントプロセスは 16-bit アプリケーションであること
  84. * を知らせる。
  85. * Return Values
  86. * 成功すれば、TRUE。そうでなければ、FALSE。
  87. ***********************************************************************/
  88. BOOL WINAPI
  89. ImeInquire (
  90. LPIMEINFO lpIMEInfo,
  91. LPTSTR lpszClassName,
  92. DWORD dwSystemInfoFlags)
  93. {
  94. #if defined (_DEBUG)
  95. static TCHAR tszLastUser [UNLEN + 1] = { TEXT ('\0') } ;
  96. #endif
  97. /*
  98. * IMEINFO 構造体を初期化する。
  99. */
  100. lpIMEInfo->dwPrivateDataSize = sizeof (UIEXTRA) ;
  101. lpIMEInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST |
  102. #if defined (MIXED_UNICODE_ANSI) || defined (UNICODE)
  103. IME_PROP_UNICODE |
  104. #endif
  105. IME_PROP_AT_CARET ;
  106. lpIMEInfo->fdwConversionCaps = IME_CMODE_LANGUAGE |
  107. IME_CMODE_FULLSHAPE |
  108. IME_CMODE_ROMAN |
  109. IME_CMODE_CHARCODE ;
  110. lpIMEInfo->fdwSentenceCaps = 0L ;
  111. lpIMEInfo->fdwUICaps = UI_CAP_2700 ;
  112. /*
  113. * fdwSCSCaps
  114. * fdwSCSCaps ビットは SetCompositionString の能力を指定する。
  115. * ----------------------------------------------------------
  116. * SCS_CAP_COMPSTR
  117. * IME は SCS_SETSTR で composition string を生成できる。
  118. * SCS_CAP_MAKEREAD
  119. * ImmSetCompositionString を SCS_SETSTR で呼び出した時に
  120. * IME は compositoin string の reading string を lpRead
  121. * なしに生成することができる。この能力のある IME の下で
  122. * はアプリケーションは SCS_SETSTR に lpRead を設定する
  123. * 必要がない。
  124. * SCS_CAP_CONVERTSTRING
  125. * IME は reconvert 機能を持っている。
  126. * ----------------------------------------------------------
  127. * SKK は composition string を直接操作されるようなインター
  128. * フェースと無茶苦茶相性が良くないので、これらの能力は持たな
  129. * い。
  130. */
  131. lpIMEInfo->fdwSCSCaps = SCS_CAP_COMPSTR | SCS_CAP_MAKEREAD | SCS_CAP_SETRECONVERTSTRING ;
  132. lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION ;
  133. /*
  134. * 呼び出し側が IME UI class 名を知ることができるように lpszClassName
  135. * に UI class 名を代入する。
  136. */
  137. #if defined (MIXED_UNICODE_ANSI)
  138. memcpy ((LPWSTR)lpszClassName, (LPWSTR)g_wszUIClassName, (lstrlenW((LPWSTR)g_wszUIClassName) + 1) * sizeof(WCHAR)) ;
  139. #else
  140. lstrcpy (lpszClassName, (LPTSTR)g_szUIClassName) ;
  141. #endif
  142. /* Logon Session かどうか */
  143. g_bSkkImeSecure = ((dwSystemInfoFlags & IME_SYSINFO_WINLOGON) != 0) ;
  144. return TRUE ;
  145. }
  146. /***********************************************************************
  147. * ImeConversionList
  148. * ImeConversionList 関数によって別の文字もしくは文字列の変換結果のリス
  149. * トを得ることができる。
  150. * DWORD
  151. * IMEConversionList(
  152. * HIMC hIMC,
  153. * LPCTSTR lpSrc,
  154. * LPCANDIDATELIST lpDst,
  155. * DWORD dwBufLen,
  156. * UINT uFlag
  157. * )
  158. * Parameters
  159. * hIMC
  160. * 入力コンテキストのハンドル。
  161. * lpSrc
  162. * 変換される文字列
  163. * lpDst
  164. * 変換結果が格納されるバッファを指すポインタ。
  165. * dwBufLen
  166. * 変換結果を格納するバッファの大きさ。
  167. * uFlag
  168. * 現在は次の3つのフラグの1つを設定することができる。
  169. * ・GCL_CONVERSION
  170. * 読み文字列を lpSrc パラメータに設定する。IME は lpDst パラメ
  171. * ータにその変換結果を返す。
  172. * ・GCL_REVERSECONVERSION
  173. * 変換結果文字列を lpSrc パラメータに設定する。IME はその読みを
  174. * lpDstパラメータに返す。
  175. * ・GCL_REVERSE_LENGTH
  176. * lpSrc パラメータに変換結果文字列を設定する。IME は
  177. * GCL_REVERSECONVERSION の扱える長さを返す。例えば、IME は
  178. * sentence period を持った変換結果を読みに変換することができな
  179. * い。結果として、sentence period を除いたバイト単位で文字列長
  180. * を返す。
  181. * Return Values
  182. * 変換結果文字列リストのバイト数を返す。
  183. * Comments
  184. * この関数はアプリケーションもしくは IME-related メッセージを作ら
  185. * ない IME によって呼び出されることを意図している。それゆえに、IME
  186. * はこの関数 IME-related メッセージを生成すべきでない。
  187. ***********************************************************************/
  188. DWORD WINAPI
  189. ImeConversionList (
  190. HIMC hIMC,
  191. LPCTSTR lpSource,
  192. LPCANDIDATELIST pCandList,
  193. DWORD dwBufLen,
  194. UINT uFlags)
  195. {
  196. #if defined (MIXED_UNICODE_ANSI)
  197. return 0 ;
  198. #else
  199. struct CTSearchSession* pHenkanSession ;
  200. LPCDSTR dstrResult ;
  201. int nNeedLength, nCandidate, iAnnotationType, nKeyLen ;
  202. DWORD dwSize ;
  203. DCHAR bufTemp [256] ;
  204. /* 逆変換は実行できない。
  205. if (uFlags == GCL_REVERSECONVERSION || uFlags == GCL_REVERSE_LENGTH)
  206. return 0 ;
  207. */
  208. if (uFlags != GCL_CONVERSION)
  209. return 0 ;
  210. nKeyLen = wcstodcs_n (bufTemp, ARRAYSIZE (bufTemp), lpSource, lstrlen (lpSource)) ;
  211. /* 数値変換の設定がうまく取れないのはまずいか…。
  212. */
  213. pHenkanSession = THenkanSession_pCreate (bufTemp, nKeyLen, SEARCH_OKURI_NASHI, ImeConfig_bSkkNumericConversionp (), ImeConfig_bSkkNumConvertFloatp ()) ;
  214. if (pHenkanSession == NULL)
  215. return 0 ;
  216. iAnnotationType = ImeConfig_iGetSkkShowAnnotationType () ;
  217. nCandidate = 0 ;
  218. nNeedLength = 0 ;
  219. for ( ; ; ) {
  220. dstrResult = TSearchSession_pGetReferCandidate (pHenkanSession) ;
  221. if (dstrResult == NULL)
  222. dstrResult = TSearchSession_pGetCandidate (pHenkanSession) ;
  223. if (dstrResult != NULL) {
  224. int nResultWLen, nResultDLen ;
  225. /* Lisp Conversion と Annotation の処理。
  226. */
  227. nResultDLen = dcslen (dstrResult) ;
  228. if (iAnnotationType != DISABLE_ANNOTATION) {
  229. LPCDSTR pdSrc, pdNote ;
  230. int nWordLen, nNoteLen, nWordWLen, nNoteWLen ;
  231. pdSrc = dstrResult + nResultDLen - 1 ;
  232. while (pdSrc >= dstrResult && *pdSrc != L';')
  233. pdSrc -- ;
  234. if (pdSrc >= dstrResult && *pdSrc == L';') {
  235. pdNote = pdSrc + 1 ;
  236. nNoteLen = nResultDLen - (pdNote - dstrResult) ;
  237. nWordLen = pdSrc - dstrResult ;
  238. } else {
  239. nNoteLen = 0 ;
  240. nWordLen = nResultDLen ;
  241. }
  242. nWordWLen = nNoteWLen = -1 ;
  243. if (nWordLen > 1 && dstrResult [0] == L'(' && dstrResult [nWordLen - 1] == L')') {
  244. if (TLispSession_bEval (dstrResult, nWordLen, bufTemp, ARRAYSIZE (bufTemp) - 1)) {
  245. bufTemp [ARRAYSIZE (bufTemp) - 1] = L'\0' ;
  246. nWordWLen = dcstowcs (NULL, 0, bufTemp, dcslen (bufTemp)) ;
  247. }
  248. }
  249. if (nWordWLen < 0) {
  250. nWordWLen = dcstowcs (NULL, 0, dstrResult, nWordLen) ;
  251. }
  252. if (nNoteLen > 1 && pdNote [0] == L'(' && pdNote [nNoteLen - 1] == L')') {
  253. if (TLispSession_bEval (pdNote, nNoteLen, bufTemp, ARRAYSIZE (bufTemp) - 1)) {
  254. bufTemp [ARRAYSIZE (bufTemp) - 1] = L'\0' ;
  255. nNoteWLen = dcstowcs (NULL, 0, bufTemp, dcslen (bufTemp)) ;
  256. }
  257. }
  258. if (nNoteWLen < 0) {
  259. if (nNoteLen > 0) {
  260. nNoteWLen = dcstowcs (NULL, 0, pdNote, nNoteLen) ;
  261. } else {
  262. nNoteWLen = 0 ;
  263. }
  264. }
  265. nResultWLen = nWordWLen + nNoteWLen + ((nNoteWLen > 0)? 1 : 0) ;
  266. } else {
  267. nResultWLen = dcstowcs (NULL, 0, dstrResult, nResultDLen) ;
  268. }
  269. nNeedLength += nResultWLen + 1 ;
  270. nCandidate ++ ;
  271. }
  272. if (! TSearchSession_bNextCandidate (pHenkanSession))
  273. break ;
  274. }
  275. TSearchSession_bRewind (pHenkanSession) ;
  276. dwSize = sizeof (CANDIDATELIST) + sizeof (DWORD) * nCandidate + sizeof (MYCHAR) * nNeedLength ;
  277. if (pCandList != NULL && dwBufLen >= sizeof (CANDIDATELIST)) {
  278. pCandList->dwSize = dwSize ;
  279. pCandList->dwStyle = IME_CAND_READ ;
  280. pCandList->dwCount = (DWORD) nCandidate ;
  281. pCandList->dwPageSize = (nCandidate < MAX_SKKCANDPAGESIZE)? nCandidate : MAX_SKKCANDPAGESIZE ;
  282. pCandList->dwSelection = 0 ;
  283. pCandList->dwPageStart = 0 ;
  284. }
  285. if (pCandList != NULL && dwBufLen >= dwSize) {
  286. LPMYSTR pCandidateStr ;
  287. LPMYSTR pLast ;
  288. DWORD* pdwCandidateOffset ;
  289. DWORD* pdwAnnotationOffset ;
  290. int i ;
  291. pCandidateStr = (LPMYSTR)((LPSTR)pCandList + sizeof (CANDIDATELIST) + sizeof (DWORD) * nCandidate * 2) ;
  292. pLast = pCandidateStr + nNeedLength ;
  293. pdwCandidateOffset = pCandList->dwOffset ;
  294. pdwAnnotationOffset = pdwCandidateOffset + nCandidate ;
  295. for (i = 0 ; i < nCandidate ; i ++) {
  296. *pdwCandidateOffset = (DWORD)((LPSTR)pCandidateStr - (LPSTR)pCandList) ;
  297. *pdwAnnotationOffset = 0 ;
  298. dstrResult = TSearchSession_pGetReferCandidate (pHenkanSession) ;
  299. if (dstrResult == NULL)
  300. dstrResult = TSearchSession_pGetCandidate (pHenkanSession) ;
  301. if (dstrResult != NULL) {
  302. int nResultLen ;
  303. /* Lisp Eval が必要かどうかをチェックするために Annotation と本体を分離する。
  304. */
  305. nResultLen = dcslen (dstrResult) ;
  306. if (iAnnotationType != DISABLE_ANNOTATION) {
  307. LPCDSTR pdSrc, pdNote, pdWord ;
  308. int nWordLen, nNoteLen ;
  309. pdSrc = dstrResult + nResultLen - 1 ;
  310. pdWord = dstrResult ;
  311. while (pdSrc >= dstrResult && *pdSrc != L';')
  312. pdSrc -- ;
  313. if (pdSrc >= dstrResult && *pdSrc == L';') {
  314. pdNote = pdSrc + 1 ;
  315. nNoteLen = nResultLen - (pdNote - dstrResult) ;
  316. nWordLen = pdSrc - dstrResult ;
  317. } else {
  318. nNoteLen = 0 ;
  319. nWordLen = nResultLen ;
  320. }
  321. /* Word を Eval する必要があるかどうかチェックする。*/
  322. if (nWordLen > 1 && dstrResult [0] == L'(' && dstrResult [nWordLen - 1] == L')') {
  323. if (TLispSession_bEval (dstrResult, nWordLen, bufTemp, ARRAYSIZE (bufTemp) - 1)) {
  324. bufTemp [ARRAYSIZE (bufTemp) - 1] = L'\0' ;
  325. nWordLen = dcslen (bufTemp) ;
  326. pdWord = bufTemp ;
  327. }
  328. }
  329. if (nWordLen > 0) {
  330. int n = dcstowcs (pCandidateStr, pLast - pCandidateStr, pdWord, nWordLen) ;
  331. pCandidateStr [n] = L'\0' ;
  332. pCandidateStr += n + 1 ;
  333. } else {
  334. *pCandidateStr ++ = L'\0' ;
  335. }
  336. /* Annotation を Eval する必要があるかどうかチェックする。*/
  337. if (nNoteLen > 1 && pdNote [0] == L'(' && pdNote [nNoteLen - 1] == L')') {
  338. if (TLispSession_bEval (pdNote, nNoteLen, bufTemp, ARRAYSIZE (bufTemp) - 1)) {
  339. bufTemp [ARRAYSIZE (bufTemp) - 1] = L'\0' ;
  340. nNoteLen = dcslen (bufTemp) ;
  341. pdNote = bufTemp ;
  342. }
  343. }
  344. if (nNoteLen > 0) {
  345. int n = dcstowcs (pCandidateStr, pLast - pCandidateStr, pdNote, nNoteLen) ;
  346. pCandidateStr [n] = L'\0' ;
  347. *pdwAnnotationOffset = (DWORD)((LPSTR)pCandidateStr - (LPSTR)pCandList) ;
  348. pCandidateStr += n + 1 ;
  349. }
  350. } else {
  351. int n = dcstowcs (pCandidateStr, pLast - pCandidateStr, dstrResult, nResultLen) ;
  352. pCandidateStr [n] = L'\0' ;
  353. pCandidateStr += n + 1 ;
  354. }
  355. pdwCandidateOffset ++ ;
  356. pdwAnnotationOffset ++ ;
  357. }
  358. TSearchSession_bNextCandidate (pHenkanSession) ;
  359. }
  360. }
  361. TSearchSession_vDestroy (pHenkanSession) ;
  362. return dwSize ;
  363. #endif
  364. }
  365. /***********************************************************************
  366. * ImeDestroy()
  367. * ImeDestroy 関数は IME 自身を終了させる。
  368. * BOOL
  369. * ImeDestroy(
  370. * UINT uReserved
  371. * )
  372. * Parameters
  373. * uReserved
  374. * 予約されているけど、現在は 0 であれぞかし。このバージョンで
  375. * は、0でなかったら FALSE を返すこと。
  376. * Return Values
  377. * 関数が成功したら、TRUE。そうじゃなかったら、FALSE。
  378. ***********************************************************************/
  379. BOOL WINAPI
  380. ImeDestroy (
  381. UINT uForce)
  382. {
  383. DEBUGPRINTFEX (99, (MYTEXT ("ImeDestroy (uReserved:%x)\n"), uForce)) ;
  384. if (uForce)
  385. return FALSE ;
  386. /*
  387. * 終了処理を書くべきなのだが…InputContext が無いと解放すべき資源が
  388. * 分からないような…。結局何もできないのでは?
  389. * IME 全体で共有している資源は全て skkiserv.exe に渡したので、何も
  390. * することがない?
  391. */
  392. return TRUE ;
  393. }
  394. /***********************************************************************
  395. * ImeEscape
  396. * ImeEscape 関数はアプリケーションに、他の IMM 関数では直接に利用でき
  397. * ないような IME の特性にアクセスすることを許す。
  398. * これは IME の country-specific 関数もしくは private 関数に対してなく
  399. * てはならないものである…らしい。
  400. * LRESULT
  401. * ImeEscape(
  402. * HIMC hIMC,
  403. * UINT uEscape,
  404. * LPVOID lpData
  405. * )
  406. * Parameters
  407. * hIMC
  408. * 入力コンテキストのハンドル。
  409. * uEscape
  410. * 実行されるエスケープ関数を指定する。
  411. * lpData
  412. * 指定されたエスケープに必要なデータを指すポインタ。
  413. * ImeEscape 関数は次のようなエスケープ関数をサポートしている。
  414. * IME_ESC_QUERY _SUPPORT
  415. * 実装されているかどうかチェックする。もし、このエスケープが実装さ
  416. * れていなかったら零を返す。
  417. * IME_ESC_RESERVED_FIRST
  418. * IME_ESC_RESERVED_FIRST と IME_ESC_RESERVED_LAST の間のエスケープ
  419. * がシステムに予約される。
  420. * IME_ESC_RESERVED_LAST
  421. * IME_ESC_RESERVED_FIRST と IME_ESC_RESERVED_LAST の間のエスケープ
  422. * がシステムに予約される。
  423. * IME_ESC_PRIVATE_FIRST
  424. * IME_ESC_PRIVATE_FIRST と IME_ESC_PRIVATE_LAST の間のエスケープが
  425. * IME に予約される。IME は自由に自分の目的に応じてこれらのエスケー
  426. * プ関数を使うことができる。
  427. * IME_ESC_PRIVATE_LAST
  428. * IME_ESC_PRIVATE_FIRST と IME_ESC_PRIVATE_LAST の間のエスケープが
  429. * IME に予約される。IME は自由に自分の目的に応じてこれらのエスケー
  430. * プ関数を使うことができる。
  431. * IME_ESC_SEQUENCE_TO_INTERNAL
  432. * 中国語固有のエスケープ。Far East プラットフォームの下で動くこと
  433. * を要求するアプリケーションはこれを使うべきではない。中国語EUDC
  434. * エディタのためのものである。*(LPWORD)lpData は sequence code
  435. * であり、返り値はその sequence code に対する文字コードである。
  436. * IME_ESC_GETHELPFILENAME
  437. * IME のヘルプファイルの名前を得るエスケープ。関数から戻った時に
  438. * (LPTSTR)lpData は IME ヘルプファイルのフルパスになっている。
  439. * パス名は 80 * sizeof (TCHAR) より短かい。この関数は Windows'98
  440. * Windows 2000 に追加されている。
  441. * IME_ESC_PRIVATE_HOTKEY
  442. * lpData は hot key ID を格納している DWORD へのポインタである。
  443. * (IME_HOTKEY_PRIVATE_FIRST からIME_HOTKEY_PRIVATE_LAST の範囲)
  444. * システムがこの範囲内の hot key を受けとった後、IMM が
  445. * ImeEscape 関数を使って IME にディスパッチする。WindowsR95 で
  446. * はサポートしていない。
  447. * Return Values
  448. * 失敗したら 0 になる。さもなくばエスケープ関数に従って返り値が
  449. * 決まる。
  450. * Comments
  451. * パラメータが正当かどうかは各々のエスケープ関数による。
  452. * uEscape が IME_ESC_QUERY_SUPPORT の時、lpData は IME エスケー
  453. * プ値を含んだ変数へのポインタである。次のサンプルは、IME が
  454. * IME_ESC_GETHELPFILENAME をサポートしているかどうかを決定する
  455. * のに利用できる。
  456. * DWORD dwEsc = IME_ESC_GETHELPFILENAME ;
  457. * LRESULT lRet = ImmEscape(hKL, hIMC, IME_ESC_QUERYSUPPORT, (LPVOID)&dwEsc) ;
  458. * See Also
  459. * ImmEscape
  460. ***********************************************************************/
  461. LRESULT WINAPI
  462. ImeEscape (
  463. HIMC hIMC,
  464. UINT uSubFunc,
  465. LPVOID lpData)
  466. {
  467. LRESULT lRet = FALSE ;
  468. DEBUGPRINTFEX (99, (TEXT ("ImeEscape (hIMC: %ld, uSubFunc: %x, lpData: %p)"), hIMC, uSubFunc, lpData)) ;
  469. switch (uSubFunc){
  470. case IME_ESC_QUERY_SUPPORT:
  471. switch (*(LPUINT)lpData){
  472. case IME_ESC_QUERY_SUPPORT:
  473. case IME_ESC_PRI_GETDWORDTEST:
  474. case IME_ESC_GETHELPFILENAME:
  475. lRet = TRUE ;
  476. break ;
  477. default:
  478. lRet = FALSE ;
  479. break ;
  480. }
  481. break ;
  482. case IME_ESC_PRI_GETDWORDTEST:
  483. lRet = 0x12345678 ;
  484. break ;
  485. case IME_ESC_GETHELPFILENAME:
  486. Mylstrcpy ((LPMYSTR)lpData, MYTEXT("SKKI1_0.HLP")) ;
  487. lRet = TRUE ;
  488. break ;
  489. default:
  490. lRet = FALSE ;
  491. break ;
  492. }
  493. return lRet ;
  494. }
  495. /***********************************************************************
  496. * ImeSetActiveContext ()
  497. * ImeSetActiveContext 関数は current IME に Input Context が active に
  498. * なったことを知らせる。
  499. * BOOL
  500. * ImeSetActiveContext(
  501. * HIMC hIMC,
  502. * BOOL fFlag
  503. * )
  504. * Parameters
  505. * hIMC
  506. * Input Context Handle
  507. * fFlag
  508. * TRUE ならアクティブに FALSE なら非アクティブになったことを示
  509. * す。
  510. * Return Values
  511. * 成功したら TRUE を、さもなくば FALSE を返す。
  512. * Comments
  513. * IME は新しく選択された Input Context についてこの関数で知らされ
  514. * る。IME は初期化を実行してよいが、要求されているわけではない。
  515. * See Also
  516. * ImeSetActiveContext
  517. ***********************************************************************/
  518. BOOL WINAPI
  519. ImeSetActiveContext (
  520. HIMC hIMC,
  521. BOOL fFlag)
  522. {
  523. TRANSMSG GnMsg ;
  524. LPINPUTCONTEXT lpIMC ;
  525. DEBUGPRINTFEX (106, (TEXT ("ImeSetActiveContext (hIMC: %lx, fFlag:%d)\n"), hIMC, fFlag)) ;
  526. if (!hIMC) {
  527. #if !defined (NO_TSF)
  528. if (fFlag)
  529. vTSF_ActivateLanguageBar (hIMC, TRUE) ;
  530. #endif
  531. return TRUE ;
  532. }
  533. lpIMC = (LPINPUTCONTEXT)ImmLockIMC (hIMC) ;
  534. if (lpIMC){
  535. if (ImmGetIMCCSize (lpIMC->hCompStr) >= sizeof (MYCOMPSTR)) {
  536. GnMsg.message = WM_IME_NOTIFY ;
  537. GnMsg.wParam = IMN_PRIVATE ;
  538. if (fFlag){
  539. GnMsg.lParam = IMN_PRIVATE_ACTIVATECONTEXT ;
  540. GenerateMessage (hIMC, lpIMC, g_lpCurTransKey, (LPTRANSMSG)&GnMsg) ;
  541. TSkkIme_vUpdateConfig (hIMC) ;
  542. } else {
  543. GnMsg.lParam = IMN_PRIVATE_DEACTIVATECONTEXT ;
  544. GenerateMessage (hIMC, lpIMC, g_lpCurTransKey, (LPTRANSMSG)&GnMsg) ;
  545. }
  546. /*
  547. * 現在のところ、DEACTIVATECONTEXT は利用していないので、以下のコードはコメント
  548. * とする。(Wed Nov 09 21:44:01 2005)
  549. *
  550. if (fFlag){
  551. GnMsg.lParam = IMN_PRIVATE_ACTIVATECONTEXT ;
  552. GenerateMessage (hIMC, lpIMC, g_lpCurTransKey, (LPTRANSMSG)&GnMsg) ;
  553. TSkkIme_vInvalidateConfig (hIMC, TRUE) ;
  554. } else {
  555. GnMsg.lParam = IMN_PRIVATE_DEACTIVATECONTEXT ;
  556. GenerateMessage (hIMC, lpIMC, g_lpCurTransKey, (LPTRANSMSG)&GnMsg) ;
  557. }
  558. */
  559. }
  560. ImmUnlockIMC (hIMC) ;
  561. }
  562. return TRUE ;
  563. }
  564. /***********************************************************************
  565. * ImeProcessKey ()
  566. * ImeProcessKey 関数は IMM を通して与えられた全てのキーストロークを前処
  567. * 理して、もしそのキーが与えられた Input Context で IME に必要なもので
  568. * あれば TRUE を返す。
  569. * BOOL
  570. * ImeProcessKey(
  571. * HIMC hIMC,
  572. * UINT uVirKey,
  573. * DWORD lParam,
  574. * CONST LPBYTE lpbKeyState
  575. * )
  576. * Parameters
  577. * hIMC
  578. * Input context handle
  579. * uVirKey
  580. * 処理されるべき仮想キー。
  581. * lParam
  582. * キーメッセージの lParam。(WM_KEYDOWN,WM_KEYUP の LPARAM)
  583. * lpbKeyState
  584. * 現在のキーボードの状態を含んだ256バイトの配列を指すポインタ。
  585. * IME はこの内容を変更すべきではない。
  586. * Return Values
  587. * 成功なら TRUE。そうでなければ FALSE。
  588. * Comments
  589. * システムはキーが IME によって取り扱われるべきか否かをこの関数を
  590. * 呼び出すことによって決定している。アプリケーションがキーメッセー
  591. * ジを受け取る前にこの関数が TRUE を返せば、IME はそのキーを処理す
  592. * る。システムは ImeToAsciiEx 関数を呼び出す。
  593. * FALSE を返したならば、システムはそのキーが IME によって処理され
  594. * ないことが分かるのでキーメッセージはアプリケーションに送られる。
  595. ***********************************************************************/
  596. BOOL WINAPI
  597. ImeProcessKey (
  598. HIMC hIMC,
  599. UINT vKey,
  600. LPARAM lKeyData,
  601. CONST LPBYTE lpbKeyState)
  602. {
  603. LPINPUTCONTEXT lpIMC ;
  604. BOOL fOpen ;
  605. BOOL fEaten = FALSE ;
  606. LPCOMPOSITIONSTRING lpCompStr ;
  607. LPMYCOMPSTR lpMyCompStr ;
  608. if (lKeyData & 0x80000000)
  609. return FALSE ;
  610. lpIMC = ImmLockIMC (hIMC) ;
  611. if (!lpIMC)
  612. return FALSE ;
  613. fOpen = lpIMC->fOpen ;
  614. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC (lpIMC->hCompStr) ;
  615. if (lpCompStr != NULL) {
  616. struct TMSG msg ;
  617. BOOL fToggleIME ;
  618. lpMyCompStr = (LPMYCOMPSTR) lpCompStr ;
  619. msg.m_nMessage = WM_KEYDOWN ;
  620. msg.m_wParam = vKey ; /* wParam, lParam の設定はこれで VK_KEYDOWN に相当するのか? 特殊なメッセージにするのか? */
  621. msg.m_lParam = lKeyData ;
  622. msg.m_rParam = 0 ;
  623. if (lpbKeyState != NULL) {
  624. msg.m_rParam |= (lpbKeyState [VK_LCONTROL] & 0x80)? KEYMASK_LCONTROL : 0 ;
  625. msg.m_rParam |= (lpbKeyState [VK_RCONTROL] & 0x80)? KEYMASK_RCONTROL : 0 ;
  626. msg.m_rParam |= (lpbKeyState [VK_LMENU] & 0x80)? KEYMASK_LMENU : 0 ;
  627. msg.m_rParam |= (lpbKeyState [VK_RMENU] & 0x80)? KEYMASK_RMENU : 0 ;
  628. msg.m_rParam |= (lpbKeyState [VK_LSHIFT] & 0x80)? KEYMASK_LSHIFT : 0 ;
  629. msg.m_rParam |= (lpbKeyState [VK_RSHIFT] & 0x80)? KEYMASK_RSHIFT : 0 ;
  630. msg.m_rParam |= (lpbKeyState [VK_SCROLL] & 0x80)? KEYMASK_SCROLL : 0 ;
  631. msg.m_rParam |= (lpbKeyState [VK_NUMLOCK] & 0x80)? KEYMASK_NUMLOCK : 0 ;
  632. } else {
  633. msg.m_rParam |= (GetKeyState (VK_LCONTROL))? KEYMASK_LCONTROL : 0 ;
  634. msg.m_rParam |= (GetKeyState (VK_RCONTROL))? KEYMASK_RCONTROL : 0 ;
  635. msg.m_rParam |= (GetKeyState (VK_LMENU))? KEYMASK_LMENU : 0 ;
  636. msg.m_rParam |= (GetKeyState (VK_RMENU))? KEYMASK_RMENU : 0 ;
  637. msg.m_rParam |= (GetKeyState (VK_LSHIFT))? KEYMASK_LSHIFT : 0 ;
  638. msg.m_rParam |= (GetKeyState (VK_RSHIFT))? KEYMASK_RSHIFT : 0 ;
  639. msg.m_rParam |= (GetKeyState (VK_SCROLL))? KEYMASK_SCROLL : 0 ;
  640. msg.m_rParam |= (GetKeyState (VK_NUMLOCK))? KEYMASK_NUMLOCK : 0 ;
  641. }
  642. msg.m_nTime = GetTickCount () ;
  643. msg.m_pt.x = msg.m_pt.y = 0 ;
  644. if (! ImeDoc_bQueryToggleIMEEvent (&lpMyCompStr->_Doc, &msg, &fEaten))
  645. fEaten = FALSE ;
  646. if (fOpen && ! fEaten)
  647. ImeDoc_bQueryFilterEvent (&lpMyCompStr->_Doc, &msg, &fEaten) ;
  648. ImmUnlockIMCC (lpIMC->hCompStr) ;
  649. }
  650. ImmUnlockIMC (hIMC) ;
  651. return fEaten ;
  652. }
  653. /***********************************************************************
  654. * ImeSelect
  655. * ImeSelect 関数は IME private context の初期化及び非初期化処理を行う
  656. * のに用いられる。
  657. * BOOL
  658. * ImeSelect(
  659. * HIMC hIMC,
  660. * BOOL fSelect
  661. * )
  662. * Parameters
  663. * hIMC
  664. * Input context handle
  665. * fSelect
  666. * TRUE ならば初期化を、FALSE なら非初期化(リソースの解放)を意
  667. * 味する。
  668. * Return Values
  669. * 成功すれば TRUE。さもなくば FALSE。
  670. ***********************************************************************/
  671. BOOL WINAPI
  672. ImeSelect (
  673. HIMC hIMC,
  674. BOOL fSelect)
  675. {
  676. LPINPUTCONTEXT lpIMC ;
  677. LPCOMPOSITIONSTRING lpCompStr ;
  678. TRANSMSG GnMsg ;
  679. LOGFONT lf ;
  680. /* it's NULL context. */
  681. if (!hIMC)
  682. return TRUE ;
  683. lpIMC = ImmLockIMC(hIMC) ;
  684. if (lpIMC){
  685. DEBUGPRINTFEX (106, (TEXT ("ImeSelect (hIMC: %lx, fSelect:%d)\n"), hIMC, fSelect)) ;
  686. if (fSelect){
  687. /* Initialize */
  688. LPCANDIDATEINFO lpCandInfo ;
  689. /* MS-IME と SKKIME を Toolbar で切り替えられると、
  690. * ImeSelect には来るが、ActiveContext には来ないという
  691. * 現象が発生する。Config の読み込みのタイミングが ActiveContext
  692. * だけに絞れない…。
  693. *
  694. * ここでレジストリに触れることが UserEnv のエラーになるのだろう
  695. * か?
  696. */
  697. ImeConfig_vLoad () ;
  698. /* Init the general member of IMC. */
  699. if (!(lpIMC->fdwInit & INIT_LOGFONT)){
  700. #if defined (UNICODE)
  701. /* これで正しいのか? もとは .A. だけだったけど */
  702. lpIMC->lfFont.W.lfCharSet = SHIFTJIS_CHARSET ;
  703. #else
  704. lpIMC->lfFont.A.lfCharSet = SHIFTJIS_CHARSET ;
  705. #endif
  706. lpIMC->fdwInit |= INIT_LOGFONT ;
  707. }
  708. if (!(lpIMC->fdwInit & INIT_CONVERSION)){
  709. lpIMC->fdwConversion = IME_CMODE_ROMAN | IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE ;
  710. lpIMC->fdwInit |= INIT_CONVERSION ;
  711. }
  712. if (!(lpIMC->fdwInit & INIT_COMPFORM)) {
  713. lpIMC->cfCompForm.dwStyle = 1 ; // ?
  714. lpIMC->cfCompForm.ptCurrentPos.x = 0 ;
  715. lpIMC->cfCompForm.ptCurrentPos.y = 0 ;
  716. lpIMC->fdwInit |= INIT_COMPFORM ;
  717. }
  718. lpIMC->hCompStr = ImmReSizeIMCC (lpIMC->hCompStr, sizeof (MYCOMPSTR)) ;
  719. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC (lpIMC->hCompStr) ;
  720. if (lpCompStr){
  721. LPMYCOMPSTR lpMyCompStr = (LPMYCOMPSTR) lpCompStr ;
  722. lpCompStr->dwSize = sizeof (MYCOMPSTR) ;
  723. TSkkIme_vInitCompStr (lpCompStr, CLR_RESULT_AND_UNDET) ;
  724. ImeDoc_bInit (&lpMyCompStr->_Doc) ;
  725. lpMyCompStr->_bCandMode = FALSE ;
  726. lpMyCompStr->_fComposing = FALSE ;
  727. lpMyCompStr->cfCandBase.hWnd = (HWND) 0 ;
  728. lpMyCompStr->cfCandBase.dwIndex = (DWORD) -1 ;
  729. lpMyCompStr->cfCandBase.dwStyle = (DWORD) 0 ;
  730. ImmUnlockIMCC (lpIMC->hCompStr) ;
  731. }
  732. TSkkIme_bSetConversionMode (hIMC, lpIMC->fdwConversion) ;
  733. lpIMC->hCandInfo = ImmReSizeIMCC (lpIMC->hCandInfo, sizeof (MYCAND)) ;
  734. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC (lpIMC->hCandInfo) ;
  735. if (lpCandInfo){
  736. TSkkIme_vClearCandidate (lpCandInfo) ;
  737. ImmUnlockIMCC (lpIMC->hCandInfo) ;
  738. }
  739. /* ImeSelect (TRUE) は Text Service Framework を利用する application でも
  740. * 呼ばれてしまう。このため、LangBarItemMgr に LangBarItem を登録するべき
  741. * 場所として適切ではない。
  742. * ImeActiveContext (TRUE) で登録する方が適切であるように見える。
  743. *
  744. * ---- 削除されたコード (Sun Aug 14 02:21:27 2005)
  745. #if !defined (NO_TSF)
  746. vTSF_ActivateLanguageBar (hIMC, TRUE) ;//commented out
  747. #endif
  748. */
  749. MakeInfoGuideLine (hIMC, NULL, 0, -1) ;
  750. } else {
  751. /* Uninitialize */
  752. /* DEBUGPRINTF ((TEXT ("ImeSelect: (%ld) -> MakeInfoGuideLine (0)\n"), hIMC)) ;
  753. * MakeInfoGuideLine (hIMC, NULL, 0, -1) ;
  754. * この MakeInfoGuideLine は不要。
  755. * ここで GenerateMessage を実行すると application 終了時に
  756. * hangup するものが現れる。注意!!
  757. */
  758. if (lpIMC->hCompStr){
  759. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC (lpIMC->hCompStr) ;
  760. if (lpCompStr && lpCompStr->dwSize == sizeof(MYCOMPSTR)){
  761. ImeDoc_vClear (&((LPMYCOMPSTR)lpCompStr)->_Doc) ;
  762. ImmUnlockIMCC (lpIMC->hCompStr) ;
  763. }
  764. }
  765. ImeConfig_vUnload () ;
  766. /* LangBarItemMgr から LangBarItem を削除するのに適した場所はこちらだと思わ
  767. * れる。ImeActiveContext (FALSE) の段階では、本来消えるべきでない場合(同じ
  768. * Application で focus が少し移動した等)にも LangBarItem が削除されてしまう
  769. * ことになる。
  770. */
  771. /* CloseStatusWindow の位置に追加したが、こちらにも残すことにする。
  772. * (Fri Dec 09 14:28:56 2005)
  773. *
  774. * この操作は良くないようだ。自動的に TSF Manager が削除してくれる?
  775. * ここで無理に削除しようとすると、操作に異常に時間がかかってしまうことがあ
  776. * る。
  777. * (Thu Apr 26 21:45:29 2007)
  778. * 下記はまずいコード。
  779. #if !defined (NO_TSF)
  780. vTSF_ActivateLanguageBar (hIMC, FALSE) ;//commented out
  781. #endif
  782. *
  783. * どうしても消えてくれない。ThreadMgrが存在する時には消せるとするのか?
  784. * これでもまずいのか?
  785. * 修正してみたコード。
  786. *
  787. #if !defined (NO_TSF)
  788. if (bTSF_DoesThreadMgrExistp ()) {
  789. vTSF_ActivateLanguageBar (hIMC, FALSE) ;//commented out
  790. }
  791. #endif
  792. */
  793. #if !defined (NO_TSF)
  794. if (bTSF_DoesThreadMgrExistp ()) {
  795. vTSF_ActivateLanguageBar (hIMC, FALSE) ;
  796. }
  797. #endif
  798. }
  799. ImmUnlockIMC (hIMC) ;
  800. }
  801. return TRUE ;
  802. }
  803. /***********************************************************************
  804. * ImeSetCompositionString ()
  805. * ImeSetCompositionString 関数はアプリケーションに lpComp やlpRead パ
  806. * ラメータに入れられたデータをIMEのcomposition string 構造体に設定する
  807. * のに用いられる。IME は WM_IME_COMPOSITION メッセージを生成する。
  808. * BOOL WINAPI
  809. * ImeSetCompositionString(
  810. * HIMC hIMC,
  811. * DWORD dwIndex,
  812. * LPCVOID lpComp,
  813. * DWORD dwCompLen,
  814. * LPCVOID lpRead,
  815. * DWORD dwReadLen
  816. * );
  817. * Parameters
  818. * hIMC
  819. * Input context handle.
  820. * dwIndex
  821. * dwIndex に与えられる値は次の通りである。
  822. * ------------------------------------------------------------
  823. * SCS_SETSTR
  824. * アプリケーションは composition string 又は reading string また
  825. * はその両方をセットする。少なくとも lpComp か lpRead パラメータ
  826. * の1つは正当な文字列を指すポインタでなければならない。
  827. * もし文字列が長すぎるのなら、IME はそれを切り詰め。
  828. * SCS_CHANGEATTR
  829. * アプリケーションは composition string 又は reading string 又は
  830. * その両者の節情報を設定する。少なくとも lpComp か lpRead の1つ
  831. * は valid な節情報の配列を指すポインタでなければならない。
  832. * SCS_QUERYRECONVERTSTRING
  833. * アプリケーションは IME にその RECONVERTSTRINGSTRUCTURE を調整
  834. * してくれるよう依頼する。もしアプリケーションがこの値を設定して
  835. * ImeSetCompositionString を呼び出したなら、IME は RECONVERTSTRING
  836. * 構造体を調整しなければならない。アプリケーションはその時調整さ
  837. * れた RECONVERTSTRING 構造体を SCS_RECONVERTSTRING でもって、
  838. * この関数に渡すことができる。IME は WM_IMECOMPOSITION メッセージ
  839. * を生成してはならない。
  840. * SCS_SETRECONVERTSTRING
  841. * アプリケーションは IME に RECONVERTSTRING 構造体に含まれる
  842. * 文字列を reconvert するように依頼する。
  843. * ------------------------------------------------------------
  844. * lpComp
  845. * 更新された文字列を含むバッファを指すポインタ。文字列の型は
  846. * dwIndex の値によって決定される。
  847. * dwCompLen
  848. * バッファのバイト長。
  849. * lpRead
  850. * 更新された文字列を含むバッファを指すポインタ。文字列の型は
  851. * dwIndex の値によって決定される。dwIndex の値が
  852. * SCS_SETRECONVERTSTRING もしくは SCS_QUERYRECONVERTSTRING な
  853. * らば、lpRead は更新された reading string を含む
  854. * RECONVERTSTRING 構造体を指すポインタである。もし選択された
  855. * IME が SCS_CAP_MAKEREAD をもっていれば、NULL になる。
  856. * dwReadLen
  857. * バッファのバイト長。
  858. * Comments
  859. * Unicode については、たとえ SCS_SETSTR が特定されており Unicode
  860. * 文字列を含んでいても、dwCompLen や dwReadLen はバッファのバイト
  861. * 長である。
  862. * SCS_SETRECONVERTSTRING または SCS_QUERYRECONVERTSTRING は
  863. * SCS_CAP_CONVERTSTRING プロパティを持った IME にのみ利用できる。
  864. * このプロパティは ImmGetProperty 関数を使うことで得ることができる。
  865. ***********************************************************************/
  866. BOOL WINAPI
  867. ImeSetCompositionString(
  868. HIMC hIMC,
  869. DWORD dwIndex,
  870. LPVOID lpComp,
  871. DWORD dwComp,
  872. LPVOID lpRead,
  873. DWORD dwRead)
  874. {
  875. LPINPUTCONTEXT lpIMC ;
  876. LPCOMPOSITIONSTRING lpCompStr ;
  877. switch (dwIndex) {
  878. case SCS_SETSTR:
  879. {
  880. if (lpComp == NULL || dwComp <= 0)
  881. break ;
  882. lpIMC = ImmLockIMC (hIMC) ;
  883. if (!lpIMC)
  884. break ;
  885. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC (lpIMC->hCompStr) ;
  886. if (lpCompStr != NULL) {
  887. TSkkIme_vInitCompStr (lpCompStr, CLR_RESULT_AND_UNDET) ;
  888. ImeDoc_bSetConversionString (&((LPMYCOMPSTR)lpCompStr)->_Doc, lpComp, dwComp) ;
  889. TSkkIme_bUpdateComposition (hIMC, lpIMC, lpCompStr) ;
  890. ImmUnlockIMCC (lpIMC->hCompStr) ;
  891. }
  892. ImmUnlockIMC (hIMC) ;
  893. return TRUE ;
  894. }
  895. case SCS_CHANGEATTR:
  896. case SCS_CHANGECLAUSE:
  897. break ;
  898. case SCS_QUERYRECONVERTSTRING:
  899. {
  900. LPRECONVERTSTRING pRStr = (LPRECONVERTSTRING)lpComp ;
  901. #if defined (DEBUG) || defined (DBG)
  902. DebugPrintf (TEXT ("SCS_QUERYRECONVERTSTRING:\n")) ;
  903. if (lpComp != NULL) {
  904. DebugPrintf (TEXT ("lpComp:\n")) ;
  905. DebugDumpRS (lpComp) ;
  906. }
  907. if (lpRead != NULL) {
  908. DebugPrintf (TEXT ("lpRead:\n")) ;
  909. DebugDumpRS (lpRead) ;
  910. }
  911. #endif
  912. if (pRStr != NULL) {
  913. /* サイズがおまかせの場合には、取り敢えずは dwStrLen に
  914. * あわせる。kakasi とこの位置で連携した方がいいのかもし
  915. * れない。*/
  916. if (pRStr->dwCompStrLen <= 0 ||
  917. pRStr->dwTargetStrLen <= 0) {
  918. pRStr->dwCompStrOffset = 0 ;
  919. pRStr->dwTargetStrOffset = 0 ;
  920. pRStr->dwCompStrLen = pRStr->dwStrLen ;
  921. pRStr->dwTargetStrLen = pRStr->dwStrLen ;
  922. }
  923. /* サイズが大き過ぎるなら調整しなければ。*/
  924. if (pRStr->dwCompStrLen >= MAXCOMPSIZE)
  925. pRStr->dwCompStrLen = MAXCOMPSIZE - 1 ;
  926. if (pRStr->dwTargetStrLen >= MAXCOMPSIZE)
  927. pRStr->dwTargetStrLen = MAXCOMPSIZE - 1 ;
  928. }
  929. return TRUE ;
  930. }
  931. case SCS_SETRECONVERTSTRING:
  932. {
  933. LPRECONVERTSTRING pRStr = (LPRECONVERTSTRING)lpComp ;
  934. #if defined (DEBUG) || defined (DBG)
  935. DebugPrintf (TEXT ("SCS_SETRECONVERTSTRING:\n")) ;
  936. if (lpComp != NULL) {
  937. DebugPrintf (TEXT ("lpComp:\n")) ;
  938. DebugDumpRS (lpComp) ;
  939. }
  940. if (lpRead != NULL) {
  941. DebugPrintf (TEXT ("lpRead:\n")) ;
  942. DebugDumpRS (lpRead) ;
  943. }
  944. #endif
  945. if (!pRStr)
  946. break ;
  947. lpIMC = ImmLockIMC (hIMC) ;
  948. if (!lpIMC) {
  949. break ;
  950. }
  951. if (ImmGetIMCCSize (lpIMC->hCompStr) < sizeof (MYCOMPSTR)){
  952. ImmUnlockIMC (hIMC) ;
  953. break ;
  954. }
  955. /* 変換モードを強制的に仮名入力モードに設定する。*/
  956. //SKKChangeConversionMode (hIMC, IDM_CMODE_TO_ROMANHIRA) ;
  957. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC (lpIMC->hCompStr) ;
  958. if (lpCompStr != NULL) {
  959. if (! ImmGetOpenStatus (hIMC))
  960. ImmSetOpenStatus (hIMC, TRUE) ;
  961. TSkkIme_bSetReconvertStr (hIMC, lpIMC, lpCompStr, pRStr, TRUE) ;
  962. ImmUnlockIMCC (lpIMC->hCompStr) ;
  963. }
  964. ImmUnlockIMC (hIMC) ;
  965. return TRUE ;
  966. }
  967. default:
  968. break ;
  969. }
  970. return FALSE ;
  971. }
  972. /***********************************************************************
  973. * ImeGetImeMenuItems
  974. * ImeGetImeMenuItems 関数は IME menu に登録されている menu item を得る。
  975. * DWORD WINAPI
  976. * ImeGetImeMenuItems(
  977. * HIMC hIMC,
  978. * DWORD dwFlags,
  979. * DWORD dwType,
  980. * LPIMEMENUITEMINFO lpImeParentMenu,
  981. * LPIMEMENUITEMINFO lpImeMenu,
  982. * DWORD dwSize
  983. * )
  984. * Parameters
  985. * hIMC
  986. * lpMenuItem はこの input context に関連付けられている menu
  987. * item を含む。
  988. * dwFlags
  989. * 続くビットの組み合わせからなる。
  990. * ------------------------------------------------------------
  991. * IGIMIF_RIGHTMENU
  992. * もし 1 なら、この関数は右クリック Context menu に対する
  993. * menu item を返す。
  994. * ------------------------------------------------------------
  995. * dwType
  996. * 続くビットの組み合わせからなる。
  997. * ------------------------------------------------------------
  998. * IGIMII_CMODE
  999. * conversion mode に関連付けられている menu item を返す。
  1000. * IGIMII_SMODE
  1001. * sentence mode に関連付けられている menu item を返す。
  1002. * IGIMII_CONFIGURE
  1003. * IME の設定に関連付けられている menu item を返す。
  1004. * IGIMII_TOOLS
  1005. * IME ツールに関連付けられている menu item を返す。
  1006. * IGIMII_HELP
  1007. * IME ヘルプに関連付けられている menu item を返す。
  1008. * IGIMII_OTHER
  1009. * その他の menu item を返す。
  1010. * IGIMII_INPUTTOOLS
  1011. * 拡張された文字の入力方法を提供する IME 入力ツールに関連
  1012. * 付けられた menu item を返す。
  1013. * ------------------------------------------------------------
  1014. * lpImeParentMenu
  1015. * fType に MFT_SUBMENU を持った IMEMENUINFO 構造体を指すポイン
  1016. * タ。ImeGetMenuItems はこの menu item の submenu item を返す。
  1017. * もし NULL なら lpImeMenu は top-level の IME menu item を含
  1018. * んでいる。
  1019. * lpImeMenu
  1020. * menu item の内容を受け取るバッファを指したポインタ。このバッ
  1021. * ファは IMEMENUINFO 構造体の配列である。もし NULL なら
  1022. * ImeGetImeMenuItems は登録される menu item の数を返す。
  1023. * dwSize
  1024. * IMEMENUITEMINFO 構造体を受けるバッファのサイズ。
  1025. * Return Values
  1026. * lpIM に設定された menu item の数が帰る。もし lpImeMenu が NULL
  1027. * ならば ImeMenuItems は指定された hKL に登録されている menu item
  1028. * の数を返す。
  1029. * ImeGetImeMenuItems は Windows'98 や Windows 2000 用の新しい関数である。
  1030. ***********************************************************************/
  1031. DWORD WINAPI
  1032. ImeGetImeMenuItems (
  1033. HIMC hIMC,
  1034. DWORD dwFlags,
  1035. DWORD dwType,
  1036. LPMYIMEMENUITEMINFO lpImeParentMenu,
  1037. LPMYIMEMENUITEMINFO lpImeMenu,
  1038. DWORD dwSize)
  1039. {
  1040. /* dwType を MSIME はチェックしていないようだ。それに合わせる。
  1041. * ただ、TSF が生きていると、この method は常に動作してないように思えるが。
  1042. *
  1043. * if (IsTSFEnabled ())
  1044. * return 0 ;
  1045. *
  1046. * このコードを有効にするかどうかは微妙だ。
  1047. * [Sun Nov 23 00:26:08 2003]
  1048. */
  1049. dwType |= IGIMII_CMODE | IGIMII_SMODE | IGIMII_CONFIGURE | IGIMII_TOOLS | IGIMII_HELP | IGIMII_OTHER ;
  1050. if (dwFlags & IGIMIF_RIGHTMENU){
  1051. return getImeRightMenuItems (hIMC, dwFlags, dwType, lpImeParentMenu, lpImeMenu, dwSize) ;
  1052. } else {
  1053. return getImeLeftMenuItems (hIMC, dwFlags, dwType, lpImeParentMenu, lpImeMenu, dwSize) ;
  1054. }
  1055. }
  1056. DWORD PASCAL
  1057. getImeLeftMenuItems (
  1058. HIMC hIMC,
  1059. DWORD dwFlags,
  1060. DWORD dwType,
  1061. LPMYIMEMENUITEMINFO lpImeParentMenu,
  1062. LPMYIMEMENUITEMINFO lpImeMenu,
  1063. DWORD dwSize)
  1064. {
  1065. static MYSTRTYPEPAIR myLeftMenuItemInfoTbl [] = {
  1066. { IDIM_SHOW_TOOLBAR, MYTEXT ("ツールバーを表示(&I)"), },
  1067. { IDIM_CANCEL, MYTEXT ("キャンセル"), },
  1068. } ;
  1069. long lUsage ;
  1070. int iMenuItem ;
  1071. if (! TSkkIme_bIsHideToolbarp ())
  1072. return 0 ;
  1073. iMenuItem = 0 ;
  1074. /* ツールバーを表示(&I) をメニューに追加する。*/
  1075. if (dwType & IGIMII_OTHER) {
  1076. if (lpImeMenu != NULL) {
  1077. insertStringMenuItem (lpImeMenu ++, &myLeftMenuItemInfoTbl [0], IMFS_ENABLED) ;
  1078. insertSeparatorMenuItem (lpImeMenu ++) ;
  1079. }
  1080. iMenuItem += 2 ;
  1081. }
  1082. if (dwType & IGIMII_CMODE) {
  1083. /* 入力モードの変更メニューを追加する。*/
  1084. lUsage = insertInputModeMenuItems (hIMC, lpImeMenu) ;
  1085. if (lUsage > 0) {
  1086. if (lpImeMenu != NULL) {
  1087. lpImeMenu += lUsage ;
  1088. insertSeparatorMenuItem (lpImeMenu ++) ;
  1089. }
  1090. iMenuItem += lUsage + 1 ;
  1091. }
  1092. }
  1093. /* キャンセルを追加する。*/
  1094. if (lpImeMenu != NULL)
  1095. insertStringMenuItem (lpImeMenu ++, &myLeftMenuItemInfoTbl [1], IMFS_ENABLED) ;
  1096. iMenuItem ++ ;
  1097. DEBUGPRINTFEX (102, (TEXT ("getImeLeftMenuItems return (%d), lUsage = %d\n"),
  1098. iMenuItem, (int) lUsage)) ;
  1099. return iMenuItem ;
  1100. }
  1101. DWORD PASCAL
  1102. getImeRightMenuItems (
  1103. HIMC hIMC,
  1104. DWORD dwFlags,
  1105. DWORD dwType,
  1106. LPMYIMEMENUITEMINFO lpImeParentMenu,
  1107. LPMYIMEMENUITEMINFO lpImeMenu,
  1108. DWORD dwSize)
  1109. {
  1110. static MYSTRTYPEPAIREX myRightMenuItemInfoTbl [NUM_ROOT_MENU_R] = {
  1111. { IDIM_SHOW_TOOLBAR, IGIMII_OTHER, MYTEXT ("ツールバーを表示(&I)"), },
  1112. { 0, IGIMII_OTHER, 0, },
  1113. { IDIM_PROPERTY, IGIMII_CONFIGURE, MYTEXT ("プロパティ(&R)"), },
  1114. { 0, IGIMII_CONFIGURE | IGIMII_OTHER, 0, },
  1115. { IDIM_INPUTMODE, IGIMII_CMODE, MYTEXT ("入力モード(&N)"), },
  1116. { 0, IGIMII_CMODE, 0, },
  1117. { IDIM_CANCEL, (DWORD)-1, MYTEXT ("キャンセル"), },
  1118. } ;
  1119. LPMYSTRTYPEPAIREX ptr ;
  1120. int iMenuItem, nCount ;
  1121. BOOL fInsert ;
  1122. if (lpImeParentMenu)
  1123. return getImeRightSubMenuItems (hIMC, dwFlags, dwType, lpImeParentMenu, lpImeMenu, dwSize) ;
  1124. if (! TSkkIme_bIsHideToolbarp ())
  1125. return 0 ;
  1126. iMenuItem = 0 ;
  1127. ptr = myRightMenuItemInfoTbl ;
  1128. for (nCount = 0 ; nCount < ARRAYSIZE (myRightMenuItemInfoTbl) ; nCount ++) {
  1129. fInsert = (ptr->m_dwType != (DWORD) -1)? ((ptr->m_dwType & dwType) != 0) : TRUE ;
  1130. if (fInsert) {
  1131. if (lpImeMenu != NULL) {
  1132. if (! ptr->m_lpString){
  1133. insertSeparatorMenuItem (lpImeMenu) ;
  1134. } else {
  1135. /* メニューを追加。*/
  1136. insertStringMenuItemEx (lpImeMenu, ptr, IMFS_ENABLED) ;
  1137. /* 入力モードの場合には submenu が存在する。*/
  1138. if (ptr->m_wID == IDIM_INPUTMODE)
  1139. lpImeMenu->fType = IMFT_SUBMENU ;
  1140. }
  1141. lpImeMenu ++ ;
  1142. }
  1143. iMenuItem ++ ;
  1144. }
  1145. ptr ++ ;
  1146. }
  1147. return iMenuItem ;
  1148. }
  1149. DWORD PASCAL
  1150. getImeRightSubMenuItems (
  1151. HIMC hIMC,
  1152. DWORD dwFlags,
  1153. DWORD dwType,
  1154. LPMYIMEMENUITEMINFO lpImeParentMenu,
  1155. LPMYIMEMENUITEMINFO lpImeMenu,
  1156. DWORD dwSize)
  1157. {
  1158. if ((lpImeParentMenu->wID != IDIM_INPUTMODE) ||
  1159. (dwType & IGIMII_CMODE) == 0)
  1160. return 0 ;
  1161. if (!lpImeMenu)
  1162. return NUM_INPUTMODE_MENU ;
  1163. return insertInputModeMenuItems (hIMC, lpImeMenu) ;
  1164. }
  1165. long PASCAL
  1166. insertStringMenuItem (
  1167. LPMYIMEMENUITEMINFO lpImeMenu,
  1168. const LPMYSTRTYPEPAIR lpMyStrTypePair,
  1169. UINT uValue)
  1170. {
  1171. if (!lpImeMenu || !lpMyStrTypePair)
  1172. return 0L ;
  1173. lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO) ;
  1174. lpImeMenu->fType = 0 ;
  1175. lpImeMenu->fState = uValue ;
  1176. lpImeMenu->wID = lpMyStrTypePair->m_wID ;
  1177. Mylstrcpy (lpImeMenu->szString, lpMyStrTypePair->m_lpString) ;
  1178. lpImeMenu->hbmpChecked = 0 ;
  1179. lpImeMenu->hbmpUnchecked = 0 ;
  1180. lpImeMenu->hbmpItem = 0 ;
  1181. return 1L ;
  1182. }
  1183. long PASCAL
  1184. insertStringMenuItemEx (
  1185. LPMYIMEMENUITEMINFO lpImeMenu,
  1186. const LPMYSTRTYPEPAIREX lpMyStrTypePair,
  1187. UINT uValue)
  1188. {
  1189. if (!lpImeMenu || !lpMyStrTypePair)
  1190. return 0L ;
  1191. lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO) ;
  1192. lpImeMenu->fType = 0 ;
  1193. lpImeMenu->fState = uValue ;
  1194. lpImeMenu->wID = lpMyStrTypePair->m_wID ;
  1195. Mylstrcpy (lpImeMenu->szString, lpMyStrTypePair->m_lpString) ;
  1196. lpImeMenu->hbmpChecked = 0 ;
  1197. lpImeMenu->hbmpUnchecked = 0 ;
  1198. lpImeMenu->hbmpItem = 0 ;
  1199. return 1L ;
  1200. }
  1201. long PASCAL
  1202. insertSeparatorMenuItem (
  1203. LPMYIMEMENUITEMINFO lpImeMenu)
  1204. {
  1205. if (!lpImeMenu)
  1206. return 0L ;
  1207. lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO) ;
  1208. lpImeMenu->fType = IMFT_SEPARATOR ;
  1209. lpImeMenu->fState = 0 ;
  1210. lpImeMenu->wID = 0 ;
  1211. lpImeMenu->szString [0] = MYTEXT ('\0') ;
  1212. lpImeMenu->hbmpChecked = 0 ;
  1213. lpImeMenu->hbmpUnchecked = 0 ;
  1214. lpImeMenu->hbmpItem = 0 ;
  1215. return 1L ;
  1216. }
  1217. long PASCAL
  1218. insertInputModeMenuItems (
  1219. HIMC hIMC,
  1220. LPMYIMEMENUITEMINFO lpImeMenu)
  1221. {
  1222. static MYSTRTYPEPAIR inputModeMenuItemTbl [NUM_INPUTMODE_MENU] = {
  1223. { IDM_CMODE_TO_ASCII, MYTEXT ("アスキー(&S)"), },
  1224. { IDM_CMODE_TO_ROMANHIRA, MYTEXT ("ローマ字平仮名(&H)"), },
  1225. { IDM_CMODE_TO_ROMANKATA, MYTEXT ("ローマ字片仮名(&K)"), },
  1226. { IDM_CMODE_TO_JISX0201KANA, MYTEXT ("半角片仮名(&A)"), },
  1227. { IDM_CMODE_TO_JISX0201ROMAN, MYTEXT ("半角英数(&R)"), },
  1228. { IDM_CMODE_TO_ZENEI, MYTEXT ("全角英字(&E)"), },
  1229. { IDM_CMODE_TO_DIRECTINPUT, MYTEXT ("直接入力(&C)"), },
  1230. } ;
  1231. DWORD dwMyInputModeTbl [NUM_INPUTMODE_MENU] = {
  1232. IDM_CMODE_TO_ROMANHIRA,
  1233. IDM_CMODE_TO_ROMANKATA,
  1234. IDM_CMODE_TO_ZENEI,
  1235. IDM_CMODE_TO_JISX0201KANA,
  1236. IDM_CMODE_TO_JISX0201ROMAN,
  1237. IDM_CMODE_TO_ASCII,
  1238. IDM_CMODE_TO_DIRECTINPUT,
  1239. } ;
  1240. LPMYSTRTYPEPAIR lpMyMenuItemInfo ;
  1241. long lCounter ;
  1242. DWORD dwCMode ;
  1243. LPINPUTCONTEXT lpIMC ;
  1244. /* 現在の入力モードを得る。*/
  1245. lpIMC = (LPINPUTCONTEXT)ImmLockIMC (hIMC) ;
  1246. if (!lpIMC)
  1247. return 0 ;
  1248. /* IMECMODE_XXX から IDM_CMODE_ に変換する。
  1249. */
  1250. dwCMode = dwMyInputModeTbl [iGetConversionModeFromLPIMC (lpIMC)] ;
  1251. ImmUnlockIMC (hIMC) ;
  1252. if (lpImeMenu == NULL)
  1253. return sizeof (inputModeMenuItemTbl) / sizeof (MYSTRTYPEPAIR) ;
  1254. lpMyMenuItemInfo = inputModeMenuItemTbl ;
  1255. lCounter = 0 ;
  1256. while (lCounter < sizeof (inputModeMenuItemTbl) / sizeof (MYSTRTYPEPAIR)){
  1257. lpImeMenu->cbSize = sizeof(IMEMENUITEMINFO) ;
  1258. lpImeMenu->fType = IMFT_RADIOCHECK ;
  1259. lpImeMenu->wID = lpMyMenuItemInfo->m_wID ;
  1260. if (lpMyMenuItemInfo->m_wID == dwCMode){
  1261. lpImeMenu->fState = IMFS_ENABLED | IMFS_CHECKED ;
  1262. } else {
  1263. lpImeMenu->fState = IMFS_ENABLED | IMFS_UNCHECKED ;
  1264. }
  1265. Mylstrcpy (lpImeMenu->szString, lpMyMenuItemInfo->m_lpString) ;
  1266. lpImeMenu->hbmpChecked = 0 ;
  1267. lpImeMenu->hbmpUnchecked = 0 ;
  1268. lpImeMenu->hbmpItem = 0 ;
  1269. lpMyMenuItemInfo ++ ;
  1270. lpImeMenu ++ ;
  1271. lCounter ++ ;
  1272. }
  1273. return lCounter ;
  1274. }