comparison win/dw.c @ 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 dbd507f42947
children 47dbe605a03f
comparison
equal deleted inserted replaced
1308:224893b5b868 1309:e73c41653de8
642 for(i=0;i<count;i++) 642 for(i=0;i<count;i++)
643 { 643 {
644 MENUITEMINFO mii; 644 MENUITEMINFO mii;
645 645
646 mii.cbSize = sizeof(MENUITEMINFO); 646 mii.cbSize = sizeof(MENUITEMINFO);
647 mii.fMask = MIIM_SUBMENU; 647 mii.fMask = MIIM_SUBMENU | MIIM_ID;
648 648
649 if ( GetMenuItemInfo( menu, i, TRUE, &mii ) && mii.hSubMenu ) 649 if ( GetMenuItemInfo( menu, i, TRUE, &mii ) )
650 _free_menu_data(mii.hSubMenu); 650 {
651 /* Free the data associated with the ID */
652 if(mii.wID >= 30000)
653 {
654 char buffer[31] = {0};
655
656 _snprintf(buffer, 30, "_dw_id%ld", mii.wID);
657 dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
658 _snprintf(buffer, 30, "_dw_checkable%ld", mii.wID);
659 dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
660 _snprintf(buffer, 30, "_dw_ischecked%ld", mii.wID);
661 dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
662 _snprintf(buffer, 30, "_dw_isdisabled%ld", mii.wID);
663 dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
664 }
665
666 /* Check any submenus */
667 if( mii.hSubMenu )
668 _free_menu_data(mii.hSubMenu);
669 }
651 } 670 }
652 dw_signal_disconnect_by_name((HWND)menu, DW_SIGNAL_CLICKED); 671 dw_signal_disconnect_by_name((HWND)menu, DW_SIGNAL_CLICKED);
653 } 672 }
654 673
655 /* Convert to our internal color scheme */ 674 /* Convert to our internal color scheme */
4801 if(IsMenu(mymenu)) 4820 if(IsMenu(mymenu))
4802 DestroyMenu(mymenu); 4821 DestroyMenu(mymenu);
4803 } 4822 }
4804 } 4823 }
4805 4824
4825 /* Internal function to make sure menu ID isn't in use */
4826 int _menuid_allocated(int id)
4827 {
4828 SignalHandler *prev = NULL, *tmp = Root;
4829
4830 while(tmp)
4831 {
4832 if(tmp->id == id)
4833 return TRUE;
4834 tmp = tmp->next;
4835 }
4836 return FALSE;
4837 }
4838
4806 /* 4839 /*
4807 * Adds a menuitem or submenu to an existing menu. 4840 * Adds a menuitem or submenu to an existing menu.
4808 * Parameters: 4841 * Parameters:
4809 * menu: The handle to the existing menu. 4842 * menu: The handle to the existing menu.
4810 * title: The title text on the menu item to be added. 4843 * title: The title text on the menu item to be added.
4862 } 4895 }
4863 /* Second pool is larger for more static windows */ 4896 /* Second pool is larger for more static windows */
4864 else if(!id || id >= 30000) 4897 else if(!id || id >= 30000)
4865 { 4898 {
4866 static ULONG menuid = 30000; 4899 static ULONG menuid = 30000;
4867 4900
4868 menuid++; 4901 do
4902 {
4903 menuid++;
4904 if(menuid > 60000)
4905 menuid = 30000;
4906 }
4907 while(_menuid_allocated(menuid));
4869 id = menuid; 4908 id = menuid;
4870
4871 if(menuid > 60000)
4872 menuid = 30000;
4873 } 4909 }
4874 mii.fType = MFT_STRING; 4910 mii.fType = MFT_STRING;
4875 } 4911 }
4876 else 4912 else
4877 mii.fType = MFT_SEPARATOR; 4913 mii.fType = MFT_SEPARATOR;
10822 if(!window || !signame || (message = _findsigmessage(signame)) == 0) 10858 if(!window || !signame || (message = _findsigmessage(signame)) == 0)
10823 return; 10859 return;
10824 10860
10825 while(tmp) 10861 while(tmp)
10826 { 10862 {
10827 if(tmp->window == window && tmp->message == message) 10863 if(((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window) && tmp->message == message)
10864 {
10865 if(prev)
10866 {
10867 prev->next = tmp->next;
10868 free(tmp);
10869 tmp = prev->next;
10870 }
10871 else
10872 {
10873 Root = tmp->next;
10874 free(tmp);
10875 tmp = Root;
10876 }
10877 }
10878 else
10879 {
10880 prev = tmp;
10881 tmp = tmp->next;
10882 }
10883 }
10884 }
10885
10886 /*
10887 * Removes all callbacks for a given window.
10888 * Parameters:
10889 * window: Window handle of callback to be removed.
10890 */
10891 void API dw_signal_disconnect_by_window(HWND window)
10892 {
10893 SignalHandler *prev = NULL, *tmp = Root;
10894
10895 while(tmp)
10896 {
10897 if((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window)
10828 { 10898 {
10829 if(prev) 10899 if(prev)
10830 { 10900 {
10831 prev->next = tmp->next; 10901 prev->next = tmp->next;
10832 free(tmp); 10902 free(tmp);
10846 } 10916 }
10847 } 10917 }
10848 } 10918 }
10849 10919
10850 /* 10920 /*
10851 * Removes all callbacks for a given window. 10921 * Removes all callbacks for a given window with specified data.
10852 * Parameters: 10922 * Parameters:
10853 * window: Window handle of callback to be removed. 10923 * window: Window handle of callback to be removed.
10854 */ 10924 * data: Pointer to the data to be compared against.
10855 void API dw_signal_disconnect_by_window(HWND window) 10925 */
10926 void API dw_signal_disconnect_by_data(HWND window, void *data)
10856 { 10927 {
10857 SignalHandler *prev = NULL, *tmp = Root; 10928 SignalHandler *prev = NULL, *tmp = Root;
10858 10929
10859 while(tmp) 10930 while(tmp)
10860 { 10931 {
10861 if(tmp->window == window) 10932 if(((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window) && tmp->data == data)
10862 { 10933 {
10863 if(prev) 10934 if(prev)
10864 { 10935 {
10865 prev->next = tmp->next; 10936 prev->next = tmp->next;
10866 free(tmp); 10937 free(tmp);
10867 tmp = prev->next; 10938 tmp = prev->next;
10868 } 10939 }
10878 prev = tmp; 10949 prev = tmp;
10879 tmp = tmp->next; 10950 tmp = tmp->next;
10880 } 10951 }
10881 } 10952 }
10882 } 10953 }
10883
10884 /*
10885 * Removes all callbacks for a given window with specified data.
10886 * Parameters:
10887 * window: Window handle of callback to be removed.
10888 * data: Pointer to the data to be compared against.
10889 */
10890 void API dw_signal_disconnect_by_data(HWND window, void *data)
10891 {
10892 SignalHandler *prev = NULL, *tmp = Root;
10893
10894 while(tmp)
10895 {
10896 if(tmp->window == window && tmp->data == data)
10897 {
10898 if(prev)
10899 {
10900 prev->next = tmp->next;
10901 free(tmp);
10902 tmp = prev->next;
10903 }
10904 else
10905 {
10906 Root = tmp->next;
10907 free(tmp);
10908 tmp = Root;
10909 }
10910 }
10911 else
10912 {
10913 prev = tmp;
10914 tmp = tmp->next;
10915 }
10916 }
10917 }