diff options
Diffstat (limited to 'src/thmviewer/thmviewer.cpp')
| -rw-r--r-- | src/thmviewer/thmviewer.cpp | 94 |
1 files changed, 86 insertions, 8 deletions
diff --git a/src/thmviewer/thmviewer.cpp b/src/thmviewer/thmviewer.cpp index 425cdf43..adad3f50 100644 --- a/src/thmviewer/thmviewer.cpp +++ b/src/thmviewer/thmviewer.cpp | |||
| @@ -6,6 +6,7 @@ static const LPCWSTR THMVWR_WINDOW_CLASS_MAIN = L"ThmViewerMain"; | |||
| 6 | 6 | ||
| 7 | static THEME* vpTheme = NULL; | 7 | static THEME* vpTheme = NULL; |
| 8 | static DWORD vdwDisplayThreadId = 0; | 8 | static DWORD vdwDisplayThreadId = 0; |
| 9 | static LPWSTR vsczThemeLoadErrors = NULL; | ||
| 9 | 10 | ||
| 10 | enum THMVWR_CONTROL | 11 | enum THMVWR_CONTROL |
| 11 | { | 12 | { |
| @@ -39,6 +40,9 @@ static LRESULT CALLBACK MainWndProc( | |||
| 39 | __in WPARAM wParam, | 40 | __in WPARAM wParam, |
| 40 | __in LPARAM lParam | 41 | __in LPARAM lParam |
| 41 | ); | 42 | ); |
| 43 | static void OnThemeLoadBegin( | ||
| 44 | __in_z_opt LPWSTR sczThemeLoadErrors | ||
| 45 | ); | ||
| 42 | static void OnThemeLoadError( | 46 | static void OnThemeLoadError( |
| 43 | __in THEME* pTheme, | 47 | __in THEME* pTheme, |
| 44 | __in HRESULT hrFailure | 48 | __in HRESULT hrFailure |
| @@ -48,6 +52,15 @@ static void OnNewTheme( | |||
| 48 | __in HWND hWnd, | 52 | __in HWND hWnd, |
| 49 | __in HANDLE_THEME* pHandle | 53 | __in HANDLE_THEME* pHandle |
| 50 | ); | 54 | ); |
| 55 | static void CALLBACK ThmviewerTraceError( | ||
| 56 | __in_z LPCSTR szFile, | ||
| 57 | __in int iLine, | ||
| 58 | __in REPORT_LEVEL rl, | ||
| 59 | __in UINT source, | ||
| 60 | __in HRESULT hrError, | ||
| 61 | __in_z __format_string LPCSTR szFormat, | ||
| 62 | __in va_list args | ||
| 63 | ); | ||
| 51 | 64 | ||
| 52 | 65 | ||
| 53 | int WINAPI wWinMain( | 66 | int WINAPI wWinMain( |
| @@ -76,6 +89,8 @@ int WINAPI wWinMain( | |||
| 76 | ExitOnFailure(hr, "Failed to initialize COM."); | 89 | ExitOnFailure(hr, "Failed to initialize COM."); |
| 77 | fComInitialized = TRUE; | 90 | fComInitialized = TRUE; |
| 78 | 91 | ||
| 92 | DutilInitialize(&ThmviewerTraceError); | ||
| 93 | |||
| 79 | hr = ProcessCommandLine(lpCmdLine, &sczThemeFile, &sczWxlFile); | 94 | hr = ProcessCommandLine(lpCmdLine, &sczThemeFile, &sczWxlFile); |
| 80 | ExitOnFailure(hr, "Failed to process command line."); | 95 | ExitOnFailure(hr, "Failed to process command line."); |
| 81 | 96 | ||
| @@ -161,6 +176,7 @@ LExit: | |||
| 161 | 176 | ||
| 162 | ThemeFree(vpTheme); | 177 | ThemeFree(vpTheme); |
| 163 | ThemeUninitialize(); | 178 | ThemeUninitialize(); |
| 179 | DutilUninitialize(); | ||
| 164 | 180 | ||
| 165 | // uninitialize COM | 181 | // uninitialize COM |
| 166 | if (fComInitialized) | 182 | if (fComInitialized) |
| @@ -168,11 +184,45 @@ LExit: | |||
| 168 | ::CoUninitialize(); | 184 | ::CoUninitialize(); |
| 169 | } | 185 | } |
| 170 | 186 | ||
| 187 | ReleaseNullStr(vsczThemeLoadErrors); | ||
| 171 | ReleaseStr(sczThemeFile); | 188 | ReleaseStr(sczThemeFile); |
| 172 | ReleaseStr(sczWxlFile); | 189 | ReleaseStr(sczWxlFile); |
| 173 | return hr; | 190 | return hr; |
| 174 | } | 191 | } |
| 175 | 192 | ||
| 193 | static void CALLBACK ThmviewerTraceError( | ||
| 194 | __in_z LPCSTR /*szFile*/, | ||
| 195 | __in int /*iLine*/, | ||
| 196 | __in REPORT_LEVEL /*rl*/, | ||
| 197 | __in UINT source, | ||
| 198 | __in HRESULT hrError, | ||
| 199 | __in_z __format_string LPCSTR szFormat, | ||
| 200 | __in va_list args | ||
| 201 | ) | ||
| 202 | { | ||
| 203 | HRESULT hr = S_OK; | ||
| 204 | LPSTR sczFormattedAnsi = NULL; | ||
| 205 | LPWSTR sczMessage = NULL; | ||
| 206 | |||
| 207 | if (DUTIL_SOURCE_THMUTIL != source) | ||
| 208 | { | ||
| 209 | ExitFunction(); | ||
| 210 | } | ||
| 211 | |||
| 212 | hr = StrAnsiAllocFormattedArgs(&sczFormattedAnsi, szFormat, args); | ||
| 213 | ExitOnFailure(hr, "Failed to format error log string."); | ||
| 214 | |||
| 215 | hr = StrAllocFormatted(&sczMessage, L"Error 0x%08x: %S\r\n", hrError, sczFormattedAnsi); | ||
| 216 | ExitOnFailure(hr, "Failed to prepend error number to error log string."); | ||
| 217 | |||
| 218 | hr = StrAllocConcat(&vsczThemeLoadErrors, sczMessage, 0); | ||
| 219 | ExitOnFailure(hr, "Failed to append theme load error."); | ||
| 220 | |||
| 221 | LExit: | ||
| 222 | ReleaseStr(sczFormattedAnsi); | ||
| 223 | ReleaseStr(sczMessage); | ||
| 224 | } | ||
| 225 | |||
| 176 | 226 | ||
| 177 | // | 227 | // |
| 178 | // ProcessCommandLine - process the provided command line arguments. | 228 | // ProcessCommandLine - process the provided command line arguments. |
| @@ -311,6 +361,10 @@ static LRESULT CALLBACK MainWndProc( | |||
| 311 | } | 361 | } |
| 312 | break; | 362 | break; |
| 313 | 363 | ||
| 364 | case WM_THMVWR_THEME_LOAD_BEGIN: | ||
| 365 | OnThemeLoadBegin(vsczThemeLoadErrors); | ||
| 366 | return 0; | ||
| 367 | |||
| 314 | case WM_THMVWR_THEME_LOAD_ERROR: | 368 | case WM_THMVWR_THEME_LOAD_ERROR: |
| 315 | OnThemeLoadError(vpTheme, lParam); | 369 | OnThemeLoadError(vpTheme, lParam); |
| 316 | return 0; | 370 | return 0; |
| @@ -351,6 +405,13 @@ static LRESULT CALLBACK MainWndProc( | |||
| 351 | return ThemeDefWindowProc(vpTheme, hWnd, uMsg, wParam, lParam); | 405 | return ThemeDefWindowProc(vpTheme, hWnd, uMsg, wParam, lParam); |
| 352 | } | 406 | } |
| 353 | 407 | ||
| 408 | static void OnThemeLoadBegin( | ||
| 409 | __in_z_opt LPWSTR sczThemeLoadErrors | ||
| 410 | ) | ||
| 411 | { | ||
| 412 | ReleaseNullStr(sczThemeLoadErrors); | ||
| 413 | } | ||
| 414 | |||
| 354 | static void OnThemeLoadError( | 415 | static void OnThemeLoadError( |
| 355 | __in THEME* pTheme, | 416 | __in THEME* pTheme, |
| 356 | __in HRESULT hrFailure | 417 | __in HRESULT hrFailure |
| @@ -358,6 +419,8 @@ static void OnThemeLoadError( | |||
| 358 | { | 419 | { |
| 359 | HRESULT hr = S_OK; | 420 | HRESULT hr = S_OK; |
| 360 | LPWSTR sczMessage = NULL; | 421 | LPWSTR sczMessage = NULL; |
| 422 | LPWSTR* psczErrors = NULL; | ||
| 423 | UINT cErrors = 0; | ||
| 361 | TVINSERTSTRUCTW tvi = { }; | 424 | TVINSERTSTRUCTW tvi = { }; |
| 362 | 425 | ||
| 363 | // Add the application node. | 426 | // Add the application node. |
| @@ -368,22 +431,37 @@ static void OnThemeLoadError( | |||
| 368 | tvi.item.pszText = L"Failed to load theme."; | 431 | tvi.item.pszText = L"Failed to load theme."; |
| 369 | tvi.hParent = reinterpret_cast<HTREEITEM>(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi))); | 432 | tvi.hParent = reinterpret_cast<HTREEITEM>(ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi))); |
| 370 | 433 | ||
| 371 | hr = StrAllocFormatted(&sczMessage, L"Error 0x%08x.", hrFailure); | 434 | if (!vsczThemeLoadErrors) |
| 372 | ExitOnFailure(hr, "Failed to format error message."); | 435 | { |
| 436 | hr = StrAllocFormatted(&sczMessage, L"Error 0x%08x.", hrFailure); | ||
| 437 | ExitOnFailure(hr, "Failed to format error message."); | ||
| 438 | |||
| 439 | tvi.item.pszText = sczMessage; | ||
| 440 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)); | ||
| 373 | 441 | ||
| 374 | tvi.item.pszText = sczMessage; | 442 | hr = StrAllocFromError(&sczMessage, hrFailure, NULL); |
| 375 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)); | 443 | ExitOnFailure(hr, "Failed to format error message text."); |
| 376 | 444 | ||
| 377 | hr = StrAllocFromError(&sczMessage, hrFailure, NULL); | 445 | tvi.item.pszText = sczMessage; |
| 378 | ExitOnFailure(hr, "Failed to format error message text."); | 446 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)); |
| 447 | } | ||
| 448 | else | ||
| 449 | { | ||
| 450 | hr = StrSplitAllocArray(&psczErrors, &cErrors, vsczThemeLoadErrors, L"\r\n"); | ||
| 451 | ExitOnFailure(hr, "Failed to split theme load errors."); | ||
| 379 | 452 | ||
| 380 | tvi.item.pszText = sczMessage; | 453 | for (DWORD i = 0; i < cErrors; ++i) |
| 381 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)); | 454 | { |
| 455 | tvi.item.pszText = psczErrors[i]; | ||
| 456 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_INSERTITEMW, 0, reinterpret_cast<LPARAM>(&tvi)); | ||
| 457 | } | ||
| 458 | } | ||
| 382 | 459 | ||
| 383 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_EXPAND, TVE_EXPAND, reinterpret_cast<LPARAM>(tvi.hParent)); | 460 | ThemeSendControlMessage(pTheme, THMVWR_CONTROL_TREE, TVM_EXPAND, TVE_EXPAND, reinterpret_cast<LPARAM>(tvi.hParent)); |
| 384 | 461 | ||
| 385 | LExit: | 462 | LExit: |
| 386 | ReleaseStr(sczMessage); | 463 | ReleaseStr(sczMessage); |
| 464 | ReleaseMem(psczErrors); | ||
| 387 | } | 465 | } |
| 388 | 466 | ||
| 389 | 467 | ||
