1 // Copyright (c) 2009 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 "chrome_frame/find_dialog.h"
9 #include "chrome_frame/chrome_frame_automation.h"
11 const int kMaxFindChars
= 1024;
13 HHOOK
CFFindDialog::msg_hook_
= NULL
;
15 CFFindDialog::CFFindDialog() {}
17 void CFFindDialog::Init(ChromeFrameAutomationClient
* automation_client
) {
18 automation_client_
= automation_client
;
21 LRESULT
CFFindDialog::OnDestroy(UINT msg
, WPARAM wparam
, LPARAM lparam
,
23 UninstallMessageHook();
27 LRESULT
CFFindDialog::OnFind(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
,
29 wchar_t buffer
[kMaxFindChars
+ 1];
30 GetDlgItemText(IDC_FIND_TEXT
, buffer
, kMaxFindChars
);
31 std::wstring
find_text(buffer
);
33 bool match_case
= IsDlgButtonChecked(IDC_MATCH_CASE
) == BST_CHECKED
;
34 bool search_down
= IsDlgButtonChecked(IDC_DIRECTION_DOWN
) == BST_CHECKED
;
36 automation_client_
->FindInPage(find_text
,
37 search_down
? FWD
: BACK
,
38 match_case
? CASE_SENSITIVE
: IGNORE_CASE
,
44 LRESULT
CFFindDialog::OnCancel(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
,
50 LRESULT
CFFindDialog::OnInitDialog(UINT msg
, WPARAM wparam
, LPARAM lparam
,
52 // Init() must be called before Create() or DoModal()!
53 DCHECK(automation_client_
.get());
56 SendDlgItemMessage(IDC_FIND_TEXT
, EM_EXLIMITTEXT
, 0, kMaxFindChars
);
57 BOOL result
= CheckRadioButton(IDC_DIRECTION_DOWN
, IDC_DIRECTION_UP
,
60 HWND text_field
= GetDlgItem(IDC_FIND_TEXT
);
61 ::SetFocus(text_field
);
63 return FALSE
; // we set the focus ourselves.
66 LRESULT CALLBACK
CFFindDialog::GetMsgProc(int code
, WPARAM wparam
,
68 // Mostly borrowed from http://support.microsoft.com/kb/q187988/
69 // and http://www.codeproject.com/KB/atl/cdialogmessagehook.aspx.
70 LPMSG msg
= reinterpret_cast<LPMSG
>(lparam
);
71 if (code
>= 0 && wparam
== PM_REMOVE
&&
72 msg
->message
>= WM_KEYFIRST
&& msg
->message
<= WM_KEYLAST
) {
73 HWND hwnd
= GetActiveWindow();
74 if (::IsWindow(hwnd
) && ::IsDialogMessage(hwnd
, msg
)) {
75 // The value returned from this hookproc is ignored, and it cannot
76 // be used to tell Windows the message has been handled. To avoid
77 // further processing, convert the message to WM_NULL before
80 msg
->message
= WM_NULL
;
86 // Passes the hook information to the next hook procedure in
87 // the current hook chain.
88 return ::CallNextHookEx(msg_hook_
, code
, wparam
, lparam
);
91 bool CFFindDialog::InstallMessageHook() {
92 // Make sure we only call this once.
93 DCHECK(msg_hook_
== NULL
);
94 msg_hook_
= ::SetWindowsHookEx(WH_GETMESSAGE
, &CFFindDialog::GetMsgProc
,
95 _AtlBaseModule
.m_hInst
, GetCurrentThreadId());
96 DCHECK(msg_hook_
!= NULL
);
97 return msg_hook_
!= NULL
;
100 bool CFFindDialog::UninstallMessageHook() {
101 DCHECK(msg_hook_
!= NULL
);
102 BOOL result
= ::UnhookWindowsHookEx(msg_hook_
);
106 return result
!= FALSE
;