← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2837: process callbacks while showing a menu; some cleanup of menu item removal

 

------------------------------------------------------------
revno: 2837
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Wed 2012-01-25 19:21:31 +0100
message:
  process callbacks while showing a menu; some cleanup of menu item removal
modified:
  changelog.txt
  dwt/src/widgets/Control.cpp
  dwt/src/widgets/Menu.cpp
  win32/ShellMenu.h


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt	2012-01-19 20:18:37 +0000
+++ changelog.txt	2012-01-25 18:21:31 +0000
@@ -14,6 +14,7 @@
 * [L#704502] Away mode after some time of inactivity (poy)
 * Allow empty user matching definitions that match every user (poy)
 * Add predefined user matching defs for favs (bold, more red) & ops (more blue) (poy)
+* [L#300971] Keep updating GUI elements while a menu is up (poy)
 
 -- 0.791 2012-01-14 --
 * Update translations

=== modified file 'dwt/src/widgets/Control.cpp'
--- dwt/src/widgets/Control.cpp	2012-01-22 20:27:14 +0000
+++ dwt/src/widgets/Control.cpp	2012-01-25 18:21:31 +0000
@@ -107,18 +107,37 @@
 
 	switch(msg.message)
 	{
+		/* messages that allow Windows controls to owner-draw are sent as notifications to the
+		parent; therefore, we catch them here assuming that the parent of an owner-drawn control
+		will have this class as a base. they are then forwarded to the relevant control for further
+		processing. */
 	case WM_DRAWITEM:
-		if(forwardPainting<DRAWITEMSTRUCT>(msg)) {
-			retVal = TRUE;
-			return true;
+		{
+			if(forwardPainting<DRAWITEMSTRUCT>(msg)) {
+				retVal = TRUE;
+				return true;
+			}
+			break;
 		}
-		break;
 	case WM_MEASUREITEM:
-		if(forwardPainting<MEASUREITEMSTRUCT>(msg)) {
-			retVal = TRUE;
-			return true;
-		}
-		break;
+		{
+			if(forwardPainting<MEASUREITEMSTRUCT>(msg)) {
+				retVal = TRUE;
+				return true;
+			}
+			break;
+		}
+
+		/* menus have their own message loop. to peek into it, one can either install a hook or
+		wait for WM_ENTERIDLE messages; we choose the latter. this allows async callbakcs to keep
+		running and updating the application while a menu is up. */
+	case WM_ENTERIDLE:
+		{
+			if(msg.wParam == MSGF_MENU) {
+				Application::instance().dispatch();
+			}
+			break;
+		}
 	}
 
 	return handled;

=== modified file 'dwt/src/widgets/Menu.cpp'
--- dwt/src/widgets/Menu.cpp	2012-01-23 21:02:12 +0000
+++ dwt/src/widgets/Menu.cpp	2012-01-25 18:21:31 +0000
@@ -736,39 +736,29 @@
 }
 
 void Menu::removeItem(unsigned index) {
-	// has sub menus ?
-	HMENU popup = ::GetSubMenu( itsHandle, index );
-
-	// try to remove item
-	if ( ::RemoveMenu( itsHandle, index, MF_BYPOSITION ) )
-	{
-		if(ownerDrawn) {
-			int itemRemoved = -1;
-
-			for(size_t i = 0; i < itsItemData.size(); ++i) {
-				// get current data wrapper
-				auto& wrapper = itsItemData[i];
-
-				if ( wrapper->index == index ) // if found
-				{
-					itemRemoved = int(i);
-					itsItemData[i] = 0;
+	auto child = ::GetSubMenu(itsHandle, index);
+
+	if(!::RemoveMenu(itsHandle, index, MF_BYPOSITION)) {
+		throw Win32Exception("Couldn't remove item in Menu::removeItem");
+	}
+
+	if(ownerDrawn) {
+		for(auto i = itsItemData.begin(); i != itsItemData.end();) {
+			if((*i)->index == index) {
+				i = itsItemData.erase(i);
+			} else {
+				if((*i)->index > index) {
+					--(*i)->index; // adjust succeeding item indices
 				}
-				else if ( wrapper->index > index )
-					--wrapper->index; // adjust succeeding item indices
+				++i;
 			}
-
-			if( itemRemoved != -1 )
-				itsItemData.erase( itsItemData.begin() + itemRemoved );
-		}
-
-		// remove sub menus if any
-		if(popup) {
-			itsChildren.erase(std::remove_if(itsChildren.begin(), itsChildren.end(),
-				[popup](std::unique_ptr<Menu>& sub) { return sub->handle() == popup; }), itsChildren.end());
-		}
-	} else {
-		dwtWin32DebugFail("Couldn't remove item in removeItem()");
+		}
+	}
+
+	// remove from the child list if this was a sub-menu.
+	if(child) {
+		itsChildren.erase(std::remove_if(itsChildren.begin(), itsChildren.end(),
+			[child](std::unique_ptr<Menu>& sub) { return sub->handle() == child; }), itsChildren.end());
 	}
 }
 

=== modified file 'win32/ShellMenu.h'
--- win32/ShellMenu.h	2012-01-22 20:27:14 +0000
+++ win32/ShellMenu.h	2012-01-25 18:21:31 +0000
@@ -49,16 +49,12 @@
 	void open(const dwt::ScreenCoordinate& pt, unsigned flags = TPM_LEFTALIGN | TPM_RIGHTBUTTON);
 
 private:
-	typedef std::pair<Menu*, LPCONTEXTMENU3> handlers_pair;
-	typedef std::vector<handlers_pair> handlers_type;
-	handlers_type handlers;
+	std::vector<std::pair<Menu*, LPCONTEXTMENU3>> handlers;
 
 	LPCONTEXTMENU3 handler;
 	unsigned sel_id;
 
-	typedef std::pair<dwt::Message, dwt::Widget::CallbackIter> callbacks_pair;
-	typedef std::vector<callbacks_pair> callbacks_type;
-	callbacks_type callbacks;
+	std::vector<std::pair<dwt::Message, dwt::Widget::CallbackIter>> callbacks;
 
 	bool handleDrawItem(const MSG& msg, LRESULT& ret);
 	bool handleMeasureItem(const MSG& msg, LRESULT& ret);