Jump to content

Need help with creating an On-screen Keyboard


b8bboi
 Share

Recommended Posts

As the title said, I'm trying to create an on-screen keyboard for my touchscreen software.

The easy part is to catch button click events and send keys to other apps. The hard part is how I can prevent the autoit buttons from grabbing the cursor focus away from the other app when they're clicked on.

If you open Windows' osk.exe, you'll see exactly what I mean. Thanks for any input.

Link to comment
Share on other sites

Zedna, thanks for the tips but GetFocus/SetFocus, et al won't work because by the time my OSK button is clicked, the focus already shifts over to Autoit. So, if I do a GetFocus now, it would just return a handle to my Autoit GUI. I hope you can see the dilemma.

Link to comment
Share on other sites

Zedna, thanks for the tips but GetFocus/SetFocus, et al won't work because by the time my OSK button is clicked, the focus already shifts over to Autoit. So, if I do a GetFocus now, it would just return a handle to my Autoit GUI. I hope you can see the dilemma.

From link I gave you above:

When the activation changes from a top-level window of one application to the top-level window of another, the system sends a WM_ACTIVATEAPP message to both applications, notifying them of the change. When the activation changes to a different top-level window in the same application, the system sends both windows a WM_ACTIVATE message.

***

WM_ACTIVATEAPP Notification

The WM_ACTIVATEAPP message is sent when a window belonging to a different application than the active window is about to be activated. The message is sent to the application whose window is being activated and to the application whose window is being deactivated.

A window receives this message through its WindowProc function.

Syntax

WM_ACTIVATEAPP

WPARAM wParam

LPARAM lParam;

Parameters

wParam

Specifies whether the window is being activated or deactivated. This parameter is TRUE if the window is being activated; it is FALSE if the window is being deactivated.

lParam

Specifies a thread identifier (a DWORD). If the wParam parameter is TRUE, lParam is the identifier of the thread that owns the window being deactivated. If wParam is FALSE, lParam is the identifier of the thread that owns the window being activated.

Return Value

If an application processes this message, it should return zero.

So try GUIRegisterMsg & WM_ACTIVATEAPP, in lparam is thread of application being deactivated

I didn't test it, so play with it yourself. It's only ideas.

Link to comment
Share on other sites

Why not just have your keyboard use an event loop, when it doesn't have focus, to keep track of the window and control that had focus before the keyboard had focus? Then you could have the on-screen keyboard send it's output to the last-focused control within it's last-focused window, and you won't have to worry at all about focus.

Link to comment
Share on other sites

How about adding a dialog before it runs, asking what window they are using, and write that data to a variable, then in your OSK, put a WinActivate($variablename) on each button, so when you click it, it activates the window, then sends the key (after adding a small sleep after the winactivate)

Also if you don't, give it an AlwaysOnTop property

Link to comment
Share on other sites

I've found the solution. $WS_EX_NOACTIVATE.

Being as this value isn't defined in AutoIt, what exactly did you do? I tried defining it with Dim Const $WS_EX_NOACTIVATE = 0x8000000 and then adding this in the GUICreate call, but my window still grabbed the focus.

I'd love to know more about your solution!

Link to comment
Share on other sites

Here's a sample.

#include <GUIConstants.au3>

$WS_EX_NOACTIVATE = 0x08000000

Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode


$x = GUICreate("Test OSK", 100, 100, 100, 100, $WS_POPUP, BITOR($WS_EX_NOACTIVATE, $WS_EX_TOPMOST))
$Button_2 = GUICtrlCreateButton ( "Button Test",  0, -1)
GUICtrlSetOnEvent ($Button_2, "OSButtonPressed")
GUISetState(@SW_SHOWNOACTIVATE)
WinSetOnTop($x, "", 1)

                        
While 1       
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
    EndSelect
Wend


Func OSButtonPressed()
    Send("A")
EndFunc
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...