shell32: Check for internal shell classes before querying the registry in SHCoCreateI...
[wine] / dlls / comctl32 / theme_listbox.c
1 /*
2  * Theming - List box control
3  *
4  * Copyright (c) 2005 by Frank Richter
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  */
21
22 #include <stdarg.h>
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "uxtheme.h"
31 #include "tmschema.h"
32 #include "comctl32.h"
33 #include "wine/debug.h"
34
35 /* Draw themed border */
36 static void nc_paint (HTHEME theme, HWND hwnd, HRGN region)
37 {
38     HRGN cliprgn = region;
39     DWORD exStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
40     if (exStyle & WS_EX_CLIENTEDGE)
41     {
42         HDC dc;
43         RECT r;
44         int cxEdge = GetSystemMetrics (SM_CXEDGE),
45             cyEdge = GetSystemMetrics (SM_CYEDGE);
46     
47         GetWindowRect(hwnd, &r);
48     
49         /* New clipping region passed to default proc to exclude border */
50         cliprgn = CreateRectRgn (r.left + cxEdge, r.top + cyEdge,
51             r.right - cxEdge, r.bottom - cyEdge);
52         if (region != (HRGN)1)
53             CombineRgn (cliprgn, cliprgn, region, RGN_AND);
54         OffsetRect(&r, -r.left, -r.top);
55     
56         dc = GetDCEx(hwnd, region, DCX_WINDOW|DCX_INTERSECTRGN);
57         OffsetRect(&r, -r.left, -r.top);
58     
59         if (IsThemeBackgroundPartiallyTransparent (theme, 0, 0))
60             DrawThemeParentBackground(hwnd, dc, &r);
61         DrawThemeBackground (theme, dc, 0, 0, &r, 0);
62         ReleaseDC(hwnd, dc);
63     }
64
65     /* Call default proc to get the scrollbars etc. painted */
66     DefWindowProcW (hwnd, WM_NCPAINT, (WPARAM)cliprgn, 0);
67 }
68
69 /**********************************************************************
70  * The list control subclass window proc.
71  */
72 LRESULT CALLBACK THEMING_ListBoxSubclassProc (HWND hwnd, UINT msg, 
73                                               WPARAM wParam, LPARAM lParam, 
74                                               ULONG_PTR dwRefData)
75 {
76     const WCHAR* themeClass = WC_LISTBOXW;
77     HTHEME theme;
78     LRESULT result;
79       
80     switch (msg)
81     {
82     case WM_CREATE:
83         result = THEMING_CallOriginalClass  (hwnd, msg, wParam, lParam);
84         OpenThemeData( hwnd, themeClass );
85         return result;
86     
87     case WM_DESTROY:
88         theme = GetWindowTheme( hwnd );
89         CloseThemeData ( theme );
90         return THEMING_CallOriginalClass (hwnd, msg, wParam, lParam);
91
92     case WM_THEMECHANGED:
93         theme = GetWindowTheme( hwnd );
94         CloseThemeData ( theme );
95         OpenThemeData( hwnd, themeClass );
96         break;
97         
98     case WM_SYSCOLORCHANGE:
99         theme = GetWindowTheme( hwnd );
100         if (!theme) return THEMING_CallOriginalClass (hwnd, msg, wParam, lParam);
101         /* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
102          * which will do the repaint. */
103         break;
104         
105     case WM_NCPAINT:
106         theme = GetWindowTheme( hwnd );
107         if (!theme) return THEMING_CallOriginalClass (hwnd, msg, wParam, lParam);
108         nc_paint (theme, hwnd, (HRGN)wParam);
109         break;
110
111     default: 
112         /* Call old proc */
113         return THEMING_CallOriginalClass (hwnd, msg, wParam, lParam);
114     }
115     return 0;
116 }