26 #include "../NativeWindowFromNode.h"
28 #include <nsComponentManagerUtils.h>
29 #include <nsThreadUtils.h>
31 #define PROP_WMS_INST L"WindowMoveServiceInstance"
54 sbWindowMoveService::hooks_t::const_iterator cit = aHooks.find(aWnd);
55 if(cit != aHooks.end()) {
66 sbWindowMoveService::listeners_t::const_iterator cit = aListeners.find(aWnd);
67 if(cit != aListeners.end()) {
68 cit->second->OnMoveStarted();
78 sbWindowMoveService::listeners_t::const_iterator cit = aListeners.find(aWnd);
79 if(cit != aListeners.end()) {
80 cit->second->OnMoveStopped();
93 return CallNextHookEx(NULL, nCode, wParam, lParam);
96 PCWPSTRUCT
msg =
reinterpret_cast<PCWPSTRUCT
>(lParam);
102 return CallNextHookEx(NULL, nCode, wParam, lParam);
105 if(msg->message == WM_WINDOWPOSCHANGING) {
108 wi.cbSize =
sizeof(WINDOWINFO);
109 if (GetWindowInfo(msg->hwnd, &wi)) {
110 RECT* oldpos = &wi.rcWindow;
111 WINDOWPOS* newpos = (WINDOWPOS*)msg->lParam;
112 if (newpos->flags & SWP_NOMOVE) {
113 return CallNextHookEx(NULL, nCode, wParam, lParam);
117 sbWindowMoveService::resizing_t::iterator it =
118 self->mResizing.find(msg->hwnd);
120 if(it ==
self->mResizing.end()) {
121 self->mResizing.insert(std::make_pair<HWND, bool>(msg->hwnd,
true));
124 else if(!it->second) {
129 else if(msg->message == WM_WINDOWPOSCHANGED) {
130 sbWindowMoveService::resizing_t::iterator it =
131 self->mResizing.find(msg->hwnd);
133 if(it !=
self->mResizing.end() &&
134 it->second ==
true) {
136 nsCOMPtr<nsITimer> timer;
137 timers_t::iterator itTimer =
self->mTimers.find(msg->hwnd);
138 if(itTimer ==
self->mTimers.end()) {
139 nsresult rv = NS_ERROR_UNEXPECTED;
141 timer = do_CreateInstance(
"@mozilla.org/timer;1");
142 self->mTimers.insert(
143 std::make_pair<HWND, nsCOMPtr<nsITimer> >(msg->hwnd, timer));
146 timer = itTimer->second;
150 self->mTimersToWnd.insert(
151 std::make_pair<nsITimer*, HWND>(timer.get(), msg->hwnd));
152 timer->InitWithCallback(
self, 1000, nsITimer::TYPE_ONE_SHOT);
157 return CallNextHookEx(NULL, nCode, wParam, lParam);
163 NS_ENSURE_ARG_POINTER(aWnd);
173 sbWindowMoveService::StartWatchingWindow(
nsISupports *aWindow,
176 NS_ENSURE_ARG_POINTER(aWindow);
177 NS_ENSURE_ARG_POINTER(aListener);
179 NS_WARN_IF_FALSE(NS_IsMainThread(),
"This service is MAIN THREAD ONLY!");
181 HWND windowHandle = NULL;
184 NS_ENSURE_TRUE(windowHandle, NS_ERROR_INVALID_ARG);
188 NS_WARNING(
"Window already hooked. Can only hook a window once.");
192 BOOL success = ::SetPropW(windowHandle,
PROP_WMS_INST, (HANDLE)
this);
193 NS_ENSURE_TRUE(success != 0, NS_ERROR_UNEXPECTED);
195 HHOOK hookHandle = ::SetWindowsHookEx(WH_CALLWNDPROC,
198 ::GetCurrentThreadId());
199 NS_ENSURE_TRUE(hookHandle, NS_ERROR_FAILURE);
201 nsCOMPtr<sbIWindowMoveListener>
listener(aListener);
203 std::make_pair<HWND, nsCOMPtr<sbIWindowMoveListener> >(windowHandle,
206 mHooks.insert(std::make_pair<HWND, HHOOK>(windowHandle, hookHandle));
212 sbWindowMoveService::StopWatchingWindow(
nsISupports *aWindow,
215 NS_ENSURE_ARG_POINTER(aWindow);
216 NS_ENSURE_ARG_POINTER(aListener);
218 NS_WARN_IF_FALSE(NS_IsMainThread(),
"This service is MAIN THREAD ONLY!");
221 NS_ENSURE_TRUE(windowHandle, NS_ERROR_INVALID_ARG);
225 NS_WARNING(
"Attempting to unhook a window that was never hooked.");
229 HANDLE propHandle = ::RemovePropW(windowHandle,
PROP_WMS_INST);
230 NS_WARN_IF_FALSE(propHandle == (HANDLE)
this,
231 "Removed property that didn't match what we should've set!");
234 NS_ENSURE_TRUE(hookHandle, NS_ERROR_FAILURE);
236 BOOL success = ::UnhookWindowsHookEx(hookHandle);
237 NS_ENSURE_TRUE(success != 0, NS_ERROR_FAILURE);
239 mHooks.erase(windowHandle);
246 sbWindowMoveService::Notify(nsITimer *aTimer)
258 nsCOMPtr<nsITimer> grip(aTimer);
NS_DECL_ISUPPORTS NS_DECL_SBIWINDOWMOVESERVICE NS_DECL_NSITIMERCALLBACK typedef std::map< HWND, nsCOMPtr< sbIWindowMoveListener > > listeners_t
void CallListenerMoveStarted(HWND aWnd, const sbWindowMoveService::listeners_t &aListeners)
PRBool IsHooked(HWND aWnd)
static const PRUint32 DEFAULT_HASHTABLE_SIZE
NS_IMPL_ISUPPORTS2(sbAlbumArtService, sbIAlbumArtService, nsIObserver) NS_IMETHODIMP sbAlbumArtService
timertohwnd_t mTimersToWnd
virtual ~sbWindowMoveService()
std::map< HWND, HHOOK > hooks_t
Native window manager interface implementation.
static void * get(nsISupports *window)
void CallListenerMoveStopped(HWND aWnd, const sbWindowMoveService::listeners_t &aListeners)
HHOOK GetHookForWindow(HWND aWnd, const sbWindowMoveService::hooks_t &aHooks)
static LRESULT CALLBACK CallWndProc(int aCode, WPARAM wParam, LPARAM lParam)