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