reviewing native widgets from build

r kmcclusk, bug 17029 (windows only)
This commit is contained in:
rods%netscape.com 2000-01-31 22:53:35 +00:00
parent 2440cb6a46
commit 9741e0faee
4 changed files with 31 additions and 846 deletions

View File

@ -21,268 +21,121 @@
*/
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsdefs.h"
#include "nsWidgetsCID.h"
#include "nsButton.h"
#include "nsCheckButton.h"
#include "nsComboBox.h"
#include "nsFileWidget.h"
#include "nsFileSpecWithUIImpl.h"
#include "nsListBox.h"
#include "nsLookAndFeel.h"
#include "nsRadioButton.h"
#include "nsScrollbar.h"
#include "nsTextAreaWidget.h"
#include "nsTextHelper.h"
#include "nsTextWidget.h"
#include "nsToolkit.h"
#include "nsWindow.h"
#include "nsLabel.h"
#include "nsMenuBar.h"
#include "nsMenu.h"
#include "nsMenuItem.h"
#include "nsContextMenu.h"
#include "nsPopUpMenu.h"
#include "nsAppShell.h"
#include "nsIServiceManager.h"
#include "nsFontRetrieverService.h"
#include "nsSound.h"
#include "nsWindowsTimer.h"
#include "nsTimerManager.h"
// Drag & Drop, Clipboard
#include "nsClipboard.h"
#include "nsTransferable.h"
#include "nsXIFFormatConverter.h"
#include "nsDragService.h"
static NS_DEFINE_IID(kCWindow, NS_WINDOW_CID);
static NS_DEFINE_IID(kCChild, NS_CHILD_CID);
static NS_DEFINE_IID(kCButton, NS_BUTTON_CID);
static NS_DEFINE_IID(kCCheckButton, NS_CHECKBUTTON_CID);
static NS_DEFINE_IID(kCCombobox, NS_COMBOBOX_CID);
static NS_DEFINE_IID(kCFileOpen, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kCListbox, NS_LISTBOX_CID);
static NS_DEFINE_IID(kCRadioButton, NS_RADIOBUTTON_CID);
static NS_DEFINE_IID(kCHorzScrollbar, NS_HORZSCROLLBAR_CID);
static NS_DEFINE_IID(kCVertScrollbar, NS_VERTSCROLLBAR_CID);
static NS_DEFINE_IID(kCTextArea, NS_TEXTAREA_CID);
static NS_DEFINE_IID(kCTextField, NS_TEXTFIELD_CID);
static NS_DEFINE_IID(kCAppShell, NS_APPSHELL_CID);
static NS_DEFINE_IID(kCToolkit, NS_TOOLKIT_CID);
static NS_DEFINE_IID(kCLookAndFeel, NS_LOOKANDFEEL_CID);
static NS_DEFINE_IID(kCLabel, NS_LABEL_CID);
static NS_DEFINE_IID(kCMenuBar, NS_MENUBAR_CID);
static NS_DEFINE_IID(kCMenu, NS_MENU_CID);
static NS_DEFINE_IID(kCMenuItem, NS_MENUITEM_CID);
static NS_DEFINE_IID(kCContextMenu, NS_CONTEXTMENU_CID);
static NS_DEFINE_IID(kCPopUpMenu, NS_POPUPMENU_CID);
static NS_DEFINE_IID(kCFontRetrieverService, NS_FONTRETRIEVERSERVICE_CID);
static NS_DEFINE_IID(kCTimer, NS_TIMER_CID);
static NS_DEFINE_IID(kCTimerManager, NS_TIMERMANAGER_CID);
// Drag & Drop, Clipboard
static NS_DEFINE_IID(kCDataObj, NS_DATAOBJ_CID);
static NS_DEFINE_IID(kCClipboard, NS_CLIPBOARD_CID);
static NS_DEFINE_IID(kCTransferable, NS_TRANSFERABLE_CID);
static NS_DEFINE_IID(kCXIFFormatConverter, NS_XIFFORMATCONVERTER_CID);
static NS_DEFINE_IID(kCDragService, NS_DRAGSERVICE_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
// Sound services (just Beep for now)
static NS_DEFINE_CID(kCSound, NS_SOUND_CID);
static NS_DEFINE_CID(kCFileSpecWithUI, NS_FILESPECWITHUI_CID);
class nsWidgetFactory : public nsIFactory
{
public:
// nsISupports methods
NS_DECL_ISUPPORTS
// nsIFactory methods
NS_IMETHOD CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
nsWidgetFactory(const nsCID &aClass);
~nsWidgetFactory();
private:
nsCID mClassID;
};
NS_IMPL_ADDREF(nsWidgetFactory)
NS_IMPL_RELEASE(nsWidgetFactory)
nsWidgetFactory::nsWidgetFactory(const nsCID &aClass)
{
NS_INIT_REFCNT();
mClassID = aClass;
}
nsWidgetFactory::~nsWidgetFactory()
{
}
nsresult nsWidgetFactory::QueryInterface(const nsIID &aIID,
void **aResult)
{
if (aResult == NULL) {
return NS_ERROR_NULL_POINTER;
return NS_ERROR_NULL_POINTER;
}
// Always NULL result, in case of failure
*aResult = NULL;
if (aIID.Equals(kISupportsIID)) {
*aResult = (void *)(nsISupports*)this;
*aResult = (void *)(nsISupports*)this;
} else if (aIID.Equals(kIFactoryIID)) {
*aResult = (void *)(nsIFactory*)this;
*aResult = (void *)(nsIFactory*)this;
}
if (*aResult == NULL) {
return NS_NOINTERFACE;
return NS_NOINTERFACE;
}
NS_ADDREF_THIS(); // Increase reference count for caller
return NS_OK;
}
@ -290,286 +143,116 @@ nsresult nsWidgetFactory::QueryInterface(const nsIID &aIID,
nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter,
const nsIID &aIID,
void **aResult)
{
if (aResult == NULL) {
return NS_ERROR_NULL_POINTER;
return NS_ERROR_NULL_POINTER;
}
*aResult = NULL;
if (nsnull != aOuter) {
return NS_ERROR_NO_AGGREGATION;
return NS_ERROR_NO_AGGREGATION;
}
nsISupports *inst = nsnull;
if (mClassID.Equals(kCWindow)) {
inst = (nsISupports*)(nsBaseWidget*)new nsWindow();
}
else if (mClassID.Equals(kCChild)) {
inst = (nsISupports*)(nsBaseWidget*)new ChildWindow();
}
else if (mClassID.Equals(kCButton)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsButton();
}
else if (mClassID.Equals(kCCheckButton)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsCheckButton();
}
else if (mClassID.Equals(kCCombobox)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsComboBox();
}
else if (mClassID.Equals(kCRadioButton)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsRadioButton();
}
else if (mClassID.Equals(kCFileOpen)) {
inst = (nsISupports*)new nsFileWidget();
}
else if (mClassID.Equals(kCListbox)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsListBox();
}
else if (mClassID.Equals(kCHorzScrollbar)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsScrollbar(PR_FALSE);
}
else if (mClassID.Equals(kCVertScrollbar)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsScrollbar(PR_TRUE);
}
else if (mClassID.Equals(kCTextArea)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsTextAreaWidget();
}
else if (mClassID.Equals(kCTextField)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsTextWidget();
}
else if (mClassID.Equals(kCAppShell)) {
inst = (nsISupports*)new nsAppShell();
}
else if (mClassID.Equals(kCToolkit)) {
inst = (nsISupports*)new nsToolkit();
}
else if (mClassID.Equals(kCLookAndFeel)) {
inst = (nsISupports*)new nsLookAndFeel();
}
else if (mClassID.Equals(kCLabel)) {
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsLabel();
}
else if (mClassID.Equals(kCMenuBar)) {
inst = (nsISupports*)(nsIMenuBar*)new nsMenuBar();
}
else if (mClassID.Equals(kCMenu)) {
inst = (nsISupports*)(nsIMenu*)new nsMenu();
}
else if (mClassID.Equals(kCMenuItem)) {
inst = (nsISupports*)(nsIMenuItem*)new nsMenuItem();
}
else if (mClassID.Equals(kCContextMenu)) {
inst = (nsISupports*)(nsIContextMenu*)new nsContextMenu();
}
else if (mClassID.Equals(kCPopUpMenu)) {
inst = (nsISupports*)new nsPopUpMenu();
}
else if (mClassID.Equals(kCSound)) {
nsISound* aSound = nsnull;
NS_NewSound(&aSound);
inst = (nsISupports*) aSound;
inst = (nsISupports*) aSound;
}
else if (mClassID.Equals(kCFileSpecWithUI))
inst = (nsISupports*) (nsIFileSpecWithUI *) new nsFileSpecWithUIImpl;
else if (mClassID.Equals(kCTransferable)) {
inst = (nsISupports*)new nsTransferable();
inst = (nsISupports*)new nsTransferable();
}
else if (mClassID.Equals(kCXIFFormatConverter)) {
inst = (nsISupports*)new nsXIFFormatConverter();
}
else if (mClassID.Equals(kCClipboard)) {
inst = (nsISupports*)(nsBaseClipboard *)new nsClipboard();
}
else if (mClassID.Equals(kCDragService)) {
inst = (nsISupports*)(nsIDragService *)new nsDragService();
}
else if (mClassID.Equals(kCFontRetrieverService)) {
inst = (nsISupports*)(nsIFontRetrieverService *)new nsFontRetrieverService();
}
else if (mClassID.Equals(kCTimer)) {
inst = (nsISupports*)(nsITimer*) new nsTimer();
}
else if (mClassID.Equals(kCTimerManager)) {
inst = (nsISupports*)(nsITimerQueue*) new nsTimerManager();
}
/* */
if (inst == NULL) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(inst); // Stabilize
nsresult res = inst->QueryInterface(aIID, aResult);
NS_RELEASE(inst); // Destabilize and avoid leaks. Avoid calling delete <interface pointer>
return res;
}
nsresult nsWidgetFactory::LockFactory(PRBool aLock)
{
// Not implemented in simplest case.
return NS_OK;
// Not implemented in simplest case.
return NS_OK;
}
// return the proper factory to the caller
extern "C" NS_WIDGET nsresult
NSGetFactory(nsISupports* serviceMgr,
const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFactory **aFactory)
{
if (nsnull == aFactory) {
return NS_ERROR_NULL_POINTER;
}
*aFactory = new nsWidgetFactory(aClass);
if (nsnull == aFactory) {
return NS_ERROR_OUT_OF_MEMORY;
}
return (*aFactory)->QueryInterface(kIFactoryIID, (void**)aFactory);
}
@ -577,4 +260,3 @@ NSGetFactory(nsISupports* serviceMgr,

View File

@ -36,25 +36,14 @@ CPPSRCS = \
nsDataObj.cpp \
nsDataObjCollection.cpp \
nsClipboard.cpp \
nsPopUpMenu.cpp \
nsMenuBar.cpp \
nsMenu.cpp \
nsMenuItem.cpp \
nsContextMenu.cpp \
nsWindow.cpp \
nsButton.cpp \
nsCheckButton.cpp \
nsRadioButton.cpp \
nsListBox.cpp \
nsComboBox.cpp \
nsTextWidget.cpp \
nsTextHelper.cpp \
nsTextAreaWidget.cpp \
nsFileWidget.cpp \
nsScrollbar.cpp \
nsAppShell.cpp \
nsLookAndFeel.cpp \
nsLabel.cpp \
nsToolkit.cpp \
nsSound.cpp \
$(NULL)
@ -71,25 +60,14 @@ OBJS = \
.\$(OBJDIR)\nsDataObj.obj \
.\$(OBJDIR)\nsDataObjCollection.obj \
.\$(OBJDIR)\nsClipboard.obj \
.\$(OBJDIR)\nsPopUpMenu.obj \
.\$(OBJDIR)\nsMenuBar.obj \
.\$(OBJDIR)\nsMenu.obj \
.\$(OBJDIR)\nsMenuItem.obj \
.\$(OBJDIR)\nsContextMenu.obj \
.\$(OBJDIR)\nsWindow.obj \
.\$(OBJDIR)\nsButton.obj \
.\$(OBJDIR)\nsCheckButton.obj \
.\$(OBJDIR)\nsRadioButton.obj \
.\$(OBJDIR)\nsListBox.obj \
.\$(OBJDIR)\nsComboBox.obj \
.\$(OBJDIR)\nsTextWidget.obj \
.\$(OBJDIR)\nsTextHelper.obj \
.\$(OBJDIR)\nsTextAreaWidget.obj \
.\$(OBJDIR)\nsFileWidget.obj \
.\$(OBJDIR)\nsScrollbar.obj \
.\$(OBJDIR)\nsAppShell.obj \
.\$(OBJDIR)\nsLookAndFeel.obj \
.\$(OBJDIR)\nsLabel.obj \
.\$(OBJDIR)\nsToolkit.obj \
.\$(OBJDIR)\nsSound.obj \
$(NULL)

View File

@ -266,14 +266,10 @@ nsWindow::nsWindow() : nsBaseWidget()
mFont = nsnull;
mIsVisible = PR_FALSE;
mHas3DBorder = PR_FALSE;
mMenuBar = nsnull;
mMenuCmdId = 0;
mWindowType = eWindowType_child;
mBorderStyle = eBorderStyle_default;
mBorderlessParent = 0;
mHitMenu = nsnull;
mHitSubMenus = new nsVoidArray();
mIsInMouseCapture = PR_FALSE;
mIMEProperty = 0;
@ -326,10 +322,6 @@ nsWindow::~nsWindow()
Destroy();
}
NS_IF_RELEASE(mHitMenu); // this should always have already been freed by the deselect
delete mHitSubMenus;
//XXX Temporary: Should not be caching the font
delete mFont;
@ -501,8 +493,6 @@ NS_IMETHODIMP nsWindow::DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus
aStatus = nsEventStatus_eIgnore;
//if (nsnull != mMenuListener)
// aStatus = mMenuListener->MenuSelected(*event);
if (nsnull != mEventCallback) {
aStatus = (*mEventCallback)(event);
}
@ -1809,407 +1799,6 @@ void nsWindow::SetUpForPaint(HDC aHDC)
::SetBkMode (aHDC, TRANSPARENT);
}
//-------------------------------------------------------------------------
nsIMenuItem * nsWindow::FindMenuItem(nsIMenu * aMenu, PRUint32 aId)
{
PRUint32 i, count;
aMenu->GetItemCount(count);
for (i=0;i<count;i++) {
nsISupports * item;
nsIMenuItem * menuItem;
nsIMenu * menu;
aMenu->GetItemAt(i, item);
if (NS_OK == item->QueryInterface(nsCOMTypeInfo<nsIMenuItem>::GetIID(), (void **)&menuItem)) {
if (((nsMenuItem *)menuItem)->GetCmdId() == (PRInt32)aId) {
NS_RELEASE(item);
return menuItem;
}
} else if (NS_OK == item->QueryInterface(nsCOMTypeInfo<nsIMenu>::GetIID(), (void **)&menu)) {
nsIMenuItem * fndItem = FindMenuItem(menu, aId);
NS_RELEASE(menu);
if (nsnull != fndItem) {
NS_RELEASE(item);
return fndItem;
}
}
NS_RELEASE(item);
}
return nsnull;
}
//-------------------------------------------------------------------------
static nsIMenuItem * FindMenuChild(nsIMenu * aMenu, PRInt32 aId)
{
PRUint32 i, count;
aMenu->GetItemCount(count);
for (i=0;i<count;i++) {
nsISupports * item;
aMenu->GetItemAt(i, item);
nsIMenuItem * menuItem;
if (NS_OK == item->QueryInterface(nsCOMTypeInfo<nsIMenuItem>::GetIID(), (void **)&menuItem)) {
if (((nsMenuItem *)menuItem)->GetCmdId() == (PRInt32)aId) {
NS_RELEASE(item);
return menuItem;
}
}
NS_RELEASE(item);
}
return nsnull;
}
//-------------------------------------------------------------------------
nsIMenu * nsWindow::FindMenu(nsIMenu * aMenu, HMENU aNativeMenu, PRInt32 &aDepth)
{
if (aNativeMenu == ((nsMenu *)aMenu)->GetNativeMenu()) {
NS_ADDREF(aMenu);
return aMenu;
}
//aDepth++;
PRUint32 i, count;
aMenu->GetItemCount(count);
for (i=0;i<count;i++) {
nsISupports * item;
aMenu->GetItemAt(i, item);
nsIMenu * menu;
if (NS_OK == item->QueryInterface(nsCOMTypeInfo<nsIMenu>::GetIID(), (void **)&menu)) {
HMENU nativeMenu = ((nsMenu *)menu)->GetNativeMenu();
if (nativeMenu == aNativeMenu) {
aDepth++;
return menu;
} else {
nsIMenu * fndMenu = FindMenu(menu, aNativeMenu, aDepth);
if (fndMenu) {
NS_RELEASE(item);
NS_RELEASE(menu);
aDepth++;
return fndMenu;
}
}
NS_RELEASE(menu);
}
NS_RELEASE(item);
}
return nsnull;
}
//-------------------------------------------------------------------------
static void AdjustMenus(nsIMenu * aCurrentMenu, nsIMenu * aNewMenu, nsMenuEvent & aEvent)
{
if (nsnull != aCurrentMenu) {
nsIMenuListener * listener;
if (NS_OK == aCurrentMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
//listener->MenuDeselected(aEvent);
NS_RELEASE(listener);
}
}
if (nsnull != aNewMenu) {
nsIMenuListener * listener;
if (NS_OK == aNewMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
NS_ASSERTION(false, "get debugger");
//listener->MenuSelected(aEvent);
NS_RELEASE(listener);
}
}
}
//-------------------------------------------------------------------------
nsresult nsWindow::MenuHasBeenSelected(
HMENU aNativeMenu,
UINT aItemNum,
UINT aFlags,
UINT aCommand)
{
// Build nsMenuEvent
nsMenuEvent event;
event.mCommand = aCommand;
event.eventStructType = NS_MENU_EVENT;
InitEvent(event, NS_MENU_SELECTED);
// The MF_POPUP flag tells us if we are a menu item or a menu
// the aItemNum is either the command ID of the menu item or
// the position of the menu as a child of its parent
PRBool isMenuItem = !(aFlags & MF_POPUP);
if(isMenuItem) {
//printf("WM_MENUSELECT for menu item\n");
//NS_RELEASE(event.widget);
//return NS_OK;
}
else
{
//printf("WM_MENUSELECT for menu\n");
}
// uItem is the position of the item that was clicked
// aNativeMenu is a handle to the menu that was clicked
// if aNativeMenu is NULL then the menu is being deselected
if (!aNativeMenu) {
//printf("... for deselect\n");
//printf("///////////// Menu is NULL!\n");
// check to make sure something had been selected
//AdjustMenus(mHitMenu, nsnull, event);
nsIMenu * aNewMenu = nsnull;
nsMenuEvent aEvent = event;
//static void AdjustMenus(nsIMenu * aCurrentMenu, nsIMenu * aNewMenu, nsMenuEvent & aEvent)
{
if (nsnull != mHitMenu) {
nsIMenuListener * listener;
if (NS_OK == mHitMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuDeselected(aEvent);
NS_RELEASE(listener);
}
}
if (nsnull != aNewMenu) {
nsIMenuListener * listener;
if (NS_OK == aNewMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuSelected(aEvent);
NS_RELEASE(listener);
}
}
}
NS_IF_RELEASE(mHitMenu);
// Clear All SubMenu items
while (mHitSubMenus->Count() > 0) {
PRUint32 inx = mHitSubMenus->Count()-1;
nsIMenu * menu = (nsIMenu *)mHitSubMenus->ElementAt(inx);
//AdjustMenus(menu, nsnull, event);
nsIMenu * aCurrentMenu = menu;
nsIMenu * aNewMenu = nsnull;
//static void AdjustMenus(nsIMenu * aCurrentMenu, nsIMenu * aNewMenu, nsMenuEvent & aEvent)
{
if (nsnull != aCurrentMenu) {
nsIMenuListener * listener;
if (NS_OK == aCurrentMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuDeselected(event);
NS_RELEASE(listener);
}
}
if (nsnull != aNewMenu) {
nsIMenuListener * listener;
if (NS_OK == aNewMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuSelected(event);
NS_RELEASE(listener);
}
}
}
NS_RELEASE(menu);
mHitSubMenus->RemoveElementAt(inx);
}
NS_RELEASE(event.widget);
return NS_OK;
} else { // The menu is being selected
//printf("... for selection\n");
void * voidData;
mMenuBar->GetNativeData(voidData);
HMENU nativeMenuBar = (HMENU)voidData;
// first check to see if it is a member of the menubar
nsIMenu * hitMenu = nsnull;
if (aNativeMenu == nativeMenuBar) {
mMenuBar->GetMenuAt(aItemNum, hitMenu);
if (mHitMenu != hitMenu) {
//mHitMenu, hitMenu, event
nsMenuEvent aEvent = event;
//AdjustMenus(nsIMenu * aCurrentMenu, nsIMenu * aNewMenu, nsMenuEvent & aEvent)
{
if (nsnull != mHitMenu) {
nsIMenuListener * listener;
if (NS_OK == mHitMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuDeselected(aEvent);
NS_RELEASE(listener);
}
}
if (nsnull != hitMenu) {
nsIMenuListener * listener;
if (NS_OK == hitMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuSelected(aEvent);
NS_RELEASE(listener);
}
}
}
NS_IF_RELEASE(mHitMenu);
mHitMenu = hitMenu;
} else {
NS_IF_RELEASE(hitMenu);
}
} else {
// At this point we know we are inside a menu
// Find the menu we are in (the parent menu)
nsIMenu * parentMenu = nsnull;
PRInt32 fndDepth = 0;
PRUint32 i, count;
mMenuBar->GetMenuCount(count);
for (i=0;i<count;i++) {
nsIMenu * menu;
mMenuBar->GetMenuAt(i, menu);
PRInt32 depth = 0;
parentMenu = FindMenu(menu, aNativeMenu, depth);
if (parentMenu) {
fndDepth = depth;
break;
}
NS_RELEASE(menu);
}
if (nsnull != parentMenu) {
// Sometimes an event comes through for a menu that is being popup down
// So it its depth is great then the current hit list count it already gone.
if (fndDepth > mHitSubMenus->Count()) {
NS_RELEASE(parentMenu);
NS_RELEASE(event.widget);
return NS_OK;
}
nsIMenu * newMenu = nsnull;
// Skip if it is a menu item, otherwise, we get the menu by position
if (!isMenuItem) {
//printf("Getting submenu by position %d from parentMenu\n", aItemNum);
nsISupports * item;
parentMenu->GetItemAt((PRUint32)aItemNum, item);
if (NS_OK != item->QueryInterface(nsCOMTypeInfo<nsIMenu>::GetIID(), (void **)&newMenu)) {
//printf("Item was not a menu! What are we doing here? Return early....\n");
NS_RELEASE(event.widget);
return NS_ERROR_FAILURE;
}
}
// Figure out if this new menu is in the list of popup'ed menus
PRBool newFound = PR_FALSE;
PRInt32 newLevel = 0;
for (newLevel=0;newLevel<mHitSubMenus->Count();newLevel++) {
if (newMenu == (nsIMenu *)mHitSubMenus->ElementAt(newLevel)) {
newFound = PR_TRUE;
break;
}
}
// Figure out if the parent menu is in the list of popup'ed menus
PRBool found = PR_FALSE;
PRInt32 level = 0;
for (level=0;level<mHitSubMenus->Count();level++) {
if (parentMenu == (nsIMenu *)mHitSubMenus->ElementAt(level)) {
found = PR_TRUE;
break;
}
}
// So now figure out were we are compared to the hit list depth
// we figure out how many items are open below
//
// If the parent was found then we use it
// if the parent was NOT found this means we are at the very first level (menu from the menubar)
// Windows will send an event for a parent AND child that is already in the hit list
// and we think we should be popping it down. So we check to see if the
// new menu is already in the tree so it doesn't get removed and then added.
PRInt32 numToRemove = 0;
if (found) {
numToRemove = mHitSubMenus->Count() - level - 1;
} else {
// This means we got a menu event for a menubar menu
if (newFound) { // newFound checks to see if the new menu to be added is already in the hit list
numToRemove = mHitSubMenus->Count() - newLevel - 1;
} else {
numToRemove = mHitSubMenus->Count();
}
}
// If we are to remove 1 item && the new menu to be added is the
// same as the one we would be removing, then don't remove it.
if (numToRemove == 1 && newMenu == (nsIMenu *)mHitSubMenus->ElementAt(mHitSubMenus->Count()-1)) {
numToRemove = 0;
}
// Now loop thru and removing the menu from thre list
PRInt32 ii;
for (ii=0;ii<numToRemove;ii++) {
nsIMenu * m = (nsIMenu *)mHitSubMenus->ElementAt(mHitSubMenus->Count()-1 );
//AdjustMenus(m, nsnull, event);
nsIMenu * aCurrentMenu = m;
nsIMenu * aNewMenu = nsnull;
nsMenuEvent aEvent = event;
//static void AdjustMenus(nsIMenu * aCurrentMenu, nsIMenu * aNewMenu, nsMenuEvent & aEvent)
{
if (nsnull != aCurrentMenu) {
nsIMenuListener * listener;
if (NS_OK == aCurrentMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuDeselected(aEvent);
NS_RELEASE(listener);
}
}
if (nsnull != aNewMenu) {
nsIMenuListener * listener;
if (NS_OK == aNewMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
NS_ASSERTION(false, "get debugger");
listener->MenuSelected(aEvent);
NS_RELEASE(listener);
}
}
}
nsString name;
m->GetLabel(name);
NS_RELEASE(m);
mHitSubMenus->RemoveElementAt(mHitSubMenus->Count()-1);
}
// At this point we bail if we are a menu item
if (isMenuItem) {
NS_RELEASE(event.widget);
return NS_OK;
}
// Here we know we have a menu, check one last time to see
// if the new one is the last one in the list
// Add it if it isn't or skip adding it
nsString name;
newMenu->GetLabel(name);
if (newMenu != (nsIMenu *)mHitSubMenus->ElementAt(mHitSubMenus->Count()-1)) {
mHitSubMenus->AppendElement(newMenu);
NS_ADDREF(newMenu);
//AdjustMenus(nsnull, newMenu, event);
nsIMenu * aCurrentMenu = nsnull;
nsIMenu * aNewMenu = newMenu;
nsMenuEvent aEvent = event;
//static void AdjustMenus(nsIMenu * aCurrentMenu, nsIMenu * aNewMenu, nsMenuEvent & aEvent)
{
if (nsnull != aCurrentMenu) {
nsIMenuListener * listener;
if (NS_OK == aCurrentMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuDeselected(aEvent);
NS_RELEASE(listener);
}
}
if (nsnull != aNewMenu) {
nsIMenuListener * listener;
if (NS_OK == aNewMenu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuSelected(aEvent);
NS_RELEASE(listener);
}
}
}
}
NS_RELEASE(parentMenu);
} else {
//printf("no menu was found. This is bad.\n");
// XXX need to assert here!
}
}
}
NS_RELEASE(event.widget);
return NS_OK;
}
//---------------------------------------------------------
NS_METHOD nsWindow::EnableDragDrop(PRBool aEnable)
{
@ -2531,31 +2120,6 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
event.eventStructType = NS_MENU_EVENT;
InitEvent(event, NS_MENU_SELECTED);
result = DispatchWindowEvent(&event);
if (mMenuBar) {
PRUint32 i, count;
mMenuBar->GetMenuCount(count);
for (i=0;i<count;i++) {
nsIMenu * menu;
mMenuBar->GetMenuAt(i, menu);
nsIMenuItem * menuItem = FindMenuItem(menu, event.mCommand);
if (menuItem) {
nsIMenuListener * listener;
if (NS_OK == menuItem->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener)) {
listener->MenuItemSelected(event);
NS_RELEASE(listener);
menu->QueryInterface(nsCOMTypeInfo<nsIMenuListener>::GetIID(), (void **)&listener);
if(listener){
//listener->MenuDestruct(event);
NS_RELEASE(listener);
}
}
NS_RELEASE(menuItem);
}
NS_RELEASE(menu);
}
}
NS_RELEASE(event.widget);
}
}
@ -2695,17 +2259,6 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
else
result = PR_FALSE;
// Let's consume the ALT key up so that we don't go into
// a menu bar if we don't have one.
// XXX This will cause a tiny breakage in viewer... namely
// that hitting ALT by itself in viewer won't move you into
// the menu. ALT+shortcut key will still work, though, so
// I figure this is ok.
if (!mMenuBar && (wParam == NS_VK_ALT)) {
result = PR_TRUE;
*aRetValue = 0;
}
break;
// Let ths fall through if it isn't a key pad
@ -2740,8 +2293,8 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
if (!mIMEIsComposing)
result = OnKeyDown(wParam, (HIWORD(lParam)));
else
result = PR_FALSE;
else
result = PR_FALSE;
}
break;
@ -2939,12 +2492,6 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
break;
}
case WM_MENUSELECT:
if (mMenuBar) {
MenuHasBeenSelected((HMENU)lParam, (UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (UINT) LOWORD(wParam));
}
break;
case WM_SETTINGCHANGE:
firstTime = TRUE;
// Fall through
@ -3753,6 +3300,21 @@ DWORD nsWindow::GetBorderStyle(nsBorderStyle aBorderStyle)
*/
}
static char* GetACPString(const nsString& aStr)
{
int acplen = aStr.Length() * 2 + 1;
char * acp = new char[acplen];
if(acp)
{
int outlen = ::WideCharToMultiByte( CP_ACP, 0,
aStr.GetUnicode(), aStr.Length(),
acp, acplen, NULL, NULL);
if ( outlen > 0)
acp[outlen] = '\0'; // null terminate
}
return acp;
}
NS_METHOD nsWindow::SetTitle(const nsString& aTitle)
{
char* title = GetACPString(aTitle);
@ -3769,36 +3331,6 @@ PRBool nsWindow::AutoErase()
return(PR_FALSE);
}
NS_METHOD nsWindow::SetMenuBar(nsIMenuBar * aMenuBar)
{
mMenuBar = aMenuBar;
NS_ADDREF(mMenuBar);
return ShowMenuBar(PR_TRUE);
}
NS_METHOD nsWindow::ShowMenuBar(PRBool aShow)
{
nsresult rv = NS_ERROR_FAILURE;
if (aShow) {
if (mMenuBar) {
HMENU nativeMenuHandle;
void *voidData;
mMenuBar->GetNativeData(voidData);
nativeMenuHandle = (HMENU)voidData;
if (nativeMenuHandle) {
::SetMenu(mWnd, nativeMenuHandle);
rv = NS_OK;
}
}
} else {
::SetMenu(mWnd, 0);
rv = NS_OK;
}
return rv;
}
NS_METHOD nsWindow::GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight)
{
aWidth = mPreferredWidth;

View File

@ -30,8 +30,6 @@
#include "nsIWidget.h"
#include "nsIKBStateControl.h"
#include "nsIMenuBar.h"
#include "nsIMouseListener.h"
#include "nsIEventListener.h"
#include "nsStringUtil.h"
@ -42,6 +40,8 @@
class nsNativeDragTarget;
class nsIRollupListener;
class nsIMenuBar;
#define NSRGB_2_COLOREF(color) \
RGB(NS_GET_R(color),NS_GET_G(color),NS_GET_B(color))
@ -130,8 +130,8 @@ public:
NS_IMETHOD ScrollWidgets(PRInt32 aDx, PRInt32 aDy);
NS_IMETHOD ScrollRect(nsRect &aRect, PRInt32 aDx, PRInt32 aDy);
NS_IMETHOD SetTitle(const nsString& aTitle);
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar);
NS_IMETHOD ShowMenuBar(PRBool aShow);
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar) { return NS_ERROR_FAILURE; }
NS_IMETHOD ShowMenuBar(PRBool aShow) { return NS_ERROR_FAILURE; }
NS_IMETHOD WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect);
NS_IMETHOD ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect);
NS_IMETHOD BeginResizingChildren(void);
@ -176,10 +176,6 @@ protected:
virtual PRBool ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *aRetValue);
virtual PRBool DispatchWindowEvent(nsGUIEvent* event);
virtual PRBool DispatchWindowEvent(nsGUIEvent*event, nsEventStatus &aStatus);
nsresult MenuHasBeenSelected(HMENU aNativeMenu, UINT aItemNum, UINT aFlags, UINT aCommand);
nsresult DynamicMenuHasBeenSelected(HMENU aNativeMenu, UINT aItemNum, UINT aFlags, UINT aCommand);
nsIMenuItem * FindMenuItem(nsIMenu * aMenu, PRUint32 aId);
nsIMenu * FindMenu(nsIMenu * aMenu, HMENU aNativeMenu, PRInt32 &aDepth);
// Allow Derived classes to modify the height that is passed
// when the window is created or resized.
@ -272,10 +268,7 @@ protected:
PRInt32 mPreferredWidth;
PRInt32 mPreferredHeight;
nsIMenuBar * mMenuBar;
PRInt32 mMenuCmdId;
nsIMenu * mHitMenu;
nsVoidArray * mHitSubMenus;
// For Input Method Support
DWORD mIMEProperty;