Leaked source code of windows server 2003
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.
 
 
 
 
 
 

494 lines
12 KiB

/**************************************************************************\
* Module Name: softkbdes.cpp
*
* Copyright (c) 1985 - 2000, Microsoft Corporation
*
* Soft Keyboard Event Sink for the Symbol layout
*
* History:
* 28-March-2000 weibz Created
\**************************************************************************/
#include "private.h"
#include "globals.h"
#include "immxutil.h"
#include "proputil.h"
#include "kes.h"
#include "helpers.h"
#include "editcb.h"
#include "dispattr.h"
#include "computil.h"
#include "regsvr.h"
#include "korimx.h"
#include "SoftKbdES.h"
#include "osver.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSoftKeyboardEventSink::CSoftKeyboardEventSink(CKorIMX *pKorIMX, DWORD dwSoftLayout)
{
m_pKorIMX = pKorIMX;
_dwSoftLayout = dwSoftLayout;
_fCaps = fFalse;
_fShift = fFalse;
_fAlt = fFalse;
_fCtrl = fFalse;
_tid = pKorIMX->GetTID();
_tim = pKorIMX->GetTIM();
_tim->AddRef( );
_cRef = 1;
}
CSoftKeyboardEventSink::~CSoftKeyboardEventSink()
{
SafeReleaseClear(_tim);
}
//+---------------------------------------------------------------------------
//
// IUnknown
//
//----------------------------------------------------------------------------
STDAPI CSoftKeyboardEventSink::QueryInterface(REFIID riid, void **ppvObj)
{
*ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ISoftKeyboardEventSink))
{
*ppvObj = SAFECAST(this, CSoftKeyboardEventSink *);
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDAPI_(ULONG) CSoftKeyboardEventSink::AddRef()
{
return ++_cRef;
}
STDAPI_(ULONG) CSoftKeyboardEventSink::Release()
{
long cr;
cr = --_cRef;
Assert(cr >= 0);
if (cr == 0)
{
delete this;
}
return cr;
}
//
// ISoftKeyboardEventSink
//
STDAPI CSoftKeyboardEventSink::OnKeySelection(KEYID KeySelected, WCHAR *lpszLabel)
{
KEYID keyId;
BYTE bVk, bScan;
BOOL fModifierSpecial = fFalse;
HKL hKL;
INT_PTR iHKL;
HRESULT hr;
hr = S_OK;
bScan = (BYTE)KeySelected;
hKL = GetKeyboardLayout(0);
if (!IsOnNT())
{
// We have to handle IME hkl specially on Win9x.
// For some reason, Win9x cannot receive IME HKL as parameter in MapVirtualKeyEx and ToAsciiEx.
iHKL = (INT_PTR)hKL;
if ((iHKL & 0xF0000000) == 0xE0000000)
{
// this is FE IME HKL.
iHKL = iHKL & 0x0000FFFF;
hKL = (HKL)iHKL;
}
}
bVk = (BYTE)MapVirtualKeyEx((UINT)bScan, 1, hKL);
switch (KeySelected)
{
case KID_CTRL :
_fCtrl = !_fCtrl;
// Generate proper key msg
if (_fCtrl)
keybd_event(bVk, bScan, 0, 0);
else
keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
break;
case KID_ALT :
_fAlt = !_fAlt;
// Generate proper key msg
if (_fAlt)
keybd_event(bVk, bScan, 0, 0);
else
keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
break;
case KID_CAPS :
if (m_pKorIMX->GetConvMode(m_pKorIMX->GetIC()) == TIP_ALPHANUMERIC_MODE)
{
_fCaps = !_fCaps;
if (_fCaps == _fShift)
// use state 0
m_pKorIMX->GetHangulSKbd()->dwCurLabel = 0;
else
// use state 1
m_pKorIMX->GetHangulSKbd()->dwCurLabel = 1;
hr = SetCompartmentDWORD(_tid, _tim, GUID_COMPARTMENT_SOFTKBD_KBDLAYOUT, _dwSoftLayout, fFalse);
}
// specially handle Caps Lock
// this is a togglable key
keybd_event(bVk, bScan, 0, 0);
keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
break;
case KID_LSHFT :
case KID_RSHFT :
_fShift = !_fShift;
if (_fCaps == _fShift)
// use state 0
m_pKorIMX->GetHangulSKbd()->dwCurLabel = 0;
else
// use state 1
m_pKorIMX->GetHangulSKbd()->dwCurLabel = 1;
hr = SetCompartmentDWORD(_tid, _tim, GUID_COMPARTMENT_SOFTKBD_KBDLAYOUT, _dwSoftLayout, fFalse);
// Generate proper key msg
if (_fShift)
keybd_event(bVk, bScan, 0, 0);
else
keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
break;
/*
case KID_F1 :
case KID_F2 :
case KID_F3 :
case KID_F4 :
case KID_F5 :
case KID_F6 :
case KID_F7 :
case KID_F8 :
case KID_F9 :
case KID_F10 :
case KID_F11 :
case KID_F12 :
case KID_TAB :
// simulate a key event and send to system.
case KID_ENTER :
case KID_ESC :
case KID_SPACE :
case KID_BACK :
case KID_UP :
case KID_DOWN :
case KID_LEFT :
case KID_RIGHT :
*/
default:
{
int j, jIndex;
BOOL fExtendKey, fPictureKey;
keyId = KeySelected;
fPictureKey = fFalse;
// Check picture key
for (j=0; j < NUM_PICTURE_KEYS; j++)
{
if (gPictureKeys[j].uScanCode == keyId)
{
// This is a picture key.
// it may be a extended key.
jIndex = j;
fPictureKey = fTrue;
break;
}
if (gPictureKeys[j].uScanCode == 0)
{
// This is the last item in gPictureKeys.
break;
}
}
fExtendKey = fFalse;
// Picture key handling
if (fPictureKey)
{
if ((keyId & 0xFF00) == 0xE000)
{
fExtendKey = fTrue;
bScan = (BYTE)(keyId & 0x000000ff);
}
else
bScan = (BYTE)keyId;
// Get virtual key code
bVk = (BYTE)(gPictureKeys[jIndex].uVkey);
}
// Generate Keyboard event
if (fExtendKey)
{
keybd_event(bVk, bScan, (DWORD)KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(bVk, bScan, (DWORD)(KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP), 0);
}
else
{
keybd_event(bVk, bScan, 0, 0);
keybd_event(bVk, bScan, (DWORD)KEYEVENTF_KEYUP, 0);
}
#if 0
// if the Shift Key is pressed, we need to release this key.
if (GetKeyState(VK_SHIFT) & 0x80)
{
fModifierSpecial = fTrue;
_fShift = !_fShift;
// simulate the SHIFT-UP key event.
keybd_event((BYTE)VK_SHIFT, (BYTE)KID_LSHFT, (DWORD)KEYEVENTF_KEYUP, 0);
}
// if the Ctrl Key is pressed, we need to release this key.
if (GetKeyState(VK_CONTROL) & 0x80)
{
fModifierSpecial = fTrue;
// simulate the Ctrl-UP key event.
keybd_event((BYTE)VK_CONTROL, (BYTE)KID_CTRL, (DWORD)KEYEVENTF_KEYUP, 0);
}
#endif
#if 0
// if the Alt Key is pressed, we need to release this key.
if (lpCurKbdLayout->ModifierStatus & MODIFIER_ALT)
{
fModifierSpecial = TRUE;
lpCurKbdLayout->ModifierStatus &= ~((WORD)MODIFIER_ALT);
// simulate the SHIFT-UP key event.
keybd_event((BYTE)VK_MENU, (BYTE)KID_ALT, (DWORD)KEYEVENTF_KEYUP, 0);
}
// if the Right Alt Key is pressed, we need to release this key.
if (lpCurKbdLayout->ModifierStatus & MODIFIER_ALTGR)
{
fModifierSpecial = TRUE;
lpCurKbdLayout->ModifierStatus &= ~((WORD)MODIFIER_ALTGR);
// simulate the SHIFT-UP key event.
keybd_event((BYTE)VK_RMENU, (BYTE)KID_RALT, (DWORD)KEYEVENTF_KEYUP, 0);
}
#endif
if (fModifierSpecial)
{
if (_fCaps == _fShift)
// use state 0
m_pKorIMX->GetHangulSKbd()->dwCurLabel = 0;
else
// use state 1
m_pKorIMX->GetHangulSKbd()->dwCurLabel = 1;
hr = SetCompartmentDWORD(_tid, _tim, GUID_COMPARTMENT_SOFTKBD_KBDLAYOUT, _dwSoftLayout, fFalse);
}
break;
}
/*
default :
if ( lpszLabel == NULL )
{
hr = E_FAIL;
return hr;
}
pic = m_pKorIMX->GetIC( );
if ( pic == NULL )
{
return hr;
}
if (pes = new CEditSession(CKorIMX::_EditSessionCallback))
{
WCHAR *lpLabel;
int i, iLen;
iLen = (int) wcslen(lpszLabel);
lpLabel = (WCHAR *)cicMemAllocClear((iLen+1)*sizeof(WCHAR));
if ( lpLabel == NULL )
{
// not enough memory.
hr = E_OUTOFMEMORY;
return hr;
}
for ( i=0; i<iLen; i++)
lpLabel[i] = lpszLabel[i];
lpLabel[iLen] = L'\0';
pes->_state.u = ESCB_KEYLABEL;
pes->_state.pv = m_pKorIMX;
pes->_state.wParam = (WPARAM)KeySelected;
pes->_state.lParam = (LPARAM)lpLabel;
pes->_state.pic = pic;
pes->_state.pv1 = NULL;
pic->EditSession(m_pKorIMX->_tid,
pes,
TF_ES_READWRITE,
&hr);
if ( FAILED(hr) )
{
SafeFreePointer(lpLabel);
}
SafeRelease(pes);
}
else
hr = E_FAIL;
SafeRelease(pic);
break;
*/
}
return hr;
}
CSoftKbdWindowEventSink::CSoftKbdWindowEventSink(CKorIMX *pKorIMX)
{
m_pKorIMX = pKorIMX;
_cRef = 1;
}
CSoftKbdWindowEventSink::~CSoftKbdWindowEventSink()
{
}
//+---------------------------------------------------------------------------
//
// IUnknown
//
//----------------------------------------------------------------------------
STDAPI CSoftKbdWindowEventSink::QueryInterface(REFIID riid, void **ppvObj)
{
*ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ISoftKbdWindowEventSink))
{
*ppvObj = SAFECAST(this, CSoftKbdWindowEventSink *);
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDAPI_(ULONG) CSoftKbdWindowEventSink::AddRef()
{
return ++_cRef;
}
STDAPI_(ULONG) CSoftKbdWindowEventSink::Release()
{
long cr;
cr = --_cRef;
Assert(cr >= 0);
if (cr == 0)
{
delete this;
}
return cr;
}
//
// ISoftKbdWindowEventSink
//
STDAPI CSoftKbdWindowEventSink::OnWindowClose( )
{
HRESULT hr = S_OK;
if (m_pKorIMX)
m_pKorIMX->SetSoftKBDOnOff(FALSE);
return hr;
}
STDAPI CSoftKbdWindowEventSink::OnWindowMove(int xWnd, int yWnd, int width, int height)
{
HRESULT hr = S_OK;
if (m_pKorIMX)
m_pKorIMX->SetSoftKBDPosition(xWnd, yWnd);
// support size change later.
UNREFERENCED_PARAMETER(width);
UNREFERENCED_PARAMETER(height);
return hr;
}