diff options
Diffstat (limited to 'vcl/win/source/gdi/salnativewidgets-luna.cxx')
-rw-r--r-- | vcl/win/source/gdi/salnativewidgets-luna.cxx | 1264 |
1 files changed, 1264 insertions, 0 deletions
diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx new file mode 100644 index 000000000000..d1f11433d532 --- /dev/null +++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx @@ -0,0 +1,1264 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#define _SV_SALNATIVEWIDGETS_CXX + +#include "svsys.h" +#include "salgdi.h" +#include "saldata.hxx" +#include "vcl/svapp.hxx" + +#include "rtl/ustring.h" +#include "osl/module.h" + +#include "uxtheme.h" +#include "vssym32.h" + +#include <map> +#include <string> + +using namespace rtl; +using namespace std; + +typedef map< wstring, HTHEME > ThemeMap; +static ThemeMap aThemeMap; + + +/**************************************************** + wrap visual styles API to avoid linking against it + it is not available on all Windows platforms +*****************************************************/ + +class VisualStylesAPI +{ +private: + typedef HTHEME (WINAPI * OpenThemeData_Proc_T) ( HWND hwnd, LPCWSTR pszClassList ); + typedef HRESULT (WINAPI * CloseThemeData_Proc_T) ( HTHEME hTheme ); + typedef HRESULT (WINAPI * GetThemeBackgroundContentRect_Proc_T) ( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect ); + typedef HRESULT (WINAPI * DrawThemeBackground_Proc_T) ( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect ); + typedef HRESULT (WINAPI * DrawThemeText_Proc_T) ( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect ); + typedef HRESULT (WINAPI * GetThemePartSize_Proc_T) ( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT *prc, THEMESIZE eSize, SIZE *psz ); + + OpenThemeData_Proc_T lpfnOpenThemeData; + CloseThemeData_Proc_T lpfnCloseThemeData; + GetThemeBackgroundContentRect_Proc_T lpfnGetThemeBackgroundContentRect; + DrawThemeBackground_Proc_T lpfnDrawThemeBackground; + DrawThemeText_Proc_T lpfnDrawThemeText; + GetThemePartSize_Proc_T lpfnGetThemePartSize; + + oslModule mhModule; + +public: + VisualStylesAPI(); + ~VisualStylesAPI(); + BOOL IsAvailable() { return (mhModule != NULL); } + + HTHEME OpenThemeData( HWND hwnd, LPCWSTR pszClassList ); + HRESULT CloseThemeData( HTHEME hTheme ); + HRESULT GetThemeBackgroundContentRect( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect ); + HRESULT DrawThemeBackground( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect ); + HRESULT DrawThemeText( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect ); + HRESULT GetThemePartSize( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT *prc, THEMESIZE eSize, SIZE *psz ); +}; + +static VisualStylesAPI vsAPI; + +VisualStylesAPI::VisualStylesAPI() +{ + OUString aLibraryName( RTL_CONSTASCII_USTRINGPARAM( "uxtheme.dll" ) ); + mhModule = osl_loadModule( aLibraryName.pData, SAL_LOADMODULE_DEFAULT ); + + if ( mhModule ) + { + lpfnOpenThemeData = (OpenThemeData_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "OpenThemeData" ); + lpfnCloseThemeData = (CloseThemeData_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "CloseThemeData" ); + lpfnGetThemeBackgroundContentRect = (GetThemeBackgroundContentRect_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "GetThemeBackgroundContentRect" ); + lpfnDrawThemeBackground = (DrawThemeBackground_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "DrawThemeBackground" ); + lpfnDrawThemeText = (DrawThemeText_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "DrawThemeText" ); + lpfnGetThemePartSize = (GetThemePartSize_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "GetThemePartSize" ); + } + else + { + lpfnOpenThemeData = NULL; + lpfnCloseThemeData = NULL; + lpfnGetThemeBackgroundContentRect = NULL; + lpfnDrawThemeBackground = NULL; + lpfnDrawThemeText = NULL; + lpfnGetThemePartSize = NULL; + } +} +VisualStylesAPI::~VisualStylesAPI() +{ + if( mhModule ) + osl_unloadModule( mhModule ); +} +HTHEME VisualStylesAPI::OpenThemeData( HWND hwnd, LPCWSTR pszClassList ) +{ + if(lpfnOpenThemeData) + return (*lpfnOpenThemeData) (hwnd, pszClassList); + else + return NULL; +} + +HRESULT VisualStylesAPI::CloseThemeData( HTHEME hTheme ) +{ + if(lpfnCloseThemeData) + return (*lpfnCloseThemeData) (hTheme); + else + return S_FALSE; +} +HRESULT VisualStylesAPI::GetThemeBackgroundContentRect( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect ) +{ + if(lpfnGetThemeBackgroundContentRect) + return (*lpfnGetThemeBackgroundContentRect) ( hTheme, hdc, iPartId, iStateId, pBoundingRect, pContentRect ); + else + return S_FALSE; +} +HRESULT VisualStylesAPI::DrawThemeBackground( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect ) +{ + if(lpfnDrawThemeBackground) + return (*lpfnDrawThemeBackground) (hTheme, hdc, iPartId, iStateId, pRect, pClipRect); + else + return S_FALSE; +} +HRESULT VisualStylesAPI::DrawThemeText( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect ) +{ + if(lpfnDrawThemeText) + return (*lpfnDrawThemeText) (hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, dwTextFlags2, pRect); + else + return S_FALSE; +} +HRESULT VisualStylesAPI::GetThemePartSize( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT *prc, THEMESIZE eSize, SIZE *psz ) +{ + if(lpfnGetThemePartSize) + return (*lpfnGetThemePartSize) (hTheme, hdc, iPartId, iStateId, prc, eSize, psz); + else + return S_FALSE; +} + + +/********************************************************* + * Initialize XP theming and local stuff + *********************************************************/ +void SalData::initNWF( void ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + // the menu bar and the top docking area should have a common background (gradient) + pSVData->maNWFData.mbMenuBarDockingAreaCommonBG = true; +} + + +// ********************************************************* +// * Release theming handles +// ******************************************************** +void SalData::deInitNWF( void ) +{ + ThemeMap::iterator iter = aThemeMap.begin(); + while( iter != aThemeMap.end() ) + { + vsAPI.CloseThemeData(iter->second); + iter++; + } + aThemeMap.clear(); +} + +static HTHEME getThemeHandle( HWND hWnd, LPCWSTR name ) +{ + if( GetSalData()->mbThemeChanged ) + { + // throw away invalid theme handles + GetSalData()->deInitNWF(); + GetSalData()->mbThemeChanged = FALSE; + } + + ThemeMap::iterator iter; + if( (iter = aThemeMap.find( name )) != aThemeMap.end() ) + return iter->second; + // theme not found -> add it to map + HTHEME hTheme = vsAPI.OpenThemeData( hWnd, name ); + if( hTheme != NULL ) + aThemeMap[name] = hTheme; + return hTheme; +} + +/* + * IsNativeControlSupported() + * + * Returns TRUE if the platform supports native + * drawing of the control defined by nPart + */ +BOOL WinSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart ) +{ + HTHEME hTheme = NULL; + + switch( nType ) + { + case CTRL_PUSHBUTTON: + case CTRL_RADIOBUTTON: + case CTRL_CHECKBOX: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Button"); + break; + case CTRL_SCROLLBAR: + if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT ) + return FALSE; // no background painting needed + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Scrollbar"); + break; + case CTRL_COMBOBOX: + if( nPart == HAS_BACKGROUND_TEXTURE ) + return FALSE; // we do not paint the inner part (ie the selection background/focus indication) + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Edit"); + else if( nPart == PART_BUTTON_DOWN ) + hTheme = getThemeHandle( mhWnd, L"Combobox"); + break; + case CTRL_SPINBOX: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Edit"); + else if( nPart == PART_ALL_BUTTONS || + nPart == PART_BUTTON_UP || nPart == PART_BUTTON_DOWN || + nPart == PART_BUTTON_LEFT|| nPart == PART_BUTTON_RIGHT ) + hTheme = getThemeHandle( mhWnd, L"Spin"); + break; + case CTRL_SPINBUTTONS: + if( nPart == PART_ENTIRE_CONTROL || nPart == PART_ALL_BUTTONS ) + hTheme = getThemeHandle( mhWnd, L"Spin"); + break; + case CTRL_EDITBOX: + case CTRL_MULTILINE_EDITBOX: + if( nPart == HAS_BACKGROUND_TEXTURE ) + return FALSE; // we do not paint the inner part (ie the selection background/focus indication) + //return TRUE; + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Edit"); + break; + case CTRL_LISTBOX: + if( nPart == HAS_BACKGROUND_TEXTURE ) + return FALSE; // we do not paint the inner part (ie the selection background/focus indication) + if( nPart == PART_ENTIRE_CONTROL || nPart == PART_WINDOW ) + hTheme = getThemeHandle( mhWnd, L"Listview"); + else if( nPart == PART_BUTTON_DOWN ) + hTheme = getThemeHandle( mhWnd, L"Combobox"); + break; + case CTRL_TAB_PANE: + case CTRL_TAB_BODY: + case CTRL_TAB_ITEM: + case CTRL_FIXEDBORDER: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Tab"); + break; + case CTRL_TOOLBAR: + if( nPart == PART_ENTIRE_CONTROL || nPart == PART_BUTTON ) + hTheme = getThemeHandle( mhWnd, L"Toolbar"); + else + // use rebar theme for grip and background + hTheme = getThemeHandle( mhWnd, L"Rebar"); + break; + case CTRL_MENUBAR: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Rebar"); + break; + case CTRL_PROGRESS: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Progress"); + break; + case CTRL_SLIDER: + if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) + hTheme = getThemeHandle( mhWnd, L"Trackbar" ); + break; + case CTRL_LISTNODE: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"TreeView" ); + break; + default: + hTheme = NULL; + break; + } + + return (hTheme != NULL); +} + + +/* + * HitTestNativeControl() + * + * If the return value is TRUE, bIsInside contains information whether + * aPos was or was not inside the native widget specified by the + * nType/nPart combination. + */ +BOOL WinSalGraphics::hitTestNativeControl( ControlType, + ControlPart, + const Region&, + const Point&, + SalControlHandle&, + BOOL& ) +{ + return FALSE; +} + +BOOL ImplDrawTheme( HTHEME hTheme, HDC hDC, int iPart, int iState, RECT rc, const OUString& aStr) +{ + HRESULT hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0); + + if( aStr.getLength() ) + { + RECT rcContent; + hr = vsAPI.GetThemeBackgroundContentRect( hTheme, hDC, iPart, iState, &rc, &rcContent); + hr = vsAPI.DrawThemeText( hTheme, hDC, iPart, iState, + reinterpret_cast<LPCWSTR>(aStr.getStr()), -1, + DT_CENTER | DT_VCENTER | DT_SINGLELINE, + 0, &rcContent); + } + return (hr == S_OK); +} + + +Rectangle ImplGetThemeRect( HTHEME hTheme, HDC hDC, int iPart, int iState, const Rectangle& aRect, THEMESIZE eTS = TS_TRUE ) +{ + SIZE aSz; + RECT rc; + rc.left = aRect.nLeft; + rc.right = aRect.nRight; + rc.top = aRect.nTop; + rc.bottom = aRect.nBottom; + HRESULT hr = vsAPI.GetThemePartSize( hTheme, hDC, iPart, iState, NULL, eTS, &aSz ); // TS_TRUE returns optimal size + if( hr == S_OK ) + return Rectangle( 0, 0, aSz.cx, aSz.cy ); + else + return Rectangle(); +} + +// Helper functions +// ---- + +void ImplConvertSpinbuttonValues( int nControlPart, const ControlState& rState, const Rectangle& rRect, + int* pLunaPart, int *pLunaState, RECT *pRect ) +{ + if( nControlPart == PART_BUTTON_DOWN ) + { + *pLunaPart = SPNP_DOWN; + if( rState & CTRL_STATE_PRESSED ) + *pLunaState = DNS_PRESSED; + else if( !(rState & CTRL_STATE_ENABLED) ) + *pLunaState = DNS_DISABLED; + else if( rState & CTRL_STATE_ROLLOVER ) + *pLunaState = DNS_HOT; + else + *pLunaState = DNS_NORMAL; + } + if( nControlPart == PART_BUTTON_UP ) + { + *pLunaPart = SPNP_UP; + if( rState & CTRL_STATE_PRESSED ) + *pLunaState = UPS_PRESSED; + else if( !(rState & CTRL_STATE_ENABLED) ) + *pLunaState = UPS_DISABLED; + else if( rState & CTRL_STATE_ROLLOVER ) + *pLunaState = UPS_HOT; + else + *pLunaState = UPS_NORMAL; + } + if( nControlPart == PART_BUTTON_RIGHT ) + { + *pLunaPart = SPNP_UPHORZ; + if( rState & CTRL_STATE_PRESSED ) + *pLunaState = DNHZS_PRESSED; + else if( !(rState & CTRL_STATE_ENABLED) ) + *pLunaState = DNHZS_DISABLED; + else if( rState & CTRL_STATE_ROLLOVER ) + *pLunaState = DNHZS_HOT; + else + *pLunaState = DNHZS_NORMAL; + } + if( nControlPart == PART_BUTTON_LEFT ) + { + *pLunaPart = SPNP_DOWNHORZ; + if( rState & CTRL_STATE_PRESSED ) + *pLunaState = UPHZS_PRESSED; + else if( !(rState & CTRL_STATE_ENABLED) ) + *pLunaState = UPHZS_DISABLED; + else if( rState & CTRL_STATE_ROLLOVER ) + *pLunaState = UPHZS_HOT; + else + *pLunaState = UPHZS_NORMAL; + } + + pRect->left = rRect.Left(); + pRect->right = rRect.Right()+1; + pRect->top = rRect.Top(); + pRect->bottom = rRect.Bottom()+1; +} + +// ---- + +BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, + ControlType nType, + ControlPart nPart, + ControlState nState, + const ImplControlValue& aValue, + SalControlHandle&, + OUString aCaption ) +{ + // a listbox dropdown is actually a combobox dropdown + if( nType == CTRL_LISTBOX ) + if( nPart == PART_BUTTON_DOWN ) + nType = CTRL_COMBOBOX; + + // draw entire combobox as a large edit box + if( nType == CTRL_COMBOBOX ) + if( nPart == PART_ENTIRE_CONTROL ) + nType = CTRL_EDITBOX; + + // draw entire spinbox as a large edit box + if( nType == CTRL_SPINBOX ) + if( nPart == PART_ENTIRE_CONTROL ) + nType = CTRL_EDITBOX; + + int iPart(0), iState(0); + if( nType == CTRL_SCROLLBAR ) + { + HRESULT hr; + if( nPart == PART_BUTTON_UP ) + { + iPart = SBP_ARROWBTN; + if( nState & CTRL_STATE_PRESSED ) + iState = ABS_UPPRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = ABS_UPDISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = ABS_UPHOT; + else + iState = ABS_UPNORMAL; + hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0); + return (hr == S_OK); + } + if( nPart == PART_BUTTON_DOWN ) + { + iPart = SBP_ARROWBTN; + if( nState & CTRL_STATE_PRESSED ) + iState = ABS_DOWNPRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = ABS_DOWNDISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = ABS_DOWNHOT; + else + iState = ABS_DOWNNORMAL; + hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0); + return (hr == S_OK); + } + if( nPart == PART_BUTTON_LEFT ) + { + iPart = SBP_ARROWBTN; + if( nState & CTRL_STATE_PRESSED ) + iState = ABS_LEFTPRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = ABS_LEFTDISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = ABS_LEFTHOT; + else + iState = ABS_LEFTNORMAL; + hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0); + return (hr == S_OK); + } + if( nPart == PART_BUTTON_RIGHT ) + { + iPart = SBP_ARROWBTN; + if( nState & CTRL_STATE_PRESSED ) + iState = ABS_RIGHTPRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = ABS_RIGHTDISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = ABS_RIGHTHOT; + else + iState = ABS_RIGHTNORMAL; + hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0); + return (hr == S_OK); + } + if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT ) + { + iPart = (nPart == PART_THUMB_HORZ) ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT; + if( nState & CTRL_STATE_PRESSED ) + iState = SCRBS_PRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = SCRBS_DISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = SCRBS_HOT; + else + iState = SCRBS_NORMAL; + + SIZE sz; + vsAPI.GetThemePartSize(hTheme, hDC, iPart, iState, NULL, TS_MIN, &sz); + vsAPI.GetThemePartSize(hTheme, hDC, iPart, iState, NULL, TS_TRUE, &sz); + vsAPI.GetThemePartSize(hTheme, hDC, iPart, iState, NULL, TS_DRAW, &sz); + + hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0); + // paint gripper on thumb if enough space + if( ( (nPart == PART_THUMB_VERT) && (rc.bottom-rc.top > 12) ) || + ( (nPart == PART_THUMB_HORZ) && (rc.right-rc.left > 12) ) ) + { + iPart = (nPart == PART_THUMB_HORZ) ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT; + iState = 0; + vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0); + } + return (hr == S_OK); + } + if( nPart == PART_TRACK_HORZ_LEFT || nPart == PART_TRACK_HORZ_RIGHT || nPart == PART_TRACK_VERT_UPPER || nPart == PART_TRACK_VERT_LOWER ) + { + switch( nPart ) + { + case PART_TRACK_HORZ_LEFT: iPart = SBP_UPPERTRACKHORZ; break; + case PART_TRACK_HORZ_RIGHT: iPart = SBP_LOWERTRACKHORZ; break; + case PART_TRACK_VERT_UPPER: iPart = SBP_UPPERTRACKVERT; break; + case PART_TRACK_VERT_LOWER: iPart = SBP_LOWERTRACKVERT; break; + } + + if( nState & CTRL_STATE_PRESSED ) + iState = SCRBS_PRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = SCRBS_DISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = SCRBS_HOT; + else + iState = SCRBS_NORMAL; + hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0); + return (hr == S_OK); + } + } + if( nType == CTRL_SPINBUTTONS && nPart == PART_ALL_BUTTONS ) + { + SpinbuttonValue *pValue = (SpinbuttonValue*) aValue.getOptionalVal(); + if( pValue ) + { + BOOL bOk = FALSE; + + RECT rect; + ImplConvertSpinbuttonValues( pValue->mnUpperPart, pValue->mnUpperState, pValue->maUpperRect, &iPart, &iState, &rect ); + bOk = ImplDrawTheme( hTheme, hDC, iPart, iState, rect, aCaption); + + if( bOk ) + { + ImplConvertSpinbuttonValues( pValue->mnLowerPart, pValue->mnLowerState, pValue->maLowerRect, &iPart, &iState, &rect ); + bOk = ImplDrawTheme( hTheme, hDC, iPart, iState, rect, aCaption); + } + + return bOk; + } + } + if( nType == CTRL_SPINBOX ) + { + // decrease spinbutton rects a little + //rc.right--; + //rc.bottom--; + if( nPart == PART_ALL_BUTTONS ) + { + SpinbuttonValue *pValue = (SpinbuttonValue*) aValue.getOptionalVal(); + if( pValue ) + { + BOOL bOk = FALSE; + + RECT rect; + ImplConvertSpinbuttonValues( pValue->mnUpperPart, pValue->mnUpperState, pValue->maUpperRect, &iPart, &iState, &rect ); + bOk = ImplDrawTheme( hTheme, hDC, iPart, iState, rect, aCaption); + + if( bOk ) + { + ImplConvertSpinbuttonValues( pValue->mnLowerPart, pValue->mnLowerState, pValue->maLowerRect, &iPart, &iState, &rect ); + bOk = ImplDrawTheme( hTheme, hDC, iPart, iState, rect, aCaption); + } + + return bOk; + } + } + + if( nPart == PART_BUTTON_DOWN ) + { + iPart = SPNP_DOWN; + if( nState & CTRL_STATE_PRESSED ) + iState = DNS_PRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = DNS_DISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = DNS_HOT; + else + iState = DNS_NORMAL; + } + if( nPart == PART_BUTTON_UP ) + { + iPart = SPNP_UP; + if( nState & CTRL_STATE_PRESSED ) + iState = UPS_PRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = UPS_DISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = UPS_HOT; + else + iState = UPS_NORMAL; + } + if( nPart == PART_BUTTON_RIGHT ) + { + iPart = SPNP_DOWNHORZ; + if( nState & CTRL_STATE_PRESSED ) + iState = DNHZS_PRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = DNHZS_DISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = DNHZS_HOT; + else + iState = DNHZS_NORMAL; + } + if( nPart == PART_BUTTON_LEFT ) + { + iPart = SPNP_UPHORZ; + if( nState & CTRL_STATE_PRESSED ) + iState = UPHZS_PRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = UPHZS_DISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = UPHZS_HOT; + else + iState = UPHZS_NORMAL; + } + if( nPart == PART_BUTTON_LEFT || nPart == PART_BUTTON_RIGHT || nPart == PART_BUTTON_UP || nPart == PART_BUTTON_DOWN ) + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + if( nType == CTRL_COMBOBOX ) + { + if( nPart == PART_BUTTON_DOWN ) + { + iPart = CP_DROPDOWNBUTTON; + if( nState & CTRL_STATE_PRESSED ) + iState = CBXS_PRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = CBXS_DISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = CBXS_HOT; + else + iState = CBXS_NORMAL; + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + } + if( nType == CTRL_PUSHBUTTON ) + { + iPart = BP_PUSHBUTTON; + if( nState & CTRL_STATE_PRESSED ) + iState = PBS_PRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = PBS_DISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = PBS_HOT; + else if( nState & CTRL_STATE_DEFAULT ) + iState = PBS_DEFAULTED; + //else if( nState & CTRL_STATE_FOCUSED ) + // iState = PBS_DEFAULTED; // may need to draw focus rect + else + iState = PBS_NORMAL; + + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( nType == CTRL_RADIOBUTTON ) + { + iPart = BP_RADIOBUTTON; + BOOL bChecked = ( aValue.getTristateVal() == BUTTONVALUE_ON ); + + if( nState & CTRL_STATE_PRESSED ) + iState = bChecked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED; + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = bChecked ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = bChecked ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT; + else + iState = bChecked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL; + + //if( nState & CTRL_STATE_FOCUSED ) + // iState |= PBS_DEFAULTED; // may need to draw focus rect + + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( nType == CTRL_CHECKBOX ) + { + iPart = BP_CHECKBOX; + ButtonValue v = aValue.getTristateVal(); + + if( nState & CTRL_STATE_PRESSED ) + iState = (v == BUTTONVALUE_ON) ? CBS_CHECKEDPRESSED : + ( (v == BUTTONVALUE_OFF) ? CBS_UNCHECKEDPRESSED : CBS_MIXEDPRESSED ); + else if( !(nState & CTRL_STATE_ENABLED) ) + iState = (v == BUTTONVALUE_ON) ? CBS_CHECKEDDISABLED : + ( (v == BUTTONVALUE_OFF) ? CBS_UNCHECKEDDISABLED : CBS_MIXEDDISABLED ); + else if( nState & CTRL_STATE_ROLLOVER ) + iState = (v == BUTTONVALUE_ON) ? CBS_CHECKEDHOT : + ( (v == BUTTONVALUE_OFF) ? CBS_UNCHECKEDHOT : CBS_MIXEDHOT ); + else + iState = (v == BUTTONVALUE_ON) ? CBS_CHECKEDNORMAL : + ( (v == BUTTONVALUE_OFF) ? CBS_UNCHECKEDNORMAL : CBS_MIXEDNORMAL ); + + //if( nState & CTRL_STATE_FOCUSED ) + // iState |= PBS_DEFAULTED; // may need to draw focus rect + + //SIZE sz; + //THEMESIZE eSize = TS_DRAW; // TS_MIN, TS_TRUE, TS_DRAW + //vsAPI.GetThemePartSize( hTheme, hDC, iPart, iState, &rc, eSize, &sz); + + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( ( nType == CTRL_EDITBOX ) || ( nType == CTRL_MULTILINE_EDITBOX ) ) + { + iPart = EP_EDITTEXT; + if( !(nState & CTRL_STATE_ENABLED) ) + iState = ETS_DISABLED; + else if( nState & CTRL_STATE_FOCUSED ) + iState = ETS_FOCUSED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = ETS_HOT; + else + iState = ETS_NORMAL; + + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( nType == CTRL_LISTBOX ) + { + if( nPart == PART_ENTIRE_CONTROL || nPart == PART_WINDOW ) + { + iPart = LVP_EMPTYTEXT; // ??? no idea which part to choose here + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + } + + if( nType == CTRL_TAB_PANE ) + { + iPart = TABP_PANE; + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( nType == CTRL_FIXEDBORDER ) + { + /* + iPart = BP_GROUPBOX; + if( !(nState & CTRL_STATE_ENABLED) ) + iState = GBS_DISABLED; + else + iState = GBS_NORMAL; + */ + // The fixed border is only used around the tools->options tabpage where + // TABP_PANE fits best + iPart = TABP_PANE; + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( nType == CTRL_TAB_BODY ) + { + iPart = TABP_BODY; + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( nType == CTRL_TAB_ITEM ) + { + iPart = TABP_TABITEMLEFTEDGE; + rc.bottom--; + + TabitemValue *pValue = (TabitemValue*) aValue.getOptionalVal(); + if( pValue ) + { + if( pValue->isBothAligned() ) + { + iPart = TABP_TABITEMLEFTEDGE; + rc.right--; + } + else if( pValue->isLeftAligned() ) + iPart = TABP_TABITEMLEFTEDGE; + else if( pValue->isRightAligned() ) + iPart = TABP_TABITEMRIGHTEDGE; + else iPart = TABP_TABITEM; + } + + if( !(nState & CTRL_STATE_ENABLED) ) + iState = TILES_DISABLED; + else if( nState & CTRL_STATE_SELECTED ) + { + iState = TILES_SELECTED; + // increase the selected tab + rc.left-=2; + if( pValue && !pValue->isBothAligned() ) + { + if( pValue->isLeftAligned() || pValue->isNotAligned() ) + rc.right+=2; + if( pValue->isRightAligned() ) + rc.right+=1; + } + rc.top-=2; + rc.bottom+=2; + } + else if( nState & CTRL_STATE_ROLLOVER ) + iState = TILES_HOT; + else if( nState & CTRL_STATE_FOCUSED ) + iState = TILES_FOCUSED; // may need to draw focus rect + else + iState = TILES_NORMAL; + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( nType == CTRL_TOOLBAR ) + { + if( nPart == PART_BUTTON ) + { + iPart = TP_BUTTON; + BOOL bChecked = ( aValue.getTristateVal() == BUTTONVALUE_ON ); + if( !(nState & CTRL_STATE_ENABLED) ) + //iState = TS_DISABLED; + // disabled buttons are typically not painted at all but we need visual + // feedback when travelling by keyboard over disabled entries + iState = TS_HOT; + else if( nState & CTRL_STATE_PRESSED ) + iState = TS_PRESSED; + else if( nState & CTRL_STATE_ROLLOVER ) + iState = bChecked ? TS_HOTCHECKED : TS_HOT; + else + iState = bChecked ? TS_CHECKED : TS_NORMAL; + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + else if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT ) + { + // the vertical gripper is not supported in most themes and it makes no + // sense to only support horizontal gripper + //iPart = (nPart == PART_THUMB_HORZ) ? RP_GRIPPERVERT : RP_GRIPPER; + //return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + else if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT ) + { + ToolbarValue *pValue = (ToolbarValue*) aValue.getOptionalVal(); + if( pValue && pValue->mbIsTopDockingArea ) + rc.top = 0; // extend potential gradient to cover menu bar as well + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + } + + if( nType == CTRL_MENUBAR ) + { + if( nPart != PART_ENTIRE_CONTROL ) + return FALSE; + + MenubarValue *pValue = (MenubarValue*) aValue.getOptionalVal(); + if( pValue ) + rc.bottom += pValue->maTopDockingAreaHeight; // extend potential gradient to cover docking area as well + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + + if( nType == CTRL_PROGRESS ) + { + if( nPart != PART_ENTIRE_CONTROL ) + return FALSE; + + if( ! ImplDrawTheme( hTheme, hDC, PP_BAR, iState, rc, aCaption) ) + return false; + RECT aProgressRect = rc; + if( vsAPI.GetThemeBackgroundContentRect( hTheme, hDC, PP_BAR, iState, &rc, &aProgressRect) != S_OK ) + return false; + + long nProgressWidth = aValue.getNumericVal(); + nProgressWidth *= (aProgressRect.right - aProgressRect.left); + nProgressWidth /= (rc.right - rc.left); + if( Application::GetSettings().GetLayoutRTL() ) + aProgressRect.left = aProgressRect.right - nProgressWidth; + else + aProgressRect.right = aProgressRect.left + nProgressWidth; + + return ImplDrawTheme( hTheme, hDC, PP_CHUNK, iState, aProgressRect, aCaption ); + } + + if( nType == CTRL_SLIDER ) + { + iPart = (nPart == PART_TRACK_HORZ_AREA) ? TKP_TRACK : TKP_TRACKVERT; + iState = (nPart == PART_TRACK_HORZ_AREA) ? TRS_NORMAL : TRVS_NORMAL; + + Rectangle aTrackRect = ImplGetThemeRect( hTheme, hDC, iPart, iState, Rectangle() ); + RECT aTRect = rc; + if( nPart == PART_TRACK_HORZ_AREA ) + { + long nH = aTrackRect.GetHeight(); + aTRect.top += (rc.bottom - rc.top - nH)/2; + aTRect.bottom = aTRect.top + nH; + } + else + { + long nW = aTrackRect.GetWidth(); + aTRect.left += (rc.right - rc.left - nW)/2; + aTRect.right = aTRect.left + nW; + } + ImplDrawTheme( hTheme, hDC, iPart, iState, aTRect, aCaption ); + + RECT aThumbRect; + SliderValue* pVal = (SliderValue*)aValue.getOptionalVal(); + aThumbRect.left = pVal->maThumbRect.Left(); + aThumbRect.top = pVal->maThumbRect.Top(); + aThumbRect.right = pVal->maThumbRect.Right(); + aThumbRect.bottom = pVal->maThumbRect.Bottom(); + iPart = (nPart == PART_TRACK_HORZ_AREA) ? TKP_THUMB : TKP_THUMBVERT; + iState = (nState & CTRL_STATE_ENABLED) ? TUS_NORMAL : TUS_DISABLED; + return ImplDrawTheme( hTheme, hDC, iPart, iState, aThumbRect, aCaption ); + } + + if( nType == CTRL_LISTNODE ) + { + if( nPart != PART_ENTIRE_CONTROL ) + return FALSE; + + ButtonValue aButtonValue = aValue.getTristateVal(); + iPart = TVP_GLYPH; + switch( aButtonValue ) + { + case BUTTONVALUE_ON: + iState = GLPS_OPENED; + break; + case BUTTONVALUE_OFF: + iState = GLPS_CLOSED; + break; + default: + return FALSE; + } + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption ); + } + + return false; +} + +/* + * DrawNativeControl() + * + * Draws the requested control described by nPart/nState. + * + * rControlRegion: The bounding region of the complete control in VCL frame coordinates. + * aValue: An optional value (tristate/numerical/string) + * rControlHandle: Carries platform dependent data and is maintained by the WinSalGraphics implementation. + * aCaption: A caption or title string (like button text etc) + */ +BOOL WinSalGraphics::drawNativeControl( ControlType nType, + ControlPart nPart, + const Region& rControlRegion, + ControlState nState, + const ImplControlValue& aValue, + SalControlHandle& rControlHandle, + const OUString& aCaption ) +{ + BOOL bOk = false; + HTHEME hTheme = NULL; + + switch( nType ) + { + case CTRL_PUSHBUTTON: + case CTRL_RADIOBUTTON: + case CTRL_CHECKBOX: + hTheme = getThemeHandle( mhWnd, L"Button"); + break; + case CTRL_SCROLLBAR: + hTheme = getThemeHandle( mhWnd, L"Scrollbar"); + break; + case CTRL_COMBOBOX: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Edit"); + else if( nPart == PART_BUTTON_DOWN ) + hTheme = getThemeHandle( mhWnd, L"Combobox"); + break; + case CTRL_SPINBOX: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Edit"); + else + hTheme = getThemeHandle( mhWnd, L"Spin"); + break; + case CTRL_SPINBUTTONS: + hTheme = getThemeHandle( mhWnd, L"Spin"); + break; + case CTRL_EDITBOX: + case CTRL_MULTILINE_EDITBOX: + hTheme = getThemeHandle( mhWnd, L"Edit"); + break; + case CTRL_LISTBOX: + if( nPart == PART_ENTIRE_CONTROL || nPart == PART_WINDOW ) + hTheme = getThemeHandle( mhWnd, L"Listview"); + else if( nPart == PART_BUTTON_DOWN ) + hTheme = getThemeHandle( mhWnd, L"Combobox"); + break; + case CTRL_TAB_PANE: + case CTRL_TAB_BODY: + case CTRL_TAB_ITEM: + case CTRL_FIXEDBORDER: + hTheme = getThemeHandle( mhWnd, L"Tab"); + break; + case CTRL_TOOLBAR: + if( nPart == PART_ENTIRE_CONTROL || nPart == PART_BUTTON ) + hTheme = getThemeHandle( mhWnd, L"Toolbar"); + else + // use rebar for grip and background + hTheme = getThemeHandle( mhWnd, L"Rebar"); + break; + case CTRL_MENUBAR: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Rebar"); + break; + case CTRL_PROGRESS: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"Progress"); + break; + case CTRL_LISTNODE: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"TreeView"); + break; + case CTRL_SLIDER: + if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) + hTheme = getThemeHandle( mhWnd, L"Trackbar" ); + break; + default: + hTheme = NULL; + break; + } + + if( !hTheme ) + return false; + + Rectangle buttonRect = rControlRegion.GetBoundRect(); + RECT rc; + rc.left = buttonRect.Left(); + rc.right = buttonRect.Right()+1; + rc.top = buttonRect.Top(); + rc.bottom = buttonRect.Bottom()+1; + + // set default text alignment + int ta = SetTextAlign( mhDC, TA_LEFT|TA_TOP|TA_NOUPDATECP ); + + OUString aCaptionStr( aCaption.replace('~', '&') ); // translate mnemonics + bOk = ImplDrawNativeControl(mhDC, hTheme, rc, + nType, nPart, nState, aValue, + rControlHandle, aCaptionStr ); + + // restore alignment + SetTextAlign( mhDC, ta ); + + + //GdiFlush(); + + return bOk; +} + + +/* + * DrawNativeControlText() + * + * OPTIONAL. Draws the requested text for the control described by nPart/nState. + * Used if text not drawn by DrawNativeControl(). + * + * rControlRegion: The bounding region of the complete control in VCL frame coordinates. + * aValue: An optional value (tristate/numerical/string) + * rControlHandle: Carries platform dependent data and is maintained by the WinSalGraphics implementation. + * aCaption: A caption or title string (like button text etc) + */ +BOOL WinSalGraphics::drawNativeControlText( ControlType, + ControlPart, + const Region&, + ControlState, + const ImplControlValue&, + SalControlHandle&, + const OUString& ) +{ + return( false ); +} + + +/* + * GetNativeControlRegion() + * + * If the return value is TRUE, rNativeBoundingRegion + * contains the true bounding region covered by the control + * including any adornment, while rNativeContentRegion contains the area + * within the control that can be safely drawn into without drawing over + * the borders of the control. + * + * rControlRegion: The bounding region of the control in VCL frame coordinates. + * aValue: An optional value (tristate/numerical/string) + * rControlHandle: Carries platform dependent data and is maintained by the WinSalGraphics implementation. + * aCaption: A caption or title string (like button text etc) + */ +BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, + ControlPart nPart, + const Region& rControlRegion, + ControlState, + const ImplControlValue&, + SalControlHandle&, + const OUString&, + Region &rNativeBoundingRegion, + Region &rNativeContentRegion ) +{ + BOOL bRet = FALSE; + + HDC hDC = GetDC( mhWnd ); + if( nType == CTRL_TOOLBAR ) + { + if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT ) + { + /* + // the vertical gripper is not supported in most themes and it makes no + // sense to only support horizontal gripper + + HTHEME hTheme = getThemeHandle( mhWnd, L"Rebar"); + if( hTheme ) + { + Rectangle aRect( ImplGetThemeRect( hTheme, hDC, nPart == PART_THUMB_HORZ ? RP_GRIPPERVERT : RP_GRIPPER, + 0, rControlRegion.GetBoundRect() ) ); + if( nPart == PART_THUMB_HORZ && !aRect.IsEmpty() ) + { + Rectangle aVertRect( 0, 0, aRect.getHeight(), aRect.getWidth() ); + rNativeContentRegion = aVertRect; + } + else + rNativeContentRegion = aRect; + rNativeBoundingRegion = rNativeContentRegion; + if( !rNativeContentRegion.IsEmpty() ) + bRet = TRUE; + } + */ + } + if( nPart == PART_BUTTON ) + { + HTHEME hTheme = getThemeHandle( mhWnd, L"Toolbar"); + if( hTheme ) + { + Rectangle aRect( ImplGetThemeRect( hTheme, hDC, TP_SPLITBUTTONDROPDOWN, + TS_HOT, rControlRegion.GetBoundRect() ) ); + rNativeContentRegion = aRect; + rNativeBoundingRegion = rNativeContentRegion; + if( !rNativeContentRegion.IsEmpty() ) + bRet = TRUE; + } + } + } + if( nType == CTRL_PROGRESS && nPart == PART_ENTIRE_CONTROL ) + { + HTHEME hTheme = getThemeHandle( mhWnd, L"Progress"); + if( hTheme ) + { + Rectangle aRect( ImplGetThemeRect( hTheme, hDC, PP_BAR, + 0, rControlRegion.GetBoundRect() ) ); + rNativeContentRegion = aRect; + rNativeBoundingRegion = rNativeContentRegion; + if( !rNativeContentRegion.IsEmpty() ) + bRet = TRUE; + } + } + if( (nType == CTRL_LISTBOX || nType == CTRL_COMBOBOX ) && nPart == PART_ENTIRE_CONTROL ) + { + HTHEME hTheme = getThemeHandle( mhWnd, L"Combobox"); + if( hTheme ) + { + Rectangle aBoxRect( rControlRegion.GetBoundRect() ); + Rectangle aRect( ImplGetThemeRect( hTheme, hDC, CP_DROPDOWNBUTTON, + CBXS_NORMAL, aBoxRect ) ); + Rectangle aBrdRect( ImplGetThemeRect( hTheme, hDC, CP_BORDER, + CBB_HOT, aBoxRect ) ); + aRect.Top() -= aBrdRect.GetHeight(); + if( aRect.GetHeight() > aBoxRect.GetHeight() ) + aBoxRect.Bottom() = aBoxRect.Top() + aRect.GetHeight(); + if( aRect.GetWidth() > aBoxRect.GetWidth() ) + aBoxRect.Right() = aBoxRect.Left() + aRect.GetWidth(); + rNativeContentRegion = aBoxRect; + rNativeBoundingRegion = rNativeContentRegion; + if( !aRect.IsEmpty() ) + bRet = TRUE; + } + } + + if( (nType == CTRL_EDITBOX || nType == CTRL_SPINBOX) && nPart == PART_ENTIRE_CONTROL ) + { + HTHEME hTheme = getThemeHandle( mhWnd, L"Edit"); + if( hTheme ) + { + // get borderr size + Rectangle aBoxRect( rControlRegion.GetBoundRect() ); + Rectangle aRect( ImplGetThemeRect( hTheme, hDC, EP_BACKGROUNDWITHBORDER, + EBWBS_HOT, aBoxRect ) ); + // ad app font height + NONCLIENTMETRICSW aNonClientMetrics; + aNonClientMetrics.cbSize = sizeof( aNonClientMetrics ); + if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) ) + { + long nFontHeight = aNonClientMetrics.lfMessageFont.lfHeight; + if( nFontHeight < 0 ) + nFontHeight = -nFontHeight; + + if( aRect.GetHeight() && nFontHeight ) + { + aRect.Bottom() += aRect.GetHeight(); + aRect.Bottom() += nFontHeight; + if( aRect.GetHeight() > aBoxRect.GetHeight() ) + aBoxRect.Bottom() = aBoxRect.Top() + aRect.GetHeight(); + if( aRect.GetWidth() > aBoxRect.GetWidth() ) + aBoxRect.Right() = aBoxRect.Left() + aRect.GetWidth(); + rNativeContentRegion = aBoxRect; + rNativeBoundingRegion = rNativeContentRegion; + bRet = TRUE; + } + } + } + } + if( nType == CTRL_SLIDER && ( (nPart == PART_THUMB_HORZ) || (nPart == PART_THUMB_VERT) ) ) + { + HTHEME hTheme = getThemeHandle( mhWnd, L"Trackbar"); + if( hTheme ) + { + int iPart = (nPart == PART_THUMB_HORZ) ? TKP_THUMB : TKP_THUMBVERT; + int iState = (nPart == PART_THUMB_HORZ) ? TUS_NORMAL : TUVS_NORMAL; + Rectangle aThumbRect = ImplGetThemeRect( hTheme, hDC, iPart, iState, Rectangle() ); + if( nPart == PART_THUMB_HORZ ) + { + long nW = aThumbRect.GetWidth(); + Rectangle aRect( rControlRegion.GetBoundRect() ); + aRect.Right() = aRect.Left() + nW - 1; + rNativeContentRegion = aRect; + rNativeBoundingRegion = rNativeContentRegion; + } + else + { + long nH = aThumbRect.GetHeight(); + Rectangle aRect( rControlRegion.GetBoundRect() ); + aRect.Bottom() = aRect.Top() + nH - 1; + rNativeContentRegion = aRect; + rNativeBoundingRegion = rNativeContentRegion; + } + bRet = TRUE; + } + } + + ReleaseDC( mhWnd, hDC ); + return( bRet ); +} + |