You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1464 lines
48 KiB
1464 lines
48 KiB
/**************************************************************************\
|
|
* Module Name: sftkbdt1.c
|
|
*
|
|
* Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
*
|
|
* Soft keyboard support for Traditional Chinese
|
|
*
|
|
* History:
|
|
* 02-Jan-1996 wkwok - ported from Win95
|
|
\**************************************************************************/
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include "softkbd.h"
|
|
|
|
|
|
CONST BYTE bSKT1VirtKey[SKT1_TOTAL_KEY_NUM] = { // Virtual Key for Letter Buttons
|
|
// ` 1 2 3 4 5 6 7 8 9 0
|
|
VK_OEM_3, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
|
|
// - = \\ line 1 letter above
|
|
VK_OEM_MINUS, VK_OEM_EQUAL, VK_OEM_BSLASH,
|
|
// q w e r t y u i o p
|
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P',
|
|
// [ ] line 2 letter above
|
|
VK_OEM_LBRACKET, VK_OEM_RBRACKET,
|
|
// a s d f g h j k l
|
|
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L',
|
|
// ; ' line 3 letter above
|
|
VK_OEM_SEMICLN, VK_OEM_QUOTE,
|
|
// z x c v b n m
|
|
'Z', 'X', 'C', 'V', 'B', 'N', 'M',
|
|
// , . / line 4 letter above
|
|
VK_OEM_COMMA, VK_OEM_PERIOD, VK_OEM_SLASH,
|
|
// <- tab caps enter
|
|
VK_BACK, VK_TAB, VK_CAPITAL, VK_RETURN,
|
|
// shift1 shift2 ctrl1 ctrl2
|
|
VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL,
|
|
// alt1 alt2 esc space special key above
|
|
VK_MENU, VK_MENU, VK_ESCAPE, VK_SPACE
|
|
};
|
|
|
|
|
|
LOGFONT lfSKT1Font;
|
|
|
|
|
|
/**********************************************************************/
|
|
/* GetSKT1TextMetric */
|
|
/**********************************************************************/
|
|
|
|
void GetSKT1TextMetric(
|
|
LPTEXTMETRIC lptm)
|
|
{
|
|
HDC hDC;
|
|
HFONT hOldFont;
|
|
SIZE szDbcs;
|
|
const WCHAR wcDbcs = 0x4e11;
|
|
|
|
hDC = GetDC((HWND)NULL);
|
|
|
|
// get the 9 pixels font
|
|
RtlZeroMemory(&lfSKT1Font, sizeof lfSKT1Font);
|
|
lfSKT1Font.lfHeight = -12;
|
|
lfSKT1Font.lfWeight = FW_NORMAL;
|
|
|
|
lfSKT1Font.lfCharSet = CHINESEBIG5_CHARSET;
|
|
|
|
lfSKT1Font.lfOutPrecision = OUT_TT_ONLY_PRECIS;
|
|
lfSKT1Font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
|
lfSKT1Font.lfQuality = PROOF_QUALITY;
|
|
lfSKT1Font.lfPitchAndFamily = FIXED_PITCH|FF_MODERN;
|
|
|
|
hOldFont = (HFONT)SelectObject(hDC, CreateFontIndirect(&lfSKT1Font));
|
|
|
|
GetTextMetrics(hDC, lptm);
|
|
|
|
/*
|
|
* NT5: Dirty hack for "Lucida Console" which was "font linked" on NT5, and
|
|
* GetTextMetrics API does not return correct text metrics.
|
|
*/
|
|
if (GetTextExtentPoint32(hDC, &wcDbcs, 1, &szDbcs) && lptm->tmMaxCharWidth < szDbcs.cx) {
|
|
TAGMSG2(DBGTAG_IMM, "GetSKT1TextMetric: tmMaxCharWidth(%d) is smaller than real width(%d).",
|
|
lptm->tmMaxCharWidth, szDbcs.cx);
|
|
lptm->tmMaxCharWidth = szDbcs.cx;
|
|
}
|
|
|
|
DeleteObject(SelectObject(hDC, hOldFont));
|
|
|
|
ReleaseDC((HWND)NULL, hDC);
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* InitSKT1ButtonPos */
|
|
/**********************************************************************/
|
|
void InitSKT1ButtonPos(
|
|
LPSKT1CTXT lpSKT1Ctxt)
|
|
{
|
|
TEXTMETRIC tm;
|
|
int nButtonWidthUnit, nButtonHeightUnit;
|
|
int i, nLetterButtonStart, nLetterButtonEnd, xStartPos, yStartPos;
|
|
|
|
GetSKT1TextMetric(&tm);
|
|
|
|
nButtonWidthUnit = tm.tmMaxCharWidth + SKT1_LABEL_BMP_X - SKT1_XOVERLAP;
|
|
|
|
#define INIT_WIDTH(name, width) \
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ ## name ## _TYPE] = (width)
|
|
|
|
INIT_WIDTH(LETTER, nButtonWidthUnit * SKT1_LETTER_WIDTH_TIMES / 2);
|
|
INIT_WIDTH(BACKSPACE, nButtonWidthUnit * SKT1_BACKSPACE_WIDTH_TIMES / 2 + 1);
|
|
INIT_WIDTH(TAB, nButtonWidthUnit * SKT1_TAB_WIDTH_TIMES / 2 + (SKT1_XIN + 1) / 2);
|
|
INIT_WIDTH(CAPS, nButtonWidthUnit * SKT1_CAPS_WIDTH_TIMES / 2 + SKT1_XIN);
|
|
INIT_WIDTH(ENTER, nButtonWidthUnit * SKT1_ENTER_WIDTH_TIMES / 2 + (SKT1_XIN + 1) / 2);
|
|
INIT_WIDTH(SHIFT, nButtonWidthUnit * SKT1_SHIFT_WIDTH_TIMES / 2 + SKT1_XIN + (SKT1_XIN + 1) / 2);
|
|
INIT_WIDTH(CTRL, nButtonWidthUnit * SKT1_CTRL_WIDTH_TIMES / 2 + (SKT1_XIN + 1) / 2);
|
|
INIT_WIDTH(ALT, nButtonWidthUnit * SKT1_ALT_WIDTH_TIMES / 2 + (SKT1_XIN + 1) / 2);
|
|
INIT_WIDTH(ESC, nButtonWidthUnit * SKT1_ESC_WIDTH_TIMES / 2 + SKT1_XIN / 2);
|
|
INIT_WIDTH(SPACE, nButtonWidthUnit * SKT1_SPACE_WIDTH_TIMES / 2 + SKT1_XIN * 5);
|
|
|
|
#undef INIT_WIDTH
|
|
|
|
nButtonHeightUnit = tm.tmHeight + SKT1_LABEL_BMP_Y;
|
|
lpSKT1Ctxt->nButtonHeight[0] = nButtonHeightUnit;
|
|
lpSKT1Ctxt->nButtonHeight[1] = nButtonHeightUnit * 2 + SKT1_YIN; // enter
|
|
|
|
// init first row attribute
|
|
xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2;
|
|
yStartPos = gptRaiseEdge.y + SKT1_YOUT + (SKT1_YIN + 1) / 2;
|
|
|
|
nLetterButtonStart = 0;
|
|
nLetterButtonEnd = nLetterButtonStart + SKT1_ROW1_LETTER_NUM;
|
|
|
|
for (i = nLetterButtonStart; i < nLetterButtonEnd; i++) {
|
|
lpSKT1Ctxt->ptButtonPos[i].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[i].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] + SKT1_XIN);
|
|
}
|
|
// backspace
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].y = yStartPos;
|
|
|
|
// init second row attribute
|
|
xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2;
|
|
yStartPos += (nButtonHeightUnit + SKT1_YIN);
|
|
// tab
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE] + SKT1_XIN);
|
|
// letter
|
|
nLetterButtonStart = nLetterButtonEnd;
|
|
nLetterButtonEnd = nLetterButtonStart + SKT1_ROW2_LETTER_NUM;
|
|
for (i = nLetterButtonStart; i < nLetterButtonEnd; i++) {
|
|
lpSKT1Ctxt->ptButtonPos[i].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[i].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] + SKT1_XIN);
|
|
}
|
|
// enter
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].y = yStartPos;
|
|
|
|
// init third row
|
|
xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2;
|
|
yStartPos += (nButtonHeightUnit + SKT1_YIN);
|
|
// caps
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_CAPS_TYPE] + SKT1_XIN);
|
|
// letter
|
|
nLetterButtonStart = nLetterButtonEnd;
|
|
nLetterButtonEnd = nLetterButtonStart + SKT1_ROW3_LETTER_NUM;
|
|
for (i = nLetterButtonStart; i < nLetterButtonEnd; i++) {
|
|
lpSKT1Ctxt->ptButtonPos[i].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[i].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] + SKT1_XIN);
|
|
}
|
|
|
|
// init fourth row
|
|
xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2;
|
|
yStartPos += (nButtonHeightUnit + SKT1_YIN);
|
|
// shift 1
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE] + SKT1_XIN);
|
|
// letter
|
|
nLetterButtonStart = nLetterButtonEnd;
|
|
nLetterButtonEnd = nLetterButtonStart + SKT1_ROW4_LETTER_NUM;
|
|
for (i = nLetterButtonStart; i < nLetterButtonEnd; i++) {
|
|
lpSKT1Ctxt->ptButtonPos[i].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[i].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] + SKT1_XIN);
|
|
}
|
|
// shift 2
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].y = yStartPos;
|
|
|
|
// init fifth row
|
|
xStartPos = gptRaiseEdge.x + SKT1_XOUT + (SKT1_XIN + 1) / 2;
|
|
yStartPos += (nButtonHeightUnit + SKT1_YIN);
|
|
// ctrl 1
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE] + SKT1_XIN);
|
|
// esc
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE] + SKT1_XIN);
|
|
// alt 1
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE] + SKT1_XIN);
|
|
// space
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_SPACE_TYPE] + SKT1_XIN);
|
|
// alt 2 .. skip blank
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].y = yStartPos;
|
|
xStartPos += (lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE] + SKT1_XIN) +
|
|
(lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE] + SKT1_XIN);
|
|
// ctrl 2
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].x = xStartPos;
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].y = yStartPos;
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1DrawConvexRect */
|
|
/* draw a convex rectangle */
|
|
/* (x,y) x+nWidth+1 */
|
|
/* +-----1------+ */
|
|
/* |+----2-----|| */
|
|
/* || || */
|
|
/* || 3| */
|
|
/* || || */
|
|
/* |V || <---- Rectangle */
|
|
/* |<----------+| */
|
|
/* y+nHeight+1 +------------+ */
|
|
/* 1 - black */
|
|
/* 2 - while */
|
|
/* 3 - dark gray */
|
|
/**********************************************************************/
|
|
void SKT1DrawConvexRect(
|
|
HDC hDC,
|
|
int x,
|
|
int y,
|
|
int nWidth,
|
|
int nHeight)
|
|
{
|
|
// extend the context rect size
|
|
x -= (SKT1_XIN + 1) / 2;
|
|
y -= (SKT1_YIN + 1) / 2;
|
|
nWidth += (SKT1_XIN + 1);
|
|
nHeight += (SKT1_XIN + 1);
|
|
|
|
// 1
|
|
SelectObject(hDC, GetStockObject(BLACK_PEN));
|
|
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
|
|
Rectangle(hDC, x, y, x + nWidth, y + nHeight);
|
|
PatBlt(hDC, x, y, 1, 1, PATCOPY);
|
|
PatBlt(hDC, x + nWidth, y, -1, 1, PATCOPY);
|
|
PatBlt(hDC, x, y + nHeight, 1, -1, PATCOPY);
|
|
PatBlt(hDC, x + nWidth, y + nHeight, -1, -1, PATCOPY);
|
|
|
|
x++;
|
|
y++;
|
|
nWidth -= 2;
|
|
nHeight -= 2;
|
|
|
|
// 2
|
|
PatBlt(hDC, x, y + nHeight, 1, -nHeight, WHITENESS);
|
|
PatBlt(hDC, x, y, nWidth , 1, WHITENESS);
|
|
// 3
|
|
SelectObject(hDC, GetStockObject(GRAY_BRUSH));
|
|
PatBlt(hDC, x, y + nHeight, nWidth, -1, PATCOPY);
|
|
PatBlt(hDC, x + nWidth, y + nHeight, -1, -nHeight, PATCOPY);
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1DrawBitmap */
|
|
/**********************************************************************/
|
|
void SKT1DrawBitmap(
|
|
HDC hDC,
|
|
int x,
|
|
int y,
|
|
int nWidth,
|
|
int nHeight,
|
|
LPCWSTR lpszBitmap)
|
|
{
|
|
HDC hMemDC;
|
|
HBITMAP hBitmap, hOldBmp;
|
|
|
|
hBitmap = (HBITMAP)LoadBitmap(ghInst, lpszBitmap);
|
|
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
|
|
hOldBmp = (HBITMAP)SelectObject(hMemDC, hBitmap);
|
|
|
|
BitBlt(hDC, x, y, nWidth, nHeight, hMemDC, 0 , 0, SRCCOPY);
|
|
|
|
SelectObject(hMemDC, hOldBmp);
|
|
|
|
DeleteObject(hBitmap);
|
|
|
|
DeleteDC(hMemDC);
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1DrawLabel */
|
|
/**********************************************************************/
|
|
void SKT1DrawLabel(
|
|
HDC hDC,
|
|
LPSKT1CTXT lpSKT1Ctxt,
|
|
LPCWSTR lpszLabel)
|
|
{
|
|
HDC hMemDC;
|
|
HBITMAP hBitmap, hOldBmp;
|
|
int i;
|
|
|
|
hBitmap = LoadBitmap(ghInst, lpszLabel);
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
hOldBmp = (HBITMAP)SelectObject(hMemDC, hBitmap);
|
|
|
|
for (i = 0; i < SKT1_LETTER_KEY_NUM; i++) {
|
|
BitBlt(hDC,
|
|
lpSKT1Ctxt->ptButtonPos[i].x, lpSKT1Ctxt->ptButtonPos[i].y,
|
|
SKT1_LABEL_BMP_X, SKT1_LABEL_BMP_Y,
|
|
hMemDC, i * SKT1_LABEL_BMP_X, 0, SRCCOPY);
|
|
}
|
|
|
|
SelectObject(hMemDC, hOldBmp);
|
|
DeleteDC(hMemDC);
|
|
DeleteObject(hBitmap);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/**********************************************************************/
|
|
/* InitSKT1Bitmap */
|
|
/**********************************************************************/
|
|
void InitSKT1Bitmap(
|
|
HWND hSKWnd,
|
|
LPSKT1CTXT lpSKT1Ctxt)
|
|
{
|
|
HDC hDC, hMemDC;
|
|
RECT rcClient;
|
|
int i;
|
|
|
|
hDC = GetDC(hSKWnd);
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
GetClientRect(hSKWnd, &rcClient);
|
|
lpSKT1Ctxt->hSKBitmap = CreateCompatibleBitmap(hDC,
|
|
rcClient.right - rcClient.left,
|
|
rcClient.bottom - rcClient.top);
|
|
ReleaseDC(hSKWnd, hDC);
|
|
SelectObject(hMemDC, lpSKT1Ctxt->hSKBitmap);
|
|
|
|
// draw SK rectangle
|
|
SelectObject(hMemDC, GetStockObject(NULL_PEN));
|
|
SelectObject(hMemDC, GetStockObject(LTGRAY_BRUSH));
|
|
Rectangle(hMemDC, rcClient.left, rcClient.top,
|
|
rcClient.right + 1, rcClient.bottom + 1);
|
|
|
|
DrawEdge(hMemDC, &rcClient, BDR_RAISED, BF_RECT);
|
|
|
|
// draw the button from the last line
|
|
// ctrl 1 -> line 5 special key
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE] / 2 - SKT1_CTRL_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_CTRL_BMP_Y / 2,
|
|
SKT1_CTRL_BMP_X,
|
|
SKT1_CTRL_BMP_Y,
|
|
MAKEINTRESOURCEW(CTRL_T1));
|
|
|
|
// ctrl 2
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE] / 2 - SKT1_CTRL_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_CTRL_BMP_Y / 2,
|
|
SKT1_CTRL_BMP_X, SKT1_CTRL_BMP_Y,
|
|
MAKEINTRESOURCEW(CTRL_T1));
|
|
|
|
// esc
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE] / 2 - SKT1_ESC_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_ESC_BMP_Y / 2,
|
|
SKT1_ESC_BMP_X, SKT1_ESC_BMP_Y,
|
|
MAKEINTRESOURCEW(ESC_T1));
|
|
|
|
// alt 1
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE] / 2 - SKT1_ALT_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_ALT_BMP_Y / 2,
|
|
SKT1_ALT_BMP_X, SKT1_ALT_BMP_Y,
|
|
MAKEINTRESOURCEW(ALT_T1));
|
|
|
|
// alt 2
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE] / 2 - SKT1_ALT_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_ALT_BMP_Y / 2,
|
|
SKT1_ALT_BMP_X, SKT1_ALT_BMP_Y,
|
|
MAKEINTRESOURCEW(ALT_T1));
|
|
|
|
// space
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_SPACE_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
|
|
// line 4
|
|
// shift 1
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE] / 2 - SKT1_SHIFT_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_SHIFT_BMP_Y / 2,
|
|
SKT1_SHIFT_BMP_X, SKT1_SHIFT_BMP_Y,
|
|
MAKEINTRESOURCEW(SHIFT_T1));
|
|
|
|
// shift 2
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE] / 2 - SKT1_SHIFT_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_SHIFT_BMP_Y / 2,
|
|
SKT1_SHIFT_BMP_X, SKT1_SHIFT_BMP_Y,
|
|
MAKEINTRESOURCEW(SHIFT_T1));
|
|
|
|
// line 3
|
|
// caps
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CAPS_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CAPS_TYPE] / 2 - SKT1_CAPS_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_CAPS_BMP_Y / 2,
|
|
SKT1_CAPS_BMP_X, SKT1_CAPS_BMP_Y,
|
|
MAKEINTRESOURCEW(CAPS_T1));
|
|
|
|
// line 2
|
|
// tab
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE] / 2 - SKT1_TAB_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_TAB_BMP_Y / 2,
|
|
SKT1_TAB_BMP_X, SKT1_TAB_BMP_Y,
|
|
MAKEINTRESOURCEW(TAB_T1));
|
|
|
|
// enter
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ENTER_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[1]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ENTER_TYPE] / 2 - SKT1_ENTER_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].y +
|
|
lpSKT1Ctxt->nButtonHeight[1] / 2 - SKT1_ENTER_BMP_Y / 2,
|
|
SKT1_ENTER_BMP_X, SKT1_ENTER_BMP_Y,
|
|
MAKEINTRESOURCEW(ENTER_T1));
|
|
|
|
// line 1
|
|
// backspace
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_BACKSPACE_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
SKT1DrawBitmap(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].x +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_BACKSPACE_TYPE] / 2 - SKT1_BACKSPACE_BMP_X / 2,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].y +
|
|
lpSKT1Ctxt->nButtonHeight[0] / 2 - SKT1_BACKSPACE_BMP_Y / 2,
|
|
SKT1_BACKSPACE_BMP_X, SKT1_BACKSPACE_BMP_Y,
|
|
MAKEINTRESOURCEW(BACK_T1));
|
|
|
|
// draw letter buttons
|
|
for (i = SKT1_LETTER_KEY_NUM - 1; i >= 0 ; i--) {
|
|
SKT1DrawConvexRect(hMemDC,
|
|
lpSKT1Ctxt->ptButtonPos[i].x,
|
|
lpSKT1Ctxt->ptButtonPos[i].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0]);
|
|
}
|
|
|
|
// draw latter label
|
|
SKT1DrawLabel(hMemDC, lpSKT1Ctxt, MAKEINTRESOURCEW(LABEL_T1));
|
|
|
|
DeleteDC(hMemDC);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/**********************************************************************/
|
|
/* CreateT1Window */
|
|
/**********************************************************************/
|
|
LRESULT CreateT1Window(
|
|
HWND hSKWnd)
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
|
|
hSKT1Ctxt = GlobalAlloc(GHND, sizeof(SKT1CTXT));
|
|
if (!hSKT1Ctxt) {
|
|
return (-1);
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
GlobalFree(hSKT1Ctxt);
|
|
return (-1);
|
|
}
|
|
|
|
SetWindowLongPtr(hSKWnd, SKT1_CONTEXT, (LONG_PTR)hSKT1Ctxt);
|
|
|
|
lpSKT1Ctxt->uKeyIndex = SKT1_TOTAL_INDEX;
|
|
lpSKT1Ctxt->ptSkOffset.x = SKT1_NOT_DRAG;
|
|
lpSKT1Ctxt->ptSkOffset.y = SKT1_NOT_DRAG;
|
|
lpSKT1Ctxt->lfCharSet = CHINESEBIG5_CHARSET;
|
|
|
|
InitSKT1ButtonPos(lpSKT1Ctxt);
|
|
|
|
InitSKT1Bitmap(hSKWnd, lpSKT1Ctxt);
|
|
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
|
|
return (0L);
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1DrawDragBorder() */
|
|
/**********************************************************************/
|
|
void SKT1DrawDragBorder(
|
|
HWND hWnd, // window of IME is dragged
|
|
LPPOINT lpptCursor, // the cursor position
|
|
LPPOINT lpptOffset) // the offset form cursor to window org
|
|
{
|
|
HDC hDC;
|
|
int cxBorder, cyBorder;
|
|
int x, y;
|
|
RECT rcWnd;
|
|
|
|
cxBorder = GetSystemMetrics(SM_CXBORDER); // width of border
|
|
cyBorder = GetSystemMetrics(SM_CYBORDER); // height of border
|
|
|
|
x = lpptCursor->x - lpptOffset->x;
|
|
y = lpptCursor->y - lpptOffset->y;
|
|
|
|
// check for the max boundary of the display
|
|
GetWindowRect(hWnd, &rcWnd);
|
|
|
|
// draw the moving track
|
|
hDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
|
|
SelectObject(hDC, GetStockObject(GRAY_BRUSH));
|
|
|
|
// ->
|
|
PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder,
|
|
PATINVERT);
|
|
// v
|
|
PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top -
|
|
cyBorder, PATINVERT);
|
|
// _>
|
|
PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top,
|
|
rcWnd.right - rcWnd.left - cxBorder, -cyBorder, PATINVERT);
|
|
// v
|
|
PatBlt(hDC, x + rcWnd.right - rcWnd.left, y,
|
|
- cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT);
|
|
|
|
DeleteDC(hDC);
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* DestroyT1Window */
|
|
/**********************************************************************/
|
|
void DestroyT1Window(
|
|
HWND hSKWnd)
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
HWND hUIWnd;
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return;
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return;
|
|
}
|
|
|
|
if (lpSKT1Ctxt->ptSkOffset.x != SKT1_NOT_DRAG &&
|
|
lpSKT1Ctxt->ptSkOffset.y != SKT1_NOT_DRAG) {
|
|
SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor,
|
|
&lpSKT1Ctxt->ptSkOffset);
|
|
}
|
|
|
|
DeleteObject(lpSKT1Ctxt->hSKBitmap);
|
|
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
GlobalFree(hSKT1Ctxt);
|
|
|
|
hUIWnd = GetWindow(hSKWnd, GW_OWNER);
|
|
if (!hUIWnd) {
|
|
return;
|
|
}
|
|
|
|
SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_SOFTKBDDESTROYED, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1InvertButton */
|
|
/**********************************************************************/
|
|
void SKT1InvertButton(
|
|
HWND hSKWnd,
|
|
HDC hPaintDC,
|
|
LPSKT1CTXT lpSKT1Ctxt,
|
|
UINT uKeyIndex)
|
|
{
|
|
HDC hDC;
|
|
int nWidth, nHeight;
|
|
|
|
if (uKeyIndex >= SKT1_TOTAL_INDEX) {
|
|
return;
|
|
}
|
|
|
|
nWidth = 0;
|
|
if (hPaintDC) {
|
|
hDC = hPaintDC;
|
|
} else {
|
|
hDC = GetDC(hSKWnd);
|
|
}
|
|
|
|
if (uKeyIndex < SKT1_LETTER_KEY_NUM) {
|
|
nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE];
|
|
} else {
|
|
switch (uKeyIndex) {
|
|
case SKT1_BACKSPACE_INDEX:
|
|
nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_BACKSPACE_TYPE];
|
|
break;
|
|
case SKT1_TAB_INDEX:
|
|
nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE];
|
|
break;
|
|
case SKT1_CAPS_INDEX:
|
|
nWidth = 0;
|
|
MessageBeep((UINT) -1);
|
|
break;
|
|
case SKT1_ENTER_INDEX:
|
|
nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_ENTER_TYPE];
|
|
break;
|
|
case SKT1_SHIFT_INDEX:
|
|
case SKT1_SHIFT_INDEX + 1:
|
|
case SKT1_CTRL_INDEX:
|
|
case SKT1_CTRL_INDEX + 1:
|
|
case SKT1_ALT_INDEX:
|
|
case SKT1_ALT_INDEX + 1:
|
|
nWidth = 0;
|
|
MessageBeep((UINT) -1);
|
|
break;
|
|
case SKT1_ESC_INDEX:
|
|
nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE];
|
|
break;
|
|
case SKT1_SPACE_INDEX:
|
|
nWidth = lpSKT1Ctxt->nButtonWidth[SKT1_SPACE_TYPE];
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (uKeyIndex == SKT1_ENTER_INDEX) {
|
|
nHeight = lpSKT1Ctxt->nButtonHeight[1];
|
|
} else {
|
|
nHeight = lpSKT1Ctxt->nButtonHeight[0];
|
|
}
|
|
|
|
if (nWidth) {
|
|
// do not reverse border
|
|
PatBlt(hDC, lpSKT1Ctxt->ptButtonPos[uKeyIndex].x - 1,
|
|
lpSKT1Ctxt->ptButtonPos[uKeyIndex].y - 1,
|
|
nWidth + 2, nHeight + 2, DSTINVERT);
|
|
}
|
|
|
|
if (!hPaintDC) {
|
|
ReleaseDC(hSKWnd, hDC);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* UpdateSKT1Window */
|
|
/**********************************************************************/
|
|
void UpdateSKT1Window(
|
|
HDC hDC,
|
|
HWND hSKWnd)
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
HDC hMemDC;
|
|
RECT rcClient;
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return;
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return;
|
|
}
|
|
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
|
|
SelectObject(hMemDC, lpSKT1Ctxt->hSKBitmap);
|
|
|
|
GetClientRect(hSKWnd, &rcClient);
|
|
|
|
BitBlt(hDC, 0, 0, rcClient.right - rcClient.left,
|
|
rcClient.bottom - rcClient.top,
|
|
hMemDC, 0, 0, SRCCOPY);
|
|
|
|
DeleteDC(hMemDC);
|
|
|
|
if (lpSKT1Ctxt->uKeyIndex < SKT1_TOTAL_INDEX) {
|
|
SKT1InvertButton(hSKWnd, hDC, lpSKT1Ctxt, lpSKT1Ctxt->uKeyIndex);
|
|
}
|
|
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1MousePosition() */
|
|
/**********************************************************************/
|
|
UINT SKT1MousePosition(
|
|
LPSKT1CTXT lpSKT1Ctxt,
|
|
LPPOINT lpptCursor)
|
|
{
|
|
int i;
|
|
|
|
// check letter button
|
|
for (i = 0; i < SKT1_LETTER_KEY_NUM; i++) {
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[i].x,
|
|
lpSKT1Ctxt->ptButtonPos[i].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
// backSapce
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_BACKSPACE_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_BACKSPACE_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_BACKSPACE_INDEX;
|
|
}
|
|
|
|
// tab
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_TAB_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_TAB_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_TAB_INDEX;
|
|
}
|
|
|
|
// caps
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CAPS_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CAPS_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_CAPS_INDEX;
|
|
}
|
|
|
|
// enter
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ENTER_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ENTER_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[1],
|
|
lpptCursor)) {
|
|
return SKT1_ENTER_INDEX;
|
|
}
|
|
|
|
// shift 1
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_SHIFT_INDEX;
|
|
}
|
|
|
|
// shift 2
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SHIFT_INDEX + 1].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_SHIFT_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_SHIFT_INDEX;
|
|
}
|
|
|
|
// ctrl 1
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_CTRL_INDEX;
|
|
}
|
|
|
|
// ctrl 2
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_CTRL_INDEX + 1].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_CTRL_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_CTRL_INDEX;
|
|
}
|
|
|
|
// alt 1
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_ALT_INDEX;
|
|
}
|
|
|
|
// alt 2
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ALT_INDEX + 1].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ALT_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_ALT_INDEX;
|
|
}
|
|
|
|
// esc
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_ESC_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_ESC_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_ESC_INDEX;
|
|
}
|
|
|
|
// space
|
|
if (ImmPtInRect(lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].x,
|
|
lpSKT1Ctxt->ptButtonPos[SKT1_SPACE_INDEX].y,
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_SPACE_TYPE],
|
|
lpSKT1Ctxt->nButtonHeight[0],
|
|
lpptCursor)) {
|
|
return SKT1_SPACE_INDEX;
|
|
}
|
|
|
|
return SKT1_TOTAL_INDEX; // This means out of range
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1IsValidButton */
|
|
/**********************************************************************/
|
|
BOOL SKT1IsValidButton(
|
|
UINT uKeyIndex,
|
|
LPSKT1CTXT lpSKT1Ctxt)
|
|
{
|
|
BOOL fRet;
|
|
|
|
if (uKeyIndex < SKT1_LETTER_KEY_NUM) {
|
|
if (lpSKT1Ctxt->wCodeTable[uKeyIndex]) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// special key
|
|
switch (uKeyIndex) {
|
|
case SKT1_BACKSPACE_INDEX:
|
|
case SKT1_TAB_INDEX:
|
|
case SKT1_ENTER_INDEX:
|
|
case SKT1_ESC_INDEX:
|
|
case SKT1_SPACE_INDEX:
|
|
fRet = TRUE;
|
|
break;
|
|
default:
|
|
fRet = FALSE;
|
|
break;
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1SetCursor */
|
|
/**********************************************************************/
|
|
BOOL SKT1SetCursor(
|
|
HWND hSKWnd,
|
|
LPARAM lParam)
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
UINT uKeyIndex;
|
|
RECT rcWnd;
|
|
RECT rcWork;
|
|
SIZE szWork;
|
|
extern void GetAllMonitorSize(LPRECT lprc);
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return (FALSE);
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return (FALSE);
|
|
}
|
|
|
|
if (lpSKT1Ctxt->ptSkOffset.x != SKT1_NOT_DRAG &&
|
|
lpSKT1Ctxt->ptSkOffset.y != SKT1_NOT_DRAG) {
|
|
// in drag operation
|
|
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
|
|
goto UnlockSKT1Ctxt;
|
|
}
|
|
|
|
GetCursorPos(&lpSKT1Ctxt->ptSkCursor);
|
|
ScreenToClient(hSKWnd, &lpSKT1Ctxt->ptSkCursor);
|
|
|
|
uKeyIndex = SKT1MousePosition(lpSKT1Ctxt, &lpSKT1Ctxt->ptSkCursor);
|
|
|
|
if (uKeyIndex < SKT1_TOTAL_INDEX) {
|
|
SetCursor(LoadCursor(NULL, IDC_HAND));
|
|
} else {
|
|
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
|
|
}
|
|
|
|
|
|
if (HIWORD(lParam) != WM_LBUTTONDOWN) {
|
|
goto UnlockSKT1Ctxt;
|
|
}
|
|
|
|
SetCapture(hSKWnd);
|
|
|
|
if (lpSKT1Ctxt->uKeyIndex < SKT1_TOTAL_INDEX) {
|
|
UINT uVirtKey;
|
|
|
|
uVirtKey = bSKT1VirtKey[lpSKT1Ctxt->uKeyIndex];
|
|
keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey],
|
|
(DWORD)KEYEVENTF_KEYUP, 0);
|
|
SKT1InvertButton(hSKWnd, NULL, lpSKT1Ctxt, lpSKT1Ctxt->uKeyIndex);
|
|
lpSKT1Ctxt->uKeyIndex = SKT1_TOTAL_INDEX;
|
|
}
|
|
|
|
if (uKeyIndex < SKT1_TOTAL_INDEX) {
|
|
UINT uVirtKey;
|
|
|
|
if (SKT1IsValidButton(uKeyIndex, lpSKT1Ctxt)) {
|
|
uVirtKey = bSKT1VirtKey[uKeyIndex];
|
|
keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey],
|
|
0, 0);
|
|
lpSKT1Ctxt->uKeyIndex = uKeyIndex;
|
|
SKT1InvertButton(hSKWnd, NULL, lpSKT1Ctxt, lpSKT1Ctxt->uKeyIndex);
|
|
} else {
|
|
MessageBeep((UINT)-1);
|
|
}
|
|
goto UnlockSKT1Ctxt;
|
|
}
|
|
|
|
GetAllMonitorSize(&rcWork);
|
|
szWork.cx = rcWork.right - rcWork.left;
|
|
szWork.cy = rcWork.bottom - rcWork.top;
|
|
|
|
GetCursorPos(&lpSKT1Ctxt->ptSkCursor);
|
|
GetWindowRect(hSKWnd, &rcWnd);
|
|
lpSKT1Ctxt->ptSkOffset.x = lpSKT1Ctxt->ptSkCursor.x - rcWnd.left;
|
|
lpSKT1Ctxt->ptSkOffset.y = lpSKT1Ctxt->ptSkCursor.y - rcWnd.top;
|
|
|
|
SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor,
|
|
&lpSKT1Ctxt->ptSkOffset);
|
|
|
|
UnlockSKT1Ctxt:
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1MouseMove */
|
|
/**********************************************************************/
|
|
BOOL SKT1MouseMove(
|
|
HWND hSKWnd)
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return FALSE;
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (lpSKT1Ctxt->ptSkOffset.x == SKT1_NOT_DRAG ||
|
|
lpSKT1Ctxt->ptSkOffset.y == SKT1_NOT_DRAG) {
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
return FALSE;
|
|
}
|
|
|
|
SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor,
|
|
&lpSKT1Ctxt->ptSkOffset);
|
|
|
|
GetCursorPos(&lpSKT1Ctxt->ptSkCursor);
|
|
|
|
SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor,
|
|
&lpSKT1Ctxt->ptSkOffset);
|
|
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKT1ButtonUp */
|
|
/**********************************************************************/
|
|
BOOL SKT1ButtonUp(
|
|
HWND hSKWnd)
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
BOOL fRet;
|
|
POINT pt;
|
|
HWND hUIWnd;
|
|
HIMC hIMC;
|
|
LPINPUTCONTEXT lpIMC;
|
|
|
|
fRet = FALSE;
|
|
|
|
if (IsWndEqual(GetCapture(), hSKWnd)) {
|
|
ReleaseCapture();
|
|
}
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return (fRet);
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return (fRet);
|
|
}
|
|
|
|
if (lpSKT1Ctxt->uKeyIndex < SKT1_TOTAL_INDEX) {
|
|
UINT uVirtKey;
|
|
|
|
uVirtKey = bSKT1VirtKey[lpSKT1Ctxt->uKeyIndex];
|
|
keybd_event((BYTE)uVirtKey, (BYTE)guScanCode[uVirtKey],
|
|
(DWORD)KEYEVENTF_KEYUP, 0);
|
|
SKT1InvertButton(hSKWnd, NULL, lpSKT1Ctxt, lpSKT1Ctxt->uKeyIndex);
|
|
lpSKT1Ctxt->uKeyIndex = SKT1_TOTAL_INDEX;
|
|
fRet = TRUE;
|
|
goto UnlockSKT1Context;
|
|
}
|
|
|
|
if (lpSKT1Ctxt->ptSkOffset.x == SKT1_NOT_DRAG ||
|
|
lpSKT1Ctxt->ptSkOffset.y == SKT1_NOT_DRAG) {
|
|
goto UnlockSKT1Context;
|
|
}
|
|
|
|
SKT1DrawDragBorder(hSKWnd, &lpSKT1Ctxt->ptSkCursor,
|
|
&lpSKT1Ctxt->ptSkOffset);
|
|
|
|
pt.x = lpSKT1Ctxt->ptSkCursor.x - lpSKT1Ctxt->ptSkOffset.x,
|
|
pt.y = lpSKT1Ctxt->ptSkCursor.y - lpSKT1Ctxt->ptSkOffset.y,
|
|
|
|
SetWindowPos(hSKWnd, (HWND)NULL, pt.x, pt.y,
|
|
0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
|
|
|
|
lpSKT1Ctxt->ptSkOffset.x = SKT1_NOT_DRAG;
|
|
lpSKT1Ctxt->ptSkOffset.y = SKT1_NOT_DRAG;
|
|
|
|
lpSKT1Ctxt->uKeyIndex = SKT1_TOTAL_INDEX;
|
|
|
|
fRet = TRUE;
|
|
|
|
hUIWnd = GetWindow(hSKWnd, GW_OWNER);
|
|
|
|
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
|
|
if (!hIMC) {
|
|
goto UnlockSKT1Context;
|
|
}
|
|
|
|
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
|
|
if (!lpIMC) {
|
|
goto UnlockSKT1Context;
|
|
}
|
|
|
|
lpIMC->ptSoftKbdPos.x = pt.x;
|
|
lpIMC->ptSoftKbdPos.y = pt.y;
|
|
lpIMC->fdwInit |= INIT_SOFTKBDPOS;
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
UnlockSKT1Context:
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
|
|
return (fRet);
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SetSKT1Data */
|
|
/**********************************************************************/
|
|
LRESULT SetSKT1Data(
|
|
HWND hSKWnd,
|
|
LPSOFTKBDDATA lpSoftKbdData)
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
HDC hDC, hMemDC;
|
|
HGDIOBJ hOldFont;
|
|
int i;
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return (1);
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return (1);
|
|
}
|
|
|
|
hDC = GetDC(hSKWnd);
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
ReleaseDC(hSKWnd, hDC);
|
|
SelectObject(hMemDC, lpSKT1Ctxt->hSKBitmap);
|
|
|
|
SetBkColor(hMemDC, RGB(0xC0, 0xC0, 0xC0));
|
|
|
|
if (lpSKT1Ctxt->lfCharSet != DEFAULT_CHARSET) {
|
|
LOGFONT lfFont;
|
|
CopyMemory(&lfFont, &lfSKT1Font, sizeof (LOGFONT));
|
|
lfFont.lfCharSet = (BYTE)lpSKT1Ctxt->lfCharSet;
|
|
hOldFont = (HFONT)SelectObject(hMemDC, CreateFontIndirect(&lfFont));
|
|
}
|
|
else {
|
|
hOldFont = (HFONT)SelectObject(hMemDC, CreateFontIndirect(&lfSKT1Font));
|
|
}
|
|
|
|
for (i = 0; i < SKT1_LETTER_KEY_NUM; i++) {
|
|
int cbCount;
|
|
RECT rcOpaque;
|
|
|
|
lpSKT1Ctxt->wCodeTable[i] = lpSoftKbdData->wCode[0][bSKT1VirtKey[i]];
|
|
|
|
cbCount = (lpSKT1Ctxt->wCodeTable[i] == 0) ? 0 : 1;
|
|
|
|
rcOpaque.left = lpSKT1Ctxt->ptButtonPos[i].x + SKT1_LABEL_BMP_X -
|
|
SKT1_XOVERLAP;
|
|
rcOpaque.top = lpSKT1Ctxt->ptButtonPos[i].y + SKT1_LABEL_BMP_Y;
|
|
|
|
rcOpaque.right = rcOpaque.left +
|
|
lpSKT1Ctxt->nButtonWidth[SKT1_LETTER_TYPE] - SKT1_LABEL_BMP_X +
|
|
SKT1_XOVERLAP;
|
|
rcOpaque.bottom = rcOpaque.top + lpSKT1Ctxt->nButtonHeight[0] -
|
|
SKT1_LABEL_BMP_Y;
|
|
|
|
ExtTextOut(hMemDC, rcOpaque.left, rcOpaque.top,
|
|
ETO_OPAQUE, &rcOpaque,
|
|
(LPWSTR)&lpSKT1Ctxt->wCodeTable[i], cbCount, NULL);
|
|
}
|
|
|
|
DeleteObject(SelectObject(hMemDC, hOldFont));
|
|
|
|
DeleteDC(hMemDC);
|
|
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
|
|
return (0);
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SKWndProcT1 */
|
|
/**********************************************************************/
|
|
LRESULT CALLBACK SKWndProcT1(
|
|
HWND hSKWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
switch (uMsg) {
|
|
case WM_CREATE:
|
|
return CreateT1Window(hSKWnd);
|
|
case WM_DESTROY:
|
|
DestroyT1Window(hSKWnd);
|
|
break;
|
|
case WM_PAINT:
|
|
{
|
|
HDC hDC;
|
|
PAINTSTRUCT ps;
|
|
|
|
hDC = BeginPaint(hSKWnd, &ps);
|
|
UpdateSKT1Window(hDC, hSKWnd);
|
|
EndPaint(hSKWnd, &ps);
|
|
}
|
|
break;
|
|
case WM_SETCURSOR:
|
|
if (!SKT1SetCursor(hSKWnd, lParam)) {
|
|
return DefWindowProc(hSKWnd, uMsg, wParam, lParam);
|
|
}
|
|
break;
|
|
case WM_MOUSEMOVE:
|
|
if (!SKT1MouseMove(hSKWnd)) {
|
|
return DefWindowProc(hSKWnd, uMsg, wParam, lParam);
|
|
}
|
|
break;
|
|
case WM_LBUTTONUP:
|
|
if (!SKT1ButtonUp(hSKWnd)) {
|
|
return DefWindowProc(hSKWnd, uMsg, wParam, lParam);
|
|
}
|
|
break;
|
|
case WM_MOUSEACTIVATE:
|
|
return (MA_NOACTIVATE);
|
|
case WM_SHOWWINDOW:
|
|
if (lParam != 0) {
|
|
} else if ((BOOL)wParam == TRUE) {
|
|
} else {
|
|
// we want to hide the soft keyboard on mouse button down
|
|
SKT1ButtonUp(hSKWnd);
|
|
}
|
|
|
|
return DefWindowProc(hSKWnd, uMsg, wParam, lParam);
|
|
|
|
case WM_IME_CONTROL:
|
|
switch (wParam) {
|
|
case IMC_GETSOFTKBDFONT:
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
BYTE lfCharSet;
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return (1);
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return (1);
|
|
}
|
|
|
|
lfCharSet = (BYTE)lpSKT1Ctxt->lfCharSet;
|
|
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
|
|
*(LPLOGFONT)lParam = lfSKT1Font;
|
|
|
|
if (lfCharSet != DEFAULT_CHARSET) {
|
|
((LPLOGFONT)lParam)->lfCharSet = lfCharSet;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
break;
|
|
case IMC_SETSOFTKBDFONT:
|
|
{
|
|
// in differet version of Windows
|
|
if (lfSKT1Font.lfCharSet != ((LPLOGFONT)lParam)->lfCharSet) {
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd,
|
|
SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return 1;
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return 1;
|
|
}
|
|
|
|
lpSKT1Ctxt->lfCharSet = ((LPLOGFONT)lParam)->lfCharSet;
|
|
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
}
|
|
}
|
|
break;
|
|
case IMC_GETSOFTKBDPOS:
|
|
{
|
|
RECT rcWnd;
|
|
|
|
GetWindowRect(hSKWnd, &rcWnd);
|
|
|
|
return MAKELRESULT(rcWnd.left, rcWnd.top);
|
|
}
|
|
break;
|
|
case IMC_SETSOFTKBDPOS:
|
|
{
|
|
POINT ptSoftKbdPos;
|
|
HWND hUIWnd;
|
|
HIMC hIMC;
|
|
LPINPUTCONTEXT lpIMC;
|
|
|
|
ptSoftKbdPos.x = ((LPPOINTS)lParam)->x;
|
|
ptSoftKbdPos.y = ((LPPOINTS)lParam)->y;
|
|
|
|
SetWindowPos(hSKWnd, NULL,
|
|
ptSoftKbdPos.x, ptSoftKbdPos.y,
|
|
0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
|
|
|
|
// Here we want to get - the owner or parent window
|
|
hUIWnd = GetParent(hSKWnd);
|
|
|
|
if (!hUIWnd) {
|
|
return (1);
|
|
}
|
|
|
|
hIMC = (HIMC) GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
|
|
|
|
if (!hIMC) {
|
|
return (1);
|
|
}
|
|
|
|
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
|
|
|
|
if (!lpIMC) {
|
|
return (1);
|
|
}
|
|
|
|
lpIMC->ptSoftKbdPos = ptSoftKbdPos;
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return (0);
|
|
}
|
|
break;
|
|
case IMC_SETSOFTKBDDATA:
|
|
{
|
|
LRESULT lRet;
|
|
|
|
lRet = SetSKT1Data(hSKWnd, (LPSOFTKBDDATA)lParam);
|
|
if (!lRet) {
|
|
InvalidateRect(hSKWnd, NULL, FALSE);
|
|
PostMessage(hSKWnd, WM_PAINT, 0, 0);
|
|
}
|
|
return (lRet);
|
|
}
|
|
break;
|
|
case IMC_GETSOFTKBDSUBTYPE:
|
|
case IMC_SETSOFTKBDSUBTYPE:
|
|
{
|
|
HGLOBAL hSKT1Ctxt;
|
|
LPSKT1CTXT lpSKT1Ctxt;
|
|
LRESULT lRet;
|
|
|
|
lRet = -1;
|
|
|
|
hSKT1Ctxt = (HGLOBAL)GetWindowLongPtr(hSKWnd, SKT1_CONTEXT);
|
|
if (!hSKT1Ctxt) {
|
|
return (lRet);
|
|
}
|
|
|
|
lpSKT1Ctxt = (LPSKT1CTXT)GlobalLock(hSKT1Ctxt);
|
|
if (!lpSKT1Ctxt) {
|
|
return (lRet);
|
|
}
|
|
|
|
if (wParam == IMC_GETSOFTKBDSUBTYPE) {
|
|
lRet = lpSKT1Ctxt->uSubType;
|
|
} else if (wParam == IMC_SETSOFTKBDSUBTYPE) {
|
|
lRet = lpSKT1Ctxt->uSubType;
|
|
lpSKT1Ctxt->uSubType = (UINT)lParam;
|
|
} else {
|
|
lRet = -1;
|
|
}
|
|
|
|
GlobalUnlock(hSKT1Ctxt);
|
|
return (lRet);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
return DefWindowProc(hSKWnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
return (0L);
|
|
}
|