This source file includes following definitions.
- ImeEventCallback
- AddImePopupObserver
- RemoveImePopupObserver
#include "win8/metro_driver/ime/ime_popup_monitor.h"
#include <windows.h>
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "win8/metro_driver/ime/ime_popup_observer.h"
namespace metro_driver {
namespace {
ImePopupObserver* g_observer_ = NULL;
HWINEVENTHOOK g_hook_handle_ = NULL;
void CALLBACK ImeEventCallback(HWINEVENTHOOK win_event_hook_handle,
DWORD event,
HWND window_handle,
LONG object_id,
LONG child_id,
DWORD event_thread,
DWORD event_time) {
DCHECK(base::MessageLoopForUI::IsCurrent());
if (!g_observer_)
return;
switch (event) {
case EVENT_OBJECT_IME_SHOW:
g_observer_->OnImePopupChanged(ImePopupObserver::kPopupShown);
return;
case EVENT_OBJECT_IME_HIDE:
g_observer_->OnImePopupChanged(ImePopupObserver::kPopupHidden);
return;
case EVENT_OBJECT_IME_CHANGE:
g_observer_->OnImePopupChanged(ImePopupObserver::kPopupUpdated);
return;
}
}
}
void AddImePopupObserver(ImePopupObserver* observer) {
CHECK(g_observer_ == NULL)
<< "Currently only one observer is supported at the same time.";
g_observer_ = observer;
g_hook_handle_ = SetWinEventHook(
EVENT_OBJECT_IME_SHOW,
EVENT_OBJECT_IME_CHANGE,
NULL,
ImeEventCallback,
GetCurrentProcessId(),
0,
WINEVENT_OUTOFCONTEXT);
LOG_IF(ERROR, !g_hook_handle_) << "SetWinEventHook failed.";
}
void RemoveImePopupObserver(ImePopupObserver* observer) {
if (g_observer_ != observer)
return;
g_observer_ = NULL;
if (!g_hook_handle_)
return;
const bool unhook_succeeded = !!UnhookWinEvent(g_hook_handle_);
LOG_IF(ERROR, !unhook_succeeded) << "UnhookWinEvent failed.";
g_hook_handle_ = NULL;
}
}