|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // Provides a way to handle exceptions that happen while a WindowProc is | 
|  | // running. The behavior of exceptions generated inside a WindowProc is OS | 
|  | // dependent, but it is possible that the OS just ignores the exception and | 
|  | // continues execution, which leads to unpredictable behavior for Chrome. | 
|  |  | 
|  | #ifndef BASE_WIN_WRAPPED_WINDOW_PROC_H_ | 
|  | #define BASE_WIN_WRAPPED_WINDOW_PROC_H_ | 
|  |  | 
|  | #include <windows.h> | 
|  |  | 
|  | #include "base/base_export.h" | 
|  | #include "base/string16.h" | 
|  |  | 
|  | namespace base { | 
|  | namespace win { | 
|  |  | 
|  | // An exception filter for a WindowProc. The return value determines how the | 
|  | // exception should be handled, following standard SEH rules. However, the | 
|  | // expected behavior for this function is to not return, instead of returning | 
|  | // EXCEPTION_EXECUTE_HANDLER or similar, given that in general we are not | 
|  | // prepared to handle exceptions. | 
|  | typedef int (__cdecl *WinProcExceptionFilter)(EXCEPTION_POINTERS* info); | 
|  |  | 
|  | // Sets the filter to deal with exceptions inside a WindowProc. Returns the old | 
|  | // exception filter, if any. | 
|  | // This function should be called before any window is created. | 
|  | BASE_EXPORT WinProcExceptionFilter SetWinProcExceptionFilter( | 
|  | WinProcExceptionFilter filter); | 
|  |  | 
|  | // Calls the registered exception filter. | 
|  | BASE_EXPORT int CallExceptionFilter(EXCEPTION_POINTERS* info); | 
|  |  | 
|  | // Initializes the WNDCLASSEX structure |*class_out| to be passed to | 
|  | // RegisterClassEx() making sure that it is associated with the module | 
|  | // containing the window procedure. | 
|  | BASE_EXPORT void InitializeWindowClass( | 
|  | const char16* class_name, | 
|  | WNDPROC window_proc, | 
|  | UINT style, | 
|  | int class_extra, | 
|  | int window_extra, | 
|  | HCURSOR cursor, | 
|  | HBRUSH background, | 
|  | const char16* menu_name, | 
|  | HICON large_icon, | 
|  | HICON small_icon, | 
|  | WNDCLASSEX* class_out); | 
|  |  | 
|  | // Wrapper that supplies a standard exception frame for the provided WindowProc. | 
|  | // The normal usage is something like this: | 
|  | // | 
|  | // LRESULT CALLBACK MyWinProc(HWND hwnd, UINT message, | 
|  | //                            WPARAM wparam, LPARAM lparam) { | 
|  | //   // Do Something. | 
|  | // } | 
|  | // | 
|  | // ... | 
|  | // | 
|  | //   WNDCLASSEX wc = {0}; | 
|  | //   wc.lpfnWndProc = WrappedWindowProc<MyWinProc>; | 
|  | //   wc.lpszClassName = class_name; | 
|  | //   ... | 
|  | //   RegisterClassEx(&wc); | 
|  | // | 
|  | //   CreateWindowW(class_name, window_name, ... | 
|  | // | 
|  | template <WNDPROC proc> | 
|  | LRESULT CALLBACK WrappedWindowProc(HWND hwnd, UINT message, | 
|  | WPARAM wparam, LPARAM lparam) { | 
|  | LRESULT rv = 0; | 
|  | __try { | 
|  | rv = proc(hwnd, message, wparam, lparam); | 
|  | } __except(CallExceptionFilter(GetExceptionInformation())) { | 
|  | } | 
|  | return rv; | 
|  | } | 
|  |  | 
|  | }  // namespace win | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_WIN_WRAPPED_WINDOW_PROC_H_ |