Sign in to follow this  
Followers 0
kalayaan

Tab Key To Cycle Focus

18 posts in this topic

How does one set a gui so that focus on the controls can be cycled by pressing the tab key?

Many thanks.

Share this post


Link to post
Share on other sites



How does one set a gui so that focus on the controls can be cycled by pressing the tab key?

Many thanks.

by default the control are created with WS_TABSTOP so it should work with the exception for edit control. :D

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

JP, have you use looked GuiMsg(0) thing yet which seems to stop tab and accelerators working?

No,

I can imagine but I am not for sure I can have a solution.

have you a small repro script I can look at. :D

If guiMsg() work I think we better stay.

The pump mecanism can be too hard to have every thing working as window. we will see.

Edited by jpm

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Opt("GuiNotifyMode", 1)
GuiCreate ("Hello World"); start the definition

GuiSetControl ("label", 'Name?', 10,10); add prompt info
$nOk    = GUISetControl ("button", "&OK", 20,70); add the button that will close the GUI
$nInput = GuiSetControl ("input", "", 10,30,200); add the input area

GuiShow()

While WinExists("Hello World")
  $msg = GuiMsg(0)
  If $msg = -3 Then
      GuiDelete(); Force exit from While loop
  ElseIf $msg = $nOk Then
      $input = GuiRead ($nInput); get the type value
      GuiDelete(); Force exit from While loop
      msgbox(0,"Greeting","Hello " & $input)
  EndIf
Wend

Note: I just cut and pasted this code as I am still a GUI learner.

Edited by Jon

Share this post


Link to post
Share on other sites

I looked at the code, GuiMsg(0) seems to end up calling Getmsg() in the guibox.cpp

You may be able to have a peekmessage/dispatchmessage/isdialogmessage section in there (similar to the AutoIt3 message pump that doesn't block execution if there are no messages waiting) so that any waiting messages are processed before returning.

I can have a play tonight, but I'm a bit busy at work today...

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

GuiMsg(0) thing yet which seems to stop tab and accelerators working

Thanks Jon, for pointing that out. :D As usual I'm late in hearing this. :huh2: I use CyberSlug's AutoBuilder in all my GUIs as it makes building them really easy so I thought that tab don't work (AutoBuilder codes the GUI with GuiMsg(0). No complaints though. :) I'll just adjust the code.

Looking forward to the fix :lol: . Thanks

Edited by kalayaan

Share this post


Link to post
Share on other sites

Opt("GuiNotifyMode", 1)
GuiCreate ("Hello World"); start the definition

GuiSetControl ("label", 'Name?', 10,10); add prompt info
$nOk    = GUISetControl ("button", "&OK", 20,70); add the button that will close the GUI
$nInput = GuiSetControl ("input", "", 10,30,200); add the input area

GuiShow()

While WinExists("Hello World")
  $msg = GuiMsg(0)
  If $msg = -3 Then
      GuiDelete(); Force exit from While loop
  ElseIf $msg = $nOk Then
      $input = GuiRead ($nInput); get the type value
      GuiDelete(); Force exit from While loop
      msgbox(0,"Greeting","Hello " & $input)
  EndIf
Wend

Note: I just cut and pasted this code as I am still a GUI learner.

I see.

I don't know if it there is a solution with the implementation I did.

When you use GuiMsg(0) you never go thru the Getmessage loop inside Execute() which take care of the message translation.

I am not sure that all interaction cannot be handled with a GuiMsg() which go thru the translation. It is true in this case you cannot manage the system menu transition as minimize/restore/maximise.

Perhaps I should change this very special handling of GuiMsg(0) to another function documenting the no translation case /no accelerator case

Any thought :D

Share this post


Link to post
Share on other sites

JP, GuiMsg(0) is used more than any other method for GuiMsg, so please make it the one that is fully functional.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

JP, GuiMsg(0) is used more than any other method for GuiMsg, so please make it the one that is fully functional.

I can't :D

I really need new idea to change the way guimsg(0) can work with translation/acceleration

Edited by jpm

Share this post


Link to post
Share on other sites

Can't you just call TranslateMessage() immediately after calling GetMessage()?

Share this post


Link to post
Share on other sites

Can't you just call TranslateMessage() immediately after calling GetMessage()?

There is no Getmessage at least the one I use for GUI. :D

Have a look at the code at point out where I can improve the situation

Thanks

Share this post


Link to post
Share on other sites

I'll have a play tonight.

is it Marseille

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

In script.cpp ( Execute() ) change:

TranslateMessage(&msg);
    DispatchMessage(&msg);

to:

// Dispatch the message - check for special dialog/GUI related messages first!
    if (g_oGUI.m_hWndGUI == NULL || (g_oGUI.m_hWndGUI != NULL && !IsDialogMessage(g_oGUI.m_hWndGUI, &msg) ) )
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }

Also, looking at your own messagepump code which contains checks for the active window....not sure why but I'll check that too.

Edited by Jon

Share this post


Link to post
Share on other sites

He got the message pump from me, which came from BCX code. The evolution/history of the BCX message pump I do not know.

Lar.

Yeh , almost everything come from AU3GUI.

I don't remember why I implement GuiMsg(0) but I should have break my leg.

Now It is difficult to to the same as GuiMsg() does with the GetMessage/translate/dispatch

:D

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

Ok,

For those who care this is what happens:

You use GetMessage/PeekMessage with the handle of the window (automatically includes child windows) you want to check messages of. If you use NULL as the window handle (as we do in the main AU3 pump) then you get the messages for all the windows associated with the main thread.

Then you call translatemessage() that checks if it is a keyboard related message and messes around converting VK codes into something usable.

Then you call dispatchmessage() to send it on its merry way.

But, dialogs are funny creatures...when you press tab or mess with other keys you want the focus to change. IsDialogMessage() handles this for us. It checks if the message is a dialog related key message, if it is it does its own special Translatemessage()/DispatchMessage() for us and handles the focus/grouping. If IsDialogMessage is successful then you DONT use the normal translate/dispatch.

The code above works because the GUI is a child of the main autot window and therefore when we are doing a GuiMsg(0) the main autoit pump is executed. When we do GuiMsg() then the code inside the guibox.cpp runs instead (althought I'm still trying to think if that works correctly for all situations - i.e. AutoIt being forced to terminate by a winclose type command).

Edited by Jon

Share this post


Link to post
Share on other sites

Ok,

For those who care this is what happens:

You use GetMessage/PeekMessage with the handle of the window (automatically includes child windows) you want to check messages of.  If you use NULL as the window handle (as we do in the main AU3 pump) then you get the messages for all the windows associated with the main thread.

Then you call translatemessage() that checks if it is a keyboard related message and messes around converting VK codes into something usable.

Then you call dispatchmessage() to send it on its merry way.

But, dialogs are funny creatures...when you press tab or mess with other keys you want the focus to change.  IsDialogMessage() handles this for us.  It checks if the message is a dialog related key message, if it is it does its own special Translatemessage()/DispatchMessage() for us and handles the focus/grouping.  If IsDialogMessage is successful then you DONT use the normal translate/dispatch.

The code above works because the GUI is a child of the main autot window and therefore when we are doing a GuiMsg(0) the main autoit pump is executed.  When we do GuiMsg() then the code inside the guibox.cpp runs instead (althought I'm still trying to think if that works correctly for all situations - i.e. AutoIt being forced to terminate by a winclose type command).

Very good,

that make the pumper more happy.

If they misinterpret a message they will stay in their while loop. They can stop the script with the AutoIt systray icon.

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