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.
 
 
 
 
 
 

1089 lines
26 KiB

//
// This is implementation of softkbd window UI.
//
#include "private.h"
#include "globals.h"
#include "softkbdui.h"
#include "maskbmp.h"
#include "commctrl.h"
#include "cuiutil.h"
#include "immxutil.h"
#include "cregkey.h"
HBITMAP MyLoadImage(HINSTANCE hInst, LPCSTR pResStr)
{
HBITMAP hBmpRes;
hBmpRes = (HBITMAP)LoadBitmap(hInst, pResStr);
return hBmpRes;
}
/* C O N V E R T L O G F O N T W T O A */
/*------------------------------------------------------------------------------
Convert LOGFONTW to LOGFONTA
------------------------------------------------------------------------------*/
void ConvertLogFontWtoA( CONST LOGFONTW *plfW, LOGFONTA *plfA )
{
UINT cpg;
plfA->lfHeight = plfW->lfHeight;
plfA->lfWidth = plfW->lfWidth;
plfA->lfEscapement = plfW->lfEscapement;
plfA->lfOrientation = plfW->lfOrientation;
plfA->lfWeight = plfW->lfWeight;
plfA->lfItalic = plfW->lfItalic;
plfA->lfUnderline = plfW->lfUnderline;
plfA->lfStrikeOut = plfW->lfStrikeOut;
plfA->lfCharSet = plfW->lfCharSet;
plfA->lfOutPrecision = plfW->lfOutPrecision;
plfA->lfClipPrecision = plfW->lfClipPrecision;
plfA->lfQuality = plfW->lfQuality;
plfA->lfPitchAndFamily = plfW->lfPitchAndFamily;
DWORD dwChs = plfW->lfCharSet;
CHARSETINFO ChsInfo = {0};
if (dwChs != SYMBOL_CHARSET && TranslateCharsetInfo( &dwChs, &ChsInfo, TCI_SRCCHARSET ))
{
cpg = ChsInfo.ciACP;
}
else
cpg = GetACP();
WideCharToMultiByte( cpg,
0,
plfW->lfFaceName,
-1,
plfA->lfFaceName,
ARRAYSIZE(plfA->lfFaceName),
NULL,
NULL );
}
///////////////////////////////////////////////////////////////////////////////
//
//class CSoftkbdButton
//
///////////////////////////////////////////////////////////////////////////////
CSoftkbdButton::CSoftkbdButton(CUIFObject *pParent, DWORD dwID, const RECT *prc, DWORD dwStyle, KEYID keyId) : CUIFButton2 (pParent, dwID, prc, dwStyle)
{
m_keyId = keyId;
CUIFWindow *pUIWnd;
pUIWnd = pParent->GetUIWnd( );
m_hFont = pUIWnd->GetFont( );
}
CSoftkbdButton::~CSoftkbdButton( void )
{
if ( m_hBmp )
{
::DeleteObject( (HGDIOBJ) m_hBmp );
m_hBmp = NULL;
}
if ( m_hBmpMask )
{
::DeleteObject( (HGDIOBJ)m_hBmpMask );
m_hBmpMask = NULL;
}
if ( m_hIcon )
{
::DestroyIcon(m_hIcon);
m_hIcon = NULL;
}
}
HRESULT CSoftkbdButton::SetSoftkbdBtnBitmap(HINSTANCE hResDll, WCHAR * wszBitmapStr)
{
HRESULT hr = S_OK;
char pBitmapAnsiName[MAX_PATH];
HBITMAP hBitMap;
WideCharToMultiByte(CP_ACP, 0, wszBitmapStr, -1, pBitmapAnsiName, MAX_PATH, NULL, NULL);
hBitMap = (HBITMAP) MyLoadImage(hResDll, pBitmapAnsiName);
if ( hBitMap == NULL )
{
if ( hResDll != g_hInst )
{
// cannot load it from client-supplied resource dll,
// try our softkbd.dll to see if there is one internal bitmap for this label.
hBitMap = (HBITMAP) MyLoadImage(g_hInst, pBitmapAnsiName);
}
}
if ( hBitMap == NULL )
{
hr = E_FAIL;
return hr;
}
CMaskBitmap maskBmp(hBitMap);
maskBmp.Init(GetSysColor(COLOR_BTNTEXT));
SetBitmap( maskBmp.GetBmp() );
SetBitmapMask( maskBmp.GetBmpMask() );
::DeleteObject(hBitMap);
return hr;
};
HRESULT CSoftkbdButton::ReleaseButtonResouce( )
{
HRESULT hr = S_OK;
if ( m_hBmp )
{
::DeleteObject( (HGDIOBJ) m_hBmp );
m_hBmp = NULL;
}
if ( m_hBmpMask )
{
::DeleteObject( (HGDIOBJ)m_hBmpMask );
m_hBmpMask = NULL;
}
if ( m_hIcon )
{
::DestroyIcon(m_hIcon);
m_hIcon = NULL;
}
if (m_pwchText != NULL) {
delete m_pwchText;
m_pwchText = NULL;
}
return hr;
}
//////////////////////////////////////////////////////////////////////////////
//
// CStaticBitmap
//
//////////////////////////////////////////////////////////////////////////////
CStaticBitmap::CStaticBitmap(CUIFObject *pParent, DWORD dwID, const RECT *prc, DWORD dwStyle) : CUIFObject(pParent, dwID, prc, dwStyle )
{
m_hBmp = NULL;
m_hBmpMask = NULL;
}
CStaticBitmap::~CStaticBitmap( void )
{
if ( m_hBmp )
{
::DeleteObject(m_hBmp);
m_hBmp = NULL;
}
if ( m_hBmpMask )
{
::DeleteObject(m_hBmpMask);
m_hBmpMask = NULL;
}
}
HRESULT CStaticBitmap::SetStaticBitmap(HINSTANCE hResDll, WCHAR * wszBitmapStr )
{
HRESULT hr = S_OK;
char pBitmapAnsiName[MAX_PATH];
HBITMAP hBitMap;
WideCharToMultiByte(CP_ACP, 0, wszBitmapStr, -1, pBitmapAnsiName, MAX_PATH, NULL, NULL);
hBitMap = (HBITMAP) MyLoadImage(hResDll, pBitmapAnsiName);
if ( hBitMap == NULL )
{
if ( hResDll != g_hInst )
{
// cannot load it from client-supplied resource dll,
// try our softkbd.dll to see if there is one internal bitmap for this label.
hBitMap = (HBITMAP) MyLoadImage(g_hInst, pBitmapAnsiName);
}
}
if ( hBitMap == NULL )
{
hr = E_FAIL;
return hr;
}
CMaskBitmap maskBmp(hBitMap);
maskBmp.Init(GetSysColor(COLOR_BTNTEXT));
m_hBmp = maskBmp.GetBmp();
m_hBmpMask = maskBmp.GetBmpMask();
::DeleteObject(hBitMap);
return hr;
}
void CStaticBitmap::OnPaint( HDC hDC )
{
if ( !hDC || !m_hBmp ||!m_hBmpMask )
return;
const RECT *prc = &GetRectRef();
const int nWidth = prc->right - prc->left;
const int nHeight= prc->bottom - prc->top;
HBITMAP hBmp = CreateMaskBmp(&GetRectRef(),
m_hBmp,
m_hBmpMask,
(HBRUSH)(COLOR_3DFACE + 1) , 0, 0);
DrawState(hDC,
NULL,
NULL,
(LPARAM)hBmp,
0,
prc->left,
prc->top,
nWidth,
nHeight,
DST_BITMAP);
DeleteObject(hBmp);
}
//////////////////////////////////////////////////////////////////////////////
//
// CTitleUIGripper
//
//////////////////////////////////////////////////////////////////////////////
void CTitleUIGripper::OnPaint(HDC hDC) {
RECT rc ;
if (GetRectRef().right-GetRectRef().left <= GetRectRef().bottom-GetRectRef().top) {
::SetRect(&rc, GetRectRef().left + 1,
GetRectRef().top,
GetRectRef().left + 4,
GetRectRef().bottom);
} else {
::SetRect(&rc, GetRectRef().left,
GetRectRef().top + 1,
GetRectRef().right,
GetRectRef().top+4);
}
DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT);
}
void CTitleUIGripper::OnLButtonUp( POINT pt )
{
CSoftkbdUIWnd *pUIWnd;
// call base class's member function first.
CUIFGripper::OnLButtonUp(pt);
pUIWnd = (CSoftkbdUIWnd *)GetUIWnd( );
if ( pUIWnd != NULL )
{
// Notify the Window position move.
pUIWnd->_OnWindowMove( );
}
return;
}
//////////////////////////////////////////////////////////////////////////////
//
// CTitleBarUIObj
//
//////////////////////////////////////////////////////////////////////////////
CTitleBarUIObj::CTitleBarUIObj(CUIFObject *pWndFrame, const RECT *prc, TITLEBAR_TYPE TitleBar_Type)
: CUIFObject(pWndFrame, 0, prc, 0)
{
m_TitlebarType = TitleBar_Type;
m_pCloseButton = NULL;
m_pIconButton = NULL;
}
CTitleBarUIObj::~CTitleBarUIObj(void)
{
HBITMAP hBitmap;
HBITMAP hBitmapMask;
if ( m_pCloseButton )
{
if (hBitmap=m_pCloseButton->GetBitmap()) {
m_pCloseButton->SetBitmap((HBITMAP) NULL);
::DeleteObject(hBitmap);
}
if (hBitmapMask=m_pCloseButton->GetBitmapMask()) {
m_pCloseButton->SetBitmapMask((HBITMAP) NULL);
::DeleteObject(hBitmapMask);
}
}
}
//----------------------------------------------------------------------------
HRESULT CTitleBarUIObj::_Init(WORD wIconId, WORD wCloseId)
{
HRESULT hr = S_OK;
RECT rectObj = {0,0,0,0};
RECT rectGripper;
if ( m_TitlebarType == TITLEBAR_NONE )
return hr;
GetRect(&rectGripper);
rectObj = rectGripper;
long lIconWidth=rectObj.bottom-rectObj.top + 1;
this->m_pointPreferredSize.y=lIconWidth;
if ( m_TitlebarType == TITLEBAR_GRIPPER_VERTI_ONLY )
{
// This is a vertical gripper only title bar.
rectGripper.left += 2;
rectGripper.right-= 2;
rectGripper.top += 2;
rectGripper.bottom -= 2;
CUIFObject *pUIFObject=new CTitleUIGripper(this,&rectGripper);
if ( !pUIFObject )
return E_OUTOFMEMORY;
pUIFObject->Initialize();
this->AddUIObj(pUIFObject);
return hr;
}
if ( m_TitlebarType == TITLEBAR_GRIPPER_HORIZ_ONLY )
{
// This is a Horizontal gripper only title bar.
rectGripper.left += 2;
rectGripper.right -= 2;
rectGripper.top += 2;
rectGripper.bottom -= 2;
CUIFObject *pUIFObject=new CTitleUIGripper(this,&rectGripper);
if ( !pUIFObject )
return E_OUTOFMEMORY;
pUIFObject->Initialize();
this->AddUIObj(pUIFObject);
return hr;
}
if ( wIconId != 0 )
{
rectObj.right=rectObj.left+lIconWidth;
m_pIconButton=new CStaticBitmap(this,wIconId,&rectObj,0);
if (m_pIconButton)
{
m_pIconButton->Initialize();
m_pIconButton->SetStaticBitmap(g_hInst, L"IDB_ICON");
m_pIconButton->m_pointPreferredSize.x=lIconWidth;
this->AddUIObj(m_pIconButton);
}
rectGripper.left = rectObj.right + 4;
}
if ( wCloseId != 0 )
{
rectObj.left=rectGripper.right - lIconWidth -1;
rectObj.right=rectGripper.right;
m_pCloseButton=new CSoftkbdButton(this,wCloseId,&rectObj,UIBUTTON_SUNKENONMOUSEDOWN | UIBUTTON_CENTER | UIBUTTON_VCENTER, 0);
if (m_pCloseButton)
{
m_pCloseButton->Initialize();
m_pCloseButton->SetSoftkbdBtnBitmap(g_hInst, L"IDB_CLOSE");
m_pCloseButton->m_pointPreferredSize.x=lIconWidth;
this->AddUIObj(m_pCloseButton);
}
rectGripper.right = rectObj.left - 4;
}
rectGripper.top += 3;
CUIFObject *pUIFObject=new CTitleUIGripper(this,&rectGripper);
if ( !pUIFObject )
return E_OUTOFMEMORY;
pUIFObject->Initialize();
this->AddUIObj(pUIFObject);
return hr;
}
///////////////////////////////////////////////////////////////////////////
//
// CSoftkbdUIWnd
//
///////////////////////////////////////////////////////////////////////////
CSoftkbdUIWnd::CSoftkbdUIWnd(CSoftKbd *pSoftKbd, HINSTANCE hInst,UINT uiWindowStyle) : CUIFWindow(hInst, uiWindowStyle)
{
m_pSoftKbd = pSoftKbd;
m_TitleBar = NULL;
m_Titlebar_Type = TITLEBAR_NONE;
m_bAlpha = 0;
m_fShowAlphaBlend =TRUE;
m_hUserTextFont = NULL;
}
CSoftkbdUIWnd::~CSoftkbdUIWnd( )
{
// if there is hwnd, detroy it and all the children objects.
if ( m_hWnd && IsWindow(m_hWnd) )
{
::DestroyWindow( m_hWnd );
m_hWnd = NULL;
}
if ( m_hUserTextFont )
{
SetFont((HFONT)NULL);
DeleteObject(m_hUserTextFont);
m_hUserTextFont = NULL;
}
}
const TCHAR c_szCTFLangBar[] = TEXT("Software\\Microsoft\\CTF\\LangBar");
const TCHAR c_szTransparency[] = TEXT("Transparency");
// Get the Alpha Blending set value from registry:
//
// HKCU\Software\Microsoft\CTF\LangBar: Transparency : REG_DWORD
//
INT CSoftkbdUIWnd::_GetAlphaSetFromReg( )
{
LONG lret = ERROR_SUCCESS;
CMyRegKey regkey;
DWORD dw = 255;
lret = regkey.Open(HKEY_CURRENT_USER,
c_szCTFLangBar,
KEY_READ);
if (ERROR_SUCCESS == lret)
{
lret = regkey.QueryValue(dw, c_szTransparency);
regkey.Close();
}
return (INT)dw;
}
LRESULT CSoftkbdUIWnd::OnObjectNotify(CUIFObject * pUIObj, DWORD dwCode, LPARAM lParam)
{
KEYID keyId;
DWORD dwObjId;
UNREFERENCED_PARAMETER(dwCode);
UNREFERENCED_PARAMETER(lParam);
if ( m_pSoftKbd == NULL )
return 0;
dwObjId = pUIObj->GetID();
if ( dwObjId != 0 )
{
// This is button object, not gripper object.
CSoftkbdButton *pButton;
if ( dwCode == UIBUTTON_PRESSED )
{
pButton = (CSoftkbdButton * )pUIObj;
if ( dwObjId <= MAX_KEY_NUM )
{
// regular keys in the keyboard layout.
keyId = pButton->GetKeyId( );
m_pSoftKbd->_HandleKeySelection(keyId);
}
else
{
// Titlebar buttons
m_pSoftKbd->_HandleTitleBarEvent(dwObjId);
}
}
}
return 0;
}
CUIFObject *CSoftkbdUIWnd::Initialize( void )
{
//
// Get the current active keyboard layout and register window class
// not to send VK_PROCESSKEY by mouse down/up in Korean SoftKbd.
// Related bug#472946 #495890
//
LANGID langId = LOWORD(HandleToUlong(GetKeyboardLayout(0)));
if (PRIMARYLANGID(langId) == LANG_KOREAN)
{
//
// Here register candidate window class.
//
WNDCLASSEX WndClass;
LPCTSTR pszClassName = GetClassName();
memset(&WndClass, 0, sizeof(WndClass));
WndClass.cbSize = sizeof(WndClass);
// Added CS_IME style not to send VK_PROCESSKEY for mouse down/up.
WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_IME;
WndClass.lpfnWndProc = WindowProcedure;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 8;
WndClass.hInstance = g_hInst;
WndClass.hIcon = NULL;
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = NULL;
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = pszClassName;
WndClass.hIconSm = NULL;
RegisterClassEx(&WndClass);
}
CUIFObject *pUIObjRet;
// call CUIFWindow::Initialize() to create tooltip window
pUIObjRet = CUIFWindow::Initialize();
return pUIObjRet;
}
HWND CSoftkbdUIWnd::_CreateSoftkbdWindow(HWND hOwner, TITLEBAR_TYPE Titlebar_type, INT xPos, INT yPos, INT width, INT height)
{
HWND hWnd;
hWnd = CreateWnd(hOwner);
Move(xPos, yPos, width, height);
m_Titlebar_Type = Titlebar_type;
return hWnd;
}
HRESULT CSoftkbdUIWnd::_GenerateWindowLayout( )
{
HRESULT hr=S_OK;
int i;
KBDLAYOUT *realKbdLayout=NULL;
KBDLAYOUTDES *lpCurKbdLayout=NULL;
CSoftkbdButton *pButton = NULL;
int nChild;
if ( m_pSoftKbd == NULL )
return E_FAIL;
if ( (m_TitleBar == NULL) && ( m_Titlebar_Type != TITLEBAR_NONE) )
{
RECT *prc;
// Get the titlebar rect.
prc = m_pSoftKbd->_GetTitleBarRect( );
m_TitleBar = (CTitleBarUIObj *) new CTitleBarUIObj(this, prc, m_Titlebar_Type);
if ( m_TitleBar == NULL )
return E_FAIL;
m_TitleBar->Initialize( );
m_TitleBar->_Init(KID_ICON, KID_CLOSE);
AddUIObj(m_TitleBar);
}
// If there is any existing object in this window object, just delete all of them, except for Titlebar object
nChild = m_ChildList.GetCount();
for (i=nChild; i>0; i--) {
CUIFObject *pUIObj = m_ChildList.Get(i-1);
if ( pUIObj->GetID( ) != 0 )
{
// This is not Gripper
m_ChildList.Remove(pUIObj);
delete pUIObj;
}
}
// Add all the keys contained in current layout to this window object as its children objects.
// every key should have already been calculated the correct position and size.
lpCurKbdLayout = m_pSoftKbd->_GetCurKbdLayout( );
if ( lpCurKbdLayout == NULL )
return E_FAIL;
realKbdLayout = &(lpCurKbdLayout->kbdLayout);
if ( realKbdLayout == NULL ) return E_FAIL;
for ( i=0; i<realKbdLayout->wNumberOfKeys; i++) {
KEYID keyId;
RECT keyRect={0,0,0,0};
keyId = realKbdLayout->lpKeyDes[i].keyId;
keyRect.left = realKbdLayout->lpKeyDes[i].wLeft;
keyRect.top = realKbdLayout->lpKeyDes[i].wTop;
keyRect.right = realKbdLayout->lpKeyDes[i].wWidth + keyRect.left - 1;
keyRect.bottom = realKbdLayout->lpKeyDes[i].wHeight + keyRect.top - 1;
if ( realKbdLayout->lpKeyDes[i].tModifier == none )
{
// This is a normal key
pButton = new CSoftkbdButton(this, i+1, &keyRect, UIBUTTON_SUNKENONMOUSEDOWN | UIBUTTON_CENTER | UIBUTTON_VCENTER, keyId);
}
else
{
// This is toggle key, Modifier key.
pButton = new CSoftkbdButton(this, i+1, &keyRect, UIBUTTON_SUNKENONMOUSEDOWN | UIBUTTON_CENTER | UIBUTTON_VCENTER | UIBUTTON_TOGGLE, keyId);
}
Assert(pButton);
if ( !pButton || !pButton->Initialize() )
{
// may need to release all created buttons.
return E_FAIL;
}
// add this button to this window container.
// button lable ( text or bitmap, or Icon ) will be set later when user selects modification status.
AddUIObj(pButton);
}
return hr;
}
HRESULT CSoftkbdUIWnd::_SetKeyLabel( )
{
HRESULT hr=S_OK;
CSoftkbdButton *pButton;
int i, iIndex;
ACTIVELABEL *pCurLabel;
KEYID keyId;
HINSTANCE hResDll;
KBDLAYOUTDES *lpCurKbdLayout=NULL;
KBDLAYOUT *realKbdLayout=NULL;
int nChild;
int nCur;
if ( m_pSoftKbd == NULL )
return E_FAIL;
lpCurKbdLayout = m_pSoftKbd->_GetCurKbdLayout( );
if ( lpCurKbdLayout == NULL )
return E_FAIL;
realKbdLayout = &(lpCurKbdLayout->kbdLayout);
if ( realKbdLayout == NULL ) return E_FAIL;
if ( (lpCurKbdLayout->lpKeyMapList)->wszResource[0] == L'\0' )
{
//
// There is no separate dll to keep picture key.
// probably, it is a standard soft keyboard layout.
// so just use internal resource kept in this dll.
//
hResDll = g_hInst;
}
else
{
// There is a separate DLL to keep the bitmap resource.
CHAR lpszAnsiResFile[MAX_PATH];
WideCharToMultiByte(CP_ACP, 0, (lpCurKbdLayout->lpKeyMapList)->wszResource, -1,
lpszAnsiResFile, MAX_PATH, NULL, NULL );
hResDll = (HINSTANCE) LoadLibraryA( lpszAnsiResFile );
if ( hResDll == NULL )
{
Assert(hResDll!=NULL);
return E_FAIL;
}
}
// All the keys are already added to this window container.
// we need to set the label ( text or picture) based on current m_pSoftKbd setting.
pCurLabel = m_pSoftKbd->_GetCurLabel( );
nChild = m_ChildList.GetCount();
for (nCur = 0; nCur < nChild; nCur++) {
DWORD dwObjId;
pButton = (CSoftkbdButton *)(m_ChildList.Get(nCur));
dwObjId = pButton->GetID( );
if ( dwObjId == 0 )
{
continue;
}
// Get the keyindex in CurLabel array.
keyId = pButton->GetKeyId( );
iIndex = -1;
for ( i=0; i<MAX_KEY_NUM; i++ )
{
if ( pCurLabel[i].keyId == keyId )
{
iIndex = i;
break;
}
}
if ( iIndex == -1 )
{
// Cannot find this key,
// return error.
hr = E_FAIL;
goto CleanUp;
}
// Found it, set the label
//
// if it is text key, call pButton->SetText( )
// if it is picture key, call pButton->SetBitmap( )
// Before we set the lable, we need to release all the previous resources
// for this key button, so that we will not cause resource leak.
pButton->ReleaseButtonResouce( );
if ( pCurLabel[iIndex].LabelType == LABEL_TEXT )
pButton->SetText( pCurLabel[iIndex].lpLabelText);
else
{
pButton->SetSoftkbdBtnBitmap(hResDll, pCurLabel[iIndex].lpLabelText);
}
// if it is Disp_Active, call pButton->Enable(TRUE)
// if it is gray key, call pButton->Enable(FALSE)
if ( pCurLabel[iIndex].LabelDisp == LABEL_DISP_ACTIVE )
{
pButton->Enable(TRUE);
}
else
{
pButton->Enable(FALSE);
}
if ( realKbdLayout->lpKeyDes[dwObjId-1].tModifier != none )
{
// this is a modifier key ( Toggle key )
// check to see if this key is pressed.
MODIFYTYPE tModifier;
tModifier = realKbdLayout->lpKeyDes[dwObjId-1].tModifier;
if ( lpCurKbdLayout->ModifierStatus & (1 << tModifier) )
{
// this modifier key has been pressed.
pButton->SetToggleState(TRUE);
}
else
pButton->SetToggleState(FALSE);
}
}
CleanUp:
// Release the resource DLL if there is a separate one.
if ( (lpCurKbdLayout->lpKeyMapList)->wszResource[0] != L'\0' )
{
// There is a separate DLL to keep the bitmap resource.
FreeLibrary(hResDll);
}
return hr;
}
void CSoftkbdUIWnd::Show( INT iShow )
{
KBDLAYOUTDES *lpCurKbdLayout=NULL;
KBDLAYOUT *realKbdLayout=NULL;
int nChild;
int i;
if ( m_pSoftKbd == NULL )
return;
lpCurKbdLayout = m_pSoftKbd->_GetCurKbdLayout( );
if ( lpCurKbdLayout == NULL )
return;
realKbdLayout = &(lpCurKbdLayout->kbdLayout);
if ( realKbdLayout == NULL ) return;
if ( !(iShow & SOFTKBD_SHOW) || (iShow & SOFTKBD_DONT_SHOW_ALPHA_BLEND) )
m_fShowAlphaBlend = FALSE;
else
m_fShowAlphaBlend = TRUE;
m_bAlphaSet = _GetAlphaSetFromReg( );
if ( iShow )
{
// check the togglable key's state.
CSoftkbdButton *pButton;
nChild = m_ChildList.GetCount();
for (i = 0; i < nChild; i++) {
DWORD dwObjId;
pButton = (CSoftkbdButton *)m_ChildList.Get(i);
dwObjId = pButton->GetID( );
if ( dwObjId == 0 )
{
continue;
}
if ( realKbdLayout->lpKeyDes[dwObjId-1].tModifier != none )
{
// this is a modifier key ( Toggle key )
// check to see if this key is pressed.
MODIFYTYPE tModifier;
tModifier = realKbdLayout->lpKeyDes[dwObjId-1].tModifier;
if ( lpCurKbdLayout->ModifierStatus & (1 << tModifier) )
{
// this modifier key has been pressed.
pButton->SetToggleState(TRUE);
}
else
pButton->SetToggleState(FALSE);
}
}
}
CUIFWindow::Show((iShow & SOFTKBD_SHOW) ? TRUE : FALSE);
POINT ptScrn;
GetCursorPos(&ptScrn);
if (WindowFromPoint(ptScrn) == GetWnd())
SetAlpha(255);
else
SetAlpha(m_bAlphaSet);
return;
}
void CSoftkbdUIWnd::UpdateFont( LOGFONTW *plfFont )
{
if ( !plfFont )
return;
HFONT hNewFont;
if ( IsOnNT( ) )
hNewFont = CreateFontIndirectW( plfFont );
else
{
LOGFONTA lfTextFontA;
ConvertLogFontWtoA(plfFont, &lfTextFontA);
hNewFont = CreateFontIndirectA( &lfTextFontA );
}
if ( hNewFont )
{
SetFont(hNewFont);
if ( m_hUserTextFont )
DeleteObject( m_hUserTextFont );
m_hUserTextFont = hNewFont;
}
}
HRESULT CSoftkbdUIWnd::_OnWindowMove( )
{
HRESULT hr = S_OK;
ISoftKbdWindowEventSink *pskbdwndes;
if ( m_pSoftKbd == NULL )
return E_FAIL;
pskbdwndes = m_pSoftKbd->_GetSoftKbdWndES( );
if ( pskbdwndes != NULL )
{
pskbdwndes->AddRef( );
hr = pskbdwndes->OnWindowMove(_xWnd, _yWnd, _nWidth, _nHeight);
pskbdwndes->Release( );
}
return hr;
}
typedef BOOL (WINAPI * SETLAYERWINDOWATTRIBUTE)(HWND, COLORREF, BYTE, DWORD);
void CSoftkbdUIWnd::SetAlpha(INT bAlpha)
{
if ( !m_fShowAlphaBlend )
return;
if ( m_bAlpha == bAlpha )
return;
if ( IsOnNT5() )
{
HINSTANCE hUser32;
DWORD dwExStyle = GetWindowLong(GetWnd(), GWL_EXSTYLE);
SetWindowLong(GetWnd(), GWL_EXSTYLE, dwExStyle | WS_EX_LAYERED);
hUser32 = GetSystemModuleHandle(TEXT("user32.dll"));
SETLAYERWINDOWATTRIBUTE pfnSetLayeredWindowAttributes;
if (pfnSetLayeredWindowAttributes = (SETLAYERWINDOWATTRIBUTE)GetProcAddress(hUser32, TEXT("SetLayeredWindowAttributes")))
pfnSetLayeredWindowAttributes(GetWnd(), 0, (BYTE)bAlpha, LWA_ALPHA);
m_bAlpha = bAlpha;
}
return;
}
void CSoftkbdUIWnd::HandleMouseMsg( UINT uMsg, POINT pt )
{
POINT ptScrn = pt;
ClientToScreen(GetWnd(), &ptScrn);
if (WindowFromPoint(ptScrn) == GetWnd())
SetAlpha(255);
else
SetAlpha(m_bAlphaSet);
CUIFWindow::HandleMouseMsg(uMsg, pt);
}
void CSoftkbdUIWnd::OnMouseOutFromWindow( POINT pt )
{
UNREFERENCED_PARAMETER(pt);
SetAlpha(m_bAlphaSet);
}