Mercurial > dwindows
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 } |