Sign in to follow this  
Followers 0
Jon

GUI Default Button

13 posts in this topic

Ok, in a standard dialog if you press ENTER while a button has focus then that button is "clicked" - this is the same in AutoIt (in my unstable here, may still be slightly broken in the published version).

When you are on an edit control however and you press ENTER then the gui checks for a button with the BS_DEFPUSHBUTTON style and clicks it. If no button has that style then it sends a msg saying that IDOK was clicked which just _happens_ to have an ID of 1 - if the very first control you create in the gui _is a button_ then this gets clicked and works 99% of the time (actually by accident).

Now, you could manually specify that you want the BS_DEFPUSHBUTTON style when creating the control but from looking at everyones scripts we are all relying on the defaults for the style parameters most of the time. So how shall I fix this:

1. Leave it as is and have to manually specify the DEFPUSHBUTTON style

2. Make the very first button created have the style automatically

3. Add a GuiSetDefaultButton() function

I prefer 3 as it allows you to use defaults for the main part and to create your controls in any order and then being able to easily set the default.

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Edit: Perhaps not "GuiSetDefaultButton()", but "GuiSetDefaultControl()"

I believe it is a button only style, but I guess it may work on other things that pretend to be buttons, if that is the case then just GuiSetDefault() may be OK.

The problem I see with option 2 is that if the first button created was not the one you wanted as default it may get confusing. Of course it may still get confusing if people use the style manually AND called the Default() function too, but hey-ho.

Also, if you create non-button control first and then a button the accidental way usually doesn't work which was very confusing to work out this morning.

Edited by Jon

Share this post


Link to post
Share on other sites

It's like the GodFather giving you a choice and then telling you what you'll choose. Stand by for the "Yes Men"  :huh2:

You mean like in the bitwise operator post? :D

(Sorry, just over using the new emoticon) :)

Share this post


Link to post
Share on other sites

Of course it may still get confusing if people use the style manually AND called the Default() function too, but hey-ho.

Bjarne Stroustrup said about C++ something to the effect that it's a lot harder to shoot yourself in the foot with C++, but when you do, your blow your whole foot off. This would be one of those cases, I think. If you have option 3 and somebody decides they want to do it themself, then they are the one responsible for blowing their foot off, you've done all you could to protect them from themself.

Share this post


Link to post
Share on other sites

Like we always say in cubicle town, GFB rules. Your gun, your foot, your bullet. :D

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

For Dev info:

This turns out to be not so easy. Our window is a "pseudo" dialog and some of the default dialog handling was working, things like tabbing and accelerators - but some things like default button processing wasn't.

Changes I've made:

- When registering the class I've added the style DLGWINDOWEXTRA which allows us to use the DefDlgProc() function in our WndProc rather than DefWindowProc() - The dialog process handles the extra dialog messages we needed (DM_SETDEFID, DM_GETDEFID, WM_NEXTDLGCTRL, etc)

- Added an internal SetFocus() replacement that correctly "highlights" a button if it is set for focus (when you focus a button you get the dotted line inside it, in a dialog it should also be given a heavy border, if the focus is NOT on a button then the default button should be the one with the heavy border)

- Added GuiSetDefButton() to set the default button

Very confusing is the fact that our window was sending IDOK and IDCANCEL messages to itself when the user presses ENTER and ESC - as luck would have it the ID number of these message is 1 and 2 (our first 2 controls!) This meant that a lot of times in a GUI when you pressed ENTER/ESC sometimes they would work depending on the order you set your GUI up. I've changed it so we only use IDs 3 and above which will allow us to handle IDOK and IDCANCEL correctly rather than trusting to luck.

The changes are working really well and when you set a default button it is correctly highlighted when the focus is on something like an edit control and you can press ENTER and the default button is triggered (unless the current focus is already a button in which case that button is triggered).

Just some tweaks and docs to update and I'll upload it.

Edited by Jon

Share this post


Link to post
Share on other sites

@Jon

Great I should have stay a little bit longer in vacation :huh2:

When I come back the gui is really is really improving.

Thanks Jon for doing it :D

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

One last thing, why does GuiMsg() not return -3 when the window is closed? I assumed code like this worked but it didn't because -3 was never returned. I've changed it so that it does now work - if this was done on purpose then let me know.

#include <GUIconstants.au3>

Opt("GUICoordMode", 1)
Opt("GUINotifyMode", 1)
GuiCreate("MyGUI", 392,273,(@DesktopHeight-392)/2, (@DesktopHeight-273)/2 , 0x04CF0000)

$button_1 = GUISetControl("button", "Button 1", 30, 20, 120, 40)

$input_1 = GUISetControl("input", "Input 1", 200, 20, 160, 30)
$input_2 = GUISetControl("input", "Input 2", 200, 70, 160, 30)

GuiShow()

While 1
  $msg = GuiMsg()
  Select
    Case $msg = -3
      MsgBox(0, "", "Window closed / ESC pressed") 
      Exit
    Case $msg = $button_1
      MsgBox(0, "", "Button clicked") 
  EndSelect
WEnd

Edited by Jon

Share this post


Link to post
Share on other sites

I just noticed that GuiSetControlEx() can be used to set control state and give focus - this is probably a better bet for the Default button with a new value of $GUI_DEFBUTTON I think.

Still not 100% on how it all hangs together :D

Share this post


Link to post
Share on other sites

One last thing, why does GuiMsg() not return -3 when the window is closed?  I assumed code like this worked but it didn't because -3 was never returned.  I've changed it so that it does now work - if this was done on purpose then let me know.

#include <GUIconstants.au3>

Opt("GUICoordMode", 1)
Opt("GUINotifyMode", 1)
GuiCreate("MyGUI", 392,273,(@DesktopHeight-392)/2, (@DesktopHeight-273)/2 , 0x04CF0000)

$button_1 = GUISetControl("button", "Button 1", 30, 20, 120, 40)

$input_1 = GUISetControl("input", "Input 1", 200, 20, 160, 30)
$input_2 = GUISetControl("input", "Input 2", 200, 70, 160, 30)

GuiShow()

While 1
  $msg = GuiMsg()
  Select
    Case $msg = -3
      MsgBox(0, "", "Window closed / ESC pressed") 
      Exit
    Case $msg = $button_1
      MsgBox(0, "", "Button clicked") 
  EndSelect
WEnd
It looks to me that the return should be the same as GuiWaitClose() which return 0.

But I don't really care to have -3 as for GuiMsg(0).

I still don't like so much the GuiMsg(0) because do we really need to take action on system menu as minimized/restored/maximized. I did it for Valik. :D

Share this post


Link to post
Share on other sites

I still don't like so much the GuiMsg(0) because do we really need to take action on system menu as minimized/restored/maximized. I did it for Valik. :huh2:

I'm not keen on GuiMsg(0) either... but I actually think that for GuiMsg() we need to be able to respond to any event:

- Controls / Clicked or changed

- Box closed either via ESC / ALT-F4 or close icon

- Maximize and Minimize messages

At the moment the first 2 work OK but you can't react to minimize/maximize using GuiMsg(). We can't change GuiNotifyMode because it is used as a toggle when creating controls not really as a global option, and there are no close/maximize/minimize controls...

Maybe a new option called....GuiSysNotifyMode which toggles if the system menu buttons (close/min/max) trigger an event.

I'll also try and make the code for (0) and () work in the same way - well better than now anyway :D

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

GuiMsg(0) could be made obsolete if:

A) GuiMsg() doesn't block, so you could still use Hotkeys or AdLib while waiting on a GUI msg to come in.

B) GuiMsg() returns at the very least something when close is clicked.

If those two criteria could be added to GuiMsg(), then GuiMsg(0) could be eliminated completely. But as it stands, GuiMsg(0) is the best way to have the most interactive application.

Edited by Valik

Share this post


Link to post
Share on other sites

GuiMsg(0) could be made obsolete if:

A) GuiMsg() doesn't block, so you could still use Hotkeys or AdLib while waiting on a GUI msg to come in.

:D GuiMsg() returns at the very least something when close is clicked.

If those two criteria could be added to GuiMsg(), then GuiMsg(0) could be eliminated completely.  But as it stands, GuiMsg(0) is the best way to have the most interactive application.

Well described Valik. I never thought that the blocking was suppressing the Adlib HotKey. :iamstupid:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0