?? im.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
//
/*++
Module Name:
im.cpp
Abstract:
Sample LSIP Input Method.
Revision History:
--*/
#define INITGUID
#include <windows.h>
#include <coguid.h>
#undef INITGUID
#include <commctrl.h>
#include <sipapi.h>
#include "resource.h"
#include "dllmain.h"
#include "im.h"
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("DynamicIM"), {
TEXT("Init"),TEXT("Keys"),TEXT(""),TEXT(""),
TEXT(""),TEXT(""),TEXT(""),TEXT(""),
TEXT(""),TEXT(""),TEXT("Interface"),TEXT("Misc"),
TEXT("Alloc"), TEXT("Function"), TEXT("Warning"), TEXT("Error") },
0x00000000
};
#else
DWORD v_dwDebugFlag = 0x0; // Allow some retail debug zones.
#endif // DEBUG
//
// The KEYENTRY structure describes a single key on the keyboard.
//
typedef struct {
UINT bVk; // If VK then just a byte, -1 for sentinel
UINT wcUnshift;
UINT wcShift;
UINT nCtrl;
DWORD fdwFlags;
int nLeft;
} KEYENTRY;
#define NUM_ROWS 6
KEYENTRY g_keys[NUM_ROWS][16+1] = {
// First Row
{
{ VK_ESCAPE, 0, 0, NO_CTL, F_VK, 0 },
{ VK_F1, 0, 0, NO_CTL, F_VK, 29 },
{ VK_F2, 0, 0, NO_CTL, F_VK, 58 },
{ VK_F3, 0, 0, NO_CTL, F_VK, 87 },
{ VK_F4, 0, 0, NO_CTL, F_VK, 116 },
{ VK_F5, 0, 0, NO_CTL, F_VK, 145 },
{ VK_F6, 0, 0, NO_CTL, F_VK, 174 },
{ VK_F7, 0, 0, NO_CTL, F_VK, 203 },
{ VK_F8, 0, 0, NO_CTL, F_VK, 232 },
{ VK_F9, 0, 0, NO_CTL, F_VK, 261 },
{ VK_F10, 0, 0, NO_CTL, F_VK, 290 },
{ VK_F11, 0, 0, NO_CTL, F_VK, 319 },
{ VK_F12, 0, 0, NO_CTL, F_VK, 348 },
{ VK_HOME, 0, 0, NO_CTL, F_VK, 377 },
{ VK_END, 0, 0, NO_CTL, F_VK, 406 },
{ VK_END/*PROP*/,0, 0, NO_CTL, F_VK, 435 },
// The above key should eventually be changed to something besides VK_END
// as soon as its purpose is clearly determined. */
{ SENTINEL, 0, 0, NO_CTL, F_VK, 462 }
},
// Second row
{
{ VK_BACKQUOTE, '`', '~', NO_CTL, 0, 0 },
{ '1', '1', '!', NO_CTL, 0, 33 },
{ '2', '2', '@', 0, 0, 66 },
{ '3', '3', '#', NO_CTL, 0, 99 },
{ '4', '4', '$', NO_CTL, 0, 132 },
{ '5', '5', '%', NO_CTL, 0, 165 },
{ '6', '6', '^', 30, 0, 198 },
{ '7', '7', '&', NO_CTL, 0, 231 },
{ '8', '8', '*', NO_CTL, 0, 264 },
{ '9', '9', '(', NO_CTL, 0, 297 },
{ '0', '0', ')', NO_CTL, 0, 330 },
{ VK_HYPHEN, '-', '_', 31, 0, 363 },
{ VK_EQUAL, '=', '+', NO_CTL, 0, 396 },
{ VK_BACK, '\x8', '\x8', 127, 0, 429 },
{ SENTINEL, 0, 0, NO_CTL, 0, 462 }
},
// Third row
{
{ VK_TAB, '\t', '\t', '\t', 0, 0 },
{ 'Q', 'q', 'Q', 17, 0, 33 },
{ 'W', 'w', 'W', 23, 0, 66 },
{ 'E', 'e', 'E', 5, 0, 99 },
{ 'R', 'r', 'R', 18, 0, 132 },
{ 'T', 't', 'T', 20, 0, 165 },
{ 'Y', 'y', 'Y', 25, 0, 198 },
{ 'U', 'u', 'U', 21, 0, 231 },
{ 'I', 'i', 'I', 9, 0, 264 },
{ 'O', 'o', 'O', 15, 0, 297 },
{ 'P', 'p', 'P', 16, 0, 330 },
{ VK_LBRACKET, '[', '{', 27, 0, 363 },
{ VK_RBRACKET, ']', '}', 29, 0, 396 },
{ VK_BACKSLASH, '\\', '|', 28, 0, 429 },
{ SENTINEL, 0, 0, NO_CTL, 0, 462 }
},
// Forth row
{
{ VK_CAPITAL, 0, 0, NO_CTL, F_VK | F_STK | F_REDRAW, 0 },
{ 'A', 'a', 'A', 1, 0, 33 },
{ 'S', 's', 'S', 19, 0, 66 },
{ 'D', 'd', 'D', 4, 0, 99 },
{ 'F', 'f', 'F', 6, 0, 132 },
{ 'G', 'g', 'G', 7, 0, 165 },
{ 'H', 'h', 'H', 8, 0, 198 },
{ 'J', 'j', 'J', 10, 0, 231 },
{ 'K', 'k', 'K', 11, 0, 264 },
{ 'L', 'l', 'L', 12, 0, 297 },
{ VK_SEMICOLON, ';', ':', NO_CTL, 0, 330 },
{ VK_APOSTROPHE,'\'', '\"', NO_CTL, 0, 363 },
{ VK_RETURN, '\xD', '\xD', 10, 0, 396 },
{ SENTINEL, 0, 0, NO_CTL, 0, 462 }
},
// Fifth row
{
{ VK_SHIFT, 0, 0, NO_CTL, F_VK | F_STK | F_REDRAW, 0 },
{ 'Z', 'z', 'Z', 26, 0, 33 },
{ 'X', 'x', 'X', 24, 0, 66 },
{ 'C', 'c', 'C', 3, 0, 99 },
{ 'V', 'v', 'V', 22, 0, 132 },
{ 'B', 'b', 'B', 2, 0, 165 },
{ 'N', 'n', 'N', 14, 0, 198 },
{ 'M', 'm', 'M', 13, 0, 231 },
{ VK_COMMA, ',', '<', NO_CTL, 0, 264 },
{ VK_PERIOD, '.', '>', NO_CTL, 0, 297 },
{ VK_SLASH, '/', '?', NO_CTL, 0, 330 },
{ VK_UP, 0, 0, NO_CTL, 0, 363 },
{ VK_UP /**/, 0, 0, NO_CTL, 0, 396 },
{ VK_PRIOR, 0, 0, NO_CTL, 0, 429 },
{ SENTINEL, 0, 0, NO_CTL, 0, 462 }
},
// Sixth row
{
{ VK_CONTROL, 0, 0, NO_CTL, F_VK | F_STK, 0 },
{ VK_LWIN, 0, 0, 0, F_VK, 33 },
{ VK_LMENU, 0, 0, 0, F_VK | F_STK, 66 },
{ VK_SPACE, ' ', ' ', 32, 0, 99 },
{ VK_INSERT, 0, 0, NO_CTL, 0, 264 },
{ VK_DELETE, 0, 0, NO_CTL, 0, 297 },
{ VK_LEFT, 0, 0, NO_CTL, 0, 330 },
{ VK_DOWN, 0, 0, NO_CTL, 0, 363 },
{ VK_RIGHT, 0, 0, NO_CTL, 0, 396 },
{ VK_NEXT, 0, 0, NO_CTL, 0, 429 },
{ SENTINEL, 0, 0, NO_CTL, 0, 462 }
},
};
static int g_RowCoord[8] = { 0, 29, 62, 95, 128, 161, 194, 0xFFFF };
//
// Globals.
//
static TCHAR const g_pwszClassName[] = TEXT("A523DFC7-1A7E-4af6-991A-510E75847828 - MicrosoftIMWndClass");
static HWND g_hwndMain;
static HDC g_hdcKeybd;
static HBITMAP g_hbmKeybd, g_hbmOld;
static IIMCallback *g_pIMCallback;
static int g_nDown; //普通按鍵是否被按下
static BOOL g_fControlDown; //Control鍵是否按下
static BOOL g_fCapsLockDown; //CapsLock鍵是否按下
static BOOL g_fShiftDown; //Shift鍵是否按下
static BOOL g_fAltDown; //Alt鍵是否按下
//
// Draw the key in the up/down position based on fPress 根據彈起或按下處的fPress值,繪制此處的按鍵
//
void IM_DrawKey(KEYENTRY *pKey, RECT *prc, BOOL fPress)
{
HDC hdc;
RECT rc;
int Offset = 0; //繪制鍵盤需要繪制BMP的上半部分還是下半部分鍵盤
hdc = GetDC(g_hwndMain);
rc = *prc;
InflateRect(&rc, -1, -1);
if (g_fShiftDown ^ g_fCapsLockDown) {
Offset = 195;
}
BitBlt(hdc, rc.left, rc.top, rc.right - rc.left + 1, rc.bottom - rc.top + 1,
g_hdcKeybd, rc.left, rc.top + Offset, fPress ? NOTSRCCOPY : SRCCOPY);
ReleaseDC(g_hwndMain, hdc);
}
//
// Paint an area of the keyboard. 繪制鍵盤的區域
//
static
void WINAPI
IM_DrawArea( HDC hdc, RECT *prcUpdate )
{
int Offset = 0;
RETAILMSG (ZONE_FUNCTION, (TEXT("+IM_DrawArea(0x%08X, 0x%08X(%d,%d,%d,%d))\r\n"), hdc, prcUpdate,
prcUpdate->left, prcUpdate->top, prcUpdate->right, prcUpdate->bottom));
// Draw the keys.
if (g_fShiftDown ^ g_fCapsLockDown) {
Offset = 195; //繪制BMP下半部分,大寫字母
}
BitBlt(hdc, prcUpdate->left, prcUpdate->top, prcUpdate->right - prcUpdate->left,
prcUpdate->bottom - prcUpdate->top, g_hdcKeybd, prcUpdate->left,
prcUpdate->top + Offset, SRCCOPY );
// Now draw any keys that are down 現在繪制某一個被按下的鍵
//
if (g_nDown) {
int nRow, nCol;
KEYENTRY *pKey;
RECT rc;
for (nRow = 0; nRow < NUM_ROWS; nRow++) {
for (nCol = 0; SENTINEL != g_keys[nRow][nCol].bVk; nCol++) {
pKey = &(g_keys[nRow][nCol]);
if (pKey->fdwFlags & F_DOWN) {
rc.left = pKey->nLeft;
rc.right = (pKey + 1)->nLeft;
rc.top = g_RowCoord[nRow];
rc.bottom = g_RowCoord[nRow + 1];
IM_DrawKey(pKey, &rc, TRUE);
}
}
}
}
return;
}
//
// Refresh the entire keyboard bitmap. 刷新整個鍵盤的BMP圖
//
static
void WINAPI
IM_SwitchBitmap( void )
{
HDC hdc;
RECT rc;
GetClientRect( g_hwndMain, &rc );
hdc = GetDC( g_hwndMain );
IM_DrawArea( hdc, &rc );
ReleaseDC( g_hwndMain, hdc );
return;
}
//
// Determine the left edge of nKey + 1
//
#define KeyLeftCoord(nRow,nKey) (g_keys[nRow][nKey+1].nLeft)
//
// Determine what key contains the point specified in rcKey.left,rcKey.top.
// Fill in the full coordinates for the key and return the keyentry.
//
// Assumptions: we will not get a down event outside of our window, and every
// point in the window maps to a key.
//
__inline static
KEYENTRY* WINAPI
IM_GetKeyFromCoord( RECT *prcKey )
{
int nRow = 0, nKey = 0, nLeft;
POINT pt;
pt.x = prcKey->left;
pt.y = prcKey->top;
//
// Row
//
while( prcKey->top > g_RowCoord[nRow + 1] ) {
nRow++;
}
if (nRow > 5) {
nRow = 5;
}
//
// Key
//
while (prcKey->left > (nLeft = KeyLeftCoord(nRow, nKey))) {
nKey++;
}
RETAILMSG (ZONE_KEYS, (TEXT("%d,%d -> %d,%d\r\n"), prcKey->top, prcKey->left, nRow, nKey));
//
// Set up rect and return the key.
//
prcKey->left = g_keys[nRow][nKey].nLeft;
prcKey->right = nLeft;
prcKey->top = g_RowCoord[nRow];
prcKey->bottom = g_RowCoord[nRow + 1];
return g_keys[nRow] + nKey;
}
//按鍵動作
static
BOOL WINAPI
IM_PressKey( BOOL fPress, KEYENTRY *pKey, RECT *prcKey )
{
DWORD dwVkFlags;
KEY_STATE_FLAGS nShiftState;
HRESULT hRes;
UINT *pnChar = NULL;
if( fPress )
{
pKey->fdwFlags |= F_DOWN;
dwVkFlags = KEYEVENTF_SILENT;
nShiftState = KeyStateDownFlag;
}
else
{
pKey->fdwFlags &= ~F_DOWN;
dwVkFlags = KEYEVENTF_KEYUP | KEYEVENTF_SILENT;
nShiftState = KeyShiftNoCharacterFlag;
}
//
// Adjust down count (an optimization for redraw and searching).
//
g_nDown += fPress ? 1 : -1;
ASSERT(g_nDown >= 0);
if ( pKey->fdwFlags & F_VK )
{
hRes = g_pIMCallback->SendVirtualKey( pKey->bVk, dwVkFlags );
}
else
{
#define ISNOCHARACTERKEY(pKey) (pKey->wcUnshift == 0 && pKey->wcShift == 0)
if (ISNOCHARACTERKEY(pKey))
{
nShiftState |= KeyShiftNoCharacterFlag;
}
if(g_fAltDown)
{
nShiftState |= KeyShiftAnyAltFlag | KeyShiftLeftAltFlag;
}
if (g_fControlDown)
{
nShiftState |= KeyShiftAnyCtrlFlag;
if (NO_CTL == pKey->nCtrl)
{
nShiftState |= KeyShiftNoCharacterFlag;
}
pnChar = &pKey->nCtrl;
}
else if (g_fShiftDown ^ g_fCapsLockDown)
{
nShiftState |= KeyShiftAnyShiftFlag;
pnChar = &pKey->wcShift;
}
else
{
pnChar = &pKey->wcUnshift;
}
if (pnChar)
{
hRes = g_pIMCallback->SendCharEvents(pKey->bVk, nShiftState, 1, &nShiftState, pnChar);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -