3

I am working on a Kiosk-type (no mouse, no keyboard) application where users enter data into an Excel spreadsheet. I would like to have the on-screen keyboard appear in the same place every time it gets called. The osk.exe window 'remembers' where it is when it gets closed and will re-appear in the same place the next time it is opened, but after a shutdown the osk returns to its default location and covers up the form.

I need a way to set the position of the osk whenever it is opened. Below is the code I have for opening the osk.

   Dim Shex As Object
   Dim tgtfile As String

   Set Shex = CreateObject("Shell.Application")
   tgtfile = "C:\Windows\System32\osk.exe"
   Shex.Open (tgtfile)

I'm wondering if there is something like Shex.Top = 250, or something like that.

Thanks!

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
jbdille
  • 35
  • 3

1 Answers1

3

Unfortunately SetWindowPos API with FindWindow API doesn't work for OSKMainClass("On-Screen Keyboard") I tried various combinations but it kept on failing. Seems like it is not treated as a normal window.

Note: Tested the code in Excel 2010 (32 bit), Windows 8.1 64 Bit (Touch Screen if it matters?)

This is the code that I tried. (THIS DOESN'T WORK)

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _
ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Public Const SWP_NOSIZE = &H1
Public Const HWND_TOPMOST = -1

Sub Sample()
    Dim Ret As Long, retval As Long
    Dim Shex As Object

    Set Shex = CreateObject("Shell.Application")
    Shex.Open ("C:\Windows\System32\osk.exe")

    Wait 1

    Ret = FindWindow("OSKMainClass", "On-Screen Keyboard")

    If Ret <> 0 Then
        'Msgbox "On-Screen Keyboard Window Found"
        retval = SetWindowPos(Ret, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE)
        DoEvents

        If retval = False Then MsgBox "Unable to move Window"
    End If
End Sub

Private Sub Wait(ByVal nSec As Long)
    nSec = nSec + Timer
    While nSec > Timer
        DoEvents
    Wend
End Sub

Here is another way to achieve what you want. I am simulating the mouse click to do the job. (THIS WORKS)

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function SetCursorPos Lib "user32" _
(ByVal X As Integer, ByVal Y As Integer) As Long

Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

Private Declare Function GetWindowRect Lib "user32" _
(ByVal hwnd As Long, lpRect As RECT) As Long

Private Declare Sub mouse_event Lib "user32.dll" (ByVal dwFlags As Long, _
ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)

Private Const MOUSEEVENTF_MOVE = &H1          ' mouse move
Private Const MOUSEEVENTF_LEFTDOWN = &H2      ' left button down
Private Const MOUSEEVENTF_LEFTUP = &H4        ' left button up
Private Const MOUSEEVENTF_ABSOLUTE = &H8000   ' absolute move

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Dim pos As RECT


Sub Sample()
    Dim Ret As Long, retval As Long
    Dim Shex As Object

    Set Shex = CreateObject("Shell.Application")
    Shex.Open ("C:\Windows\System32\osk.exe")

    Wait 1

    Ret = FindWindow("OSKMainClass", "On-Screen Keyboard")

    If Ret <> 0 Then
        GetWindowRect Ret, pos

        '~~> Get the co-ordinates of some point in titlebar
        cur_x = pos.Left + 10
        cur_y = pos.Top + 10

        '~~> New Destination (Top Left Corner of Desktop)
        dest_x = 0
        dest_y = 0

        '~~> Move the cursor to a place in titlebar
        SetCursorPos cur_x, cur_y
        Wait 1 '<~~ Wait 1 second

        '~~> Press the left mouse button on the Title Bar
        mouse_event MOUSEEVENTF_LEFTDOWN, cur_x, cur_y, 0, 0

        '~> Set the new destination. Take cursor there
        SetCursorPos dest_x, dest_y

        '~~> Press the left mouse button again to release it
        mouse_event MOUSEEVENTF_LEFTUP, dest_x, dest_y, 0, 0
        Wait 1

        MsgBox "done"

    End If
End Sub

Private Sub Wait(ByVal nSec As Long)
    nSec = nSec + Timer
    While nSec > Timer
        DoEvents
    Wend
End Sub
Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250