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