wrapped_window_proc.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // Provides a way to handle exceptions that happen while a WindowProc is
  5. // running. The behavior of exceptions generated inside a WindowProc is OS
  6. // dependent, but it is possible that the OS just ignores the exception and
  7. // continues execution, which leads to unpredictable behavior for Chrome.
  8. #ifndef BASE_WIN_WRAPPED_WINDOW_PROC_H_
  9. #define BASE_WIN_WRAPPED_WINDOW_PROC_H_
  10. #include <windows.h>
  11. #include "base/base_export.h"
  12. #include "base/strings/string16.h"
  13. namespace base {
  14. namespace win {
  15. // An exception filter for a WindowProc. The return value determines how the
  16. // exception should be handled, following standard SEH rules. However, the
  17. // expected behavior for this function is to not return, instead of returning
  18. // EXCEPTION_EXECUTE_HANDLER or similar, given that in general we are not
  19. // prepared to handle exceptions.
  20. using WinProcExceptionFilter = int __cdecl (*)(EXCEPTION_POINTERS* info);
  21. // Sets the filter to deal with exceptions inside a WindowProc. Returns the old
  22. // exception filter, if any.
  23. // This function should be called before any window is created.
  24. BASE_EXPORT WinProcExceptionFilter
  25. SetWinProcExceptionFilter(WinProcExceptionFilter filter);
  26. // Calls the registered exception filter.
  27. BASE_EXPORT int CallExceptionFilter(EXCEPTION_POINTERS* info);
  28. // Initializes the WNDCLASSEX structure |*class_out| to be passed to
  29. // RegisterClassEx() making sure that it is associated with the module
  30. // containing the window procedure.
  31. BASE_EXPORT void InitializeWindowClass(const char16* class_name,
  32. WNDPROC window_proc,
  33. UINT style,
  34. int class_extra,
  35. int window_extra,
  36. HCURSOR cursor,
  37. HBRUSH background,
  38. const char16* menu_name,
  39. HICON large_icon,
  40. HICON small_icon,
  41. WNDCLASSEX* class_out);
  42. // Wrapper that supplies a standard exception frame for the provided WindowProc.
  43. // The normal usage is something like this:
  44. //
  45. // LRESULT CALLBACK MyWinProc(HWND hwnd, UINT message,
  46. // WPARAM wparam, LPARAM lparam) {
  47. // // Do Something.
  48. // }
  49. //
  50. // ...
  51. //
  52. // WNDCLASSEX wc = {0};
  53. // wc.lpfnWndProc = WrappedWindowProc<MyWinProc>;
  54. // wc.lpszClassName = class_name;
  55. // ...
  56. // RegisterClassEx(&wc);
  57. //
  58. // CreateWindowW(class_name, window_name, ...
  59. //
  60. template <WNDPROC proc>
  61. LRESULT CALLBACK
  62. WrappedWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
  63. LRESULT rv = 0;
  64. __try {
  65. rv = proc(hwnd, message, wparam, lparam);
  66. } __except (CallExceptionFilter(GetExceptionInformation())) {
  67. }
  68. return rv;
  69. }
  70. } // namespace win
  71. } // namespace base
  72. #endif // BASE_WIN_WRAPPED_WINDOW_PROC_H_