xref: /AOO41X/main/vcl/win/source/gdi/salnativewidgets-luna.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f62ea84SAndrew Rist  * distributed with this work for additional information
69f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
139f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist  * software distributed under the License is distributed on an
159f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
179f62ea84SAndrew Rist  * specific language governing permissions and limitations
189f62ea84SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
229f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #define _SV_SALNATIVEWIDGETS_CXX
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "rtl/ustring.h"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "osl/module.h"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include "vcl/svapp.hxx"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include "win/svsys.h"
36cdf0e10cSrcweir #include "win/salgdi.h"
37cdf0e10cSrcweir #include "win/saldata.hxx"
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include "uxtheme.h"
40cdf0e10cSrcweir #include "vssym32.h"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <map>
43cdf0e10cSrcweir #include <string>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir using namespace rtl;
46cdf0e10cSrcweir using namespace std;
47cdf0e10cSrcweir 
48cdf0e10cSrcweir typedef map< wstring, HTHEME > ThemeMap;
49cdf0e10cSrcweir static ThemeMap aThemeMap;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir 
52cdf0e10cSrcweir /****************************************************
53cdf0e10cSrcweir  wrap visual styles API to avoid linking against it
54cdf0e10cSrcweir  it is not available on all Windows platforms
55cdf0e10cSrcweir *****************************************************/
56cdf0e10cSrcweir 
57cdf0e10cSrcweir class VisualStylesAPI
58cdf0e10cSrcweir {
59cdf0e10cSrcweir private:
60cdf0e10cSrcweir     typedef HTHEME  (WINAPI * OpenThemeData_Proc_T) ( HWND hwnd, LPCWSTR pszClassList );
61cdf0e10cSrcweir     typedef HRESULT (WINAPI * CloseThemeData_Proc_T) ( HTHEME hTheme );
62cdf0e10cSrcweir     typedef HRESULT (WINAPI * GetThemeBackgroundContentRect_Proc_T) ( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect );
63cdf0e10cSrcweir     typedef HRESULT (WINAPI * DrawThemeBackground_Proc_T) ( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect );
64cdf0e10cSrcweir     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 );
65cdf0e10cSrcweir     typedef HRESULT (WINAPI * GetThemePartSize_Proc_T) ( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT *prc, THEMESIZE eSize, SIZE *psz );
66cdf0e10cSrcweir 
67cdf0e10cSrcweir     OpenThemeData_Proc_T                    lpfnOpenThemeData;
68cdf0e10cSrcweir     CloseThemeData_Proc_T                   lpfnCloseThemeData;
69cdf0e10cSrcweir     GetThemeBackgroundContentRect_Proc_T    lpfnGetThemeBackgroundContentRect;
70cdf0e10cSrcweir     DrawThemeBackground_Proc_T              lpfnDrawThemeBackground;
71cdf0e10cSrcweir     DrawThemeText_Proc_T                    lpfnDrawThemeText;
72cdf0e10cSrcweir     GetThemePartSize_Proc_T                 lpfnGetThemePartSize;
73cdf0e10cSrcweir 
74cdf0e10cSrcweir     oslModule mhModule;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir public:
77cdf0e10cSrcweir     VisualStylesAPI();
78cdf0e10cSrcweir     ~VisualStylesAPI();
IsAvailable()79cdf0e10cSrcweir     sal_Bool IsAvailable()  { return (mhModule != NULL); }
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     HTHEME OpenThemeData( HWND hwnd, LPCWSTR pszClassList );
82cdf0e10cSrcweir     HRESULT CloseThemeData( HTHEME hTheme );
83cdf0e10cSrcweir     HRESULT GetThemeBackgroundContentRect( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect );
84cdf0e10cSrcweir     HRESULT DrawThemeBackground( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect );
85cdf0e10cSrcweir     HRESULT DrawThemeText( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect );
86cdf0e10cSrcweir     HRESULT GetThemePartSize( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT *prc, THEMESIZE eSize, SIZE *psz );
87cdf0e10cSrcweir };
88cdf0e10cSrcweir 
89cdf0e10cSrcweir static VisualStylesAPI vsAPI;
90cdf0e10cSrcweir 
VisualStylesAPI()91cdf0e10cSrcweir VisualStylesAPI::VisualStylesAPI()
92cdf0e10cSrcweir {
93aa150a94SHerbert Dürr     mhModule = osl_loadAsciiModule( "uxtheme.dll", SAL_LOADMODULE_DEFAULT );
94cdf0e10cSrcweir 
95cdf0e10cSrcweir     if ( mhModule )
96cdf0e10cSrcweir     {
97cdf0e10cSrcweir         lpfnOpenThemeData = (OpenThemeData_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "OpenThemeData" );
98cdf0e10cSrcweir         lpfnCloseThemeData = (CloseThemeData_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "CloseThemeData" );
99cdf0e10cSrcweir         lpfnGetThemeBackgroundContentRect = (GetThemeBackgroundContentRect_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "GetThemeBackgroundContentRect" );
100cdf0e10cSrcweir         lpfnDrawThemeBackground = (DrawThemeBackground_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "DrawThemeBackground" );
101cdf0e10cSrcweir         lpfnDrawThemeText = (DrawThemeText_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "DrawThemeText" );
102cdf0e10cSrcweir         lpfnGetThemePartSize = (GetThemePartSize_Proc_T)osl_getAsciiFunctionSymbol( mhModule, "GetThemePartSize" );
103cdf0e10cSrcweir     }
104cdf0e10cSrcweir     else
105cdf0e10cSrcweir     {
106cdf0e10cSrcweir         lpfnOpenThemeData = NULL;
107cdf0e10cSrcweir         lpfnCloseThemeData = NULL;
108cdf0e10cSrcweir         lpfnGetThemeBackgroundContentRect = NULL;
109cdf0e10cSrcweir         lpfnDrawThemeBackground = NULL;
110cdf0e10cSrcweir         lpfnDrawThemeText = NULL;
111cdf0e10cSrcweir         lpfnGetThemePartSize = NULL;
112cdf0e10cSrcweir     }
113cdf0e10cSrcweir }
~VisualStylesAPI()114cdf0e10cSrcweir VisualStylesAPI::~VisualStylesAPI()
115cdf0e10cSrcweir {
116cdf0e10cSrcweir     if( mhModule )
117cdf0e10cSrcweir         osl_unloadModule( mhModule );
118cdf0e10cSrcweir }
OpenThemeData(HWND hwnd,LPCWSTR pszClassList)119cdf0e10cSrcweir HTHEME VisualStylesAPI::OpenThemeData( HWND hwnd, LPCWSTR pszClassList )
120cdf0e10cSrcweir {
121cdf0e10cSrcweir     if(lpfnOpenThemeData)
122cdf0e10cSrcweir         return (*lpfnOpenThemeData) (hwnd, pszClassList);
123cdf0e10cSrcweir     else
124cdf0e10cSrcweir         return NULL;
125cdf0e10cSrcweir }
126cdf0e10cSrcweir 
CloseThemeData(HTHEME hTheme)127cdf0e10cSrcweir HRESULT VisualStylesAPI::CloseThemeData( HTHEME hTheme )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir     if(lpfnCloseThemeData)
130cdf0e10cSrcweir         return (*lpfnCloseThemeData) (hTheme);
131cdf0e10cSrcweir     else
132cdf0e10cSrcweir         return S_FALSE;
133cdf0e10cSrcweir }
GetThemeBackgroundContentRect(HTHEME hTheme,HDC hdc,int iPartId,int iStateId,const RECT * pBoundingRect,RECT * pContentRect)134cdf0e10cSrcweir HRESULT VisualStylesAPI::GetThemeBackgroundContentRect( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir     if(lpfnGetThemeBackgroundContentRect)
137cdf0e10cSrcweir         return (*lpfnGetThemeBackgroundContentRect) ( hTheme, hdc, iPartId, iStateId, pBoundingRect, pContentRect );
138cdf0e10cSrcweir     else
139cdf0e10cSrcweir         return S_FALSE;
140cdf0e10cSrcweir }
DrawThemeBackground(HTHEME hTheme,HDC hdc,int iPartId,int iStateId,const RECT * pRect,const RECT * pClipRect)141cdf0e10cSrcweir HRESULT VisualStylesAPI::DrawThemeBackground( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect )
142cdf0e10cSrcweir {
143cdf0e10cSrcweir     if(lpfnDrawThemeBackground)
144cdf0e10cSrcweir         return (*lpfnDrawThemeBackground) (hTheme, hdc, iPartId, iStateId, pRect, pClipRect);
145cdf0e10cSrcweir     else
146cdf0e10cSrcweir         return S_FALSE;
147cdf0e10cSrcweir }
DrawThemeText(HTHEME hTheme,HDC hdc,int iPartId,int iStateId,LPCWSTR pszText,int iCharCount,DWORD dwTextFlags,DWORD dwTextFlags2,const RECT * pRect)148cdf0e10cSrcweir HRESULT VisualStylesAPI::DrawThemeText( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir     if(lpfnDrawThemeText)
151cdf0e10cSrcweir         return (*lpfnDrawThemeText) (hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, dwTextFlags2, pRect);
152cdf0e10cSrcweir     else
153cdf0e10cSrcweir         return S_FALSE;
154cdf0e10cSrcweir }
GetThemePartSize(HTHEME hTheme,HDC hdc,int iPartId,int iStateId,RECT * prc,THEMESIZE eSize,SIZE * psz)155cdf0e10cSrcweir HRESULT VisualStylesAPI::GetThemePartSize( HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT *prc, THEMESIZE eSize, SIZE *psz )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir     if(lpfnGetThemePartSize)
158cdf0e10cSrcweir         return (*lpfnGetThemePartSize) (hTheme, hdc, iPartId, iStateId, prc, eSize, psz);
159cdf0e10cSrcweir     else
160cdf0e10cSrcweir         return S_FALSE;
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 
164cdf0e10cSrcweir /*********************************************************
165cdf0e10cSrcweir  * Initialize XP theming and local stuff
166cdf0e10cSrcweir  *********************************************************/
initNWF(void)167cdf0e10cSrcweir void SalData::initNWF( void )
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     ImplSVData* pSVData = ImplGetSVData();
170cdf0e10cSrcweir 
171cdf0e10cSrcweir     // the menu bar and the top docking area should have a common background (gradient)
172cdf0e10cSrcweir     pSVData->maNWFData.mbMenuBarDockingAreaCommonBG = true;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 
176cdf0e10cSrcweir // *********************************************************
177cdf0e10cSrcweir // * Release theming handles
178cdf0e10cSrcweir // ********************************************************
deInitNWF(void)179cdf0e10cSrcweir void SalData::deInitNWF( void )
180cdf0e10cSrcweir {
181cdf0e10cSrcweir     ThemeMap::iterator iter = aThemeMap.begin();
182cdf0e10cSrcweir     while( iter != aThemeMap.end() )
183cdf0e10cSrcweir     {
184cdf0e10cSrcweir         vsAPI.CloseThemeData(iter->second);
185cdf0e10cSrcweir         iter++;
186cdf0e10cSrcweir     }
187cdf0e10cSrcweir     aThemeMap.clear();
188cdf0e10cSrcweir     if( maDwmLib )
189cdf0e10cSrcweir         osl_unloadModule( maDwmLib );
190cdf0e10cSrcweir }
191cdf0e10cSrcweir 
getThemeHandle(HWND hWnd,LPCWSTR name)192cdf0e10cSrcweir static HTHEME getThemeHandle( HWND hWnd, LPCWSTR name )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir     if( GetSalData()->mbThemeChanged )
195cdf0e10cSrcweir     {
196cdf0e10cSrcweir         // throw away invalid theme handles
197cdf0e10cSrcweir         GetSalData()->deInitNWF();
198cdf0e10cSrcweir         GetSalData()->mbThemeChanged = FALSE;
199cdf0e10cSrcweir     }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir     ThemeMap::iterator iter;
202cdf0e10cSrcweir     if( (iter = aThemeMap.find( name )) != aThemeMap.end() )
203cdf0e10cSrcweir         return iter->second;
204cdf0e10cSrcweir     // theme not found -> add it to map
205cdf0e10cSrcweir     HTHEME hTheme = vsAPI.OpenThemeData( hWnd, name );
206cdf0e10cSrcweir     if( hTheme != NULL )
207cdf0e10cSrcweir         aThemeMap[name] = hTheme;
208cdf0e10cSrcweir     return hTheme;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
211cdf0e10cSrcweir /*
212cdf0e10cSrcweir  * IsNativeControlSupported()
213cdf0e10cSrcweir  *
214cdf0e10cSrcweir  *  Returns TRUE if the platform supports native
215cdf0e10cSrcweir  *  drawing of the control defined by nPart
216cdf0e10cSrcweir  */
IsNativeControlSupported(ControlType nType,ControlPart nPart)217cdf0e10cSrcweir sal_Bool WinSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     HTHEME hTheme = NULL;
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     switch( nType )
222cdf0e10cSrcweir     {
223cdf0e10cSrcweir         case CTRL_PUSHBUTTON:
224cdf0e10cSrcweir         case CTRL_RADIOBUTTON:
225cdf0e10cSrcweir         case CTRL_CHECKBOX:
226cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
227cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Button");
228cdf0e10cSrcweir             break;
229cdf0e10cSrcweir         case CTRL_SCROLLBAR:
230cdf0e10cSrcweir             if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT )
231cdf0e10cSrcweir                 return FALSE;   // no background painting needed
232cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
233cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Scrollbar");
234cdf0e10cSrcweir             break;
235cdf0e10cSrcweir         case CTRL_COMBOBOX:
236cdf0e10cSrcweir             if( nPart == HAS_BACKGROUND_TEXTURE )
237cdf0e10cSrcweir                 return FALSE;   // we do not paint the inner part (ie the selection background/focus indication)
238cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
239cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Edit");
240cdf0e10cSrcweir             else if( nPart == PART_BUTTON_DOWN )
241cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Combobox");
242cdf0e10cSrcweir             break;
243cdf0e10cSrcweir         case CTRL_SPINBOX:
244cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
245cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Edit");
246cdf0e10cSrcweir             else if( nPart == PART_ALL_BUTTONS ||
247cdf0e10cSrcweir                 nPart == PART_BUTTON_UP || nPart == PART_BUTTON_DOWN ||
248cdf0e10cSrcweir                 nPart == PART_BUTTON_LEFT|| nPart == PART_BUTTON_RIGHT )
249cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Spin");
250cdf0e10cSrcweir             break;
251cdf0e10cSrcweir         case CTRL_SPINBUTTONS:
252cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL || nPart == PART_ALL_BUTTONS )
253cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Spin");
254cdf0e10cSrcweir             break;
255cdf0e10cSrcweir         case CTRL_EDITBOX:
256cdf0e10cSrcweir         case CTRL_MULTILINE_EDITBOX:
257cdf0e10cSrcweir             if( nPart == HAS_BACKGROUND_TEXTURE )
258cdf0e10cSrcweir                 return FALSE;   // we do not paint the inner part (ie the selection background/focus indication)
259cdf0e10cSrcweir                 //return TRUE;
260cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
261cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Edit");
262cdf0e10cSrcweir             break;
263cdf0e10cSrcweir         case CTRL_LISTBOX:
264cdf0e10cSrcweir             if( nPart == HAS_BACKGROUND_TEXTURE )
265cdf0e10cSrcweir                 return FALSE;   // we do not paint the inner part (ie the selection background/focus indication)
266cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL || nPart == PART_WINDOW )
267cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Listview");
268cdf0e10cSrcweir             else if( nPart == PART_BUTTON_DOWN )
269cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Combobox");
270cdf0e10cSrcweir             break;
271cdf0e10cSrcweir         case CTRL_TAB_PANE:
272cdf0e10cSrcweir         case CTRL_TAB_BODY:
273cdf0e10cSrcweir         case CTRL_TAB_ITEM:
274cdf0e10cSrcweir         case CTRL_FIXEDBORDER:
275cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
276cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Tab");
277cdf0e10cSrcweir             break;
278cdf0e10cSrcweir         case CTRL_TOOLBAR:
279cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL || nPart == PART_BUTTON )
280cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Toolbar");
281cdf0e10cSrcweir             else
282cdf0e10cSrcweir                 // use rebar theme for grip and background
283cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Rebar");
284cdf0e10cSrcweir             break;
285cdf0e10cSrcweir         case CTRL_MENUBAR:
286cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
287cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Rebar");
288cdf0e10cSrcweir             else if( GetSalData()->mbThemeMenuSupport )
289cdf0e10cSrcweir             {
290cdf0e10cSrcweir                 if( nPart == PART_MENU_ITEM )
291cdf0e10cSrcweir                     hTheme = getThemeHandle( mhWnd, L"Menu" );
292cdf0e10cSrcweir             }
293cdf0e10cSrcweir             break;
294cdf0e10cSrcweir         case CTRL_MENU_POPUP:
295cdf0e10cSrcweir             if( GetSalData()->mbThemeMenuSupport )
296cdf0e10cSrcweir             {
297cdf0e10cSrcweir                 if( nPart == PART_ENTIRE_CONTROL ||
298cdf0e10cSrcweir                     nPart == PART_MENU_ITEM ||
299cdf0e10cSrcweir                     nPart == PART_MENU_ITEM_CHECK_MARK ||
300cdf0e10cSrcweir                     nPart == PART_MENU_ITEM_RADIO_MARK ||
301cdf0e10cSrcweir                     nPart == PART_MENU_SEPARATOR )
302cdf0e10cSrcweir                     hTheme = getThemeHandle( mhWnd, L"Menu" );
303cdf0e10cSrcweir             }
304cdf0e10cSrcweir             break;
305cdf0e10cSrcweir         case CTRL_PROGRESS:
306cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
307cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Progress");
308cdf0e10cSrcweir             break;
309cdf0e10cSrcweir         case CTRL_SLIDER:
310cdf0e10cSrcweir             if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA )
311cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Trackbar" );
312cdf0e10cSrcweir             break;
313cdf0e10cSrcweir         case CTRL_LISTNODE:
314cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
315cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"TreeView" );
316cdf0e10cSrcweir             break;
317cdf0e10cSrcweir         default:
318cdf0e10cSrcweir             hTheme = NULL;
319cdf0e10cSrcweir             break;
320cdf0e10cSrcweir     }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir     return (hTheme != NULL);
323cdf0e10cSrcweir }
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 
326cdf0e10cSrcweir /*
327cdf0e10cSrcweir  * HitTestNativeControl()
328cdf0e10cSrcweir  *
329cdf0e10cSrcweir  *  If the return value is TRUE, bIsInside contains information whether
330cdf0e10cSrcweir  *  aPos was or was not inside the native widget specified by the
331cdf0e10cSrcweir  *  nType/nPart combination.
332cdf0e10cSrcweir  */
hitTestNativeControl(ControlType,ControlPart,const Rectangle &,const Point &,sal_Bool &)333cdf0e10cSrcweir sal_Bool WinSalGraphics::hitTestNativeControl( ControlType,
334cdf0e10cSrcweir 							  ControlPart,
335cdf0e10cSrcweir 							  const Rectangle&,
336cdf0e10cSrcweir 							  const Point&,
337cdf0e10cSrcweir 							  sal_Bool& )
338cdf0e10cSrcweir {
339cdf0e10cSrcweir     return FALSE;
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
ImplDrawTheme(HTHEME hTheme,HDC hDC,int iPart,int iState,RECT rc,const OUString & aStr)342cdf0e10cSrcweir sal_Bool ImplDrawTheme( HTHEME hTheme, HDC hDC, int iPart, int iState, RECT rc, const OUString& aStr)
343cdf0e10cSrcweir {
344cdf0e10cSrcweir     HRESULT hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0);
345cdf0e10cSrcweir 
346cdf0e10cSrcweir     if( aStr.getLength() )
347cdf0e10cSrcweir     {
348cdf0e10cSrcweir         RECT rcContent;
349cdf0e10cSrcweir         hr = vsAPI.GetThemeBackgroundContentRect( hTheme, hDC, iPart, iState, &rc, &rcContent);
350cdf0e10cSrcweir         hr = vsAPI.DrawThemeText( hTheme, hDC, iPart, iState,
351cdf0e10cSrcweir             reinterpret_cast<LPCWSTR>(aStr.getStr()), -1,
352cdf0e10cSrcweir             DT_CENTER | DT_VCENTER | DT_SINGLELINE,
353cdf0e10cSrcweir             0, &rcContent);
354cdf0e10cSrcweir     }
355cdf0e10cSrcweir     return (hr == S_OK);
356cdf0e10cSrcweir }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 
ImplGetThemeRect(HTHEME hTheme,HDC hDC,int iPart,int iState,const Rectangle & aRect,THEMESIZE eTS=TS_TRUE)359cdf0e10cSrcweir Rectangle ImplGetThemeRect( HTHEME hTheme, HDC hDC, int iPart, int iState, const Rectangle& aRect, THEMESIZE eTS = TS_TRUE )
360cdf0e10cSrcweir {
361cdf0e10cSrcweir     SIZE aSz;
362cdf0e10cSrcweir     RECT rc;
363cdf0e10cSrcweir     rc.left = aRect.nLeft;
364cdf0e10cSrcweir     rc.right = aRect.nRight;
365cdf0e10cSrcweir     rc.top = aRect.nTop;
366cdf0e10cSrcweir     rc.bottom = aRect.nBottom;
367cdf0e10cSrcweir     HRESULT hr = vsAPI.GetThemePartSize( hTheme, hDC, iPart, iState, NULL, eTS, &aSz ); // TS_TRUE returns optimal size
368cdf0e10cSrcweir     if( hr == S_OK )
369cdf0e10cSrcweir         return Rectangle( 0, 0, aSz.cx, aSz.cy );
370cdf0e10cSrcweir     else
371cdf0e10cSrcweir         return Rectangle();
372cdf0e10cSrcweir }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir // Helper functions
375cdf0e10cSrcweir // ----
376cdf0e10cSrcweir 
ImplConvertSpinbuttonValues(int nControlPart,const ControlState & rState,const Rectangle & rRect,int * pLunaPart,int * pLunaState,RECT * pRect)377cdf0e10cSrcweir void ImplConvertSpinbuttonValues( int nControlPart, const ControlState& rState, const Rectangle& rRect,
378cdf0e10cSrcweir                                  int* pLunaPart, int *pLunaState, RECT *pRect )
379cdf0e10cSrcweir {
380cdf0e10cSrcweir     if( nControlPart == PART_BUTTON_DOWN )
381cdf0e10cSrcweir     {
382cdf0e10cSrcweir         *pLunaPart = SPNP_DOWN;
383cdf0e10cSrcweir         if( rState & CTRL_STATE_PRESSED )
384cdf0e10cSrcweir             *pLunaState = DNS_PRESSED;
385cdf0e10cSrcweir         else if( !(rState & CTRL_STATE_ENABLED) )
386cdf0e10cSrcweir             *pLunaState = DNS_DISABLED;
387cdf0e10cSrcweir         else if( rState & CTRL_STATE_ROLLOVER )
388cdf0e10cSrcweir             *pLunaState = DNS_HOT;
389cdf0e10cSrcweir         else
390cdf0e10cSrcweir             *pLunaState = DNS_NORMAL;
391cdf0e10cSrcweir     }
392cdf0e10cSrcweir     if( nControlPart == PART_BUTTON_UP )
393cdf0e10cSrcweir     {
394cdf0e10cSrcweir         *pLunaPart = SPNP_UP;
395cdf0e10cSrcweir         if( rState & CTRL_STATE_PRESSED )
396cdf0e10cSrcweir             *pLunaState = UPS_PRESSED;
397cdf0e10cSrcweir         else if( !(rState & CTRL_STATE_ENABLED) )
398cdf0e10cSrcweir             *pLunaState = UPS_DISABLED;
399cdf0e10cSrcweir         else if( rState & CTRL_STATE_ROLLOVER )
400cdf0e10cSrcweir             *pLunaState = UPS_HOT;
401cdf0e10cSrcweir         else
402cdf0e10cSrcweir             *pLunaState = UPS_NORMAL;
403cdf0e10cSrcweir     }
404cdf0e10cSrcweir     if( nControlPart == PART_BUTTON_RIGHT )
405cdf0e10cSrcweir     {
406cdf0e10cSrcweir         *pLunaPart = SPNP_UPHORZ;
407cdf0e10cSrcweir         if( rState & CTRL_STATE_PRESSED )
408cdf0e10cSrcweir             *pLunaState = DNHZS_PRESSED;
409cdf0e10cSrcweir         else if( !(rState & CTRL_STATE_ENABLED) )
410cdf0e10cSrcweir             *pLunaState = DNHZS_DISABLED;
411cdf0e10cSrcweir         else if( rState & CTRL_STATE_ROLLOVER )
412cdf0e10cSrcweir             *pLunaState = DNHZS_HOT;
413cdf0e10cSrcweir         else
414cdf0e10cSrcweir             *pLunaState = DNHZS_NORMAL;
415cdf0e10cSrcweir     }
416cdf0e10cSrcweir     if( nControlPart == PART_BUTTON_LEFT )
417cdf0e10cSrcweir     {
418cdf0e10cSrcweir         *pLunaPart = SPNP_DOWNHORZ;
419cdf0e10cSrcweir         if( rState & CTRL_STATE_PRESSED )
420cdf0e10cSrcweir             *pLunaState = UPHZS_PRESSED;
421cdf0e10cSrcweir         else if( !(rState & CTRL_STATE_ENABLED) )
422cdf0e10cSrcweir             *pLunaState = UPHZS_DISABLED;
423cdf0e10cSrcweir         else if( rState & CTRL_STATE_ROLLOVER )
424cdf0e10cSrcweir             *pLunaState = UPHZS_HOT;
425cdf0e10cSrcweir         else
426cdf0e10cSrcweir             *pLunaState = UPHZS_NORMAL;
427cdf0e10cSrcweir     }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir     pRect->left   = rRect.Left();
430cdf0e10cSrcweir     pRect->right  = rRect.Right()+1;
431cdf0e10cSrcweir     pRect->top    = rRect.Top();
432cdf0e10cSrcweir     pRect->bottom = rRect.Bottom()+1;
433cdf0e10cSrcweir }
434cdf0e10cSrcweir 
435cdf0e10cSrcweir // ----
436cdf0e10cSrcweir 
ImplDrawNativeControl(HDC hDC,HTHEME hTheme,RECT rc,ControlType nType,ControlPart nPart,ControlState nState,const ImplControlValue & aValue,OUString aCaption)437cdf0e10cSrcweir sal_Bool ImplDrawNativeControl(	HDC hDC, HTHEME hTheme, RECT rc,
438cdf0e10cSrcweir                             ControlType nType,
439cdf0e10cSrcweir 							ControlPart nPart,
440cdf0e10cSrcweir 							ControlState nState,
441cdf0e10cSrcweir 							const ImplControlValue& aValue,
442cdf0e10cSrcweir 							OUString aCaption )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir     // a listbox dropdown is actually a combobox dropdown
445cdf0e10cSrcweir     if( nType == CTRL_LISTBOX )
446cdf0e10cSrcweir         if( nPart == PART_BUTTON_DOWN )
447cdf0e10cSrcweir             nType = CTRL_COMBOBOX;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     // draw entire combobox as a large edit box
450cdf0e10cSrcweir     if( nType == CTRL_COMBOBOX )
451cdf0e10cSrcweir         if( nPart == PART_ENTIRE_CONTROL )
452cdf0e10cSrcweir             nType = CTRL_EDITBOX;
453cdf0e10cSrcweir 
454cdf0e10cSrcweir     // draw entire spinbox as a large edit box
455cdf0e10cSrcweir     if( nType == CTRL_SPINBOX )
456cdf0e10cSrcweir         if( nPart == PART_ENTIRE_CONTROL )
457cdf0e10cSrcweir             nType = CTRL_EDITBOX;
458cdf0e10cSrcweir 
459cdf0e10cSrcweir     int iPart(0), iState(0);
460cdf0e10cSrcweir     if( nType == CTRL_SCROLLBAR )
461cdf0e10cSrcweir     {
462cdf0e10cSrcweir         HRESULT hr;
463cdf0e10cSrcweir         if( nPart == PART_BUTTON_UP )
464cdf0e10cSrcweir         {
465cdf0e10cSrcweir             iPart = SBP_ARROWBTN;
466cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
467cdf0e10cSrcweir                 iState = ABS_UPPRESSED;
468cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
469cdf0e10cSrcweir                 iState = ABS_UPDISABLED;
470cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
471cdf0e10cSrcweir                 iState = ABS_UPHOT;
472cdf0e10cSrcweir             else
473cdf0e10cSrcweir                 iState = ABS_UPNORMAL;
474cdf0e10cSrcweir             hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0);
475cdf0e10cSrcweir             return (hr == S_OK);
476cdf0e10cSrcweir         }
477cdf0e10cSrcweir         if( nPart == PART_BUTTON_DOWN )
478cdf0e10cSrcweir         {
479cdf0e10cSrcweir             iPart = SBP_ARROWBTN;
480cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
481cdf0e10cSrcweir                 iState = ABS_DOWNPRESSED;
482cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
483cdf0e10cSrcweir                 iState = ABS_DOWNDISABLED;
484cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
485cdf0e10cSrcweir                 iState = ABS_DOWNHOT;
486cdf0e10cSrcweir             else
487cdf0e10cSrcweir                 iState = ABS_DOWNNORMAL;
488cdf0e10cSrcweir             hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0);
489cdf0e10cSrcweir             return (hr == S_OK);
490cdf0e10cSrcweir         }
491cdf0e10cSrcweir         if( nPart == PART_BUTTON_LEFT )
492cdf0e10cSrcweir         {
493cdf0e10cSrcweir             iPart = SBP_ARROWBTN;
494cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
495cdf0e10cSrcweir                 iState = ABS_LEFTPRESSED;
496cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
497cdf0e10cSrcweir                 iState = ABS_LEFTDISABLED;
498cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
499cdf0e10cSrcweir                 iState = ABS_LEFTHOT;
500cdf0e10cSrcweir             else
501cdf0e10cSrcweir                 iState = ABS_LEFTNORMAL;
502cdf0e10cSrcweir             hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0);
503cdf0e10cSrcweir             return (hr == S_OK);
504cdf0e10cSrcweir         }
505cdf0e10cSrcweir         if( nPart == PART_BUTTON_RIGHT )
506cdf0e10cSrcweir         {
507cdf0e10cSrcweir             iPart = SBP_ARROWBTN;
508cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
509cdf0e10cSrcweir                 iState = ABS_RIGHTPRESSED;
510cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
511cdf0e10cSrcweir                 iState = ABS_RIGHTDISABLED;
512cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
513cdf0e10cSrcweir                 iState = ABS_RIGHTHOT;
514cdf0e10cSrcweir             else
515cdf0e10cSrcweir                 iState = ABS_RIGHTNORMAL;
516cdf0e10cSrcweir             hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0);
517cdf0e10cSrcweir             return (hr == S_OK);
518cdf0e10cSrcweir         }
519cdf0e10cSrcweir         if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
520cdf0e10cSrcweir         {
521cdf0e10cSrcweir             iPart = (nPart == PART_THUMB_HORZ) ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
522cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
523cdf0e10cSrcweir                 iState = SCRBS_PRESSED;
524cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
525cdf0e10cSrcweir                 iState = SCRBS_DISABLED;
526cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
527cdf0e10cSrcweir                 iState = SCRBS_HOT;
528cdf0e10cSrcweir             else
529cdf0e10cSrcweir                 iState = SCRBS_NORMAL;
530cdf0e10cSrcweir 
531cdf0e10cSrcweir             SIZE sz;
532cdf0e10cSrcweir             vsAPI.GetThemePartSize(hTheme, hDC, iPart, iState, NULL, TS_MIN, &sz);
533cdf0e10cSrcweir             vsAPI.GetThemePartSize(hTheme, hDC, iPart, iState, NULL, TS_TRUE, &sz);
534cdf0e10cSrcweir             vsAPI.GetThemePartSize(hTheme, hDC, iPart, iState, NULL, TS_DRAW, &sz);
535cdf0e10cSrcweir 
536cdf0e10cSrcweir             hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0);
537cdf0e10cSrcweir             // paint gripper on thumb if enough space
538cdf0e10cSrcweir             if( ( (nPart == PART_THUMB_VERT) && (rc.bottom-rc.top > 12) ) ||
539cdf0e10cSrcweir                 ( (nPart == PART_THUMB_HORZ) && (rc.right-rc.left > 12) ) )
540cdf0e10cSrcweir             {
541cdf0e10cSrcweir                 iPart = (nPart == PART_THUMB_HORZ) ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
542cdf0e10cSrcweir                 iState = 0;
543cdf0e10cSrcweir                 vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0);
544cdf0e10cSrcweir             }
545cdf0e10cSrcweir             return (hr == S_OK);
546cdf0e10cSrcweir         }
547cdf0e10cSrcweir         if( nPart == PART_TRACK_HORZ_LEFT || nPart == PART_TRACK_HORZ_RIGHT || nPart == PART_TRACK_VERT_UPPER || nPart == PART_TRACK_VERT_LOWER )
548cdf0e10cSrcweir         {
549cdf0e10cSrcweir             switch( nPart )
550cdf0e10cSrcweir             {
551cdf0e10cSrcweir                 case PART_TRACK_HORZ_LEFT:  iPart = SBP_UPPERTRACKHORZ; break;
552cdf0e10cSrcweir                 case PART_TRACK_HORZ_RIGHT: iPart = SBP_LOWERTRACKHORZ; break;
553cdf0e10cSrcweir                 case PART_TRACK_VERT_UPPER: iPart = SBP_UPPERTRACKVERT; break;
554cdf0e10cSrcweir                 case PART_TRACK_VERT_LOWER: iPart = SBP_LOWERTRACKVERT; break;
555cdf0e10cSrcweir             }
556cdf0e10cSrcweir 
557cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
558cdf0e10cSrcweir                 iState = SCRBS_PRESSED;
559cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
560cdf0e10cSrcweir                 iState = SCRBS_DISABLED;
561cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
562cdf0e10cSrcweir                 iState = SCRBS_HOT;
563cdf0e10cSrcweir             else
564cdf0e10cSrcweir                 iState = SCRBS_NORMAL;
565cdf0e10cSrcweir             hr = vsAPI.DrawThemeBackground( hTheme, hDC, iPart, iState, &rc, 0);
566cdf0e10cSrcweir             return (hr == S_OK);
567cdf0e10cSrcweir         }
568cdf0e10cSrcweir     }
569cdf0e10cSrcweir     if( nType == CTRL_SPINBUTTONS && nPart == PART_ALL_BUTTONS )
570cdf0e10cSrcweir     {
571cdf0e10cSrcweir         if( aValue.getType() == CTRL_SPINBUTTONS )
572cdf0e10cSrcweir         {
573*3460f9c8SHerbert Dürr             const SpinbuttonValue* pValue = (aValue.getType() == CTRL_SPINBUTTONS) ? static_cast<const SpinbuttonValue*>(&aValue) : NULL;
574cdf0e10cSrcweir             sal_Bool bOk = sal_False;
575cdf0e10cSrcweir 
576cdf0e10cSrcweir             RECT rect;
577cdf0e10cSrcweir             ImplConvertSpinbuttonValues( pValue->mnUpperPart, pValue->mnUpperState, pValue->maUpperRect, &iPart, &iState, &rect );
578cdf0e10cSrcweir             bOk = ImplDrawTheme( hTheme, hDC, iPart, iState, rect, aCaption);
579cdf0e10cSrcweir 
580cdf0e10cSrcweir             if( bOk )
581cdf0e10cSrcweir             {
582cdf0e10cSrcweir                 ImplConvertSpinbuttonValues( pValue->mnLowerPart, pValue->mnLowerState, pValue->maLowerRect, &iPart, &iState, &rect );
583cdf0e10cSrcweir                 bOk = ImplDrawTheme( hTheme, hDC, iPart, iState, rect, aCaption);
584cdf0e10cSrcweir             }
585cdf0e10cSrcweir 
586cdf0e10cSrcweir             return bOk;
587cdf0e10cSrcweir         }
588cdf0e10cSrcweir     }
589cdf0e10cSrcweir     if( nType == CTRL_SPINBOX )
590cdf0e10cSrcweir     {
591cdf0e10cSrcweir         // decrease spinbutton rects a little
592cdf0e10cSrcweir         //rc.right--;
593cdf0e10cSrcweir         //rc.bottom--;
594cdf0e10cSrcweir         if( nPart == PART_ALL_BUTTONS )
595cdf0e10cSrcweir         {
596cdf0e10cSrcweir             if( aValue.getType() == CTRL_SPINBUTTONS )
597cdf0e10cSrcweir             {
598cdf0e10cSrcweir                 const SpinbuttonValue *pValue = static_cast<const SpinbuttonValue*>(&aValue);
599cdf0e10cSrcweir                 sal_Bool bOk = sal_False;
600cdf0e10cSrcweir 
601cdf0e10cSrcweir                 RECT rect;
602cdf0e10cSrcweir                 ImplConvertSpinbuttonValues( pValue->mnUpperPart, pValue->mnUpperState, pValue->maUpperRect, &iPart, &iState, &rect );
603cdf0e10cSrcweir                 bOk = ImplDrawTheme( hTheme, hDC, iPart, iState, rect, aCaption);
604cdf0e10cSrcweir 
605cdf0e10cSrcweir                 if( bOk )
606cdf0e10cSrcweir                 {
607cdf0e10cSrcweir                     ImplConvertSpinbuttonValues( pValue->mnLowerPart, pValue->mnLowerState, pValue->maLowerRect, &iPart, &iState, &rect );
608cdf0e10cSrcweir                     bOk = ImplDrawTheme( hTheme, hDC, iPart, iState, rect, aCaption);
609cdf0e10cSrcweir                 }
610cdf0e10cSrcweir 
611cdf0e10cSrcweir                 return bOk;
612cdf0e10cSrcweir             }
613cdf0e10cSrcweir         }
614cdf0e10cSrcweir 
615cdf0e10cSrcweir         if( nPart == PART_BUTTON_DOWN )
616cdf0e10cSrcweir         {
617cdf0e10cSrcweir             iPart = SPNP_DOWN;
618cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
619cdf0e10cSrcweir                 iState = DNS_PRESSED;
620cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
621cdf0e10cSrcweir                 iState = DNS_DISABLED;
622cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
623cdf0e10cSrcweir                 iState = DNS_HOT;
624cdf0e10cSrcweir             else
625cdf0e10cSrcweir                 iState = DNS_NORMAL;
626cdf0e10cSrcweir         }
627cdf0e10cSrcweir         if( nPart == PART_BUTTON_UP )
628cdf0e10cSrcweir         {
629cdf0e10cSrcweir             iPart = SPNP_UP;
630cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
631cdf0e10cSrcweir                 iState = UPS_PRESSED;
632cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
633cdf0e10cSrcweir                 iState = UPS_DISABLED;
634cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
635cdf0e10cSrcweir                 iState = UPS_HOT;
636cdf0e10cSrcweir             else
637cdf0e10cSrcweir                 iState = UPS_NORMAL;
638cdf0e10cSrcweir         }
639cdf0e10cSrcweir         if( nPart == PART_BUTTON_RIGHT )
640cdf0e10cSrcweir         {
641cdf0e10cSrcweir             iPart = SPNP_DOWNHORZ;
642cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
643cdf0e10cSrcweir                 iState = DNHZS_PRESSED;
644cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
645cdf0e10cSrcweir                 iState = DNHZS_DISABLED;
646cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
647cdf0e10cSrcweir                 iState = DNHZS_HOT;
648cdf0e10cSrcweir             else
649cdf0e10cSrcweir                 iState = DNHZS_NORMAL;
650cdf0e10cSrcweir         }
651cdf0e10cSrcweir         if( nPart == PART_BUTTON_LEFT )
652cdf0e10cSrcweir         {
653cdf0e10cSrcweir             iPart = SPNP_UPHORZ;
654cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
655cdf0e10cSrcweir                 iState = UPHZS_PRESSED;
656cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
657cdf0e10cSrcweir                 iState = UPHZS_DISABLED;
658cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
659cdf0e10cSrcweir                 iState = UPHZS_HOT;
660cdf0e10cSrcweir             else
661cdf0e10cSrcweir                 iState = UPHZS_NORMAL;
662cdf0e10cSrcweir         }
663cdf0e10cSrcweir         if( nPart == PART_BUTTON_LEFT || nPart == PART_BUTTON_RIGHT || nPart == PART_BUTTON_UP || nPart == PART_BUTTON_DOWN )
664cdf0e10cSrcweir             return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
665cdf0e10cSrcweir     }
666cdf0e10cSrcweir     if( nType == CTRL_COMBOBOX )
667cdf0e10cSrcweir     {
668cdf0e10cSrcweir         if( nPart == PART_BUTTON_DOWN )
669cdf0e10cSrcweir         {
670cdf0e10cSrcweir             iPart = CP_DROPDOWNBUTTON;
671cdf0e10cSrcweir             if( nState & CTRL_STATE_PRESSED )
672cdf0e10cSrcweir                 iState = CBXS_PRESSED;
673cdf0e10cSrcweir             else if( !(nState & CTRL_STATE_ENABLED) )
674cdf0e10cSrcweir                 iState = CBXS_DISABLED;
675cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
676cdf0e10cSrcweir                 iState = CBXS_HOT;
677cdf0e10cSrcweir             else
678cdf0e10cSrcweir                 iState = CBXS_NORMAL;
679cdf0e10cSrcweir             return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
680cdf0e10cSrcweir         }
681cdf0e10cSrcweir     }
682cdf0e10cSrcweir     if( nType == CTRL_PUSHBUTTON )
683cdf0e10cSrcweir     {
684cdf0e10cSrcweir         iPart = BP_PUSHBUTTON;
685cdf0e10cSrcweir         if( nState & CTRL_STATE_PRESSED )
686cdf0e10cSrcweir             iState = PBS_PRESSED;
687cdf0e10cSrcweir         else if( !(nState & CTRL_STATE_ENABLED) )
688cdf0e10cSrcweir             iState = PBS_DISABLED;
689cdf0e10cSrcweir         else if( nState & CTRL_STATE_ROLLOVER )
690cdf0e10cSrcweir             iState = PBS_HOT;
691cdf0e10cSrcweir         else if( nState & CTRL_STATE_DEFAULT )
692cdf0e10cSrcweir             iState = PBS_DEFAULTED;
693cdf0e10cSrcweir         //else if( nState & CTRL_STATE_FOCUSED )
694cdf0e10cSrcweir         //    iState = PBS_DEFAULTED;    // may need to draw focus rect
695cdf0e10cSrcweir         else
696cdf0e10cSrcweir             iState = PBS_NORMAL;
697cdf0e10cSrcweir 
698cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
699cdf0e10cSrcweir     }
700cdf0e10cSrcweir 
701cdf0e10cSrcweir     if( nType == CTRL_RADIOBUTTON )
702cdf0e10cSrcweir     {
703cdf0e10cSrcweir         iPart = BP_RADIOBUTTON;
704cdf0e10cSrcweir         sal_Bool bChecked = ( aValue.getTristateVal() == BUTTONVALUE_ON );
705cdf0e10cSrcweir 
706cdf0e10cSrcweir         if( nState & CTRL_STATE_PRESSED )
707cdf0e10cSrcweir             iState = bChecked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED;
708cdf0e10cSrcweir         else if( !(nState & CTRL_STATE_ENABLED) )
709cdf0e10cSrcweir             iState = bChecked ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED;
710cdf0e10cSrcweir         else if( nState & CTRL_STATE_ROLLOVER )
711cdf0e10cSrcweir             iState = bChecked ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT;
712cdf0e10cSrcweir         else
713cdf0e10cSrcweir             iState = bChecked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL;
714cdf0e10cSrcweir 
715cdf0e10cSrcweir         //if( nState & CTRL_STATE_FOCUSED )
716cdf0e10cSrcweir         //    iState |= PBS_DEFAULTED;    // may need to draw focus rect
717cdf0e10cSrcweir 
718cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
719cdf0e10cSrcweir     }
720cdf0e10cSrcweir 
721cdf0e10cSrcweir     if( nType == CTRL_CHECKBOX )
722cdf0e10cSrcweir     {
723cdf0e10cSrcweir         iPart = BP_CHECKBOX;
724cdf0e10cSrcweir         ButtonValue v = aValue.getTristateVal();
725cdf0e10cSrcweir 
726cdf0e10cSrcweir         if( nState & CTRL_STATE_PRESSED )
727cdf0e10cSrcweir             iState = (v == BUTTONVALUE_ON)  ? CBS_CHECKEDPRESSED :
728cdf0e10cSrcweir                     ( (v == BUTTONVALUE_OFF) ? CBS_UNCHECKEDPRESSED : CBS_MIXEDPRESSED );
729cdf0e10cSrcweir         else if( !(nState & CTRL_STATE_ENABLED) )
730cdf0e10cSrcweir             iState = (v == BUTTONVALUE_ON)  ? CBS_CHECKEDDISABLED :
731cdf0e10cSrcweir                     ( (v == BUTTONVALUE_OFF) ? CBS_UNCHECKEDDISABLED : CBS_MIXEDDISABLED );
732cdf0e10cSrcweir         else if( nState & CTRL_STATE_ROLLOVER )
733cdf0e10cSrcweir             iState = (v == BUTTONVALUE_ON)  ? CBS_CHECKEDHOT :
734cdf0e10cSrcweir                     ( (v == BUTTONVALUE_OFF) ? CBS_UNCHECKEDHOT : CBS_MIXEDHOT );
735cdf0e10cSrcweir         else
736cdf0e10cSrcweir             iState = (v == BUTTONVALUE_ON)  ? CBS_CHECKEDNORMAL :
737cdf0e10cSrcweir                     ( (v == BUTTONVALUE_OFF) ? CBS_UNCHECKEDNORMAL : CBS_MIXEDNORMAL );
738cdf0e10cSrcweir 
739cdf0e10cSrcweir         //if( nState & CTRL_STATE_FOCUSED )
740cdf0e10cSrcweir         //    iState |= PBS_DEFAULTED;    // may need to draw focus rect
741cdf0e10cSrcweir 
742cdf0e10cSrcweir         //SIZE sz;
743cdf0e10cSrcweir         //THEMESIZE eSize = TS_DRAW; // TS_MIN, TS_TRUE, TS_DRAW
744cdf0e10cSrcweir         //vsAPI.GetThemePartSize( hTheme, hDC, iPart, iState, &rc, eSize, &sz);
745cdf0e10cSrcweir 
746cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
747cdf0e10cSrcweir     }
748cdf0e10cSrcweir 
749cdf0e10cSrcweir     if( ( nType == CTRL_EDITBOX ) || ( nType == CTRL_MULTILINE_EDITBOX ) )
750cdf0e10cSrcweir     {
751cdf0e10cSrcweir         iPart = EP_EDITTEXT;
752cdf0e10cSrcweir         if( !(nState & CTRL_STATE_ENABLED) )
753cdf0e10cSrcweir             iState = ETS_DISABLED;
754cdf0e10cSrcweir         else if( nState & CTRL_STATE_FOCUSED )
755cdf0e10cSrcweir             iState = ETS_FOCUSED;
756cdf0e10cSrcweir         else if( nState & CTRL_STATE_ROLLOVER )
757cdf0e10cSrcweir             iState = ETS_HOT;
758cdf0e10cSrcweir         else
759cdf0e10cSrcweir             iState = ETS_NORMAL;
760cdf0e10cSrcweir 
761cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
762cdf0e10cSrcweir     }
763cdf0e10cSrcweir 
764cdf0e10cSrcweir     if( nType == CTRL_LISTBOX )
765cdf0e10cSrcweir     {
766cdf0e10cSrcweir         if( nPart == PART_ENTIRE_CONTROL || nPart == PART_WINDOW )
767cdf0e10cSrcweir         {
768cdf0e10cSrcweir             iPart = LVP_EMPTYTEXT; // ??? no idea which part to choose here
769cdf0e10cSrcweir             return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
770cdf0e10cSrcweir         }
771cdf0e10cSrcweir     }
772cdf0e10cSrcweir 
773cdf0e10cSrcweir     if( nType == CTRL_TAB_PANE )
774cdf0e10cSrcweir     {
775cdf0e10cSrcweir         iPart = TABP_PANE;
776cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
777cdf0e10cSrcweir     }
778cdf0e10cSrcweir 
779cdf0e10cSrcweir     if( nType == CTRL_FIXEDBORDER )
780cdf0e10cSrcweir     {
781cdf0e10cSrcweir         /*
782cdf0e10cSrcweir         iPart = BP_GROUPBOX;
783cdf0e10cSrcweir         if( !(nState & CTRL_STATE_ENABLED) )
784cdf0e10cSrcweir             iState = GBS_DISABLED;
785cdf0e10cSrcweir         else
786cdf0e10cSrcweir             iState = GBS_NORMAL;
787cdf0e10cSrcweir             */
788cdf0e10cSrcweir         // The fixed border is only used around the tools->options tabpage where
789cdf0e10cSrcweir         // TABP_PANE fits best
790cdf0e10cSrcweir         iPart = TABP_PANE;
791cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
792cdf0e10cSrcweir     }
793cdf0e10cSrcweir 
794cdf0e10cSrcweir     if( nType == CTRL_TAB_BODY )
795cdf0e10cSrcweir     {
796cdf0e10cSrcweir         iPart = TABP_BODY;
797cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
798cdf0e10cSrcweir     }
799cdf0e10cSrcweir 
800cdf0e10cSrcweir     if( nType == CTRL_TAB_ITEM )
801cdf0e10cSrcweir     {
802cdf0e10cSrcweir         iPart = TABP_TABITEMLEFTEDGE;
803cdf0e10cSrcweir         rc.bottom--;
804cdf0e10cSrcweir 
805cdf0e10cSrcweir         OSL_ASSERT( aValue.getType() == CTRL_TAB_ITEM );
806cdf0e10cSrcweir 
807cdf0e10cSrcweir         const TabitemValue *pValue = static_cast<const TabitemValue*>(&aValue);
808cdf0e10cSrcweir         if( pValue->isBothAligned() )
809cdf0e10cSrcweir         {
810cdf0e10cSrcweir             iPart = TABP_TABITEMLEFTEDGE;
811cdf0e10cSrcweir             rc.right--;
812cdf0e10cSrcweir         }
813cdf0e10cSrcweir         else if( pValue->isLeftAligned() )
814cdf0e10cSrcweir             iPart = TABP_TABITEMLEFTEDGE;
815cdf0e10cSrcweir         else if( pValue->isRightAligned() )
816cdf0e10cSrcweir             iPart = TABP_TABITEMRIGHTEDGE;
817cdf0e10cSrcweir         else iPart = TABP_TABITEM;
818cdf0e10cSrcweir 
819cdf0e10cSrcweir         if( !(nState & CTRL_STATE_ENABLED) )
820cdf0e10cSrcweir             iState = TILES_DISABLED;
821cdf0e10cSrcweir         else if( nState & CTRL_STATE_SELECTED )
822cdf0e10cSrcweir         {
823cdf0e10cSrcweir             iState = TILES_SELECTED;
824cdf0e10cSrcweir             // increase the selected tab
825cdf0e10cSrcweir             rc.left-=2;
826cdf0e10cSrcweir             if( pValue && !pValue->isBothAligned() )
827cdf0e10cSrcweir             {
828cdf0e10cSrcweir                 if( pValue->isLeftAligned() || pValue->isNotAligned() )
829cdf0e10cSrcweir                     rc.right+=2;
830cdf0e10cSrcweir                 if( pValue->isRightAligned() )
831cdf0e10cSrcweir                     rc.right+=1;
832cdf0e10cSrcweir             }
833cdf0e10cSrcweir             rc.top-=2;
834cdf0e10cSrcweir             rc.bottom+=2;
835cdf0e10cSrcweir         }
836cdf0e10cSrcweir         else if( nState & CTRL_STATE_ROLLOVER )
837cdf0e10cSrcweir             iState = TILES_HOT;
838cdf0e10cSrcweir         else if( nState & CTRL_STATE_FOCUSED )
839cdf0e10cSrcweir             iState = TILES_FOCUSED;    // may need to draw focus rect
840cdf0e10cSrcweir         else
841cdf0e10cSrcweir             iState = TILES_NORMAL;
842cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
843cdf0e10cSrcweir     }
844cdf0e10cSrcweir 
845cdf0e10cSrcweir     if( nType == CTRL_TOOLBAR )
846cdf0e10cSrcweir     {
847cdf0e10cSrcweir         if( nPart == PART_BUTTON )
848cdf0e10cSrcweir         {
849cdf0e10cSrcweir             iPart = TP_BUTTON;
850cdf0e10cSrcweir             sal_Bool bChecked = ( aValue.getTristateVal() == BUTTONVALUE_ON );
851cdf0e10cSrcweir             if( !(nState & CTRL_STATE_ENABLED) )
852cdf0e10cSrcweir                 //iState = TS_DISABLED;
853cdf0e10cSrcweir                 // disabled buttons are typically not painted at all but we need visual
854cdf0e10cSrcweir                 // feedback when travelling by keyboard over disabled entries
855cdf0e10cSrcweir                 iState = TS_HOT;
856cdf0e10cSrcweir             else if( nState & CTRL_STATE_PRESSED )
857cdf0e10cSrcweir                 iState = TS_PRESSED;
858cdf0e10cSrcweir             else if( nState & CTRL_STATE_ROLLOVER )
859cdf0e10cSrcweir                 iState = bChecked ? TS_HOTCHECKED : TS_HOT;
860cdf0e10cSrcweir             else
861cdf0e10cSrcweir                 iState = bChecked ? TS_CHECKED : TS_NORMAL;
862cdf0e10cSrcweir             return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
863cdf0e10cSrcweir         }
864cdf0e10cSrcweir         else if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
865cdf0e10cSrcweir         {
866cdf0e10cSrcweir             // the vertical gripper is not supported in most themes and it makes no
867cdf0e10cSrcweir             // sense to only support horizontal gripper
868cdf0e10cSrcweir             //iPart = (nPart == PART_THUMB_HORZ) ? RP_GRIPPERVERT : RP_GRIPPER;
869cdf0e10cSrcweir             //return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
870cdf0e10cSrcweir         }
871cdf0e10cSrcweir         else if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT )
872cdf0e10cSrcweir         {
873cdf0e10cSrcweir             if( aValue.getType() == CTRL_TOOLBAR )
874cdf0e10cSrcweir             {
875cdf0e10cSrcweir                 const ToolbarValue *pValue = static_cast<const ToolbarValue*>(&aValue);
876cdf0e10cSrcweir                 if( pValue->mbIsTopDockingArea )
877cdf0e10cSrcweir                     rc.top = 0; // extend potential gradient to cover menu bar as well
878cdf0e10cSrcweir             }
879cdf0e10cSrcweir             return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
880cdf0e10cSrcweir         }
881cdf0e10cSrcweir     }
882cdf0e10cSrcweir 
883cdf0e10cSrcweir     if( nType == CTRL_MENUBAR )
884cdf0e10cSrcweir     {
885cdf0e10cSrcweir         if( nPart == PART_ENTIRE_CONTROL )
886cdf0e10cSrcweir         {
887cdf0e10cSrcweir             if( aValue.getType() == CTRL_MENUBAR )
888cdf0e10cSrcweir             {
889cdf0e10cSrcweir                 const MenubarValue *pValue = static_cast<const MenubarValue*>(&aValue);
890cdf0e10cSrcweir                 rc.bottom += pValue->maTopDockingAreaHeight;    // extend potential gradient to cover docking area as well
891cdf0e10cSrcweir             }
892cdf0e10cSrcweir             return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
893cdf0e10cSrcweir         }
894cdf0e10cSrcweir         else if( nPart == PART_MENU_ITEM )
895cdf0e10cSrcweir         {
896cdf0e10cSrcweir             if( (nState & CTRL_STATE_ENABLED) )
897cdf0e10cSrcweir                 iState = (nState & CTRL_STATE_SELECTED) ? MBI_HOT : MBI_NORMAL;
898cdf0e10cSrcweir             else
899cdf0e10cSrcweir                 iState = (nState & CTRL_STATE_SELECTED) ? MBI_DISABLEDHOT : MBI_DISABLED;
900cdf0e10cSrcweir             return ImplDrawTheme( hTheme, hDC, MENU_BARITEM, iState, rc, aCaption );
901cdf0e10cSrcweir         }
902cdf0e10cSrcweir     }
903cdf0e10cSrcweir 
904cdf0e10cSrcweir     if( nType == CTRL_PROGRESS )
905cdf0e10cSrcweir     {
906cdf0e10cSrcweir         if( nPart != PART_ENTIRE_CONTROL )
907cdf0e10cSrcweir             return FALSE;
908cdf0e10cSrcweir 
909cdf0e10cSrcweir         if( ! ImplDrawTheme( hTheme, hDC, PP_BAR, iState, rc, aCaption) )
910cdf0e10cSrcweir             return false;
911cdf0e10cSrcweir         RECT aProgressRect = rc;
912cdf0e10cSrcweir         if( vsAPI.GetThemeBackgroundContentRect( hTheme, hDC, PP_BAR, iState, &rc, &aProgressRect) != S_OK )
913cdf0e10cSrcweir             return false;
914cdf0e10cSrcweir 
915cdf0e10cSrcweir         long nProgressWidth = aValue.getNumericVal();
916cdf0e10cSrcweir         nProgressWidth *= (aProgressRect.right - aProgressRect.left);
917cdf0e10cSrcweir         nProgressWidth /= (rc.right - rc.left);
918cdf0e10cSrcweir         if( Application::GetSettings().GetLayoutRTL() )
919cdf0e10cSrcweir             aProgressRect.left = aProgressRect.right - nProgressWidth;
920cdf0e10cSrcweir         else
921cdf0e10cSrcweir             aProgressRect.right = aProgressRect.left + nProgressWidth;
922cdf0e10cSrcweir 
923cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, PP_CHUNK, iState, aProgressRect, aCaption );
924cdf0e10cSrcweir     }
925cdf0e10cSrcweir 
926cdf0e10cSrcweir     if( nType == CTRL_SLIDER )
927cdf0e10cSrcweir     {
928cdf0e10cSrcweir         iPart = (nPart == PART_TRACK_HORZ_AREA) ? TKP_TRACK : TKP_TRACKVERT;
929cdf0e10cSrcweir         iState = (nPart == PART_TRACK_HORZ_AREA) ? TRS_NORMAL : TRVS_NORMAL;
930cdf0e10cSrcweir 
931cdf0e10cSrcweir         Rectangle aTrackRect = ImplGetThemeRect( hTheme, hDC, iPart, iState, Rectangle() );
932cdf0e10cSrcweir         RECT aTRect = rc;
933cdf0e10cSrcweir         if( nPart == PART_TRACK_HORZ_AREA )
934cdf0e10cSrcweir         {
935cdf0e10cSrcweir             long nH = aTrackRect.GetHeight();
936cdf0e10cSrcweir             aTRect.top += (rc.bottom - rc.top - nH)/2;
937cdf0e10cSrcweir             aTRect.bottom = aTRect.top + nH;
938cdf0e10cSrcweir         }
939cdf0e10cSrcweir         else
940cdf0e10cSrcweir         {
941cdf0e10cSrcweir             long nW = aTrackRect.GetWidth();
942cdf0e10cSrcweir             aTRect.left += (rc.right - rc.left - nW)/2;
943cdf0e10cSrcweir             aTRect.right = aTRect.left + nW;
944cdf0e10cSrcweir         }
945cdf0e10cSrcweir         ImplDrawTheme( hTheme, hDC, iPart, iState, aTRect, aCaption );
946cdf0e10cSrcweir 
947cdf0e10cSrcweir         RECT aThumbRect;
948cdf0e10cSrcweir         OSL_ASSERT( aValue.getType() == CTRL_SLIDER );
949cdf0e10cSrcweir         const SliderValue* pVal = static_cast<const SliderValue*>(&aValue);
950cdf0e10cSrcweir         aThumbRect.left   = pVal->maThumbRect.Left();
951cdf0e10cSrcweir         aThumbRect.top    = pVal->maThumbRect.Top();
952cdf0e10cSrcweir         aThumbRect.right  = pVal->maThumbRect.Right();
953cdf0e10cSrcweir         aThumbRect.bottom = pVal->maThumbRect.Bottom();
954cdf0e10cSrcweir         iPart = (nPart == PART_TRACK_HORZ_AREA) ? TKP_THUMB : TKP_THUMBVERT;
955cdf0e10cSrcweir         iState = (nState & CTRL_STATE_ENABLED) ? TUS_NORMAL : TUS_DISABLED;
956cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, aThumbRect, aCaption );
957cdf0e10cSrcweir     }
958cdf0e10cSrcweir 
959cdf0e10cSrcweir     if( nType == CTRL_LISTNODE )
960cdf0e10cSrcweir     {
961cdf0e10cSrcweir         if( nPart != PART_ENTIRE_CONTROL )
962cdf0e10cSrcweir             return FALSE;
963cdf0e10cSrcweir 
964cdf0e10cSrcweir         ButtonValue aButtonValue = aValue.getTristateVal();
965cdf0e10cSrcweir         iPart = TVP_GLYPH;
966cdf0e10cSrcweir         switch( aButtonValue )
967cdf0e10cSrcweir         {
968cdf0e10cSrcweir         case BUTTONVALUE_ON:
969cdf0e10cSrcweir             iState = GLPS_OPENED;
970cdf0e10cSrcweir             break;
971cdf0e10cSrcweir         case BUTTONVALUE_OFF:
972cdf0e10cSrcweir             iState = GLPS_CLOSED;
973cdf0e10cSrcweir             break;
974cdf0e10cSrcweir         default:
975cdf0e10cSrcweir             return FALSE;
976cdf0e10cSrcweir         }
977cdf0e10cSrcweir         return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption );
978cdf0e10cSrcweir     }
979cdf0e10cSrcweir 
980cdf0e10cSrcweir     if( GetSalData()->mbThemeMenuSupport )
981cdf0e10cSrcweir     {
982cdf0e10cSrcweir         if( nType == CTRL_MENU_POPUP )
983cdf0e10cSrcweir         {
984cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
985cdf0e10cSrcweir             {
986cdf0e10cSrcweir                 RECT aGutterRC = rc;
987cdf0e10cSrcweir                 aGutterRC.left += aValue.getNumericVal();
988cdf0e10cSrcweir                 aGutterRC.right = aGutterRC.left+3;
989cdf0e10cSrcweir                 return
990cdf0e10cSrcweir                 ImplDrawTheme( hTheme, hDC, MENU_POPUPBACKGROUND, 0, rc, aCaption ) &&
991cdf0e10cSrcweir                 ImplDrawTheme( hTheme, hDC, MENU_POPUPGUTTER, 0, aGutterRC, aCaption )
992cdf0e10cSrcweir                 ;
993cdf0e10cSrcweir             }
994cdf0e10cSrcweir             else if( nPart == PART_MENU_ITEM )
995cdf0e10cSrcweir             {
996cdf0e10cSrcweir                 if( (nState & CTRL_STATE_ENABLED) )
997cdf0e10cSrcweir                     iState = (nState & CTRL_STATE_SELECTED) ? MPI_HOT : MPI_NORMAL;
998cdf0e10cSrcweir                 else
999cdf0e10cSrcweir                     iState = (nState & CTRL_STATE_SELECTED) ? MPI_DISABLEDHOT : MPI_DISABLED;
1000cdf0e10cSrcweir                 return ImplDrawTheme( hTheme, hDC, MENU_POPUPITEM, iState, rc, aCaption );
1001cdf0e10cSrcweir             }
1002cdf0e10cSrcweir             else if( nPart == PART_MENU_ITEM_CHECK_MARK || nPart == PART_MENU_ITEM_RADIO_MARK )
1003cdf0e10cSrcweir             {
1004cdf0e10cSrcweir                 if( (nState & CTRL_STATE_PRESSED) )
1005cdf0e10cSrcweir                 {
1006cdf0e10cSrcweir                     RECT aBGRect = rc;
1007cdf0e10cSrcweir                     if( aValue.getType() == CTRL_MENU_POPUP )
1008cdf0e10cSrcweir                     {
1009cdf0e10cSrcweir                         const MenupopupValue& rMVal( static_cast<const MenupopupValue&>(aValue) );
1010cdf0e10cSrcweir                         aBGRect.left   = rMVal.maItemRect.Left();
1011cdf0e10cSrcweir                         aBGRect.top    = rMVal.maItemRect.Top();
1012cdf0e10cSrcweir                         aBGRect.bottom = rMVal.maItemRect.Bottom()+1; // see below in drawNativeControl
1013cdf0e10cSrcweir                         aBGRect.right  = rMVal.getNumericVal();
1014cdf0e10cSrcweir 
1015cdf0e10cSrcweir                         // FIXME: magic
1016cdf0e10cSrcweir                         aBGRect.left += 1; aBGRect.top += 1; aBGRect.bottom +=1;
1017cdf0e10cSrcweir                     }
1018cdf0e10cSrcweir                     iState = (nState & CTRL_STATE_ENABLED) ? MCB_NORMAL : MCB_DISABLED;
1019cdf0e10cSrcweir                     ImplDrawTheme( hTheme, hDC, MENU_POPUPCHECKBACKGROUND, iState, aBGRect, aCaption );
1020cdf0e10cSrcweir                     if( nPart == PART_MENU_ITEM_CHECK_MARK )
1021cdf0e10cSrcweir                         iState = (nState & CTRL_STATE_ENABLED) ? MC_CHECKMARKNORMAL : MC_CHECKMARKDISABLED;
1022cdf0e10cSrcweir                     else
1023cdf0e10cSrcweir                         iState = (nState & CTRL_STATE_ENABLED) ? MC_BULLETNORMAL : MC_BULLETDISABLED;
1024cdf0e10cSrcweir                     return ImplDrawTheme( hTheme, hDC, MENU_POPUPCHECK, iState, rc, aCaption );
1025cdf0e10cSrcweir                 }
1026cdf0e10cSrcweir                 else
1027cdf0e10cSrcweir                     return true; // unchecked: do nothing
1028cdf0e10cSrcweir             }
1029cdf0e10cSrcweir             else if( nPart == PART_MENU_SEPARATOR )
1030cdf0e10cSrcweir             {
1031cdf0e10cSrcweir                 rc.left += aValue.getNumericVal(); // adjust for gutter position
1032cdf0e10cSrcweir                 Rectangle aRect( ImplGetThemeRect( hTheme, hDC,
1033cdf0e10cSrcweir                     MENU_POPUPSEPARATOR, 0, Rectangle( rc.left, rc.top, rc.right, rc.bottom ) ) );
1034cdf0e10cSrcweir 				// center the separator inside the passed rectangle
1035cdf0e10cSrcweir 				long nDY = ((rc.bottom - rc.top + 1) - aRect.GetHeight()) / 2;
1036cdf0e10cSrcweir 				rc.top += nDY;
1037cdf0e10cSrcweir 				rc.bottom = rc.top+aRect.GetHeight()-1;
1038cdf0e10cSrcweir                 return ImplDrawTheme( hTheme, hDC, MENU_POPUPSEPARATOR, 0, rc, aCaption );
1039cdf0e10cSrcweir             }
1040cdf0e10cSrcweir         }
1041cdf0e10cSrcweir     }
1042cdf0e10cSrcweir 
1043cdf0e10cSrcweir     return false;
1044cdf0e10cSrcweir }
1045cdf0e10cSrcweir 
1046cdf0e10cSrcweir /*
1047cdf0e10cSrcweir  * DrawNativeControl()
1048cdf0e10cSrcweir  *
1049cdf0e10cSrcweir  *  Draws the requested control described by nPart/nState.
1050cdf0e10cSrcweir  *
1051cdf0e10cSrcweir  *  rControlRegion:	The bounding region of the complete control in VCL frame coordinates.
1052cdf0e10cSrcweir  *  aValue:  		An optional value (tristate/numerical/string)
1053cdf0e10cSrcweir  *  aCaption:  	A caption or title string (like button text etc)
1054cdf0e10cSrcweir  */
drawNativeControl(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,ControlState nState,const ImplControlValue & aValue,const OUString & aCaption)1055cdf0e10cSrcweir sal_Bool WinSalGraphics::drawNativeControl(	ControlType nType,
1056cdf0e10cSrcweir 							ControlPart nPart,
1057cdf0e10cSrcweir 							const Rectangle& rControlRegion,
1058cdf0e10cSrcweir 							ControlState nState,
1059cdf0e10cSrcweir 							const ImplControlValue& aValue,
1060cdf0e10cSrcweir 							const OUString& aCaption )
1061cdf0e10cSrcweir {
1062cdf0e10cSrcweir     sal_Bool bOk = false;
1063cdf0e10cSrcweir     HTHEME hTheme = NULL;
1064cdf0e10cSrcweir 
1065cdf0e10cSrcweir     switch( nType )
1066cdf0e10cSrcweir     {
1067cdf0e10cSrcweir         case CTRL_PUSHBUTTON:
1068cdf0e10cSrcweir         case CTRL_RADIOBUTTON:
1069cdf0e10cSrcweir         case CTRL_CHECKBOX:
1070cdf0e10cSrcweir             hTheme = getThemeHandle( mhWnd, L"Button");
1071cdf0e10cSrcweir             break;
1072cdf0e10cSrcweir         case CTRL_SCROLLBAR:
1073cdf0e10cSrcweir             hTheme = getThemeHandle( mhWnd, L"Scrollbar");
1074cdf0e10cSrcweir             break;
1075cdf0e10cSrcweir         case CTRL_COMBOBOX:
1076cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
1077cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Edit");
1078cdf0e10cSrcweir             else if( nPart == PART_BUTTON_DOWN )
1079cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Combobox");
1080cdf0e10cSrcweir             break;
1081cdf0e10cSrcweir         case CTRL_SPINBOX:
1082cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
1083cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Edit");
1084cdf0e10cSrcweir             else
1085cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Spin");
1086cdf0e10cSrcweir             break;
1087cdf0e10cSrcweir         case CTRL_SPINBUTTONS:
1088cdf0e10cSrcweir             hTheme = getThemeHandle( mhWnd, L"Spin");
1089cdf0e10cSrcweir             break;
1090cdf0e10cSrcweir         case CTRL_EDITBOX:
1091cdf0e10cSrcweir         case CTRL_MULTILINE_EDITBOX:
1092cdf0e10cSrcweir             hTheme = getThemeHandle( mhWnd, L"Edit");
1093cdf0e10cSrcweir             break;
1094cdf0e10cSrcweir         case CTRL_LISTBOX:
1095cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL || nPart == PART_WINDOW )
1096cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Listview");
1097cdf0e10cSrcweir             else if( nPart == PART_BUTTON_DOWN )
1098cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Combobox");
1099cdf0e10cSrcweir             break;
1100cdf0e10cSrcweir         case CTRL_TAB_PANE:
1101cdf0e10cSrcweir         case CTRL_TAB_BODY:
1102cdf0e10cSrcweir         case CTRL_TAB_ITEM:
1103cdf0e10cSrcweir         case CTRL_FIXEDBORDER:
1104cdf0e10cSrcweir             hTheme = getThemeHandle( mhWnd, L"Tab");
1105cdf0e10cSrcweir             break;
1106cdf0e10cSrcweir         case CTRL_TOOLBAR:
1107cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL || nPart == PART_BUTTON )
1108cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Toolbar");
1109cdf0e10cSrcweir             else
1110cdf0e10cSrcweir                 // use rebar for grip and background
1111cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Rebar");
1112cdf0e10cSrcweir             break;
1113cdf0e10cSrcweir         case CTRL_MENUBAR:
1114cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
1115cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Rebar");
1116cdf0e10cSrcweir             else if( GetSalData()->mbThemeMenuSupport )
1117cdf0e10cSrcweir             {
1118cdf0e10cSrcweir                 if( nPart == PART_MENU_ITEM )
1119cdf0e10cSrcweir                     hTheme = getThemeHandle( mhWnd, L"Menu" );
1120cdf0e10cSrcweir             }
1121cdf0e10cSrcweir             break;
1122cdf0e10cSrcweir         case CTRL_PROGRESS:
1123cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
1124cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Progress");
1125cdf0e10cSrcweir             break;
1126cdf0e10cSrcweir         case CTRL_LISTNODE:
1127cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
1128cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"TreeView");
1129cdf0e10cSrcweir             break;
1130cdf0e10cSrcweir         case CTRL_SLIDER:
1131cdf0e10cSrcweir             if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA )
1132cdf0e10cSrcweir                 hTheme = getThemeHandle( mhWnd, L"Trackbar" );
1133cdf0e10cSrcweir             break;
1134cdf0e10cSrcweir         case CTRL_MENU_POPUP:
1135cdf0e10cSrcweir             if( GetSalData()->mbThemeMenuSupport )
1136cdf0e10cSrcweir             {
1137cdf0e10cSrcweir                 if( nPart == PART_ENTIRE_CONTROL || nPart == PART_MENU_ITEM ||
1138cdf0e10cSrcweir                     nPart == PART_MENU_ITEM_CHECK_MARK || nPart == PART_MENU_ITEM_RADIO_MARK ||
1139cdf0e10cSrcweir                     nPart == PART_MENU_SEPARATOR
1140cdf0e10cSrcweir                     )
1141cdf0e10cSrcweir                     hTheme = getThemeHandle( mhWnd, L"Menu" );
1142cdf0e10cSrcweir             }
1143cdf0e10cSrcweir             break;
1144cdf0e10cSrcweir         default:
1145cdf0e10cSrcweir             hTheme = NULL;
1146cdf0e10cSrcweir             break;
1147cdf0e10cSrcweir     }
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir     if( !hTheme )
1150cdf0e10cSrcweir         return false;
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir 	Rectangle buttonRect = rControlRegion;
1153cdf0e10cSrcweir     RECT rc;
1154cdf0e10cSrcweir     rc.left   = buttonRect.Left();
1155cdf0e10cSrcweir     rc.right  = buttonRect.Right()+1;
1156cdf0e10cSrcweir     rc.top    = buttonRect.Top();
1157cdf0e10cSrcweir     rc.bottom = buttonRect.Bottom()+1;
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir     // set default text alignment
11605f27b83cSArmin Le Grand     int ta = SetTextAlign( getHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP );
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir     OUString aCaptionStr( aCaption.replace('~', '&') ); // translate mnemonics
11635f27b83cSArmin Le Grand     bOk = ImplDrawNativeControl(getHDC(), hTheme, rc,
1164cdf0e10cSrcweir                             nType, nPart, nState, aValue,
1165cdf0e10cSrcweir 							aCaptionStr );
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir     // restore alignment
11685f27b83cSArmin Le Grand     SetTextAlign( getHDC(), ta );
1169cdf0e10cSrcweir 
1170cdf0e10cSrcweir 
1171cdf0e10cSrcweir     //GdiFlush();
1172cdf0e10cSrcweir 
1173cdf0e10cSrcweir 	return bOk;
1174cdf0e10cSrcweir }
1175cdf0e10cSrcweir 
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir /*
1178cdf0e10cSrcweir  * DrawNativeControlText()
1179cdf0e10cSrcweir  *
1180cdf0e10cSrcweir  *  OPTIONAL.  Draws the requested text for the control described by nPart/nState.
1181cdf0e10cSrcweir  *     Used if text not drawn by DrawNativeControl().
1182cdf0e10cSrcweir  *
1183cdf0e10cSrcweir  *  rControlRegion:	The bounding region of the complete control in VCL frame coordinates.
1184cdf0e10cSrcweir  *  aValue:  		An optional value (tristate/numerical/string)
1185cdf0e10cSrcweir  *  aCaption:  	A caption or title string (like button text etc)
1186cdf0e10cSrcweir  */
drawNativeControlText(ControlType,ControlPart,const Rectangle &,ControlState,const ImplControlValue &,const OUString &)1187cdf0e10cSrcweir sal_Bool WinSalGraphics::drawNativeControlText(	ControlType,
1188cdf0e10cSrcweir 								ControlPart,
1189cdf0e10cSrcweir 								const Rectangle&,
1190cdf0e10cSrcweir 								ControlState,
1191cdf0e10cSrcweir 								const ImplControlValue&,
1192cdf0e10cSrcweir 								const OUString& )
1193cdf0e10cSrcweir {
1194cdf0e10cSrcweir 	return( false );
1195cdf0e10cSrcweir }
1196cdf0e10cSrcweir 
1197cdf0e10cSrcweir 
1198cdf0e10cSrcweir /*
1199cdf0e10cSrcweir  * GetNativeControlRegion()
1200cdf0e10cSrcweir  *
1201cdf0e10cSrcweir  *  If the return value is TRUE, rNativeBoundingRegion
1202cdf0e10cSrcweir  *  contains the true bounding region covered by the control
1203cdf0e10cSrcweir  *  including any adornment, while rNativeContentRegion contains the area
1204cdf0e10cSrcweir  *  within the control that can be safely drawn into without drawing over
1205cdf0e10cSrcweir  *  the borders of the control.
1206cdf0e10cSrcweir  *
1207cdf0e10cSrcweir  *  rControlRegion:	The bounding region of the control in VCL frame coordinates.
1208cdf0e10cSrcweir  *  aValue:		An optional value (tristate/numerical/string)
1209cdf0e10cSrcweir  *  aCaption:		A caption or title string (like button text etc)
1210cdf0e10cSrcweir  */
getNativeControlRegion(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,ControlState nState,const ImplControlValue & rControlValue,const OUString &,Rectangle & rNativeBoundingRegion,Rectangle & rNativeContentRegion)1211cdf0e10cSrcweir sal_Bool WinSalGraphics::getNativeControlRegion(  ControlType nType,
1212cdf0e10cSrcweir 								ControlPart nPart,
1213cdf0e10cSrcweir 								const Rectangle& rControlRegion,
1214cdf0e10cSrcweir 								ControlState nState,
1215cdf0e10cSrcweir 								const ImplControlValue& rControlValue,
1216cdf0e10cSrcweir 								const OUString&,
1217cdf0e10cSrcweir 								Rectangle &rNativeBoundingRegion,
1218cdf0e10cSrcweir 								Rectangle &rNativeContentRegion )
1219cdf0e10cSrcweir {
1220cdf0e10cSrcweir     sal_Bool bRet = FALSE;
1221cdf0e10cSrcweir 
1222cdf0e10cSrcweir     HDC hDC = GetDC( mhWnd );
1223cdf0e10cSrcweir     if( nType == CTRL_TOOLBAR )
1224cdf0e10cSrcweir     {
1225cdf0e10cSrcweir         if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
1226cdf0e10cSrcweir         {
1227cdf0e10cSrcweir             /*
1228cdf0e10cSrcweir             // the vertical gripper is not supported in most themes and it makes no
1229cdf0e10cSrcweir             // sense to only support horizontal gripper
1230cdf0e10cSrcweir 
1231cdf0e10cSrcweir             HTHEME hTheme = getThemeHandle( mhWnd, L"Rebar");
1232cdf0e10cSrcweir             if( hTheme )
1233cdf0e10cSrcweir             {
1234cdf0e10cSrcweir                 Rectangle aRect( ImplGetThemeRect( hTheme, hDC, nPart == PART_THUMB_HORZ ? RP_GRIPPERVERT : RP_GRIPPER,
1235cdf0e10cSrcweir                     0, rControlRegion.GetBoundRect() ) );
1236cdf0e10cSrcweir                 if( nPart == PART_THUMB_HORZ && !aRect.IsEmpty() )
1237cdf0e10cSrcweir                 {
1238cdf0e10cSrcweir                     Rectangle aVertRect( 0, 0, aRect.getHeight(), aRect.getWidth() );
1239cdf0e10cSrcweir                     rNativeContentRegion = aVertRect;
1240cdf0e10cSrcweir                 }
1241cdf0e10cSrcweir                 else
1242cdf0e10cSrcweir                     rNativeContentRegion = aRect;
1243cdf0e10cSrcweir                 rNativeBoundingRegion = rNativeContentRegion;
1244cdf0e10cSrcweir                 if( !rNativeContentRegion.IsEmpty() )
1245cdf0e10cSrcweir                     bRet = TRUE;
1246cdf0e10cSrcweir             }
1247cdf0e10cSrcweir             */
1248cdf0e10cSrcweir         }
1249cdf0e10cSrcweir         if( nPart == PART_BUTTON )
1250cdf0e10cSrcweir         {
1251cdf0e10cSrcweir             HTHEME hTheme = getThemeHandle( mhWnd, L"Toolbar");
1252cdf0e10cSrcweir             if( hTheme )
1253cdf0e10cSrcweir             {
1254cdf0e10cSrcweir                 Rectangle aRect( ImplGetThemeRect( hTheme, hDC, TP_SPLITBUTTONDROPDOWN,
1255cdf0e10cSrcweir                     TS_HOT, rControlRegion ) );
1256cdf0e10cSrcweir                 rNativeContentRegion = aRect;
1257cdf0e10cSrcweir                 rNativeBoundingRegion = rNativeContentRegion;
1258cdf0e10cSrcweir                 if( !rNativeContentRegion.IsEmpty() )
1259cdf0e10cSrcweir                     bRet = TRUE;
1260cdf0e10cSrcweir             }
1261cdf0e10cSrcweir         }
1262cdf0e10cSrcweir     }
1263cdf0e10cSrcweir     if( nType == CTRL_PROGRESS && nPart == PART_ENTIRE_CONTROL )
1264cdf0e10cSrcweir     {
1265cdf0e10cSrcweir         HTHEME hTheme = getThemeHandle( mhWnd, L"Progress");
1266cdf0e10cSrcweir         if( hTheme )
1267cdf0e10cSrcweir         {
1268cdf0e10cSrcweir             Rectangle aRect( ImplGetThemeRect( hTheme, hDC, PP_BAR,
1269cdf0e10cSrcweir                 0, rControlRegion ) );
1270cdf0e10cSrcweir             rNativeContentRegion = aRect;
1271cdf0e10cSrcweir             rNativeBoundingRegion = rNativeContentRegion;
1272cdf0e10cSrcweir             if( !rNativeContentRegion.IsEmpty() )
1273cdf0e10cSrcweir                 bRet = TRUE;
1274cdf0e10cSrcweir         }
1275cdf0e10cSrcweir     }
1276cdf0e10cSrcweir     if( (nType == CTRL_LISTBOX || nType == CTRL_COMBOBOX ) && nPart == PART_ENTIRE_CONTROL )
1277cdf0e10cSrcweir     {
1278cdf0e10cSrcweir         HTHEME hTheme = getThemeHandle( mhWnd, L"Combobox");
1279cdf0e10cSrcweir         if( hTheme )
1280cdf0e10cSrcweir         {
1281cdf0e10cSrcweir             Rectangle aBoxRect( rControlRegion );
1282cdf0e10cSrcweir             Rectangle aRect( ImplGetThemeRect( hTheme, hDC, CP_DROPDOWNBUTTON,
1283cdf0e10cSrcweir                                                CBXS_NORMAL, aBoxRect ) );
1284cdf0e10cSrcweir             if( aRect.GetHeight() > aBoxRect.GetHeight() )
1285cdf0e10cSrcweir                 aBoxRect.Bottom() = aBoxRect.Top() + aRect.GetHeight();
1286cdf0e10cSrcweir             if( aRect.GetWidth() > aBoxRect.GetWidth() )
1287cdf0e10cSrcweir                 aBoxRect.Right() = aBoxRect.Left() + aRect.GetWidth();
1288cdf0e10cSrcweir             rNativeContentRegion = aBoxRect;
1289cdf0e10cSrcweir             rNativeBoundingRegion = rNativeContentRegion;
1290cdf0e10cSrcweir             if( !aRect.IsEmpty() )
1291cdf0e10cSrcweir                 bRet = TRUE;
1292cdf0e10cSrcweir         }
1293cdf0e10cSrcweir     }
1294cdf0e10cSrcweir 
1295cdf0e10cSrcweir     if( (nType == CTRL_EDITBOX || nType == CTRL_SPINBOX) && nPart == PART_ENTIRE_CONTROL )
1296cdf0e10cSrcweir     {
1297cdf0e10cSrcweir         HTHEME hTheme = getThemeHandle( mhWnd, L"Edit");
1298cdf0e10cSrcweir         if( hTheme )
1299cdf0e10cSrcweir         {
1300cdf0e10cSrcweir             // get border size
1301cdf0e10cSrcweir             Rectangle aBoxRect( rControlRegion );
1302cdf0e10cSrcweir             Rectangle aRect( ImplGetThemeRect( hTheme, hDC, EP_BACKGROUNDWITHBORDER,
1303cdf0e10cSrcweir                                                EBWBS_HOT, aBoxRect ) );
1304cdf0e10cSrcweir             // ad app font height
1305cdf0e10cSrcweir             NONCLIENTMETRICSW aNonClientMetrics;
1306cdf0e10cSrcweir             aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
1307cdf0e10cSrcweir             if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
1308cdf0e10cSrcweir             {
1309cdf0e10cSrcweir                 long nFontHeight = aNonClientMetrics.lfMessageFont.lfHeight;
1310cdf0e10cSrcweir                 if( nFontHeight < 0 )
1311cdf0e10cSrcweir                     nFontHeight = -nFontHeight;
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir                 if( aRect.GetHeight() && nFontHeight )
1314cdf0e10cSrcweir                 {
1315cdf0e10cSrcweir                     aRect.Bottom() += aRect.GetHeight();
1316cdf0e10cSrcweir                     aRect.Bottom() += nFontHeight;
1317cdf0e10cSrcweir                     if( aRect.GetHeight() > aBoxRect.GetHeight() )
1318cdf0e10cSrcweir                         aBoxRect.Bottom() = aBoxRect.Top() + aRect.GetHeight();
1319cdf0e10cSrcweir                     if( aRect.GetWidth() > aBoxRect.GetWidth() )
1320cdf0e10cSrcweir                         aBoxRect.Right() = aBoxRect.Left() + aRect.GetWidth();
1321cdf0e10cSrcweir                     rNativeContentRegion = aBoxRect;
1322cdf0e10cSrcweir                     rNativeBoundingRegion = rNativeContentRegion;
1323cdf0e10cSrcweir                         bRet = TRUE;
1324cdf0e10cSrcweir                 }
1325cdf0e10cSrcweir             }
1326cdf0e10cSrcweir         }
1327cdf0e10cSrcweir     }
1328cdf0e10cSrcweir 
1329cdf0e10cSrcweir     if( GetSalData()->mbThemeMenuSupport )
1330cdf0e10cSrcweir     {
1331cdf0e10cSrcweir         if( nType == CTRL_MENU_POPUP )
1332cdf0e10cSrcweir         {
1333cdf0e10cSrcweir             if( nPart == PART_MENU_ITEM_CHECK_MARK ||
1334cdf0e10cSrcweir                 nPart == PART_MENU_ITEM_RADIO_MARK )
1335cdf0e10cSrcweir             {
1336cdf0e10cSrcweir                 HTHEME hTheme = getThemeHandle( mhWnd, L"Menu");
1337cdf0e10cSrcweir                 Rectangle aBoxRect( rControlRegion );
1338cdf0e10cSrcweir                 Rectangle aRect( ImplGetThemeRect( hTheme, hDC,
1339cdf0e10cSrcweir                     MENU_POPUPCHECK,
1340cdf0e10cSrcweir                     MC_CHECKMARKNORMAL,
1341cdf0e10cSrcweir                     aBoxRect ) );
1342cdf0e10cSrcweir                 if( aBoxRect.GetWidth() && aBoxRect.GetHeight() )
1343cdf0e10cSrcweir                 {
1344cdf0e10cSrcweir                     rNativeContentRegion = aRect;
1345cdf0e10cSrcweir                     rNativeBoundingRegion = rNativeContentRegion;
1346cdf0e10cSrcweir                     bRet = TRUE;
1347cdf0e10cSrcweir                 }
1348cdf0e10cSrcweir             }
1349cdf0e10cSrcweir         }
1350cdf0e10cSrcweir     }
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir     if( nType == CTRL_SLIDER && ( (nPart == PART_THUMB_HORZ) || (nPart == PART_THUMB_VERT) ) )
1353cdf0e10cSrcweir     {
1354cdf0e10cSrcweir         HTHEME hTheme = getThemeHandle( mhWnd, L"Trackbar");
1355cdf0e10cSrcweir         if( hTheme )
1356cdf0e10cSrcweir         {
1357cdf0e10cSrcweir             int iPart = (nPart == PART_THUMB_HORZ) ? TKP_THUMB : TKP_THUMBVERT;
1358cdf0e10cSrcweir             int iState = (nPart == PART_THUMB_HORZ) ? TUS_NORMAL : TUVS_NORMAL;
1359cdf0e10cSrcweir             Rectangle aThumbRect = ImplGetThemeRect( hTheme, hDC, iPart, iState, Rectangle() );
1360cdf0e10cSrcweir             if( nPart == PART_THUMB_HORZ )
1361cdf0e10cSrcweir             {
1362cdf0e10cSrcweir                 long nW = aThumbRect.GetWidth();
1363cdf0e10cSrcweir                 Rectangle aRect( rControlRegion );
1364cdf0e10cSrcweir                 aRect.Right() = aRect.Left() + nW - 1;
1365cdf0e10cSrcweir                 rNativeContentRegion = aRect;
1366cdf0e10cSrcweir                 rNativeBoundingRegion = rNativeContentRegion;
1367cdf0e10cSrcweir             }
1368cdf0e10cSrcweir             else
1369cdf0e10cSrcweir             {
1370cdf0e10cSrcweir                 long nH = aThumbRect.GetHeight();
1371cdf0e10cSrcweir                 Rectangle aRect( rControlRegion );
1372cdf0e10cSrcweir                 aRect.Bottom() = aRect.Top() + nH - 1;
1373cdf0e10cSrcweir                 rNativeContentRegion = aRect;
1374cdf0e10cSrcweir                 rNativeBoundingRegion = rNativeContentRegion;
1375cdf0e10cSrcweir             }
1376cdf0e10cSrcweir             bRet = TRUE;
1377cdf0e10cSrcweir         }
1378cdf0e10cSrcweir     }
1379cdf0e10cSrcweir 
1380cdf0e10cSrcweir     if ( ( nType == CTRL_TAB_ITEM ) && ( nPart == PART_ENTIRE_CONTROL ) )
1381cdf0e10cSrcweir     {
1382cdf0e10cSrcweir         Rectangle aControlRect( rControlRegion );
1383cdf0e10cSrcweir         rNativeContentRegion = aControlRect;
1384cdf0e10cSrcweir 
1385cdf0e10cSrcweir         --aControlRect.Bottom();
1386cdf0e10cSrcweir 
1387cdf0e10cSrcweir         if( rControlValue.getType() == CTRL_TAB_ITEM )
1388cdf0e10cSrcweir         {
1389cdf0e10cSrcweir             const TabitemValue *pValue = static_cast<const TabitemValue*>(&rControlValue);
1390cdf0e10cSrcweir             if ( pValue->isBothAligned() )
1391cdf0e10cSrcweir                 --aControlRect.Right();
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir             if ( nState & CTRL_STATE_SELECTED )
1394cdf0e10cSrcweir             {
1395cdf0e10cSrcweir                 aControlRect.Left() -= 2;
1396cdf0e10cSrcweir                 if ( pValue && !pValue->isBothAligned() )
1397cdf0e10cSrcweir                 {
1398cdf0e10cSrcweir                     if ( pValue->isLeftAligned() || pValue->isNotAligned() )
1399cdf0e10cSrcweir                         aControlRect.Right() += 2;
1400cdf0e10cSrcweir                     if ( pValue->isRightAligned() )
1401cdf0e10cSrcweir                         aControlRect.Right() += 1;
1402cdf0e10cSrcweir                 }
1403cdf0e10cSrcweir                 aControlRect.Top() -= 2;
1404cdf0e10cSrcweir                 aControlRect.Bottom() += 2;
1405cdf0e10cSrcweir             }
1406cdf0e10cSrcweir         }
1407cdf0e10cSrcweir         rNativeBoundingRegion = aControlRect;
1408cdf0e10cSrcweir         bRet = TRUE;
1409cdf0e10cSrcweir     }
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir     ReleaseDC( mhWnd, hDC );
1412cdf0e10cSrcweir 	return( bRet );
1413cdf0e10cSrcweir }
1414cdf0e10cSrcweir 
1415