1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Andrei Volkov <av@netscape.com>
24 * Brian Stell <bstell@netscape.com>
25 * Peter Lubczynski <peterl@netscape.com>
26 * Jim Mathies <jmathies@mozilla.com>
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
45 // XXXbz windowsx.h defines GetFirstChild, GetNextSibling,
46 // GetPrevSibling are macros, apparently... Eeevil. We have functions
47 // called that on some classes, so undef them.
54 #include "nsGUIEvent.h"
55 #include "nsWindowsDllInterceptor.h"
56 #include "nsPluginSafety.h"
57 #include "nsPluginNativeWindow.h"
58 #include "nsThreadUtils.h"
59 #include "nsAutoPtr.h"
60 #include "nsTWeakRef.h"
62 #define NP_POPUP_API_VERSION 16
64 #define nsMajorVersion(v) (((PRInt32)(v) >> 16) & 0xffff)
65 #define nsMinorVersion(v) ((PRInt32)(v) & 0xffff)
66 #define versionOK(suppliedV, requiredV) \
67 (nsMajorVersion(suppliedV) == nsMajorVersion(requiredV) \
68 && nsMinorVersion(suppliedV) >= nsMinorVersion(requiredV))
71 #define NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION TEXT("MozillaPluginWindowPropertyAssociation")
72 #define NS_PLUGIN_CUSTOM_MSG_ID TEXT("MozFlashUserRelay")
73 #define WM_USER_FLASH WM_USER+1
74 static UINT sWM_FLASHBOUNCEMSG
= 0;
76 typedef nsTWeakRef
<class nsPluginNativeWindowWin
> PluginWindowWeakRef
;
79 * PLEvent handling code
81 class PluginWindowEvent
: public nsRunnable
{
84 void Init(const PluginWindowWeakRef
&ref
, HWND hWnd
, UINT msg
, WPARAM wParam
,
87 HWND
GetWnd() { return mWnd
; };
88 UINT
GetMsg() { return mMsg
; };
89 WPARAM
GetWParam() { return mWParam
; };
90 LPARAM
GetLParam() { return mLParam
; };
91 PRBool
InUse() { return (mWnd
!=NULL
); };
96 PluginWindowWeakRef mPluginWindowRef
;
103 PluginWindowEvent::PluginWindowEvent()
108 void PluginWindowEvent::Clear()
116 void PluginWindowEvent::Init(const PluginWindowWeakRef
&ref
, HWND aWnd
,
117 UINT aMsg
, WPARAM aWParam
, LPARAM aLParam
)
119 NS_ASSERTION(aWnd
!= NULL
, "invalid plugin event value");
120 NS_ASSERTION(mWnd
== NULL
, "event already in use");
121 mPluginWindowRef
= ref
;
129 * nsPluginNativeWindow Windows specific class declaration
133 nsPluginType_Unknown
= 0,
140 class nsPluginNativeWindowWin
: public nsPluginNativeWindow
{
142 nsPluginNativeWindowWin();
143 virtual ~nsPluginNativeWindowWin();
145 virtual nsresult
CallSetWindow(nsCOMPtr
<nsIPluginInstance
> &aPluginInstance
);
149 nsresult
SubclassAndAssociateWindow();
150 nsresult
UndoSubclassAndAssociateWindow();
155 WNDPROC
GetPrevWindowProc();
156 void SetPrevWindowProc(WNDPROC proc
) { mPluginWinProc
= proc
; }
157 WNDPROC
GetWindowProc();
158 PluginWindowEvent
* GetPluginWindowEvent(HWND aWnd
,
164 WNDPROC mPluginWinProc
;
165 WNDPROC mPrevWinProc
;
166 PluginWindowWeakRef mWeakRef
;
167 nsRefPtr
<PluginWindowEvent
> mCachedPluginWindowEvent
;
170 LONG_PTR mParentProc
;
172 nsPluginType mPluginType
;
175 static PRBool sInMessageDispatch
= PR_FALSE
;
176 static PRBool sInPreviousMessageDispatch
= PR_FALSE
;
177 static UINT sLastMsg
= 0;
179 static PRBool
ProcessFlashMessageDelayed(nsPluginNativeWindowWin
* aWin
, nsIPluginInstance
* aInst
,
180 HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
182 NS_ENSURE_TRUE(aWin
, NS_ERROR_NULL_POINTER
);
183 NS_ENSURE_TRUE(aInst
, NS_ERROR_NULL_POINTER
);
185 if (msg
== sWM_FLASHBOUNCEMSG
) {
186 // See PluginWindowEvent::Run() below.
187 NS_ASSERTION((sWM_FLASHBOUNCEMSG
!= 0), "RegisterWindowMessage failed in flash plugin WM_USER message handling!");
188 NS_TRY_SAFE_CALL_VOID(::CallWindowProc((WNDPROC
)aWin
->GetWindowProc(), hWnd
, WM_USER_FLASH
, wParam
, lParam
),
193 if (msg
!= WM_USER_FLASH
)
194 return PR_FALSE
; // no need to delay
197 nsCOMPtr
<nsIRunnable
> pwe
= aWin
->GetPluginWindowEvent(hWnd
, msg
, wParam
, lParam
);
199 NS_DispatchToCurrentThread(pwe
);
205 class nsDelayedPopupsEnabledEvent
: public nsRunnable
208 nsDelayedPopupsEnabledEvent(nsIPluginInstance
*inst
)
215 nsCOMPtr
<nsIPluginInstance
> mInst
;
218 NS_IMETHODIMP
nsDelayedPopupsEnabledEvent::Run()
220 mInst
->PushPopupsEnabledState(PR_FALSE
);
225 * New plugin window procedure
227 static LRESULT CALLBACK
PluginWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
229 nsPluginNativeWindowWin
* win
= (nsPluginNativeWindowWin
*)::GetProp(hWnd
, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION
);
233 // The DispatchEvent(NS_PLUGIN_ACTIVATE) below can trigger a reentrant focus
234 // event which might destroy us. Hold a strong ref on the plugin instance
235 // to prevent that, bug 374229.
236 nsCOMPtr
<nsIPluginInstance
> inst
;
237 win
->GetPluginInstance(inst
);
239 // Real may go into a state where it recursivly dispatches the same event
240 // when subclassed. If this is Real, lets examine the event and drop it
241 // on the floor if we get into this recursive situation. See bug 192914.
242 if (win
->mPluginType
== nsPluginType_Real
) {
243 if (sInMessageDispatch
&& msg
== sLastMsg
)
245 // Cache the last message sent
249 PRBool enablePopups
= PR_FALSE
;
251 // Activate/deactivate mouse capture on the plugin widget
252 // here, before we pass the Windows event to the plugin
253 // because its possible our widget won't get paired events
254 // (see bug 131007) and we'll look frozen. Note that this
255 // is also done in ChildWindow::DispatchMouseEvent.
259 case WM_RBUTTONDOWN
: {
260 nsCOMPtr
<nsIWidget
> widget
;
261 win
->GetPluginWidget(getter_AddRefs(widget
));
263 widget
->CaptureMouse(PR_TRUE
);
267 enablePopups
= PR_TRUE
;
272 nsCOMPtr
<nsIWidget
> widget
;
273 win
->GetPluginWidget(getter_AddRefs(widget
));
275 widget
->CaptureMouse(PR_FALSE
);
279 // Ignore repeating keydown messages...
280 if ((lParam
& 0x40000000) != 0) {
286 enablePopups
= PR_TRUE
;
291 case WM_MOUSEACTIVATE
: {
292 // If a child window of this plug-in is already focused,
293 // don't focus the parent to avoid focus dance. We'll
294 // receive a follow up WM_SETFOCUS which will notify
295 // the appropriate window anyway.
296 HWND focusedWnd
= ::GetFocus();
297 if (!::IsChild((HWND
)win
->window
, focusedWnd
)) {
298 // Notify the dom / focus manager the plugin has focus when one of
299 // it's child windows receives it. OOPP specific - this code is
300 // critical in notifying the dom of focus changes when the plugin
301 // window in the child process receives focus via a mouse click.
302 // WM_MOUSEACTIVATE is sent by nsWindow via a custom window event
303 // sent from PluginInstanceParent in response to focus events sent
304 // from the child. (bug 540052) Note, this gui event could also be
305 // sent directly from widget.
306 nsCOMPtr
<nsIWidget
> widget
;
307 win
->GetPluginWidget(getter_AddRefs(widget
));
309 nsGUIEvent
event(PR_TRUE
, NS_PLUGIN_ACTIVATE
, widget
);
310 nsEventStatus status
;
311 widget
->DispatchEvent(&event
, status
);
319 // RealPlayer can crash, don't process the message for those,
321 if (win
->mPluginType
== nsPluginType_Real
&& msg
== sLastMsg
)
323 // Make sure setfocus and killfocus get through to the widget procedure
324 // even if they are eaten by the plugin. Also make sure we aren't calling
326 WNDPROC prevWndProc
= win
->GetPrevWindowProc();
327 if (prevWndProc
&& !sInPreviousMessageDispatch
) {
328 sInPreviousMessageDispatch
= PR_TRUE
;
329 ::CallWindowProc(prevWndProc
, hWnd
, msg
, wParam
, lParam
);
330 sInPreviousMessageDispatch
= PR_FALSE
;
337 // Macromedia Flash plugin may flood the message queue with some special messages
338 // (WM_USER+1) causing 100% CPU consumption and GUI freeze, see mozilla bug 132759;
339 // we can prevent this from happening by delaying the processing such messages;
340 if (win
->mPluginType
== nsPluginType_Flash
) {
341 if (ProcessFlashMessageDelayed(win
, inst
, hWnd
, msg
, wParam
, lParam
))
345 if (enablePopups
&& inst
) {
347 if (NS_SUCCEEDED(inst
->GetPluginAPIVersion(&apiVersion
)) &&
348 !versionOK(apiVersion
, NP_POPUP_API_VERSION
)) {
349 inst
->PushPopupsEnabledState(PR_TRUE
);
353 sInMessageDispatch
= PR_TRUE
;
356 NS_TRY_SAFE_CALL_RETURN(res
,
357 ::CallWindowProc((WNDPROC
)win
->GetWindowProc(), hWnd
, msg
, wParam
, lParam
),
360 sInMessageDispatch
= PR_FALSE
;
363 // Popups are enabled (were enabled before the call to
364 // CallWindowProc()). Some plugins (at least the flash player)
365 // post messages from their key handlers etc that delay the actual
366 // processing, so we need to delay the disabling of popups so that
367 // popups remain enabled when the flash player ends up processing
368 // the actual key handlers. We do this by posting an event that
369 // does the disabling, this way our disabling will happen after
370 // the handlers in the plugin are done.
372 // Note that it's not fatal if any of this fails (which won't
373 // happen unless we're out of memory anyways) since the plugin
374 // code will pop any popup state pushed by this plugin on
377 nsCOMPtr
<nsIRunnable
> event
= new nsDelayedPopupsEnabledEvent(inst
);
379 NS_DispatchToCurrentThread(event
);
386 * Flash will reset the subclass of our widget at various times.
387 * (Notably when entering and exiting full screen mode.) This
388 * occurs independent of the main plugin window event procedure.
389 * We trap these subclass calls to prevent our subclass hook from
391 * Note, ascii versions can be nixed once flash versions < 10.1
392 * are considered obsolete.
394 static WindowsDllInterceptor sUser32Intercept
;
398 (WINAPI
*User32SetWindowLongPtrA
)(HWND hWnd
,
402 (WINAPI
*User32SetWindowLongPtrW
)(HWND hWnd
,
405 static User32SetWindowLongPtrA sUser32SetWindowLongAHookStub
= NULL
;
406 static User32SetWindowLongPtrW sUser32SetWindowLongWHookStub
= NULL
;
409 (WINAPI
*User32SetWindowLongA
)(HWND hWnd
,
413 (WINAPI
*User32SetWindowLongW
)(HWND hWnd
,
416 static User32SetWindowLongA sUser32SetWindowLongAHookStub
= NULL
;
417 static User32SetWindowLongW sUser32SetWindowLongWHookStub
= NULL
;
420 SetWindowLongHookCheck(HWND hWnd
,
424 nsPluginNativeWindowWin
* win
=
425 (nsPluginNativeWindowWin
*)GetProp(hWnd
, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION
);
426 if (!win
|| (win
&& win
->mPluginType
!= nsPluginType_Flash
) ||
427 (nIndex
== GWLP_WNDPROC
&&
428 newLong
== reinterpret_cast<LONG_PTR
>(PluginWndProc
)))
435 SetWindowLongPtrAHook(HWND hWnd
,
440 SetWindowLongAHook(HWND hWnd
,
445 if (SetWindowLongHookCheck(hWnd
, nIndex
, newLong
))
446 return sUser32SetWindowLongAHookStub(hWnd
, nIndex
, newLong
);
448 // Set flash's new subclass to get the result.
449 LONG_PTR proc
= sUser32SetWindowLongAHookStub(hWnd
, nIndex
, newLong
);
451 // We already checked this in SetWindowLongHookCheck
452 nsPluginNativeWindowWin
* win
=
453 (nsPluginNativeWindowWin
*)GetProp(hWnd
, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION
);
455 // Hook our subclass back up, just like we do on setwindow.
456 win
->SetPrevWindowProc(
457 reinterpret_cast<WNDPROC
>(sUser32SetWindowLongAHookStub(hWnd
, nIndex
,
458 reinterpret_cast<LONG_PTR
>(PluginWndProc
))));
464 SetWindowLongPtrWHook(HWND hWnd
,
469 SetWindowLongWHook(HWND hWnd
,
474 if (SetWindowLongHookCheck(hWnd
, nIndex
, newLong
))
475 return sUser32SetWindowLongWHookStub(hWnd
, nIndex
, newLong
);
477 // Set flash's new subclass to get the result.
478 LONG_PTR proc
= sUser32SetWindowLongWHookStub(hWnd
, nIndex
, newLong
);
480 // We already checked this in SetWindowLongHookCheck
481 nsPluginNativeWindowWin
* win
=
482 (nsPluginNativeWindowWin
*)GetProp(hWnd
, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION
);
484 // Hook our subclass back up, just like we do on setwindow.
485 win
->SetPrevWindowProc(
486 reinterpret_cast<WNDPROC
>(sUser32SetWindowLongWHookStub(hWnd
, nIndex
,
487 reinterpret_cast<LONG_PTR
>(PluginWndProc
))));
492 HookSetWindowLongPtr()
495 // XXX WindowsDllInterceptor doesn't support hooks
496 // in 64-bit builds, disabling this code for now.
500 sUser32Intercept
.Init("user32.dll");
502 sUser32Intercept
.AddHook("SetWindowLongPtrA", SetWindowLongPtrAHook
,
503 (void**) &sUser32SetWindowLongAHookStub
);
504 sUser32Intercept
.AddHook("SetWindowLongPtrW", SetWindowLongPtrWHook
,
505 (void**) &sUser32SetWindowLongWHookStub
);
507 sUser32Intercept
.AddHook("SetWindowLongA", SetWindowLongAHook
,
508 (void**) &sUser32SetWindowLongAHookStub
);
509 sUser32Intercept
.AddHook("SetWindowLongW", SetWindowLongWHook
,
510 (void**) &sUser32SetWindowLongWHookStub
);
515 * nsPluginNativeWindowWin implementation
517 nsPluginNativeWindowWin::nsPluginNativeWindowWin() : nsPluginNativeWindow()
519 // initialize the struct fields
527 mPluginWinProc
= NULL
;
528 mPluginType
= nsPluginType_Unknown
;
533 if (!sWM_FLASHBOUNCEMSG
) {
534 sWM_FLASHBOUNCEMSG
= ::RegisterWindowMessage(NS_PLUGIN_CUSTOM_MSG_ID
);
538 nsPluginNativeWindowWin::~nsPluginNativeWindowWin()
540 // clear weak reference to self to prevent any pending events from
541 // dereferencing this.
545 WNDPROC
nsPluginNativeWindowWin::GetPrevWindowProc()
550 WNDPROC
nsPluginNativeWindowWin::GetWindowProc()
552 return mPluginWinProc
;
555 NS_IMETHODIMP
PluginWindowEvent::Run()
557 nsPluginNativeWindowWin
*win
= mPluginWindowRef
.get();
561 HWND hWnd
= GetWnd();
565 nsCOMPtr
<nsIPluginInstance
> inst
;
566 win
->GetPluginInstance(inst
);
568 if (GetMsg() == WM_USER_FLASH
) {
569 // XXX Unwind issues related to runnable event callback depth for this
570 // event and destruction of the plugin. (Bug 493601)
571 ::PostMessage(hWnd
, sWM_FLASHBOUNCEMSG
, GetWParam(), GetLParam());
574 // Currently not used, but added so that processing events here
576 NS_TRY_SAFE_CALL_VOID(::CallWindowProc(win
->GetWindowProc(),
589 nsPluginNativeWindowWin::GetPluginWindowEvent(HWND aWnd
, UINT aMsg
, WPARAM aWParam
, LPARAM aLParam
)
597 PluginWindowEvent
*event
;
599 // We have the ability to alloc if needed in case in the future some plugin
600 // should post multiple PostMessages. However, this could lead to many
601 // alloc's per second which could become a performance issue. See bug 169247.
602 if (!mCachedPluginWindowEvent
)
604 event
= new PluginWindowEvent();
605 if (!event
) return nsnull
;
606 mCachedPluginWindowEvent
= event
;
608 else if (mCachedPluginWindowEvent
->InUse())
610 event
= new PluginWindowEvent();
611 if (!event
) return nsnull
;
615 event
= mCachedPluginWindowEvent
;
618 event
->Init(mWeakRef
, aWnd
, aMsg
, aWParam
, aLParam
);
622 nsresult
nsPluginNativeWindowWin::CallSetWindow(nsCOMPtr
<nsIPluginInstance
> &aPluginInstance
)
624 // Note, 'window' can be null
626 // check the incoming instance, null indicates that window is going away and we are
627 // not interested in subclassing business any more, undo and don't subclass
628 if (!aPluginInstance
) {
629 UndoSubclassAndAssociateWindow();
630 nsPluginNativeWindow::CallSetWindow(aPluginInstance
);
634 // check plugin mime type and cache it if it will need special treatment later
635 if (mPluginType
== nsPluginType_Unknown
) {
636 const char* mimetype
= nsnull
;
637 aPluginInstance
->GetMIMEType(&mimetype
);
639 if (!strcmp(mimetype
, "application/x-shockwave-flash"))
640 mPluginType
= nsPluginType_Flash
;
641 else if (!strcmp(mimetype
, "audio/x-pn-realaudio-plugin"))
642 mPluginType
= nsPluginType_Real
;
643 else if (!strcmp(mimetype
, "application/pdf"))
644 mPluginType
= nsPluginType_PDF
;
646 mPluginType
= nsPluginType_Other
;
650 // WINCE does not subclass windows. See bug 300011 for the details.
653 // grab the widget procedure before the plug-in does a subclass in
654 // setwindow. We'll use this in PluginWndProc for forwarding focus
655 // events to the widget.
656 WNDPROC currentWndProc
=
657 (WNDPROC
)::GetWindowLongPtr((HWND
)window
, GWLP_WNDPROC
);
658 if (!mPrevWinProc
&& currentWndProc
!= PluginWndProc
)
659 mPrevWinProc
= currentWndProc
;
661 // PDF plugin v7.0.9, v8.1.3, and v9.0 subclass parent window, bug 531551
662 // V8.2.2 and V9.1 don't have such problem.
663 if (mPluginType
== nsPluginType_PDF
) {
664 HWND parent
= ::GetParent((HWND
)window
);
665 if (mParentWnd
!= parent
) {
666 NS_ASSERTION(!mParentWnd
, "Plugin's parent window changed");
668 mParentProc
= ::GetWindowLongPtr(mParentWnd
, GWLP_WNDPROC
);
674 nsPluginNativeWindow::CallSetWindow(aPluginInstance
);
677 SubclassAndAssociateWindow();
679 if (window
&& mPluginType
== nsPluginType_Flash
&&
680 !GetPropW((HWND
)window
, L
"PluginInstanceParentProperty")) {
681 HookSetWindowLongPtr();
690 nsresult
nsPluginNativeWindowWin::SubclassAndAssociateWindow()
692 if (type
!= NPWindowTypeWindow
|| !window
)
693 return NS_ERROR_FAILURE
;
695 HWND hWnd
= (HWND
)window
;
697 // check if we need to subclass
698 WNDPROC currentWndProc
= (WNDPROC
)::GetWindowLongPtr(hWnd
, GWLP_WNDPROC
);
699 if (currentWndProc
== PluginWndProc
)
702 // If the plugin reset the subclass, set it back.
703 if (mPluginWinProc
) {
705 NS_WARNING("A plugin cleared our subclass - resetting.");
706 if (currentWndProc
!= mPluginWinProc
) {
707 NS_WARNING("Procedures do not match up, discarding old subclass value.");
709 if (mPrevWinProc
&& currentWndProc
== mPrevWinProc
) {
710 NS_WARNING("The new procedure is our widget procedure?");
713 SetWindowLongPtr(hWnd
, GWLP_WNDPROC
, (LONG_PTR
)PluginWndProc
);
717 LONG_PTR style
= GetWindowLongPtr(hWnd
, GWL_STYLE
);
719 // Out of process plugins must not have the WS_CLIPCHILDREN style set on their
720 // parent windows or else synchronous paints (via UpdateWindow() and others)
721 // will cause deadlocks.
722 if (::GetPropW(hWnd
, L
"PluginInstanceParentProperty"))
723 style
&= ~WS_CLIPCHILDREN
;
725 style
|= WS_CLIPCHILDREN
;
727 style
|= WS_CLIPCHILDREN
;
729 SetWindowLongPtr(hWnd
, GWL_STYLE
, style
);
731 mPluginWinProc
= (WNDPROC
)SetWindowLongPtr(hWnd
, GWLP_WNDPROC
, (LONG_PTR
)PluginWndProc
);
733 return NS_ERROR_FAILURE
;
735 nsPluginNativeWindowWin
* win
= (nsPluginNativeWindowWin
*)::GetProp(hWnd
, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION
);
736 NS_ASSERTION(!win
|| (win
== this), "plugin window already has property and this is not us");
738 if (!::SetProp(hWnd
, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION
, (HANDLE
)this))
739 return NS_ERROR_FAILURE
;
744 nsresult
nsPluginNativeWindowWin::UndoSubclassAndAssociateWindow()
746 // release plugin instance
747 SetPluginInstance(nsnull
);
749 // remove window property
750 HWND hWnd
= (HWND
)window
;
752 ::RemoveProp(hWnd
, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION
);
754 // restore the original win proc
755 // but only do this if this were us last time
756 if (mPluginWinProc
) {
757 WNDPROC currentWndProc
= (WNDPROC
)::GetWindowLongPtr(hWnd
, GWLP_WNDPROC
);
758 if (currentWndProc
== PluginWndProc
)
759 SetWindowLongPtr(hWnd
, GWLP_WNDPROC
, (LONG_PTR
)mPluginWinProc
);
760 mPluginWinProc
= NULL
;
762 LONG_PTR style
= GetWindowLongPtr(hWnd
, GWL_STYLE
);
763 style
&= ~WS_CLIPCHILDREN
;
764 SetWindowLongPtr(hWnd
, GWL_STYLE
, style
);
767 if (mPluginType
== nsPluginType_PDF
&& mParentWnd
) {
768 ::SetWindowLongPtr(mParentWnd
, GWLP_WNDPROC
, mParentProc
);
777 nsresult
PLUG_NewPluginNativeWindow(nsPluginNativeWindow
** aPluginNativeWindow
)
779 NS_ENSURE_ARG_POINTER(aPluginNativeWindow
);
781 *aPluginNativeWindow
= new nsPluginNativeWindowWin();
783 return *aPluginNativeWindow
? NS_OK
: NS_ERROR_OUT_OF_MEMORY
;
786 nsresult
PLUG_DeletePluginNativeWindow(nsPluginNativeWindow
* aPluginNativeWindow
)
788 NS_ENSURE_ARG_POINTER(aPluginNativeWindow
);
789 nsPluginNativeWindowWin
*p
= (nsPluginNativeWindowWin
*)aPluginNativeWindow
;