wrapped_window_proc.h 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. namespace base {
  13. namespace win {
  14. // An exception filter for a WindowProc. The return value determines how the
  15. // exception should be handled, following standard SEH rules. However, the
  16. // expected behavior for this function is to not return, instead of returning
  17. // EXCEPTION_EXECUTE_HANDLER or similar, given that in general we are not
  18. // prepared to handle exceptions.
  19. using WinProcExceptionFilter = int __cdecl (*)(EXCEPTION_POINTERS* info);
  20. // Sets the filter to deal with exceptions inside a WindowProc. Returns the old
  21. // exception filter, if any.
  22. // This function should be called before any window is created.
  23. BASE_EXPORT WinProcExceptionFilter
  24. SetWinProcExceptionFilter(WinProcExceptionFilter filter);
  25. // Calls the registered exception filter.
  26. BASE_EXPORT int CallExceptionFilter(EXCEPTION_POINTERS* info);
  27. // Initializes the WNDCLASSEX structure |*class_out| to be passed to
  28. // RegisterClassEx() making sure that it is associated with the module
  29. // containing the window procedure.
  30. BASE_EXPORT void InitializeWindowClass(const wchar_t* class_name,
  31. WNDPROC window_proc,
  32. UINT style,
  33. int class_extra,
  34. int window_extra,
  35. HCURSOR cursor,
  36. HBRUSH background,
  37. const wchar_t* menu_name,
  38. HICON large_icon,
  39. HICON small_icon,
  40. WNDCLASSEX* class_out);
  41. // Wrapper that supplies a standard exception frame for the provided WindowProc.
  42. // The normal usage is something like this:
  43. //
  44. // LRESULT CALLBACK MyWinProc(HWND hwnd, UINT message,
  45. // WPARAM wparam, LPARAM lparam) {
  46. // // Do Something.
  47. // }
  48. //
  49. // ...
  50. //
  51. // WNDCLASSEX wc = {0};
  52. // wc.lpfnWndProc = WrappedWindowProc<MyWinProc>;
  53. // wc.lpszClassName = class_name;
  54. // ...
  55. // RegisterClassEx(&wc);
  56. //
  57. // CreateWindowW(class_name, window_name, ...
  58. //
  59. template <WNDPROC proc>
  60. LRESULT CALLBACK
  61. WrappedWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
  62. LRESULT rv = 0;
  63. __try {
  64. rv = proc(hwnd, message, wparam, lparam);
  65. } __except (CallExceptionFilter(GetExceptionInformation())) {
  66. }
  67. return rv;
  68. }
  69. } // namespace win
  70. } // namespace base
  71. #endif // BASE_WIN_WRAPPED_WINDOW_PROC_H_