зеркало из https://github.com/mozilla/pjs.git
r=mkaply, a=brendan More fixups to widget - better menu code Use Window Properties instead of PresParams Rework subclass stuff to be more like Win
This commit is contained in:
Родитель
88f5805353
Коммит
a3333b4414
|
@ -0,0 +1,4 @@
|
|||
IMPORTS
|
||||
WinQueryProperty = PMMERGE.5450
|
||||
WinRemoveProperty = PMMERGE.5451
|
||||
WinSetProperty = PMMERGE.5452
|
|
@ -53,8 +53,6 @@
|
|||
#define KBD_CTRL KBD_CONTROL
|
||||
#endif
|
||||
|
||||
#define WARPZILLA_PRESPARAM "PP_WARPZILLA"
|
||||
|
||||
static void GetKeyboardName( char *buff);
|
||||
|
||||
nsWidgetModuleData::nsWidgetModuleData()
|
||||
|
@ -98,8 +96,6 @@ void nsWidgetModuleData::Init( nsIAppShell *aPrimaevalAppShell)
|
|||
DosQueryDBCSEnv( CCHMAXPATH, &cc, buffer);
|
||||
bIsDBCS = buffer[0] || buffer[1];
|
||||
|
||||
ppMozilla = GetAtom( WARPZILLA_PRESPARAM);
|
||||
|
||||
fontService = nsnull;
|
||||
|
||||
// XXXX KNOCKED OUT UNTIL nsDragService.cpp builds again
|
||||
|
|
|
@ -52,7 +52,6 @@ class nsWidgetModuleData
|
|||
LONG lHtEntryfield; // ideal height of an entryfield
|
||||
char *pszFontNameSize; // fns for default widget font
|
||||
BOOL bIsDBCS; // true if system is dbcs
|
||||
ULONG ppMozilla; // pres-param for hwnd <-> nsWindow*
|
||||
|
||||
// xptoolkit services we look after, & the primaeval appshell too.
|
||||
nsIFontRetrieverService *fontService;
|
||||
|
|
|
@ -107,18 +107,6 @@ nsIRollupListener * gRollupListener = nsnull;
|
|||
nsIWidget * gRollupWidget = nsnull;
|
||||
PRBool gRollupConsumeRollupEvent = PR_FALSE;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// HWND -> (nsWindow *) conversion ------------------------------------------
|
||||
|
||||
nsWindow *NS_HWNDToWindow( HWND hwnd)
|
||||
{
|
||||
nsWindow *pWnd = nsnull;
|
||||
|
||||
WinQueryPresParam( hwnd, gModuleData.ppMozilla, 0, NULL,
|
||||
sizeof pWnd, &pWnd, QPF_NOINHERIT);
|
||||
return pWnd;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// NSWindow create / destroy ------------------------------------------------
|
||||
|
||||
|
@ -127,7 +115,7 @@ nsWindow::nsWindow() : nsBaseWidget()
|
|||
NS_INIT_REFCNT();
|
||||
|
||||
mWnd = 0;
|
||||
mFnWP = 0;
|
||||
mPrevWndProc = 0;
|
||||
mParent = 0;
|
||||
mNextID = 1;
|
||||
mNextCmdID = 1;
|
||||
|
@ -179,7 +167,7 @@ nsresult nsWindow::Create( nsNativeWidget aParent, const nsRect &aRect,
|
|||
HWND hwndP = (HWND) aParent;
|
||||
|
||||
if( hwndP && hwndP != HWND_DESKTOP)
|
||||
pParent = NS_HWNDToWindow( hwndP);
|
||||
pParent = GetNSWindowPtr(hwndP);
|
||||
|
||||
// XXX WC_MOZILLA will probably need a change here
|
||||
//
|
||||
|
@ -508,6 +496,105 @@ BOOL bothFromSameWindow( HWND hwnd1, HWND hwnd2 )
|
|||
return (hwnd1 == hwnd2);
|
||||
}
|
||||
|
||||
PVOID APIENTRY WinQueryProperty(HWND hwnd, PCSZ pszNameOrAtom);
|
||||
|
||||
PVOID APIENTRY WinRemoveProperty(HWND hwnd, PCSZ pszNameOrAtom);
|
||||
|
||||
BOOL APIENTRY WinSetProperty(HWND hwnd, PCSZ pszNameOrAtom,
|
||||
PVOID pvData, ULONG ulFlags);
|
||||
|
||||
static PCSZ GetNSWindowPropName() {
|
||||
static ATOM atom = 0;
|
||||
|
||||
// this is threadsafe, even without locking;
|
||||
// even if there's a race, GlobalAddAtom("nsWindowPtr")
|
||||
// will just return the same value
|
||||
if (!atom) {
|
||||
atom = WinAddAtom(WinQuerySystemAtomTable(), "nsWindowPtr");
|
||||
}
|
||||
|
||||
return (PCSZ)atom;
|
||||
}
|
||||
|
||||
nsWindow * nsWindow::GetNSWindowPtr(HWND aWnd) {
|
||||
return (nsWindow *) ::WinQueryProperty(aWnd, GetNSWindowPropName());
|
||||
}
|
||||
|
||||
BOOL nsWindow::SetNSWindowPtr(HWND aWnd, nsWindow * ptr) {
|
||||
if (ptr == NULL) {
|
||||
::WinRemoveProperty(aWnd, GetNSWindowPropName());
|
||||
return TRUE;
|
||||
} else {
|
||||
return ::WinSetProperty(aWnd, GetNSWindowPropName(), (PVOID)ptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// DealWithPopups
|
||||
//
|
||||
// Handle events that may cause a popup (combobox, XPMenu, etc) to need to rollup.
|
||||
//
|
||||
BOOL
|
||||
nsWindow :: DealWithPopups ( ULONG inMsg, MRESULT* outResult )
|
||||
{
|
||||
if ( gRollupListener && gRollupWidget) {
|
||||
#ifdef XP_OS2
|
||||
if( inMsg == WM_ACTIVATE || inMsg == WM_BUTTON1DOWN ||
|
||||
inMsg == WM_BUTTON2DOWN || inMsg == WM_BUTTON3DOWN) {
|
||||
#else
|
||||
if (inMsg == WM_ACTIVATE || inMsg == WM_NCLBUTTONDOWN || inMsg == WM_LBUTTONDOWN ||
|
||||
inMsg == WM_RBUTTONDOWN || inMsg == WM_MBUTTONDOWN ||
|
||||
inMsg == WM_NCMBUTTONDOWN || inMsg == WM_NCRBUTTONDOWN || inMsg == WM_MOUSEACTIVATE) {
|
||||
#endif
|
||||
// Rollup if the event is outside the popup.
|
||||
PRBool rollup = !nsWindow::EventIsInsideWindow((nsWindow*)gRollupWidget);
|
||||
|
||||
// If we're dealing with menus, we probably have submenus and we don't
|
||||
// want to rollup if the click is in a parent menu of the current submenu.
|
||||
if (rollup) {
|
||||
nsCOMPtr<nsIMenuRollup> menuRollup ( do_QueryInterface(gRollupListener) );
|
||||
if ( menuRollup ) {
|
||||
nsCOMPtr<nsISupportsArray> widgetChain;
|
||||
menuRollup->GetSubmenuWidgetChain ( getter_AddRefs(widgetChain) );
|
||||
if ( widgetChain ) {
|
||||
PRUint32 count = 0;
|
||||
widgetChain->Count(&count);
|
||||
for ( PRUint32 i = 0; i < count; ++i ) {
|
||||
nsCOMPtr<nsISupports> genericWidget;
|
||||
widgetChain->GetElementAt ( i, getter_AddRefs(genericWidget) );
|
||||
nsCOMPtr<nsIWidget> widget ( do_QueryInterface(genericWidget) );
|
||||
if ( widget ) {
|
||||
nsIWidget* temp = widget.get();
|
||||
if ( nsWindow::EventIsInsideWindow((nsWindow*)temp) ) {
|
||||
rollup = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // foreach parent menu widget
|
||||
}
|
||||
} // if rollup listener knows about menus
|
||||
}
|
||||
|
||||
// if we've determined that we should still rollup everything, do it.
|
||||
if ( rollup ) {
|
||||
gRollupListener->Rollup();
|
||||
|
||||
// return TRUE tells Windows that the event is consumed,
|
||||
// false allows the event to be dispatched
|
||||
//
|
||||
// So if we are NOT supposed to be consuming events, let it go through
|
||||
if (gRollupConsumeRollupEvent) {
|
||||
*outResult = (MRESULT)TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
} // if event that might trigger a popup to rollup
|
||||
} // if rollup listeners registered
|
||||
|
||||
return FALSE;
|
||||
|
||||
} // DealWithPopups
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// PM messaging layer - wndproc, subclasser, default handler ----------------
|
||||
|
||||
|
@ -520,7 +607,7 @@ MRESULT EXPENTRY fnwpNSWindow( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
|||
#endif
|
||||
|
||||
// Get the nsWindow for this hwnd
|
||||
nsWindow *wnd = NS_HWNDToWindow( hwnd);
|
||||
nsWindow *wnd = nsWindow::GetNSWindowPtr(hwnd);
|
||||
|
||||
// check to see if we have a rollup listener registered
|
||||
if( nsnull != gRollupListener && nsnull != gRollupWidget) {
|
||||
|
@ -577,7 +664,7 @@ MRESULT EXPENTRY fnwpNSWindow( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
|||
HWND hwndChild = WinWindowFromID( hwnd, SHORT1FROMMP( mp1));
|
||||
if( hwndChild)
|
||||
{
|
||||
nsWindow *w = NS_HWNDToWindow( hwndChild);
|
||||
nsWindow *w = nsWindow::GetNSWindowPtr(hwndChild);
|
||||
if( w)
|
||||
wnd = w;
|
||||
}
|
||||
|
@ -605,24 +692,29 @@ MRESULT EXPENTRY fnwpNSWindow( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
|
|||
return mRC;
|
||||
}
|
||||
|
||||
// Subclass (or remove the subclass)
|
||||
void nsWindow::SubclassWindow( PRBool bState)
|
||||
// -----------------------------------------------------------------------
|
||||
//
|
||||
// Subclass (or remove the subclass from) this component's nsWindow
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
void nsWindow::SubclassWindow(BOOL bState)
|
||||
{
|
||||
NS_PRECONDITION(WinIsWindow( 0/*hab*/, mWnd), "Invalid window handle");
|
||||
if (NULL != mWnd) {
|
||||
NS_PRECONDITION(::WinIsWindow(0, mWnd), "Invalid window handle");
|
||||
|
||||
if( PR_TRUE == bState)
|
||||
{
|
||||
mFnWP = WinSubclassWindow( mWnd, fnwpNSWindow);
|
||||
// connect the this pointer to the window handle
|
||||
nsWindow *pWin = this; // learn something new about C++ every day...
|
||||
WinSetPresParam( mWnd, gModuleData.ppMozilla, sizeof pWin, &pWin);
|
||||
}
|
||||
else
|
||||
{
|
||||
WinSubclassWindow( mWnd, mFnWP);
|
||||
WinRemovePresParam( mWnd, gModuleData.ppMozilla);
|
||||
mFnWP = nsnull;
|
||||
}
|
||||
if (bState) {
|
||||
// change the nsWindow proc
|
||||
mPrevWndProc = WinSubclassWindow(mWnd, fnwpNSWindow);
|
||||
NS_ASSERTION(mPrevWndProc, "Null standard window procedure");
|
||||
// connect the this pointer to the nsWindow handle
|
||||
SetNSWindowPtr(mWnd, this);
|
||||
}
|
||||
else {
|
||||
WinSubclassWindow(mWnd, mPrevWndProc);
|
||||
SetNSWindowPtr(mWnd, NULL);
|
||||
mPrevWndProc = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 'Window procedure'
|
||||
|
|
|
@ -159,9 +159,15 @@ class nsWindow : public nsBaseWidget,
|
|||
void NS2PM( RECTL &rcl);
|
||||
// void SetContextMenu( nsContextMenu *aMenu);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
static BOOL DealWithPopups ( ULONG inMsg, MRESULT* outResult ) ;
|
||||
|
||||
static PRBool EventIsInsideWindow(nsWindow* aWindow);
|
||||
|
||||
static nsWindow * GetNSWindowPtr(HWND aWnd);
|
||||
static BOOL SetNSWindowPtr(HWND aWnd, nsWindow * ptr);
|
||||
|
||||
static nsWindow* gCurrentWindow;
|
||||
static PRBool EventIsInsideWindow(nsWindow* aWindow);
|
||||
// nsWindow methods subclasses must provide for creation to work
|
||||
virtual PCSZ WindowClass() = 0;
|
||||
virtual ULONG WindowStyle() = 0;
|
||||
|
@ -209,7 +215,7 @@ class nsWindow : public nsBaseWidget,
|
|||
|
||||
// PM data members
|
||||
HWND mWnd; // window handle
|
||||
PFNWP mFnWP; // previous window procedure
|
||||
PFNWP mPrevWndProc; // previous window procedure
|
||||
nsWindow *mParent; // parent widget
|
||||
ULONG mNextID; // next child window id
|
||||
USHORT mNextCmdID; // next WM_COMMAND id for menus
|
||||
|
@ -226,7 +232,7 @@ class nsWindow : public nsBaseWidget,
|
|||
|
||||
HWND GetParentHWND() const;
|
||||
HWND GetHWND() const { return mWnd; }
|
||||
PFNWP GetPrevWP() const { return mFnWP; }
|
||||
PFNWP GetPrevWP() const { return mPrevWndProc; }
|
||||
|
||||
// nglayout data members
|
||||
PRInt32 mPreferredHeight;
|
||||
|
@ -260,7 +266,7 @@ class nsWindow : public nsBaseWidget,
|
|||
nsWidgetInitData *aInitData,
|
||||
HWND hwndOwner = 0);
|
||||
|
||||
virtual void SubclassWindow( PRBool bState);
|
||||
virtual void SubclassWindow(BOOL bState);
|
||||
|
||||
PRBool ConvertStatus( nsEventStatus aStatus);
|
||||
void InitEvent( nsGUIEvent &event, PRUint32 aEventType, nsPoint *pt = 0);
|
||||
|
|
Загрузка…
Ссылка в новой задаче