You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1187 lines
28 KiB
C++

// XTPSystemHelpers.cpp
//
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XTPMacros.h"
#include "XTPSystemHelpers.h"
#ifdef _XTP_INCLUDE_GRAPHICLIBRARY
#include "GraphicLibrary/zlib/zlib.h"
#endif
#pragma warning (disable : 4201)
#include <mmsystem.h>
#pragma warning (default : 4201)
#pragma message(" Automatically linking with WinMM library")
#pragma message(" (Windows Multimedia System)")
#pragma comment(lib, "winmm.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TRACE_ACCESSIBLE(x)
//===========================================================================
// CXTPSystemVersion class
//===========================================================================
CXTPSystemVersion::CXTPSystemVersion()
{
// zero memory and set struct size.
::ZeroMemory((OSVERSIONINFO*)this, sizeof(OSVERSIONINFO));
dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
// get the Windows OS version information.
::GetVersionEx((OSVERSIONINFO*)this);
}
_XTP_EXT_CLASS CXTPSystemVersion* AFXAPI XTPSystemVersion()
{
static CXTPSystemVersion instance;
return &instance;
}
bool CXTPSystemVersion::IsWin31() const
{
return (dwPlatformId == VER_PLATFORM_WIN32s);
}
bool CXTPSystemVersion::IsWin95() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
(dwMajorVersion == 4) && (dwMinorVersion < 10);
}
bool CXTPSystemVersion::IsWin98() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
EqualTo(4, 10);
}
bool CXTPSystemVersion::IsWin9x() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
}
bool CXTPSystemVersion::IsWinME() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
EqualTo(4, 90);
}
bool CXTPSystemVersion::IsWinNT4() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_NT) &&
EqualTo(4, 0);
}
bool CXTPSystemVersion::IsWin2K() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_NT) &&
EqualTo(5, 0);
}
bool CXTPSystemVersion::IsWinXP() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_NT) &&
EqualTo(5, 1);
}
bool CXTPSystemVersion::IsWin95OrGreater() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
(dwMajorVersion >= 4);
}
bool CXTPSystemVersion::IsWin98OrGreater() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
GreaterThanEqualTo(4, 10);
}
bool CXTPSystemVersion::IsWinMEOrGreater() const
{
return (dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
GreaterThanEqualTo(4, 90);
}
bool CXTPSystemVersion::IsWinNT4OrGreater() const
{
return (dwPlatformId >= VER_PLATFORM_WIN32_NT) &&
(dwMajorVersion >= 4);
}
bool CXTPSystemVersion::IsWin2KOrGreater() const
{
return (dwPlatformId >= VER_PLATFORM_WIN32_NT) &&
(dwMajorVersion >= 5);
}
bool CXTPSystemVersion::IsWinXPOrGreater() const
{
return (dwPlatformId >= VER_PLATFORM_WIN32_NT) &&
GreaterThanEqualTo(5, 1);
}
bool CXTPSystemVersion::IsWinVistaOrGreater() const
{
return (dwPlatformId >= VER_PLATFORM_WIN32_NT) &&
GreaterThanEqualTo(6, 0);
}
bool CXTPSystemVersion::IsWin7OrGreater() const
{
return (dwPlatformId >= VER_PLATFORM_WIN32_NT) &&
GreaterThanEqualTo(6, 1);
}
bool CXTPSystemVersion::GreaterThanEqualTo(const DWORD maj, const DWORD min) const
{
return (dwMajorVersion > maj) || (dwMajorVersion == maj &&
dwMinorVersion >= min);
}
bool CXTPSystemVersion::EqualTo(const DWORD maj, const DWORD min) const
{
return (dwMajorVersion == maj) && (dwMinorVersion == min);
}
DWORD CXTPSystemVersion::GetComCtlVersion() const
{
static DWORD dwVersion = 0;
if (dwVersion != 0)
return dwVersion;
CXTPModuleHandle modComCtl32(_T("COMCTL32.DLL"));
dwVersion = modComCtl32.GetVersion();
if (dwVersion == NULL)
dwVersion = MAKELONG(0, 4); // Old ComCtl32 had version 4.0
return dwVersion;
}
BOOL CXTPSystemVersion::IsLayoutRTLSupported() const
{
return IsWin2KOrGreater() || GetSystemMetrics(SM_MIDEASTENABLED);
}
BOOL CXTPSystemVersion::IsClearTypeTextQualitySupported() const
{
return IsWinXPOrGreater();
}
int CXTPSystemVersion::GetMaxCharSize() const
{
#ifdef _UNICODE
return 1;
#else
static int nMaxCharSize = -1;
if (nMaxCharSize == -1)
{
CPINFO info;
GetCPInfo(GetOEMCP(), &info);
nMaxCharSize = info.MaxCharSize;
}
return nMaxCharSize;
#endif
}
//=============================================================================
// Multi-Monitor API
//=============================================================================
_XTP_EXT_CLASS CXTPMultiMonitor* AFX_CDECL XTPMultiMonitor()
{
static CXTPMultiMonitor instance;
return &instance;
}
CXTPMultiMonitor::CXTPMultiMonitor()
{
#ifdef UNICODE
BOOL bIsPlatformNT = XTPSystemVersion()->IsWinNT4OrGreater();
#endif
m_modUser32.Init(TEXT("User32.dll"));
if (!m_modUser32)
{
TRACE(_T("WARNING: Could not locate User32.dll.\n"));
}
if (!m_modUser32 ||
!m_modUser32.GetProcAddress((FARPROC*)&m_pfnGetSystemMetrics, "GetSystemMetrics") ||
!m_modUser32.GetProcAddress((FARPROC*)&m_pfnMonitorFromWindow, "MonitorFromWindow") ||
!m_modUser32.GetProcAddress((FARPROC*)&m_pfnMonitorFromRect, "MonitorFromRect") ||
!m_modUser32.GetProcAddress((FARPROC*)&m_pfnMonitorFromPoint, "MonitorFromPoint") ||
#ifndef UNICODE
!m_modUser32.GetProcAddress((FARPROC*)&m_pfnGetMonitorInfo, "GetMonitorInfoA"))
#else
!m_modUser32.GetProcAddress((FARPROC*)&m_pfnGetMonitorInfo, bIsPlatformNT ? "GetMonitorInfoW" : "GetMonitorInfoA"))
#endif
{
m_pfnGetSystemMetrics = NULL;
m_pfnMonitorFromWindow = NULL;
m_pfnMonitorFromRect = NULL;
m_pfnMonitorFromPoint = NULL;
m_pfnGetMonitorInfo = NULL;
}
}
BOOL CXTPMultiMonitor::GetMonitorInfo(XTP_HMONITOR hMonitor, XTP_MONITORINFO* lpMonitorInfo)
{
if (hMonitor && m_pfnGetMonitorInfo)
{
lpMonitorInfo->cbSize = sizeof(XTP_MONITORINFO);
ASSERT(sizeof(XTP_MONITORINFO) == 40);
if (m_pfnGetMonitorInfo(hMonitor, lpMonitorInfo))
return TRUE;
}
return FALSE;
}
CRect CXTPMultiMonitor::GetWorkArea(XTP_HMONITOR hMonitor)
{
XTP_MONITORINFO info;
if (GetMonitorInfo(hMonitor, &info))
{
return info.rcWork;
}
RECT rcWork;
::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcWork, 0);
return rcWork;
}
CRect CXTPMultiMonitor::GetScreenArea(XTP_HMONITOR hMonitor)
{
XTP_MONITORINFO info;
if (GetMonitorInfo(hMonitor, &info))
{
return info.rcMonitor;
}
return CRect(0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN));
}
CRect CXTPMultiMonitor::GetScreenArea(HWND hWnd)
{
return GetScreenArea(m_pfnMonitorFromWindow ? m_pfnMonitorFromWindow(hWnd, 0) : 0);
}
CRect CXTPMultiMonitor::GetScreenArea(const CWnd* pWnd)
{
return GetScreenArea(pWnd->GetSafeHwnd());
}
CRect CXTPMultiMonitor::GetScreenArea(const POINT& ptScreenCoords)
{
return GetScreenArea(m_pfnMonitorFromPoint ? m_pfnMonitorFromPoint(ptScreenCoords, 0) : 0);
}
CRect CXTPMultiMonitor::GetScreenArea(LPCRECT lprcScreenCoords)
{
return GetScreenArea(m_pfnMonitorFromRect ? m_pfnMonitorFromRect(lprcScreenCoords, 0) : 0);
}
CRect CXTPMultiMonitor::GetWorkArea(HWND hWnd)
{
return GetWorkArea(m_pfnMonitorFromWindow ? m_pfnMonitorFromWindow(hWnd, 0) : 0);
}
CRect CXTPMultiMonitor::GetWorkArea(const POINT& ptScreenCoords)
{
return GetWorkArea(m_pfnMonitorFromPoint ? m_pfnMonitorFromPoint(ptScreenCoords, 0) : 0);
}
CRect CXTPMultiMonitor::GetWorkArea(LPCRECT lprcScreenCoords)
{
return GetWorkArea(m_pfnMonitorFromRect ? m_pfnMonitorFromRect(lprcScreenCoords, 0) : 0);
}
CRect CXTPMultiMonitor::GetWorkArea(const CWnd* pWnd)
{
return GetWorkArea(pWnd->GetSafeHwnd());
}
CRect CXTPMultiMonitor::GetWorkArea()
{
POINT point;
::GetCursorPos(&point);
return GetWorkArea(point);
}
//=============================================================================
// CXTPModuleHandle :
//=============================================================================
CXTPModuleHandle::CXTPModuleHandle()
: m_hModule(0)
, m_eModuleState(xtpModNone)
{
::ZeroMemory(&m_dvInfo, sizeof(m_dvInfo));
}
CXTPModuleHandle::CXTPModuleHandle(LPCTSTR lpszModuleName)
: m_hModule(0)
, m_eModuleState(xtpModNone)
{
::ZeroMemory(&m_dvInfo, sizeof(m_dvInfo));
Init(lpszModuleName);
}
CXTPModuleHandle::~CXTPModuleHandle()
{
VERIFY(FreeLibrary());
}
BOOL CXTPModuleHandle::Init(LPCTSTR lpszModuleName)
{
// first, try to obtain the module that was mapped into
// the address space of the calling process, if not found,
// attempt to load the library.
return (GetModuleHandle(lpszModuleName) || LoadLibrary(lpszModuleName));
}
BOOL CXTPModuleHandle::GetModuleHandle(LPCTSTR lpszModuleName)
{
FreeLibrary();
if ((m_hModule = ::GetModuleHandle(lpszModuleName)) != NULL)
{
m_eModuleState = xtpModMapped;
m_strModuleName = lpszModuleName;
return TRUE;
}
return FALSE;
}
BOOL CXTPModuleHandle::LoadLibrary(LPCTSTR lpszModuleName)
{
FreeLibrary();
if ((m_hModule = ::LoadLibrary(lpszModuleName)) != NULL)
{
m_eModuleState = xtpModLoaded;
m_strModuleName = lpszModuleName;
return TRUE;
}
return FALSE;
}
BOOL CXTPModuleHandle::FreeLibrary()
{
BOOL bRet = TRUE;
if (m_hModule && m_eModuleState == xtpModLoaded)
bRet = ::FreeLibrary(m_hModule);
m_hModule = NULL;
m_eModuleState = xtpModNone;
m_strModuleName.Empty();
return bRet;
}
BOOL CXTPModuleHandle::GetVersionInfo()
{
if (!m_hModule)
return FALSE;
m_dvInfo.cbSize = sizeof(m_dvInfo);
typedef HRESULT (WINAPI* PFNDLLVERSIONINFO)(XTP_DLLVERSIONINFO*);
PFNDLLVERSIONINFO pfn = (PFNDLLVERSIONINFO)::GetProcAddress(m_hModule, "DllGetVersion");
if (pfn != NULL)
{
return (pfn(&m_dvInfo) != NOERROR);
}
return FALSE;
}
DWORD CXTPModuleHandle::GetVersion()
{
if (m_dvInfo.cbSize == 0)
GetVersionInfo();
DWORD dwModVer = MAKELONG(m_dvInfo.dwMinorVersion, m_dvInfo.dwMajorVersion);
ASSERT(HIWORD(dwModVer) <= 0xFFFF);
ASSERT(LOWORD(dwModVer) <= 0xFFFF);
return dwModVer;
}
BOOL CXTPModuleHandle::GetProcAddress(FARPROC* ppFnPtr, LPCSTR lpProcName, DWORD dwMinVer /*= NULL*/)
{
if (!m_hModule)
return FALSE;
if (dwMinVer != NULL)
{
DWORD dwModVer = GetVersion();
if ((HIWORD(dwMinVer) > HIWORD(dwModVer)) ||
(HIWORD(dwMinVer) == HIWORD(dwModVer)) &&
(LOWORD(dwMinVer) > LOWORD(dwModVer)))
{
*ppFnPtr = NULL;
return FALSE;
}
}
*ppFnPtr = ::GetProcAddress(m_hModule, lpProcName);
return (*ppFnPtr != NULL);
}
//=============================================================================
// CXTPCriticalSection
//=============================================================================
CXTPCriticalSection::CXTPCriticalSection()
{
::InitializeCriticalSection(&m_csMutex);
}
CXTPCriticalSection::~CXTPCriticalSection()
{
::DeleteCriticalSection(&m_csMutex);
}
void CXTPCriticalSection::EnterCritical()
{
::EnterCriticalSection(&m_csMutex);
}
void CXTPCriticalSection::LeaveCritical()
{
::LeaveCriticalSection(&m_csMutex);
}
//=============================================================================
// CXTPLockGuard
//=============================================================================
CXTPLockGuard::CXTPLockGuard(CRITICAL_SECTION& key)
: m_key(key)
{
LockThread();
}
CXTPLockGuard::~CXTPLockGuard()
{
UnLockThread();
}
void CXTPLockGuard::LockThread()
{
::EnterCriticalSection(&m_key);
}
void CXTPLockGuard::UnLockThread()
{
::LeaveCriticalSection(&m_key);
}
//////////////////////////////////////////////////////////////////////////
// CXTPAccessible
CXTPAccessible::CXTPAccessible()
{
m_pNotifyWinEvent = NULL;
m_pLresultFromObject = NULL;
m_pAccessibleObjectFromWindow = NULL;
m_hOleAcc = NULL;
m_hUser32 = NULL;
}
CXTPAccessible::~CXTPAccessible()
{
if (m_hOleAcc && m_hOleAcc != INVALID_HANDLE_VALUE)
{
FreeLibrary(m_hOleAcc);
}
}
void CXTPAccessible::AccessibleNotifyWinEvent(DWORD event, HWND hwnd, LONG idObject, LONG idChild)
{
if (m_hUser32 == INVALID_HANDLE_VALUE)
return;
if (m_hUser32 == NULL)
{
m_hUser32 = GetModuleHandle(_T("user32.dll"));
}
if (m_pNotifyWinEvent == NULL && m_hUser32)
{
m_pNotifyWinEvent = (LPFNNOTIFYWINEVENT)GetProcAddress(m_hUser32, "NotifyWinEvent");
if (!m_pNotifyWinEvent)
{
m_hUser32 = (HMODULE)INVALID_HANDLE_VALUE;
}
}
if (m_pNotifyWinEvent != NULL)
{
m_pNotifyWinEvent(event, hwnd, idObject, idChild);
}
}
HRESULT CXTPAccessible::AccessibleObjectFromWindow(HWND hwnd, DWORD dwId, REFIID riid, void** ppvObject)
{
if (m_hOleAcc == INVALID_HANDLE_VALUE)
return E_FAIL;
if (m_hOleAcc == NULL)
{
m_hOleAcc = LoadLibrary(_T("oleacc.dll"));
}
if (m_hOleAcc != NULL && m_pAccessibleObjectFromWindow == NULL)
{
m_pAccessibleObjectFromWindow = (LPFNACCESSIBLEOBJECTFROMWINDOW)GetProcAddress(m_hOleAcc, "AccessibleObjectFromWindow");
if (!m_pAccessibleObjectFromWindow)
{
FreeLibrary(m_hOleAcc);
m_hOleAcc = (HMODULE)INVALID_HANDLE_VALUE;
m_pLresultFromObject = NULL;
m_pAccessibleObjectFromWindow = NULL;
}
}
if (m_pAccessibleObjectFromWindow)
{
return m_pAccessibleObjectFromWindow(hwnd, dwId, riid, ppvObject);
}
return E_FAIL;
}
LRESULT CXTPAccessible::LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN punk)
{
if (m_hOleAcc == INVALID_HANDLE_VALUE)
return E_FAIL;
if (m_hOleAcc == NULL)
{
m_hOleAcc = LoadLibrary(_T("oleacc.dll"));
}
if (m_hOleAcc != NULL && m_pLresultFromObject == NULL)
{
m_pLresultFromObject = (LPFNLRESULTFROMOBJECT)GetProcAddress(m_hOleAcc, "LresultFromObject");
if (!m_pLresultFromObject)
{
FreeLibrary(m_hOleAcc);
m_hOleAcc = (HMODULE)INVALID_HANDLE_VALUE;
m_pLresultFromObject = NULL;
m_pAccessibleObjectFromWindow = NULL;
}
}
if (m_pLresultFromObject)
{
return m_pLresultFromObject(riid, wParam, punk);
}
return E_FAIL;
}
long CXTPAccessible::GetChildIndex(VARIANT* varChild)
{
if (!varChild) return -1;
if (varChild->vt == VT_EMPTY)
return CHILDID_SELF;
if (varChild->vt == VT_I4) return V_I4(varChild);
if (varChild->vt == VT_I2) return V_I2(varChild);
if (varChild->vt == (VT_I4 | VT_BYREF) && V_I4REF(varChild)) return *V_I4REF(varChild);
if (varChild->vt == (VT_I2 | VT_BYREF) && V_I2REF(varChild)) return *V_I2REF(varChild);
if (varChild->vt == (VT_VARIANT | VT_BYREF)) return GetChildIndex(varChild->pvarVal);
return -1;
}
STDMETHODIMP_(ULONG) CXTPAccessible::XAccessible::AddRef()
{
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible)
return (ULONG)pThis->GetAccessible()->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CXTPAccessible::XAccessible::Release()
{
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible)
return (ULONG)pThis->GetAccessible()->ExternalRelease();
}
STDMETHODIMP CXTPAccessible::XAccessible::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible)
return (HRESULT)pThis->GetAccessible()->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP CXTPAccessible::XAccessible::GetTypeInfoCount(
unsigned int*)
{
return E_NOTIMPL;
}
STDMETHODIMP CXTPAccessible::XAccessible::GetTypeInfo(
unsigned int, LCID, ITypeInfo**)
{
return E_NOTIMPL;
}
STDMETHODIMP CXTPAccessible::XAccessible::GetIDsOfNames(
REFIID, LPOLESTR*, unsigned int, LCID, DISPID*)
{
return E_NOTIMPL;
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accParent(IDispatch* FAR* ppdispParent)
{
TRACE_ACCESSIBLE(_T("get_accParent\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleParent(ppdispParent);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accChildCount(long FAR* pChildCount)
{
TRACE_ACCESSIBLE(_T("get_accChildCount\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleChildCount(pChildCount);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accChild(VARIANT varChild, IDispatch* FAR* ppdispChild)
{
TRACE_ACCESSIBLE(_T("get_accChild\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleChild(varChild, ppdispChild);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accName(VARIANT varChild, BSTR* pszName)
{
TRACE_ACCESSIBLE(_T("get_accName\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleName(varChild, pszName);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accValue(VARIANT varChild, BSTR* pszValue)
{
TRACE_ACCESSIBLE(_T("get_accValue\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleValue(varChild, pszValue);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accDescription(VARIANT varChild, BSTR FAR* pszDescription)
{
TRACE_ACCESSIBLE(_T("get_accDescription\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleDescription(varChild, pszDescription);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accRole(VARIANT varChild, VARIANT* pvarRole)
{
TRACE_ACCESSIBLE(_T("get_accRole\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleRole(varChild, pvarRole);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accState(VARIANT varChild, VARIANT* pvarState)
{
TRACE_ACCESSIBLE(_T("get_accState\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleState(varChild, pvarState);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accHelp(VARIANT varChild, BSTR* pszHelp)
{
TRACE_ACCESSIBLE(_T("get_accHelp\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleHelp(varChild, pszHelp);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accHelpTopic(BSTR* pszHelpFile, VARIANT varChild, long* pidTopic)
{
TRACE_ACCESSIBLE(_T("get_accHelpTopic\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleHelpTopic(pszHelpFile, varChild, pidTopic);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accKeyboardShortcut(VARIANT varChild, BSTR* pszKeyboardShortcut)
{
TRACE_ACCESSIBLE(_T("get_accKeyboardShortcut\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleKeyboardShortcut(varChild, pszKeyboardShortcut);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accFocus(VARIANT FAR* pvarFocusChild)
{
TRACE_ACCESSIBLE(_T("get_accFocus\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleFocus(pvarFocusChild);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accSelection(VARIANT FAR* pvarSelectedChildren)
{
TRACE_ACCESSIBLE(_T("get_accSelection\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleSelection(pvarSelectedChildren);
}
STDMETHODIMP CXTPAccessible::XAccessible::get_accDefaultAction(VARIANT varChild, BSTR* pszDefaultAction)
{
TRACE_ACCESSIBLE(_T("get_accDefaultAction\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->GetAccessibleDefaultAction(varChild, pszDefaultAction);
}
STDMETHODIMP CXTPAccessible::XAccessible::accSelect(long flagsSelect, VARIANT varChild)
{
TRACE_ACCESSIBLE(_T("accSelect\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->AccessibleSelect(flagsSelect, varChild);
}
STDMETHODIMP CXTPAccessible::XAccessible::accLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild)
{
TRACE_ACCESSIBLE(_T("accLocation\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->AccessibleLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varChild);
}
STDMETHODIMP CXTPAccessible::XAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT* pvarEndUpAt)
{
TRACE_ACCESSIBLE(_T("accNavigate\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->AccessibleNavigate(navDir, varStart, pvarEndUpAt);
}
STDMETHODIMP CXTPAccessible::XAccessible::accHitTest(long xLeft, long yTop, VARIANT* pvarID)
{
TRACE_ACCESSIBLE(_T("accHitTest\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->AccessibleHitTest(xLeft, yTop, pvarID);
}
STDMETHODIMP CXTPAccessible::XAccessible::accDoDefaultAction(VARIANT varChild)
{
TRACE_ACCESSIBLE(_T("accDoDefaultAction\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->AccessibleDoDefaultAction(varChild);
}
STDMETHODIMP CXTPAccessible::XAccessible::put_accName(VARIANT varChild, BSTR szName)
{
TRACE_ACCESSIBLE(_T("put_accName\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->PutAccessibleName(varChild, szName);
}
STDMETHODIMP CXTPAccessible::XAccessible::put_accValue(VARIANT varChild, BSTR pszValue)
{
TRACE_ACCESSIBLE(_T("put_accValue\n"));
METHOD_PROLOGUE_EX_(CXTPAccessible, ExternalAccessible);
return pThis->PutAccessibleValue(varChild, pszValue);
}
STDMETHODIMP CXTPAccessible::XAccessible::Invoke(
DISPID /*dispid*/, REFIID, LCID, unsigned short /*wFlags*/,
DISPPARAMS* /*pDispParams*/, VARIANT* /*pvarResult*/,
EXCEPINFO*, unsigned int*)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleParent(IDispatch** /*ppdispParent*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleChildCount(long* /*pcountChildren*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleChild(VARIANT /*varChild*/, IDispatch** /*ppdispChild*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleName(VARIANT /*varChild*/, BSTR* /*pszName*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleValue(VARIANT /*varChild*/, BSTR* /*pszValue*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleDescription(VARIANT /*varChild*/, BSTR* /*pszDescription*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleRole(VARIANT /*varChild*/, VARIANT* /*pvarRole*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleState(VARIANT /*varChild*/, VARIANT* /*pvarState*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleHelp(VARIANT /*varChild*/, BSTR* /*pszHelp*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleHelpTopic(BSTR* /*pszHelpFile*/, VARIANT /*varChild*/, long* /*pidTopic*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleKeyboardShortcut(VARIANT /*varChild*/, BSTR* /*pszKeyboardShortcut*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::GetAccessibleFocus(VARIANT* /*pvarChild*/)
{
return S_FALSE;
}
HRESULT CXTPAccessible::GetAccessibleSelection(VARIANT* /*pvarChildren*/)
{
return S_FALSE;
}
HRESULT CXTPAccessible::GetAccessibleDefaultAction(VARIANT /*varChild*/, BSTR* /*pszDefaultAction*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::AccessibleSelect(long /*flagsSelect*/, VARIANT /*varChild*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::AccessibleLocation(long* /*pxLeft*/, long* /*pyTop*/, long* /*pcxWidth*/, long* /*pcyHeight*/, VARIANT /*varChild*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::AccessibleNavigate(long /*navDir*/, VARIANT /*varStart*/, VARIANT* /*pvarEndUpAt*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::AccessibleHitTest(long /*xLeft*/, long /*yTop*/, VARIANT* /*pvarChild*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::AccessibleDoDefaultAction(VARIANT /*varChild*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::PutAccessibleName(VARIANT /*varChild*/, BSTR /*szName*/)
{
return E_NOTIMPL;
}
HRESULT CXTPAccessible::PutAccessibleValue(VARIANT /*varChild*/, BSTR /*szValue*/)
{
return E_NOTIMPL;
}
CCmdTarget* CXTPAccessible::GetAccessible()
{
ASSERT(FALSE);
return NULL;
}
//////////////////////////////////////////////////////////////////////////
// CXTPSoundManager
CXTPSoundManager::CXTPSoundManager()
{
m_hThread = 0;
m_bSystemSounds = TRUE;
m_bTerminate = FALSE;
m_soundState = xtpSoundNone;
m_bSoundAvailable = TRUE;
m_hEvent = CreateEvent(NULL, TRUE, FALSE, 0);
}
CXTPSoundManager* AFX_CDECL XTPSoundManager()
{
static CXTPSoundManager s_managerInstance;
return &s_managerInstance;
}
CXTPSoundManager::~CXTPSoundManager()
{
StopThread();
CloseHandle(m_hEvent);
}
DWORD WINAPI CXTPSoundManager::SoundThreadProc(LPVOID lp)
{
CXTPSoundManager* pSoundManager = (CXTPSoundManager*)lp;
XTPSoundManagerState& soundState = pSoundManager->m_soundState;
while (!pSoundManager->m_bTerminate)
{
switch (soundState)
{
case xtpSoundMenuCommand:
::PlaySound (_T("MenuCommand"), NULL, (SND_SYNC | SND_NODEFAULT | SND_ALIAS | SND_NOWAIT));
break;
case xtpSoundMenuPopup:
::PlaySound (_T("MenuPopup"), NULL, (SND_SYNC | SND_NODEFAULT | SND_ALIAS | SND_NOWAIT));
break;
}
soundState = xtpSoundNone;
WaitForSingleObject(pSoundManager->m_hEvent, INFINITE);
if (!pSoundManager->m_bTerminate)
ResetEvent(pSoundManager->m_hEvent);
}
::PlaySound(NULL, NULL, SND_PURGE);
return 0;
}
void CXTPSoundManager::StartThread()
{
ASSERT (m_hThread == NULL);
m_soundState = xtpSoundNone;
m_bTerminate = FALSE;
::ResetEvent(m_hEvent);
DWORD dwThreadID;
m_hThread = ::CreateThread(NULL, 0, SoundThreadProc, this, CREATE_SUSPENDED, &dwThreadID);
if (m_hThread != NULL)
{
::SetThreadPriority(m_hThread, THREAD_PRIORITY_BELOW_NORMAL);
::ResumeThread(m_hThread);
}
}
void CXTPSoundManager::StopThread()
{
if (m_hThread)
{
m_bTerminate = TRUE;
SetEvent(m_hEvent);
DWORD dwCount = 0, dwExitCode = 0;
while (GetExitCodeThread(m_hThread, &dwExitCode) && dwExitCode == STILL_ACTIVE)
{
dwCount++;
if (dwCount > 10)
{
TerminateThread(m_hThread, 0);
break;
}
::WaitForSingleObject(m_hThread, 100);
}
::CloseHandle(m_hThread);
m_hThread = 0;
}
}
void CXTPSoundManager::PlaySystemSound(XTPSoundManagerState state)
{
if (m_bSystemSounds && m_bSoundAvailable)
{
if (m_hThread == 0)
StartThread();
m_soundState = state;
SetEvent(m_hEvent);
}
}
void CXTPSoundManager::EnableSystemSounds(BOOL bEnable)
{
m_bSystemSounds = bEnable;
}
//////////////////////////////////////////////////////////////////////////
// XTPGetThread
CWinThread* AFX_CDECL XTPGetThread()
{
CWinThread* pThread = AfxGetThread();
if (pThread != NULL)
return pThread;
return AfxGetApp();
}
//////////////////////////////////////////////////////////////////////////
// CXTPZipMemFile
#define ZIP_HEADER ('Z' + ('I' << 8) + ('P' << 16) + ('!' << 24))
CXTPZipMemFile::CXTPZipMemFile()
{
}
CXTPZipMemFile::CXTPZipMemFile(BYTE* lpBuffer, UINT nBufferSize)
{
AttachCompressedBuffer(lpBuffer, nBufferSize);
}
CXTPZipMemFile::~CXTPZipMemFile()
{
}
void CXTPZipMemFile::AttachCompressedBuffer(BYTE* lpBuffer, UINT nBufferSize, BOOL bAutoDelete)
{
#ifdef ZLIB_H
ZIPBUFFERINFO* pbi = (ZIPBUFFERINFO*)lpBuffer;
if (nBufferSize < sizeof(ZIPBUFFERINFO) ||
pbi->bh.dwType != ZIP_HEADER)
{
Attach(lpBuffer, nBufferSize);
m_bAutoDelete = bAutoDelete;
return;
}
DWORD dwDestCount = pbi->bh.dwSize;
BYTE* lpBufferDest = (BYTE*)malloc(dwDestCount);
uncompress(lpBufferDest, &dwDestCount, (LPBYTE)&pbi->bBuffer, nBufferSize - sizeof(ZIPBUFFERHEADER));
ASSERT(dwDestCount == pbi->bh.dwSize);
Attach(lpBufferDest, dwDestCount);
m_bAutoDelete = TRUE;
if (bAutoDelete)
{
free(lpBuffer);
}
#else
Attach(lpBuffer, nBufferSize);
m_bAutoDelete = bAutoDelete;
#endif
}
BOOL CXTPZipMemFile::OpenCompressedFile(LPCTSTR lpszFileName)
{
CFile file;
if (!file.Open(lpszFileName, CFile::modeRead))
return FALSE;
UINT nSize = (UINT)file.GetLength();
LPBYTE lpBuffer = (LPBYTE)malloc(nSize);
file.Read(lpBuffer, nSize);
file.Close();
AttachCompressedBuffer(lpBuffer, nSize, TRUE);
return TRUE;
}
void CXTPZipMemFile::DetachCompressedBuffer(BYTE*& lpBuffer, DWORD& dwCount)
{
dwCount = (DWORD)GetPosition();
lpBuffer = Detach();
#ifdef ZLIB_H
if (dwCount < 20)
return;
ZIPBUFFERINFO* pbi = (ZIPBUFFERINFO*)malloc(dwCount + sizeof(ZIPBUFFERHEADER));
if (!pbi)
return;
DWORD dwDestCount = dwCount;
if (compress((LPBYTE)&pbi->bBuffer, &dwDestCount, lpBuffer, dwCount) != Z_OK)
{
free(pbi);
return;
}
pbi->bh.dwType = ZIP_HEADER;
pbi->bh.dwSize = dwCount;
free(lpBuffer);
dwCount = dwDestCount + sizeof(ZIPBUFFERHEADER);
lpBuffer = (LPBYTE)pbi;
#endif
}