summaryrefslogtreecommitdiffstats
path: root/ceee/ie/plugin/bho/window_message_source.h
blob: baceafabde995adca5b9294d721764c5da71e4af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Window message source implementation.
#ifndef CEEE_IE_PLUGIN_BHO_WINDOW_MESSAGE_SOURCE_H_
#define CEEE_IE_PLUGIN_BHO_WINDOW_MESSAGE_SOURCE_H_

#include <map>
#include <vector>

#include "base/basictypes.h"
#include "base/lock.h"

// A WindowMessageSource instance monitors keyboard and mouse messages on the
// same thread as the one that creates the instance, and fires events to those
// registered sinks.
//
// NOTE: (1) All the non-static methods are supposed to be called on the thread
//           that creates the instance.
//       (2) Multiple WindowMessageSource instances cannot live in the same
//           thread. Only the first one will be successfully initialized.
class WindowMessageSource {
 public:
  enum MessageType {
    // The destination of the message is the content window (or its descendants)
    // of a tab.
    TAB_CONTENT_WINDOW,
    // Otherwise.
    BROWSER_UI_SAME_THREAD
  };

  // The interface that event consumers have to implement.
  // NOTE: All the callback methods will be called on the thread that creates
  // the WindowMessageSource instance.
  class Sink {
   public:
    virtual ~Sink() {}
    // Called before a message is handled.
    virtual void OnHandleMessage(MessageType type, const MSG* message_info) {}
  };

  WindowMessageSource();
  virtual ~WindowMessageSource();

  bool Initialize();
  void TearDown();

  virtual void RegisterSink(Sink* sink);
  virtual void UnregisterSink(Sink* sink);

 private:
  // Hook procedure for WH_GETMESSAGE.
  static LRESULT CALLBACK GetMessageHookProc(int code,
                                             WPARAM wparam,
                                             LPARAM lparam);
  void OnHandleMessage(const MSG* message_info);

  // Hook procedure for WH_CALLWNDPROCRET.
  static LRESULT CALLBACK CallWndProcRetHookProc(int code,
                                                 WPARAM wparam,
                                                 LPARAM lparam);
  void OnWindowNcDestroy(HWND window);

  // Returns true if the specified window is the tab content window or one of
  // its descendants.
  bool IsWithinTabContentWindow(HWND window);

  // Adds an entry to the message_source_map_. Returns false if the item was
  // already present.
  static bool AddEntryToMap(DWORD thread_id, WindowMessageSource* source);
  // Retrieves an entry from the message_source_map_.
  static WindowMessageSource* GetEntryFromMap(DWORD thread_id);
  // Removes an entry from the message_source_map_.
  static void RemoveEntryFromMap(DWORD thread_id);

  // The thread that creates this object.
  const DWORD create_thread_id_;
  // Event consumers.
  std::vector<Sink*> sinks_;

  // The handle to the hook procedure of WH_GETMESSAGE.
  HHOOK get_message_hook_;
  // The handle to the hook procedure of WH_CALLWNDPROCRET.
  HHOOK call_wnd_proc_ret_hook_;

  // Caches the information about whether a given window is within the tab
  // content window or not.
  typedef std::map<HWND, bool> TabContentWindowMap;
  TabContentWindowMap tab_content_window_map_;

  // Maintains a map from thread IDs to their corresponding
  // WindowMessageSource instances.
  typedef std::map<DWORD, WindowMessageSource*> MessageSourceMap;
  static MessageSourceMap message_source_map_;

  // Used to protect access to the message_source_map_.
  static Lock lock_;

  DISALLOW_COPY_AND_ASSIGN(WindowMessageSource);
};

#endif  // CEEE_IE_PLUGIN_BHO_WINDOW_MESSAGE_SOURCE_H_