📄 dvorak_implementation.cpp
字号:
hRes = g_pIMCallback->SendVirtualKey( pKey->bVk, dwVkFlags );
}
else
{
if( ALTED() )
{
nShiftState |= KeyShiftAnyAltFlag;
}
if( CONTROLLED() )
{
nShiftState |= KeyShiftAnyCtrlFlag;
if( NO_CTL == *(pnChar = (UINT*)&pKey->nCtrl) )
{
nShiftState |= KeyShiftNoCharacterFlag;
}
}
else if( SHIFTED() )
{
nShiftState |= KeyShiftAnyShiftFlag;
pnChar = &pKey->wcShift;
}
else
{
pnChar = &pKey->wcUnshift;
}
hRes = g_pIMCallback->SendCharEvents(
pKey->bVk,
nShiftState,
1,
&nShiftState,
pnChar );
}
//
// If the key unpressed is not sticky, unpress all currently stuck keys
// except for caps lock.
//
if( !fPress && g_nDown && !(pKey->fdwFlags & F_STK) )
{
for( nRow = 0; nRow < NUM_ROWS; nRow++ )
{
pKey = g_keys[nRow];
while( g_nDown && pKey->bVk != SENTINEL )
{
if( pKey->fdwFlags & F_STK &&
pKey->fdwFlags & F_DOWN &&
VK_CAPITAL != pKey->bVk )
{
rc.left = pKey->nLeft;
rc.right = (pKey + 1)->nLeft;
rc.top = g_nRowCoord[nRow];
rc.bottom = g_nRowCoord[nRow + 1];
IM_PressKey( FALSE, pKey, &rc );
}
pKey++;
}
}
}
return SUCCEEDED(hRes);
}
//
// Handle mouse events.
//
__inline static LRESULT WINAPI IM_OnMouseEvent( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static RECT rcKey;
static KEYENTRY* pKey = NULL;
switch( msg )
{
//
// On a keydown, either press the button, or if it is sticky, toggle it.
//
case WM_LBUTTONDOWN:
rcKey.left = LOWORD(lParam);
rcKey.top = HIWORD(lParam);
if( pKey = IM_GetKeyFromCoord( &rcKey ) )
{
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 );
}
}
SetCapture( hwnd );
}
break;
//
// on a keyup, unpress a non-sticky button.
//
case WM_LBUTTONUP:
if( pKey && !(pKey->fdwFlags & F_STK) )
{
IM_PressKey( FALSE, pKey, &rcKey );
}
pKey = NULL;
ReleaseCapture();
break;
} // switch( msg )
return 0;
}
//
// Main window procedure.
//
LRESULT WINAPI ImWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM 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.
//
__inline static void WINAPI IM_SetDownKeys( void )
{
KEYENTRY* pKey;
int nRow;
g_nDown = 0;
for( nRow = 0; nRow < NUM_ROWS; nRow++ )
{
pKey = g_keys[nRow];
while( pKey->bVk != SENTINEL )
{
pKey->fdwFlags &= ~F_DOWN;
pKey++;
}
}
return;
}
//
// IInputMethod implementation.
//
//
// Ctor, Dtor.
//
CInputMethod::CInputMethod( IUnknown *pUnkOuter, HINSTANCE hInstance )
{
m_cRef = 0;
g_dwObjectCount++;
if( !pUnkOuter )
{
m_pUnkOuter = this;
}
else
{
m_pUnkOuter = pUnkOuter;
}
return;
}
CInputMethod::~CInputMethod()
{
g_dwObjectCount--;
return;
}
//
// IInputMethod methods.
//
STDMETHODIMP CInputMethod::Select( HWND hwndSip )
{
WNDCLASS wc;
ZeroMemory( &wc, sizeof(wc) );
wc.lpfnWndProc = ImWndProc;
wc.hInstance = g_hInstDll;
wc.hbrBackground = NULL;
wc.lpszClassName = g_ptszClassName;
if( !RegisterClass( &wc ) )
{
return E_FAIL;
}
IM_SetDownKeys();
g_hbmKeybd = LoadBitmap( g_hInstDll, MAKEINTRESOURCE(IDB_KEYBD1) );
g_hdcKeybd = CreateCompatibleDC( NULL );
g_hbmOld = (HBITMAP)SelectObject( g_hdcKeybd, g_hbmKeybd );
g_hwndMain = CreateWindow(
g_ptszClassName,
TEXT(""),
WS_CHILD,
0,
0,
10,
10,
hwndSip,
(HMENU)NULL,
g_hInstDll,
NULL );
ShowWindow( g_hwndMain, SW_SHOWNOACTIVATE );
return NOERROR;
}
STDMETHODIMP CInputMethod::Deselect( void )
{
ImageList_Destroy( g_hImagelistWide );
ImageList_Destroy( g_hImagelistNarrow );
g_hImagelistWide = g_hImagelistNarrow = NULL;
SelectObject( g_hdcKeybd, g_hbmOld );
DeleteObject( g_hbmKeybd );
DeleteDC( g_hdcKeybd );
DestroyWindow( g_hwndMain );
UnregisterClass( g_ptszClassName, g_hInstDll );
return NOERROR;
}
STDMETHODIMP CInputMethod::Showing( void )
{
return NOERROR;
}
STDMETHODIMP CInputMethod::Hiding( void )
{
return NOERROR;
}
STDMETHODIMP CInputMethod::GetInfo( IMINFO *pimi )
{
HBITMAP hbm;
if( !g_hImagelistWide )
{
g_hImagelistWide = ImageList_Create(
32,
16,
ILC_COLOR | ILC_MASK,
1,
1 );
g_hImagelistNarrow = ImageList_Create(
16,
16,
ILC_COLOR | ILC_MASK,
1,
1 );
if( hbm = LoadBitmap( g_hInstDll, MAKEINTRESOURCE(IDB_WIDE1) ) )
{
ImageList_AddMasked( g_hImagelistWide, hbm, RGB(192,192,192) );
DeleteObject( hbm );
}
if( hbm = LoadBitmap( g_hInstDll, MAKEINTRESOURCE(IDB_NARROW1) ) )
{
ImageList_AddMasked( g_hImagelistNarrow, hbm, RGB(192,192,192) );
DeleteObject( hbm );
}
}
pimi->fdwFlags = SIPF_DOCKED;
pimi->hImageNarrow = (HANDLE)g_hImagelistNarrow;
pimi->hImageWide = (HANDLE)g_hImagelistWide;
pimi->iNarrow = pimi->iWide = 0;
pimi->rcSipRect.left = pimi->rcSipRect.top = 0;
pimi->rcSipRect.right = BITMAP_WIDTH;
pimi->rcSipRect.bottom = BITMAP_HEIGHT;
return NOERROR;
}
STDMETHODIMP CInputMethod::ReceiveSipInfo( SIPINFO *psi )
{
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 )
{
g_pIMCallback = pIMCallback;
return NOERROR;
}
STDMETHODIMP CInputMethod::GetImData( DWORD dwSize, void *pvImData )
{
return E_NOTIMPL;
}
STDMETHODIMP CInputMethod::SetImData( DWORD dwSize, void *pvImData )
{
return E_NOTIMPL;
}
STDMETHODIMP CInputMethod::UserOptionsDlg( HWND hwndParent )
{
return E_NOTIMPL;
}
//
// IUnknown methods.
//
STDMETHODIMP CInputMethod::QueryInterface( REFIID riid, LPVOID FAR* ppobj )
{
if( IID_IUnknown == riid || IID_IInputMethod == riid )
{
*ppobj = this;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CInputMethod::AddRef( void )
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CInputMethod::Release( void )
{
if( --m_cRef )
{
return m_cRef;
}
delete this;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -