[COMCTL32][EXPLORER][UXTHEME] Properly draw the taskbar rebar when themes are enabled...
[reactos.git] / reactos / base / shell / explorer / util.cpp
1 #include "precomp.h"
2 #include <winver.h>
3
4 typedef struct _LANGCODEPAGE
5 {
6 WORD wLanguage;
7 WORD wCodePage;
8 } LANGCODEPAGE, *PLANGCODEPAGE;
9
10 HRESULT
11 IsSameObject(IN IUnknown *punk1, IN IUnknown *punk2)
12 {
13 HRESULT hRet;
14
15 hRet = punk1->QueryInterface(IID_PPV_ARG(IUnknown, &punk1));
16
17 if (!SUCCEEDED(hRet))
18 return hRet;
19
20 hRet = punk2->QueryInterface(IID_PPV_ARG(IUnknown, &punk2));
21
22 punk1->Release();
23
24 if (!SUCCEEDED(hRet))
25 return hRet;
26
27 punk2->Release();
28
29 /* We're dealing with the same object if the IUnknown pointers are equal */
30 return (punk1 == punk2) ? S_OK : S_FALSE;
31 }
32
33 HMENU
34 LoadPopupMenu(IN HINSTANCE hInstance,
35 IN LPCTSTR lpMenuName)
36 {
37 HMENU hMenu, hSubMenu = NULL;
38
39 hMenu = LoadMenu(hInstance,
40 lpMenuName);
41
42 if (hMenu != NULL)
43 {
44 hSubMenu = GetSubMenu(hMenu,
45 0);
46 if (hSubMenu != NULL &&
47 !RemoveMenu(hMenu,
48 0,
49 MF_BYPOSITION))
50 {
51 hSubMenu = NULL;
52 }
53
54 DestroyMenu(hMenu);
55 }
56
57 return hSubMenu;
58 }
59
60 HMENU
61 FindSubMenu(IN HMENU hMenu,
62 IN UINT uItem,
63 IN BOOL fByPosition)
64 {
65 MENUITEMINFO mii;
66
67 mii.cbSize = sizeof(mii);
68 mii.fMask = MIIM_SUBMENU;
69
70 if (GetMenuItemInfo(hMenu,
71 uItem,
72 fByPosition,
73 &mii))
74 {
75 return mii.hSubMenu;
76 }
77
78 return NULL;
79 }
80
81 BOOL
82 GetCurrentLoggedOnUserName(OUT LPTSTR szBuffer,
83 IN DWORD dwBufferSize)
84 {
85 DWORD dwType;
86 DWORD dwSize;
87
88 /* Query the user name from the registry */
89 dwSize = (dwBufferSize * sizeof(WCHAR)) - 1;
90 if (RegQueryValueEx(hkExplorer,
91 TEXT("Logon User Name"),
92 0,
93 &dwType,
94 (LPBYTE) szBuffer,
95 &dwSize) == ERROR_SUCCESS &&
96 (dwSize / sizeof(WCHAR)) > 1 &&
97 szBuffer[0] != _T('\0'))
98 {
99 szBuffer[dwSize / sizeof(WCHAR)] = _T('\0');
100 return TRUE;
101 }
102
103 /* Fall back to GetUserName() */
104 dwSize = dwBufferSize;
105 if (!GetUserName(szBuffer,
106 &dwSize))
107 {
108 szBuffer[0] = _T('\0');
109 return FALSE;
110 }
111
112 return TRUE;
113 }
114
115 BOOL
116 FormatMenuString(IN HMENU hMenu,
117 IN UINT uPosition,
118 IN UINT uFlags,
119 ...)
120 {
121 va_list vl;
122 MENUITEMINFO mii;
123 WCHAR szBuf[128];
124 WCHAR szBufFmt[128];
125
126 /* Find the menu item and read the formatting string */
127 mii.cbSize = sizeof(mii);
128 mii.fMask = MIIM_STRING;
129 mii.dwTypeData = (LPTSTR) szBufFmt;
130 mii.cch = sizeof(szBufFmt) / sizeof(szBufFmt[0]);
131 if (GetMenuItemInfo(hMenu,
132 uPosition,
133 uFlags,
134 &mii))
135 {
136 /* Format the string */
137 va_start(vl, uFlags);
138 _vsntprintf(szBuf,
139 (sizeof(szBuf) / sizeof(szBuf[0])) - 1,
140 szBufFmt,
141 vl);
142 va_end(vl);
143 szBuf[(sizeof(szBuf) / sizeof(szBuf[0])) - 1] = _T('\0');
144
145 /* Update the menu item */
146 mii.dwTypeData = (LPTSTR) szBuf;
147 if (SetMenuItemInfo(hMenu,
148 uPosition,
149 uFlags,
150 &mii))
151 {
152 return TRUE;
153 }
154 }
155
156 return FALSE;
157 }
158
159 BOOL
160 GetExplorerRegValueSet(IN HKEY hKey,
161 IN LPCTSTR lpSubKey,
162 IN LPCTSTR lpValue)
163 {
164 WCHAR szBuffer[MAX_PATH];
165 HKEY hkSubKey;
166 DWORD dwType, dwSize;
167 BOOL Ret = FALSE;
168
169 StringCbCopy(szBuffer, sizeof(szBuffer),
170 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"));
171 if (FAILED_UNEXPECTEDLY(StringCbCat(szBuffer, sizeof(szBuffer),
172 _T("\\"))))
173 return FALSE;
174 if (FAILED_UNEXPECTEDLY(StringCbCat(szBuffer, sizeof(szBuffer),
175 lpSubKey)))
176 return FALSE;
177
178 dwSize = sizeof(szBuffer);
179 if (RegOpenKeyEx(hKey,
180 szBuffer,
181 0,
182 KEY_QUERY_VALUE,
183 &hkSubKey) == ERROR_SUCCESS)
184 {
185 ZeroMemory(szBuffer,
186 sizeof(szBuffer));
187
188 if (RegQueryValueEx(hkSubKey,
189 lpValue,
190 0,
191 &dwType,
192 (LPBYTE) szBuffer,
193 &dwSize) == ERROR_SUCCESS)
194 {
195 if (dwType == REG_DWORD && dwSize == sizeof(DWORD))
196 Ret = *((PDWORD) szBuffer) != 0;
197 else if (dwSize > 0)
198 Ret = *((PCHAR) szBuffer) != 0;
199 }
200
201 RegCloseKey(hkSubKey);
202 }
203 return Ret;
204 }
205
206 BOOL
207 GetVersionInfoString(IN WCHAR *szFileName,
208 IN WCHAR *szVersionInfo,
209 OUT WCHAR *szBuffer,
210 IN UINT cbBufLen)
211 {
212 LPVOID lpData = NULL;
213 WCHAR szSubBlock[128];
214 WCHAR *lpszLocalBuf = NULL;
215 LANGID UserLangId;
216 PLANGCODEPAGE lpTranslate = NULL;
217 DWORD dwLen;
218 DWORD dwHandle;
219 UINT cbTranslate;
220 UINT cbLen;
221 BOOL bRet = FALSE;
222 unsigned int i;
223
224 dwLen = GetFileVersionInfoSize(szFileName, &dwHandle);
225
226 if (dwLen > 0)
227 {
228 lpData = HeapAlloc(hProcessHeap, 0, dwLen);
229
230 if (lpData != NULL)
231 {
232 if (GetFileVersionInfo(szFileName,
233 0,
234 dwLen,
235 lpData) != 0)
236 {
237 UserLangId = GetUserDefaultLangID();
238
239 VerQueryValue(lpData,
240 TEXT("\\VarFileInfo\\Translation"),
241 (LPVOID *) &lpTranslate,
242 &cbTranslate);
243
244 for (i = 0; i < cbTranslate / sizeof(LANGCODEPAGE); i++)
245 {
246 /* If the bottom eight bits of the language id's
247 match, use this version information (since this
248 means that the version information and the users
249 default language are the same). */
250 if ((lpTranslate[i].wLanguage & 0xFF) ==
251 (UserLangId & 0xFF))
252 {
253 wnsprintf(szSubBlock,
254 sizeof(szSubBlock) / sizeof(szSubBlock[0]),
255 TEXT("\\StringFileInfo\\%04X%04X\\%s"),
256 lpTranslate[i].wLanguage,
257 lpTranslate[i].wCodePage,
258 szVersionInfo);
259
260 if (VerQueryValue(lpData,
261 szSubBlock,
262 (LPVOID *) &lpszLocalBuf,
263 &cbLen) != 0)
264 {
265 _tcsncpy(szBuffer, lpszLocalBuf, cbBufLen / sizeof(*szBuffer));
266
267 bRet = TRUE;
268 break;
269 }
270 }
271 }
272 }
273 HeapFree(hProcessHeap, 0, lpData);
274 lpData = NULL;
275 }
276 }
277
278 return bRet;
279 }