Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

sftkbdt1.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: sftkbdt1.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Soft keyboard support for Traditional Chinese 00007 * 00008 * History: 00009 * 02-Jan-1996 wkwok - ported from Win95 00010 \**************************************************************************/ 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 #include "softkbd.h" 00015 00016 00017 CONST BYTE bSKT1VirtKey[SKT1_TOTAL_KEY_NUM] = { // Virtual Key for Letter Buttons 00018 // ` 1 2 3 4 5 6 7 8 9 0 00019 VK_OEM_3, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 00020 // - = \\ line 1 letter above 00021 VK_OEM_MINUS, VK_OEM_EQUAL, VK_OEM_BSLASH, 00022 // q w e r t y u i o p 00023 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 00024 // [ ] line 2 letter above 00025 VK_OEM_LBRACKET, VK_OEM_RBRACKET, 00026 // a s d f g h j k l 00027 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 00028 // ; ' line 3 letter above 00029 VK_OEM_SEMICLN, VK_OEM_QUOTE, 00030 // z x c v b n m 00031 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 00032 // , . / line 4 letter above 00033 VK_OEM_COMMA, VK_OEM_PERIOD, VK_OEM_SLASH, 00034 // <- tab caps enter 00035 VK_BACK, VK_TAB, VK_CAPITAL, VK_RETURN, 00036 // shift1 shift2 ctrl1 ctrl2 00037 VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, 00038 // alt1 alt2 esc space special key above 00039 VK_MENU, VK_MENU, VK_ESCAPE, VK_SPACE 00040 }; 00041 00042 00043 LOGFONT lfSKT1Font; 00044 00045 00046 /**********************************************************************/ 00047 /* GetSKT1TextMetric */ 00048 /**********************************************************************/ 00049 00050 void GetSKT1TextMetric( 00051 LPTEXTMETRIC lptm) 00052 { 00053 HDC hDC; 00054 HFONT hOldFont; 00055 SIZE szDbcs; 00056 const WCHAR wcDbcs = 0x4e11; 00057 00058 hDC = GetDC((HWND)NULL); 00059 00060 // get the 9 pixels font 00061 RtlZeroMemory(&lfSKT1Font, sizeof lfSKT1Font); 00062 lfSKT1Font.lfHeight = -12; 00063 lfSKT1Font.lfWeight = FW_NORMAL; 00064 00065 lfSKT1Font.lfCharSet = CHINESEBIG5_CHARSET; 00066 00067 lfSKT1Font.lfOutPrecision = OUT_TT_ONLY_PRECIS; 00068 lfSKT1Font.lfClipPrecision = CLIP_DEFAULT_PRECIS; 00069 lfSKT1Font.lfQuality = PROOF_QUALITY; 00070 lfSKT1Font.lfPitchAndFamily = FIXED_PITCH|FF_MODERN; 00071 00072 hOldFont = (HFONT)SelectObject(hDC, CreateFontIndirect(&lfSKT1Font)); 00073 00074 GetTextMetrics(hDC, lptm); 00075 00076 /* 00077 * NT5: Dirty hack for "Lucida Console" which was "font linked" on NT5, and 00078 * GetTextMetrics API does not return correct text metrics. 00079 */ 00080 if (GetTextExtentPoint32(hDC, &wcDbcs, 1, &szDbcs) && lptm->tmMaxCharWidth < szDbcs.cx) { 00081 TAGMSG2(DBGTAG_IMM, "GetSKT1TextMetric: tmMaxCharWidth(%d) is smaller than real width(%d).", 00082 lptm->tmMaxCharWidth, szDbcs.cx); 00083 lptm->tmMaxCharWidth = szDbcs.cx; 00084 } 00085 00086 DeleteObject(SelectObject(hDC, hOldFont)); 00087 00088 ReleaseDC((HWND)NULL, hDC); 00089 00090 return; 00091 } 00092 00093 /**********************************************************************/ 00094 /* InitSKT1ButtonPos */ 00095 /**********************************************************************/ 00096 void InitSKT1ButtonPos( 00097 LPSKT1CTXT lpSKT1Ctxt) 00098 { 00099 TEXTMETRIC tm; 00100 int nButtonWidthUnit, nButtonHeightUnit; 00101 int i, nLetterButtonStart, nLetterButtonEnd, xStartPos, yStartPos; 00102 00103 GetSKT1TextMetric(&tm); 00104 00105 nButtonWidthUnit = tm.tmMaxCharWidth + SKT1_LABEL_BMP_X - SKT1_XOVERLAP; 00106 00107 #define INIT_WIDTH(name, width) \ 00108 lpSKT1Ctxt->nButtonWidth[SKT1_ ## name ## _TYPE] = (width) 00109 00110 INIT_WIDTH(LETTER, nButtonWidthUnit * SKT1_LETTER_WIDTH_TIMES / 2); 00111 INIT_WIDTH(BACKSPACE, nButtonWidthUnit * SKT1_BACKSPACE_WIDTH_TIMES / 2 + 1); 00112 INIT_WIDTH(TAB, nButtonWidthUnit * SKT1_TAB_WIDTH_TIMES / 2 + (SKT1_XIN + 1) / 2); 00113 INIT_WIDTH(CAPS, nButtonWidthUnit * SKT1_CAPS_WIDTH_TIMES / 2 + SKT1_XIN); 00114 INIT_WIDTH(ENTER, nButtonWidthUnit * SKT1_ENTER_WIDTH_TIMES / 2 + (SKT1_XIN + 1) / 2); 00115 INIT_WIDTH(SHIFT, nButtonWidthUnit * SKT1_SHIFT_WIDTH_TIMES / 2 + SKT1_XIN + (SKT1_XIN + 1) / 2); 00116 INIT_WIDTH(CTRL, nButtonWidthUnit * SKT1_CTRL_WIDTH_TIMES / 2 + (SKT1_XIN + 1) / 2); 00117 INIT_WIDTH(ALT, nButtonWidthUnit * SKT1_ALT_WIDTH_TIMES / 2 + (SKT1_XIN + 1) / 2); 00118 INIT_WIDTH(ESC, nButtonWidthUnit * SKT1_ESC_WIDTH_TIMES / 2 + SKT1_XIN / 2); 00119 INIT_WIDTH(SPACE, nButtonWidthUnit * SKT1_SPACE_WIDTH_TIMES / 2 + SKT1_XIN * 5); 00120 00121 #undef INIT_WIDTH 00122 00123 nButtonHeightUnit = tm.tmHeight + SKT1_LABEL_BMP_Y; 00124 lpSKT1Ctxt->nButtonHeight[0] = nButtonHeightUnit; 00125 lpSKT1Ctxt->nButtonHeight[1] = nButtonHeightUnit * 2 + SKT1_YIN; // enter 00126 00127 // init first row attribute 00128 xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2; 00129 yStartPos = gptRaiseEdge.y + SKT1_YOUT + (SKT1_YIN + 1) / 2; 00130 00131 nLetterButtonStart = 0; 00132 nLetterButtonEnd = nLetterButtonStart + SKT1_ROW1_LETTER_NUM; 00133 00134 for (i = nLetterButtonStart; i < nLetterButtonEnd; i++) { 00135 lpSKT1Ctxt->ptButtonPos[i].x = xStartPos; 00136 lpSKT1Ctxt->ptButtonPos[i].y = yStartPos; 00137 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] + SKT1_XIN); 00138 } 00139 // backspace 00140 lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].x = xStartPos; 00141 lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].y = yStartPos; 00142 00143 // init second row attribute 00144 xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2; 00145 yStartPos += (nButtonHeightUnit + SKT1_YIN); 00146 // tab 00147 lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].x = xStartPos; 00148 lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].y = yStartPos; 00149 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE] + SKT1_XIN); 00150 // letter 00151 nLetterButtonStart = nLetterButtonEnd; 00152 nLetterButtonEnd = nLetterButtonStart + SKT1_ROW2_LETTER_NUM; 00153 for (i = nLetterButtonStart; i < nLetterButtonEnd; i++) { 00154 lpSKT1Ctxt->ptButtonPos[i].x = xStartPos; 00155 lpSKT1Ctxt->ptButtonPos[i].y = yStartPos; 00156 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] + SKT1_XIN); 00157 } 00158 // enter 00159 lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].x = xStartPos; 00160 lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].y = yStartPos; 00161 00162 // init third row 00163 xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2; 00164 yStartPos += (nButtonHeightUnit + SKT1_YIN); 00165 // caps 00166 lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].x = xStartPos; 00167 lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].y = yStartPos; 00168 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_CAPS_TYPE] + SKT1_XIN); 00169 // letter 00170 nLetterButtonStart = nLetterButtonEnd; 00171 nLetterButtonEnd = nLetterButtonStart + SKT1_ROW3_LETTER_NUM; 00172 for (i = nLetterButtonStart; i < nLetterButtonEnd; i++) { 00173 lpSKT1Ctxt->ptButtonPos[i].x = xStartPos; 00174 lpSKT1Ctxt->ptButtonPos[i].y = yStartPos; 00175 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] + SKT1_XIN); 00176 } 00177 00178 // init fourth row 00179 xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2; 00180 yStartPos += (nButtonHeightUnit + SKT1_YIN); 00181 // shift 1 00182 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].x = xStartPos; 00183 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].y = yStartPos; 00184 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE] + SKT1_XIN); 00185 // letter 00186 nLetterButtonStart = nLetterButtonEnd; 00187 nLetterButtonEnd = nLetterButtonStart + SKT1_ROW4_LETTER_NUM; 00188 for (i = nLetterButtonStart; i < nLetterButtonEnd; i++) { 00189 lpSKT1Ctxt->ptButtonPos[i].x = xStartPos; 00190 lpSKT1Ctxt->ptButtonPos[i].y = yStartPos; 00191 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] + SKT1_XIN); 00192 } 00193 // shift 2 00194 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].x = xStartPos; 00195 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].y = yStartPos; 00196 00197 // init fifth row 00198 xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2; 00199 yStartPos += (nButtonHeightUnit + SKT1_YIN); 00200 // ctrl 1 00201 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].x = xStartPos; 00202 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].y = yStartPos; 00203 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE] + SKT1_XIN); 00204 // esc 00205 lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].x = xStartPos; 00206 lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].y = yStartPos; 00207 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE] + SKT1_XIN); 00208 // alt 1 00209 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].x = xStartPos; 00210 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].y = yStartPos; 00211 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE] + SKT1_XIN); 00212 // space 00213 lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].x = xStartPos; 00214 lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].y = yStartPos; 00215 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_SPACE_TYPE] + SKT1_XIN); 00216 // alt 2 .. skip blank 00217 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].x = xStartPos; 00218 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].y = yStartPos; 00219 xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE] + SKT1_XIN) + 00220 (lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE] + SKT1_XIN); 00221 // ctrl 2 00222 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].x = xStartPos; 00223 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].y = yStartPos; 00224 00225 return; 00226 } 00227 00228 /**********************************************************************/ 00229 /* SKT1DrawConvexRect */ 00230 /* draw a convex rectangle */ 00231 /* (x,y) x+nWidth+1 */ 00232 /* +-----1------+ */ 00233 /* |+----2-----|| */ 00234 /* || || */ 00235 /* || 3| */ 00236 /* || || */ 00237 /* |V || <---- Rectangle */ 00238 /* |<----------+| */ 00239 /* y+nHeight+1 +------------+ */ 00240 /* 1 - black */ 00241 /* 2 - while */ 00242 /* 3 - dark gray */ 00243 /**********************************************************************/ 00244 void SKT1DrawConvexRect( 00245 HDC hDC, 00246 int x, 00247 int y, 00248 int nWidth, 00249 int nHeight) 00250 { 00251 // extend the context rect size 00252 x -= (SKT1_XIN + 1) / 2; 00253 y -= (SKT1_YIN + 1) / 2; 00254 nWidth += (SKT1_XIN + 1); 00255 nHeight += (SKT1_XIN + 1); 00256 00257 // 1 00258 SelectObject(hDC, GetStockObject(BLACK_PEN)); 00259 SelectObject(hDC, GetStockObject(LTGRAY_BRUSH)); 00260 Rectangle(hDC, x, y, x + nWidth, y + nHeight); 00261 PatBlt(hDC, x, y, 1, 1, PATCOPY); 00262 PatBlt(hDC, x + nWidth, y, -1, 1, PATCOPY); 00263 PatBlt(hDC, x, y + nHeight, 1, -1, PATCOPY); 00264 PatBlt(hDC, x + nWidth, y + nHeight, -1, -1, PATCOPY); 00265 00266 x++; 00267 y++; 00268 nWidth -= 2; 00269 nHeight -= 2; 00270 00271 // 2 00272 PatBlt(hDC, x, y + nHeight, 1, -nHeight, WHITENESS); 00273 PatBlt(hDC, x, y, nWidth , 1, WHITENESS); 00274 // 3 00275 SelectObject(hDC, GetStockObject(GRAY_BRUSH)); 00276 PatBlt(hDC, x, y + nHeight, nWidth, -1, PATCOPY); 00277 PatBlt(hDC, x + nWidth, y + nHeight, -1, -nHeight, PATCOPY); 00278 00279 return; 00280 } 00281 00282 /**********************************************************************/ 00283 /* SKT1DrawBitmap */ 00284 /**********************************************************************/ 00285 void SKT1DrawBitmap( 00286 HDC hDC, 00287 int x, 00288 int y, 00289 int nWidth, 00290 int nHeight, 00291 LPCWSTR lpszBitmap) 00292 { 00293 HDC hMemDC; 00294 HBITMAP hBitmap, hOldBmp; 00295 00296 hBitmap = (HBITMAP)LoadBitmap(ghInst, lpszBitmap); 00297 00298 hMemDC = CreateCompatibleDC(hDC); 00299 00300 hOldBmp = (HBITMAP)SelectObject(hMemDC, hBitmap); 00301 00302 BitBlt(hDC, x, y, nWidth, nHeight, hMemDC, 0 , 0, SRCCOPY); 00303 00304 SelectObject(hMemDC, hOldBmp); 00305 00306 DeleteObject(hBitmap); 00307 00308 DeleteDC(hMemDC); 00309 00310 return; 00311 } 00312 00313 /**********************************************************************/ 00314 /* SKT1DrawLabel */ 00315 /**********************************************************************/ 00316 void SKT1DrawLabel( 00317 HDC hDC, 00318 LPSKT1CTXT lpSKT1Ctxt, 00319 LPCWSTR lpszLabel) 00320 { 00321 HDC hMemDC; 00322 HBITMAP hBitmap, hOldBmp; 00323 int i; 00324 00325 hBitmap = LoadBitmap(ghInst, lpszLabel); 00326 hMemDC = CreateCompatibleDC(hDC); 00327 hOldBmp = (HBITMAP)SelectObject(hMemDC, hBitmap); 00328 00329 for (i = 0; i < SKT1_LETTER_KEY_NUM; i++) { 00330 BitBlt(hDC, 00331 lpSKT1Ctxt->ptButtonPos[i].x, lpSKT1Ctxt->ptButtonPos[i].y, 00332 SKT1_LABEL_BMP_X, SKT1_LABEL_BMP_Y, 00333 hMemDC, i * SKT1_LABEL_BMP_X, 0, SRCCOPY); 00334 } 00335 00336 SelectObject(hMemDC, hOldBmp); 00337 DeleteDC(hMemDC); 00338 DeleteObject(hBitmap); 00339 00340 return; 00341 } 00342 00343 00344 /**********************************************************************/ 00345 /* InitSKT1Bitmap */ 00346 /**********************************************************************/ 00347 void InitSKT1Bitmap( 00348 HWND hSKWnd, 00349 LPSKT1CTXT lpSKT1Ctxt) 00350 { 00351 HDC hDC, hMemDC; 00352 RECT rcClient; 00353 int i; 00354 00355 hDC = GetDC(hSKWnd); 00356 hMemDC = CreateCompatibleDC(hDC); 00357 GetClientRect(hSKWnd, &rcClient); 00358 lpSKT1Ctxt->hSKBitmap = CreateCompatibleBitmap(hDC, 00359 rcClient.right - rcClient.left, 00360 rcClient.bottom - rcClient.top); 00361 ReleaseDC(hSKWnd, hDC); 00362 SelectObject(hMemDC, lpSKT1Ctxt->hSKBitmap); 00363 00364 // draw SK rectangle 00365 SelectObject(hMemDC, GetStockObject(NULL_PEN)); 00366 SelectObject(hMemDC, GetStockObject(LTGRAY_BRUSH)); 00367 Rectangle(hMemDC, rcClient.left, rcClient.top, 00368 rcClient.right + 1, rcClient.bottom + 1); 00369 00370 DrawEdge(hMemDC, &rcClient, BDR_RAISED, BF_RECT); 00371 00372 // draw the button from the last line 00373 // ctrl 1 -> line 5 special key 00374 SKT1DrawConvexRect(hMemDC, 00375 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].x, 00376 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].y, 00377 lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE], 00378 lpSKT1Ctxt->nButtonHeight[0]); 00379 SKT1DrawBitmap(hMemDC, 00380 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].x + 00381 lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE] / 2 - SKT1_CTRL_BMP_X / 2, 00382 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].y + 00383 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_CTRL_BMP_Y / 2, 00384 SKT1_CTRL_BMP_X, 00385 SKT1_CTRL_BMP_Y, 00386 MAKEINTRESOURCEW(CTRL_T1)); 00387 00388 // ctrl 2 00389 SKT1DrawConvexRect(hMemDC, 00390 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].x, 00391 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].y, 00392 lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE], 00393 lpSKT1Ctxt->nButtonHeight[0]); 00394 SKT1DrawBitmap(hMemDC, 00395 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].x + 00396 lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE] / 2 - SKT1_CTRL_BMP_X / 2, 00397 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].y + 00398 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_CTRL_BMP_Y / 2, 00399 SKT1_CTRL_BMP_X, SKT1_CTRL_BMP_Y, 00400 MAKEINTRESOURCEW(CTRL_T1)); 00401 00402 // esc 00403 SKT1DrawConvexRect(hMemDC, 00404 lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].x, 00405 lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].y, 00406 lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE], 00407 lpSKT1Ctxt->nButtonHeight[0]); 00408 SKT1DrawBitmap(hMemDC, 00409 lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].x + 00410 lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE] / 2 - SKT1_ESC_BMP_X / 2, 00411 lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].y + 00412 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_ESC_BMP_Y / 2, 00413 SKT1_ESC_BMP_X, SKT1_ESC_BMP_Y, 00414 MAKEINTRESOURCEW(ESC_T1)); 00415 00416 // alt 1 00417 SKT1DrawConvexRect(hMemDC, 00418 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].x, 00419 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].y, 00420 lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE], 00421 lpSKT1Ctxt->nButtonHeight[0]); 00422 SKT1DrawBitmap(hMemDC, 00423 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].x + 00424 lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE] / 2 - SKT1_ALT_BMP_X / 2, 00425 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].y + 00426 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_ALT_BMP_Y / 2, 00427 SKT1_ALT_BMP_X, SKT1_ALT_BMP_Y, 00428 MAKEINTRESOURCEW(ALT_T1)); 00429 00430 // alt 2 00431 SKT1DrawConvexRect(hMemDC, 00432 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].x, 00433 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].y, 00434 lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE], 00435 lpSKT1Ctxt->nButtonHeight[0]); 00436 SKT1DrawBitmap(hMemDC, 00437 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].x + 00438 lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE] / 2 - SKT1_ALT_BMP_X / 2, 00439 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].y + 00440 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_ALT_BMP_Y / 2, 00441 SKT1_ALT_BMP_X, SKT1_ALT_BMP_Y, 00442 MAKEINTRESOURCEW(ALT_T1)); 00443 00444 // space 00445 SKT1DrawConvexRect(hMemDC, 00446 lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].x, 00447 lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].y, 00448 lpSKT1Ctxt->nButtonWidth[SKT1_SPACE_TYPE], 00449 lpSKT1Ctxt->nButtonHeight[0]); 00450 00451 // line 4 00452 // shift 1 00453 SKT1DrawConvexRect(hMemDC, 00454 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].x, 00455 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].y, 00456 lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE], 00457 lpSKT1Ctxt->nButtonHeight[0]); 00458 SKT1DrawBitmap(hMemDC, 00459 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].x + 00460 lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE] / 2 - SKT1_SHIFT_BMP_X / 2, 00461 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].y + 00462 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_SHIFT_BMP_Y / 2, 00463 SKT1_SHIFT_BMP_X, SKT1_SHIFT_BMP_Y, 00464 MAKEINTRESOURCEW(SHIFT_T1)); 00465 00466 // shift 2 00467 SKT1DrawConvexRect(hMemDC, 00468 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].x, 00469 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].y, 00470 lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE], 00471 lpSKT1Ctxt->nButtonHeight[0]); 00472 SKT1DrawBitmap(hMemDC, 00473 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].x + 00474 lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE] / 2 - SKT1_SHIFT_BMP_X / 2, 00475 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].y + 00476 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_SHIFT_BMP_Y / 2, 00477 SKT1_SHIFT_BMP_X, SKT1_SHIFT_BMP_Y, 00478 MAKEINTRESOURCEW(SHIFT_T1)); 00479 00480 // line 3 00481 // caps 00482 SKT1DrawConvexRect(hMemDC, 00483 lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].x, 00484 lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].y, 00485 lpSKT1Ctxt->nButtonWidth[SKT1_CAPS_TYPE], 00486 lpSKT1Ctxt->nButtonHeight[0]); 00487 SKT1DrawBitmap(hMemDC, 00488 lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].x + 00489 lpSKT1Ctxt->nButtonWidth[SKT1_CAPS_TYPE] / 2 - SKT1_CAPS_BMP_X / 2, 00490 lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].y + 00491 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_CAPS_BMP_Y / 2, 00492 SKT1_CAPS_BMP_X, SKT1_CAPS_BMP_Y, 00493 MAKEINTRESOURCEW(CAPS_T1)); 00494 00495 // line 2 00496 // tab 00497 SKT1DrawConvexRect(hMemDC, 00498 lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].x, 00499 lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].y, 00500 lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE], 00501 lpSKT1Ctxt->nButtonHeight[0]); 00502 SKT1DrawBitmap(hMemDC, 00503 lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].x + 00504 lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE] / 2 - SKT1_TAB_BMP_X / 2, 00505 lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].y + 00506 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_TAB_BMP_Y / 2, 00507 SKT1_TAB_BMP_X, SKT1_TAB_BMP_Y, 00508 MAKEINTRESOURCEW(TAB_T1)); 00509 00510 // enter 00511 SKT1DrawConvexRect(hMemDC, 00512 lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].x, 00513 lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].y, 00514 lpSKT1Ctxt->nButtonWidth[SKT1_ENTER_TYPE], 00515 lpSKT1Ctxt->nButtonHeight[1]); 00516 SKT1DrawBitmap(hMemDC, 00517 lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].x + 00518 lpSKT1Ctxt->nButtonWidth[SKT1_ENTER_TYPE] / 2 - SKT1_ENTER_BMP_X / 2, 00519 lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].y + 00520 lpSKT1Ctxt->nButtonHeight[1] / 2 - SKT1_ENTER_BMP_Y / 2, 00521 SKT1_ENTER_BMP_X, SKT1_ENTER_BMP_Y, 00522 MAKEINTRESOURCEW(ENTER_T1)); 00523 00524 // line 1 00525 // backspace 00526 SKT1DrawConvexRect(hMemDC, 00527 lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].x, 00528 lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].y, 00529 lpSKT1Ctxt->nButtonWidth[SKT1_BACKSPACE_TYPE], 00530 lpSKT1Ctxt->nButtonHeight[0]); 00531 SKT1DrawBitmap(hMemDC, 00532 lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].x + 00533 lpSKT1Ctxt->nButtonWidth[SKT1_BACKSPACE_TYPE] / 2 - SKT1_BACKSPACE_BMP_X / 2, 00534 lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].y + 00535 lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_BACKSPACE_BMP_Y / 2, 00536 SKT1_BACKSPACE_BMP_X, SKT1_BACKSPACE_BMP_Y, 00537 MAKEINTRESOURCEW(BACK_T1)); 00538 00539 // draw letter buttons 00540 for (i = SKT1_LETTER_KEY_NUM - 1; i >= 0 ; i--) { 00541 SKT1DrawConvexRect(hMemDC, 00542 lpSKT1Ctxt->ptButtonPos[i].x, 00543 lpSKT1Ctxt->ptButtonPos[i].y, 00544 lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE], 00545 lpSKT1Ctxt->nButtonHeight[0]); 00546 } 00547 00548 // draw latter label 00549 SKT1DrawLabel(hMemDC, lpSKT1Ctxt, MAKEINTRESOURCEW(LABEL_T1)); 00550 00551 DeleteDC(hMemDC); 00552 00553 return; 00554 } 00555 00556 00557 /**********************************************************************/ 00558 /* CreateT1Window */ 00559 /**********************************************************************/ 00560 LRESULT CreateT1Window( 00561 HWND hSKWnd) 00562 { 00563 HGLOBAL hSKT1Ctxt; 00564 LPSKT1CTXT lpSKT1Ctxt; 00565 00566 hSKT1Ctxt = GlobalAlloc(GHND, sizeof(SKT1CTXT)); 00567 if (!hSKT1Ctxt) { 00568 return (-1); 00569 } 00570 00571 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 00572 if (!lpSKT1Ctxt) { 00573 GlobalFree(hSKT1Ctxt); 00574 return (-1); 00575 } 00576 00577 SetWindowLongPtr(hSKWnd, SKT1_CONTEXT, (LONG_PTR)hSKT1Ctxt); 00578 00579 lpSKT1Ctxt->uKeyIndex = SKT1_TOTAL_INDEX; 00580 lpSKT1Ctxt->ptSkOffset.x = SKT1_NOT_DRAG; 00581 lpSKT1Ctxt->ptSkOffset.y = SKT1_NOT_DRAG; 00582 lpSKT1Ctxt->lfCharSet = CHINESEBIG5_CHARSET; 00583 00584 InitSKT1ButtonPos(lpSKT1Ctxt); 00585 00586 InitSKT1Bitmap(hSKWnd, lpSKT1Ctxt); 00587 00588 GlobalUnlock(hSKT1Ctxt); 00589 00590 return (0L); 00591 } 00592 00593 /**********************************************************************/ 00594 /* SKT1DrawDragBorder() */ 00595 /**********************************************************************/ 00596 void SKT1DrawDragBorder( 00597 HWND hWnd, // window of IME is dragged 00598 LPPOINT lpptCursor, // the cursor position 00599 LPPOINT lpptOffset) // the offset form cursor to window org 00600 { 00601 HDC hDC; 00602 int cxBorder, cyBorder; 00603 int x, y; 00604 RECT rcWnd; 00605 00606 cxBorder = GetSystemMetrics(SM_CXBORDER); // width of border 00607 cyBorder = GetSystemMetrics(SM_CYBORDER); // height of border 00608 00609 x = lpptCursor->x - lpptOffset->x; 00610 y = lpptCursor->y - lpptOffset->y; 00611 00612 // check for the max boundary of the display 00613 GetWindowRect(hWnd, &rcWnd); 00614 00615 // draw the moving track 00616 hDC = CreateDC(L"DISPLAY", NULL, NULL, NULL); 00617 SelectObject(hDC, GetStockObject(GRAY_BRUSH)); 00618 00619 // -> 00620 PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder, 00621 PATINVERT); 00622 // v 00623 PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top - 00624 cyBorder, PATINVERT); 00625 // _> 00626 PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top, 00627 rcWnd.right - rcWnd.left - cxBorder, -cyBorder, PATINVERT); 00628 // v 00629 PatBlt(hDC, x + rcWnd.right - rcWnd.left, y, 00630 - cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT); 00631 00632 DeleteDC(hDC); 00633 return; 00634 } 00635 00636 /**********************************************************************/ 00637 /* DestroyT1Window */ 00638 /**********************************************************************/ 00639 void DestroyT1Window( 00640 HWND hSKWnd) 00641 { 00642 HGLOBAL hSKT1Ctxt; 00643 LPSKT1CTXT lpSKT1Ctxt; 00644 HWND hUIWnd; 00645 00646 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT); 00647 if (!hSKT1Ctxt) { 00648 return; 00649 } 00650 00651 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 00652 if (!lpSKT1Ctxt) { 00653 return; 00654 } 00655 00656 if (lpSKT1Ctxt->ptSkOffset.x != SKT1_NOT_DRAG && 00657 lpSKT1Ctxt->ptSkOffset.y != SKT1_NOT_DRAG) { 00658 SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor, 00659 &lpSKT1Ctxt->ptSkOffset); 00660 } 00661 00662 DeleteObject(lpSKT1Ctxt->hSKBitmap); 00663 00664 GlobalUnlock(hSKT1Ctxt); 00665 GlobalFree(hSKT1Ctxt); 00666 00667 hUIWnd = GetWindow(hSKWnd, GW_OWNER); 00668 if (!hUIWnd) { 00669 return; 00670 } 00671 00672 SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_SOFTKBDDESTROYED, 0); 00673 00674 return; 00675 } 00676 00677 /**********************************************************************/ 00678 /* SKT1InvertButton */ 00679 /**********************************************************************/ 00680 void SKT1InvertButton( 00681 HWND hSKWnd, 00682 HDC hPaintDC, 00683 LPSKT1CTXT lpSKT1Ctxt, 00684 UINT uKeyIndex) 00685 { 00686 HDC hDC; 00687 int nWidth, nHeight; 00688 00689 if (uKeyIndex >= SKT1_TOTAL_INDEX) { 00690 return; 00691 } 00692 00693 nWidth = 0; 00694 if (hPaintDC) { 00695 hDC = hPaintDC; 00696 } else { 00697 hDC = GetDC(hSKWnd); 00698 } 00699 00700 if (uKeyIndex < SKT1_LETTER_KEY_NUM) { 00701 nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE]; 00702 } else { 00703 switch (uKeyIndex) { 00704 case SKT1_BACKSPACE_INDEX: 00705 nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_BACKSPACE_TYPE]; 00706 break; 00707 case SKT1_TAB_INDEX: 00708 nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE]; 00709 break; 00710 case SKT1_CAPS_INDEX: 00711 nWidth = 0; 00712 MessageBeep((UINT) -1); 00713 break; 00714 case SKT1_ENTER_INDEX: 00715 nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_ENTER_TYPE]; 00716 break; 00717 case SKT1_SHIFT_INDEX: 00718 case SKT1_SHIFT_INDEX + 1: 00719 case SKT1_CTRL_INDEX: 00720 case SKT1_CTRL_INDEX + 1: 00721 case SKT1_ALT_INDEX: 00722 case SKT1_ALT_INDEX + 1: 00723 nWidth = 0; 00724 MessageBeep((UINT) -1); 00725 break; 00726 case SKT1_ESC_INDEX: 00727 nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE]; 00728 break; 00729 case SKT1_SPACE_INDEX: 00730 nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_SPACE_TYPE]; 00731 break; 00732 default: 00733 break; 00734 } 00735 } 00736 00737 if (uKeyIndex == SKT1_ENTER_INDEX) { 00738 nHeight = lpSKT1Ctxt->nButtonHeight[1]; 00739 } else { 00740 nHeight = lpSKT1Ctxt->nButtonHeight[0]; 00741 } 00742 00743 if (nWidth) { 00744 // do not reverse border 00745 PatBlt(hDC, lpSKT1Ctxt->ptButtonPos[uKeyIndex].x - 1, 00746 lpSKT1Ctxt->ptButtonPos[uKeyIndex].y - 1, 00747 nWidth + 2, nHeight + 2, DSTINVERT); 00748 } 00749 00750 if (!hPaintDC) { 00751 ReleaseDC(hSKWnd, hDC); 00752 } 00753 00754 return; 00755 } 00756 00757 /**********************************************************************/ 00758 /* UpdateSKT1Window */ 00759 /**********************************************************************/ 00760 void UpdateSKT1Window( 00761 HDC hDC, 00762 HWND hSKWnd) 00763 { 00764 HGLOBAL hSKT1Ctxt; 00765 LPSKT1CTXT lpSKT1Ctxt; 00766 HDC hMemDC; 00767 RECT rcClient; 00768 00769 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT); 00770 if (!hSKT1Ctxt) { 00771 return; 00772 } 00773 00774 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 00775 if (!lpSKT1Ctxt) { 00776 return; 00777 } 00778 00779 hMemDC = CreateCompatibleDC(hDC); 00780 00781 SelectObject(hMemDC, lpSKT1Ctxt->hSKBitmap); 00782 00783 GetClientRect(hSKWnd, &rcClient); 00784 00785 BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, 00786 rcClient.bottom - rcClient.top, 00787 hMemDC, 0, 0, SRCCOPY); 00788 00789 DeleteDC(hMemDC); 00790 00791 if (lpSKT1Ctxt->uKeyIndex < SKT1_TOTAL_INDEX) { 00792 SKT1InvertButton(hSKWnd, hDC, lpSKT1Ctxt, lpSKT1Ctxt->uKeyIndex); 00793 } 00794 00795 GlobalUnlock(hSKT1Ctxt); 00796 00797 return; 00798 } 00799 00800 /**********************************************************************/ 00801 /* SKT1MousePosition() */ 00802 /**********************************************************************/ 00803 UINT SKT1MousePosition( 00804 LPSKT1CTXT lpSKT1Ctxt, 00805 LPPOINT lpptCursor) 00806 { 00807 int i; 00808 00809 // check letter button 00810 for (i = 0; i < SKT1_LETTER_KEY_NUM; i++) { 00811 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[i].x, 00812 lpSKT1Ctxt->ptButtonPos[i].y, 00813 lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE], 00814 lpSKT1Ctxt->nButtonHeight[0], 00815 lpptCursor)) { 00816 return i; 00817 } 00818 } 00819 00820 // backSapce 00821 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].x, 00822 lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].y, 00823 lpSKT1Ctxt->nButtonWidth[SKT1_BACKSPACE_TYPE], 00824 lpSKT1Ctxt->nButtonHeight[0], 00825 lpptCursor)) { 00826 return SKT1_BACKSPACE_INDEX; 00827 } 00828 00829 // tab 00830 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].x, 00831 lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].y, 00832 lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE], 00833 lpSKT1Ctxt->nButtonHeight[0], 00834 lpptCursor)) { 00835 return SKT1_TAB_INDEX; 00836 } 00837 00838 // caps 00839 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].x, 00840 lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].y, 00841 lpSKT1Ctxt->nButtonWidth[SKT1_CAPS_TYPE], 00842 lpSKT1Ctxt->nButtonHeight[0], 00843 lpptCursor)) { 00844 return SKT1_CAPS_INDEX; 00845 } 00846 00847 // enter 00848 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].x, 00849 lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].y, 00850 lpSKT1Ctxt->nButtonWidth[SKT1_ENTER_TYPE], 00851 lpSKT1Ctxt->nButtonHeight[1], 00852 lpptCursor)) { 00853 return SKT1_ENTER_INDEX; 00854 } 00855 00856 // shift 1 00857 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].x, 00858 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].y, 00859 lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE], 00860 lpSKT1Ctxt->nButtonHeight[0], 00861 lpptCursor)) { 00862 return SKT1_SHIFT_INDEX; 00863 } 00864 00865 // shift 2 00866 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].x, 00867 lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].y, 00868 lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE], 00869 lpSKT1Ctxt->nButtonHeight[0], 00870 lpptCursor)) { 00871 return SKT1_SHIFT_INDEX; 00872 } 00873 00874 // ctrl 1 00875 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].x, 00876 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].y, 00877 lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE], 00878 lpSKT1Ctxt->nButtonHeight[0], 00879 lpptCursor)) { 00880 return SKT1_CTRL_INDEX; 00881 } 00882 00883 // ctrl 2 00884 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].x, 00885 lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].y, 00886 lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE], 00887 lpSKT1Ctxt->nButtonHeight[0], 00888 lpptCursor)) { 00889 return SKT1_CTRL_INDEX; 00890 } 00891 00892 // alt 1 00893 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].x, 00894 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].y, 00895 lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE], 00896 lpSKT1Ctxt->nButtonHeight[0], 00897 lpptCursor)) { 00898 return SKT1_ALT_INDEX; 00899 } 00900 00901 // alt 2 00902 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].x, 00903 lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].y, 00904 lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE], 00905 lpSKT1Ctxt->nButtonHeight[0], 00906 lpptCursor)) { 00907 return SKT1_ALT_INDEX; 00908 } 00909 00910 // esc 00911 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].x, 00912 lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].y, 00913 lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE], 00914 lpSKT1Ctxt->nButtonHeight[0], 00915 lpptCursor)) { 00916 return SKT1_ESC_INDEX; 00917 } 00918 00919 // space 00920 if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].x, 00921 lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].y, 00922 lpSKT1Ctxt->nButtonWidth[SKT1_SPACE_TYPE], 00923 lpSKT1Ctxt->nButtonHeight[0], 00924 lpptCursor)) { 00925 return SKT1_SPACE_INDEX; 00926 } 00927 00928 return SKT1_TOTAL_INDEX; // This means out of range 00929 } 00930 00931 /**********************************************************************/ 00932 /* SKT1IsValidButton */ 00933 /**********************************************************************/ 00934 BOOL SKT1IsValidButton( 00935 UINT uKeyIndex, 00936 LPSKT1CTXT lpSKT1Ctxt) 00937 { 00938 BOOL fRet; 00939 00940 if (uKeyIndex < SKT1_LETTER_KEY_NUM) { 00941 if (lpSKT1Ctxt->wCodeTable[uKeyIndex]) { 00942 return TRUE; 00943 } else { 00944 return FALSE; 00945 } 00946 } 00947 00948 // special key 00949 switch (uKeyIndex) { 00950 case SKT1_BACKSPACE_INDEX: 00951 case SKT1_TAB_INDEX: 00952 case SKT1_ENTER_INDEX: 00953 case SKT1_ESC_INDEX: 00954 case SKT1_SPACE_INDEX: 00955 fRet = TRUE; 00956 break; 00957 default: 00958 fRet = FALSE; 00959 break; 00960 } 00961 00962 return fRet; 00963 } 00964 00965 /**********************************************************************/ 00966 /* SKT1SetCursor */ 00967 /**********************************************************************/ 00968 BOOL SKT1SetCursor( 00969 HWND hSKWnd, 00970 LPARAM lParam) 00971 { 00972 HGLOBAL hSKT1Ctxt; 00973 LPSKT1CTXT lpSKT1Ctxt; 00974 UINT uKeyIndex; 00975 RECT rcWnd; 00976 RECT rcWork; 00977 SIZE szWork; 00978 extern void GetAllMonitorSize(LPRECT lprc); 00979 00980 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT); 00981 if (!hSKT1Ctxt) { 00982 return (FALSE); 00983 } 00984 00985 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 00986 if (!lpSKT1Ctxt) { 00987 return (FALSE); 00988 } 00989 00990 if (lpSKT1Ctxt->ptSkOffset.x != SKT1_NOT_DRAG && 00991 lpSKT1Ctxt->ptSkOffset.y != SKT1_NOT_DRAG) { 00992 // in drag operation 00993 SetCursor(LoadCursor(NULL, IDC_SIZEALL)); 00994 goto UnlockSKT1Ctxt; 00995 } 00996 00997 GetCursorPos(&lpSKT1Ctxt->ptSkCursor); 00998 ScreenToClient(hSKWnd, &lpSKT1Ctxt->ptSkCursor); 00999 01000 uKeyIndex = SKT1MousePosition(lpSKT1Ctxt, &lpSKT1Ctxt->ptSkCursor); 01001 01002 if (uKeyIndex < SKT1_TOTAL_INDEX) { 01003 SetCursor(LoadCursor(NULL, IDC_HAND)); 01004 } else { 01005 SetCursor(LoadCursor(NULL, IDC_SIZEALL)); 01006 } 01007 01008 01009 if (HIWORD(lParam) != WM_LBUTTONDOWN) { 01010 goto UnlockSKT1Ctxt; 01011 } 01012 01013 SetCapture(hSKWnd); 01014 01015 if (lpSKT1Ctxt->uKeyIndex < SKT1_TOTAL_INDEX) { 01016 UINT uVirtKey; 01017 01018 uVirtKey = bSKT1VirtKey[lpSKT1Ctxt->uKeyIndex]; 01019 keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey], 01020 (DWORD)KEYEVENTF_KEYUP, 0); 01021 SKT1InvertButton(hSKWnd, NULL, lpSKT1Ctxt, lpSKT1Ctxt->uKeyIndex); 01022 lpSKT1Ctxt->uKeyIndex = SKT1_TOTAL_INDEX; 01023 } 01024 01025 if (uKeyIndex < SKT1_TOTAL_INDEX) { 01026 UINT uVirtKey; 01027 01028 if (SKT1IsValidButton(uKeyIndex, lpSKT1Ctxt)) { 01029 uVirtKey = bSKT1VirtKey[uKeyIndex]; 01030 keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey], 01031 0, 0); 01032 lpSKT1Ctxt->uKeyIndex = uKeyIndex; 01033 SKT1InvertButton(hSKWnd, NULL, lpSKT1Ctxt, lpSKT1Ctxt->uKeyIndex); 01034 } else { 01035 MessageBeep((UINT)-1); 01036 } 01037 goto UnlockSKT1Ctxt; 01038 } 01039 01040 GetAllMonitorSize(&rcWork); 01041 szWork.cx = rcWork.right - rcWork.left; 01042 szWork.cy = rcWork.bottom - rcWork.top; 01043 01044 GetCursorPos(&lpSKT1Ctxt->ptSkCursor); 01045 GetWindowRect(hSKWnd, &rcWnd); 01046 lpSKT1Ctxt->ptSkOffset.x = lpSKT1Ctxt->ptSkCursor.x - rcWnd.left; 01047 lpSKT1Ctxt->ptSkOffset.y = lpSKT1Ctxt->ptSkCursor.y - rcWnd.top; 01048 01049 SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor, 01050 &lpSKT1Ctxt->ptSkOffset); 01051 01052 UnlockSKT1Ctxt: 01053 GlobalUnlock(hSKT1Ctxt); 01054 01055 return (TRUE); 01056 } 01057 01058 /**********************************************************************/ 01059 /* SKT1MouseMove */ 01060 /**********************************************************************/ 01061 BOOL SKT1MouseMove( 01062 HWND hSKWnd) 01063 { 01064 HGLOBAL hSKT1Ctxt; 01065 LPSKT1CTXT lpSKT1Ctxt; 01066 01067 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT); 01068 if (!hSKT1Ctxt) { 01069 return FALSE; 01070 } 01071 01072 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 01073 if (!lpSKT1Ctxt) { 01074 return FALSE; 01075 } 01076 01077 if (lpSKT1Ctxt->ptSkOffset.x == SKT1_NOT_DRAG || 01078 lpSKT1Ctxt->ptSkOffset.y == SKT1_NOT_DRAG) { 01079 GlobalUnlock(hSKT1Ctxt); 01080 return FALSE; 01081 } 01082 01083 SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor, 01084 &lpSKT1Ctxt->ptSkOffset); 01085 01086 GetCursorPos(&lpSKT1Ctxt->ptSkCursor); 01087 01088 SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor, 01089 &lpSKT1Ctxt->ptSkOffset); 01090 01091 GlobalUnlock(hSKT1Ctxt); 01092 01093 return TRUE; 01094 } 01095 01096 /**********************************************************************/ 01097 /* SKT1ButtonUp */ 01098 /**********************************************************************/ 01099 BOOL SKT1ButtonUp( 01100 HWND hSKWnd) 01101 { 01102 HGLOBAL hSKT1Ctxt; 01103 LPSKT1CTXT lpSKT1Ctxt; 01104 BOOL fRet; 01105 POINT pt; 01106 HWND hUIWnd; 01107 HIMC hIMC; 01108 LPINPUTCONTEXT lpIMC; 01109 01110 fRet = FALSE; 01111 01112 if (IsWndEqual(GetCapture(), hSKWnd)) { 01113 ReleaseCapture(); 01114 } 01115 01116 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT); 01117 if (!hSKT1Ctxt) { 01118 return (fRet); 01119 } 01120 01121 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 01122 if (!lpSKT1Ctxt) { 01123 return (fRet); 01124 } 01125 01126 if (lpSKT1Ctxt->uKeyIndex < SKT1_TOTAL_INDEX) { 01127 UINT uVirtKey; 01128 01129 uVirtKey = bSKT1VirtKey[lpSKT1Ctxt->uKeyIndex]; 01130 keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey], 01131 (DWORD)KEYEVENTF_KEYUP, 0); 01132 SKT1InvertButton(hSKWnd, NULL, lpSKT1Ctxt, lpSKT1Ctxt->uKeyIndex); 01133 lpSKT1Ctxt->uKeyIndex = SKT1_TOTAL_INDEX; 01134 fRet = TRUE; 01135 goto UnlockSKT1Context; 01136 } 01137 01138 if (lpSKT1Ctxt->ptSkOffset.x == SKT1_NOT_DRAG || 01139 lpSKT1Ctxt->ptSkOffset.y == SKT1_NOT_DRAG) { 01140 goto UnlockSKT1Context; 01141 } 01142 01143 SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor, 01144 &lpSKT1Ctxt->ptSkOffset); 01145 01146 pt.x = lpSKT1Ctxt->ptSkCursor.x - lpSKT1Ctxt->ptSkOffset.x, 01147 pt.y = lpSKT1Ctxt->ptSkCursor.y - lpSKT1Ctxt->ptSkOffset.y, 01148 01149 SetWindowPos(hSKWnd, (HWND)NULL, pt.x, pt.y, 01150 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER); 01151 01152 lpSKT1Ctxt->ptSkOffset.x = SKT1_NOT_DRAG; 01153 lpSKT1Ctxt->ptSkOffset.y = SKT1_NOT_DRAG; 01154 01155 lpSKT1Ctxt->uKeyIndex = SKT1_TOTAL_INDEX; 01156 01157 fRet = TRUE; 01158 01159 hUIWnd = GetWindow(hSKWnd, GW_OWNER); 01160 01161 hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); 01162 if (!hIMC) { 01163 goto UnlockSKT1Context; 01164 } 01165 01166 lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); 01167 if (!lpIMC) { 01168 goto UnlockSKT1Context; 01169 } 01170 01171 lpIMC->ptSoftKbdPos.x = pt.x; 01172 lpIMC->ptSoftKbdPos.y = pt.y; 01173 lpIMC->fdwInit |= INIT_SOFTKBDPOS; 01174 01175 ImmUnlockIMC(hIMC); 01176 01177 UnlockSKT1Context: 01178 GlobalUnlock(hSKT1Ctxt); 01179 01180 return (fRet); 01181 } 01182 01183 /**********************************************************************/ 01184 /* SetSKT1Data */ 01185 /**********************************************************************/ 01186 LRESULT SetSKT1Data( 01187 HWND hSKWnd, 01188 LPSOFTKBDDATA lpSoftKbdData) 01189 { 01190 HGLOBAL hSKT1Ctxt; 01191 LPSKT1CTXT lpSKT1Ctxt; 01192 HDC hDC, hMemDC; 01193 HGDIOBJ hOldFont; 01194 int i; 01195 01196 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT); 01197 if (!hSKT1Ctxt) { 01198 return (1); 01199 } 01200 01201 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 01202 if (!lpSKT1Ctxt) { 01203 return (1); 01204 } 01205 01206 hDC = GetDC(hSKWnd); 01207 hMemDC = CreateCompatibleDC(hDC); 01208 ReleaseDC(hSKWnd, hDC); 01209 SelectObject(hMemDC, lpSKT1Ctxt->hSKBitmap); 01210 01211 SetBkColor(hMemDC, RGB(0xC0, 0xC0, 0xC0)); 01212 01213 if (lpSKT1Ctxt->lfCharSet != DEFAULT_CHARSET) { 01214 LOGFONT lfFont; 01215 CopyMemory(&lfFont, &lfSKT1Font, sizeof (LOGFONT)); 01216 lfFont.lfCharSet = (BYTE)lpSKT1Ctxt->lfCharSet; 01217 hOldFont = (HFONT)SelectObject(hMemDC, CreateFontIndirect(&lfFont)); 01218 } 01219 else { 01220 hOldFont = (HFONT)SelectObject(hMemDC, CreateFontIndirect(&lfSKT1Font)); 01221 } 01222 01223 for (i = 0; i < SKT1_LETTER_KEY_NUM; i++) { 01224 int cbCount; 01225 RECT rcOpaque; 01226 01227 lpSKT1Ctxt->wCodeTable[i] = lpSoftKbdData->wCode[0][bSKT1VirtKey[i]]; 01228 01229 cbCount = (lpSKT1Ctxt->wCodeTable[i] == 0) ? 0 : 1; 01230 01231 rcOpaque.left = lpSKT1Ctxt->ptButtonPos[i].x + SKT1_LABEL_BMP_X - 01232 SKT1_XOVERLAP; 01233 rcOpaque.top = lpSKT1Ctxt->ptButtonPos[i].y + SKT1_LABEL_BMP_Y; 01234 01235 rcOpaque.right = rcOpaque.left + 01236 lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] - SKT1_LABEL_BMP_X + 01237 SKT1_XOVERLAP; 01238 rcOpaque.bottom = rcOpaque.top + lpSKT1Ctxt->nButtonHeight[0] - 01239 SKT1_LABEL_BMP_Y; 01240 01241 ExtTextOut(hMemDC, rcOpaque.left, rcOpaque.top, 01242 ETO_OPAQUE, &rcOpaque, 01243 (LPWSTR)&lpSKT1Ctxt->wCodeTable[i], cbCount, NULL); 01244 } 01245 01246 DeleteObject(SelectObject(hMemDC, hOldFont)); 01247 01248 DeleteDC(hMemDC); 01249 01250 GlobalUnlock(hSKT1Ctxt); 01251 01252 return (0); 01253 } 01254 01255 /**********************************************************************/ 01256 /* SKWndProcT1 */ 01257 /**********************************************************************/ 01258 LRESULT CALLBACK SKWndProcT1( 01259 HWND hSKWnd, 01260 UINT uMsg, 01261 WPARAM wParam, 01262 LPARAM lParam) 01263 { 01264 switch (uMsg) { 01265 case WM_CREATE: 01266 return CreateT1Window(hSKWnd); 01267 case WM_DESTROY: 01268 DestroyT1Window(hSKWnd); 01269 break; 01270 case WM_PAINT: 01271 { 01272 HDC hDC; 01273 PAINTSTRUCT ps; 01274 01275 hDC = BeginPaint(hSKWnd, &ps); 01276 UpdateSKT1Window(hDC, hSKWnd); 01277 EndPaint(hSKWnd, &ps); 01278 } 01279 break; 01280 case WM_SETCURSOR: 01281 if (!SKT1SetCursor(hSKWnd, lParam)) { 01282 return DefWindowProc(hSKWnd, uMsg, wParam, lParam); 01283 } 01284 break; 01285 case WM_MOUSEMOVE: 01286 if (!SKT1MouseMove(hSKWnd)) { 01287 return DefWindowProc(hSKWnd, uMsg, wParam, lParam); 01288 } 01289 break; 01290 case WM_LBUTTONUP: 01291 if (!SKT1ButtonUp(hSKWnd)) { 01292 return DefWindowProc(hSKWnd, uMsg, wParam, lParam); 01293 } 01294 break; 01295 case WM_MOUSEACTIVATE: 01296 return (MA_NOACTIVATE); 01297 case WM_SHOWWINDOW: 01298 if (lParam != 0) { 01299 } else if ((BOOL)wParam == TRUE) { 01300 } else { 01301 // we want to hide the soft keyboard on mouse button down 01302 SKT1ButtonUp(hSKWnd); 01303 } 01304 01305 return DefWindowProc(hSKWnd, uMsg, wParam, lParam); 01306 01307 case WM_IME_CONTROL: 01308 switch (wParam) { 01309 case IMC_GETSOFTKBDFONT: 01310 { 01311 HGLOBAL hSKT1Ctxt; 01312 LPSKT1CTXT lpSKT1Ctxt; 01313 BYTE lfCharSet; 01314 01315 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT); 01316 if (!hSKT1Ctxt) { 01317 return (1); 01318 } 01319 01320 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 01321 if (!lpSKT1Ctxt) { 01322 return (1); 01323 } 01324 01325 lfCharSet = (BYTE)lpSKT1Ctxt->lfCharSet; 01326 01327 GlobalUnlock(hSKT1Ctxt); 01328 01329 *(LPLOGFONT)lParam = lfSKT1Font; 01330 01331 if (lfCharSet != DEFAULT_CHARSET) { 01332 ((LPLOGFONT)lParam)->lfCharSet = lfCharSet; 01333 } 01334 01335 return (0); 01336 } 01337 break; 01338 case IMC_SETSOFTKBDFONT: 01339 { 01340 // in differet version of Windows 01341 if (lfSKT1Font.lfCharSet != ((LPLOGFONT)lParam)->lfCharSet) { 01342 HGLOBAL hSKT1Ctxt; 01343 LPSKT1CTXT lpSKT1Ctxt; 01344 01345 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, 01346 SKT1_CONTEXT); 01347 if (!hSKT1Ctxt) { 01348 return 1; 01349 } 01350 01351 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 01352 if (!lpSKT1Ctxt) { 01353 return 1; 01354 } 01355 01356 lpSKT1Ctxt->lfCharSet = ((LPLOGFONT)lParam)->lfCharSet; 01357 01358 GlobalUnlock(hSKT1Ctxt); 01359 } 01360 } 01361 break; 01362 case IMC_GETSOFTKBDPOS: 01363 { 01364 RECT rcWnd; 01365 01366 GetWindowRect(hSKWnd, &rcWnd); 01367 01368 return MAKELRESULT(rcWnd.left, rcWnd.top); 01369 } 01370 break; 01371 case IMC_SETSOFTKBDPOS: 01372 { 01373 POINT ptSoftKbdPos; 01374 HWND hUIWnd; 01375 HIMC hIMC; 01376 LPINPUTCONTEXT lpIMC; 01377 01378 ptSoftKbdPos.x = ((LPPOINTS)lParam)->x; 01379 ptSoftKbdPos.y = ((LPPOINTS)lParam)->y; 01380 01381 SetWindowPos(hSKWnd, NULL, 01382 ptSoftKbdPos.x, ptSoftKbdPos.y, 01383 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER); 01384 01385 // Here we want to get - the owner or parent window 01386 hUIWnd = GetParent(hSKWnd); 01387 01388 if (!hUIWnd) { 01389 return (1); 01390 } 01391 01392 hIMC = (HIMC) GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); 01393 01394 if (!hIMC) { 01395 return (1); 01396 } 01397 01398 lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); 01399 01400 if (!lpIMC) { 01401 return (1); 01402 } 01403 01404 lpIMC->ptSoftKbdPos = ptSoftKbdPos; 01405 01406 ImmUnlockIMC(hIMC); 01407 01408 return (0); 01409 } 01410 break; 01411 case IMC_SETSOFTKBDDATA: 01412 { 01413 LRESULT lRet; 01414 01415 lRet = SetSKT1Data(hSKWnd, (LPSOFTKBDDATA)lParam); 01416 if (!lRet) { 01417 InvalidateRect(hSKWnd, NULL, FALSE); 01418 PostMessage(hSKWnd, WM_PAINT, 0, 0); 01419 } 01420 return (lRet); 01421 } 01422 break; 01423 case IMC_GETSOFTKBDSUBTYPE: 01424 case IMC_SETSOFTKBDSUBTYPE: 01425 { 01426 HGLOBAL hSKT1Ctxt; 01427 LPSKT1CTXT lpSKT1Ctxt; 01428 LRESULT lRet; 01429 01430 lRet = -1; 01431 01432 hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT); 01433 if (!hSKT1Ctxt) { 01434 return (lRet); 01435 } 01436 01437 lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt); 01438 if (!lpSKT1Ctxt) { 01439 return (lRet); 01440 } 01441 01442 if (wParam == IMC_GETSOFTKBDSUBTYPE) { 01443 lRet = lpSKT1Ctxt->uSubType; 01444 } else if (wParam == IMC_SETSOFTKBDSUBTYPE) { 01445 lRet = lpSKT1Ctxt->uSubType; 01446 lpSKT1Ctxt->uSubType = (UINT)lParam; 01447 } else { 01448 lRet = -1; 01449 } 01450 01451 GlobalUnlock(hSKT1Ctxt); 01452 return (lRet); 01453 } 01454 break; 01455 default: 01456 break; 01457 } 01458 break; 01459 default: 01460 return DefWindowProc(hSKWnd, uMsg, wParam, lParam); 01461 } 01462 01463 return (0L); 01464 }

Generated on Sat May 15 19:41:49 2004 for test by doxygen 1.3.7