IME前後参照変換をUnicode化
- この機能は98/2000以降
- IsWindowUnicode()がTRUEのとき Unicode版を使用するようにした
- IME前後参照変換
- BuffGetLineStrW()追加
@@ -2047,6 +2047,65 @@ | ||
2047 | 2047 | #endif |
2048 | 2048 | |
2049 | 2049 | /** |
2050 | + * 1セル分をwchar_t文字列に展開する | |
2051 | + * @param[in] b 1セル分の文字情報へのポインタ | |
2052 | + * @param[in,out] buf 文字列展開先 NULLの場合は展開されない | |
2053 | + * @param[in] buf_size bufの文字数 NULLの場合は参照されない | |
2054 | + * @retrun 文字数 | |
2055 | + */ | |
2056 | +static size_t expand_wchar(const buff_char_t *b, wchar_t *buf, size_t buf_size, BOOL *too_samll) | |
2057 | +{ | |
2058 | + size_t len; | |
2059 | + | |
2060 | + if (IsBuffPadding(b)) { | |
2061 | + if (too_samll != NULL) { | |
2062 | + *too_samll = FALSE; | |
2063 | + } | |
2064 | + return 0; | |
2065 | + } | |
2066 | + | |
2067 | + // 長さを測る | |
2068 | + len = 0; | |
2069 | + if (b->wc2[1] == 0) { | |
2070 | + // サロゲートペアではない | |
2071 | + len++; | |
2072 | + } else { | |
2073 | + // サロゲートペア | |
2074 | + len += 2; | |
2075 | + } | |
2076 | + // コンビネーション | |
2077 | + len += b->CombinationCharCount16; | |
2078 | + | |
2079 | + if (buf == NULL) { | |
2080 | + // 長さだけを返す | |
2081 | + return len; | |
2082 | + } | |
2083 | + | |
2084 | + // バッファに収まる? | |
2085 | + if (len > buf_size) { | |
2086 | + // バッファに収まらない | |
2087 | + if (too_samll != NULL) { | |
2088 | + *too_samll = TRUE; | |
2089 | + } | |
2090 | + return 0; | |
2091 | + } | |
2092 | + if (too_samll != NULL) { | |
2093 | + *too_samll = FALSE; | |
2094 | + } | |
2095 | + | |
2096 | + // 展開していく | |
2097 | + *buf++ = b->wc2[0]; | |
2098 | + if (b->wc2[1] != 0) { | |
2099 | + *buf++ = b->wc2[1]; | |
2100 | + } | |
2101 | + if (b->CombinationCharCount16 != 0) { | |
2102 | + memcpy(buf, b->pCombinationChars16, b->CombinationCharCount16 * sizeof(wchar_t)); | |
2103 | + } | |
2104 | + | |
2105 | + return len; | |
2106 | +} | |
2107 | + | |
2108 | +/** | |
2050 | 2109 | * (x,y) の1文字が strと同一か調べる |
2051 | 2110 | * *注 1文字が複数のwchar_tから構成されている |
2052 | 2111 | * |
@@ -6114,6 +6173,50 @@ | ||
6114 | 6173 | return (CursorX); |
6115 | 6174 | } |
6116 | 6175 | |
6176 | +/** | |
6177 | + * Sy行の一行を文字列にして返す | |
6178 | + * | |
6179 | + * @param[in] Sy Sy行の1行を返す | |
6180 | + * @param[in] *Cx 文字の位置(カーソルなどの位置), NULLのとき無効 | |
6181 | + * @param[out] *Cx 左端からの文字数(先頭からカーソル位置までの文字数) | |
6182 | + * @param[out] *lenght 文字数(ターミネータ含む) | |
6183 | + */ | |
6184 | +wchar_t *BuffGetLineStrW(int Sy, int *cx, size_t *lenght) | |
6185 | +{ | |
6186 | + size_t total_len = 0; | |
6187 | + size_t i = 0; | |
6188 | + LONG Ptr = GetLinePtr(PageStart + Sy); | |
6189 | + buff_char_t* b = &CodeBuffW[Ptr]; | |
6190 | + int x; | |
6191 | + int cx_pos = cx != NULL ? *cx : 0; | |
6192 | + int cx_char_count = 0; | |
6193 | + size_t idx; | |
6194 | + wchar_t *result; | |
6195 | + for(x = 0; x < NumOfColumns; x++) { | |
6196 | + size_t len; | |
6197 | + if (x == cx_pos) { | |
6198 | + if (cx != NULL) { | |
6199 | + *cx = (int)total_len; | |
6200 | + } | |
6201 | + } | |
6202 | + len = expand_wchar(b + x, NULL, 0, NULL); | |
6203 | + total_len += len; | |
6204 | + } | |
6205 | + total_len++; | |
6206 | + result = (wchar_t *)malloc(total_len * sizeof(wchar_t)); | |
6207 | + idx = 0; | |
6208 | + for(x = 0; x < NumOfColumns; x++) { | |
6209 | + wchar_t *p = &result[idx]; | |
6210 | + size_t len = expand_wchar(b + x, p, total_len - idx, NULL); | |
6211 | + idx += len; | |
6212 | + } | |
6213 | + result[idx] = 0; | |
6214 | + if (lenght != NULL) { | |
6215 | + *lenght = total_len; | |
6216 | + } | |
6217 | + return result; | |
6218 | +} | |
6219 | + | |
6117 | 6220 | // 全バッファから指定した行を返す。 |
6118 | 6221 | int BuffGetAnyLineData(int offset_y, char *buf, int bufsize) |
6119 | 6222 | { |
@@ -6345,6 +6448,14 @@ | ||
6345 | 6448 | } |
6346 | 6449 | #endif |
6347 | 6450 | |
6451 | +#if 0 | |
6452 | + { | |
6453 | + wchar_t *p = BuffGetCurrentLineDataW(ScreenY, NULL, NULL); | |
6454 | + OutputDebugPrintfW(L"BuffGetCurrentLineDataW(%d)='%s'\n", Yw, p); | |
6455 | + free(p); | |
6456 | + } | |
6457 | +#endif | |
6458 | + | |
6348 | 6459 | UnlockBuffer(); |
6349 | 6460 | |
6350 | 6461 | return str_ptr; |
@@ -148,7 +148,8 @@ | ||
148 | 148 | void BuffScrollLeft(int count); |
149 | 149 | void BuffScrollRight(int count); |
150 | 150 | int BuffGetCurrentLineData(char *buf, int bufsize); |
151 | -int BuffGetAnyLineData(int offset_y, char *buf, int bufsize); | |
151 | +wchar_t *BuffGetLineStrW(int Sy, int *cx, size_t *length); | |
152 | +int BuffGetAnyLineData(int offset_y, char *buf, int bufsize); // from filesys.cpp | |
152 | 153 | BOOL BuffCheckMouseOnURL(int Xw, int Yw); |
153 | 154 | wchar_t *BuffGetCharInfo(int Xw, int Yw); |
154 | 155 | void BuffSetCursorCharAttr(int x, int y, TCharAttr Attr); |
@@ -33,12 +33,14 @@ | ||
33 | 33 | #if !defined(_CRTDBG_MAP_ALLOC) |
34 | 34 | #define _CRTDBG_MAP_ALLOC |
35 | 35 | #endif |
36 | +#include <stdio.h> // for snprintf, snwprintf | |
36 | 37 | #include <stdlib.h> |
37 | 38 | #include <crtdbg.h> |
38 | 39 | #include <string.h> |
39 | 40 | #include <imm.h> |
40 | 41 | #include <assert.h> |
41 | - | |
42 | +#include "asprintf.h" | |
43 | +#include "layer_for_unicode.h" | |
42 | 44 | #include "ttime.h" |
43 | 45 | |
44 | 46 | // #define ENABLE_DUMP 1 |
@@ -367,22 +369,9 @@ | ||
367 | 369 | static void DumpReconvStringSt(RECONVERTSTRING *pReconv, BOOL unicode) |
368 | 370 | { |
369 | 371 | if (unicode) { |
370 | - wchar_t tmp[1024]; | |
371 | - _snwprintf(tmp, _countof(tmp), | |
372 | - L"Str %d,%d CompStr %d,%d TargeteStr %d,%d '%s'\n", | |
373 | - pReconv->dwStrLen, | |
374 | - pReconv->dwStrOffset, | |
375 | - pReconv->dwCompStrLen, | |
376 | - pReconv->dwCompStrOffset, | |
377 | - pReconv->dwTargetStrLen, | |
378 | - pReconv->dwTargetStrOffset, | |
379 | - (wchar_t *)(((char *)pReconv) + pReconv->dwStrOffset) | |
380 | - ); | |
381 | - OutputDebugStringW(tmp); | |
382 | - } else { | |
383 | - char tmp[1024]; | |
384 | - _snprintf(tmp, sizeof(tmp), | |
385 | - "Str %d,%d CompStr %d,%d TargeteStr %d,%d '%s'\n", | |
372 | + wchar_t *buf; | |
373 | + aswprintf(&buf, | |
374 | + L"Str %d,%d CompStr %d,%d TargeteStr %d,%d '%s'\n", | |
386 | 375 | pReconv->dwStrLen, |
387 | 376 | pReconv->dwStrOffset, |
388 | 377 | pReconv->dwCompStrLen, |
@@ -389,9 +378,24 @@ | ||
389 | 378 | pReconv->dwCompStrOffset, |
390 | 379 | pReconv->dwTargetStrLen, |
391 | 380 | pReconv->dwTargetStrOffset, |
392 | - (((char *)pReconv) + pReconv->dwStrOffset) | |
381 | + (wchar_t *)(((char *)pReconv) + pReconv->dwStrOffset) | |
393 | 382 | ); |
394 | - OutputDebugStringA(tmp); | |
383 | + _OutputDebugStringW(buf); | |
384 | + free(buf); | |
385 | + } else { | |
386 | + char *buf; | |
387 | + asprintf(&buf, | |
388 | + "Str %d,%d CompStr %d,%d TargeteStr %d,%d '%s'\n", | |
389 | + pReconv->dwStrLen, | |
390 | + pReconv->dwStrOffset, | |
391 | + pReconv->dwCompStrLen, | |
392 | + pReconv->dwCompStrOffset, | |
393 | + pReconv->dwTargetStrLen, | |
394 | + pReconv->dwTargetStrOffset, | |
395 | + (((char *)pReconv) + pReconv->dwStrOffset) | |
396 | + ); | |
397 | + OutputDebugStringA(buf); | |
398 | + free(buf); | |
395 | 399 | } |
396 | 400 | } |
397 | 401 | #endif |
@@ -481,8 +485,8 @@ | ||
481 | 485 | pReconv->dwStrOffset = sizeof(RECONVERTSTRING); |
482 | 486 | pReconv->dwCompStrLen = complen_count; |
483 | 487 | pReconv->dwCompStrOffset = cx_bytes; |
484 | - pReconv->dwTargetStrLen = complen_count; // = dwCompStrOffset | |
485 | - pReconv->dwTargetStrOffset = cx_bytes; // = dwTargetStrLen | |
488 | + pReconv->dwTargetStrLen = complen_count; // = dwCompStrLen | |
489 | + pReconv->dwTargetStrOffset = cx_bytes; // = dwCompStrOffset | |
486 | 490 | |
487 | 491 | // RECONVERTSTRINGの後ろに |
488 | 492 | // 参照文字列をコピー+カーソル位置に変文字列を挿入 |
@@ -3177,32 +3177,65 @@ | ||
3177 | 3177 | |
3178 | 3178 | if (lParam == 0) |
3179 | 3179 | { // 1回目の呼び出し サイズだけを返す |
3180 | - char buf[512]; // 参照文字列を受け取るバッファ | |
3181 | - size_t str_len_count; | |
3182 | - int cx; | |
3183 | -// assert(IsWindowUnicode(hWnd) == FALSE); // TODO UNICODE/ANSI切り替え | |
3180 | + if(IsWindowUnicode(hWnd) == FALSE) { | |
3181 | + // ANSI版 | |
3182 | + char buf[512]; // 参照文字列を受け取るバッファ | |
3183 | + size_t str_len_count; | |
3184 | + int cx; | |
3184 | 3185 | |
3185 | - // 参照文字列取得、1行取り出す | |
3186 | - { // カーソルから後ろ、スペース以外が見つかったところを行末とする | |
3187 | - int x; | |
3188 | - int len; | |
3189 | - cx = BuffGetCurrentLineData(buf, sizeof(buf)); | |
3190 | - len = cx; | |
3191 | - for (x=cx; x < NumOfColumns; x++) { | |
3192 | - const char c = buf[x]; | |
3193 | - if (c != 0 && c != 0x20) { | |
3194 | - len = x+1; | |
3186 | + // 参照文字列取得、1行取り出す | |
3187 | + { // カーソルから後ろ、スペース以外が見つかったところを行末とする | |
3188 | + int x; | |
3189 | + int len; | |
3190 | + cx = BuffGetCurrentLineData(buf, sizeof(buf)); | |
3191 | + len = cx; | |
3192 | + for (x=cx; x < NumOfColumns; x++) { | |
3193 | + const char c = buf[x]; | |
3194 | + if (c != 0 && c != 0x20) { | |
3195 | + len = x+1; | |
3196 | + } | |
3195 | 3197 | } |
3198 | + str_len_count = len; | |
3196 | 3199 | } |
3197 | - str_len_count = len; | |
3200 | + | |
3201 | + // IMEに返す構造体を作成する | |
3202 | + if (pReconvPtrSave != NULL) { | |
3203 | + free(pReconvPtrSave); | |
3204 | + } | |
3205 | + pReconvPtrSave = (RECONVERTSTRING *)CreateReconvStringStA( | |
3206 | + hWnd, buf, str_len_count, cx, &ReconvSizeSave); | |
3198 | 3207 | } |
3208 | + else { | |
3209 | + // UNICODE版 | |
3210 | + size_t str_len_count; | |
3211 | + int cx; | |
3212 | + wchar_t *strW; | |
3199 | 3213 | |
3200 | - // IMEに返す構造体を作成する | |
3201 | - if (pReconvPtrSave != NULL) { | |
3202 | - free(pReconvPtrSave); | |
3214 | + // 参照文字列取得、1行取り出す | |
3215 | + { // カーソルから後ろ、スペース以外が見つかったところを行末とする | |
3216 | + int x; | |
3217 | + size_t len = 0; | |
3218 | + cx = CursorX; | |
3219 | + strW = BuffGetLineStrW(CursorY, &cx, &len); | |
3220 | + len = cx; | |
3221 | + for (x=cx; x < NumOfColumns; x++) { | |
3222 | + const wchar_t c = strW[x]; | |
3223 | + if (c == 0 || c == 0x20) { | |
3224 | + len = x; | |
3225 | + break; | |
3226 | + } | |
3227 | + } | |
3228 | + str_len_count = len; | |
3229 | + } | |
3230 | + | |
3231 | + // IMEに返す構造体を作成する | |
3232 | + if (pReconvPtrSave != NULL) { | |
3233 | + free(pReconvPtrSave); | |
3234 | + } | |
3235 | + pReconvPtrSave = (RECONVERTSTRING *)CreateReconvStringStW( | |
3236 | + hWnd, strW, str_len_count, cx, &ReconvSizeSave); | |
3237 | + free(strW); | |
3203 | 3238 | } |
3204 | - pReconvPtrSave = (RECONVERTSTRING *)CreateReconvStringStA( | |
3205 | - hWnd, buf, str_len_count, cx, &ReconvSizeSave); | |
3206 | 3239 | |
3207 | 3240 | // 1回目はサイズだけを返す |
3208 | 3241 | result = ReconvSizeSave; |
@@ -3211,8 +3244,12 @@ | ||
3211 | 3244 | // 2回目の呼び出し 構造体を渡す |
3212 | 3245 | if (pReconvPtrSave != NULL) { |
3213 | 3246 | RECONVERTSTRING *pReconv = (RECONVERTSTRING*)lParam; |
3214 | - memcpy(pReconv, pReconvPtrSave, ReconvSizeSave); | |
3215 | - result = ReconvSizeSave; | |
3247 | + result = 0; | |
3248 | + if (pReconv->dwSize >= ReconvSizeSave) { | |
3249 | + // 1回目のサイズが確保されてきているはず | |
3250 | + memcpy(pReconv, pReconvPtrSave, ReconvSizeSave); | |
3251 | + result = ReconvSizeSave; | |
3252 | + } | |
3216 | 3253 | free(pReconvPtrSave); |
3217 | 3254 | pReconvPtrSave = NULL; |
3218 | 3255 | ReconvSizeSave = 0; |
@@ -3222,11 +3259,6 @@ | ||
3222 | 3259 | } |
3223 | 3260 | } |
3224 | 3261 | |
3225 | -#if 0 | |
3226 | - OutputDebugPrintf("WM_IME_REQUEST,IMR_DOCUMENTFEED lp=%p LRESULT %d\n", | |
3227 | - lParam, result); | |
3228 | -#endif | |
3229 | - | |
3230 | 3262 | return result; |
3231 | 3263 | } |
3232 | 3264 |