15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provides a way to handle exceptions that happen while a WindowProc is
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// running. The behavior of exceptions generated inside a WindowProc is OS
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dependent, but it is possible that the OS just ignores the exception and
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// continues execution, which leads to unpredictable behavior for Chrome.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_WIN_WRAPPED_WINDOW_PROC_H_
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_WIN_WRAPPED_WINDOW_PROC_H_
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace win {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An exception filter for a WindowProc. The return value determines how the
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// exception should be handled, following standard SEH rules. However, the
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expected behavior for this function is to not return, instead of returning
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EXCEPTION_EXECUTE_HANDLER or similar, given that in general we are not
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// prepared to handle exceptions.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (__cdecl *WinProcExceptionFilter)(EXCEPTION_POINTERS* info);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the filter to deal with exceptions inside a WindowProc. Returns the old
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// exception filter, if any.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function should be called before any window is created.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT WinProcExceptionFilter SetWinProcExceptionFilter(
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WinProcExceptionFilter filter);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Calls the registered exception filter.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT int CallExceptionFilter(EXCEPTION_POINTERS* info);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes the WNDCLASSEX structure |*class_out| to be passed to
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RegisterClassEx() making sure that it is associated with the module
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// containing the window procedure.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void InitializeWindowClass(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char16* class_name,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WNDPROC window_proc,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UINT style,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int class_extra,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int window_extra,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HCURSOR cursor,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HBRUSH background,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char16* menu_name,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HICON large_icon,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HICON small_icon,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WNDCLASSEX* class_out);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wrapper that supplies a standard exception frame for the provided WindowProc.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The normal usage is something like this:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LRESULT CALLBACK MyWinProc(HWND hwnd, UINT message,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                            WPARAM wparam, LPARAM lparam) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   // Do Something.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ...
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   WNDCLASSEX wc = {0};
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   wc.lpfnWndProc = WrappedWindowProc<MyWinProc>;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   wc.lpszClassName = class_name;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   ...
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   RegisterClassEx(&wc);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   CreateWindowW(class_name, window_name, ...
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <WNDPROC proc>
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LRESULT CALLBACK WrappedWindowProc(HWND hwnd, UINT message,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   WPARAM wparam, LPARAM lparam) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LRESULT rv = 0;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  __try {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = proc(hwnd, message, wparam, lparam);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } __except(CallExceptionFilter(GetExceptionInformation())) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace win
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_WIN_WRAPPED_WINDOW_PROC_H_
86