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:
mkaply%us.ibm.com 2000-09-01 01:00:46 +00:00
Родитель 88f5805353
Коммит a3333b4414
5 изменённых файлов: 139 добавлений и 42 удалений

Просмотреть файл

@ -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);