|
|
//
// tipbar.cpp
//
#include "private.h"
#include "globals.h"
#include <initguid.h>
#include "tipbar.h"
#include "helpers.h"
#include "xstring.h"
#include "commctrl.h"
#include "resource.h"
#include "inatlib.h"
#include "thdutil.h"
#include "catutil.h"
#include "immxutil.h"
#include "utbmenu.h"
#include "balloon.h"
#include "cregkey.h"
#include "cuimenu.h"
#include "cuishadw.h"
#include "cuischem.h"
#include "cmydc.h"
#include "intlmenu.h"
#include "utbtray.h"
#include "catenum.h"
#include "asynccal.h"
#include "fontlink.h"
#include "cresstr.h"
#include "nuiinat.h"
#include "tlapi.h"
#include "cuiutil.h"
#include "cuischem.h"
#include "cuitip.h"
#include "utbdlgs.h"
#include <shlapip.h>
#include "deskband.h"
#include "lmcons.h" // for UNLEN
#include "sddl.h"
#include "winuserp.h"
const DWORD TF_LBESF_GLOBAL = 0x0001; const DWORD TF_LBSMI_FILTERCURRENTTHREAD = 0x0001;
extern HINSTANCE g_hInst; const TCHAR c_szTipbarWndClass[] = TEXT("TipbarWndClass"); const TCHAR c_szTipbarWndName[] = TEXT("Cicload Tipbar");
const TCHAR c_szCicKey[] = TEXT("SOFTWARE\\Microsoft\\CTF\\"); const TCHAR c_szUTBKey[] = TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"); const TCHAR c_szSkipRedrawHKL[] = TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\SkipRedrawHKL"); const TCHAR c_szShowTipbar[] = TEXT("ShowTipbar"); const TCHAR c_szDontShowCloseLangBarDlg[] = TEXT("DontShowCloseLangBarDlg"); const TCHAR c_szDontShowMinimizeLangBarDlg[] = TEXT("DontShowMinimizeLangBarDlg"); const TCHAR c_szShowDebugMenu[] = TEXT("ShowDebugMenu"); const TCHAR c_szShowDeskBand[] = TEXT("ShowDeskBand"); const TCHAR c_szNewLook[] = TEXT("NewLook"); const TCHAR c_szIntelliSense[] = TEXT("IntelliSense"); const TCHAR c_szTimeOutNonIntentional[] = TEXT("TimeOutNonIntentional"); const TCHAR c_szTimeOutIntentional[] = TEXT("TimeOutIntentional"); const TCHAR c_szShowCloseMenu[] = TEXT("ShowCloseMenu"); const TCHAR c_szShowMinimizedBalloon[] = TEXT("ShowMinimizedBalloon"); const TCHAR c_szLeft[] = TEXT("Left"); const TCHAR c_szTop[] = TEXT("Top"); const TCHAR c_szExcludeCaptionButtons[] = TEXT("ExcludeCaptionButtons"); const TCHAR c_szShowShadow[] = TEXT("ShowShadow"); const TCHAR c_szTaskbarTheme[] = TEXT("TaskbarTheme"); const TCHAR c_szVertical[] = TEXT("Vertical"); // const TCHAR c_szMoveToTray[] = TEXT("MoveToTray");
BOOL g_bNewLook = TRUE; BOOL g_bIntelliSense = FALSE; BOOL g_bShowTipbar = TRUE; BOOL g_bShowDebugMenu = FALSE; BOOL g_bShowCloseMenu = FALSE; BOOL g_bShowMinimizedBalloon = TRUE; BOOL g_bExcludeCaptionButtons = TRUE; BOOL g_bShowShadow = FALSE; BOOL g_bShowDeskBand = FALSE; BOOL g_nLeft = -1; BOOL g_nTop = -1; DWORD g_dwWndStyle = 0; DWORD g_dwChildWndStyle = 0; DWORD g_dwMenuStyle = 0; CTipbarWnd *g_pTipbarWnd; CTrayIconWnd *g_pTrayIconWnd; HWND g_hwndParent; BOOL g_bWinLogon = FALSE; BOOL g_fTaskbarTheme = TRUE; BOOL g_fVertical = FALSE; BOOL g_fInClosePopupTipbar = FALSE; BOOL g_fRTL = FALSE;
const TCHAR c_szTimerElapseSTUBSTART[] = TEXT("TimerElapseSTUBSTART"); const TCHAR c_szTimerElapseSTUBEND[] = TEXT("TimerElapseSTUBEND"); const TCHAR c_szTimerElapseBACKTOALPHA[] = TEXT("TimerElapseBACKTOALPHA"); const TCHAR c_szTimerElapseONTHREADITEMCHANGE[] = TEXT("TimerElapseONTHREADITEMCHANGE"); const TCHAR c_szTimerElapseSETWINDOWPOS[] = TEXT("TimerElapseSETWINDOWPOS"); const TCHAR c_szTimerElapseONUPDATECALLED[] = TEXT("TimerElapseONUPDATECALLED"); const TCHAR c_szTimerElapseSYSCOLORCHANGED[] = TEXT("TimerElapseSYSCOLORCHANGED"); const TCHAR c_szTimerElapseDISPLAYCHANGE[] = TEXT("TimerElapseDISPLAYCHANGE"); const TCHAR c_szTimerElapseUPDATEUI[] = TEXT("TimerElapseUPDATEUI"); const TCHAR c_szTimerElapseSHOWWINDOW[] = TEXT("TimerElapseSHOWWINDOW"); const TCHAR c_szTimerElapseMOVETOTRAY[] = TEXT("TimerElapseMOVETOTRAY"); const TCHAR c_szTimerElapseTRAYWNDONDELAYMSG[] = TEXT("TimerElapseTRAYWNDONDELAYMSG"); const TCHAR c_szTimerElapseDOACCDEFAULTACTION[] = TEXT("TimerElapseDOACCDEFAULTACTION"); const TCHAR c_szTimerElapseENSUREFOCUS[] = TEXT("TimerElapseENSUREFOCUS"); const TCHAR c_szTimerElapseSHOWDESKBAND[] = TEXT("TimerElapseSHOWWDESKBAND");
UINT g_uTimerElapseSTUBSTART = 100; UINT g_uTimerElapseSTUBEND = 2000; UINT g_uTimerElapseBACKTOALPHA = 3000; UINT g_uTimerElapseONTHREADITEMCHANGE = 200; UINT g_uTimerElapseSETWINDOWPOS = 100; UINT g_uTimerElapseONUPDATECALLED = 50; // Satori tune up 20,50,100 or 200
UINT g_uTimerElapseSYSCOLORCHANGED = 20; UINT g_uTimerElapseDISPLAYCHANGE = 20; UINT g_uTimerElapseUPDATEUI = 70; // MSIME2002 JP needs 70ms.
UINT g_uTimerElapseSHOWWINDOW = 50; UINT g_uTimerElapseMOVETOTRAY = 50; UINT g_uTimerElapseTRAYWNDONDELAYMSG = 50; UINT g_uTimerElapseDOACCDEFAULTACTION = 200; UINT g_uTimerElapseENSUREFOCUS = 50; UINT g_uTimerElapseSHOWDESKBAND = 3000;
//
// from bandobjs.cpp
//
extern UINT g_wmTaskbarCreated;
//
// from itemlist.cpp
//
extern UINT g_uTimeOutNonIntentional; extern UINT g_uTimeOutIntentional; extern UINT g_uTimeOutMax;
//
// SkipRedrawing Hack HKL list.
//
CStructArray<HKL> *g_prghklSkipRedrawing = NULL; void UninitSkipRedrawHKLArray();
#define WM_LBWND_SHOWCONTEXTMENU (WM_USER + 1)
// TM_LANGUAGEBAND is defined in "shell\inc\trayp.h"
#define TM_LANGUAGEBAND WM_USER+0x105
/* 142b6d42-955d-4488-97c0-b23b23e6b048 */ const IID IID_PRIV_BUTTONITEM = { 0x142b6d42, 0x955d, 0x4488, {0x97, 0xc0, 0xb2, 0x3b, 0x23, 0xe6, 0xb0, 0x48} };
/* 8dd1cc81-fca0-4dd5-b848-2b85732d2fc4 */ const IID IID_PRIV_BITMAPBUTTONITEM = { 0x8dd1cc81, 0xfca0, 0x4dd5, {0xb8, 0x48, 0x2b, 0x85, 0x73, 0x2d, 0x2f, 0xc4} };
/* 36b40e05-7b3e-4a4a-bda7-2249ba17d3c4 */ const IID IID_PRIV_BITMAPITEM = { 0x36b40e05, 0x7b3e, 0x4a4a, {0xbd, 0xa7, 0x22, 0x49, 0xba, 0x17, 0xd3, 0xc4} };
/* 68831a74-6f86-447a-b2b8-634250ac445e */ const IID IID_PRIV_BALLOONITEM = { 0x68831a74, 0x6f86, 0x447a, {0xb2, 0xb8, 0x63, 0x42, 0x50, 0xac, 0x44, 0x5e} };
//
// from MSCTF.DLL.
//
extern "C" BOOL WINAPI TF_IsFullScreenWindowAcitvated(); extern "C" DWORD WINAPI TF_CheckThreadInputIdle(DWORD dwThreadId, DWORD dwTimeOut);
//
// from intlmenu.cpp
//
extern BOOL IsFELangId(LANGID langid);
//////////////////////////////////////////////////////////////////////////////
//
// predefined control buttons
//
//////////////////////////////////////////////////////////////////////////////
static CTRLBTNMAP g_cbCtrlBtn[NUM_CTRLBUTTONS] = { {ID_CBTN_CAPSKEY, UIBUTTON_CENTER | UIBUTTON_VCENTER | UIBUTTON_TOGGLE, 0, 0, CTRL_ICONFROMRES | CTRL_TOGGLEBUTTON, {0x0, 0x0}}, {ID_CBTN_KANAKEY, UIBUTTON_CENTER | UIBUTTON_VCENTER | UIBUTTON_TOGGLE, 0, 1, CTRL_ICONFROMRES | CTRL_TOGGLEBUTTON, {0x0, 0x0}}, {ID_CBTN_MINIMIZE, UIBUTTON_CENTER | UIBUTTON_VCENTER, 1, 0, CTRL_USEMARLETT | CTRL_DISABLEONWINLOGON, {0x0030, 0x0000}}, {ID_CBTN_EXTMENU, UIBUTTON_CENTER | UIBUTTON_VCENTER, 1, 1, CTRL_USEMARLETT | CTRL_DISABLEONWINLOGON, {0x0075, 0x0000}}, };
static CTRLBTNMAP g_cbCtrlBtnDeskBand[NUM_CTRLBUTTONS] = { {ID_CBTN_CAPSKEY, UIBUTTON_CENTER | UIBUTTON_VCENTER | UIBUTTON_TOGGLE, 0, 0, CTRL_ICONFROMRES | CTRL_TOGGLEBUTTON, {0x0, 0x0}}, {ID_CBTN_KANAKEY, UIBUTTON_CENTER | UIBUTTON_VCENTER | UIBUTTON_TOGGLE, 0, 1, CTRL_ICONFROMRES | CTRL_TOGGLEBUTTON, {0x0, 0x0}}, {ID_CBTN_RESTORE, UIBUTTON_CENTER | UIBUTTON_VCENTER, 1, 0, CTRL_USEMARLETT | CTRL_DISABLEONWINLOGON, {0x0032, 0x0000}}, {ID_CBTN_EXTMENU, UIBUTTON_CENTER | UIBUTTON_VCENTER, 1, 1, CTRL_USEMARLETT | CTRL_DISABLEONWINLOGON, {0x0075, 0x0000}}, };
static int c_nColumnStart[] = {0, CX_COLUMN0, CX_COLUMN1};
//////////////////////////////////////////////////////////////////////////////
//
// APIs
//
//////////////////////////////////////////////////////////////////////////////
extern "C" BOOL WINAPI GetPopupTipbar(HWND hwndParent, DWORD dwFlags) { if ( !(dwFlags & UTB_GTI_WINLOGON) ) { TurnOffSpeechIfItsOn( ); }
return GetTipbarInternal(hwndParent, UTB_GTI_POPUP | dwFlags, NULL); }
BOOL GetTipbarInternal(HWND hwndParent, DWORD dwFlags, CDeskBand *pDeskBand) { DWORD dwSFSFlags; BOOL fPopup = (dwFlags & UTB_GTI_POPUP) ? TRUE : FALSE;
g_bWinLogon = (dwFlags & UTB_GTI_WINLOGON) ? TRUE : FALSE;
//
// MSAA support
//
InitTipbarAcc();
InitFromReg();
if (!g_bShowTipbar) return NULL;
//
// we don't have to create TrayIconWnd under explorer's desk band.
//
if (fPopup) { g_pTrayIconWnd = new CTrayIconWnd(); if (!g_pTrayIconWnd) return FALSE;
g_pTrayIconWnd->CreateWnd(); }
g_pTipbarWnd = new CTipbarWnd(fPopup ? g_dwWndStyle : g_dwChildWndStyle); if (!g_pTipbarWnd) return FALSE;
if (!g_pTipbarWnd->Initialize()) return FALSE;
g_pTipbarWnd->Init(!fPopup, pDeskBand);
g_pTipbarWnd->CreateWnd(hwndParent); SetWindowText(g_pTipbarWnd->GetWnd(), TF_FLOATINGLANGBAR_WNDTITLE);
DWORD dwPrevFlags = 0; if (!fPopup) { g_pTipbarWnd->GetLangBarMgr()->GetPrevShowFloatingStatus(&dwPrevFlags);
g_pTipbarWnd->GetLangBarMgr()->ShowFloating(TF_SFT_DESKBAND); }
g_pTipbarWnd->GetLangBarMgr()->GetShowFloatingStatus(&dwSFSFlags); g_pTipbarWnd->ShowFloating(dwSFSFlags);
//
// get the previous show floating status.
// if it does not have TF_SFT_DESKBAND, the floating toolbar
// was minimized.
// if it has TF_SFT_DESKBAND, exploere just started. Then we don't
// want to adjust the deskband and use the default size.
// (Explorer remembers the position of the previous logon.)
//
if (!fPopup && (dwPrevFlags & TF_SFT_DESKBAND)) g_pTipbarWnd->SetDeskbandSizeAdjusted();
g_hwndParent = hwndParent;
return TRUE; }
extern "C" void WINAPI ClosePopupTipbar() { if (g_fInClosePopupTipbar) return;
g_fInClosePopupTipbar = TRUE;
if (g_pTipbarWnd) { g_pTipbarWnd->ClearDeskBandPointer(); g_pTipbarWnd->DestroyWnd(); g_pTipbarWnd->Release(); g_pTipbarWnd = NULL; }
if (g_pTrayIconWnd) { g_pTrayIconWnd->DestroyWnd(); delete g_pTrayIconWnd; g_pTrayIconWnd = NULL; }
UninitSkipRedrawHKLArray();
g_fInClosePopupTipbar = FALSE; }
//////////////////////////////////////////////////////////////////////////////
//
// misc func
//
//////////////////////////////////////////////////////////////////////////////
extern "C" HRESULT WINAPI TF_GetGlobalCompartment(ITfCompartmentMgr **pCompMgr);
//+---------------------------------------------------------------------------
//
// GetCompartment
//
//----------------------------------------------------------------------------
HRESULT GetGlobalCompartment(REFGUID rguidComp, ITfCompartment **ppComp) { HRESULT hr = E_FAIL; ITfCompartmentMgr *pCompMgr = NULL;
if (FAILED(hr = TF_GetGlobalCompartment(&pCompMgr))) { Assert(0); goto Exit; }
if (SUCCEEDED(hr) && pCompMgr) { hr = pCompMgr->GetCompartment(rguidComp, ppComp); pCompMgr->Release(); } else hr = E_FAIL;
Exit: return hr; }
//+---------------------------------------------------------------------------
//
// SetCompartmentDWORD
//
//----------------------------------------------------------------------------
HRESULT SetGlobalCompartmentDWORD(REFGUID rguidComp, DWORD dw) { HRESULT hr; ITfCompartment *pComp; VARIANT var;
if (SUCCEEDED(hr = GetGlobalCompartment(rguidComp, &pComp))) { var.vt = VT_I4; var.lVal = dw; hr = pComp->SetValue(0, &var); pComp->Release(); } return hr; }
//+---------------------------------------------------------------------------
//
// GetGlobalCompartmentDWORD
//
//----------------------------------------------------------------------------
HRESULT GetGlobalCompartmentDWORD(REFGUID rguidComp, DWORD *pdw) { HRESULT hr; ITfCompartment *pComp; VARIANT var;
*pdw = 0; if (SUCCEEDED(hr = GetGlobalCompartment(rguidComp, &pComp))) { if ((hr = pComp->GetValue(&var)) == S_OK) { Assert(var.vt == VT_I4); *pdw = var.lVal; } pComp->Release(); }
return hr; }
//+---------------------------------------------------------------------------
//
// TurnOffSpeechIfItsOn
//
//----------------------------------------------------------------------------
void TurnOffSpeechIfItsOn() { // turn off the mic here only if someone set speech on
DWORD dw = 0; HRESULT hr = GetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, &dw); if (SUCCEEDED(hr) && dw > 0) { SetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0); } }
//+---------------------------------------------------------------------------
//
// InitSkipRedrawHKLArray
//
//+---------------------------------------------------------------------------
void InitSkipRedrawHKLArray() { CMyRegKey key; HKL *phkl;
Assert(!g_prghklSkipRedrawing); g_prghklSkipRedrawing = new CStructArray<HKL>; if (!g_prghklSkipRedrawing) return;
if (IsOnNT51()) { phkl = g_prghklSkipRedrawing->Append(1); if (phkl) *phkl = (HKL)IntToPtr(0xe0010411); }
if (key.Open(HKEY_LOCAL_MACHINE, c_szSkipRedrawHKL, KEY_READ) == S_OK) { char szValue[255]; DWORD dwIndex = 0; while (key.EnumValue(dwIndex, szValue, ARRAYSIZE(szValue)) == S_OK) { if ((szValue[0] == '0') && ((szValue[1] == 'X') || (szValue[1] == 'x'))) { phkl = g_prghklSkipRedrawing->Append(1); if (phkl) *phkl = (HKL)IntToPtr(AsciiToNum(&szValue[2])); } dwIndex++; } } }
//+---------------------------------------------------------------------------
//
// UninitSkipRedrawHKLArray
//
//+---------------------------------------------------------------------------
void UninitSkipRedrawHKLArray() { if (!g_prghklSkipRedrawing) return;
delete g_prghklSkipRedrawing; g_prghklSkipRedrawing = NULL; }
//+---------------------------------------------------------------------------
//
// IsSkipRedrawHKL
//
//+---------------------------------------------------------------------------
BOOL IsSkipRedrawHKL(HKL hkl) { int i;
if (0x0411 != LANGID(LOWORD(HandleToLong(hkl)))) return FALSE;
if (!g_prghklSkipRedrawing) return FALSE;
for (i = 0; i < g_prghklSkipRedrawing->Count(); i++) { HKL *phkl = g_prghklSkipRedrawing->GetPtr(i); if (phkl && (*phkl == hkl)) return TRUE; }
return FALSE; }
//+---------------------------------------------------------------------------
//
// InitFromReg
//
//+---------------------------------------------------------------------------
BOOL InitFromReg() { CMyRegKey key; CMyRegKey keyUTB; DWORD dwValue; LANGID langID = 0;
if (key.Open(HKEY_CURRENT_USER, c_szCicKey, KEY_READ) == S_OK) { if (key.QueryValue(dwValue, c_szShowTipbar) == S_OK) g_bShowTipbar = dwValue ? TRUE : FALSE; }
if (keyUTB.Open(HKEY_CURRENT_USER, c_szUTBKey, KEY_READ) == S_OK) { if (keyUTB.QueryValue(dwValue, c_szShowDebugMenu) == S_OK) g_bShowDebugMenu = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szNewLook) == S_OK) g_bNewLook = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szIntelliSense) == S_OK) g_bIntelliSense = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szShowCloseMenu) == S_OK) g_bShowCloseMenu = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szTimeOutNonIntentional) == S_OK) g_uTimeOutNonIntentional = dwValue * 1000;
if (keyUTB.QueryValue(dwValue, c_szTimeOutIntentional) == S_OK) { g_uTimeOutIntentional = dwValue * 1000; g_uTimeOutMax = g_uTimeOutIntentional * 6; }
if (keyUTB.QueryValue(dwValue, c_szShowMinimizedBalloon) == S_OK) g_bShowMinimizedBalloon = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szLeft) == S_OK) g_nLeft = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTop) == S_OK) g_nTop = dwValue;
if (keyUTB.QueryValue(dwValue, c_szExcludeCaptionButtons) == S_OK) g_bExcludeCaptionButtons = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szShowShadow) == S_OK) g_bShowShadow = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szTaskbarTheme) == S_OK) g_fTaskbarTheme = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szVertical) == S_OK) g_fVertical = dwValue ? TRUE : FALSE;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseSTUBSTART) == S_OK) g_uTimerElapseSTUBSTART = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseSTUBEND) == S_OK) g_uTimerElapseSTUBEND = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseBACKTOALPHA) == S_OK) g_uTimerElapseBACKTOALPHA = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseONTHREADITEMCHANGE) == S_OK) g_uTimerElapseONTHREADITEMCHANGE = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseSETWINDOWPOS) == S_OK) g_uTimerElapseSETWINDOWPOS = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseONUPDATECALLED) == S_OK) g_uTimerElapseONUPDATECALLED = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseSYSCOLORCHANGED) == S_OK) g_uTimerElapseSYSCOLORCHANGED = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseDISPLAYCHANGE) == S_OK) g_uTimerElapseDISPLAYCHANGE = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseUPDATEUI) == S_OK) g_uTimerElapseUPDATEUI = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseSHOWWINDOW) == S_OK) g_uTimerElapseSHOWWINDOW = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseMOVETOTRAY) == S_OK) g_uTimerElapseMOVETOTRAY = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseTRAYWNDONDELAYMSG) == S_OK) g_uTimerElapseTRAYWNDONDELAYMSG = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseDOACCDEFAULTACTION) == S_OK) g_uTimerElapseDOACCDEFAULTACTION = dwValue;
if (keyUTB.QueryValue(dwValue, c_szTimerElapseENSUREFOCUS) == S_OK) g_uTimerElapseENSUREFOCUS = dwValue;
if (IsOnNT51() && keyUTB.QueryValue(dwValue, c_szShowDeskBand) == S_OK) g_bShowDeskBand = dwValue ? TRUE : FALSE;
if (IsOnNT51() && keyUTB.QueryValue(dwValue, c_szTimerElapseSHOWDESKBAND) == S_OK) g_uTimerElapseSHOWDESKBAND = dwValue; }
InitSkipRedrawHKLArray(); if (g_bNewLook) { g_dwWndStyle = UIWINDOW_TOPMOST | // UIWINDOW_WSDLGFRAME |
UIWINDOW_HASTOOLTIP | UIWINDOW_HABITATINWORKAREA | UIWINDOW_OFC10TOOLBAR | UIWINDOW_TOOLWINDOW;
if (IsOnNT51()) { g_dwWndStyle &= ~UIWINDOW_OFC10TOOLBAR; g_dwWndStyle |= UIWINDOW_WHISTLERLOOK; // g_dwWndStyle |= UIWINDOW_WSBORDER;
}
if (g_bShowShadow) g_dwWndStyle |= UIWINDOW_HASSHADOW;
g_dwMenuStyle = UIWINDOW_TOPMOST | UIWINDOW_TOOLWINDOW | UIWINDOW_OFC10MENU | UIWINDOW_HASSHADOW | UIWINDOW_HABITATINSCREEN; } else { g_dwWndStyle = UIWINDOW_TOPMOST | UIWINDOW_HASTOOLTIP | UIWINDOW_WSDLGFRAME | UIWINDOW_HABITATINWORKAREA; g_dwMenuStyle = UIWINDOW_TOPMOST | UIWINDOW_WSDLGFRAME | UIWINDOW_HABITATINSCREEN; }
g_dwChildWndStyle = UIWINDOW_CHILDWND;
if (IsOnNT51()) { g_dwChildWndStyle |= UIWINDOW_WHISTLERLOOK | UIWINDOW_HASTOOLTIP | UIWINDOW_NOMOUSEMSGFROMSETCURSOR; }
langID = GetPlatformResourceLangID(); if (PRIMARYLANGID(langID) == LANG_ARABIC || PRIMARYLANGID(langID) == LANG_HEBREW) { g_dwWndStyle |= UIWINDOW_LAYOUTRTL; g_dwChildWndStyle |= UIWINDOW_LAYOUTRTL; g_dwMenuStyle |= UIWINDOW_LAYOUTRTL; g_fRTL = TRUE; }
return TRUE; }
//+---------------------------------------------------------------------------
//
// GetTopLevelWindow
//
//+---------------------------------------------------------------------------
HWND GetTopLevelWindow(HWND hwnd) { HWND hwndT,hwndRet; HWND hwndDsktop = GetDesktopWindow();
hwndT = hwndRet = hwnd;
while (hwndT && hwndT != hwndDsktop) { HWND hwndT0; hwndRet = hwndT; hwndT0 = GetParent(hwndT);
if (IsOn98() && !hwndT0) { //
// GetLastActivePopup() returns hwnd->hwndLastActive.
// But top level owner's hwndLastActive is used.
// We need to find a top level owner.
//
hwndT0 = GetWindow(hwndT, GW_OWNER); } hwndT = hwndT0; }
return(hwndRet); }
//+---------------------------------------------------------------------------
//
// MyWaitForInputIdle
//
//+---------------------------------------------------------------------------
#define UTB_INPUTIDLETIMEOUT 2000
DWORD MyWaitForInputIdle(DWORD dwThreadId, DWORD dwTimeOut) { DWORD dwRet = -1; DWORD dwProcessId = 0; DWORD dwThreadFlags;
if (g_pTipbarWnd && g_pTipbarWnd->IsSFDeskband()) { //
// Skip it on the Deskband that is belong to Explorer process.
//
return 0; }
//
// If the target thread is in marshaling call, we can behave as it's busy.
//
if (TF_IsInMarshaling(dwThreadId)) return WAIT_TIMEOUT;
if (TF_GetThreadFlags(dwThreadId, &dwThreadFlags, &dwProcessId, NULL) && dwProcessId) { dwRet = 0;
if (IsOnNT() && Is16bitThread(dwProcessId, dwThreadId)) { //
// we need to do something here to detect 16bit idle.
//
} else if (IsOnNT() || !(dwThreadFlags & TLF_NOWAITFORINPUTIDLEONWIN9X)) { #if 0
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); if (hProcess) { dwRet = WaitForInputIdle(hProcess, dwTimeOut); CloseHandle(hProcess); } else dwRet = -1; #else
dwRet = TF_CheckThreadInputIdle(dwThreadId, dwTimeOut); #endif
} }
return dwRet; }
//+---------------------------------------------------------------------------
//
// ClearMsgQueue
//
//+---------------------------------------------------------------------------
void ClearMsgQueue() { MSG msg; ULONG ulQuitCode; BOOL fQuitReceived = FALSE; while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD)) { if (msg.message == WM_QUIT) { ulQuitCode = (ULONG)(msg.wParam); fQuitReceived = TRUE; }
DispatchMessage(&msg); }
if (fQuitReceived) PostQuitMessage(ulQuitCode); }
//+---------------------------------------------------------------------------
//
// IsFullScreenSize
//
//+---------------------------------------------------------------------------
BOOL IsFullScreenSize(HWND hwnd) { RECT rc; GetWindowRect(hwnd, &rc); if ((rc.left <= 0) && (rc.top <= 0)&& (rc.right >= GetSystemMetrics(SM_CXFULLSCREEN)) && (rc.bottom >= GetSystemMetrics(SM_CYFULLSCREEN))) { return TRUE; } return FALSE; }
//+---------------------------------------------------------------------------
//
// InitUniqueString
//
//----------------------------------------------------------------------------
BOOL GetUserSIDString(DWORD dwProcessId, char *pch, UINT cch) { HANDLE hToken = NULL; char *pszStringSid = NULL; HANDLE hProcess;
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
if (hProcess) OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
if (hToken) { DWORD dwReturnLength = 0; void *pvUserBuffer = NULL;
GetTokenInformation(hToken, TokenUser, NULL, 0, &dwReturnLength);
pvUserBuffer = cicMemAllocClear(dwReturnLength); if (pvUserBuffer && GetTokenInformation(hToken, TokenUser, pvUserBuffer, dwReturnLength, &dwReturnLength)) { if (!ConvertSidToStringSid(((TOKEN_USER*)(pvUserBuffer))->User.Sid, &pszStringSid)) { if (pszStringSid) LocalFree(pszStringSid);
pszStringSid = NULL; }
}
if (pvUserBuffer) { cicMemFree(pvUserBuffer); }
CloseHandle(hToken); }
if (hProcess) CloseHandle(hProcess);
if (pszStringSid) { StringCchCopy(pch, cch, pszStringSid); LocalFree(pszStringSid); return TRUE; }
*pch = '\0'; return FALSE; }
//+---------------------------------------------------------------------------
//
// InitCurrentProcessSid
//
//+---------------------------------------------------------------------------
BOOL g_fSidInit = FALSE; char g_szSid[UNLEN + 1];
BOOL InitCurrentProcessSid() { if (g_fSidInit) return TRUE;
if (GetUserSIDString(GetCurrentProcessId(), g_szSid, ARRAYSIZE(g_szSid))) g_fSidInit = TRUE;
return g_fSidInit; }
//+---------------------------------------------------------------------------
//
// IsVisibleWindowInDesktop()
//
//+---------------------------------------------------------------------------
BOOL CALLBACK EnumVisibleWindowProc(HWND hwnd, LPARAM lParam) { DWORD dwProcessId;
if (!GetWindowThreadProcessId(hwnd, &dwProcessId)) dwProcessId = 0;
//
// we're not interested in ctfmon's process window.
//
if (g_pTipbarWnd && !g_pTipbarWnd->IsInDeskBand()) if (dwProcessId == GetCurrentProcessId()) return TRUE;
if (IsWindowVisible(hwnd)) { if (g_fSidInit) { //
// if the process is owned by different user, we skip it.
//
char szSid[UNLEN + 1]; GetUserSIDString(dwProcessId, szSid, ARRAYSIZE(szSid)); if (lstrcmp(szSid, g_szSid)) return TRUE; }
BOOL *pfFound = (BOOL *)lParam; *pfFound = TRUE; return FALSE; }
return TRUE; }
BOOL IsVisibleWindowInDesktop() { BOOL fFound = FALSE;
InitCurrentProcessSid(); EnumWindows(EnumVisibleWindowProc, (LPARAM)&fFound); return fFound; }
//////////////////////////////////////////////////////////////////////////////
//
// CTipbarGripper
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// CTipbarGripper::ctor
//
//----------------------------------------------------------------------------
CTipbarGripper::CTipbarGripper(CTipbarWnd *pTipbarWnd, RECT *prc, DWORD dwStyle) : CUIFGripper( pTipbarWnd, prc, dwStyle) { _pTipbarWnd = pTipbarWnd; _fInMenu = FALSE; }
//+---------------------------------------------------------------------------
//
// CTipbarGripper::OnSetCursor
//
//----------------------------------------------------------------------------
BOOL CTipbarGripper::OnSetCursor(UINT uMsg, POINT pt) { if (!_fInMenu) return CUIFGripper::OnSetCursor(uMsg, pt);
return FALSE; }
//+---------------------------------------------------------------------------
//
// CTipbarGripper::OnRButtonUp
//
//----------------------------------------------------------------------------
void CTipbarGripper::OnRButtonUp(POINT pt) { if (!g_bShowDebugMenu) return;
HMENU hMenu = CreatePopupMenu(); if (!hMenu) return;
SetCursor(LoadCursor(NULL, IDC_ARROW));
ClientToScreen(_pTipbarWnd->GetWnd(), &pt);
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING, IDM_CLOSECICLOAD, "Close cicload");
#ifdef DEBUG
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING, IDM_BREAK, CRStr(IDS_BREAK)); #endif
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING, IDCANCEL, CRStr(IDS_CANCEL));
_fInMenu = TRUE; int nRet = TrackPopupMenuEx(hMenu, TPM_LEFTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, _pTipbarWnd->GetWnd(), NULL); _fInMenu = FALSE;
DestroyMenu(hMenu);
switch (nRet) { case IDM_CLOSECICLOAD: { _pTipbarWnd->UnInit(); if (IsWindow(g_hwndParent)) DestroyWindow(g_hwndParent); MSG msg; while(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE | PM_NOYIELD)); PostQuitMessage(0); } break;
#ifdef DEBUG
case IDM_BREAK: DebugBreak(); break; #endif
}
}
//+---------------------------------------------------------------------------
//
// CTipbarGripper::OnLButtonUp
//
//----------------------------------------------------------------------------
void CTipbarGripper::OnLButtonUp(POINT pt) { _pTipbarWnd->RestoreFromStub();
//
// Mouse Drag/Drop from floating language bar to deskband.
//
if (IsOnNT51()) { APPBARDATA abd; RECT rcTrayWnd;
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = FindWindow(TEXT(WNDCLASS_TRAYNOTIFY), NULL);
if (SHAppBarMessage(ABM_GETTASKBARPOS, &abd)) { POINT ptCursor;
rcTrayWnd = abd.rc;
GetCursorPos(&ptCursor);
if ((ptCursor.x >= rcTrayWnd.left && ptCursor.x <= rcTrayWnd.right) && (ptCursor.y >= rcTrayWnd.top && ptCursor.y <= rcTrayWnd.bottom)) { if (g_pTipbarWnd) g_pTipbarWnd->GetLangBarMgr()->ShowFloating(TF_SFT_DESKBAND | TF_SFT_EXTRAICONSONMINIMIZED);
} } }
CUIFGripper::OnLButtonUp(pt);
//
// CUIFGripper::OnLButonUp() calls MoveWindow.
// Now we update pos flags of TipbarWnd.
//
_pTipbarWnd->UpdatePosFlags(); }
//////////////////////////////////////////////////////////////////////////////
//
// CTipbarWnd
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// IUnknown
//
//----------------------------------------------------------------------------
STDAPI CTipbarWnd::QueryInterface(REFIID riid, void **ppvObj) { *ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfLangBarEventSink)) { *ppvObj = SAFECAST(this, ITfLangBarEventSink *); } else if (IsEqualIID(riid, IID_ITfLangBarEventSink_P)) { *ppvObj = SAFECAST(this, ITfLangBarEventSink_P *); }
if (*ppvObj) { AddRef(); return S_OK; }
return E_NOINTERFACE; }
STDAPI_(ULONG) CTipbarWnd::AddRef() { return ++_cRef; }
STDAPI_(ULONG) CTipbarWnd::Release() { _cRef--; Assert(_cRef >= 0);
if (_cRef == 0) { delete this; return 0; }
return _cRef; }
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CTipbarWnd::CTipbarWnd(DWORD dwStyle) : CUIFWindow(g_hInst, dwStyle) { Dbg_MemSetThisName(TEXT("CTipbarWnd")); POINT pt; RECT rc;
pt.x = g_nLeft; pt.y = g_nTop; CUIGetScreenRect(pt, &rc); if (!PtInRect(&rc, pt)) { if (IsOnFE()) { RECT rcWork; SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 ); g_nLeft = rcWork.right; g_nTop = rcWork.bottom; } else if (g_fRTL) { g_nLeft = GetSystemMetrics(SM_CXSIZE) * 3; g_nTop = 0; } else { g_nLeft = GetSystemMetrics(SM_CXSCREEN) - (GetSystemMetrics(SM_CXSIZE) * 3); g_nTop = 0; } } Move(g_nLeft, g_nTop, STATUSWND_WIDTH, STATUSWND_HEIGHT);
//
// initialize Pos flags after calling Move().
//
UpdatePosFlags();
_fShowText = FALSE; _fInStub = FALSE;
_hfontMarlett = CreateFont(8, 8, 0, 0, 400, FALSE, FALSE, FALSE, SYMBOL_CHARSET, 0, 0, 0, 0, "Marlett");
ITfLangBarMgr *putb; if (SUCCEEDED(TF_CreateLangBarMgr(&putb)) && putb) { putb->QueryInterface(IID_ITfLangBarMgr_P, (void **)&_putb);
putb->Release(); }
if (dwStyle & UIWINDOW_WHISTLERLOOK) { if (g_fTaskbarTheme) SetActiveTheme(L"TASKBAR", TBP_BACKGROUNDBOTTOM, TS_NORMAL ); else SetActiveTheme(L"REBAR", 0, TS_NORMAL ); }
SetVertical(g_fVertical);
_cRef = 1; }
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CTipbarWnd::~CTipbarWnd() { Assert(!_pModalMenu);
UnInit();
DeleteObject(_hfontMarlett); if (_hfontVert) DeleteObject(_hfontVert);
TFUninitLib_Thread(&g_libTLS); }
//+---------------------------------------------------------------------------
//
// UnInit
//
//----------------------------------------------------------------------------
void CTipbarWnd::UnInit() { SetFocusThread(NULL);
int i; for (i = 0; i < _rgThread.Count(); i++) { CTipbarThread *pThread = _rgThread.Get(i); if (!pThread) continue;
pThread->_UninitItemList(TRUE); pThread->Disconnect(); pThread->_Release(); } _rgThread.Clear();
if (_putb) _putb->UnadviseEventSink(_dwlbimCookie);
SafeReleaseClear(_putb); }
//+---------------------------------------------------------------------------
//
// SetFocus
//
//----------------------------------------------------------------------------
HRESULT CTipbarWnd::OnSetFocus(DWORD dwThreadId) { BOOL fNewThread = FALSE; CTipbarThread *pThread; CTipbarThread *pPrevFocusThread; BOOL fWasInFullScreen = _fInFullScreen; HWND hwndFore = GetForegroundWindow(); DWORD dwThreadIdFore = GetWindowThreadProcessId(hwndFore, NULL); HRESULT hr; CTipbarThread *pThreadPrev = NULL; BOOL fSkipRedrawOnNoItem = FALSE;
TraceMsg(TF_FUNC, "focusnfy OnSetFocus %x ", dwThreadId);
//
// if the toolbar is being terminated, do nothing.
//
if (_fTerminating) return S_OK;
if (_dwThreadIdWaitNotify && (_dwThreadIdWaitNotify != dwThreadId)) return S_OK; //
// If this MSUTB is in ctfmon.exe and the langbar status is in Deskband,
// this meutb should stop wroking.
//
if (!_fInDeskBand && IsSFDeskband()) return S_OK;
if (!IsWindow(GetWnd())) return E_FAIL;
StartPendingUpdateUI(); AddRef();
if (!_fInDeskBand && dwThreadIdFore) { BOOL fScreenSaverRunning = FALSE;
if (IsOnNT5() || IsOn98()) { SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &fScreenSaverRunning, FALSE); }
if (IsFullScreenWindow(hwndFore) || fScreenSaverRunning) { if (GetWindowLongPtr(GetWnd(), GWL_STYLE) & WS_VISIBLE) { Show(FALSE); _fInFullScreen = TRUE; _dwPrevTBStatus = _dwSFTFlags; } } else if (fWasInFullScreen) { Show(TRUE); _fInFullScreen = FALSE;
//
// Bug#500507 - Need to recover language bar show status value.
//
if (!(_dwPrevTBStatus & TF_SFT_DESKBAND)) GetLangBarMgr()->ShowFloating(_dwPrevTBStatus); } }
KillTimer(TIPWND_TIMER_SETWINDOWPOS); SetTimer(TIPWND_TIMER_SETWINDOWPOS, g_uTimerElapseSETWINDOWPOS);
pThread = _FindThread(dwThreadId); if (_pFocusThread && (pThread == _pFocusThread)) { hr = S_OK; goto Exit; }
//
// keep the current focus thread.
//
pPrevFocusThread = _pFocusThread;
CancelMenu();
if (!pThread) { pThread = _CreateThread(dwThreadId); if (!pThread) { hr = E_FAIL; goto Exit; }
fNewThread = TRUE; }
//
// focus has been change during creating pThread.
// we don't have to do anything now.
//
if (_pFocusThread && (pPrevFocusThread != _pFocusThread)) { hr = S_OK; goto Exit; }
if (_pFocusThread) { _pFocusThread->RemoveUIObjs(); }
SetFocusThread(pThread);
if (pThread) { Assert(pThread == _pFocusThread); BOOL fItemChanged = pThread->_fItemChanged;
//
// addref to increment the refcount.
//
pThread->_AddRef();
hr = S_OK; if (fItemChanged) hr = pThread->_UninitItemList(TRUE);
if (SUCCEEDED(hr)) { pThread->RemoveUIObjs();
if (fItemChanged) pThread->InitItemList(); }
//
// UninitItemList and InitItemList make marshaling calls.
// we need to check _pFocusThread again.
//
if (pThread == _pFocusThread) { pThread->LocateItems(); pThread->AddUIObjs();
if (fNewThread || fItemChanged) { if (!pThread->UpdateItems()) { pThread->RemoveUIObjs(); SetFocusThread(NULL); } } else if (pThread->IsDirtyItem()) { //
// this thread has a update dirty item. Need to update now.
// We got OnUpdate call while it was background thread.
//
KillTimer(TIPWND_TIMER_ONUPDATECALLED); SetTimer(TIPWND_TIMER_ONUPDATECALLED, g_uTimerElapseONUPDATECALLED); } }
fSkipRedrawOnNoItem = pThread->_fSkipRedrawOnNoItem; //
// release to decrement the refcount.
//
pThread->_Release(); }
_ctrlbtnHolder.EnableBtns();
if (_fShowTrayIcon) { KillTimer(TIPWND_TIMER_MOVETOTRAY); SetTimer(TIPWND_TIMER_MOVETOTRAY, g_uTimerElapseMOVETOTRAY); }
//
// Cic#4712
//
if (_dwThreadItemChangedForTimer != dwThreadId) { KillOnTheadItemChangeTimer(); }
hr = S_OK;
Exit: if (fSkipRedrawOnNoItem) KillTimer(TIPWND_TIMER_UPDATEUI);
EndPendingUpdateUI(); Release(); return hr; }
//+---------------------------------------------------------------------------
//
// IsFullScreenWindow
//
//+---------------------------------------------------------------------------
BOOL CTipbarWnd::IsFullScreenWindow(HWND hwnd) { ULONG_PTR dwStyle; ULONG_PTR dwExStyle;
dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE); if (!(dwStyle & WS_VISIBLE)) return FALSE;
if (dwStyle & WS_CAPTION) return FALSE;
dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
#ifdef OLD_FULLSCREENDETECTION
if (dwExStyle & WS_EX_TOOLWINDOW) return FALSE;
if (!IsZoomed(hwnd) && !(dwExStyle & WS_EX_LAYERED)) { if (IsFullScreenSize(hwnd)) return TRUE; } #else
if (dwExStyle & WS_EX_LAYERED) return FALSE;
//
// #376691
//
// the full screen mode of Windows Media Player uses WS_EX_TOOLWINDOW style.
// we need to check if it is fullscreen window or not.
//
if (dwExStyle & WS_EX_TOOLWINDOW) { if (hwnd == shellwnd.GetWndProgman()) return FALSE; }
//
// And some shell fullscreen window (such as slide show)
// has "mazimized" status. So we don't want to check IsZoomed().
//
// Thus any application without caption covers the screen won't have a
// floating toolbar.
//
if (IsFullScreenSize(hwnd)) return TRUE; #endif
return FALSE; }
//+---------------------------------------------------------------------------
//
// SetFocusThread
//
//----------------------------------------------------------------------------
HRESULT CTipbarWnd::SetFocusThread(CTipbarThread *pThread) { if (pThread == _pFocusThread) return S_OK;
DWORD dwThreadId = GetCurrentThreadId();
DestroyOverScreenSizeBalloon();
if (_pFocusThread) { _pFocusThread->SetFocus(FALSE); AttachThreadInput(dwThreadId, _pFocusThread->_dwThreadId, FALSE); }
_pFocusThread = pThread;
//
// we will attach the focus thread input into this thread when
// when we need (mouse message comes and any other case?).
//
_fFocusAttached = FALSE;
if (_pFocusThread) { _pFocusThread->SetFocus(TRUE); }
if (!_pFocusThread) { if (!IsVisibleWindowInDesktop()) { // this is a hack to shut down ctfmon.exe when we're in a terminal server session
// and the main app has shutdown and no shell is running -- terminal server won't
// end the session as long as ctfmon is running which effectively locks the machine.
// See cicero bug 4235.
//
// Issue: got some more info from the terminal server team, another cleaner fix:
//
// Anyway if you need to put something in "not wait for" list, just add a value to
// "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\SysProcs" key.
// Name of the value should be equal to a name of executable, type is REG_DWORD, value is 0.
if (!_fInDeskBand) PostQuitMessage(0); else if (_pDeskBand) _pDeskBand->DeleteBand();
} } return S_OK; }
//+---------------------------------------------------------------------------
//
// AttachFocusThread
//
//----------------------------------------------------------------------------
HRESULT CTipbarWnd::AttachFocusThread() { if (_fFocusAttached) return TRUE;
//
// Attach the focus thread when mouse message is coming. Since this
// toolbar window is disabled window, using different input focus
// causes unexpected focus change.
//
if (_pFocusThread) { DWORD dwThreadId = GetCurrentThreadId(); AttachThreadInput(dwThreadId, _pFocusThread->_dwThreadId, TRUE); _fFocusAttached = TRUE; }
return S_OK; }
//+---------------------------------------------------------------------------
//
// ThreadTerminate
//
//----------------------------------------------------------------------------
HRESULT CTipbarWnd::OnThreadTerminate(DWORD dwThreadId) { HRESULT hr;
StartPendingUpdateUI(); AddRef();
hr = OnThreadTerminateInternal(dwThreadId); if (!_pFocusThread) EnsureFocusThread();
EndPendingUpdateUI(); Release(); return hr; }
//+---------------------------------------------------------------------------
//
// OnThreadTerminateInternal
//
//----------------------------------------------------------------------------
HRESULT CTipbarWnd::OnThreadTerminateInternal(DWORD dwThreadId) { TraceMsg(TF_FUNC, "focusnfy OnThreadTerminate %x ", dwThreadId);
int i; for (i = 0; i < _rgThread.Count(); i++) { CTipbarThread *pThread = _rgThread.Get(i); if (!pThread) continue;
if (pThread->_dwThreadId == dwThreadId) { _rgThread.Remove(i, 1);
pThread->RemoveUIObjs();
CleanUpThreadPointer(pThread, FALSE);
pThread->_UninitItemList(TRUE); pThread->Disconnect(); pThread->_Release(); goto Exit; } }
Exit: return S_OK; }
//+---------------------------------------------------------------------------
//
// CleanUpThreadPointer
//
// This function make sure CTipbarWnd does not have pThread pointer any more.
//
//----------------------------------------------------------------------------
void CTipbarWnd::CleanUpThreadPointer(CTipbarThread *pThread, BOOL fCheckThreadArray) { Assert(pThread);
if (fCheckThreadArray) { int i; for (i = 0; i < _rgThread.Count(); i++) { if (pThread == _rgThread.Get(i)) { _rgThread.Remove(i, 1); break; } } }
if (pThread == _pFocusThread) SetFocusThread(NULL);
if (pThread == _pttModal) _pttModal = NULL;
if (pThread == _pThreadShowWindowAtTimer) _pThreadShowWindowAtTimer = NULL; }
//+---------------------------------------------------------------------------
//
// EnsureFocusThread
//
//----------------------------------------------------------------------------
void CTipbarWnd::EnsureFocusThread() { if (_pFocusThread) { Assert(0); return; }
if (_fTerminating) return;
if (_fInEnsureFocusThread) return;
_fInEnsureFocusThread = TRUE;
HWND hwndFore = GetForegroundWindow(); if (hwndFore) { DWORD dwThreadId = GetWindowThreadProcessId(hwndFore, NULL); if (dwThreadId) OnSetFocus(dwThreadId); }
_fInEnsureFocusThread = FALSE; }
//+---------------------------------------------------------------------------
//
// OnThreadItemChange
//
//----------------------------------------------------------------------------
HRESULT CTipbarWnd::OnThreadItemChange(DWORD dwThreadId) { CTipbarThread *pThread; TraceMsg(TF_FUNC, "focusnfy OnThreadItemChange %x ", dwThreadId);
//
// if the toolbar is being terminated, do nothing.
//
if (_fTerminating) return S_OK;
//
// If this MSUTB is in ctfmon.exe and the langbar status is in Deskband,
// this meutb should stop wroking.
//
if (!_fInDeskBand && IsSFDeskband()) return S_OK;
pThread = _FindThread(dwThreadId); if (!pThread) { #if 0
//
// Issue: #365434 - In the running of Deskband after just restart
// machine, this hit will disable the showing deskband.
//
if (!_pFocusThread) Show(FALSE); #endif
return S_OK; }
if ((_dwThreadIdWaitNotify && (_dwThreadIdWaitNotify != dwThreadId)) || (pThread != _pFocusThread)) { pThread->_fItemChanged = TRUE; return S_OK; }
KillOnTheadItemChangeTimer();
_dwThreadItemChangedForTimer = dwThreadId; KillTimer(TIPWND_TIMER_ONUPDATECALLED); SetTimer(TIPWND_TIMER_ONTHREADITEMCHANGE, g_uTimerElapseONTHREADITEMCHANGE); return S_OK; }
//+---------------------------------------------------------------------------
//
// OnThreadItemChange
//
//----------------------------------------------------------------------------
HRESULT CTipbarWnd::OnThreadItemChangeInternal(DWORD dwThreadId) { CTipbarThread *pThread; HRESULT hr = S_OK;
TraceMsg(TF_FUNC, "focusnfy OnThreadItemChangeInternal %x ", dwThreadId);
if (_dwThreadIdWaitNotify && (_dwThreadIdWaitNotify != dwThreadId)) return S_OK;
//
// If this MSUTB is in ctfmon.exe and the langbar status is in Deskband,
// this meutb should stop wroking.
//
if (!_fInDeskBand && IsSFDeskband()) return S_OK;
pThread = _FindThread(dwThreadId);
if (!pThread) return S_OK;
if (pThread != _pFocusThread) { pThread->_fItemChanged = TRUE; return hr; }
//
// Ok, dwThreadId has a focus now, we need immediate action to update
// langbar.
//
Assert(dwThreadId == pThread->_dwThreadId);
StartPendingUpdateUI();
//
// addref to increment the refcount.
//
pThread->_AddRef();
hr = pThread->_UninitItemList(TRUE);
if (SUCCEEDED(hr)) { pThread->RemoveUIObjs(); hr = pThread->InitItemList();
if (SUCCEEDED(hr)) { //
// UninitItemList and InitItemList make marshaling calls.
// we need to check _pFocusThread again.
//
if (pThread == _pFocusThread) { pThread->LocateItems(); pThread->AddUIObjs(); pThread->UpdateItems(); } } }
//
// release to decrement the refcount.
//
pThread->_Release();
//
// #366835
//
// We got an error for the focus thread. Marshalling stubs might been gone!
// Let's restart marshaling.
//
if (hr == RPC_E_CONNECTION_TERMINATED) { //
// Throw away lost marshalled interfaces.
//
OnThreadTerminateInternal(dwThreadId);
//
// OnSetFocus() will reacate CTipbarThread.
//
OnSetFocus(dwThreadId); }
_ctrlbtnHolder.EnableBtns();
// InvalidateRect(GetWnd(), NULL, TRUE);
if (_fShowTrayIcon) { KillTimer(TIPWND_TIMER_MOVETOTRAY); SetTimer(TIPWND_TIMER_MOVETOTRAY, g_uTimerElapseMOVETOTRAY); }
EndPendingUpdateUI(); return hr; }
//+---------------------------------------------------------------------------
//
// MoveToTray
//
//----------------------------------------------------------------------------
void CTipbarWnd::MoveToTray() { //
// we don't use NotyfTrayIcon on WinXP.
//
if (IsOnNT51()) return;
if (!g_pTrayIconWnd) return;
//
// Even if the floating toolbar setting is "minimized", we need to show
// it when explorer.exe is not running.
//
if (!g_pTrayIconWnd->GetNotifyWnd()) { Show(TRUE); return; }
if (_fShowTrayIcon) { if (_pFocusThread) { if (TF_IsInMarshaling(_pFocusThread->_dwThreadId)) { SetTimer(TIPWND_TIMER_MOVETOTRAY, g_uTimerElapseMOVETOTRAY); return; } } //
// we move to TrayIcon. Make sure the toolbar is hidden.
//
KillTimer(TIPWND_TIMER_SHOWWINDOW); Show(FALSE);
DestroyOverScreenSizeBalloon(); CTipbarItem *pItem = NULL; BOOL fIsKeyboardItemVisible = FALSE; CTipbarItem *pKeyboardItem = NULL; if (_pFocusThread) { if (_pFocusThread->IsConsole()) pItem = _pFocusThread->GetItem(GUID_LBI_INATITEM); else pItem = _pFocusThread->GetItem(GUID_LBI_CTRL);
if (pItem && !pItem->IsVisibleInToolbar()) pItem = NULL;
pKeyboardItem = _pFocusThread->GetItem(GUID_TFCAT_TIP_KEYBOARD); if (pKeyboardItem && !pKeyboardItem->IsInHiddenStatus()) fIsKeyboardItemVisible = TRUE; }
//
// we don't have to show UTB's Main Icon when
// - there is LBI_INATITEM or LBI_CTRL item.
// - there is a visible keyboard item.
//
g_pTrayIconWnd->SetMainIcon(pItem ? NULL : fIsKeyboardItemVisible ? NULL : GetFocusKeyboardLayout());
if (!g_pTrayIconWnd->_fShowExtraIcons) { DWORD dwRAIFlags = 0; if (pItem) dwRAIFlags |= TIW_RAI_LEAVELANGICON;
if (fIsKeyboardItemVisible) dwRAIFlags |= TIW_RAI_LEAVEKEYBOARDICON;
g_pTrayIconWnd->RemoveAllIcon(dwRAIFlags);
if (pItem) { pItem->MoveToTray(); } else if (fIsKeyboardItemVisible) { Assert(!!pKeyboardItem) pKeyboardItem->MoveToTray(); } } else if (_pFocusThread) { int i;
g_pTrayIconWnd->RemoveUnusedIcons(&_pFocusThread->_rgItem);
for (i = 0; i < _pFocusThread->_rgItem.Count(); i++) { if (TF_IsInMarshaling(_pFocusThread->_dwThreadId)) { SetTimer(TIPWND_TIMER_MOVETOTRAY, g_uTimerElapseMOVETOTRAY); return; }
pItem = _pFocusThread->_rgItem.Get(i); if (pItem) pItem->MoveToTray(); } } } } //+---------------------------------------------------------------------------
//
// OnModalInput
//
//----------------------------------------------------------------------------
STDAPI CTipbarWnd::OnModalInput(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_KEYDOWN: case WM_KEYUP: if (_pttModal) { Assert(_pModalMenu); Assert(_pttModal->_dwThreadId == dwThreadId); _pModalMenu->PostKey((uMsg == WM_KEYUP), wParam, lParam); } break;
case WM_NCLBUTTONDOWN: case WM_NCRBUTTONDOWN: case WM_NCMBUTTONDOWN: break;
case WM_NCLBUTTONUP: case WM_NCRBUTTONUP: case WM_NCMBUTTONUP: //
// Multi Monitor
//
// if the disable window is in the negative location of
// screen coordinate, wm_ncxx message is generated.
// (maybe this is not mm specific, since siable window does not
// get WM_NCHITTEST.)
//
// we just forward this message to modal menu window as a normal
// mouse message to simulate the mouse action.
//
if (_pttModal) { Assert(_pModalMenu); Assert(_pttModal->_dwThreadId == dwThreadId); HWND hwnd = _pModalMenu->GetWnd(); if (hwnd) { POINT pt; POINTSTOPOINT( pt, MAKEPOINTS( lParam ) ); ScreenToClient(hwnd, &pt); PostMessage(hwnd, uMsg + (WM_MOUSEMOVE - WM_NCMOUSEMOVE), wParam, MAKELPARAM(pt.x, pt.y)); } } break;
case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: break;
default: CancelMenu(); break; } return S_OK; }
//+---------------------------------------------------------------------------
//
// ShowFloating
//
//----------------------------------------------------------------------------
STDAPI CTipbarWnd::ShowFloating(DWORD dwFlags) { if (_fInDeskBand) { _dwSFTFlags = dwFlags;
if (dwFlags & TF_SFT_DESKBAND) { //
// If we don't have _pFocusThread, the empty langbar is shown.
// Try to get the thread of the foreground window. This may not
// work correctly because the actual focus could be different
// from the thread of the foreground window.
//
if (!_pFocusThread) { KillTimer(TIPWND_TIMER_ENSUREFOCUS); SetTimer(TIPWND_TIMER_ENSUREFOCUS, g_uTimerElapseENSUREFOCUS); }
//
// Update Extra icons changing options
//
KillTimer(TIPWND_TIMER_SYSCOLORCHANGED); SetTimer(TIPWND_TIMER_SYSCOLORCHANGED, g_uTimerElapseSYSCOLORCHANGED); }
if (dwFlags & TF_SFT_EXTRAICONSONMINIMIZED) { _fAddExtraIcon = TRUE; ClearDeskbandSizeAdjusted(); } else if (dwFlags & TF_SFT_NOEXTRAICONSONMINIMIZED) { _fAddExtraIcon = FALSE; ClearDeskbandSizeAdjusted(); }
return S_OK; } if (dwFlags & TF_SFT_SHOWNORMAL) { //
// we update the itemlist from registry now.
// something might be change during deskbanding.
//
_itemList.Load();
SetShowTrayIcon(FALSE);
//
// Call SetLangBar() before updating _dwSFTFlags.
//
SetLangBand(FALSE);
//
// Set SHOWNOARMAL flag before calling OnSetFocus().
//
_dwSFTFlags = TF_SFT_SHOWNORMAL;
//
// If we don't have _pFocusThread, the empty langbar is shown.
// Try to get the thread of the foreground window. This may not
// work correctly because the actual focus could be different
// from the thread of the foreground window.
//
if (!_pFocusThread) EnsureFocusThread();
Show(TRUE);
} else if (dwFlags & TF_SFT_DOCK) { //
// Call SetLangBar() before updating _dwSFTFlags.
//
SetLangBand(FALSE); _dwSFTFlags = TF_SFT_DOCK; } else if (dwFlags & TF_SFT_MINIMIZED) { SetShowTrayIcon(TRUE); KillTimer(TIPWND_TIMER_SHOWWINDOW); Show(FALSE);
//
// Call SetLangBar() before updating _dwSFTFlags.
//
SetLangBand(FALSE);
_dwSFTFlags = TF_SFT_MINIMIZED; } else if (dwFlags & TF_SFT_HIDDEN) { SetShowTrayIcon(FALSE); KillTimer(TIPWND_TIMER_SHOWWINDOW); Show(FALSE);
//
// Call SetLangBar() before updating _dwSFTFlags.
//
SetLangBand(FALSE); _dwSFTFlags = TF_SFT_HIDDEN;
TurnOffSpeechIfItsOn(); } else if (dwFlags & TF_SFT_DESKBAND) { SetShowTrayIcon(FALSE); KillTimer(TIPWND_TIMER_SHOWWINDOW); KillTimer(TIPWND_TIMER_SHOWDESKBAND); Show(FALSE);
//
// if the process of explorer belongs to different user, we don't
// set langband.
//
if (InitCurrentProcessSid()) { DWORD dwProcessIdTray; HWND hwndTray = shellwnd.GetWndTray(); GetWindowThreadProcessId(hwndTray, &dwProcessIdTray); if (dwProcessIdTray) { char szSid[UNLEN + 1]; GetUserSIDString(dwProcessIdTray, szSid, ARRAYSIZE(szSid)); if (lstrcmp(szSid, g_szSid)) return S_OK; } }
//
// Need to make sure adding the language bar menu on taskbar
//
SetRegisterLangBand(TRUE);
//
// BugBug#377897 - Always show the extra additional icons in case of
// single keyboard layout.
//
if (IsSFNoExtraIcon()) { if (IsSingleKeyboardLayout()) { GetLangBarMgr()->ShowFloating(TF_SFT_EXTRAICONSONMINIMIZED); } }
//
// Call SetLangBar() before updating _dwSFTFlags.
//
if (SetLangBand(TRUE)) _dwSFTFlags = TF_SFT_DESKBAND; else SetTimer(TIPWND_TIMER_SHOWDESKBAND, g_uTimerElapseSHOWDESKBAND); }
if (dwFlags & TF_SFT_NOTRANSPARENCY) { SetAlpha(255, FALSE); } else if (dwFlags & TF_SFT_LOWTRANSPARENCY) { SetAlpha(128, FALSE); } else if (dwFlags & TF_SFT_HIGHTRANSPARENCY) { SetAlpha(62, FALSE); }
if (dwFlags & TF_SFT_LABELS) { SetShowText(TRUE); } else if (dwFlags & TF_SFT_NOLABELS) { SetShowText(FALSE); }
if (dwFlags & TF_SFT_EXTRAICONSONMINIMIZED) { _fAddExtraIcon = TRUE;
if (g_pTrayIconWnd) { g_pTrayIconWnd->_fShowExtraIcons = TRUE; if (_fShowTrayIcon) SetShowTrayIcon(TRUE); } } else if (dwFlags & TF_SFT_NOEXTRAICONSONMINIMIZED) { _fAddExtraIcon = FALSE;
if (g_pTrayIconWnd) { g_pTrayIconWnd->_fShowExtraIcons = FALSE; if (_fShowTrayIcon) SetShowTrayIcon(TRUE); } }
return S_OK; }
//+---------------------------------------------------------------------------
//
// GetItemFloatingRect
//
//----------------------------------------------------------------------------
STDAPI CTipbarWnd::GetItemFloatingRect(DWORD dwThreadId, REFGUID rguid, RECT *prc) { HRESULT hr;
if (IsShowTrayIcon()) return E_UNEXPECTED;
if (!_pFocusThread) return E_FAIL;
if (_pFocusThread->_dwThreadId != dwThreadId) return E_FAIL;
hr = E_FAIL;
int i; for (i = 0; i < _pFocusThread->_rgItem.Count(); i++) { CTipbarItem *pItem = _pFocusThread->_rgItem.Get(i); if (!pItem) continue;
if (pItem->IsVisibleInToolbar() && IsEqualGUID(*pItem->GetGUID(), rguid)) { pItem->GetScreenRect(prc); hr = S_OK; break; } } return hr; }
//+---------------------------------------------------------------------------
//
// OnLangBarUpdate
//
//----------------------------------------------------------------------------
STDAPI CTipbarWnd::OnLangBarUpdate(UINT uUpdate, LPARAM lParam) { switch (uUpdate) { case TF_LBU_CAPSKANAKEY: _ctrlbtnHolder.UpdateCapsKanaState(lParam); break;
case TF_LBU_NTCONSOLELANGCHANGE: if (_pFocusThread && _pFocusThread->IsConsole()) { CTipbarItem *pItem = _pFocusThread->GetItem(GUID_LBI_INATITEM); if (pItem) { CLBarInatItem *plbi = (CLBarInatItem *)pItem->GetNotifyUI();
HKL hkl = (HKL)lParam; if (!hkl) { //
// #403714
//
// Don't know when GetKeyboardLayout() starts returning
// the correct value for the Console thread id.
// Want to use another timer to have an interval but
// having lots of code and path is not good idea at
// this time (just before releasing WinXP).
// Calling Sleep() with small interval looks the
// safest way to solve this problem.
//
Sleep(50); hkl = GetKeyboardLayout(_pFocusThread->_dwThreadId); }
plbi->SetHKL(hkl); if (g_pTrayIconWnd) { g_pTrayIconWnd->SetMainIcon(NULL); } } _pFocusThread->UpdateItems(); } break; } return S_OK; }
//+---------------------------------------------------------------------------
//
// FindAndCreateThread
//
//----------------------------------------------------------------------------
CTipbarThread *CTipbarWnd::_FindThread(DWORD dwThreadId) { int i; for (i = 0; i < _rgThread.Count(); i++) { CTipbarThread *pThread = _rgThread.Get(i); if (!pThread) continue;
if (pThread->_dwThreadId == dwThreadId) { DWORD dwProcessId; DWORD dwThreadFlags; DWORD dwTickTime;
//
// TF_GetThreadFlag() does not work corrently on
// winlogon desktop..
//
if (g_bWinLogon) break;
TF_GetThreadFlags(dwThreadId, &dwThreadFlags, &dwProcessId, &dwTickTime);
if (!dwProcessId || (dwProcessId != pThread->_dwProcessId) || (dwTickTime != pThread->_dwTickTime)) { OnThreadTerminateInternal(dwThreadId); pThread = NULL; }
return pThread; } }
return NULL; }
//+---------------------------------------------------------------------------
//
// FindAndCreateThread
//
//----------------------------------------------------------------------------
CTipbarThread *CTipbarWnd::_CreateThread(DWORD dwThreadId) { HRESULT hr; CTipbarThread *pThread = _FindThread(dwThreadId);
if (pThread) return pThread;
CTipbarThread **ppThread;
MyWaitForInputIdle(dwThreadId, UTB_INPUTIDLETIMEOUT);
pThread = new CTipbarThread(this); if (!pThread) goto Exit;
hr = pThread->Init(dwThreadId); if (FAILED(hr)) { goto FreeThread; }
if (SUCCEEDED(pThread->InitItemList())) { TraceMsg(TF_GENERAL, "OnSetFocus Create New CTipbarThreadm");
ppThread = _rgThread.Append(1); if (!ppThread) { goto FreeThread; }
*ppThread = pThread; } else { TraceMsg(TF_GENERAL, "focusnfy OnSetFocus fail to create CTipbarThreadm"); FreeThread: pThread->_UninitItemList(TRUE); pThread->Disconnect(); pThread->_Release(); pThread = NULL; goto Exit; }
Exit: return pThread; }
//+---------------------------------------------------------------------------
//
// Init
//
//----------------------------------------------------------------------------
void CTipbarWnd::Init(BOOL fInDeskBand, CDeskBand *pDeskBand) { RECT rc;
if (_fInDeskBand = fInDeskBand) _fShowText = FALSE; _pDeskBand = pDeskBand;
::SetRect(&rc, 0, 0, 0, 0);
if (g_bNewLook && !_pWndFrame && (GetStyle() & UIWINDOW_OFC10TOOLBAR)) { UINT uWndFrameStyle;
uWndFrameStyle = UIWNDFRAME_THIN | UIWNDFRAME_NORESIZE;
_pWndFrame = new CUIFWndFrame(this, &rc, uWndFrameStyle);
if (_pWndFrame) { _pWndFrame->Initialize();
AddUIObj(_pWndFrame); } }
if (!_pGripper && !_fInDeskBand) { _pGripper = new CTipbarGripper(this, &rc, IsVertical() ? UIGRIPPER_VERTICAL : 0);
if (_pGripper) { _pGripper->Initialize();
AddUIObj(_pGripper); } }
_ctrlbtnHolder.Init(this);
if (!IsVertical()) Move(_xWnd, _yWnd, 0, GetTipbarHeight()); else Move(_xWnd, _yWnd, GetTipbarHeight(), 0); }
//+---------------------------------------------------------------------------
//
// SetVertical
//
//----------------------------------------------------------------------------
void CTipbarWnd::SetVertical(BOOL fVertical) { int iPartID; _fVertical = fVertical;
if (_fVertical) iPartID = TBP_BACKGROUNDLEFT; else iPartID = TBP_BACKGROUNDBOTTOM;
if (_pGripper) { DWORD dwStyle = _pGripper->GetStyle(); if (fVertical) dwStyle |= UIGRIPPER_VERTICAL; else dwStyle &= ~UIGRIPPER_VERTICAL; _pGripper->SetStyle(dwStyle); }
if (g_fTaskbarTheme) SetActiveTheme(L"TASKBAR", iPartID, TS_NORMAL );
if (!_fInDeskBand) { if (!IsVertical()) Move(_xWnd, _yWnd, 0, GetTipbarHeight()); else Move(_xWnd, _yWnd, GetTipbarHeight(), 0); }
if (GetWnd()) { KillTimer(TIPWND_TIMER_SYSCOLORCHANGED); SetTimer(TIPWND_TIMER_SYSCOLORCHANGED, g_uTimerElapseSYSCOLORCHANGED); } }
//+---------------------------------------------------------------------------
//
// InitThemeMargins
//
//----------------------------------------------------------------------------
void CTipbarWnd::InitThemeMargins() { CUIFTheme themeBtn; memset(&_marginsItem, 0, sizeof(_marginsItem)); _cxItemMargin = CX_ITEMMARGIN; _nItemDistance = ITEMDISTANCE; _nCtrlItemHeightMargin = CTRLITEMHEIGHTMARGIN; _cxCapBtn = GetSystemMetrics( SM_CXSIZE );
themeBtn.SetActiveTheme(L"TOOLBAR", TP_BUTTON, 0); if (SUCCEEDED(themeBtn.OpenThemeData(GetWnd()))) { themeBtn.GetThemeMargins(NULL, TS_NORMAL, TMT_CONTENTMARGINS, NULL, &_marginsItem); _cxItemMargin = CX_ITEMMARGIN_THEME; _nItemDistance = ITEMDISTANCE_THEME; _nCtrlItemHeightMargin = CTRLITEMHEIGHTMARGIN_THEME; }
themeBtn.CloseThemeData(); themeBtn.SetActiveTheme(L"WINDOW", WP_CLOSEBUTTON, 0); if (SUCCEEDED(themeBtn.OpenThemeData(GetWnd()))) { SIZE size; themeBtn.GetThemePartSize(NULL, TS_NORMAL, NULL, TS_TRUE, &size);
int cy = themeBtn.GetThemeSysSize(SM_CYSIZE); _cxCapBtn = MulDiv(cy, size.cx, size.cy); } }
//+---------------------------------------------------------------------------
//
// UpdateVerticalFont
//
//----------------------------------------------------------------------------
void CTipbarWnd::UpdateVerticalFont() { if (_fVertical) { if (_hfontVert) { DeleteObject(_hfontVert); SetFontToThis(NULL); _hfontVert = NULL; }
_hfontVert = CreateVerticalFont(); SetFontToThis(_hfontVert); } else { SetFontToThis(NULL); } }
//+---------------------------------------------------------------------------
//
// CheckEAFonts
//
//----------------------------------------------------------------------------
int CALLBACK FindEAEnumFontProc(const LOGFONT *plf, const TEXTMETRIC *ptm, WORD wType, LPARAM lParam) { BOOL *pf = (BOOL *)lParam;
if (wType != TRUETYPE_FONTTYPE) return 1;
if (plf->lfFaceName[0] == '@') { *pf = TRUE; return 0; }
return 1; }
BOOL CheckEAFonts() { HDC hdc = GetDC(NULL); BOOL fFound = FALSE;
EnumFonts(hdc, NULL, (FONTENUMPROC)FindEAEnumFontProc, (LPARAM)&fFound);
ReleaseDC(NULL, hdc); return fFound; }
//+---------------------------------------------------------------------------
//
// CreateVerticalFont
//
//----------------------------------------------------------------------------
HFONT CTipbarWnd::CreateVerticalFont() { HFONT hfontVert = NULL; CUIFTheme themeBtn; themeBtn.SetActiveTheme(L"TOOLBAR", TP_BUTTON, 0);
if (!GetWnd()) return NULL;
BOOL fIsEAFonts = CheckEAFonts();
if (SUCCEEDED(themeBtn.OpenThemeData(GetWnd()))) { LOGFONTW lfw; Assert(IsOnNT51());
if (SUCCEEDED(themeBtn.GetThemeFont(NULL, 0 , TMT_FONT, &lfw))) { lfw.lfEscapement = 2700; lfw.lfOrientation = 2700; lfw.lfOutPrecision = OUT_TT_ONLY_PRECIS;
if (fIsEAFonts) { //
// Use @font for vertical langbar.
//
WCHAR szFaceName[LF_FACESIZE]; szFaceName[0] = L'@'; StringCchCopyW(&szFaceName[1], ARRAYSIZE(szFaceName) -1, lfw.lfFaceName); StringCchCopyW(lfw.lfFaceName, ARRAYSIZE(lfw.lfFaceName), szFaceName);
} hfontVert = CreateFontIndirectW(&lfw); goto CheckFont; } }
LOGFONT lf; HFONT hDefFont = (HFONT)GetStockObject( DEFAULT_GUI_FONT ); GetObject(hDefFont, sizeof(LOGFONT), &lf); lf.lfEscapement = 2700; lf.lfOrientation = 2700; lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
if (fIsEAFonts) { //
// Use @font for vertical langbar.
//
char szFaceName[LF_FACESIZE]; szFaceName[0] = '@'; StringCchCopy(&szFaceName[1], ARRAYSIZE(szFaceName) -1, lf.lfFaceName); StringCchCopy(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), szFaceName); }
hfontVert = CreateFontIndirect(&lf);
CheckFont: return hfontVert; }
//+---------------------------------------------------------------------------
//
// SetLangBand
//
//----------------------------------------------------------------------------
BOOL CTipbarWnd::SetLangBand(BOOL fLangBand, BOOL fNotify) { BOOL fRet = TRUE;
if (fLangBand == (IsSFDeskband() ? TRUE : FALSE)) return fRet;
//
// Set/Remove language band object
//
HWND hwndTray = shellwnd.GetWndTray();
if (fNotify && hwndTray) { #ifndef CUAS_ENABLE
DWORD_PTR dwResult; LRESULT lResult = (LRESULT)0;
lResult = SendMessageTimeout(hwndTray, TM_LANGUAGEBAND, 0, fLangBand, SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, &dwResult);
//
// Checking the language band setting fail case
//
if (!lResult || dwResult != fLangBand) { Assert(0); } #else
DWORD_PTR dwResult; LRESULT lResult = (LRESULT)0;
//
// Workaround fixes of Cicero 5181
// Explorer process doesn't initialize _ptbs yet when receive TM_LANGUAGEBAND.
//
HWND hwndIME = NULL;
//
// we should not load IMM32 here. If there is no IMM32.DLL loaded,
// there is no hwndIME.
//
if (GetSystemModuleHandle("imm32.dll")) hwndIME = ImmGetDefaultIMEWnd(hwndTray);
if (hwndIME) { lResult = SendMessageTimeout(hwndIME, WM_IME_SYSTEM, fLangBand ? IMS_SETLANGBAND : IMS_RESETLANGBAND, (LPARAM)hwndTray, SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, &dwResult); } else { lResult = SendMessageTimeout(hwndTray, TM_LANGUAGEBAND, 0, fLangBand, SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, &dwResult); }
//
// Checking the language band setting fail case
//
if (!lResult || dwResult != fLangBand) { Assert(0); } #endif
} else { fRet = FALSE; }
//
// If this MSUTB is in ctfmon.exe and the langbar status is in Deskband,
// this meutb should stop wroking.
//
if (!_fInDeskBand && fLangBand) { KillTimer(TIPWND_TIMER_SYSCOLORCHANGED); SetTimer(TIPWND_TIMER_SYSCOLORCHANGED, g_uTimerElapseSYSCOLORCHANGED); }
return fRet; }
//+---------------------------------------------------------------------------
//
// SetMoveRect
//
//----------------------------------------------------------------------------
void CTipbarWnd::SetMoveRect( int x, int y, int nWidth, int nHeight) { if (_fInDeskBand) { //
// In case of DeskBand case, only update width and height.
//
_nWidth = nWidth; _nHeight = nHeight;
return; }
_rcNew.left = x; _rcNew.top = y; _rcNew.right = nWidth; _rcNew.bottom = nHeight; _fNeedMoveWindow = TRUE;
StartPendingUpdateUI();
RECT rc; SIZE sizeWndFrame; sizeWndFrame.cx = 0; sizeWndFrame.cy = 0; if (_pWndFrame) { ::SetRect(&rc, 0, 0, nWidth - GetCxDlgFrame(), nHeight - GetCyDlgFrame()); _pWndFrame->SetRect(&rc); _pWndFrame->GetFrameSize( &sizeWndFrame ); }
if (_pGripper) { if (!IsVertical()) { ::SetRect(&rc, sizeWndFrame.cx, sizeWndFrame.cy, sizeWndFrame.cx + GetGripperWidth(), nHeight - GetCyDlgFrame() - sizeWndFrame.cy); } else { ::SetRect(&rc, sizeWndFrame.cx, sizeWndFrame.cy, nWidth - GetCxDlgFrame() - sizeWndFrame.cx, sizeWndFrame.cy + GetGripperWidth()); } _pGripper->SetRect(&rc); } EndPendingUpdateUI(); }
//+---------------------------------------------------------------------------
//
// GetGripperWidth
//
//----------------------------------------------------------------------------
int CTipbarWnd::GetGripperWidth() { if (_fInDeskBand) return 0;
if (_pGripper) { if (SUCCEEDED(_pGripper->EnsureThemeData(GetWnd()))) { int nRet = -1;
SIZE size; HDC hdc = GetDC(GetWnd()); if (SUCCEEDED(_pGripper->GetThemePartSize(hdc, TS_NORMAL, NULL, TS_TRUE, &size))) { if (!IsVertical()) nRet = size.cx + CUI_GRIPPER_THEME_MARGIN * 2; else nRet = size.cy + CUI_GRIPPER_THEME_MARGIN * 2; }
ReleaseDC(GetWnd(), hdc);
if (nRet >= 0) return nRet; } }
return 5; }
//+---------------------------------------------------------------------------
//
// Move
//
//----------------------------------------------------------------------------
void CTipbarWnd::Move( int x, int y, int nWidth, int nHeight) { CUIFWindow::Move(x, y, nWidth, nHeight); }
//+---------------------------------------------------------------------------
//
// LocateCtrlButtons
//
//----------------------------------------------------------------------------
void CTipbarWnd::LocateCtrlButtons() { DWORD dwFlags = 0;
if (IsSFDeskband() && IsSFNoExtraIcon()) dwFlags |= TCBH_NOCOLUMN;
if (!IsCapKanaShown()) dwFlags |= TCBH_NOCOLUMN0;
SIZE sizeWndFrame; sizeWndFrame.cx = 0; sizeWndFrame.cy = 0; if (_pWndFrame != NULL) _pWndFrame->GetFrameSize( &sizeWndFrame );
int nTipbarHeight = GetTipbarHeight(); RECT rc; GetRect(&rc); int nHeightPadding = 0;
if (!IsVertical()) { if (rc.bottom - rc.top > nTipbarHeight) nHeightPadding = (rc.bottom - rc.top - nTipbarHeight) / 2;
int xNew; if (_fNeedMoveWindow) xNew = _rcNew.right - GetCtrlButtonWidth() - sizeWndFrame.cx; else xNew = _nWidth - GetCtrlButtonWidth() - sizeWndFrame.cx;
_ctrlbtnHolder.Locate(this, xNew, sizeWndFrame.cy + nHeightPadding, nTipbarHeight - (sizeWndFrame.cy * 2), dwFlags, FALSE); } else { if (rc.right - rc.left > nTipbarHeight) nHeightPadding = (rc.right - rc.left - nTipbarHeight) / 2;
int yNew; if (_fNeedMoveWindow) yNew = _rcNew.bottom - GetCtrlButtonWidth() - sizeWndFrame.cy; else yNew = _nHeight - GetCtrlButtonWidth() - sizeWndFrame.cy;
_ctrlbtnHolder.Locate(this, sizeWndFrame.cx + nHeightPadding, yNew, nTipbarHeight - (sizeWndFrame.cx * 2), dwFlags, TRUE); } }
//+---------------------------------------------------------------------------
//
// GetFocusKeyboardLayout
//
//----------------------------------------------------------------------------
HKL CTipbarWnd::GetFocusKeyboardLayout() { return GetKeyboardLayout(_pFocusThread ? _pFocusThread->_dwThreadId : 0); }
//+---------------------------------------------------------------------------
//
// HandleMouseMsg
//
//----------------------------------------------------------------------------
void CTipbarWnd::HandleMouseMsg( UINT uMsg, POINT pt ) { if (_fInHandleMouseMsg) return;
//
// Bug#477031: Add the reference count to finish the current task before
// destructing this object.
//
//
AddRef();
_fInHandleMouseMsg = TRUE;
if (_pFocusThread) { AttachFocusThread();
if ((uMsg == WM_LBUTTONDOWN) || (uMsg == WM_RBUTTONDOWN)) if (!MyWaitForInputIdle(_pFocusThread->_dwThreadId, UTB_INPUTIDLETIMEOUT)) _pFocusThread->_ptw->_putb->RestoreLastFocus(NULL, FALSE); }
POINT ptScrn = pt; ClientToScreen(GetWnd(), &ptScrn); if (WindowFromPoint(ptScrn) == GetWnd()) { SetAlpha(255, TRUE);
if (_fInStub) { KillTimer(TIPWND_TIMER_STUBEND);
if (!_fInStubShow) SetTimer(TIPWND_TIMER_STUBSTART, g_uTimerElapseSTUBSTART); } } else { SetAlpha(_bAlpha, TRUE);
if (_fInStub && _fInStubShow) SetTimer(TIPWND_TIMER_STUBEND, g_uTimerElapseSTUBEND); } CUIFWindow::HandleMouseMsg(uMsg, pt);
if (uMsg == WM_RBUTTONUP) { CUIFObject *pUIObj = ObjectFromPoint( pt ); if (pUIObj && pUIObj->GetID() != (-1)) { PostMessage(GetWnd(), WM_LBWND_SHOWCONTEXTMENU, 0, MAKELPARAM(pt.x, pt.y)); } }
_fInHandleMouseMsg = FALSE; Release(); }
//+---------------------------------------------------------------------------
//
// OnMouseOutFromWindow
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnMouseOutFromWindow( POINT pt ) { StartBackToAlphaTimer();
if (_fInStub && _fInStubShow) SetTimer(TIPWND_TIMER_STUBEND, g_uTimerElapseSTUBEND); }
//+---------------------------------------------------------------------------
//
// CheckO10Flag
//
//----------------------------------------------------------------------------
#ifdef USE_OFC10LOOKONWINXP
void CTipbarWnd::CheckO10Flag() { if (!g_bNewLook) return;
EnsureThemeData(GetWnd()); if (IsThemeActive() || _fInDeskBand) { g_dwWndStyle &= ~UIWINDOW_OFC10TOOLBAR; } else { g_dwWndStyle |= UIWINDOW_OFC10TOOLBAR; }
SetStyle(g_dwWndStyle); CreateScheme(); } #endif
//+---------------------------------------------------------------------------
//
// OnCreate
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnCreate(HWND hWnd) {
if (g_fTaskbarTheme) SetWindowTheme(hWnd, L"TASKBAR", NULL);
#ifdef USE_OFC10LOOKONWINXP
CheckO10Flag(); #endif
if (_fVertical) { if (!_hfontVert) { _hfontVert = CreateVerticalFont(); } SetFontToThis(_hfontVert); } _ctrlbtnHolder.UpdateBitmap(this);
_itemList.Load();
if (_putb) _putb->AdviseEventSink(this, hWnd, TF_LBESF_GLOBAL, &_dwlbimCookie);
if (_pFocusThread) _pFocusThread->InitItemList(); InitHighContrast(); SetAlpha(128, FALSE);
InitMetrics();
//
// MSAA support
//
Assert(!_pTipbarAcc); _pTipbarAcc = new CTipbarAccessible(this); if (_pTipbarAcc) { _pTipbarAcc->SetWindow(hWnd); } }
//+---------------------------------------------------------------------------
//
// SetAlpha
//
//----------------------------------------------------------------------------
typedef BOOL (WINAPI * SETLAYERWINDOWATTRIBUTE)(HWND, COLORREF, BYTE, DWORD); void CTipbarWnd::SetAlpha(BYTE bAlpha, BOOL fTemp) { if (!_fInDeskBand && IsOnNT5()) {
//
// we don't do alpha blending.
//
// when high contrast is on
// when Modal Menu is shown.
//
//
if (IsHighContrastOn() || _pModalMenu) { fTemp = TRUE; bAlpha = 255; }
if (!fTemp) _bAlpha = bAlpha;
if (_bCurAlpha == bAlpha) return;
CUIFShadow *pShadowWnd = GetShadowWnd(); if (pShadowWnd) { EnableShadow(bAlpha == 255); pShadowWnd->Show((bAlpha == 255) && IsVisible()); }
DWORD dwExStyle = GetWindowLong(GetWnd(), GWL_EXSTYLE); SetWindowLong(GetWnd(), GWL_EXSTYLE, dwExStyle | WS_EX_LAYERED);
static SETLAYERWINDOWATTRIBUTE pfnSetLayeredWindowAttributes = NULL; if (!pfnSetLayeredWindowAttributes) { HINSTANCE hUser32; hUser32 = GetSystemModuleHandle(TEXT("user32.dll")); if (hUser32) pfnSetLayeredWindowAttributes = (SETLAYERWINDOWATTRIBUTE)GetProcAddress(hUser32, TEXT("SetLayeredWindowAttributes")); }
if (pfnSetLayeredWindowAttributes) pfnSetLayeredWindowAttributes(GetWnd(), 0, (BYTE)bAlpha, LWA_ALPHA);
_bCurAlpha = bAlpha; } }
//+---------------------------------------------------------------------------
//
// OnDestroy
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnDestroy(HWND hWnd) { CancelMenu();
//
// MSAA support
//
if (_pTipbarAcc) _pTipbarAcc->NotifyWinEvent( EVENT_OBJECT_DESTROY, this);
OnTerminateToolbar();
if (_pTipbarAcc) { _pTipbarAcc->ClearAccItems(); _pTipbarAcc->Release(); _pTipbarAcc = NULL; }
CoUninit();
if (_putb) _putb->UnadviseEventSink(_dwlbimCookie); }
//+---------------------------------------------------------------------------
//
// OnShowWindow
//
//----------------------------------------------------------------------------
LRESULT CTipbarWnd::OnShowWindow( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { //
// MSAA support
//
if (_pTipbarAcc) { if (wParam) { _pTipbarAcc->NotifyWinEvent( EVENT_OBJECT_SHOW ,this);
//
// MSCANDUI does this.
//
// REVIEW: KOJIW: Unless we send notify EVENT_OBJECT_FOCUS,
// we never receive WM_GETOBJECT message. Why???
//
_pTipbarAcc->NotifyWinEvent( EVENT_OBJECT_FOCUS ,this); } else { _pTipbarAcc->NotifyWinEvent( EVENT_OBJECT_HIDE ,this); } }
return CUIFWindow::OnShowWindow( hWnd, uMsg, wParam, lParam ); }
//+---------------------------------------------------------------------------
//
// OnEndSession
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnEndSession(HWND hwnd, WPARAM wParam, LPARAM lParam) { if (!g_bWinLogon) OnTerminateToolbar();
if (wParam) { if (lParam & ENDSESSION_LOGOFF) { KillTimer(TIPWND_TIMER_SHOWWINDOW); Show(FALSE); } else { OnTerminateToolbar();
AddRef(); DestroyWindow(hwnd); Release(); } } }
//+---------------------------------------------------------------------------
//
// OnTerminateToolbar
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnTerminateToolbar() { _fTerminating = TRUE;
DestroyOverScreenSizeBalloon();
TerminateAllThreads(TRUE);
if (!_fInDeskBand) SavePosition(); }
//+---------------------------------------------------------------------------
//
// SavePosition
//
//----------------------------------------------------------------------------
void CTipbarWnd::SavePosition() { CMyRegKey keyUTB;
if (keyUTB.Create(HKEY_CURRENT_USER, c_szUTBKey) == S_OK) { POINT pt; pt.x = 0; pt.y = 0; MyClientToScreen(&pt, NULL); keyUTB.SetValue((DWORD)pt.x, c_szLeft); keyUTB.SetValue((DWORD)pt.y, c_szTop); keyUTB.SetValue((DWORD)_fVertical ? 1 : 0, c_szVertical); } }
//+---------------------------------------------------------------------------
//
// TerminateAllThreads
//
//----------------------------------------------------------------------------
void CTipbarWnd::TerminateAllThreads(BOOL fTerminatFocusThread) { int nCnt = _rgThread.Count(); int i; DWORD *pdwThread;
pdwThread = new DWORD[nCnt + 1]; if (!pdwThread) return;
for (i = 0; i < nCnt; i++) { pdwThread[i] = 0;
CTipbarThread *pThread = _rgThread.Get(i); if (!pThread) continue;
if (!fTerminatFocusThread && (pThread == _pFocusThread)) continue;
pdwThread[i] = pThread->_dwThreadId; }
for (i = 0; i < nCnt; i++) { if (pdwThread[i]) OnThreadTerminateInternal(pdwThread[i]); }
delete[] pdwThread; }
//+---------------------------------------------------------------------------
//
// SetShowText()
//
//----------------------------------------------------------------------------
void CTipbarWnd::SetShowText(BOOL fShowText) { _fShowText = fShowText;
if (_pFocusThread) { OnThreadItemChange(_pFocusThread->_dwThreadId); }
TerminateAllThreads(FALSE); }
//+---------------------------------------------------------------------------
//
// OnWindowPosChanged
//
//----------------------------------------------------------------------------
LRESULT CTipbarWnd::OnWindowPosChanged(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (_pFocusThread) { int i; for (i = 0; i < _pFocusThread->_rgItem.Count(); i++) { CTipbarItem *pItem = _pFocusThread->_rgItem.Get(i); if (pItem) pItem->OnPosChanged(); } }
return CUIFWindow::OnWindowPosChanged(hWnd, uMsg, wParam, lParam); }
//+---------------------------------------------------------------------------
//
// OnWindowPosChanging
//
//----------------------------------------------------------------------------
LRESULT CTipbarWnd::OnWindowPosChanging(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WINDOWPOS *pwp = (WINDOWPOS *)lParam;
if (!(pwp->flags & SWP_NOZORDER)) { CUIFToolTip *ptip = GetToolTipWnd();
//
// we don't patch hwndInsertAfter, when
// - Tooltip is being shown.
// - Modal Popup menu is shown.
//
if ((!ptip || !(ptip->IsBeingShown())) && !_pttModal) pwp->hwndInsertAfter = HWND_TOP; }
return CUIFWindow::OnWindowPosChanged(hWnd, uMsg, wParam, lParam); }
//+---------------------------------------------------------------------------
//
// OnEraseBkGnd()
//
//----------------------------------------------------------------------------
LRESULT CTipbarWnd::OnEraseBkGnd( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { return 1; }
//+---------------------------------------------------------------------------
//
// PaintObject()
//
//----------------------------------------------------------------------------
void CTipbarWnd::PaintObject( HDC hDC, const RECT *prcUpdate ) { // KillTimer(TIPWND_TIMER_ONUPDATECALLED);
if (_fNeedMoveWindow) { Move(_rcNew.left, _rcNew.top, _rcNew.right, _rcNew.bottom); _fNeedMoveWindow = FALSE; }
if (_pFocusThread && _pFocusThread->IsDirtyItem()) { _pFocusThread->CallOnUpdateHandler();
//
// #432697: Stress fault
//
// ClosePopupTipbar() could be called while CallOnUpdateHandler()
// is calling marshaling. We should check if g_pTIpbarWnd is
// available.
//
if (!g_pTipbarWnd) return; }
CUIFWindow::PaintObject(hDC, prcUpdate); }
//+---------------------------------------------------------------------------
//
// UpdateUI()
//
//----------------------------------------------------------------------------
void CTipbarWnd::UpdateUI( const RECT *prcUpdate ) { // TraceMsg(TF_FUNC, "UpdateUI");
KillTimer(TIPWND_TIMER_UPDATEUI);
if (_dwThreadItemChangedForTimer || _dwPendingUpdateUI || (_pFocusThread && _pFocusThread->IsDirtyItem())) { SetTimer(TIPWND_TIMER_UPDATEUI, g_uTimerElapseUPDATEUI); return; }
if (_fNeedMoveWindow) { // TraceMsg(TF_FUNC, "UpdateUI need move window");
StartPendingUpdateUI(); Move(_rcNew.left, _rcNew.top, _rcNew.right, _rcNew.bottom); _fNeedMoveWindow = FALSE; EndPendingUpdateUI(); }
TraceMsg(TF_FUNC, "UpdateUI update now "); CUIFWindow::UpdateUI(NULL); }
//+---------------------------------------------------------------------------
//
// SetShowTrayIcon()
//
//----------------------------------------------------------------------------
void CTipbarWnd::SetShowTrayIcon(BOOL fShowTrayIcon) { _fShowTrayIcon = fShowTrayIcon;
if (_fShowTrayIcon && _pFocusThread) { KillTimer(TIPWND_TIMER_MOVETOTRAY); SetTimer(TIPWND_TIMER_MOVETOTRAY, g_uTimerElapseMOVETOTRAY); } else if (g_pTrayIconWnd) { g_pTrayIconWnd->SetMainIcon(NULL); g_pTrayIconWnd->RemoveAllIcon(0); }
}
//+---------------------------------------------------------------------------
//
// ShowOverScreenSizeBalloon
//
//----------------------------------------------------------------------------
void CTipbarWnd::ShowOverScreenSizeBalloon() { RECT rc; POINT pt; CTipbarCtrlButton *pcuiCtrlbtn = _ctrlbtnHolder.GetCtrlBtn(ID_CBTN_EXTMENU); if (!pcuiCtrlbtn) { Assert(0); return; }
DestroyOverScreenSizeBalloon();
_pblnOverScreenSize = new CUIFBalloonWindow(g_hInst, UIBALLOON_OK); if (!_pblnOverScreenSize) return;
_pblnOverScreenSize->Initialize();
pcuiCtrlbtn->GetRect(&rc); pt.x = (rc.left + rc.right) / 2; pt.y = rc.top; MyClientToScreen(&pt, &rc);
_pblnOverScreenSize->SetTargetPos(pt); _pblnOverScreenSize->SetExcludeRect(&rc);
_pblnOverScreenSize->SetText(CRStr(IDS_OVERSCREENSIZE)); _pblnOverScreenSize->CreateWnd(GetWnd());
}
//+---------------------------------------------------------------------------
//
// DestroyMinimizeBalloon
//
//----------------------------------------------------------------------------
void CTipbarWnd::DestroyOverScreenSizeBalloon() { if (_pblnOverScreenSize) { if (IsWindow(_pblnOverScreenSize->GetWnd())) DestroyWindow(_pblnOverScreenSize->GetWnd()); delete _pblnOverScreenSize; _pblnOverScreenSize = NULL; } }
//+---------------------------------------------------------------------------
//
// CancelMenu
//
//----------------------------------------------------------------------------
void CTipbarWnd::CancelMenu() { if (_pttModal) { if (_pttModal->_ptw && _pttModal->_ptw->_putb) _pttModal->_ptw->StartModalInput(NULL, _pttModal->_dwThreadId); Assert(_pModalMenu); _pModalMenu->CancelMenu();
StartBackToAlphaTimer(); } }
//+---------------------------------------------------------------------------
//
// MoveToStub
//
//----------------------------------------------------------------------------
void CTipbarWnd::MoveToStub(BOOL fHide) { RECT rc; _fInStub = TRUE;
SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);
if (fHide) { _xWnd = rc.right - (24 + 14); _fInStubShow = FALSE; } else { RECT rcWnd; GetWindowRect(GetWnd(), &rcWnd); _xWnd = rc.right - (rcWnd.right - rcWnd.left); _fInStubShow = TRUE; } _yWnd = rc.bottom - GetTipbarHeight() - _cyDlgFrame;
if (_pFocusThread) _pFocusThread->MyMoveWnd(0, 0); }
//+---------------------------------------------------------------------------
//
// RestoreFromStub
//
//----------------------------------------------------------------------------
void CTipbarWnd::RestoreFromStub() { _fInStub = FALSE; _fInStubShow = FALSE; KillTimer(TIPWND_TIMER_STUBSTART); KillTimer(TIPWND_TIMER_STUBEND); }
//+---------------------------------------------------------------------------
//
// CTipbarWnd::KillOnThreadItemChangeTimer
//
//----------------------------------------------------------------------------
void CTipbarWnd::KillOnTheadItemChangeTimer() { DWORD dwThreadId = _dwThreadItemChangedForTimer; _dwThreadItemChangedForTimer = 0;
KillTimer(TIPWND_TIMER_ONTHREADITEMCHANGE);
if (dwThreadId) { CTipbarThread *pThread = _FindThread(dwThreadId); if (pThread) pThread->_fItemChanged = TRUE; } }
//+---------------------------------------------------------------------------
//
// CTipbarWnd::OnTimer
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnTimer(UINT uId) { DWORD dwFocusThreadId; DWORD dwRet;
AddRef();
switch (uId) { case TIPWND_TIMER_STUBSTART: KillTimer(TIPWND_TIMER_STUBSTART); MoveToStub(FALSE); break;
case TIPWND_TIMER_STUBEND: KillTimer(TIPWND_TIMER_STUBEND); MoveToStub(TRUE); break;
case TIPWND_TIMER_BACKTOALPHA: KillTimer(TIPWND_TIMER_BACKTOALPHA); SetAlpha(_bAlpha, TRUE); break;
case TIPWND_TIMER_ONTHREADITEMCHANGE: //
// OnThreadItemChangeInternat will disconnect the marshaling for
// all items. It is better todo this later.
//
dwRet = MyWaitForInputIdle(_dwThreadItemChangedForTimer, UTB_INPUTIDLETIMEOUT); if (dwRet) { if (dwRet != WAIT_TIMEOUT) { KillTimer(TIPWND_TIMER_ONTHREADITEMCHANGE); _dwThreadItemChangedForTimer = 0; } break; }
if (!_pttModal) { KillTimer(TIPWND_TIMER_ONTHREADITEMCHANGE);
//
// #509156
//
// Set _dwThreadItemChagnedForTimer before calling
// OnThreadItemChangeInternal(). During the marshaling call
// in the function, someone else may set
// _dwThreadItemChangedForTimer.
//
DWORD dwThreadIdTemp = _dwThreadItemChangedForTimer; _dwThreadItemChangedForTimer = 0; OnThreadItemChangeInternal(dwThreadIdTemp); } break;
case TIPWND_TIMER_SETWINDOWPOS: KillTimer(TIPWND_TIMER_SETWINDOWPOS); SetWindowPos(GetWnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); break;
case TIPWND_TIMER_ONUPDATECALLED: KillTimer(TIPWND_TIMER_ONUPDATECALLED); //
// if _dwThreadItemChangedForTimer is not 0, we will
// update all items later.
//
if (_pFocusThread && (_pFocusThread->_dwThreadId != _dwThreadItemChangedForTimer)) { if (!_pFocusThread->CallOnUpdateHandler()) { if (_pFocusThread) OnThreadItemChange(_pFocusThread->_dwThreadId); } } break;
case TIPWND_TIMER_SYSCOLORCHANGED: KillTimer(TIPWND_TIMER_SYSCOLORCHANGED);
//
// the sys colors were changed, we recreate all thread info
// again.
//
if (_pFocusThread) dwFocusThreadId = _pFocusThread->_dwThreadId; else dwFocusThreadId = 0;
TerminateAllThreads(TRUE);
UpdateVerticalFont();
if (dwFocusThreadId) OnSetFocus(dwFocusThreadId);
InitMetrics(); _ctrlbtnHolder.UpdateBitmap(this); InitHighContrast(); SetAlpha(255, TRUE);
::RedrawWindow(GetWnd(), NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); break;
case TIPWND_TIMER_DISPLAYCHANGE: KillTimer(TIPWND_TIMER_DISPLAYCHANGE);
AdjustPosOnDisplayChange(); break;
case TIPWND_TIMER_UPDATEUI: KillTimer(TIPWND_TIMER_UPDATEUI); UpdateUI(NULL); break;
case TIPWND_TIMER_SHOWWINDOW: KillTimer(TIPWND_TIMER_SHOWWINDOW);
if (_pThreadShowWindowAtTimer == _pFocusThread) Show(_fShowWindowAtTimer);
_pThreadShowWindowAtTimer = NULL; //
// If the window was over the screen and hide some items,
// we show balloon tips.
//
if (_fShowOverItemBalloonAtTimer) ShowOverScreenSizeBalloon();
break;
case TIPWND_TIMER_SHOWDESKBAND: if (SetLangBand(TRUE)) { _dwSFTFlags = TF_SFT_DESKBAND; KillTimer(TIPWND_TIMER_SHOWDESKBAND); }
break;
case TIPWND_TIMER_MOVETOTRAY: KillTimer(TIPWND_TIMER_MOVETOTRAY); MoveToTray(); break;
case TIPWND_TIMER_ENSUREFOCUS: if (_pDeskBand && _pDeskBand->IsInTipbarCreating()) break; KillTimer(TIPWND_TIMER_ENSUREFOCUS); if (!_pFocusThread) EnsureFocusThread(); break;
case TIPWND_TIMER_DOACCDEFAULTACTION: //
// MSAA support
//
KillTimer(TIPWND_TIMER_DOACCDEFAULTACTION); if (_pTipbarAcc && _nDoAccDefaultActionItemId) { _pTipbarAcc->DoDefaultActionReal(_nDoAccDefaultActionItemId); _nDoAccDefaultActionItemId = 0; } break;
default: if ((uId >= TIPWND_TIMER_DEMOTEITEMFIRST) && (uId < TIPWND_TIMER_DEMOTEITEMLAST)) { LANGBARITEMSTATE *pItemState; if (pItemState = _itemList.GetItemStateFromTimerId(uId)) { CTipbarItem *pItem; _itemList.SetDemoteLevel(pItemState->guid, DL_HIDDENLEVEL1); if (_pFocusThread && (pItem = _pFocusThread->GetItem(pItemState->guid))) { Assert(!pItem->IsHiddenStatusControl()) pItem->AddRemoveMeToUI(FALSE); } } break; } }
Release(); return; }
//+---------------------------------------------------------------------------
//
// CTipbarWnd::OnSysColoeChange
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnSysColorChange() { KillTimer(TIPWND_TIMER_SYSCOLORCHANGED); SetTimer(TIPWND_TIMER_SYSCOLORCHANGED, g_uTimerElapseSYSCOLORCHANGED); }
//+---------------------------------------------------------------------------
//
// OnUser
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnUser(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { POINT pt;
switch (uMsg) { case WM_LBWND_SHOWCONTEXTMENU: pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); MyClientToScreen(&pt, NULL); ShowContextMenu(pt, NULL, TRUE); break;
default: if (uMsg == g_wmTaskbarCreated) { shellwnd.Clear(); } break; } }
//+---------------------------------------------------------------------------
//
// OnSettingChange
//
//----------------------------------------------------------------------------
LRESULT CTipbarWnd::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (wParam) { case 0: case SPI_SETHIGHCONTRAST: case SPI_SETNONCLIENTMETRICS: KillTimer(TIPWND_TIMER_SYSCOLORCHANGED); SetTimer(TIPWND_TIMER_SYSCOLORCHANGED, g_uTimerElapseSYSCOLORCHANGED); break; } return 0; }
//+---------------------------------------------------------------------------
//
// OnDisplayChange
//
//----------------------------------------------------------------------------
LRESULT CTipbarWnd::OnDisplayChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (!_fInDeskBand) { KillTimer(TIPWND_TIMER_DISPLAYCHANGE); SetTimer(TIPWND_TIMER_DISPLAYCHANGE, g_uTimerElapseDISPLAYCHANGE); } return CUIFWindow::OnDisplayChange(hWnd, uMsg, wParam, lParam); }
//+---------------------------------------------------------------------------
//
// AdjustPosOnDisplayChange
//
//----------------------------------------------------------------------------
void CTipbarWnd::AdjustPosOnDisplayChange() { RECT rc; RECT rcWnd; int xWnd = _xWnd; int yWnd = _yWnd;
Assert(!_fInDeskBand);
rcWnd.left = _xWnd; rcWnd.top = _yWnd; rcWnd.right = _xWnd + _nWidth; rcWnd.bottom = _yWnd + _nHeight; if (!GetWorkArea(&rcWnd, &rc)) return;
if (_fPosLeft) xWnd = rc.left;
if (_fPosTop) yWnd = rc.top;
if (_fPosRight) xWnd = rc.right - _nWidth;
if (_fPosBottom) yWnd = rc.bottom - _nHeight;
if ((xWnd != _xWnd) || (yWnd != _yWnd)) Move(xWnd, yWnd, _nWidth, _nHeight); }
//+---------------------------------------------------------------------------
//
// UpdatePosFlags
//
//----------------------------------------------------------------------------
#define POSFLAG_MARGIN 2
void CTipbarWnd::UpdatePosFlags() { RECT rc; RECT rcWnd;
if (_fInDeskBand) return;
rcWnd.left = _xWnd; rcWnd.top = _yWnd; rcWnd.right = _xWnd + _nWidth; rcWnd.bottom = _yWnd + _nHeight; if (!GetWorkArea(&rcWnd, &rc)) return;
if (_xWnd <= rc.left + POSFLAG_MARGIN) _fPosLeft = TRUE; else _fPosLeft = FALSE;
if (_yWnd <= rc.top + POSFLAG_MARGIN) _fPosTop = TRUE; else _fPosTop = FALSE;
if (_xWnd + _nWidth >= rc.right - POSFLAG_MARGIN) _fPosRight = TRUE; else _fPosRight = FALSE;
if (_yWnd + _nHeight >= rc.bottom - POSFLAG_MARGIN) _fPosBottom = TRUE; else _fPosBottom = FALSE;
}
//+---------------------------------------------------------------------------
//
// AutoAdjustDeskBandSize
//
//----------------------------------------------------------------------------
BOOL CTipbarWnd::AutoAdjustDeskBandSize() { if (_fDeskbandSizeAdjusted) return FALSE;
if (!_pFocusThread) return FALSE;
if (_pFocusThread->IsCtfmonProcess()) return FALSE;
//
// if _fAdjustDeskbandIfNoRoom is on, don't put fFit so we don't
// do anything if there is a room.
//
BOOL fFit = TRUE; if (_fAdjustDeskbandIfNoRoom) fFit = FALSE;
_fAdjustDeskbandIfNoRoom = FALSE;
if (AdjustDeskBandSize(fFit)) { SetDeskbandSizeAdjusted(); return TRUE; }
return FALSE; }
//+---------------------------------------------------------------------------
//
// AdjustDeskBandSize
//
//----------------------------------------------------------------------------
BOOL CTipbarWnd::AdjustDeskBandSize(BOOL fFit) { if (!_fInDeskBand) return FALSE;
if (!_pDeskBand) return FALSE;
return _pDeskBand->ResizeRebar(GetWnd(), IsVertical() ? _nHeight : _nWidth, fFit); }
//+---------------------------------------------------------------------------
//
// GetThread
//
//----------------------------------------------------------------------------
CTipbarThread *CTipbarWnd::GetThread(DWORD dwThreadId) { int i; for (i = 0; i < _rgThread.Count(); i++) { CTipbarThread *pThread = _rgThread.Get(i); if (!pThread) continue;
if (pThread->_dwThreadId == dwThreadId) { if (TF_GetThreadFlags(dwThreadId, NULL, NULL, NULL)) { return pThread; } } }
return NULL; }
//+---------------------------------------------------------------------------
//
// RestoreLastFocs
//
//----------------------------------------------------------------------------
void CTipbarWnd::RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev) { if (_putb) _putb->RestoreLastFocus(pdwThreadId, fPrev); }
//+---------------------------------------------------------------------------
//
// StartModalInput
//
//----------------------------------------------------------------------------
void CTipbarWnd::StartModalInput(ITfLangBarEventSink *pSink, DWORD dwThreadId) { if (!_putb) return;
_putb->SetModalInput(pSink, dwThreadId, 0);
//
// we want this to track a mouse event of Tray window.
//
if (g_pTrayIconWnd) _putb->SetModalInput(pSink, g_pTrayIconWnd->GetThreadIdTray(), 0);
//
// we want this to track a mouse event of CMD prompt window.
//
_putb->SetModalInput(pSink, GetCurrentThreadId(), TF_LBSMI_FILTERCURRENTTHREAD ); }
//+---------------------------------------------------------------------------
//
// StopModalInput
//
//----------------------------------------------------------------------------
void CTipbarWnd::StopModalInput(DWORD dwThreadId) { if (!_putb) return;
_putb->SetModalInput(NULL, dwThreadId, 0);
if (g_pTrayIconWnd) _putb->SetModalInput(NULL, g_pTrayIconWnd->GetThreadIdTray(), 0);
_putb->SetModalInput(NULL, GetCurrentThreadId(), 0); }
//+---------------------------------------------------------------------------
//
// ClearLBItemList
//
//----------------------------------------------------------------------------
void CTipbarWnd::ClearLBItemList() { _itemList.Clear(); if (_pFocusThread) { OnThreadItemChange(_pFocusThread->_dwThreadId); } }
//+---------------------------------------------------------------------------
//
// ShowMenuExtendMenu
//
//----------------------------------------------------------------------------
void CTipbarWnd::ShowContextMenu(POINT pt, RECT *prc, BOOL fExtendMenuItems) { CUTBContextMenu *pMenu = NULL; RECT rc; CTipbarThread *ptt = GetFocusThread(); DWORD dwThreadId; UINT uId = CUI_MENU_UNSELECTED;
//
// CTipbarWnd could be destroyed during ShowPopup().
//
AddRef();
if (!prc) { rc.left = pt.x; rc.top = pt.y; rc.right = pt.x; rc.bottom = pt.y; prc = &rc; }
if (!ptt) goto Exit;
pMenu = new CUTBContextMenu(this); if (!pMenu) goto Exit;
if (!pMenu->Init()) goto Exit;
_pttModal = ptt; StartModalInput(this, ptt->_dwThreadId);
dwThreadId = GetCurrentThreadId(); _pModalMenu = pMenu;
uId = pMenu->ShowPopup(this, pt, prc, fExtendMenuItems);
_pModalMenu = NULL;
if (_pttModal) StopModalInput(_pttModal->_dwThreadId); _pttModal = NULL;
if (uId != CUI_MENU_UNSELECTED) { pMenu->SelectMenuItem(uId); }
Exit: if (pMenu) delete pMenu;
Release(); }
//+---------------------------------------------------------------------------
//
// IsInItemChangOrDirty
//
//----------------------------------------------------------------------------
BOOL CTipbarWnd::IsInItemChangeOrDirty(CTipbarThread *pThread) { if (pThread->_dwThreadId == _dwThreadItemChangedForTimer) return TRUE;
return pThread->IsDirtyItem(); }
//+---------------------------------------------------------------------------
//
// OnGetObject
//
//----------------------------------------------------------------------------
LRESULT CTipbarWnd::OnGetObject( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { LRESULT lResult = (LRESULT)0;
switch (lParam) { //
// We process the OBJID_CLIENT object identifier;
// this is the client area of our application
// window.
//
case OBJID_CLIENT: { HRESULT hr;
if (_pTipbarAcc == NULL) { return E_OUTOFMEMORY; }
if (!_pTipbarAcc->IsInitialized()) { //
//
//
hr = EnsureCoInit(); if (FAILED(hr)) { break; }
//
// Initialize our Accessible object. If the
// initialization fails, delete the Accessible
// object and return the failure code.
//
hr = _pTipbarAcc->Initialize(); if (FAILED(hr)) { _pTipbarAcc->Release(); _pTipbarAcc = NULL;
lResult = (LRESULT)hr; break; }
//
// Send an EVENT_OBJECT_CREATE WinEvent for the
// creation of the Accessible object for the
// client area.
//
_pTipbarAcc->NotifyWinEvent( EVENT_OBJECT_CREATE , this); }
//
// Call LresultFromObject() to create reference to
// our Accessible object that MSAA will marshal to
// the client.
//
lResult = _pTipbarAcc->CreateRefToAccObj( wParam ); break; }
}
return lResult; }
//+---------------------------------------------------------------------------
//
// OnThemeChanged
//
//----------------------------------------------------------------------------
void CTipbarWnd::OnThemeChanged(HWND hwnd, WPARAM wParam, LPARAM lParam) { #ifdef USE_OFC10LOOKONWINXP
CheckO10Flag(); #endif
CUIFWindow::OnThemeChanged(hwnd, wParam, lParam); }
//+---------------------------------------------------------------------------
//
// StartDoDefaultActionTimer
//
//----------------------------------------------------------------------------
BOOL CTipbarWnd::StartDoAccDefaultActionTimer(CTipbarItem *pItem) { if (!_pTipbarAcc) return FALSE;
_nDoAccDefaultActionItemId = _pTipbarAcc->GetIDOfItem(pItem); if ((_nDoAccDefaultActionItemId == 0) || (_nDoAccDefaultActionItemId == -1)) return FALSE;
KillTimer(TIPWND_TIMER_DOACCDEFAULTACTION); SetTimer(TIPWND_TIMER_DOACCDEFAULTACTION, g_uTimerElapseDOACCDEFAULTACTION);
return TRUE; }
//////////////////////////////////////////////////////////////////////////////
//
// CTipbarThread
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CTipbarThread::CTipbarThread(CTipbarWnd *ptw) {
Dbg_MemSetThisName(TEXT("CTipbarThread"));
_ptw = ptw; _dwThreadId = 0; _plbim = NULL; _ref = 1; }
//+---------------------------------------------------------------------------
//
// Init
//
//----------------------------------------------------------------------------
HRESULT CTipbarThread::Init(DWORD dwThreadId) { DWORD dwThreadIdTmp; HRESULT hr = S_OK;
_dwThreadId = dwThreadId;
if (!TF_GetThreadFlags(_dwThreadId, &_dwThreadFlags, &_dwProcessId, &_dwTickTime)) return E_FAIL;
if (IsConsole()) return S_OK;
// What's happening: we eventually reach InternalGetThreadUIManager
// which, if _dwThreadId is NULL, will substitute
// g_ShareMem.dwActiveThreadId.
// This is dangerous, because if the active thread does not match
// this one we'll do rpc and _plbim will be on the wrong thread.
// Passing in _dwThreadId seems like the right thing to do....
hr = _ptw->GetLangBarMgr()->GetThreadLangBarItemMgr(_dwThreadId, &_plbim, &dwThreadIdTmp); if (FAILED(hr)) return hr;
Assert(dwThreadIdTmp == _dwThreadId);
return hr; }
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CTipbarThread::~CTipbarThread() { #ifdef DEBUG
Assert(!_fInCallOnUpdateHandler); #endif
if (_ptw) { Assert(this != _ptw->GetFocusThread()); RemoveUIObjs();
_ptw->CleanUpThreadPointer(this, TRUE); }
_UninitItemList(TRUE); SafeReleaseClear(_plbim); }
//+---------------------------------------------------------------------------
//
// _AddRef
//
//----------------------------------------------------------------------------
ULONG CTipbarThread::_AddRef( ) { _ref++;
return _ref; }
//+---------------------------------------------------------------------------
//
// _Release
//
//----------------------------------------------------------------------------
ULONG CTipbarThread::_Release( ) { ULONG cr; _ref--;
cr = _ref;
if (cr == 0) { delete this; }
return cr; }
//+---------------------------------------------------------------------------
//
// SetFocus
//
//----------------------------------------------------------------------------
BOOL CTipbarThread::SetFocus(BOOL fFocus) {
if (!fFocus) { int i; for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *pItem = _rgItem.Get(i); CTipbarBalloonItem *pballoon; if (pItem && SUCCEEDED(pItem->QueryInterface(IID_PRIV_BALLOONITEM, (void **)&pballoon))) { pballoon->DestroyBalloonTip(); pballoon->Release(); } }
} return TRUE; }
//+---------------------------------------------------------------------------
//
// InitItemList
//
//----------------------------------------------------------------------------
#define NUM_GETITEMATONCE 30
HRESULT CTipbarThread::InitItemList() { HRESULT hr = E_FAIL; IEnumTfLangBarItems *pEnum = NULL; RECT rc; CEnumCatCache *penumcache = NULL; CGuidDwordCache *pgdcache = NULL;
if (!_ptw) return hr;
SIZE sizeWndFrame; sizeWndFrame.cx = 0; sizeWndFrame.cy = 0; if (_ptw->GetWndFrame() != NULL) _ptw->GetWndFrame()->GetFrameSize( &sizeWndFrame );
_ptw->InitThemeMargins();
if (!IsVertical()) { rc.left = _ptw->GetGripperWidth() + 1 + sizeWndFrame.cx; rc.top = 0 + sizeWndFrame.cy; rc.right = 0; rc.bottom = _ptw->GetTipbarHeight() - sizeWndFrame.cy; } else { rc.left = 0 + sizeWndFrame.cx; rc.top = _ptw->GetGripperWidth() + 1 + sizeWndFrame.cy; rc.right = _ptw->GetTipbarHeight() - sizeWndFrame.cx; rc.bottom = 0; }
_nNumItem = 0;
penumcache = new CEnumCatCache; if (!penumcache) { TraceMsg(TF_FUNC, "could not create CEnumCatCache"); goto Exit; }
pgdcache = new CGuidDwordCache; if (!pgdcache) { TraceMsg(TF_FUNC, "could not create CGuidDwordCache"); goto Exit; }
if (_plbim) { ULONG ulFetched = 0; ITfLangBarItem *plbi[NUM_GETITEMATONCE] = {NULL}; TF_LANGBARITEMINFO lbiInfo[NUM_GETITEMATONCE]; DWORD dwStatus[NUM_GETITEMATONCE]; ULONG ul; if (SUCCEEDED(hr = _plbim->GetItems(NUM_GETITEMATONCE, plbi, lbiInfo, dwStatus, &ulFetched)) && ulFetched) { for (ul = 0; ul < ulFetched; ul++) { if (plbi[ul]) { if (SUCCEEDED(hr)) { if (!InsertItem(plbi[ul], penumcache, pgdcache, &rc, _ptw->GetThemeMargins(), &lbiInfo[ul], &dwStatus[ul])) { hr = E_FAIL; } }
plbi[ul]->Release(); } }
}
if (SUCCEEDED(hr)) _AdviseItemsSink(); } else if (IsConsole()) { CLBarInatItem *pInatItem = new CLBarInatItem(_dwThreadId); if (pInatItem) { #ifdef DEBUG
Assert(!_fIsInatItem); _fIsInatItem = TRUE; #endif
TF_LANGBARITEMINFO lbiInfo; DWORD dwStatus; pInatItem->GetInfo(&lbiInfo); pInatItem->GetStatus(&dwStatus); InsertItem(pInatItem, penumcache, pgdcache, &rc, _ptw->GetThemeMargins(), &lbiInfo, &dwStatus);
pInatItem->Release();
_AdviseItemsSink(); hr = S_OK; } }
LocateItems();
Exit:
if (penumcache) delete penumcache;
if (pgdcache) delete pgdcache;
return hr; }
//+---------------------------------------------------------------------------
//
// GetTextSize
//
//----------------------------------------------------------------------------
void CTipbarThread::GetTextSize(BSTR bstr, SIZE *psize) { HFONT hfontOld = NULL; HDC hdc = GetDC(_ptw->GetWnd());
if (SUCCEEDED(_ptw->EnsureThemeData(_ptw->GetWnd()))) { RECT rcText; LOGFONTW lf; HFONT hfont = NULL; CUIFTheme themeBtn;
Assert(IsOnNT51());
themeBtn.SetActiveTheme(L"TOOLBAR", TP_BUTTON, 0);
if (SUCCEEDED(themeBtn.OpenThemeData(_ptw->GetWnd()))) { if (SUCCEEDED(themeBtn.GetThemeFont(NULL, 0 , TMT_FONT, &lf))) if (hfont = CreateFontIndirectW(&lf)) hfontOld = (HFONT)SelectObject(hdc, hfont);
themeBtn.GetThemeTextExtent(hdc, 0 , bstr, SysStringLen(bstr),0, NULL, &rcText); } psize->cx = rcText.right; psize->cy = rcText.bottom;
if (hfontOld) SelectObject(hdc, hfontOld);
if (hfont) DeleteObject(hfont); } else { if (_ptw->GetFont()) hfontOld = (HFONT)SelectObject(hdc, _ptw->GetFont());
FLGetTextExtentPoint32( hdc, bstr, SysStringLen(bstr), psize);
if (hfontOld) SelectObject(hdc, hfontOld); }
ReleaseDC(_ptw->GetWnd(), hdc); }
//+---------------------------------------------------------------------------
//
// InsertItem
//
//----------------------------------------------------------------------------
BOOL CTipbarThread::InsertItem(ITfLangBarItem *plbi, CEnumCatCache *penumcache, CGuidDwordCache *pgdcache, RECT *prc, MARGINS *pmargins, TF_LANGBARITEMINFO *plbiInfo, DWORD *pdwStatus) { ITfLangBarItemButton *plbiButton = NULL; ITfLangBarItemBitmapButton *plbiBitmapButton = NULL; ITfLangBarItemBitmap *plbiBitmap = NULL; ITfLangBarItemBalloon *plbiBalloon = NULL; CTipbarItem *ptbItem = NULL; RECT rc = {0, 0, 0, 0}; BOOL bRet = FALSE; BSTR bstrText = NULL;
Assert(plbi);
if ((SUCCEEDED(plbi->QueryInterface(IID_ITfLangBarItemButton, (void **)&plbiButton))) || (SUCCEEDED(plbi->QueryInterface(IID_ITfLangBarItemBitmapButton, (void **)&plbiBitmapButton)))) { if (!_ptw) goto Next;
SIZE sizeText = {0,0}; DWORD dwNuiBtnStyle = 0; DWORD dwSBtnShowType = 0; int nWidth = _ptw->GetSmIconWidth() + _ptw->GetItemMargin();
if (_ptw->IsShowText()) { dwSBtnShowType |= UITBBUTTON_TEXT; HRESULT hr;
if (plbiButton) hr = plbiButton->GetText(&bstrText); else if (plbiBitmapButton) hr = plbiBitmapButton->GetText(&bstrText); else goto Next;
//
// check if it is disconnected.
//
if (!_ptw) goto Next;
if (SUCCEEDED(hr) && bstrText) {
GetTextSize(bstrText, &sizeText); //
// use height for text margin.
//
nWidth += (sizeText.cx + (sizeText.cy / 2)); } }
nWidth += pmargins->cxLeftWidth; nWidth += pmargins->cxRightWidth;
dwNuiBtnStyle = plbiInfo->dwStyle & (TF_LBI_STYLE_BTN_BUTTON | TF_LBI_STYLE_BTN_MENU | TF_LBI_STYLE_BTN_TOGGLE);
if ((dwNuiBtnStyle & (TF_LBI_STYLE_BTN_BUTTON | TF_LBI_STYLE_BTN_MENU)) == (TF_LBI_STYLE_BTN_BUTTON | TF_LBI_STYLE_BTN_MENU)) nWidth += 14;
if (!IsVertical()) { prc->right = prc->left + nWidth; } else { prc->bottom = prc->top + nWidth; dwNuiBtnStyle |= UITBBUTTON_VERTICAL; }
if (plbiButton) { ptbItem = new CTipbarButtonItem(this, plbiButton, plbiButton, 0, prc, 0, dwNuiBtnStyle, dwSBtnShowType, plbiInfo, *pdwStatus); } else if (plbiBitmapButton) { ptbItem = new CTipbarBitmapButtonItem(this, plbiBitmapButton, plbiBitmapButton, 0, prc, 0, dwNuiBtnStyle, dwSBtnShowType, plbiInfo, *pdwStatus); } else { Assert(0); goto Next; }
if (!ptbItem) goto Next;
ptbItem->Init();
if (IsVertical()) ptbItem->SetFont(_ptw->GetVerticalFont());
ptbItem->SetText((bstrText && SysStringLen(bstrText)) ? bstrText : NULL); ptbItem->SetTextSize(&sizeText);
GetSortScore(ptbItem->GetItemSortScore(), plbiInfo, penumcache, pgdcache); ptbItem->SetWidth(nWidth);
} else if (SUCCEEDED(plbi->QueryInterface(IID_ITfLangBarItemBitmap, (void **)&plbiBitmap))) { if (!_ptw) goto Next;
if (!plbiBitmap) goto Next;
SIZE sizeDefault = {_ptw->GetSmIconWidth() * 2, _ptw->GetSmIconHeight()}; SIZE size; plbiBitmap->GetPreferredSize(&sizeDefault, &size);
if (!_ptw) goto Next;
if (!IsVertical()) prc->right = prc->left + size.cx; else prc->bottom = prc->top + size.cx;
ptbItem = new CTipbarBitmapItem(this, plbiBitmap, plbiBitmap, 0, prc, 0, plbiInfo, *pdwStatus);
if (!ptbItem) goto Next;
ptbItem->Init(); GetSortScore(ptbItem->GetItemSortScore(), plbiInfo, penumcache, pgdcache); ptbItem->SetWidth(size.cx); } else if (SUCCEEDED(plbi->QueryInterface(IID_ITfLangBarItemBalloon, (void **)&plbiBalloon))) { if (!_ptw) goto Next;
if (!plbiBalloon) goto Next;
SIZE sizeDefault = {32,16}; SIZE size; plbiBalloon->GetPreferredSize(&sizeDefault, &size);
if (!_ptw) goto Next;
if (!IsVertical()) prc->right = prc->left + size.cx; else prc->bottom = prc->top + size.cx;
ptbItem = new CTipbarBalloonItem(this, plbiBalloon, plbiBalloon, 0, prc, 0, plbiInfo, *pdwStatus);
if (!ptbItem) goto Next;
ptbItem->Init();
if (IsVertical()) ptbItem->SetFont(_ptw->GetVerticalFont());
GetSortScore(ptbItem->GetItemSortScore(), plbiInfo, penumcache, pgdcache); ptbItem->SetWidth(size.cx);
}
Next: SafeReleaseClear(plbiButton); SafeReleaseClear(plbiBitmapButton); SafeReleaseClear(plbiBitmap); SafeReleaseClear(plbiBalloon);
if (!_ptw && ptbItem) { delete ptbItem; ptbItem = NULL; } if (ptbItem) { CTipbarItem **pptbItem = _rgItem.Append(1); if (pptbItem) { *pptbItem = ptbItem;
if (!IsVertical()) prc->left = prc->right; else prc->top = prc->bottom;
_nNumItem++; bRet = TRUE; } else { delete ptbItem; ptbItem = NULL; } }
if (bstrText) SysFreeString(bstrText);
return bRet; }
//+---------------------------------------------------------------------------
//
// _UninitItemList
//
//----------------------------------------------------------------------------
HRESULT CTipbarThread::_UninitItemList(BOOL fUnAdvise) { int i = 0; HRESULT hr = S_OK;
for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *pItem = _rgItem.Get(i); if (!pItem) continue;
pItem->Disconnect(); }
if (fUnAdvise) { if ((_dwThreadId == GetCurrentThreadId()) || !MyWaitForInputIdle(_dwThreadId, UTB_INPUTIDLETIMEOUT)) hr = _UnadviseItemsSink(); }
for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *pItem = _rgItem.Get(i); if (!pItem) continue;
if (_ptw) pItem->RemoveMeToUI(_ptw);
pItem->ClearConnections();
if (!_ptw) pItem->ClearWnd(); else pItem->DetachWnd(); pItem->UninitUIResource(); pItem->Release(); }
_rgItem.Clear();
RemoveAllSeparators(); return hr; }
//+---------------------------------------------------------------------------
//
// _AdviseItemsSink
//
//----------------------------------------------------------------------------
void CTipbarThread::_AdviseItemsSink() { HRESULT hr; int nCnt = _rgItem.Count(); int i = 0; ITfLangBarItemSink **pplbis = NULL; GUID *pguid = NULL; DWORD *pdwCookie = NULL;
if (!_plbim || !nCnt) goto Exit;
pplbis = new ITfLangBarItemSink*[nCnt]; if (!pplbis) goto Exit;
pguid = new GUID[nCnt]; if (!pguid) goto Exit; pdwCookie = new DWORD[nCnt]; if (!pdwCookie) goto Exit; for (i = 0; (i < nCnt) && (i < _rgItem.Count()); i++) { CTipbarItem *pItem = _rgItem.Get(i); if (!pItem) { Assert(0); goto Exit; }
pguid[i] = *pItem->GetGUID();
hr = pItem->QueryInterface(IID_ITfLangBarItemSink, (void **)&pplbis[i]); if (FAILED(hr)) { Assert(0); goto Exit; }
} if (FAILED(_plbim->AdviseItemsSink(nCnt, pplbis, pguid, pdwCookie))) goto Exit;
for (i = 0; (i < nCnt) && (i < _rgItem.Count()); i++) { CTipbarItem *pItem = _rgItem.Get(i); if (pItem) pItem->_dwlbiSinkCookie = pdwCookie[i];
pplbis[i]->Release(); }
Exit: if (pplbis) delete[] pplbis; if (pguid) delete[] pguid; if (pdwCookie) delete[] pdwCookie; }
//+---------------------------------------------------------------------------
//
// _UnadviseItemsSink
//
//----------------------------------------------------------------------------
HRESULT CTipbarThread::_UnadviseItemsSink() { int nCnt = _rgItem.Count(); int i = 0; DWORD *pdwCookie = NULL; HRESULT hr = S_OK;
if (!nCnt) goto Exit;
if (!_plbim) { hr = E_FAIL; goto Exit; } pdwCookie = new DWORD[nCnt]; if (!pdwCookie) { hr = E_OUTOFMEMORY; goto Exit; } for (i = 0; i < nCnt; i++) { CTipbarItem *pItem = _rgItem.Get(i); if (pItem) pdwCookie[i] = pItem->_dwlbiSinkCookie; } if (FAILED(hr = _plbim->UnadviseItemsSink(nCnt, pdwCookie))) goto Exit; Exit: if (pdwCookie) delete[] pdwCookie;
return hr; }
//+---------------------------------------------------------------------------
//
// IsHKLToSkipRedrawOnNoItem
//
//----------------------------------------------------------------------------
BOOL CTipbarWnd::IsHKLToSkipRedrawOnNoItem() { return IsSkipRedrawHKL(GetFocusKeyboardLayout()); }
//+---------------------------------------------------------------------------
//
// LocateItems
//
//----------------------------------------------------------------------------
void CTipbarThread::LocateItems() { int i = 0; SIZE sizeWndFrame; POINT pt; RECT rcWork; RECT rc; BOOL fOverScreen = FALSE; int nTipbarHeight;
_fSkipRedrawOnNoItem = FALSE;
if (!_ptw) return;
_ptw->GetRect(&rc);
pt.x = rc.left; pt.y = rc.top; CUIGetWorkAreaRect(pt, &rcWork);
sizeWndFrame.cx = 0; sizeWndFrame.cy = 0; if (_ptw->GetWndFrame() != NULL) _ptw->GetWndFrame()->GetFrameSize( &sizeWndFrame );
for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *ptbItem = _rgItem.Get(i); CTipbarItem *ptbMin = NULL; if (!ptbItem) continue;
int j; CItemSortScore issMin(-1, -1, -1); int nMin;
for (j = i; j < _rgItem.Count(); j++) { CTipbarItem *ptb = _rgItem.Get(j); CItemSortScore *piss = ptb->GetItemSortScore(); if (issMin > *piss) { ptbMin = ptb; issMin = *piss; nMin = j; } } if (ptbMin) { CTipbarItem **pptbItem = _rgItem.GetPtr(i); CTipbarItem **pptbMin = _rgItem.GetPtr(nMin);
*pptbItem = ptbMin; *pptbMin = ptbItem; }
}
LocateItemsAgain: RemoveAllSeparators();
nTipbarHeight = _ptw->GetTipbarHeight(); if (!IsVertical()) { rc.left = 1 + _ptw->GetGripperWidth() + sizeWndFrame.cx;
if (rc.bottom - rc.top > nTipbarHeight) { int nHeightPadding = (rc.bottom - rc.top - nTipbarHeight) / 2;
if (nHeightPadding > CY_ITEMMARGIN_THEME) nHeightPadding -= CY_ITEMMARGIN_THEME; else nHeightPadding = 0;
rc.top += (0 + sizeWndFrame.cy + nHeightPadding); rc.bottom -= (sizeWndFrame.cy + nHeightPadding); } else { rc.top = 0 + sizeWndFrame.cy; rc.bottom = nTipbarHeight - sizeWndFrame.cy; }
} else { rc.top = 1 + _ptw->GetGripperWidth() + sizeWndFrame.cx;
if (rc.right - rc.left > nTipbarHeight) { int nHeightPadding = (rc.right - rc.left - nTipbarHeight) / 2;
if (nHeightPadding > CY_ITEMMARGIN_THEME) nHeightPadding -= CY_ITEMMARGIN_THEME; else nHeightPadding = 0;
rc.left += (0 + sizeWndFrame.cy + nHeightPadding); rc.right -= (sizeWndFrame.cy + nHeightPadding); } else { rc.left = 0 + sizeWndFrame.cy; rc.right = nTipbarHeight - sizeWndFrame.cy; } }
i = 0; DWORD dwCatScore = 0; ULONG ulShownItemInPrevCat = 0; BOOL bShowToolbar = FALSE; LANGID langid = LANGID(LOWORD(HandleToLong(_ptw->GetFocusKeyboardLayout())));
CTipbarItem *ptbLastHiddenableItem = NULL;
while (i < _rgItem.Count()) { LANGBARITEMSTATE *pItemState; CTipbarItem *ptbItem = _rgItem.Get(i); DWORD dwWidth = ptbItem->GetWidth();
if (ptbItem->IsHiddenStatusControl()) { if (ptbItem->IsInHiddenStatus()) goto HideThis; } else { pItemState = _ptw->_itemList.FindItem(*ptbItem->GetGUID()); if (pItemState) { if (!pItemState->IsShown()) goto HideThis; } else { if (ptbItem->IsHiddenByDefault()) goto HideThis; } ptbLastHiddenableItem = ptbItem; }
if (_ptw->IsSFDeskband() && _ptw->IsSFNoExtraIcon()) { REFGUID rguidItem = *ptbItem->GetGUID();
if (!IsEqualGUID(rguidItem, GUID_TFCAT_TIP_KEYBOARD) && !IsEqualGUID(rguidItem, GUID_LBI_INATITEM) && !IsEqualGUID(rguidItem, GUID_LBI_CTRL) && (!IsFELangId(langid) || (IsFELangId(langid) && !ptbItem->IsShownInTray()))) goto HideThis; }
if (ptbItem->IsShownInTrayOnly()) { HideThis: RECT rcEmp = {0, 0, 0, 0}; ptbItem->SetRect(&rcEmp); ptbItem->VisibleInToolbar(FALSE); goto Next; }
if (!ptbItem->IsHiddenStatusControl()) _ptw->_itemList.StartDemotingTimer(*ptbItem->GetGUID(), FALSE);
//
// If we find an Item to be shown, we show toolbar.
// If we have only "HideOnNoOterItems" to be shown, we hide toolbar.
//
if (!ptbItem->IsHideOnNoOtherItems()) { bShowToolbar = TRUE; }
if (ulShownItemInPrevCat && (dwCatScore != ptbItem->GetCatScore())) { DWORD dwSepStyle = 0; if (!IsVertical()) rc.right = rc.left + _ptw->GetItemDistance(); else { rc.bottom = rc.top + _ptw->GetItemDistance(); dwSepStyle |= UITBSEPARATOR_VERTICAL; }
CUIFSeparator *pSep = new CUIFSeparator(_ptw, -1, &rc, dwSepStyle); if (pSep) { int nCntSep = _rgSep.Count(); pSep->Initialize();
if (_rgSep.Insert(nCntSep, 1)) { _rgSep.Set(nCntSep, pSep); } else { delete pSep; pSep = NULL; } }
if (!IsVertical()) rc.left = rc.right; else rc.top = rc.bottom;
ulShownItemInPrevCat = 0; }
dwCatScore = ptbItem->GetCatScore();
if (!IsVertical()) rc.right = rc.left + dwWidth; else rc.bottom = rc.top + dwWidth;
ptbItem->SetRect(&rc); ptbItem->VisibleInToolbar(TRUE);
if (!IsVertical()) rc.left = rc.right; else rc.top = rc.bottom;
ulShownItemInPrevCat++; Next: i++; }
// Add the last sepcarator
if (!IsVertical()) rc.right = rc.left + 4; else rc.bottom = rc.top + 4;
DWORD dwSepStyle = 0; if (IsVertical()) dwSepStyle |= UITBSEPARATOR_VERTICAL;
CUIFSeparator *pSep = new CUIFSeparator(_ptw, -1, &rc, dwSepStyle);
if (pSep) { int nCntSep = _rgSep.Count(); pSep->Initialize(); if (_rgSep.Insert(nCntSep, 1)) { _rgSep.Set(nCntSep, pSep); } else { delete pSep; pSep = NULL; } }
if (!IsVertical()) { rc.left = rc.right; // allocate the space for ctrl buttons.
rc.right = rc.left + _ptw->GetCtrlButtonWidth(); } else { rc.top = rc.bottom; // allocate the space for ctrl buttons.
rc.bottom = rc.top + _ptw->GetCtrlButtonWidth(); }
_sizeWnd.cx = rc.right + sizeWndFrame.cx; _sizeWnd.cy = rc.bottom + sizeWndFrame.cy;
if (_ptw->GetWndFrame() != NULL) { RECT rcWnd; rcWnd.left = 0; rcWnd.top = 0; rcWnd.right = _sizeWnd.cx; rcWnd.bottom = _sizeWnd.cy; _ptw->GetWndFrame()->SetRect(&rcWnd); }
//
// If the window is wider than WorkArea, we hide one item and locate items
// again.
//
if (_sizeWnd.cx > (rcWork.right - rcWork.left)) { fOverScreen = TRUE; if (ptbLastHiddenableItem) { _ptw->_itemList.SetDemoteLevel(*ptbLastHiddenableItem->GetGUID(), DL_HIDDENLEVEL1); goto LocateItemsAgain; } }
//
// Exclude caption buttons.
//
int dxOffset = 0; int dyOffset = 0; if (!IsVertical() && g_bExcludeCaptionButtons) { RECT rcWnd; _ptw->GetRect(&rcWnd); _ptw->MyClientToScreen(NULL, &rcWnd); if (_ptw->CheckExcludeCaptionButtonMode(&rcWnd, &rcWork)) { if ((rcWnd.left + _sizeWnd.cx + _ptw->GetCxDlgFrame()) > (rcWork.right - (_ptw->GetCaptionButtonWidth() * 3))) { dyOffset = 0 - rcWnd.top; dxOffset = (rcWork.right - (_ptw->GetCaptionButtonWidth() * 3)) - (rcWnd.left + _sizeWnd.cx + _ptw->GetCxDlgFrame()); _ptw->SetRect(&rcWnd); _ptw->SetExcludeCaptionButtonMode(TRUE); } } else _ptw->SetExcludeCaptionButtonMode(FALSE); }
MyMoveWnd(dxOffset, dyOffset);
if (!_ptw) goto Exit;
_ptw->_fIsItemShownInFloatingToolbar = bShowToolbar; //
// We show or hide only when toolbar is floating arround.
//
if (IsFocusThread() && _ptw->IsSFShowNormal() && !_ptw->IsInFullScreen()) { //
// Satori Hack.
//
// If the focus thread is running with Satori we don't hide
// the toolbar.
//
if (!bShowToolbar && _ptw->IsHKLToSkipRedrawOnNoItem()) { _fSkipRedrawOnNoItem = TRUE; goto Exit; }
_ptw->_fShowWindowAtTimer = bShowToolbar; _ptw->_pThreadShowWindowAtTimer = this; _ptw->_fShowOverItemBalloonAtTimer = fOverScreen;
_ptw->KillTimer(TIPWND_TIMER_SHOWWINDOW); _ptw->SetTimer(TIPWND_TIMER_SHOWWINDOW, g_uTimerElapseSHOWWINDOW);
#if 0
_ptw->Show(bShowToolbar);
//
// If the window was over the screen and hide some items,
// we show balloon tips.
//
if (fOverScreen) _ptw->ShowOverScreenSizeBalloon(); #endif
} Exit: return; }
//+---------------------------------------------------------------------------
//
// GetSortScore
//
//----------------------------------------------------------------------------
void CTipbarThread::GetSortScore(CItemSortScore *pScore, TF_LANGBARITEMINFO *plbiInfo, CEnumCatCache *penumcache, CGuidDwordCache *pgdcache) { DWORD dwSub = 0; DWORD dwCat = 0; DWORD dwCatIndex = 256; IEnumGUID *pEnum; BOOL bFound = FALSE; GUID guid; //
// check system device type button.
//
if (pEnum = penumcache->GetEnumItemsInCategory(GUID_TFCAT_CATEGORY_OF_TIP)) { while (!bFound && (pEnum->Next(1, &guid, NULL) == S_OK)) { dwCatIndex++;
if (!(dwCat = pgdcache->GetGuidDWORD(guid))) dwCat = dwCatIndex;
if (IsEqualGUID(guid, plbiInfo->guidItem)) bFound = TRUE; else { IEnumGUID *pEnumTip; if (pEnumTip = penumcache->GetEnumItemsInCategory(guid)) { CLSID clsid; while (!bFound && (pEnumTip->Next(1, &clsid, NULL) == S_OK)) {
dwSub++;
if (IsEqualGUID(clsid, plbiInfo->clsidService)) { bFound = TRUE; } } } } } }
if (bFound) { pScore->Set(dwCat, plbiInfo->ulSort, dwSub); return; }
//
// check system toolbar button.
//
if (IsEqualGUID(GUID_NULL, plbiInfo->clsidService)) { pScore->Set(0, plbiInfo->ulSort, 0); return; } else if (IsEqualGUID(CLSID_SYSTEMLANGBARITEM, plbiInfo->clsidService)) { pScore->Set(0, plbiInfo->ulSort, 0); return; } else if (IsEqualGUID(CLSID_SYSTEMLANGBARITEM2, plbiInfo->clsidService)) { pScore->Set((-1), plbiInfo->ulSort, 0); return; } else if (IsEqualGUID(CLSID_SYSTEMLANGBARITEM_KEYBOARD, plbiInfo->clsidService)) { dwCat = pgdcache->GetGuidDWORD(GUID_TFCAT_TIP_KEYBOARD); pScore->Set(dwCat, plbiInfo->ulSort, (DWORD)-1); return; } else if (IsEqualGUID(CLSID_SYSTEMLANGBARITEM_SPEECH, plbiInfo->clsidService)) { dwCat = pgdcache->GetGuidDWORD(GUID_TFCAT_TIP_SPEECH); pScore->Set(dwCat, plbiInfo->ulSort, (DWORD)-1); return; } else if (IsEqualGUID(CLSID_SYSTEMLANGBARITEM_HANDWRITING, plbiInfo->clsidService)) { dwCat = pgdcache->GetGuidDWORD(GUID_TFCAT_TIP_HANDWRITING); pScore->Set(dwCat, plbiInfo->ulSort, (DWORD)-1); return; }
pScore->Set((DWORD)-1, (DWORD)-1, (DWORD)-1); return; }
//+---------------------------------------------------------------------------
//
// UpdateItems
//
//----------------------------------------------------------------------------
BOOL CTipbarThread::UpdateItems() { int i;
_fItemChanged = FALSE;
for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *ptbItem = _rgItem.Get(i);
if (ptbItem) ptbItem->OnUpdate(TF_LBI_STATUS | TF_LBI_BTNALL | TF_LBI_BMPALL | TF_LBI_BALLOON);
}
for (i = 0; i < _rgSep.Count(); i++) { CUIFSeparator *pSep = _rgSep.Get(i); if (pSep) pSep->CallOnPaint(); } return TRUE; }
//+---------------------------------------------------------------------------
//
// MyMoveWnd
//
//----------------------------------------------------------------------------
void CTipbarThread::MyMoveWnd(int dxOffset, int dyOffset) { if (!_ptw) return;
if (_ptw->GetFocusThread() != this) return;
POINT pt; RECT rc; RECT rcWork;
_ptw->GetRect(&rc); pt.x = rc.left; pt.y = rc.top; CUIGetWorkAreaRect(pt, &rcWork);
GetWindowRect(_ptw->GetWnd(), &rc); int x = rc.left + dxOffset; int y = rc.top + dyOffset;
if (_ptw->IsInExcludeCaptionButtonMode()) { //
// now we're in exclude caption button mode.
// adjust position to the next of caption buttons.
//
if (_ptw->CheckExcludeCaptionButtonMode(&rc, &rcWork)) { x = (rcWork.right - (_ptw->GetCaptionButtonWidth() * 3)) - (_sizeWnd.cx + _ptw->GetCxDlgFrame()); y = 0; } else { _ptw->SetExcludeCaptionButtonMode(FALSE); } }
if (!IsVertical()) { _ptw->SetMoveRect(x, y, _sizeWnd.cx + _ptw->GetCxDlgFrame(), _ptw->GetTipbarHeight() + _ptw->GetCyDlgFrame()); } else { _ptw->SetMoveRect(x, y, _ptw->GetTipbarHeight() + _ptw->GetCxDlgFrame(), _sizeWnd.cy + _ptw->GetCyDlgFrame()); }
SIZE sizeWndFrame; sizeWndFrame.cx = 0; sizeWndFrame.cy = 0; if (_ptw->GetWndFrame() != NULL) _ptw->GetWndFrame()->GetFrameSize( &sizeWndFrame );
_ptw->LocateCtrlButtons();
//
// call AutoAdjustDeskBandSize() now.
// this function adjust the deskband size at first call only.
//
_ptw->AutoAdjustDeskBandSize(); }
//+---------------------------------------------------------------------------
//
// AddUIObjs
//
//----------------------------------------------------------------------------
void CTipbarThread::AddUIObjs() {
_AddRef();
int i; for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *ptbItem = _rgItem.Get(i); if (ptbItem && ptbItem->IsVisibleInToolbar()) ptbItem->AddMeToUI(_ptw);
}
AddAllSeparators(); MyMoveWnd(0, 0);
_Release(); }
//+---------------------------------------------------------------------------
//
// AddAllSeparators
//
//----------------------------------------------------------------------------
void CTipbarThread::AddAllSeparators() { int i; for (i = 0; i < _rgSep.Count(); i++) { CUIFSeparator *pSep = _rgSep.Get(i); if (pSep) _ptw->AddUIObj(pSep); } }
//+---------------------------------------------------------------------------
//
// RemoveUIObjs
//
//----------------------------------------------------------------------------
void CTipbarThread::RemoveUIObjs() { int i; for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *ptbItem = _rgItem.Get(i); if (ptbItem) ptbItem->RemoveMeToUI(_ptw); } RemoveAllSeparators(); }
//+---------------------------------------------------------------------------
//
// RemoveAllSeparators
//
//----------------------------------------------------------------------------
void CTipbarThread::RemoveAllSeparators() { int i; for (i = 0; i < _rgSep.Count(); i++) { CUIFSeparator *pSep = _rgSep.Get(i); if (pSep) { if (_ptw) _ptw->RemoveUIObj(pSep);
delete pSep; } } _rgSep.Clear(); }
//+---------------------------------------------------------------------------
//
// GetItem
//
//----------------------------------------------------------------------------
CTipbarItem *CTipbarThread::GetItem(REFGUID guid) { int i; for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *ptbItem = _rgItem.Get(i); if (ptbItem) { GUID *pguid= ptbItem->GetGUID(); if (IsEqualGUID(*pguid, guid)) return ptbItem; } } return NULL; }
//+---------------------------------------------------------------------------
//
// IsDirtyItem
//
//----------------------------------------------------------------------------
DWORD CTipbarThread::IsDirtyItem() { DWORD dwFlags = 0;
int i; for (i = 0; i < _rgItem.Count(); i++) { CTipbarItem *pItem = _rgItem.Get(i); if (pItem) dwFlags |= pItem->GetDirtyUpdateFlags(); }
return dwFlags; }
//+---------------------------------------------------------------------------
//
// CallOnUpdateHandler
//
//----------------------------------------------------------------------------
BOOL CTipbarThread::CallOnUpdateHandler() { int i; int nCnt; DWORD dwFlags; CTipbarItemGuidArray rgGuid; DWORD *pdw = NULL; BOOL bRet = TRUE;
//
// Windows Bug #367869.
//
// AddRef now because there is a change for this thread to be removed.
//
_AddRef();
#ifdef DEBUG
_fInCallOnUpdateHandler = TRUE; #endif
//
// we want to use g_pTipbarWnd instead of _ptw.
// _ptw could be disconnected during this function. If it is disconnected,
// we can not decrement the pending counter.
//
if (g_pTipbarWnd) g_pTipbarWnd->StartPendingUpdateUI();
//
// if there is no items, do nothing
//
nCnt = _rgItem.Count(); if (!nCnt) { goto Exit; }
if (!_plbim) { if (IsConsole()) { for (i = 0; i < _rgItem.Count(); i++) { DWORD dwStatus;
CTipbarItem *pItem = _rgItem.Get(i);
if (pItem && pItem->GetNotifyUI()) { dwFlags = pItem->GetDirtyUpdateFlags(); if (dwFlags & TF_LBI_STATUS) pItem->GetNotifyUI()->GetStatus(&dwStatus); else dwStatus = 0;
pItem->ClearDirtyUpdateFlags(); pItem->OnUpdateHandler(dwFlags, dwStatus); } } } goto Exit; }
rgGuid.Init(&_rgItem);
//
// if there is no dirty flag, do nothig.
//
dwFlags = IsDirtyItem(); if (!dwFlags) goto Exit;
pdw = new DWORD[nCnt]; if (!pdw) goto Exit;
//
// Clear the each item OnUpdate() request
//
for (i = 0; (i < nCnt) && (i < _rgItem.Count()); i++) { CTipbarItem *pItem = _rgItem.Get(i); if (!pItem) continue;
pItem->ClearOnUpdateRequest(); }
//
// get items flag at once.
//
if (FAILED(_plbim->GetItemsStatus(nCnt, rgGuid.GetPtr(), pdw))) { TraceMsg(TF_FUNC, "GetItemStatus failed"); bRet = FALSE; goto Exit; }
for (i = 0; (i < nCnt) && (i < _rgItem.Count()); i++) { CTipbarItem *pItem = _rgItem.Get(i); if (!pItem) continue;
//
// Skip the current item update request if the item has another OnUpdate() Request
//
if (pItem->IsNewOnUpdateRequest()) continue;
dwFlags = pItem->GetDirtyUpdateFlags(); if (dwFlags) { pItem->ClearDirtyUpdateFlags(); pItem->OnUpdateHandler(dwFlags, pdw[i]); } }
Exit: if (pdw) delete[] pdw;
//
// we want to use g_pTipbarWnd instead of _ptw.
// _ptw could be disconnected during this function. If it is disconnected,
// we can not decrement the pending counter.
//
if (g_pTipbarWnd) g_pTipbarWnd->EndPendingUpdateUI();
#ifdef DEBUG
_fInCallOnUpdateHandler = FALSE; #endif
_Release();
return bRet; }
//////////////////////////////////////////////////////////////////////////////
//
// CTipbarItem
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CTipbarItem::CTipbarItem(CTipbarThread *ptt, ITfLangBarItem *plbi, TF_LANGBARITEMINFO *plbiInfo, DWORD dwStatus) { _ptt = ptt; _lbiInfo = *plbiInfo; _plbi = plbi; _plbi->AddRef(); _fToolTipInit = FALSE; _fAddedToUI = FALSE; _fDisconnected = FALSE;
_dwDirtyUpdateFlags = (TF_LBI_STATUS | TF_LBI_BTNALL | TF_LBI_BMPALL | TF_LBI_BALLOON);
_dwStatus = dwStatus; }
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CTipbarItem::~CTipbarItem() { if (g_pTipbarWnd && g_pTipbarWnd->GetAccessible()) { g_pTipbarWnd->GetAccessible()->RemoveAccItem(this); }
SafeRelease(_plbi); }
//+---------------------------------------------------------------------------
//
// OnSetCursor
//
//----------------------------------------------------------------------------
BOOL CTipbarItem::OnSetCursor(UINT uMsg, POINT pt) { return FALSE; }
//+---------------------------------------------------------------------------
//
// GetToolTip
//
//----------------------------------------------------------------------------
LPCWSTR CTipbarItem::GetToolTip() { AddRef();
if (!_fToolTipInit) { BSTR bstrTooltip; HRESULT hr;
_fToolTipInit = TRUE; if (FAILED(hr =_plbi->GetTooltipString(&bstrTooltip))) return NULL;
if (bstrTooltip) { SetToolTip(bstrTooltip); SysFreeString(bstrTooltip); } }
LPCWSTR psz; psz = GetToolTipFromUIOBJ();
Release(); return psz; }
//+---------------------------------------------------------------------------
//
// AddedToUI
//
//----------------------------------------------------------------------------
void CTipbarItem::_AddedToUI() { if (!IsConnected()) return;
AddRef();
_fAddedToUI = TRUE; if (_dwDirtyUpdateFlags) { DWORD dwStatus; if (_dwDirtyUpdateFlags & TF_LBI_STATUS) _plbi->GetStatus(&dwStatus); else dwStatus = 0; OnUpdateHandler(_dwDirtyUpdateFlags, dwStatus); _dwDirtyUpdateFlags = 0; } if (_ptt && _ptt->_ptw && _ptt->_ptw->GetAccessible()) { _ptt->_ptw->GetAccessible()->AddAccItem(this); }
Release(); }
//+---------------------------------------------------------------------------
//
// RemovedToUI
//
//----------------------------------------------------------------------------
void CTipbarItem::_RemovedToUI() { _fAddedToUI = FALSE; if (g_pTipbarWnd && g_pTipbarWnd->GetAccessible()) { g_pTipbarWnd->GetAccessible()->RemoveAccItem(this); } }
//+---------------------------------------------------------------------------
//
// Update
//
//----------------------------------------------------------------------------
HRESULT CTipbarItem::OnUpdate(DWORD dwFlags) { DWORD dwPrevDirtyUpdateFlags = _dwDirtyUpdateFlags; if (!IsConnected()) return S_OK;
_dwDirtyUpdateFlags |= dwFlags; _fNewOnUpdateRequest = TRUE;
//
// if this item is not aded to UI or TrayIcon,
// we don't have to update anything yet.
// OnUpdate() will be called again
// when this item is added to UI or TrayIcon.
//
if ((!(dwFlags & TF_LBI_STATUS)) && !_fAddedToUI && !_fAddedToIconTray) { return S_OK; }
if (_ptt && _ptt->_ptw && _ptt->_ptw->GetWnd()) { _ptt->_ptw->KillTimer(TIPWND_TIMER_ONUPDATECALLED); _ptt->_ptw->SetTimer(TIPWND_TIMER_ONUPDATECALLED, g_uTimerElapseONUPDATECALLED); }
return S_OK; }
//+---------------------------------------------------------------------------
//
// OnUpdateHandler
//
//----------------------------------------------------------------------------
HRESULT CTipbarItem::OnUpdateHandler(DWORD dwFlags, DWORD dwStatus) { if (!IsConnected()) return S_OK;
BOOL fPrevHidden = TRUE;
if (IsHiddenStatusControl()) fPrevHidden = IsInHiddenStatus();
if (dwFlags & TF_LBI_TOOLTIP) { _fToolTipInit = FALSE; }
if (dwFlags & TF_LBI_STATUS) { BOOL fEnabled = (_dwStatus & TF_LBI_STATUS_DISABLED) ? FALSE : TRUE;
if (!IsHiddenStatusControl()) { // Assert(dwStatus & TF_LBI_STATUS_HIDDEN);
dwStatus &= ~TF_LBI_STATUS_HIDDEN; }
//
// MSAA support
//
if (_dwStatus != dwStatus) { if (_ptt && _ptt->_ptw && _ptt->_ptw->GetAccessible()) _ptt->_ptw->GetAccessible()->NotifyWinEvent( EVENT_OBJECT_STATECHANGE , this); }
_dwStatus = dwStatus;
if (fEnabled && (_dwStatus & TF_LBI_STATUS_DISABLED)) Enable(FALSE); else if (!fEnabled && !(_dwStatus & TF_LBI_STATUS_DISABLED)) Enable(TRUE); }
if (IsHiddenStatusControl()) { if (fPrevHidden != IsInHiddenStatus()) AddRemoveMeToUI(!IsInHiddenStatus() && !IsShownInTrayOnly()); }
return S_OK; }
//+---------------------------------------------------------------------------
//
// AddRemoveMeToUI
//
//----------------------------------------------------------------------------
void CTipbarItem::AddRemoveMeToUI(BOOL fAdd) { if (!IsConnected()) return;
_ptt->LocateItems(); _ptt->AddAllSeparators(); if (fAdd) { Assert(IsVisibleInToolbar()); AddMeToUI(_ptt->_ptw); } else { Assert(!IsVisibleInToolbar()); RemoveMeToUI(_ptt->_ptw); } }
//////////////////////////////////////////////////////////////////////////////
//
// CTipbarButtonItem
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// IUnknown
//
//----------------------------------------------------------------------------
STDAPI CTipbarButtonItem::QueryInterface(REFIID riid, void **ppvObj) { *ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfLangBarItemSink)) { *ppvObj = SAFECAST(this, ITfLangBarItemSink *); } else if (IsEqualIID(riid, IID_PRIV_BUTTONITEM)) { *ppvObj = this; }
if (*ppvObj) { AddRef(); return S_OK; }
return E_NOINTERFACE; }
STDAPI_(ULONG) CTipbarButtonItem::AddRef() { return ++_cRef; }
STDAPI_(ULONG) CTipbarButtonItem::Release() { _cRef--; Assert(_cRef >= 0);
if (_cRef == 0) { delete this; return 0; }
return _cRef; }
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CTipbarButtonItem::CTipbarButtonItem(CTipbarThread *ptt, ITfLangBarItem *plbi, ITfLangBarItemButton *plbiButton, DWORD dwId, RECT *prc, DWORD dwStyle, DWORD dwNuiBtnStyle, DWORD dwSBtnShowType, TF_LANGBARITEMINFO *plbiInfo, DWORD dwStatus) : CUIFToolbarButton(ptt->_ptw, dwId, prc, dwStyle, dwNuiBtnStyle, dwSBtnShowType) , CTipbarItem(ptt, plbi, plbiInfo, dwStatus) { Dbg_MemSetThisName(TEXT("CTipbarButtonItem"));
_plbiButton = plbiButton; _plbiButton->AddRef();
if (_dwStatus & TF_LBI_STATUS_DISABLED) Enable(FALSE);
_cRef = 1; }
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CTipbarButtonItem::~CTipbarButtonItem() { UninitUIResource(); SafeRelease(_plbiButton); }
//+---------------------------------------------------------------------------
//
// OnUpdateHandler
//
//----------------------------------------------------------------------------
HRESULT CTipbarButtonItem::OnUpdateHandler(DWORD dwFlags, DWORD dwStatus) { BOOL fPrevHidden = TRUE;
if (!IsConnected()) return S_OK;
HRESULT hr = S_OK; BOOL fCallPaint = FALSE; BOOL fUpdateToggleStatus = FALSE;
//
// add ref count to be safe for releasing during marshaling.
//
AddRef();
if (dwFlags & TF_LBI_ICON) { HICON hIconOld; HICON hIcon = GetIcon();
if (!_ptt || !_ptt->_ptw) goto Exit;
if (hIconOld = GetIconFromUIObj()) DestroyIcon(hIconOld);
if (hIcon) { HICON hSmIcon = NULL; int cxSmIcon; int cySmIcon;
#ifdef SCALE_ICON
cxSmIcon = GetSystemMetrics( SM_CXSMICON ); cySmIcon = GetSystemMetrics( SM_CYSMICON ); #else
cxSmIcon = 16; cySmIcon = 16; #endif
if (IsTextColorIcon()) { COLORREF rgbText = GetSysColor(COLOR_BTNTEXT); if (_ptt && _ptt->_ptw && SUCCEEDED(_pBtn->EnsureThemeData(_ptt->_ptw->GetWnd()))) { COLORREF col; if (SUCCEEDED(_pBtn->GetThemeColor(TS_NORMAL, TMT_TEXTCOLOR, &col))) rgbText = col; }
CMaskBitmap maskbmp; maskbmp.Init(hIcon, 16,16, rgbText);
ICONINFO ii; ii.fIcon = TRUE; ii.xHotspot = 0; ii.yHotspot = 0; ii.hbmMask = maskbmp.GetBmpMask(); ii.hbmColor = maskbmp.GetBmp(); hSmIcon = CreateIconIndirect(&ii);
} else { #ifdef SCALE_ICON
hSmIcon = StretchIcon(hIcon, cxSmIcon, cySmIcon); #else
hSmIcon = (HICON)CopyImage(hIcon, IMAGE_ICON, cxSmIcon, cySmIcon, LR_COPYFROMRESOURCE); #endif
}
SetIcon(hSmIcon ? hSmIcon : hIcon);
if (!IsHiddenStatusControl() && IsVisibleInToolbar()) StartDemotingTimer(FALSE);
if (hSmIcon) DestroyIcon(hIcon); } else SetIcon((HICON)NULL);
fCallPaint = TRUE; }
if ((dwFlags & TF_LBI_TEXT) && _ptt && _ptt->_ptw && _ptt->_ptw->IsShowText()) { BSTR bstr; hr = _plbiButton->GetText(&bstr);
if (FAILED(hr)) goto Exit; if (_ptt && bstr && (!GetText() || wcscmp(GetText(), bstr))) { SIZE size; _ptt->GetTextSize(bstr, &size);
SetText(SysStringLen(bstr) ? bstr : NULL);
if (_sizeText.cx != size.cx) { _dwWidth += (size.cx - _sizeText.cx); _ptt->LocateItems(); }
_sizeText = size; fCallPaint = TRUE; }
if (bstr) SysFreeString(bstr); }
if (IsHiddenStatusControl()) fPrevHidden = IsInHiddenStatus();
CTipbarItem::OnUpdateHandler(dwFlags, dwStatus);
if (_pBtn->GetToggleState() != IsToggled()) { _pBtn->SetToggleState(IsToggled()); fUpdateToggleStatus = TRUE; }
if ((dwFlags & (TF_LBI_ICON | TF_LBI_TOOLTIP)) || fUpdateToggleStatus || (fPrevHidden != IsInHiddenStatus())) { // we need to call Thread's MoveToTray too keep the order of Icons.
// _ptt->_ptw->MoveToTray();
if (_ptt && _ptt->_ptw && _ptt->_ptw->IsShowTrayIcon()) { _ptt->_ptw->KillTimer(TIPWND_TIMER_MOVETOTRAY); _ptt->_ptw->SetTimer(TIPWND_TIMER_MOVETOTRAY, g_uTimerElapseMOVETOTRAY); } }
if (fCallPaint) CallOnPaint();
Exit: Release(); return hr; }
//+---------------------------------------------------------------------------
//
// OnRightClick
//
//----------------------------------------------------------------------------
void CTipbarButtonItem::OnRightClick() { if (_plbiButton) { HRESULT hr; POINT pt; RECT rc; GetCursorPos(&pt); GetRect(&rc); MyClientToScreen(&rc);
CAsyncCall *pac = new CAsyncCall(_plbiButton);
if (pac) { hr = pac->OnClick(TF_LBI_CLK_RIGHT, pt, &rc); pac->_Release(); } else { hr = E_OUTOFMEMORY; }
if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId);
return; } } }
//+---------------------------------------------------------------------------
//
// OnLeftClick
//
//----------------------------------------------------------------------------
void CTipbarButtonItem::OnLeftClick() { if (_plbiButton) { HRESULT hr; POINT pt; RECT rc; GetCursorPos(&pt); GetRect(&rc); MyClientToScreen(&rc);
CAsyncCall *pac = new CAsyncCall(_plbiButton);
if (pac) { hr = pac->OnClick(TF_LBI_CLK_LEFT, pt, &rc); pac->_Release(); } else { hr = E_OUTOFMEMORY; }
if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId); return; }
if (!IsHiddenStatusControl() && IsVisibleInToolbar()) StartDemotingTimer(TRUE); } }
//+---------------------------------------------------------------------------
//
// OnShowMenu
//
//----------------------------------------------------------------------------
void CTipbarButtonItem::OnShowMenu() { if (!_ptt) return;
if (!_ptt->_ptw) return;
if (_plbiButton) { POINT pt; RECT rc; GetRect(&rc); pt.x = rc.left; pt.y = rc.bottom; MyClientToScreen(&pt, &rc);
DoModalMenu(&pt, &rc); } }
//+---------------------------------------------------------------------------
//
// DoModalMenu
//
//----------------------------------------------------------------------------
void CTipbarButtonItem::DoModalMenu(POINT *ppt, RECT *prc) { HRESULT hr; UINT uId; DWORD dwThreadId; CTipbarWnd *ptw;
if (!_ptt) return;
if (!_ptt->_ptw) return;
CUTBLBarMenu *pMenu = new CUTBLBarMenu(g_hInst); if (!pMenu) return;
AddRef();
hr = _plbiButton->InitMenu(pMenu); if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId); goto Exit; } if (FAILED(hr)) goto Exit;
ptw = _ptt->_ptw; dwThreadId = _ptt->_dwThreadId; Assert(!_ptt->_ptw->_pttModal); ptw->_pttModal = _ptt; ptw->StartModalInput(ptw, dwThreadId);
Assert(!ptw->_pModalMenu); ptw->_pModalMenu = pMenu; uId = pMenu->ShowPopup(ptw, *ppt, prc);
ptw->_pModalMenu = NULL;
ptw->StopModalInput(dwThreadId); ptw->_pttModal = NULL;
if (IsConnected() && (uId != CUI_MENU_UNSELECTED)) { CAsyncCall *pac = new CAsyncCall(_plbiButton); if (pac) { hr = pac->OnMenuSelect(uId); pac->_Release(); }
if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId); goto Exit; }
if (FAILED(hr)) goto Exit; }
Exit: pMenu->Release(); Release(); }
//+---------------------------------------------------------------------------
//
// MoveToTray
//
//----------------------------------------------------------------------------
void CTipbarButtonItem::MoveToTray() { if (!g_pTrayIconWnd) return;
if (IsVisibleInToolbar() && (IsShownInTray() || IsShownInTrayOnly())) { HICON hIcon = GetIcon(); if (hIcon) { SIZE size; if (IsToggled() && CUIGetIconSize(hIcon, &size)) { COLORREF cr; RECT rc; CBitmapDC hdcSrc(TRUE); CBitmapDC hdcMask(TRUE);
#if 0
CUIFScheme *pscheme = _ptt->_ptw->GetUIFScheme(); if (!pscheme) cr = GetSysColor(COLOR_HIGHLIGHT); else cr = pscheme->GetColor(UIFCOLOR_MOUSEDOWNBKGND); #else
cr = GetSysColor(COLOR_HIGHLIGHT); #endif
CSolidBrush hbrBk(cr); hdcSrc.SetDIB(size.cx, size.cy); hdcMask.SetBitmap(size.cx, size.cy, 1, 1); rc.left = 0; rc.top = 0; rc.right = size.cx; rc.bottom = size.cy; FillRect(hdcSrc, &rc, (HBRUSH)hbrBk); DrawIconEx(hdcSrc, 0, 0, hIcon, size.cx, size.cy, 0, NULL, DI_NORMAL); FillRect(hdcMask, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); ICONINFO ii; ii.fIcon = TRUE; ii.xHotspot = 0; ii.yHotspot = 0; ii.hbmMask = hdcMask.GetBitmap(); ii.hbmColor = hdcSrc.GetBitmap(); DestroyIcon(hIcon); hIcon = CreateIconIndirect(&ii); } if (hIcon) { g_pTrayIconWnd->SetIcon(*GetGUID(), IsMenuBtn(), hIcon, GetToolTip()); DestroyIcon(hIcon); } } } else { g_pTrayIconWnd->SetIcon(*GetGUID(), IsMenuBtn(), NULL, NULL); } }
//////////////////////////////////////////////////////////////////////////////
//
// CTipbarBitmapButtonItem
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// IUnknown
//
//----------------------------------------------------------------------------
STDAPI CTipbarBitmapButtonItem::QueryInterface(REFIID riid, void **ppvObj) { *ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfLangBarItemSink)) { *ppvObj = SAFECAST(this, ITfLangBarItemSink *); } else if (IsEqualIID(riid, IID_PRIV_BITMAPBUTTONITEM)) { *ppvObj = this; }
if (*ppvObj) { AddRef(); return S_OK; }
return E_NOINTERFACE; }
STDAPI_(ULONG) CTipbarBitmapButtonItem::AddRef() { return ++_cRef; }
STDAPI_(ULONG) CTipbarBitmapButtonItem::Release() { _cRef--; Assert(_cRef >= 0);
if (_cRef == 0) { delete this; return 0; }
return _cRef; }
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CTipbarBitmapButtonItem::CTipbarBitmapButtonItem(CTipbarThread *ptt, ITfLangBarItem *plbi, ITfLangBarItemBitmapButton *plbiBitmapButton, DWORD dwId, RECT *prc, DWORD dwStyle, DWORD dwNuiBtnStyle, DWORD dwSBtnShowType, TF_LANGBARITEMINFO *plbiInfo, DWORD dwStatus) : CUIFToolbarButton(ptt->_ptw, dwId, prc, dwStyle, dwNuiBtnStyle, dwSBtnShowType) , CTipbarItem(ptt, plbi, plbiInfo, dwStatus) { Dbg_MemSetThisName(TEXT("CTipbarBitmapButtonItem"));
_plbiBitmapButton = plbiBitmapButton; _plbiBitmapButton->AddRef();
if (_dwStatus & TF_LBI_STATUS_DISABLED) Enable(FALSE);
_cRef = 1;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CTipbarBitmapButtonItem::~CTipbarBitmapButtonItem() { HBITMAP hbmpOld; HBITMAP hbmpMaskOld;
hbmpOld = GetBitmap(); hbmpMaskOld = GetBitmapMask(); if (hbmpOld) DeleteObject(hbmpOld); if (hbmpMaskOld) DeleteObject(hbmpMaskOld); SetBitmap((HBITMAP)NULL); SetBitmapMask((HBITMAP)NULL);
SafeRelease(_plbiBitmapButton); }
//+---------------------------------------------------------------------------
//
// Update
//
//----------------------------------------------------------------------------
HRESULT CTipbarBitmapButtonItem::OnUpdateHandler(DWORD dwFlags, DWORD dwStatus) { if (!IsConnected()) return S_OK;
HRESULT hr = S_OK; BOOL fCallPaint = FALSE;
//
// add ref count to be safe for releasing during marshaling.
//
AddRef();
if (dwFlags & TF_LBI_BITMAP) { if (!_GetBitmapFromNUI()) { hr = E_FAIL; goto Exit; } if (!IsHiddenStatusControl() && IsVisibleInToolbar()) StartDemotingTimer(FALSE);
fCallPaint = TRUE; }
if ((dwFlags & TF_LBI_TEXT) && _ptt && _ptt->_ptw && _ptt->_ptw->IsShowText()) { BSTR bstr; hr = _plbiBitmapButton->GetText(&bstr);
if (FAILED(hr)) goto Exit; if (bstr && (!GetText() || wcscmp(GetText(), bstr))) { SIZE size; _ptt->GetTextSize(bstr, &size);
SetText(SysStringLen(bstr) ? bstr : NULL);
if (_sizeText.cx != size.cx) { _dwWidth += (size.cx - _sizeText.cx); _ptt->LocateItems(); }
_sizeText = size; fCallPaint = TRUE; }
if (bstr) SysFreeString(bstr); }
CTipbarItem::OnUpdateHandler(dwFlags, dwStatus);
if (_pBtn->GetToggleState() != IsToggled()) { _pBtn->SetToggleState(IsToggled()); }
if (fCallPaint) CallOnPaint();
Exit: Release(); return hr; }
//+---------------------------------------------------------------------------
//
// _GetBitmapFromNUI
//
//----------------------------------------------------------------------------
BOOL CTipbarBitmapButtonItem::_GetBitmapFromNUI() { BOOL bRet = FALSE; HBITMAP hbmp; HBITMAP hbmpMask; HBITMAP hbmpOld; HBITMAP hbmpMaskOld; int x, y;
hbmpOld = GetBitmap(); if (hbmpOld) DeleteObject(hbmpOld); hbmpMaskOld = GetBitmapMask(); if (hbmpMaskOld) DeleteObject(hbmpMaskOld); SetBitmap((HBITMAP)NULL); SetBitmapMask((HBITMAP)NULL);
x = GetRectRef().right - GetRectRef().left; y = GetRectRef().bottom - GetRectRef().top; if (_ptt->_ptw->IsShowText()) y -= 12;
HRESULT hr = _plbiBitmapButton->DrawBitmap(x, y, 0, &hbmp, &hbmpMask);
if (SUCCEEDED(hr)) { SetBitmap(hbmp); SetBitmapMask(hbmpMask); bRet = TRUE; }
return bRet; }
//+---------------------------------------------------------------------------
//
// OnRightClick
//
//----------------------------------------------------------------------------
void CTipbarBitmapButtonItem::OnRightClick() { if (_plbiBitmapButton) { HRESULT hr; POINT pt; RECT rc; GetCursorPos(&pt); GetRect(&rc); MyClientToScreen(&rc);
CAsyncCall *pac = new CAsyncCall(_plbiBitmapButton);
if (pac) { hr = pac->OnClick(TF_LBI_CLK_RIGHT, pt, &rc); pac->_Release(); } else { hr = E_OUTOFMEMORY; }
if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId); return; } } }
//+---------------------------------------------------------------------------
//
// OnLeftClick
//
//----------------------------------------------------------------------------
void CTipbarBitmapButtonItem::OnLeftClick() { if (_plbiBitmapButton) { HRESULT hr; POINT pt; RECT rc; GetCursorPos(&pt); GetRect(&rc); MyClientToScreen(&rc);
CAsyncCall *pac = new CAsyncCall(_plbiBitmapButton);
if (pac) { hr = pac->OnClick(TF_LBI_CLK_LEFT, pt, &rc); pac->_Release(); } else { hr = E_OUTOFMEMORY; }
if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId); return; }
if (!IsHiddenStatusControl() && IsVisibleInToolbar()) StartDemotingTimer(TRUE); } }
//+---------------------------------------------------------------------------
//
// OnShowMenu
//
//----------------------------------------------------------------------------
void CTipbarBitmapButtonItem::OnShowMenu() { if (!_ptt) return;
if (!_ptt->_ptw) return;
if (_plbiBitmapButton) { POINT pt; RECT rc; GetRect(&rc); pt.x = rc.left; pt.y = rc.bottom; MyClientToScreen(&pt, &rc); HRESULT hr; UINT uId; DWORD dwThreadId; CTipbarWnd *ptw;
CUTBLBarMenu *pMenu = new CUTBLBarMenu(g_hInst); if (!pMenu) return;
hr = _plbiBitmapButton->InitMenu(pMenu); if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId); goto Exit; } if (FAILED(hr)) goto Exit;
ptw = _ptt->_ptw; dwThreadId = _ptt->_dwThreadId;
Assert(!ptw->_pttModal); ptw->_pttModal = _ptt; ptw->StartModalInput(ptw, dwThreadId);
Assert(!ptw->_pModalMenu); ptw->_pModalMenu = pMenu; uId = pMenu->ShowPopup(ptw, pt, &rc); ptw->_pModalMenu = NULL;
ptw->StopModalInput(dwThreadId); ptw->_pttModal = NULL;
if (IsConnected() && (uId != CUI_MENU_UNSELECTED)) { Assert(_ptt); CAsyncCall *pac = new CAsyncCall(_plbiBitmapButton); if (pac) { hr = pac->OnMenuSelect(uId); pac->_Release(); } else { hr = E_OUTOFMEMORY; }
if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { ptw->OnThreadTerminate(dwThreadId); goto Exit; } if (FAILED(hr)) goto Exit; }
Exit: pMenu->Release(); } }
//////////////////////////////////////////////////////////////////////////////
//
// CTipbarBitmapItem
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// IUnknown
//
//----------------------------------------------------------------------------
STDAPI CTipbarBitmapItem::QueryInterface(REFIID riid, void **ppvObj) { *ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfLangBarItemSink)) { *ppvObj = SAFECAST(this, ITfLangBarItemSink *); } else if (IsEqualIID(riid, IID_PRIV_BITMAPITEM)) { *ppvObj = this; }
if (*ppvObj) { AddRef(); return S_OK; }
return E_NOINTERFACE; }
STDAPI_(ULONG) CTipbarBitmapItem::AddRef() { return ++_cRef; }
STDAPI_(ULONG) CTipbarBitmapItem::Release() { _cRef--; Assert(_cRef >= 0);
if (_cRef == 0) { delete this; return 0; }
return _cRef; }
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CTipbarBitmapItem::CTipbarBitmapItem(CTipbarThread *ptt, ITfLangBarItem *plbi, ITfLangBarItemBitmap *plbiBitmap, DWORD dwId, RECT *prc, DWORD dwStyle, TF_LANGBARITEMINFO *plbiInfo, DWORD dwStatus) : CUIFObject(ptt->_ptw, dwId, prc, dwStyle) , CTipbarItem(ptt, plbi, plbiInfo, dwStatus) { Dbg_MemSetThisName(TEXT("CTipbarBitmapItem"));
_plbiBitmap = plbiBitmap; _plbiBitmap->AddRef();
if (_dwStatus & TF_LBI_STATUS_DISABLED) Enable(FALSE);
_cRef = 1;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CTipbarBitmapItem::~CTipbarBitmapItem() { if (_hbmp) DeleteObject(_hbmp); SafeRelease(_plbiBitmap); }
//+---------------------------------------------------------------------------
//
// Update
//
//----------------------------------------------------------------------------
HRESULT CTipbarBitmapItem::OnUpdateHandler(DWORD dwFlags, DWORD dwStatus) { if (!IsConnected()) return S_OK;
HRESULT hr = S_OK; BOOL fCallPaint = FALSE;
//
// add ref count to be safe for releasing during marshaling.
//
AddRef();
if (dwFlags & TF_LBI_BITMAP) { if (!_GetBitmapFromNUI()) { hr = E_FAIL; goto Exit; } fCallPaint = TRUE; }
CTipbarItem::OnUpdateHandler(dwFlags, dwStatus);
if (fCallPaint) CallOnPaint();
Exit: Release(); return hr; }
//+---------------------------------------------------------------------------
//
// _GetBitmapFromNUI
//
//----------------------------------------------------------------------------
BOOL CTipbarBitmapItem::_GetBitmapFromNUI() { BOOL bRet = TRUE; HBITMAP hbmp = NULL; HBITMAP hbmpMask = NULL; int x = GetRectRef().right - GetRectRef().left; int y = GetRectRef().bottom - GetRectRef().top;
HRESULT hr = _plbiBitmap->DrawBitmap(x, y, 0, &hbmp, &hbmpMask);
if (FAILED(hr)) { if (_hbmp) DeleteObject(_hbmp); _hbmp = NULL; bRet = FALSE; }
if (!hbmpMask) { if (_hbmp) DeleteObject(_hbmp); _hbmp = hbmp; } else { CUIFScheme *pScheme = GetUIFScheme();
if (_hbmp) DeleteObject(_hbmp);
_hbmp = CreateMaskBmp(&GetRectRef(), hbmp, hbmpMask, pScheme->GetBrush(UIFCOLOR_CTRLBKGND), 0, 0); }
if (hbmp) DeleteObject(hbmp); if (hbmpMask) DeleteObject(hbmpMask);
return bRet; }
//+---------------------------------------------------------------------------
//
// OnPaint
//
//----------------------------------------------------------------------------
void CTipbarBitmapItem::OnPaint( HDC hdc ) { CBitmapDC hdcMem(TRUE); hdcMem.SetBitmap(_hbmp);
BitBlt(hdc, GetRectRef().left, GetRectRef().top, GetRectRef().right - GetRectRef().left, GetRectRef().bottom - GetRectRef().top, hdcMem, 0, 0, SRCCOPY);
}
//+---------------------------------------------------------------------------
//
// SetRect
//
//----------------------------------------------------------------------------
void CTipbarBitmapItem::SetRect( const RECT *prc ) {
if (((GetRectRef().bottom - GetRectRef().top) != (prc->bottom - prc->top)) || ((GetRectRef().right - GetRectRef().left) != (prc->right - prc->left))) { if (_hbmp) DeleteObject(_hbmp); _hbmp = NULL; }
CUIFObject::SetRect(prc); }
//+---------------------------------------------------------------------------
//
// OnRightClick
//
//----------------------------------------------------------------------------
void CTipbarBitmapItem::OnRightClick() { if (_plbiBitmap) { POINT pt; RECT rc; HRESULT hr; GetCursorPos(&pt); GetRect(&rc); MyClientToScreen(&rc);
CAsyncCall *pac = new CAsyncCall(_plbiBitmap); if (!pac) return;
hr = pac->OnClick(TF_LBI_CLK_RIGHT, pt, &rc); pac->_Release();
if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId); return; } } }
//+---------------------------------------------------------------------------
//
// OnLeftClick
//
//----------------------------------------------------------------------------
void CTipbarBitmapItem::OnLeftClick() { if (_plbiBitmap) { HRESULT hr; POINT pt; RECT rc; GetCursorPos(&pt); GetRect(&rc); MyClientToScreen(&rc);
CAsyncCall *pac = new CAsyncCall(_plbiBitmap);
if (pac) { hr = pac->OnClick(TF_LBI_CLK_LEFT, pt, &rc); pac->_Release(); } else { hr = E_OUTOFMEMORY; }
if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr)) { if (_ptt && _ptt->_ptw) _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId); return; }
if (!IsHiddenStatusControl() && IsVisibleInToolbar()) StartDemotingTimer(TRUE); } }
//////////////////////////////////////////////////////////////////////////////
//
// CTipbarCtrlButtonHolder
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CTipbarCtrlButtonHolder::CTipbarCtrlButtonHolder() { }
//+---------------------------------------------------------------------------
//
// Init
//
//+---------------------------------------------------------------------------
void CTipbarCtrlButtonHolder::Init(CTipbarWnd *ptw) { int i; RECT rc; ::SetRect(&rc, 0, 0, 0, 0);
if (ptw->IsInDeskBand()) _pcbCtrlBtn = g_cbCtrlBtnDeskBand; else _pcbCtrlBtn = g_cbCtrlBtn;
for (i = 0; i < NUM_CTRLBUTTONS; i++) { Assert(!_rgpCtrlBtn[i]);
_rgpCtrlBtn[i] = new CTipbarCtrlButton(ptw, _pcbCtrlBtn[i].dwId, &rc, _pcbCtrlBtn[i].dwStyle); _rgpCtrlBtn[i]->Initialize();
ptw->AddUIObj(_rgpCtrlBtn[i]);
if (_pcbCtrlBtn[i].dwFlags & CTRL_USEMARLETT) _rgpCtrlBtn[i]->SetFont(ptw->GetMarlett()); if (_pcbCtrlBtn[i].dwFlags & CTRL_ICONFROMRES) { if (_pcbCtrlBtn[i].dwId == ID_CBTN_CAPSKEY) { _rgpCtrlBtn[i]->SetVKey(VK_CAPITAL); } else { _rgpCtrlBtn[i]->SetVKey(VK_KANA); } _rgpCtrlBtn[i]->SetToggleStateByVKey(); } else _rgpCtrlBtn[i]->SetText(_pcbCtrlBtn[i].wsz);
} }
//+---------------------------------------------------------------------------
//
// EnableBtns
//
//+---------------------------------------------------------------------------
void CTipbarCtrlButtonHolder::EnableBtns() { int i; for (i = 0; i < NUM_CTRLBUTTONS; i++) { if (_pcbCtrlBtn[i].dwFlags & CTRL_DISABLEONWINLOGON) { if (g_bWinLogon || (g_pTipbarWnd && g_pTipbarWnd->IsSFMinmized())) _rgpCtrlBtn[i]->Enable(FALSE); else _rgpCtrlBtn[i]->Enable(TRUE); } } }
//+---------------------------------------------------------------------------
//
// UpdateBitmap
//
//+---------------------------------------------------------------------------
void CTipbarCtrlButtonHolder::UpdateBitmap(CTipbarWnd *ptw) { int i;
for (i = 0; i < NUM_CTRLBUTTONS; i++) { if (_pcbCtrlBtn[i].dwFlags & CTRL_ICONFROMRES) { HBITMAP hbmp; HBITMAP hbmpMask; COLORREF rgbText = GetSysColor(COLOR_BTNTEXT); if (SUCCEEDED(_rgpCtrlBtn[i]->EnsureThemeData(ptw->GetWnd()))) { COLORREF col; if (SUCCEEDED(_rgpCtrlBtn[i]->GetThemeColor(TS_NORMAL, TMT_TEXTCOLOR, &col))) rgbText = col; }
if (_pcbCtrlBtn[i].dwId == ID_CBTN_CAPSKEY) { if (!ptw->IsVertical()) _maskbmpCap.Init(ID_BITMAP_CAPS , KANACAPSBMP_WIDTH, KANACAPSBMP_HEIGHT, rgbText); else _maskbmpCap.Init(ID_BITMAP_CAPSV, KANACAPSBMP_HEIGHT, KANACAPSBMP_WIDTH, rgbText);
hbmp = _maskbmpCap.GetBmp(); hbmpMask = _maskbmpCap.GetBmpMask(); } else { if (!ptw->IsVertical()) _maskbmpKana.Init(ID_BITMAP_KANA , KANACAPSBMP_WIDTH, KANACAPSBMP_HEIGHT, rgbText); else _maskbmpKana.Init(ID_BITMAP_KANAV, KANACAPSBMP_HEIGHT, KANACAPSBMP_WIDTH, rgbText);
hbmp = _maskbmpKana.GetBmp(); hbmpMask = _maskbmpKana.GetBmpMask(); }
_rgpCtrlBtn[i]->SetBitmap(hbmp); _rgpCtrlBtn[i]->SetBitmapMask(hbmpMask); } } } //+---------------------------------------------------------------------------
//
// Locate
//
//+---------------------------------------------------------------------------
void CTipbarCtrlButtonHolder::Locate(CTipbarWnd *ptw, int x, int y, int nHeight, DWORD dwFlags, BOOL fVertical) { int i; int nCtrlItemHeight = (nHeight - ptw->GetCtrlItemHeightMargin() * 2) / 2; c_nColumnStart[0] = 0; c_nColumnStart[1] = CX_COLUMN0 + ptw->GetThemeMargins()->cxLeftWidth + ptw->GetThemeMargins()->cxRightWidth; c_nColumnStart[2] = CX_COLUMN1 + ptw->GetThemeMargins()->cxLeftWidth + ptw->GetThemeMargins()->cxRightWidth;
for (i = 0; i < NUM_CTRLBUTTONS; i++) { RECT rc; int nColumn = _pcbCtrlBtn[i].nColumn; int nRow = _pcbCtrlBtn[i].nRow;
if (dwFlags & TCBH_NOCOLUMN) { rc.left = 0; rc.top = 0; rc.right = 0; rc.bottom = 0; _rgpCtrlBtn[i]->SetRect(&rc); continue; } if (dwFlags & TCBH_NOCOLUMN0) { if (!_pcbCtrlBtn[i].nColumn) { rc.left = 0; rc.top = 0; rc.right = 0; rc.bottom = 0; _rgpCtrlBtn[i]->SetRect(&rc); continue; } nColumn--; } if (!fVertical) { rc.left = x + c_nColumnStart[nColumn]; rc.top = ptw->GetCtrlItemHeightMargin() + y + nRow * nCtrlItemHeight; rc.right = rc.left + c_nColumnStart[_pcbCtrlBtn[i].nColumn + 1]; rc.bottom = rc.top + nCtrlItemHeight; } else { //
// swap Row when this is the vertical langbar.
//
rc.left = ptw->GetCtrlItemHeightMargin() + x + (1 - nRow) * nCtrlItemHeight; rc.top = y + c_nColumnStart[nColumn]; rc.right = rc.left + nCtrlItemHeight; rc.bottom = rc.top + c_nColumnStart[_pcbCtrlBtn[i].nColumn + 1]; } _rgpCtrlBtn[i]->SetRect(&rc);
} }
//+---------------------------------------------------------------------------
//
// GetWidth
//
//+---------------------------------------------------------------------------
int CTipbarCtrlButtonHolder::GetWidth(DWORD dwFlags) { if (dwFlags & TCBH_NOCOLUMN) return 0;
int nWidth = 0;
if (!(dwFlags & TCBH_NOCOLUMN0)) nWidth += c_nColumnStart[1];
nWidth += c_nColumnStart[2]; return nWidth; }
//+---------------------------------------------------------------------------
//
// UpdateCapsKanaState
//
//+---------------------------------------------------------------------------
void CTipbarCtrlButtonHolder::UpdateCapsKanaState(LPARAM lParam) { int i; for (i = 0; i < NUM_CTRLBUTTONS; i++) { if (_rgpCtrlBtn[i]->GetVKey()) { if (_rgpCtrlBtn[i]->GetVKey() == VK_CAPITAL) _rgpCtrlBtn[i]->SetToggleState((lParam & TF_LBUF_CAPS) ? TRUE: FALSE); else if (_rgpCtrlBtn[i]->GetVKey() == VK_KANA) _rgpCtrlBtn[i]->SetToggleState((lParam & TF_LBUF_KANA) ? TRUE: FALSE); } } }
//+---------------------------------------------------------------------------
//
// GetCtrlBtn
//
//+---------------------------------------------------------------------------
CTipbarCtrlButton *CTipbarCtrlButtonHolder::GetCtrlBtn(DWORD dwId) { int i; for (i = 0; i < NUM_CTRLBUTTONS; i++) { if (_rgpCtrlBtn[i]->GetID() == dwId) return _rgpCtrlBtn[i]; }
return NULL; } //////////////////////////////////////////////////////////////////////////////
//
// CTipbarCtrlButton
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CTipbarCtrlButton::CTipbarCtrlButton(CTipbarWnd *ptw, DWORD dwId, const RECT *prc, DWORD dwStyle) : CUIFButton2(ptw, dwId, prc, dwStyle) { _ptw = ptw; _fInMenu = FALSE; SetToolTip(CRStr(IDS_CONTROLBUTTONTOOLTIP + dwId)); }
//+---------------------------------------------------------------------------
//
// OnLButtonUp
//
//----------------------------------------------------------------------------
void CTipbarCtrlButton::OnLButtonUp(POINT pt) { CUIFButton2::OnLButtonUp(pt); CUTBMinimizeLangBarDlg *pMinimizeDlg;
switch (GetID()) { case ID_CBTN_MINIMIZE: //
// Use Deskband object instead of system tray icon on NT51
//
if (IsOnNT51()) { if (!_ptw->IsSFDeskband()) { _ptw->GetLangBarMgr()->ShowFloating(TF_SFT_DESKBAND);
if (pMinimizeDlg = new CUTBMinimizeLangBarDlg) { pMinimizeDlg->DoModal(_ptw->GetWnd()); pMinimizeDlg->_Release(); } } break; } else { _ptw->GetLangBarMgr()->ShowFloating(TF_SFT_MINIMIZED);
if (pMinimizeDlg = new CUTBMinimizeLangBarDlg) { pMinimizeDlg->DoModal(_ptw->GetWnd()); pMinimizeDlg->_Release(); } break; }
case ID_CBTN_RESTORE: //
// Use Deskband object instead of system tray icon on NT51
//
Assert(IsOnNT51()); if (_ptw->IsSFDeskband()) { _ptw->GetLangBarMgr()->ShowFloating(TF_SFT_SHOWNORMAL); } break;
case ID_CBTN_EXTMENU: ShowExtendMenu(pt); break;
case ID_CBTN_KANAKEY: keybd_event(VK_KANA, 0, 0, 0); keybd_event(VK_KANA, 0, KEYEVENTF_KEYUP, 0); break;
case ID_CBTN_CAPSKEY: keybd_event(VK_CAPITAL, 0, 0, 0); keybd_event(VK_CAPITAL, 0, KEYEVENTF_KEYUP, 0); break; }
}
//+---------------------------------------------------------------------------
//
// ShowExtendMenu
//
//----------------------------------------------------------------------------
void CTipbarCtrlButton::ShowExtendMenu(POINT pt) { CUTBIntelliMenu *pMenu; RECT rc; GetRect(&rc); MyClientToScreen(&pt, &rc); DWORD dwThreadId; UINT uId = CUI_MENU_UNSELECTED;
if (!_ptw) return;
if (!_ptw->GetFocusThread()) return;
dwThreadId = _ptw->GetFocusThread()->_dwThreadId;
pMenu = new CUTBIntelliMenu(_ptw); if (!pMenu) return;
if (!pMenu->Init()) goto Exit;
_ptw->_pttModal = _ptw->GetFocusThread();
_ptw->StartModalInput(_ptw, dwThreadId);
_ptw->_pModalMenu = pMenu;
uId = pMenu->ShowPopup(_ptw, pt, &rc);
_ptw->_pModalMenu = NULL;
_ptw->StopModalInput(dwThreadId); _ptw->_pttModal = NULL;
if (uId != CUI_MENU_UNSELECTED) { pMenu->SelectMenuItem(uId); }
Exit: delete pMenu; }
|