Page 1 of 1
A window can be opened unlimited times by hotkeys
Posted: Wed Jun 29, 2016 2:31 pm
by zolifree
Hi Roger!
My program is used by many customers, and the program sends error log to me over interet.
I saw a lot of unexplainable error messages logged, that I was never able to reproduce until now.
The problem is that if I have a window which has hotkey like pusbuttons, and if I open a subwindow over this window I can use the hotkey of the window below the active window.
And I can use it unlimited times. It is possible to open a subwindows as many times as You want be pressing a hotkey opening that window.
In my programs there are hundreds of windows with more than 10 hotyes in each of them, and many opens a subwindow.
I never tried to use a hotkey twice, or use a hotkey which is on the window that is not active.
But it seems customers do this many times.
So it is a very serious problem for me, and I was not able to find a way to stop this.
I using the latest express++ and xbase++ but I tried with 1.9 alaska and older express, and each has this problem.
This is a test program:
FUNCTION Main()
LOCAL GetList[0], wget:=space(20),wget2:=space(20)
@0,0 DCPUSHBUTTON CAPTION "&Test" ;
SIZE 10,1 ;
ACTION {||test()}
@2,0 dcsay "Get1:" get wget
@3,0 dcsay "Get2:" get wget2
DCREAD GUI FIT ADDBUTTONS TITLE 'Main';
EVAL {|o|SetAppWindow(o)}
RETURN nil
function test()
LOCAL GetList[0], wg:=space(10)
@0,0 dcsay "Alt+T will open this windows again :" get wg saysize 0
DCREAD GUI FIT ADDBUTTONS TITLE 'Test';
EVAL {|o|dc_centerobject(o,SetAppWindow(o))} ;
MODAL to wlok addbuttons
RETURN nil
If you press Alt+T on the main window it opens a new over it, and in that subwindow you can press the Alt+T again in the get object, and it opens the window again and again.
Best regards,
Zoltan
Re: A window can be opened unlimited times by hotkeys
Posted: Wed Jun 29, 2016 3:42 pm
by rdonnay
I am surprised that nobody has reported this problem before now.
Many years ago, when I first started with Xbase++, Alaska Software recommended that hot-keys on pushbuttons should be marked with an ampersand & and that the function SetAppEvent() should be used to cause the action. eXpress++ uses SetAppEvent() whenever an ampersand is in the caption of a pushbutton.
Unfortunately, spawned windows in the same thread will respond to the same hot-key.
To suppress this behavior, I recommend using the tilde ~ to underline the character and the ACCELKEY clause of the DCPUSHBUTTON command to force the action. This will make the Alt-T action local only to the GUI window where it is declared.
Code: Select all
Change this:
@0,0 DCPUSHBUTTON CAPTION "&Test" ;
SIZE 10,1 ;
ACTION {||test()}
to this:
#include "appevent.ch"
@0,0 DCPUSHBUTTON CAPTION "~Test" ;
SIZE 10,1 ;
ACTION {||test()} ;
ACCELKEY xbeK_ALT_T
Re: A window can be opened unlimited times by hotkeys
Posted: Thu Jun 30, 2016 7:32 am
by rdonnay
I have corrected this problem in eXpress++.
If you make the below code changes, you will not need to make any changes to your source code.
These changes are made in \exp20\source\dclipx\_DCXBUTT.PRG.
Replace the methods
DC_XbpPushButton:SetShortCut() and
DC_XbpPushButtonXP:SetShortCut()
with the below code:
Run BUILD20.BAT or BUILD19_SL1.BAT to rebuild DCLIPX.DLL.
This change will be in build 265.
Code: Select all
METHOD DC_XbpPushButton:SetShortCut()
IF ( ::nShortCut := ::GetShortCut()) != NIL
::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] := ::nShortCut
ENDIF
METHOD DC_XbpPushButtonXP:SetShortCut()
IF ( ::nShortCut := ::GetShortCut()) != NIL
::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] := ::nShortCut
ENDIF
Re: A window can be opened unlimited times by hotkeys
Posted: Thu Jun 30, 2016 4:24 pm
by zolifree
One little change needed.
I use 2 hotkeys with buttons many times like this:
Code: Select all
@0, 0 DCPUSHBUTTONXP CAPTION tny("&Bizonylat") ;
SIZE 10,1 ;
ACCELKEY xbeK_F2 ;
ACTION {||f_tartalom()}
Now the ACCELKEY hotkey is not working, only the Alt+& letter with the modification that You sent.
I know I can use an array with hotkeys at ACCELKEY, but if it is possible to solve it without code change, would be the perfect solution. I think I have more than 1000 buttons that has this problem, so it is a long time to manually correct each.
I tried this, but it is generating errors:
Code: Select all
IF ( ::nShortCut := ::GetShortCut()) != NIL
if ::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] = NIL
::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] := ::nShortCut
else
private wuto:={}
aadd(wuto,::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY])
aadd(wuto,::nShortCut)
::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] := wuto
endif
ENDIF
Re: A window can be opened unlimited times by hotkeys
Posted: Thu Jun 30, 2016 6:04 pm
by rdonnay
This will work:
Code: Select all
METHOD DC_XbpPushButtonXP:SetShortCut()
LOCAL xAccelKey := ::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY]
::nShortCut := ::GetShortCut()
IF Valtype(::nShortCut) == 'N'
IF Valtype(xAccelKey) == 'N'
::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] := { xAccelKey, ::nShortCut }
ELSEIF Valtype(xAccelKey) == 'A'
AAdd( xAccelKey, ::nShortCut )
ELSEIF Valtype(xAccelKey) == 'U'
::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] := ::nShortCut
ENDIF
ENDIF
RETURN self
Re: A window can be opened unlimited times by hotkeys
Posted: Thu Jun 30, 2016 7:22 pm
by zolifree
Thanks Roger, it is perfect!
Re: A window can be opened unlimited times by hotkeys
Posted: Fri Jul 01, 2016 2:03 am
by hz_scotty
is this the same code for "METHOD DC_XbpPushButton" ?
Re: A window can be opened unlimited times by hotkeys
Posted: Fri Jul 01, 2016 7:08 am
by rdonnay
is this the same code for "METHOD DC_XbpPushButton" ?
YES !!!!
Re: A window can be opened unlimited times by hotkeys
Posted: Sat Jul 02, 2016 5:28 pm
by zolifree
Roger,
there is one more thing need to be fixed:
Now the Alt+O hotkey does not working for the Ok button, when I use the addbuttons.
The customers want this function back.
I had this problem before, and You solved that, but with this fix for the hotkeys bring this problem back.
Re: A window can be opened unlimited times by hotkeys
Posted: Thu Jul 07, 2016 1:34 pm
by zolifree
Roger,
this works well:
Code: Select all
METHOD DC_XbpPushButtonXP:SetShortCut()
LOCAL xAccelKey := ::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY]
::nShortCut := ::GetShortCut()
if Valtype(::caption) == 'C'.and. ::caption="&Ok".and.::nShortCut != NIL
::oldShortCut := SetAppEvent( ::nShortCut, { | uNil1, uNil2, o| ;
IIF(::isVisible(),(SetAppFocus(self), ;
PostAppEvent( xbeP_Activate,,, self)),nil)})
RETURN self
endif
IF Valtype(::nShortCut) == 'N'
IF Valtype(xAccelKey) == 'N'
::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] := { xAccelKey, ::nShortCut }
ELSEIF Valtype(xAccelKey) == 'A'
AAdd( xAccelKey, ::nShortCut )
ELSEIF Valtype(xAccelKey) == 'U'
::getList:getListArray[::getListPointer,nGETLIST_ACCELKEY] := ::nShortCut
ENDIF
ENDIF
RETURN self
Please put it in _dcxbutt.prg
METHOD DC_XbpPushButton:SetShortCut() is the same.