How disable a menu (OpenInsight 32-bit Specific)
At 11 SEP 2002 03:52:37AM Oystein Reigem wrote:
I have a menu with several items. Some of the items have accelerator keys assigned to them. Now when I programmatically disable the menu, all the menu's items effectively become disabled too, since they are not accessible any more. But unfortunately their accelerator keys still work.
Is this the way it is supposed to be? Must I disable each single item? Revelation?
Version: OI 4.0.3. I'm fairly certain it's the same in OI16 (OI 3.6.1 and/or 3.7.1).
- Oystein -
At 12 SEP 2002 08:29AM Colin Rule wrote:
I disable each menu as appropriate and the attached accelerator keys do not work, which is what you are after.
If you are disabling the top branch, then this does not mean the lower branches are disabled also.
Colin
At 12 SEP 2002 10:06AM Oystein Reigem wrote:
Colin,
E.g Edit is a menu.
E.g Copy and Paste are menu items.
I assume what you say is one has to disable each menu item. It's not enough to disable the top level, i.e, the menu.
Thanks.
But it sure doesn't seem logical to me…
![]()
- Oystein -
At 13 SEP 2002 04:36AM Colin Rule wrote:
Yes, exactly.
Each menu branch is a separate entity, and they are only logically grouped in the menu.
At 25 SEP 2002 07:28AM Oystein Reigem wrote:
I made a general function to thoroughly disable/enable a menu. I post it here in case others are interested.
- Oystein -
function Set_Menu_ENABLE( MenuId, Enabled )
/*
MenuId is the id of a menu in the current window (@Window), e.g "FILE" or "EDIT".
it is the short version of the id, not the full id "MYWINDOW.MENU.FILE".
this functions enables or disables that menu and all its items.
Enable tells it to enable (true$) or disable (false$).
the function takes advantage of the hierarchical nature of ids.
the function should work on sub-items as well, e.g MenuId=VIEW.TOOLS",
but have not been tested on such.
the function is useful because one normally wants all items to be disabled
when one disables the menu. this is not so by default.
even if items don't show and so cannot be clicked
their accelerator keys still work.
*/
$insert Logical
declare function Set_Property
declare function Get_Property
/* init returned state. 0=OK */
Stat=0
/* prepare some values we need later */
ThisWindowsName=@Window1, "*"
ThisWindowsMainMenuId=ThisWindowsName : ".MENU"
FullMenuId=ThisWindowsMainMenuId : "." : MenuId
/* get menu stuff from window common */
WinID=@Window
$Insert OIWin_Comm_Init
NumCtrls=count(ControlList@, @FM) + (ControlList@ "")
if NumCtrls /* empty window? */
Stat=-1
goto Exit
end
MenuStuff=ControlList@
/* just a check to make certain we got the right stuff */
Test=MenuStuff
if Test=ThisWindowsMainMenuId else
/* program error */
Stat=-9
goto Exit
end
/* skip header */
for I=1 to 4
MenuStuff=delete(MenuStuff, 1, 1, 0)
next I
/* run through all menus and items
and set the ENABLE property for just the current menu and its items */NumMenusAndItems=count(MenuStuff, @VM) + 1
for I=1 to NumMenusAndItems
FullId=MenuStuff
if (FullId=FullMenuId) or (FullId1, len(FullMenuId)+1=FullMenuId:".") then
UnUsed=Set_Property( FullId, "ENABLED", Enabled )
end
next I
Exit:
return Stat
At 25 SEP 2002 07:56AM Oystein Reigem wrote:
At 25 SEP 2002 07:57AM Oystein Reigem wrote:
Some late changes…
function Set_Menu_ENABLE( MenuId, Enabled )
/*
Author: Oystein
Date: 2002-09-25
MenuId is the id of a menu in the current window (@Window), e.g "FILE" or "EDIT".
it is the short version of the id, not the full id "MYWINDOW.MENU.FILE".
this functions enables or disables that menu and all its items.
Enable tells it to enable (true$) or disable (false$).
the function takes advantage of the hierarchical nature of ids,
and looks for ids with a beginning that matches MenuId.
(but note that MenuId must be complete, e.g, not "FIL" or "FI" instead of "FILE".)
the function should work on sub-items as well, e.g MenuId=VIEW.TOOLS",
but have not been tested on such.
the function is useful because one normally wants all items to be disabled
when one disables the menu. this is not so by default.
even if items don't show and so cannot be clicked
their accelerator keys still work.
return values:
0=OK
1=no entries found in ControlList@. empty window?
2=last entry in ControlList@ is no menu? window has no menus?
3=no menu with id matching MenuId found.
*/
$insert Logical
declare function Set_Property
declare function Get_Property
/* init returned state. 0=OK */
Stat=0
/* prepare some values we need later */
ThisWindowsName=@Window1, "*"
ThisWindowsMainMenuId=ThisWindowsName : ".MENU"
FullMenuId=ThisWindowsMainMenuId : "." : MenuId
/* get menu stuff from window common */
WinID=@Window
$Insert OIWin_Comm_Init
NumCtrls=count(ControlList@, @FM) + (ControlList@ "")
if NumCtrls /* empty window? */
Stat=-1
goto Exit
end
MenuStuff=ControlList@
/* just a check to make certain we got the right stuff */
Test=MenuStuff
if Test=ThisWindowsMainMenuId else
/* window has no menus? */
Stat=-2
goto Exit
end
/* skip header */
for I=1 to 4
MenuStuff=delete(MenuStuff, 1, 1, 0)
next I
/* run through all menus and items
and set the ENABLE property for just the current menu and its items */NumMenusAndItems=count(MenuStuff, @VM) + 1
Found=false$
for I=1 to NumMenusAndItems
FullId=MenuStuff
if (FullId=FullMenuId) or (FullId1, len(FullMenuId)+1=FullMenuId:".") then
UnUsed=Set_Property( FullId, "ENABLED", Enabled )
Found=true$
end
next I
if not(Found) then
/* no menu with that id found */
Stat=-3
goto Exit
end
Exit:
return Stat
At 25 SEP 2002 10:47AM Oystein Reigem wrote:
Turned out my func didn't handle windows with more than one instance. This version does. (I was aware of the problem earlier but my solution was all wrong.)
- Oystein -
function Set_Menu_ENABLE( MenuId, Enabled )
/*
Author: Oystein
Date: 2002-09-25
MenuId is the id of a menu in the current window (@Window), e.g "FILE" or "EDIT".
it is the short version of the id, not the full id "MYWINDOW.MENU.FILE".
this functions enables or disables that menu and all its items.
Enable tells it to enable (true$) or disable (false$).
the function takes advantage of the hierarchical nature of ids,
and looks for ids with a beginning that matches MenuId.
(but note that MenuId must be complete, e.g, not "FIL" or "FI" instead of "FILE".)
the function should work on sub-items as well, e.g MenuId=VIEW.TOOLS",
but have not been tested on such.
the function works on windows with more than one instance.
the function is useful because one normally wants all items to be disabled
when one disables the menu. this is not so by default.
even if items don't show and so cannot be clicked
their accelerator keys still work.
return values:
0=OK
1=no entries found in ControlList@. empty window?
2=last entry in ControlList@ is no menu? window has no menus?
3=no menu with id matching MenuId found.
*/
$insert Logical
declare function Set_Property
declare function Get_Property
/* init returned state. 0=OK */
Stat=0
/* prepare some values we need later.
some with and some without instance number */WinName=@Window1, "*"
ThisWindowsMainMenuId_Inst =@Window : ".MENU"
ThisWindowsMainMenuId_NoInst=WinName : ".MENU"
FullMenuId_Inst =ThisWindowsMainMenuId_Inst : "." : MenuId
FullMenuId_NoInst=ThisWindowsMainMenuId_NoInst : "." : MenuId
/* get menu stuff from window common */
WinID=@Window
$Insert OIWin_Comm_Init
NumCtrls=count(ControlList@, @FM) + (ControlList@ "")
if NumCtrls /* empty window? */
Stat=-1
goto Exit
end
MenuStuff=ControlList@
/* just a check to make certain we got the right stuff */
Test=MenuStuff /* this guy got instance number */
if Test=ThisWindowsMainMenuId_Inst else
/* window has no menus? */
Stat=-2
goto Exit
end
/* skip header */
for I=1 to 4
MenuStuff=delete(MenuStuff, 1, 1, 0)
next I
/* run through all menus and items
and set the ENABLE property for just the current menu and its items */NumMenusAndItems=count(MenuStuff, @VM) + 1
Found=false$
for I=1 to NumMenusAndItems
FullId_NoInst=MenuStuff /* this stuff haven't got instance number */
FullId_Inst=FullId_NoInst; swap WinName with @Window in FullId_Inst
if (FullId_NoInst=FullMenuId_NoInst) or (FullId_NoInst1, len(FullMenuId_NoInst)+1=FullMenuId_NoInst:".") then
UnUsed=Set_Property( FullId_Inst, "ENABLED", Enabled )
Found=true$
end
next I
if not(Found) then
/* no menu with that id found */
Stat=-3
goto Exit
end
Exit:
return Stat
At 25 SEP 2002 02:38PM Ray Chan wrote:
Oystein,
Jeezz, wish you would thoroughly test your code before posting.
It takes a lot of work to cut and paste, cut and paste, and cut and paste. I wearing out my mouse.
Don't have an immediate use for such code, but I will cut and paste and store it away for future reference.
Hey thanks for the snippet.
Well must get back to my simple coding, one line at a time…
Ray
At 05 DEC 2002 06:40AM Oystein Reigem wrote:
function Set_Menu_ENABLE( MenuId, Enable )
/*
Author: Oystein
Date: 2002-09-25, 2002-12-05
MenuId is the id of a menu in the current window (@Window), e.g "FILE" or "EDIT".
it is the short version of the id,
e.g "FILE", and not the full id "MYWINDOW.MENU.FILE".
this functions enables or disables that menu and all its items.
disabling the menu is not always enough to disable the menu's items.
the items' accelerator keys will still work even if the menu is disabled.
Enable tells it to enable (true$) or disable (false$).
some extra coding (2002-12-05) was necessary to thoroughly silence
accelerator keys that are used in more than one menu
(e.g Ctrl+S used for both File | Save Row and Search | Execute).
thanks to Sprezzatura for advice on setting the ACCELERATOR property to 0.
when the ACCELERATOR of the disabled item is not set to 0
it keeps the accelerator of the enabled item from working.
(also some coding (2002-12-05) was necessary to save away
the accelerator values while they are silenced.
they are stored in user defined properties named after the item id.)
the function takes advantage of the hierarchical nature of ids,
and looks for ids with a beginning that matches MenuId.
(but note that MenuId must be complete,
e.g, "FILE" will work but not "FIL" or "FI".)
the function should work on sub-menus as well, e.g MenuId=VIEW.TOOLS",
but have not been tested on such.
the function works on windows with more than one instance.
the function is useful because one normally wants all items to be disabled
when one disables the menu. this is not so by default.
even if items don't show and so cannot be clicked
their accelerator keys still work.
return values:
0=OK
1=no entries found in ControlList@. empty window?
2=last entry in ControlList@ is no menu? window has no menus?
3=no menu with id matching MenuId found.
*/
$insert Logical
declare function Set_Property
declare function Get_Property
/* init returned state. 0=OK */
Stat=0
/* prepare some values we need later.
some with and some without window instance number */WinName=@Window1, "*"
ThisWindowsMainMenuId_Inst =@Window : ".MENU"
ThisWindowsMainMenuId_NoInst=WinName : ".MENU"
FullMenuId_Inst =ThisWindowsMainMenuId_Inst : "." : MenuId
FullMenuId_NoInst=ThisWindowsMainMenuId_NoInst : "." : MenuId
/* get menu stuff from window common */
WinID=@Window
$Insert OIWin_Comm_Init
NumCtrls=count(ControlList@, @FM) + (ControlList@ "")
if NumCtrls /* empty window? */
Stat=-1
goto Exit
end
MenuStuff=ControlList@
/* just a check to make certain we got the right stuff */
Test=MenuStuff /* this guy got a window instance number */
if Test=ThisWindowsMainMenuId_Inst else
/* window has no menus? */
Stat=-2
goto Exit
end
/* skip header */
for I=1 to 4
MenuStuff=delete(MenuStuff, 1, 1, 0)
next I
/* run through all menus and items
and set the ENABLE property for just the current menu and its items */NumMenusAndItems=count(MenuStuff, @VM) + 1
Found=false$
for I=1 to NumMenusAndItems
FullId_NoInst=MenuStuff /* this stuff hasn't got any window instance number */
FullId_Inst=FullId_NoInst; swap WinName with @Window in FullId_Inst
if (FullId_NoInst=FullMenuId_NoInst) or (FullId_NoInst1, len(FullMenuId_NoInst)+1=FullMenuId_NoInst:".") then
/* make a property name Prop out of menu item id FullId_NoInst.
e.g, "MYWIN.MENU.FILE.SAVE_ROW" will become "@MENU__FILE__SAVE_ROW" */Prop=field( FullId_NoInst, ".", 2, 999 )
swap "." with "__" in Prop
Prop=@" : Prop
/* enable/disable the item */
UnUsed=Set_Property( FullId_Inst, "ENABLED", Enable )
if Enable then /* enabling time */
/* check if we have an accelerator value saved away */
Acc=Get_Property( @Window, Prop )
if Acc then
/* yes, we have. restore from that value */
UnUsed=Set_Property( FullId_Inst, "ACCELERATOR", Acc )
end
end else /* disabling time */
/* get the accelerator value and save it away */
Acc=Get_Property( FullId_Inst, "ACCELERATOR" )
begin case
case Acc="
/* this item never had any accelerator */
null
case Acc=0
/* there is no accelerator for this item,
or the accelerator has already been silencedbecause disabling has been run twice in a row */null
case true$
/* this item has a "live" accelerator.
save it away */UnUsed=Set_Property( @Window, Prop, Acc )
/* thoroughly silence the accelerator */
UnUsed=Set_Property( FullId_Inst, "ACCELERATOR", 0 )
end case
end
Found=true$
end
next I
if not(Found) then
/* no menu with that id found */
Stat=-3
goto Exit
end
Exit:
return Stat