📄 im.cpp
字号:
switch (pKey->bVk)
{
case VK_CONTROL :
g_fControlDown = fPress;
break;
case VK_SHIFT :
g_fShiftDown = fPress;
break;
case VK_LMENU :
g_fAltDown = fPress;
break;
case VK_CAPITAL :
g_fCapsLockDown = fPress;
break;
}
if (pKey->fdwFlags & F_REDRAW)
{
IM_SwitchBitmap();
}
IM_DrawKey (pKey, prcKey, fPress);
if (!fPress && g_nDown)
{
int nRow, nCol;
KEYENTRY *pKeyTemp;
RECT rc;
for (nRow = 0; g_nDown && (nRow < NUM_ROWS); nRow++)
{
for (nCol = 0; g_nDown && (SENTINEL != g_keys[nRow][nCol].bVk); nCol++)
{
pKeyTemp = &(g_keys[nRow][nCol]);
if ((pKeyTemp->fdwFlags & F_DOWN) && (VK_CAPITAL != pKeyTemp->bVk))
{
// We need a small delay to allow characters sent earlier
// to be processed before we change the global keyboard state.
// If not, keybd_event may change the global keyboard state before
// an application has received and processed the characters sent earlier.
Sleep(100);
rc.left = pKeyTemp->nLeft;
rc.right = (pKeyTemp + 1)->nLeft;
rc.top = g_RowCoord[nRow];
rc.bottom = g_RowCoord[nRow + 1];
IM_PressKey(FALSE, pKeyTemp, &rc);
}
}
}
}
return SUCCEEDED(hRes);
}
//
// Handle mouse events. 鼠标句柄事件
//
__inline static
LRESULT WINAPI
IM_OnMouseEvent( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static int nKeyDownX, nKeyDownY;
static RECT rcKey;
static KEYENTRY *pKey = NULL;
int nKeyUpX, nKeyUpY;
static BOOL fDblClk = FALSE;
// RETAILMSG (ZONE_FUNCTION, (TEXT("+IM_OnMouseEvent(0x%08X, 0x%08X, 0x%08X, 0x%08X)\r\n"), hwnd, msg, wParam, lParam));
switch (msg) {
case WM_LBUTTONDOWN :
RETAILMSG (ZONE_MOUSE, (TEXT("Got WM_LBUTTONDOWN\r\n")));
fDblClk = FALSE;
rcKey.left = nKeyDownX = (int)((short)LOWORD(lParam)); //keep the sign
rcKey.top = nKeyDownY = (int)((short)HIWORD(lParam));
if (pKey = IM_GetKeyFromCoord(&rcKey)) {
RETAILMSG (ZONE_KEYS, (TEXT("Found pKey=0x%08X\r\n"), pKey));
pKey->fdwFlags |= F_CAPTURED;
IM_DrawKey(pKey, &rcKey, TRUE);
SetCapture(hwnd);
} else {
RETAILMSG (ZONE_KEYS, (TEXT("ERROR: Get coord (%d,%d)but can't find key\r\n"),
nKeyDownX, nKeyDownY));
}
break;
case WM_LBUTTONUP :
RETAILMSG (ZONE_MOUSE, (TEXT("Got WM_LBUTTONUP\r\n")));
if (fDblClk) {
break;
}
nKeyUpX = (int)((short)LOWORD(lParam)); // keep the sign
nKeyUpY = (int)((short)HIWORD(lParam));
if (pKey) {
pKey->fdwFlags &= ~F_CAPTURED;
if ((pKey->fdwFlags & F_STK) && (pKey->fdwFlags & F_DOWN)) {
if (VK_CAPITAL == pKey->bVk) {
g_pIMCallback->SendVirtualKey(pKey->bVk, KEYEVENTF_SILENT);
}
IM_PressKey (FALSE, pKey, &rcKey);
} else {
IM_PressKey (TRUE, pKey, &rcKey);
if (VK_CAPITAL == pKey->bVk) {
g_pIMCallback->SendVirtualKey(pKey->bVk,
KEYEVENTF_SILENT | KEYEVENTF_KEYUP );
//Now, get the CAPS lock mode bitmap up
IM_SwitchBitmap();
}
}
if( !(pKey->fdwFlags & F_STK) ) {
//Not a sticky key, so unpress this guy please
IM_PressKey( FALSE, pKey, &rcKey );
pKey = NULL;
}
}
ReleaseCapture();
break;
case WM_LBUTTONDBLCLK:
RETAILMSG (ZONE_MOUSE, (TEXT("Got WM_LBUTTONDBCLK\r\n")));
rcKey.left = LOWORD(lParam);
rcKey.top = HIWORD(lParam);
pKey = IM_GetKeyFromCoord( &rcKey );
SetCapture(hwnd);
if (pKey->fdwFlags & F_STK) {
//For sticky keys, we need to remember that we got a double click
//and BLOW OFF the ensuing WM_LBUTTONUP. This will allow them to
//stay down. For normal keys, processing the ensuing button up
//allows us to get a key for the double click.
fDblClk = TRUE;
} else {
IM_DrawKey(pKey, &rcKey, TRUE);
}
#if 0
// LARGEKB doesn't really support shift lock state. This would be used if you wanted to have a different
// handling of keys like the numeric keys. On most keyboards CAPS lock does not affect the numeric values
// This simplistic keyboard shiftlock and capslock are the same.
switch (pKey->bVk) {
case VK_SHIFT:
if (pKey->fdwFlags & F_DOWN) {
//Shift key is down, unpress it
g_pIMCallback->SendVirtualKey(VK_SHIFT, KEYEVENTF_KEYUP | KEYEVENTF_SILENT);
g_nDown--;
}
pKey->fdwFlags |= F_DOWN;
g_fShiftDown = TRUE;
g_nDown++; //When in CAPS LOCK mode, we'll consider the key "down" for painting purposes.
g_pIMCallback->SendVirtualKey(VK_CAPITAL, KEYEVENTF_SILENT);
g_pIMCallback->SendVirtualKey(VK_CAPITAL, KEYEVENTF_KEYUP | KEYEVENTF_SILENT);
//Now, get the CAPS lock mode bitmap up
IM_SwitchBitmap();
break;
}
#endif
break;
}
return 0;
}
//
// Main window procedure.
//
LRESULT WINAPI
ImWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
// RETAILMSG (ZONE_FUNCTION, (TEXT("+ImWndProc(0x%08X, 0x%08X, 0x%08X, 0x%08X)\r\n"), hwnd, msg, wParam, lParam));
PAINTSTRUCT ps;
switch( msg )
{
case WM_PAINT:
BeginPaint( hwnd, &ps );
IM_DrawArea( ps.hdc, &ps.rcPaint );
EndPaint( hwnd, &ps );
return 0;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
case WM_LBUTTONDBLCLK:
return IM_OnMouseEvent( hwnd, msg, wParam, lParam );
} // switch( message )
return DefWindowProc( hwnd, msg, wParam, lParam );
}
//
// At startup, set our keystate for all of our keys to up.
// We rely on the SIP manager to lift all sticky/modifier keys, and to turn
// caps lock off, before selecting a new IM.
//
//
// IInputMethod implementation.
//
//
// Ctor, Dtor.
//
CInputMethod::CInputMethod( IUnknown *pUnkOuter, HINSTANCE hInstance )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::CInputMethod(0x%08X, 0x%08X)\r\n"), pUnkOuter, hInstance));
m_cRef = 0;
g_dwObjectCount++;
if( !pUnkOuter ) {
m_pUnkOuter = this;
} else {
m_pUnkOuter = pUnkOuter;
}
return;
}
CInputMethod::~CInputMethod()
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::~CInputMethod()\r\n")));
g_dwObjectCount--;
return;
}
//
// IInputMethod methods.
//
STDMETHODIMP CInputMethod::Select( HWND hwndSip )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Select(0x%08X)\r\n"), hwndSip));
WNDCLASS wc;
// UINT uKB;
RETAILMSG (ZONE_KEYS, (TEXT("CInputMethod::Select\r\n")));
ZeroMemory( &wc, sizeof(wc) );
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = ImWndProc;
wc.hInstance = g_hInstDll;
wc.hbrBackground = NULL;
wc.lpszClassName = g_pwszClassName;
if( !RegisterClass( &wc ) ) {
return E_FAIL;
}
g_hdcKeybd = CreateCompatibleDC( NULL );
g_hbmKeybd = LoadBitmap (g_hInstDll, MAKEINTRESOURCE(IDB_KEYBD));
g_hbmOld = (HBITMAP)SelectObject (g_hdcKeybd, g_hbmKeybd);
g_hwndMain = CreateWindow(
g_pwszClassName,
TEXT(""),
WS_CHILD,
0,
0,
10,
10,
hwndSip,
(HMENU)NULL,
g_hInstDll,
NULL );
InvalidateRect(g_hwndMain, NULL, TRUE);
UpdateWindow(g_hwndMain);
ShowWindow( g_hwndMain, SW_SHOWNOACTIVATE );
return NOERROR;
}
STDMETHODIMP CInputMethod::Deselect( void )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Deselect()\r\n")));
SelectObject( g_hdcKeybd, g_hbmOld );
DeleteObject( g_hbmKeybd );
DeleteDC( g_hdcKeybd );
DestroyWindow( g_hwndMain );
UnregisterClass( g_pwszClassName, g_hInstDll );
return NOERROR;
}
STDMETHODIMP CInputMethod::Showing( void )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Showing()\r\n")));
IM_SwitchBitmap ();
return NOERROR;
}
STDMETHODIMP CInputMethod::Hiding( void )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Hiding()\r\n")));
return NOERROR;
}
STDMETHODIMP CInputMethod::GetInfo( IMINFO *pimi )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::GetInfo()\r\n")));
pimi->fdwFlags = SIPF_DOCKED;
pimi->hImageNarrow = (HANDLE)NULL;
pimi->hImageWide = (HANDLE)NULL;
pimi->iNarrow = pimi->iWide = 0;
pimi->rcSipRect.right = pimi->rcSipRect.left + 465;
pimi->rcSipRect.bottom = pimi->rcSipRect.top + 194;
if (g_pIMCallback)
{
g_pIMCallback->SetImInfo(pimi);
}
InvalidateRect(g_hwndMain, NULL, TRUE);
UpdateWindow(g_hwndMain);
return NOERROR;
}
STDMETHODIMP CInputMethod::ReceiveSipInfo( SIPINFO *psi )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::ReceiveSipInfo()\r\n")));
RETAILMSG (ZONE_KEYS, (TEXT("MIM: ReceiveSipInfo!!! ltrb: %d %d %d %d\r\n"), psi->rcSipRect.left,
psi->rcSipRect.top,
psi->rcSipRect.right,
psi->rcSipRect.bottom));
MoveWindow(
g_hwndMain,
0,
0,
psi->rcSipRect.right - psi->rcSipRect.left,
psi->rcSipRect.bottom - psi->rcSipRect.top,
FALSE );
return NOERROR;
}
STDMETHODIMP CInputMethod::RegisterCallback( IIMCallback *pIMCallback )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::RegisterCallback(0x%08X)\r\n"), pIMCallback));
g_pIMCallback = pIMCallback;
return NOERROR;
}
STDMETHODIMP CInputMethod::GetImData( DWORD dwSize, void *pvImData )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::GetImData(%d, 0x%08X)\r\n"), dwSize, pvImData));
return E_NOTIMPL;
}
STDMETHODIMP CInputMethod::SetImData( DWORD dwSize, void *pvImData )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::SetImData(%d, 0x%08X)\r\n"), dwSize, pvImData));
return NOERROR;
}
STDMETHODIMP CInputMethod::UserOptionsDlg( HWND hwndParent )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::UserOptionsDlg(0x%08X)\r\n"), hwndParent));
return E_NOTIMPL;
}
//
// IUnknown methods.
//
STDMETHODIMP CInputMethod::QueryInterface( REFIID riid, LPVOID FAR* ppobj )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::QueryInterface(0x%08X, 0x%08X)\r\n"), riid, ppobj));
if( IID_IUnknown == riid || IID_IInputMethod == riid ) {
*ppobj = this;
AddRef();
return NOERROR;
}
RETAILMSG (ZONE_ERROR, (TEXT("CInputMethod::QueryInterface : Error Ret\r\n")));
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CInputMethod::AddRef( void )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::AddRef()\r\n")));
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CInputMethod::Release( void )
{
RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Release()\r\n")));
if( --m_cRef ) {
return m_cRef;
}
delete this;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -