changeset 1309:e73c41653de8

Added support on OS/2 and Windows for looking for signal handlers with menu IDs... and skipping auto generating menu IDs that have handlers already attached. Also remove associated menu data when destroying menus with auto generated IDs. Also allow dw_window_disconnect*() to work on the handle returned by dw_menu_append_item().
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 04 Nov 2011 03:30:27 +0000
parents 224893b5b868
children 47dbe605a03f
files os2/dw.c win/dw.c
diffstat 2 files changed, 92 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/os2/dw.c	Thu Nov 03 23:42:12 2011 +0000
+++ b/os2/dw.c	Fri Nov 04 03:30:27 2011 +0000
@@ -459,6 +459,22 @@
       SHORT menuid = (SHORT)WinSendMsg(menu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0);
       MENUITEM mi;
 
+      /* Free the data associated with the ID */
+      if(menuid >= 30000)
+      {
+         char buffer[31] = {0};
+       
+         sprintf(buffer, "_dw_id%ld", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_checkable%ld", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_ischecked%ld", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_isdisabled%ld", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+      }
+      
+      /* Check any submenus */
       if(WinSendMsg(menu, MM_QUERYITEM, MPFROMSHORT(menuid), MPFROMP(&mi))
          && mi.hwndSubMenu)
          _free_menu_data(mi.hwndSubMenu);
@@ -4681,6 +4697,20 @@
       WinDestroyWindow(*menu);
 }
 
+/* Internal function to make sure menu ID isn't in use */
+int _menuid_allocated(int id)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   while(tmp)
+   {
+     if(tmp->id == id)
+        return TRUE;   
+     tmp = tmp->next;
+   }
+   return FALSE;
+}
+
 /*
  * Adds a menuitem or submenu to an existing menu.
  * Parameters:
@@ -4737,11 +4767,14 @@
       {
          static ULONG menuid = 30000;
          
-         menuid++;
+         do
+         {
+            menuid++;
+            if(menuid > 60000)
+               menuid = 30000;
+         }
+         while(_menuid_allocated(menuid));
          id = menuid;
-         
-         if(menuid > 60000)
-            menuid = 30000;
       }
       miSubMenu.afStyle = MIS_TEXT;
    }
@@ -11019,7 +11052,7 @@
 
    while(tmp)
    {
-      if(tmp->window == window && tmp->message == message)
+      if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->message == message)
       {
          if(prev)
          {
@@ -11053,7 +11086,7 @@
 
    while(tmp)
    {
-      if(tmp->window == window)
+      if((window < 65536 && tmp->id == window) || tmp->window == window)
       {
          if(prev)
          {
@@ -11088,7 +11121,7 @@
 
    while(tmp)
    {
-      if(tmp->window == window && tmp->data == data)
+      if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->data == data)
       {
          if(prev)
          {
--- a/win/dw.c	Thu Nov 03 23:42:12 2011 +0000
+++ b/win/dw.c	Fri Nov 04 03:30:27 2011 +0000
@@ -644,10 +644,29 @@
         MENUITEMINFO mii;
 
         mii.cbSize = sizeof(MENUITEMINFO);
-        mii.fMask = MIIM_SUBMENU;
-
-        if ( GetMenuItemInfo( menu, i, TRUE, &mii ) && mii.hSubMenu )
-            _free_menu_data(mii.hSubMenu);
+        mii.fMask = MIIM_SUBMENU | MIIM_ID;
+
+        if ( GetMenuItemInfo( menu, i, TRUE, &mii ) )
+        {  
+           /* Free the data associated with the ID */
+           if(mii.wID >= 30000)
+           {
+              char buffer[31] = {0};
+           
+              _snprintf(buffer, 30, "_dw_id%ld", mii.wID);
+              dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
+              _snprintf(buffer, 30, "_dw_checkable%ld", mii.wID);
+              dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
+              _snprintf(buffer, 30, "_dw_ischecked%ld", mii.wID);
+              dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
+              _snprintf(buffer, 30, "_dw_isdisabled%ld", mii.wID);
+              dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
+           }
+           
+           /* Check any submenus */
+           if( mii.hSubMenu )
+              _free_menu_data(mii.hSubMenu);
+        }
     }
     dw_signal_disconnect_by_name((HWND)menu, DW_SIGNAL_CLICKED);
 }
@@ -4803,6 +4822,20 @@
    }
 }
 
+/* Internal function to make sure menu ID isn't in use */
+int _menuid_allocated(int id)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   while(tmp)
+   {
+     if(tmp->id == id)
+        return TRUE;   
+     tmp = tmp->next;
+   }
+   return FALSE;
+}
+
 /*
  * Adds a menuitem or submenu to an existing menu.
  * Parameters:
@@ -4864,12 +4897,15 @@
       else if(!id || id >= 30000)
       {
          static ULONG menuid = 30000;
-         
-         menuid++;
+
+         do
+         {
+            menuid++;
+            if(menuid > 60000)
+               menuid = 30000;
+         }
+         while(_menuid_allocated(menuid));
          id = menuid;
-         
-         if(menuid > 60000)
-            menuid = 30000;
       }
       mii.fType = MFT_STRING;
    }
@@ -10824,9 +10860,9 @@
 
    while(tmp)
    {
-      if(tmp->window == window && tmp->message == message)
-      {
-         if(prev)
+      if(((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window) && tmp->message == message)
+      {
+        if(prev)
          {
             prev->next = tmp->next;
             free(tmp);
@@ -10858,7 +10894,7 @@
 
    while(tmp)
    {
-      if(tmp->window == window)
+      if((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window)
       {
          if(prev)
          {
@@ -10893,9 +10929,9 @@
 
    while(tmp)
    {
-      if(tmp->window == window && tmp->data == data)
-      {
-         if(prev)
+      if(((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window) && tmp->data == data)
+      {
+        if(prev)
          {
             prev->next = tmp->next;
             free(tmp);