|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Sat Mar 05, 2011 6:29 pm Post subject: Accelerator keys |
|
|
In a fit of enthusiasm, I decided to add some accelerator keys to an existing program. Some hours later, I find myself completely bemused.
When setting up the menu system, I finally puzzled out how it works, and managed to do wonderful things with (for example) PgUp and PgDn.
In common with many other programs, I associated Ctrl+N with File|New, Ctrl+O with File|Open, and Ctrl+S with File|Save. It appears to me that although these sequences are listed in the relevant menus, they don't work. I imagine that Ctrl+ any letter doesn't.
So, Question 1: Am I right that Ctrl+ a letter (like Ctrl+N) only works with %ac, and not with %mn?
In my simplicity, I had assumed that it would, and so when the menu was greyed-out, the accelerator would be disabled too. I think that the answer to Q1 is Yes, and greying-out the menu doesn't disable the accelerator.
It didn't seem so bad, as maybe that is what the %ac format is there for. Hooray! It is. Ctrl+ a letter sequences work as expected. I already knew that there were subroutines ADD_ACCELERATOR@ and REMOVE_ACCELERATOR@. A quick check revealed that they weren't FUNCTIONs (a trap I sometimes fall into) - and that I have INCLUDEd WINDOWS.INS.
Code: | CALL REMOVE_ACCELERATOR@ (MASTER(1), 'Ctrl+N')
CALL REMOVE_ACCELERATOR@ (MASTER(1), 'Ctrl+O') |
MASTER(1) is the handle of my main window.
When it didn't remove the accelerator, I had a quick go with square brackets '[Ctrl+N]', but that's definitely wrong as FTN95 complains.
Question 2: Is it the case that you can only remove an accelerator that is associated with ADD_ACCELERATOR@ ?
If the answer to question 2 is Yes, then clearly the accelerators you need to turn on and off can go in the callback for %sc. However, as ADD_ACCELERATOR@ can't use standard callbacks such as FILE_OPENR this route does have a certain amount of additional coding associated with it that I have yet to attempt.
I found a note that said accelerators should not go in top level menus.
This leads to Question 3: Why not? They seem to work (but only if they are of the form Alt+F4 for Exit and F1 for Help) and other programs use this approach.
I'm using 4.9.0
Eddie
PS it looks like you can add and remove only accelerators added and removed via the suboutine calls. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Mon Mar 07, 2011 3:06 pm Post subject: |
|
|
From memory I would say that the answer to question 1 is to find out how to underline a character (I have just looked it up and you need to use the ampersand character) then you can use Alt+ (the character) as an accelerator. The alternative is to use char(20) followed by the full accelerator key.
The answer to question 2 is probably to try it and see if it works. |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Mon Mar 07, 2011 4:49 pm Post subject: |
|
|
Paul,
As always, you are the fount of knowledge.
I suppose the <Alt+character> sequence isn't needed to be explicitly stated in the menu because the underline-and-ampersand system takes care of it - but it was <Ctrl+letter> I was after. MS applications use it a lot especially in the file menu, and I was after that. If you put Ctrl+character in the %mn, it shows on screen but doesn't get acted on. I puzzled long and hard about that, when MS applications use the convention.
Yep, if an accelerator is added with %ac (or as far as I can see with %mn), it is not removable. You have to add it with ADD_ACCELERATOR@ if you want it removable later. I was right in my supposition - if it is wanted from the initial state of the window, then it is probably best if it goes in the %sc callback. As greying-out has no effect on the associated accelerators, anything that needs to be context-sensitive needs to be in the category of accelerators added and removed. However, since one may want the accelerator description in the menu, it seems to be a design feature that <Ctrl+letter> doesn't actually work in %mn.
I clearly didn't understand what "top level menu" meant - it is the menu name, not the first drop-down list.
Which, after about 20 hours of trying and seeing, are probably the answers to Question 3.
So, for future enquirers after knowledge:
1. Accelerator key chords can be defined in %mn or %ac format codes.
2. Accelerator key chords can also be defined with the ADD_ACCELERATOR@ subroutine call, and this MUST be used if they are to be turned off later under program control using the subroutine REMOVE_ACCELERATOR@.
3. A convenient place for ADD_ACCELERATOR@ calls needed from the outset is in the callback for %sc or %`sc.
4. Key chords of the form <Ctrl+letter> can be put into the %mn format code, but they are merely shown on the menu, and are not enabled - they need to be defined elsewhere: with %ac if they are always available, but with ADD_ACCELERATOR@ if they need to be turned on/off.
5. Accelerators for the menu names always displayed on the menu bar may be set up using & in the name, which makes the following letter a "hot key" when used in the chord with Alt.
6. Accelerator key chords defined by ADD_ACCELERATOR@ can only have user-defined callback functions, standard WINIO@ callbacks can't be used.
... as far as I can discover!
Eddie |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Mon Mar 07, 2011 10:32 pm Post subject: |
|
|
I will aim to check these conclusions later but in the mean time, if you want to disable an accelerator key when the menu item is greyed then all you need to do is use the same control variable for both the greying of the menu item and also to bypass the action of the accelerator key. In other words, in the callback for the accelerator key, use an if-construct based on the state of the grey control variable. |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Tue Mar 08, 2011 11:54 pm Post subject: |
|
|
Paul,
I thought I'd write a demonstration program. Here it is:
Code: | WINAPP
OPTIONS (INTL)
PROGRAM TRY_AND_SEE
COMMON IGREY, IH
EXTERNAL KB1, KB2, KB3
INCLUDE <WINDOWS.INS>
IGREY = 1
IA=WINIO@('%ca[Try and See Accelerators]%hw&',IH)
IA=WINIO@('%mn[~Test[Beep'//CHAR(9)//'Ctrl+B]]&',IGREY,KB1)
IA=WINIO@('%mn[Grey toggle]&',KB2)
IA=WINIO@('%mn[Turn on]',KB3)
END
INTEGER FUNCTION KB1()
INCLUDE <WINDOWS.INS>
COMMON IGREY, IH
CALL BEEP@; KB1=1; RETURN
END
INTEGER FUNCTION KB2()
INCLUDE <WINDOWS.INS>
COMMON IGREY, IH
IGREY = 1-IGREY
IF (IGREY .EQ. 0) CALL REMOVE_ACCELERATOR@(IH, 'Ctrl+B')
KB2=1
RETURN
END
INTEGER FUNCTION KB3()
INCLUDE <WINDOWS.INS>
COMMON IGREY, IH
EXTERNAL KB1
CALL ADD_ACCELERATOR@(IH, 'Ctrl+B', KB1)
KB3=1; RETURN
END |
Drat. It works as I at first thought it should. You can generate a beep with the first menu item, or with Ctrl+B. Grey out the Beep menu, and Ctrl-B is deactivated. This definitely doesn't happen in my 20,000 line program!
So, I just give up at points like this. I haven't discovered the underlying secret, I have just discovered a workaround to a foible of a particular arrangement of code.
Eddie |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|