1 // Copyright (c) 2011 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.
5 #include "base/message_loop/message_loop.h"
6 #include "base/win/wrapped_window_proc.h"
7 #include "testing/gtest/include/gtest/gtest.h"
11 DWORD kExceptionCode
= 12345;
12 WPARAM kCrashMsg
= 98765;
14 // A trivial WindowProc that generates an exception.
15 LRESULT CALLBACK
TestWindowProc(HWND hwnd
, UINT message
,
16 WPARAM wparam
, LPARAM lparam
) {
17 if (message
== kCrashMsg
)
18 RaiseException(kExceptionCode
, 0, 0, NULL
);
19 return DefWindowProc(hwnd
, message
, wparam
, lparam
);
22 // This class implements an exception filter that can be queried about a past
24 class TestWrappedExceptionFiter
{
26 TestWrappedExceptionFiter() : called_(false) {
27 EXPECT_FALSE(s_filter_
);
31 ~TestWrappedExceptionFiter() {
32 EXPECT_EQ(s_filter_
, this);
40 // The actual exception filter just records the exception.
41 static int Filter(EXCEPTION_POINTERS
* info
) {
42 EXPECT_FALSE(s_filter_
->called_
);
43 if (info
->ExceptionRecord
->ExceptionCode
== kExceptionCode
)
44 s_filter_
->called_
= true;
45 return EXCEPTION_EXECUTE_HANDLER
;
50 static TestWrappedExceptionFiter
* s_filter_
;
52 TestWrappedExceptionFiter
* TestWrappedExceptionFiter::s_filter_
= NULL
;
56 TEST(WrappedWindowProc
, CatchesExceptions
) {
57 HINSTANCE hinst
= GetModuleHandle(NULL
);
58 std::wstring
class_name(L
"TestClass");
61 wc
.lpfnWndProc
= base::win::WrappedWindowProc
<TestWindowProc
>;
63 wc
.lpszClassName
= class_name
.c_str();
66 HWND window
= CreateWindow(class_name
.c_str(), 0, 0, 0, 0, 0, 0, HWND_MESSAGE
,
70 // Before generating the exception we make sure that the filter will see it.
71 TestWrappedExceptionFiter wrapper
;
72 base::win::WinProcExceptionFilter old_filter
=
73 base::win::SetWinProcExceptionFilter(TestWrappedExceptionFiter::Filter
);
75 SendMessage(window
, kCrashMsg
, 0, 0);
76 EXPECT_TRUE(wrapper
.called());
78 base::win::SetWinProcExceptionFilter(old_filter
);