diff --git a/dll/win32/msctf/msctf.spec b/dll/win32/msctf/msctf.spec index 569f8701e8b..52288129e1c 100644 --- a/dll/win32/msctf/msctf.spec +++ b/dll/win32/msctf/msctf.spec @@ -18,7 +18,7 @@ @ stdcall -stub TF_DllDetachInOther() @ stdcall -stub TF_GetGlobalCompartment(ptr) @ stub TF_GetInputScope -@ stub TF_GetLangIcon +@ stdcall -stub TF_GetLangIcon(long ptr long) @ stub TF_GetMlngHKL @ stub TF_GetMlngIconIndex @ stub TF_GetThreadFlags diff --git a/dll/win32/msutb/lang/en-US.rc b/dll/win32/msutb/lang/en-US.rc index 98a9ea10f96..3c3a7a579dd 100644 --- a/dll/win32/msutb/lang/en-US.rc +++ b/dll/win32/msutb/lang/en-US.rc @@ -16,6 +16,8 @@ BEGIN IDS_IGNORE "&Ignore" IDS_YES "&Yes" IDS_NO "&No" + + IDS_RESTORELANGBAR "Restore Language Bar" IDS_MENUWND "Menu Window" IDS_LEFTCLICK "Left Click" END diff --git a/dll/win32/msutb/msutb.cpp b/dll/win32/msutb/msutb.cpp index 9a4a96e8553..26816ecb962 100644 --- a/dll/win32/msutb/msutb.cpp +++ b/dll/win32/msutb/msutb.cpp @@ -16,6 +16,10 @@ DWORD g_dwOSInfo = 0; CRITICAL_SECTION g_cs; LONG g_DllRefCount = 0; +UINT g_uTimerElapseDOACCDEFAULTACTION = 200; + +#define TIMER_ID_DOACCDEFAULTACTION 11 + EXTERN_C void __cxa_pure_virtual(void) { ERR("__cxa_pure_virtual\n"); @@ -34,6 +38,12 @@ CMsUtbModule gModule; class CCicLibMenuItem; class CTipbarAccItem; class CUTBMenuItem; +class CMainIconItem; +class CTrayIconItem; +class CTipbarWnd; +class CButtonIconItem; + +CTipbarWnd *g_pTipbarWnd = NULL; HRESULT GetGlobalCompartment(REFGUID rguid, ITfCompartment **ppComp) { @@ -98,9 +108,8 @@ void DoCloseLangbar(void) if (pLangBarMgr) { - hr = pLangBarMgr->ShowFloating(8); + hr = pLangBarMgr->ShowFloating(TF_SFT_HIDDEN); pLangBarMgr->Release(); - pLangBarMgr = NULL; } if (SUCCEEDED(hr)) @@ -453,9 +462,50 @@ public: class CTrayIconWnd { +protected: + DWORD m_dwUnknown20; + BOOL m_bBusy; + UINT m_uCallbackMessage; + UINT m_uMsg; + HWND m_hWnd; + DWORD m_dwUnknown21[2]; + HWND m_hTrayWnd; + HWND m_hNotifyWnd; + DWORD m_dwTrayWndThreadId; + DWORD m_dwUnknown22; + HWND m_hwndProgman; + DWORD m_dwProgmanThreadId; + CMainIconItem *m_pMainIconItem; + CicArray m_Items; + UINT m_uCallbackMsg; + UINT m_uNotifyIconID; + + static BOOL CALLBACK EnumChildWndProc(HWND hWnd, LPARAM lParam); + static LRESULT CALLBACK _WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + public: - //FIXME - HWND GetNotifyWnd() { return NULL; }; + CTrayIconWnd(); + ~CTrayIconWnd(); + + BOOL RegisterClass(); + HWND CreateWnd(); + void DestroyWnd(); + + BOOL SetMainIcon(HKL hKL); + BOOL SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz); + + void RemoveAllIcon(DWORD dwFlags); + void RemoveUnusedIcons(int unknown); + + CButtonIconItem *FindIconItem(REFGUID rguid); + BOOL FindTrayEtc(); + HWND GetNotifyWnd(); + BOOL OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); + + static CTrayIconWnd *GetThis(HWND hWnd); + static void SetThis(HWND hWnd, LPCREATESTRUCT pCS); + + void CallOnDelayMsg(); }; /***********************************************************************/ @@ -469,20 +519,50 @@ protected: DWORD m_dwIconAddOrModify; BOOL m_bIconAdded; CTrayIconWnd *m_pTrayIconWnd; - DWORD m_dw; + DWORD m_dwUnknown25; GUID m_guid; RECT m_rcMenu; POINT m_ptCursor; + friend class CTrayIconWnd; +public: CTrayIconItem(CTrayIconWnd *pTrayIconWnd); + virtual ~CTrayIconItem() { } BOOL _Init(HWND hWnd, UINT uCallbackMessage, UINT uNotifyIconID, const GUID& rguid); BOOL UpdateMenuRectPoint(); BOOL RemoveIcon(); - STDMETHOD_(BOOL, SetIcon)(HICON hIcon, LPCTSTR pszTip); - STDMETHOD_(LRESULT, OnMsg)(WPARAM wParam, LPARAM lParam) { return 0; }; - STDMETHOD_(LRESULT, OnDelayMsg)(LPARAM lParam) { return 0; }; + STDMETHOD_(BOOL, SetIcon)(HICON hIcon, LPCWSTR pszTip); + STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) { return FALSE; }; + STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) { return 0; }; +}; + +/***********************************************************************/ + +class CButtonIconItem : public CTrayIconItem +{ +protected: + DWORD m_dwUnknown24; + HKL m_hKL; + friend class CTrayIconWnd; + +public: + CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24); + + STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) override; + STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override; +}; + +/***********************************************************************/ + +class CMainIconItem : public CButtonIconItem +{ +public: + CMainIconItem(CTrayIconWnd *pWnd); + + BOOL Init(HWND hWnd); + STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override; }; /*********************************************************************** @@ -780,7 +860,7 @@ STDMETHODIMP CCicLibMenu::AddMenuItem( pSubMenu->AddRef(); } - *m_MenuItems.Append(1) = pMenuItem; + m_MenuItems.Add(pMenuItem); return S_OK; } @@ -1429,8 +1509,8 @@ BOOL CUTBMenuWnd::StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget) if (::IsWindow(m_hWnd)) { - ::KillTimer(m_hWnd, 11); - ::SetTimer(m_hWnd, 11, 200, NULL); + ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION); + ::SetTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION, g_uTimerElapseDOACCDEFAULTACTION, NULL); } return TRUE; @@ -1525,9 +1605,9 @@ CUTBMenuWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) STDMETHODIMP_(void) CUTBMenuWnd::OnTimer(WPARAM wParam) { - if (wParam == 11) + if (wParam == TIMER_ID_DOACCDEFAULTACTION) { - ::KillTimer(m_hWnd, 11); + ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION); if (m_pAccessible && m_nMenuWndID) { m_pAccessible->DoDefaultActionReal(m_nMenuWndID); @@ -1633,10 +1713,10 @@ BOOL CTrayIconItem::RemoveIcon() { if (m_dwIconAddOrModify == NIM_MODIFY) { - NOTIFYICONDATA NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; + NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; NotifyIcon.uCallbackMessage = m_uCallbackMessage; - ::Shell_NotifyIcon(NIM_DELETE, &NotifyIcon); + ::Shell_NotifyIconW(NIM_DELETE, &NotifyIcon); } m_dwIconAddOrModify = NIM_ADD; @@ -1644,22 +1724,22 @@ BOOL CTrayIconItem::RemoveIcon() return TRUE; } -BOOL CTrayIconItem::SetIcon(HICON hIcon, LPCTSTR pszTip) +BOOL CTrayIconItem::SetIcon(HICON hIcon, LPCWSTR pszTip) { if (!hIcon) return FALSE; - NOTIFYICONDATA NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; + NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE; NotifyIcon.uCallbackMessage = m_uCallbackMessage; NotifyIcon.hIcon = hIcon; if (pszTip) { NotifyIcon.uFlags |= NIF_TIP; - StringCchCopy(NotifyIcon.szTip, _countof(NotifyIcon.szTip), pszTip); + StringCchCopyW(NotifyIcon.szTip, _countof(NotifyIcon.szTip), pszTip); } - ::Shell_NotifyIcon(m_dwIconAddOrModify, &NotifyIcon); + ::Shell_NotifyIconW(m_dwIconAddOrModify, &NotifyIcon); m_dwIconAddOrModify = NIM_MODIFY; m_bIconAdded = NIM_MODIFY; @@ -1676,6 +1756,347 @@ BOOL CTrayIconItem::UpdateMenuRectPoint() return TRUE; } +/*********************************************************************** + * CButtonIconItem + */ + +CButtonIconItem::CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24) + : CTrayIconItem(pWnd) +{ + m_dwUnknown24 = dwUnknown24; +} + +/// @unimplemented +STDMETHODIMP_(BOOL) CButtonIconItem::OnMsg(WPARAM wParam, LPARAM lParam) +{ + switch (lParam) + { + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + break; + default: + return TRUE; + } + + //FIXME + return TRUE; +} + +/// @unimplemented +STDMETHODIMP_(BOOL) CButtonIconItem::OnDelayMsg(UINT uMsg) +{ + //FIXME + return FALSE; +} + +/*********************************************************************** + * CMainIconItem + */ + +CMainIconItem::CMainIconItem(CTrayIconWnd *pWnd) + : CButtonIconItem(pWnd, 1) +{ +} + +BOOL CMainIconItem::Init(HWND hWnd) +{ + return CTrayIconItem::_Init(hWnd, WM_USER, 0, GUID_LBI_TRAYMAIN); +} + +/// @unimplemented +STDMETHODIMP_(BOOL) CMainIconItem::OnDelayMsg(UINT uMsg) +{ + if (!CButtonIconItem::OnDelayMsg(uMsg)) + return 0; + + if (uMsg == WM_LBUTTONDBLCLK) + { + //FIXME + //if (g_pTipbarWnd->m_dwUnknown20) + // g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL); + } + else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN) + { + //FIXME + //g_pTipbarWnd->ShowContextMenu(m_ptCursor, &m_rcClient, uMsg == WM_RBUTTONDOWN); + } + return TRUE; +} + +/*********************************************************************** + * CTrayIconWnd + */ + +CTrayIconWnd::CTrayIconWnd() +{ + m_uCallbackMsg = WM_USER + 0x1000; + m_uNotifyIconID = 0x1000; +} + +CTrayIconWnd::~CTrayIconWnd() +{ + for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) + { + auto& pItem = m_Items[iItem]; + if (pItem) + { + delete pItem; + pItem = NULL; + } + } +} + +void CTrayIconWnd::CallOnDelayMsg() +{ + for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) + { + auto pItem = m_Items[iItem]; + if (pItem && m_uCallbackMessage == pItem->m_uCallbackMessage) + { + pItem->OnDelayMsg(m_uMsg); + break; + } + } +} + +HWND CTrayIconWnd::CreateWnd() +{ + m_hWnd = ::CreateWindowEx(0, TEXT("CTrayIconWndClass"), NULL, WS_DISABLED, + 0, 0, 0, 0, NULL, NULL, g_hInst, this); + FindTrayEtc(); + + m_pMainIconItem = new(cicNoThrow) CMainIconItem(this); + if (m_pMainIconItem) + { + m_pMainIconItem->Init(m_hWnd); + m_Items.Add(m_pMainIconItem); + } + + return m_hWnd; +} + +void CTrayIconWnd::DestroyWnd() +{ + ::DestroyWindow(m_hWnd); + m_hWnd = NULL; +} + +BOOL CALLBACK CTrayIconWnd::EnumChildWndProc(HWND hWnd, LPARAM lParam) +{ + CTrayIconWnd *pWnd = (CTrayIconWnd *)lParam; + + TCHAR ClassName[60]; + ::GetClassName(hWnd, ClassName, _countof(ClassName)); + if (lstrcmp(ClassName, TEXT("TrayNotifyWnd")) != 0) + return TRUE; + + pWnd->m_hNotifyWnd = hWnd; + return FALSE; +} + +CButtonIconItem *CTrayIconWnd::FindIconItem(REFGUID rguid) +{ + for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) + { + auto pItem = m_Items[iItem]; + if (IsEqualGUID(rguid, pItem->m_guid)) + return pItem; + } + return NULL; +} + +BOOL CTrayIconWnd::FindTrayEtc() +{ + m_hTrayWnd = ::FindWindow(TEXT("Shell_TrayWnd"), NULL); + if (!m_hTrayWnd) + return FALSE; + + ::EnumChildWindows(m_hTrayWnd, EnumChildWndProc, (LPARAM)this); + if (!m_hNotifyWnd) + return FALSE; + m_dwTrayWndThreadId = ::GetWindowThreadProcessId(m_hTrayWnd, NULL); + m_hwndProgman = FindWindow(TEXT("Progman"), NULL); + m_dwProgmanThreadId = ::GetWindowThreadProcessId(m_hwndProgman, NULL); + return TRUE; +} + +HWND CTrayIconWnd::GetNotifyWnd() +{ + if (!::IsWindow(m_hNotifyWnd)) + FindTrayEtc(); + return m_hNotifyWnd; +} + +/// @unimplemented +BOOL CTrayIconWnd::OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + //FIXME + //if (g_pTipbarWnd) + // g_pTipbarWnd->AttachFocusThread(); + + for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) + { + auto pItem = m_Items[iItem]; + if (pItem) + { + if (uMsg == pItem->m_uCallbackMessage) + { + pItem->OnMsg(wParam, lParam); + return TRUE; + } + } + } + return FALSE; +} + +BOOL CTrayIconWnd::RegisterClass() +{ + WNDCLASSEX wc = { sizeof(wc) }; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.hInstance = g_hInst; + wc.hCursor = ::LoadCursor(NULL, (LPCTSTR)IDC_ARROW); + wc.lpfnWndProc = CTrayIconWnd::_WndProc; + wc.lpszClassName = TEXT("CTrayIconWndClass"); + ::RegisterClassEx(&wc); + return TRUE; +} + +void CTrayIconWnd::RemoveAllIcon(DWORD dwFlags) +{ + for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) + { + auto pItem = m_Items[iItem]; + if (dwFlags & 0x1) + { + if (IsEqualGUID(pItem->m_guid, GUID_LBI_INATITEM) || + IsEqualGUID(pItem->m_guid, GUID_LBI_CTRL)) + { + continue; + } + } + + if (dwFlags & 0x2) + { + if (IsEqualGUID(pItem->m_guid, GUID_TFCAT_TIP_KEYBOARD)) + continue; + } + + if (pItem->m_uNotifyIconID < 0x1000) + continue; + + pItem->RemoveIcon(); + } +} + +/// @unimplemented +void CTrayIconWnd::RemoveUnusedIcons(int unknown) +{ + //FIXME +} + +BOOL CTrayIconWnd::SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz) +{ + CButtonIconItem *pItem = FindIconItem(rguid); + if (!pItem) + { + if (!hIcon) + return FALSE; + pItem = new(cicNoThrow) CButtonIconItem(this, dwUnknown24); + if (!pItem) + return FALSE; + + pItem->_Init(m_hWnd, m_uCallbackMsg, m_uNotifyIconID, rguid); + m_uCallbackMsg += 2; + ++m_uNotifyIconID; + m_Items.Add(pItem); + } + + if (!hIcon) + return pItem->RemoveIcon(); + + return pItem->SetIcon(hIcon, psz); +} + +BOOL CTrayIconWnd::SetMainIcon(HKL hKL) +{ + if (!hKL) + { + m_pMainIconItem->RemoveIcon(); + m_pMainIconItem->m_hKL = NULL; + return TRUE; + } + + if (hKL != m_pMainIconItem->m_hKL) + { + WCHAR szText[64]; + HICON hIcon = TF_GetLangIcon(LOWORD(hKL), szText, _countof(szText)); + if (hIcon) + { + m_pMainIconItem->SetIcon(hIcon, szText); + ::DestroyIcon(hIcon); + } + else + { + ::LoadStringW(g_hInst, IDS_RESTORELANGBAR, szText, _countof(szText)); + hIcon = ::LoadIconW(g_hInst, MAKEINTRESOURCEW(IDI_MAINICON)); + m_pMainIconItem->SetIcon(hIcon, szText); + } + + m_pMainIconItem->m_hKL = hKL; + } + + return TRUE; +} + +CTrayIconWnd *CTrayIconWnd::GetThis(HWND hWnd) +{ + return (CTrayIconWnd *)::GetWindowLongPtr(hWnd, GWL_USERDATA); +} + +void CTrayIconWnd::SetThis(HWND hWnd, LPCREATESTRUCT pCS) +{ + if (pCS) + ::SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)pCS->lpCreateParams); + else + ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0); +} + +LRESULT CALLBACK +CTrayIconWnd::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + CTrayIconWnd *pThis; + switch (uMsg) + { + case WM_CREATE: + CTrayIconWnd::SetThis(hWnd, (LPCREATESTRUCT)lParam); + break; + case WM_DESTROY: + ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0); + break; + case WM_TIMER: + if (wParam == 100) + { + ::KillTimer(hWnd, 100); + pThis = CTrayIconWnd::GetThis(hWnd); + if (pThis) + pThis->CallOnDelayMsg(); + } + break; + default: + { + if (uMsg < WM_USER) + return ::DefWindowProc(hWnd, uMsg, wParam, lParam); + pThis = CTrayIconWnd::GetThis(hWnd); + if (pThis && pThis->OnIconMessage(uMsg, wParam, lParam)) + break; + return ::DefWindowProc(hWnd, uMsg, wParam, lParam); + } + } + return 0; +} + /*********************************************************************** * GetLibTls (MSUTB.@) * diff --git a/dll/win32/msutb/msutb.rc b/dll/win32/msutb/msutb.rc index 21964d264da..82ae823ce07 100644 --- a/dll/win32/msutb/msutb.rc +++ b/dll/win32/msutb/msutb.rc @@ -20,6 +20,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #include +IDI_MAINICON ICON "res/earth.ico" + /* UTF-8 */ #pragma code_page(65001) diff --git a/dll/win32/msutb/precomp.h b/dll/win32/msutb/precomp.h index d198ded03f1..05b2a826e27 100644 --- a/dll/win32/msutb/precomp.h +++ b/dll/win32/msutb/precomp.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/dll/win32/msutb/res/earth.ico b/dll/win32/msutb/res/earth.ico new file mode 100644 index 00000000000..7d47171f990 Binary files /dev/null and b/dll/win32/msutb/res/earth.ico differ diff --git a/dll/win32/msutb/resource.h b/dll/win32/msutb/resource.h index 6808bd02597..c3abc6b696c 100644 --- a/dll/win32/msutb/resource.h +++ b/dll/win32/msutb/resource.h @@ -7,6 +7,10 @@ #define IDS_IGNORE 104 #define IDS_YES 105 #define IDS_NO 106 + +#define IDI_MAINICON 100 + +#define IDS_RESTORELANGBAR 308 #define IDS_MENUWND 322 #define IDS_LEFTCLICK 323 diff --git a/sdk/include/psdk/msctf.idl b/sdk/include/psdk/msctf.idl index 60219b328e0..c9cc9908474 100644 --- a/sdk/include/psdk/msctf.idl +++ b/sdk/include/psdk/msctf.idl @@ -43,6 +43,7 @@ cpp_quote("EXTERN_C HRESULT WINAPI TF_InvalidAssemblyListCacheIfExist(VOID);") cpp_quote("EXTERN_C HRESULT WINAPI TF_DllDetachInOther(VOID);") cpp_quote("EXTERN_C HRESULT WINAPI TF_CreateCategoryMgr(ITfCategoryMgr **ppcat);") cpp_quote("EXTERN_C HRESULT WINAPI TF_CreateDisplayAttributeMgr(ITfDisplayAttributeMgr **ppdam);") +cpp_quote("EXTERN_C HICON WINAPI TF_GetLangIcon(LANGID LangID, LPWSTR pszText, INT cchText);") cpp_quote("EXTERN_C const GUID GUID_PROP_TEXTOWNER;") cpp_quote("EXTERN_C const GUID GUID_PROP_ATTRIBUTE;") diff --git a/sdk/include/reactos/cicero/cicutb.h b/sdk/include/reactos/cicero/cicutb.h index 9c0ff831530..916b0c4befb 100644 --- a/sdk/include/reactos/cicero/cicutb.h +++ b/sdk/include/reactos/cicero/cicutb.h @@ -8,6 +8,10 @@ #pragma once DEFINE_GUID(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0x544D6A63, 0xE2E8, 0x4752, 0xBB, 0xD1, 0x00, 0x09, 0x60, 0xBC, 0xA0, 0x83); +DEFINE_GUID(GUID_LBI_TRAYMAIN, 0xE0B724E9, 0x6F76, 0x45F7, 0xB4, 0xC1, 0xB1, 0xC0, 0xFA, 0xBC, 0xE2, 0x3E); +DEFINE_GUID(GUID_LBI_INATITEM, 0xCDBC683A, 0x55CE, 0x4717, 0xBA, 0xC0, 0x50, 0xBF, 0x44, 0xA3, 0x27, 0x0C); +DEFINE_GUID(GUID_LBI_CTRL, 0x58C99D96, 0x2F9B, 0x42CE, 0x91, 0xBE, 0x37, 0xEF, 0x18, 0x60, 0xF8, 0x82); +DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63, 0xB2F0, 0x4784, 0x8B, 0x67, 0x5E, 0x12, 0xC8, 0x70, 0x1A, 0x31); EXTERN_C LPVOID WINAPI GetLibTls(VOID); EXTERN_C BOOL WINAPI GetPopupTipbar(HWND hWnd, BOOL fWinLogon);