Antonio: ALT accelerator with button - Urgent help needed

Antonio: ALT accelerator with button - Urgent help needed

Postby Colin Wisbey » Wed Aug 13, 2008 7:56 am

FUNCTION TESTALT
// Indicates differences between results when clicking a button
// compared to instead using ALT accelerator for the button.
// Example 1. BUTTON'S ACTION DOESN'T FURTHER CHANGE THE FOCUS:
// If ALT accelerator is pressed for a button when the current focus
// is on a GET which has a valid, focus returns to the control (in
// this case a GET) that had focus before the button's action was
// executed - and the valid is executed twice.
// If instead the button is clicked, focus remains on the BUTTON after
// the button's action is executed - and the valid hass executed just
// once.
//
// 2. BUTTON'S ACTION DOES FURTHER CHANGE THE FOCUS:
// If ALT accelerator is pressed for a button when the current focus
// is on a GET which has a valid, focus returns to the control (in
// this case a GET) that had focus before the button's action was
// executed - and the valid is not executed until AFTER the button's
// ACTION.
// If instead the button is clicked, focus remains on the BUTTON after
// the button's action is executed - and the valid is executed BEFORE
// the button's ACTION.

//--------------------------------------------
#include 'Fivewin.ch'

LOCAL oDlg
LOCAL oGet1, oGet2, oGet3, oBtn
LOCAL cVar1 := 'ABCDEF '
LOCAL cVar2 := SPACE(8)
LOCAL cVar3 := SPACE(8)

DEFINE DIALOG oDlg FROM 0, 0 TO 10, 30 ;
TITLE 'Test Alt / Button / GET_VALID'

@ 1, 1 GET oGet1 VAR cVar1 SIZE 30,12 PIXEL ;
Valid (MSGBEEP(), .T. )

@ 2, 1 GET oGet2 VAR cVar2 SIZE 30,12

@ 3, 1 GET oGet3 VAR cVar3 SIZE 30,12

// Example 1: ACTION doesn't try to further change focus:
@ 40,50 BUTTON oBtn PROMPT '&Test' ;
SIZE 30, 20 PIXEL ;
ACTION (SYSWAIT(1), ( cVar2 := cVar1 ), oGet2:Refresh())

// Example 2: Next ACTION does try to further change focus.
// Uncomment to see the difference:
/*
@ 40,50 BUTTON oBtn PROMPT '&Test' ;
SIZE 30, 20 PIXEL ;
ACTION MsgInfo('This is a test')
*/

ACTIVATE DIALOG oDlg CENTER

return NIL
//-------------------------------------------------

Hope you can help fix if a bug, or tell me what I need to do.

Thanks,
Colin Wisbey
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Postby Antonio Linares » Wed Aug 13, 2008 8:41 am

Colin,

We are already reviewing your example to provide you an answer as soon as possible
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Wed Aug 13, 2008 9:01 am

Colin,

If you modify your code this way, then there is no difference between using the mouse to click on the button or using the accelerator. Please review the generated .TXT files contents:
Code: Select all  Expand view
@ 1, 1 GET oGet1 VAR cVar1 SIZE 30,12 PIXEL ;
   VALID ( LogFile( "valid.txt", { "valid" } ), .T. )
...

@ 40,50 BUTTON oBtn PROMPT '&Test' ;
SIZE 30, 20 PIXEL ;
ACTION ( LogFile( "action.txt", { "action" } ), ( cVar2 := cVar1 ), oGet2:Refresh() )

Please don't use MsgInfo() as it changes the focus sequence.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Wed Aug 13, 2008 9:09 am

This code seems to be fine also. Please check the contents of the generated TXT files. Even using MsgInfo():
Code: Select all  Expand view
@ 1, 1 GET oGet1 VAR cVar1 SIZE 30,12 PIXEL ;
Valid ( LogFile( "valid.txt", { "valid" } ), .T. )

...

@ 40,50 BUTTON oBtn PROMPT '&Test' ;
SIZE 30, 20 PIXEL ;
ACTION ( LogFile( "action.txt", { "action" } ), MsgInfo( "action" ) )

Tested with Harbour and FWH 8.07
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Wed Aug 13, 2008 9:10 am

Same behaviors with xHarbour and FWH 8.07
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Colin Wisbey » Wed Aug 13, 2008 10:52 am

Thanks for prompt reply, Antonio, but it doesn't address either of the 2 problems.

Please try the following with my original example #1:

Step 1: Place cursor in oGet1.
Step 2: Action the button by using ALT A. Notice that focus is still on oGet1. When done, click on another get. The VALID (which you can hear from the Msgbeep()) gets evaluated twice.

Step 3: Place cursor in oGet1 again.
Step 2: Action the button by clicking the button. Notice that focus is now on the button, not on oGet1. When done, click on another get. The VALID (which you can hear from the Msgbeep()) got evaluated prior (and only) prior) to the button click, which is how I want a button to be actioned.

For problem 2, try the above with my original example #2.

The example I posted is an artificial example to demonstrate the problem. In my real apps, the equivalent of my oGet1 VALID is vital in both it needing to be executed only once and before the button's action gets executed. The VALID can't afford to executed twice or only after the button's action.

In short, clicking on the button works the way it always has and works perfectly. However, if we instead action the button by ALT-accelerator, the results are not only different (depending on what the VALID does) but very different in change of focus and when the VALID gets actioned.

It's never previously presented a problem for my users because I haven't offered ALT accelerators with a button until now. Now they are screaming at me due to reproducible errors whenever they use the ALT accelerator.

Incidentally, I used MSGINFO() in my 2nd example as it represents the equivalent of real-world actions of my buttons. e.g. The real-world dialog represents a docket (invoice) and one of the buttons calls up the image of the docket (obviously changing focus in the process, as does Msginfo()). The VALID on the GET does the equivalent of incrementing a base number so I can't afford it to be actioned twice.

As I said, clicking on a button works fine. The problem is with actioning the button by ALT accelerator.

Hope that explains my problems better than my original post did.

Thanks again. Hope you can help.
Col
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Postby Colin Wisbey » Wed Aug 13, 2008 11:16 am

Oops!. I referred to "ALT A".

I meant "ALT T" of course.
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Postby Antonio Linares » Wed Aug 13, 2008 3:06 pm

Colin,

When you press a button accelerator, the focus is not changed to the button. Just its action is fired. A workaround for this:

Code: Select all  Expand view
@ 1, 1 GET oGet1 VAR cVar1 SIZE 30,12 PIXEL ;
Valid ( MsgBeep(), .T. )

...

@ 40,50 BUTTON oBtn PROMPT '&Test' ;
SIZE 30, 20 PIXEL ;
ACTION ( ( cVar2 := cVar1 ), oGet2:Refresh(), oBtn:SetFocus() )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Colin Wisbey » Wed Aug 13, 2008 3:58 pm

>When you press a button accelerator, the focus is not changed to the button. Just its action is fired.

Correct. That's the problem I've been trying to explain.

>A workaround for this
< snip >

Great. That should do it. That solution never crossed my mind (but probably should have, now I've seen how simple it is).

Many thanks, Antonio. I really appreciate such prompt and useful support.

Col
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Postby Colin Wisbey » Thu Aug 14, 2008 2:42 am

Antonio, your suggestion fix doesn't make any difference.

The only difference it makes is that, if using ALT accelerator, focus now finishes up on the button. However, using ALT accelerator, the valid still gets executed as per all the original problems (wrong timing and/or executed twice) in my 2 examples.

Any other thoughts?

From a quick check, it seems Microsoft's apps behave identically regardless of whether button action is initiated by clicking or by ALT accelerator. (i.e. the way clicking on a button in FWH works, the focus automatically finishing on the button control). This is the way FWH should automatically work. Whether clicking on a button or using ALT accelerator, the sequence of actions and end results need to be identical. After all, the ALT accelerator is intended to be merely an alternative equivalent to clicking the button.

(I sincerely appreciate the time you are investing on this problem. The problem poses a potential trap for any developer using ALT accelerators with buttons, especially if VALID clauses are involved.)
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Postby Antonio Linares » Thu Aug 14, 2008 6:41 am

Colin,

What FWH version are you using ?

Here its working fine using FWH 8.07. If you use LogFile() as I shown here then you will see that the VALID is executed just once.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Colin Wisbey » Thu Aug 14, 2008 10:22 am

Antonio, please try this sample. Note that a single Validxxxxx txt file gets created (as it should) if we click the button but two Validxxxxx txt files get created if we use ALT accelerator.

//--------------------------------------

FUNCTION TESTALT

#include 'Fivewin.ch'

LOCAL oDlg
LOCAL oGet1, oGet2, oGet3, oBtn
LOCAL cVar1 := 'ABCDEF '
LOCAL cVar2 := SPACE(8)
LOCAL cVar3 := SPACE(8)

DEFINE DIALOG oDlg FROM 0, 0 TO 10, 30 ;
TITLE 'Test Alt / Button / GET_VALID'

@ 1, 1 GET oGet1 VAR cVar1 SIZE 30,12 PIXEL ;
Valid ( LogFile( "valid" +STR(Seconds(),9,2) +".txt", { "valid" } ), .T. )

@ 2, 1 GET oGet2 VAR cVar2 SIZE 30,12

@ 3, 1 GET oGet3 VAR cVar3 SIZE 30,12

@ 40,50 BUTTON oBtn PROMPT '&Test' ;
SIZE 30, 20 PIXEL ;
ACTION ( ( SYSWAIT(2),;
LogFile( "action" +STR(Seconds(),9,2) +".txt", { "action" } ),;
oBtn:SetFocus() ) )

ACTIVATE DIALOG oDlg CENTER

return NIL
//----------------------------------

FWH 8.06

Thanks
Col
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Postby Antonio Linares » Thu Aug 14, 2008 10:20 pm

Colin,

Many thanks for your example. Yes, you were right and there was a problem that was firing twice the focus, when Alt + acc was pressed.

This change is required in Class TButton:
Code: Select all  Expand view
METHOD Click() CLASS TButton

   if ! ::lProcessing
   
      ::lProcessing = .t.
     
      if ::bWhen != nil .and. ! Eval( ::bWhen )
         ::lProcessing = .f.
         return nil
      endif   

      ::oWnd:lValidating = .T.
      if GetFocus() != ::hWnd
         SetFocus( ::hWnd )
      endif

      if ::bAction != nil
         Eval( ::bAction )
      endif

      if ! ::lCancel .and. ::oWnd:hWnd != 0
         Super:Click()
      endif               

      if ( GetFocus() == ::hWnd )
         ::PostMsg( BM_SETSTYLE, BS_DEFPUSHBUTTON, 1 )
      else
         if ! ::lDefault
            ::PostMsg( BM_SETSTYLE, BS_PUSHBUTTON, 1 )
         endif
      endif

      ::lProcessing = .f.
   endif

return nil

With such change, this test is properly working here:
Code: Select all  Expand view
#include 'Fivewin.ch'

function Main()

LOCAL oDlg
LOCAL oGet1, oGet2, oGet3, oBtn
LOCAL cVar1 := 'ABCDEF '
LOCAL cVar2 := SPACE( 8 )
LOCAL cVar3 := SPACE( 8 )

DEFINE DIALOG oDlg FROM 0, 0 TO 10, 30 ;
TITLE 'Test Alt / Button / GET_VALID'

@ 1, 1 GET oGet1 VAR cVar1 SIZE 30,12 PIXEL ;
Valid ( LogFile( "valid" + AllTrim( Str( GetTickCount() ) ) + ".txt", { "valid" } ), .T. )

@ 2, 1 GET oGet2 VAR cVar2 SIZE 30,12

@ 3, 1 GET oGet3 VAR cVar3 SIZE 30,12

@ 40,50 BUTTON oBtn PROMPT '&Test' ;
SIZE 30, 20 PIXEL ;
ACTION ( LogFile( "action" + AllTrim( Str( GetTickCount() ) )  + ".txt", { "action", GetClassName( GetFocus() ) } ) )

ACTIVATE DIALOG oDlg CENTER

return NIL

Please test it and let us know your results. Thanks!
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41314
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 64 guests