Windows keyboard on screen -OSK.exe-

Published on by Yousfi Benameur

Updated on jeudi 5 mars 2015; 11:03:27                            

The osk.exe is a windows visual application of  keyboard.
On-Screen Keyboard Portable makes it easy to access Windows' built-in On-Screen Keyboard on any system you come across. (and any language set on system).
Give the focus to the editbox area (click on) and stroke keys from osk.Any stroke àon osk,is replicated on editbox simultaneously.
can resize, move, maximize ,minimize the form.

The function setParent API dont work on new osk (in my Win8.1)
(maybe MS have changed the osk behavior to be a child window on  form surface).
Its indeed becomes alwaysontop app.It cannot be installed as child window of form by this API.

can test that and you see the detached osk from the form app (move the form /close to see difrence).


I set a cutted titlebar on the osk have  and dock it on form with the API
setWindowpos() function.I make some codes when the form is reduced or closed to synchronize with osk.
The editox have  tools to set fontname,fontsize,bold,italic and color.
Can resize the form with spinner(more easy to do that manually with mousedown)

Warning: the onscreen keyboard window title is localized and then depends on language used with os.In french its  "Clavier visuel", in english (...)

set this in code before running.

These codes are tested on win8.1


*Begin code
Publi oform
Set Classlib To Home(1)+"SAMPLES\CLASSES\SAMPLES.VCX" AddI
oform=Newobject("yosk")
Release Classlib Home(1)+"SAMPLES\CLASSES\SAMPLES.VCX"
oform.Show
Read Events
Retu
*
Define Class yosk As Form
    BorderStyle = 3
    Height = 600
    Width = 814
    ShowWindow = 2

    AlwaysOnTop=.T.  &&avoid to be recovered by another windows (even inserted)
    AutoCenter = .T.
    Caption = "Visual keyboard on form"
    MinHeight = 600
    MinWidth = 700
    KeyPreview = .T.
    ShowTips=.T.
    yhwnd = .F.
    tour = .F.
    Name = "Form1"

    Add Object edit1 As EditBox With ;
        FontSize = 12, ;
        Height = 216, ;
        Left = -2, ;
        Top = 351, ;
        Width = 815, ;
        BackColor = Rgb(255,255,221), ;
        Name = "Edit1"

    Add Object spinner1 As Spinner With ;
        Height = 24, ;
        Increment = 10.00, ;
        Left = 347, ;
        SpinnerHighValue = (Sysmetric(1)), ;
        SpinnerLowValue = 600.00, ;
        ToolTipText = "W+/-", ;
        Top = 145, ;
        Width = 72, ;
        Value = 800, ;
        Name = "Spinner1"

    Add Object spinner2 As Spinner With ;
        Height = 24, ;
        Increment = 10.00, ;
        Left = 451, ;
        SpinnerHighValue = (Sysmetric(2)), ;
        SpinnerLowValue = 600.00, ;
        ToolTipText = "H+/-", ;
        Top = 147, ;
        Width = 71, ;
        Value = 800, ;
        Name = "Spinner2"

    Add Object label1 As Label With ;
        AutoSize = .T., ;
        Caption = "W", ;
        Height = 17, ;
        Left = 328, ;
        Top = 150, ;
        Width = 13, ;
        ToolTipText = "Form width", ;
        Name = "Label1"

    Add Object label2 As Label With ;
        AutoSize = .T., ;
        Caption = "H", ;
        Height = 17, ;
        Left = 430, ;
        Top = 148, ;
        Width = 11, ;
        ToolTipText = "Form height", ;
        Name = "Label2"

    Add Object rtfcontrols1 As rtfcontrols With ;
        Top = 144, ;
        Left = 0, ;
        Width = 313, ;
        Height = 32, ;
        SpecialEffect = 1, ;
        Name = "Rtfcontrols1", ;
        Cbofontname1.FontName = "MS Sans Serif", ;
        Cbofontname1.FontSize = 8, ;
        Cbofontname1.Value = "Arial", ;
        Cbofontname1.ToolTipText = "FontName", ;
        Cbofontname1.Name = "Cbofontname1", ;
        Cbofontsize1.FontName = "MS Sans Serif", ;
        Cbofontsize1.FontSize = 8, ;
        Cbofontsize1.Name = "Cbofontsize1", ;
        cmdBold.FontName = "Courier New", ;
        cmdBold.FontSize = 8, ;
        cmdBold.Name = "cmdBold", ;
        cmdItalic.FontName = "Courier New", ;
        cmdItalic.FontSize = 8, ;
        cmdItalic.Name = "cmdItalic", ;
        cmdColor.FontName = "Courier New", ;
        cmdColor.FontSize = 8, ;
        cmdColor.Name = "cmdColor"


    Add Object command1 As CommandButton With ;
        Top = 144, ;
        Left = 528, ;
        Height = 25, ;
        Width = 25, ;
        FontBold = .T., ;
        FontSize = 14, ;
        Caption = "?", ;
        MousePointer = 15, ;
        ForeColor = Rgb(0,255,0), ;
        Name = "Command1"

    Procedure yprocess
        Thisform.LockScreen=.T.
        
*Important: must be the EXACT Caption of the window depending on language used on system-place it in the form
        Local i,fail
        i=0
        fail=.F.
        Thisform.yhwnd=0
        Do While Thisform.yhwnd=0
            Thisform.yhwnd = FindWindow(Null, "Clavier visuel") 
&&localized
            sleep(1000)
            i=i+1
            If! Thisform.yhwnd=0
                =SetParent(Thisform.yhwnd,Thisform.HWnd)
                DoEvents
                Exit
            Endi

            If i>5
                fail=.T.
                Exit
            Endi
        Enddo

        If m.fail=.T.
            Messagebox("Fail top find osk",16+4096,1000)
            Return .F.
        Endi
        _Screen.WindowState=1

        If Thisform.yhwnd<>0
            SetParent(Thisform.yhwnd,Thisform.HWnd)
            SetForegroundWindow(Thisform.HWnd)
            sleep(100)
            Thisform.ycut_titlebar(Thisform.yhwnd)
            sleep(100)
            Thisform.ypos(Thisform.yhwnd)
        Else
            Wait Window("Fail")
        Endi
        Thisform.LockScreen=.F.
    Endproc

    Procedure ypos
        Lparameters HWnd &&position
        Do Case

            Case Thisform.WindowState=1
                SetWindowPos (HWnd,1,-2000,Thisform.Top+35,Thisform.Width,150,64) && move the osk out of screen
                && can also  hide the window with
                * ShowWindow(hwnd, SW_HIDE) where  Sw_Hide=0

                sleep(100)
            Otherwise

                #Define HWND_BOTTOM         1
                #Define SWP_SHOWWINDOW      64

                SetWindowPos (HWnd,HWND_BOTTOM,Thisform.Left+6, Thisform.Top+35,Thisform.Width,150,SWP_SHOWWINDOW)
                sleep(100)

                With Thisform.edit1
                    .Left=0
                    .Top=240
                    .Width=.Parent.Width-2
                    .Height=Thisform.Height-.Top-2
                Endwith

                With This.spinner1
                    .Top=.Parent.edit1.Top-.Height-1
                    .Value=Thisform.Width
                Endwith

                With This.spinner2
                    .Top=.Parent.spinner1.Top
                    .Value=Thisform.Height
                Endwith

                With Thisform.rtfcontrols1
                    .Top=.Parent.spinner1.Top
                Endwith

                With Thisform.command1
                    .Top=.Parent.spinner1.Top
                Endwith

        Endcase
    Endproc

    Procedure ycut_titlebar
        Lparameters HWnd
        #Define GWL_STYLE -16
        #Define WS_CAPTION 0x00C00000
        #Define WS_THICKFRAME 0x00040000
        #Define WS_DLGFRAME 0x00400000


        *this extened style dont show any window (hwnd)  on the taskbar
        #Define SW_HIDE 0
        #Define SW_SHOW 5
        #Define WS_EX_NOACTIVATE 0x08000000  &&L
        #Define GWL_EXSTYLE -20
        ShowWindow(HWnd, SW_HIDE)
        SetWindowLong(HWnd, GWL_EXSTYLE , WS_EX_NOACTIVATE)
        ShowWindow(HWnd, SW_SHOW)

        *Cut the titlebar
        Local lnStyle, lnNewStyle
        * Get the current style of the window
        lnStyle = GetWindowLong(HWnd, GWL_STYLE)

        * Remove the border of the window
        lnNewStyle = Bitxor(lnStyle, WS_CAPTION)

        * Set the new style for the window
        SetWindowLong(HWnd, GWL_STYLE, lnNewStyle)
    Endproc

    Procedure Moved
        Thisform.ypos(Thisform.yhwnd)
    Endproc

    Procedure KeyPress
        Lparameters nKeyCode, nShiftAltCtrl
        If nKeyCode=27
            Thisform.Release
        Endi
    Endproc

    Procedure Destroy
        *close osk.exe and the form
        #Define WM_CLOSE 0x0010
        SendMessage(Thisform.yhwnd,WM_CLOSE,0,0)
        Clea Events
    Endproc

    Procedure Load
        Declare Integer SetParent In user32;
            INTEGER hWndChild,;
            INTEGER hWndNewParent
        Declare Integer WinExec In kernel32 String lpCmdLine,;
            INTEGER nCmdShow
        Declare Integer FindWindow In user32;
            STRING lpClassName, String lpWindowName
        Declare Integer SetWindowPos In user32;
            INTEGER HWnd,;
            INTEGER hWndInsertAfter,;
            INTEGER x,;
            INTEGER Y,;
            INTEGER cx,;
            INTEGER cy,;
            INTEGER wFlags
        Declare Integer Sleep In kernel32 Integer
        Declare Integer SetForegroundWindow In WIN32API Integer hWinHandle
        Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex
        Declare Integer SetWindowLong In user32 Integer HWnd,;
            INTEGER nIndex, Integer dwNewLong
        Declare Integer IsWindow In user32 Integer hWindow
        Declare Integer SendMessage In Win32API;
            INTEGER HWnd,;
            INTEGER uMsg,;
            INTEGER wParam,;
            INTEGER Lparam
        Declare Long FindWindow In "user32" String lpClassName, String lpWindowName
        Declare Long SetWindowPos In "user32" Long HWnd, Long hWndInsertAfter, Long x, Long Y, Long cx, Long cy, Long wFlags
        Declare Integer ShowWindow In user32;
            INTEGER HWnd,;
            INTEGER nCmdShow

        Run/N osk.Exe
        sleep(1000)
    Endproc

    Procedure Resize
        Thisform.ypos(Thisform.yhwnd)
        sleep(10)
    Endproc

    Procedure Init
        _Screen.WindowState=1
        With Thisform
            .Caption = "Screen Keyboard hosted on VFP form"
            .BackColor = Rgb(213,223,240)
            .yhwnd = 0
            .Width=800
            .Height=600
            .rtfcontrols1.Cbofontname1.InteractiveChange()
            .rtfcontrols1.Cbofontsize1.Value="12"
            .yprocess()
        Endwith
    Endproc

    Procedure edit1.RightClick
        Define Popup raccourci SHORTCUT Relative From Mrow(),Mcol()
        Define Bar _Med_slcta Of raccourci Prompt "Sélec\<tionner tout" ;
            KEY CTRL+A, "Ctrl+A" ;
            PICTRES _Med_slcta ;
            MESSAGE "Sélectionne tout le texte ou tous les éléments de la fenêtre active"
        Define Bar _Med_redo Of raccourci Prompt "\<Rétablir" ;
            KEY CTRL+R, "Ctrl+R" ;
            PICTRES _Med_redo ;
            MESSAGE "Rétablit la dernière opération annulée"
        Define Bar _Med_undo Of raccourci Prompt "\<Annuler" ;
            KEY CTRL+Z, "Ctrl+Z" ;
            PICTRES _Med_undo ;
            MESSAGE "Annule la dernière modification"
        Define Bar _Med_paste Of raccourci Prompt "C\<oller" ;
            KEY CTRL+V, "Ctrl+V" ;
            PICTRES _Med_paste ;
            MESSAGE "Place le contenu du Presse-papiers au point d'insertion"
        Define Bar _Med_cut Of raccourci Prompt "\<Couper" ;
            KEY CTRL+x, "Ctrl+X" ;
            PICTRES _Med_cut ;
            MESSAGE "Enlève la sélection et la place dans le Presse-papiers"
        Activate Popup raccourci
    Endproc

    Procedure spinner1.InteractiveChange
        With Thisform
            .Width=This.Value
            .AutoCenter=.T.
        Endwith
    Endproc

    Procedure spinner2.InteractiveChange
        With Thisform
            .Height=This.Value
            .AutoCenter=.T.
        Endwith
    Endproc

    Procedure rtfcontrols1.Init
        DoDefault()
    Endproc

    Procedure rtfcontrols1.Cbofontname1.Init
        DoDefault()
        This.Value=[Arial]
    Endproc

    Procedure rtfcontrols1.Cbofontsize1.InteractiveChange
        Thisform.edit1.FontSize = Val(This.Value)
    Endproc

    Procedure rtfcontrols1.Cbofontname1.InteractiveChange
        DoDefault()
        This.Parent.Cbofontsize1.FillList(This.Value)
        Try
            This.Parent.Cbofontsize1.Value="12"
        Catch
        Endtry
        Thisform.edit1.FontName = This.Value
    Endproc

    Procedure rtfcontrols1.cmdBold.Click
        Thisform.edit1.FontBold = !Thisform.edit1.FontBold
    Endproc

    Procedure rtfcontrols1.cmdItalic.Click
        Thisform.edit1.FontItalic = !Thisform.edit1.FontItalic
    Endproc

    Procedure rtfcontrols1.cmdColor.Click
        Thisform.edit1.ForeColor = Getcolor()
    Endproc

    Procedure command1.Click
        Local m.myvar
        TEXT to m.myvar noshow
The osk.exe is a windows application of keyboard.
Give the focus to the editbox area (click on) and stroke keys from osk.
Any stroke àon osk,is replicated on editbox simultaneously.
can resize, move, maximize ,minimize the form.
The function setParent dont work on new osk (in my Win8.1)
(maybe MS have changed its behavior to be a child window on form surface).
Its indeed becomes alwaysontop app.
I set a cutted titlebar on the osk have and dock it on form with the API
setWindowpos() function.
The editox have tools to set fontname,fontsize,bold,italic and color.
Can resize the form with spinner(more easy to do that manually with mousedown)
NB:the osk dont appear on the taskbar.
        ENDTEXT
        Messagebox(m.myvar,0+32+4096,"Summary help")
    Endproc
Enddefine
*

*End code

 

 


on screen keyboard last version (win8.1) on vfp form.Can use charmap (run/n charmap) to use special chars.
on screen keyboard last version (win8.1) on vfp form.Can use charmap (run/n charmap) to use special chars.
on screen keyboard last version (win8.1) on vfp form.Can use charmap (run/n charmap) to use special chars.
on screen keyboard last version (win8.1) on vfp form.Can use charmap (run/n charmap) to use special chars.
on screen keyboard last version (win8.1) on vfp form.Can use charmap (run/n charmap) to use special chars.
on screen keyboard last version (win8.1) on vfp form.Can use charmap (run/n charmap) to use special chars.
on screen keyboard last version (win8.1) on vfp form.Can use charmap (run/n charmap) to use special chars.

on screen keyboard last version (win8.1) on vfp form.Can use charmap (run/n charmap) to use special chars.

*Problem solved: the osk.exe dont appear on taskbar to prevent manipulating by user.

A new  windows extended style WS_EX_NOACTIVATE is set to make the icon dont appear on taskbar.

i cut the code to hide/show taskbar.

 

The primary code to run the osk &s standalone is very simple

*begin code
run /n osk
run /n  notepad

*end code

give the focus to notepad and its ok.

Click on code to select [then copy] -click outside to deselect

                  

*added on 14 november 2015
*the osk.exe runs only with the set language on system.it cannot swicth to another language.
*the lang executed must be added on system in the control panel/regional lang
*if not installed the keyboard OSK runs with default (english)
*this code can run the osk with multi languages installed and switch from one to other.
*can see on the lang bar the language switch to new value set by code

Publi yform
yform=Newobject("yOSK")
yform.Show
Read Events
Retu
*
Define Class yosk As Form
    Top = 1
	Left = 46
	Height = 54
	Width = 216
	ShowWindow = 2
	Caption = "OSK multiLanguages"
	MaxButton = .F.
	Name = "Form1"

	Add Object combo1 As ComboBox With ;
		Height = 37, ;
		Left = 12, ;
		Top = 12, ;
		Width = 192, ;
		Name = "Combo1"

	Procedure Destroy
		Clea Events
	Endproc

	Procedure combo1.Click

		Do Case
			Case This.Value=1
				*french*
				ActivateKeyboardLayout(1036,1)
				lnRetCode = LoadKeyboardLayout('0000040c', 1 )     &&0x040c

			Case This.Value=2
				*Arabic
				ActivateKeyboardLayout(1025,0)
				lnRetCode = LoadKeyboardLayout('00001401',3)   &&0x1401   (Arabe/DZ)

			Case This.Value=3
				*english
				ActivateKeyboardLayout(1033,8)
				lnRetCode = LoadKeyboardLayout('00000409', 1 )

			Case This.Value=4
				*Russian
				ActivateKeyboardLayout(1049,0)
				lnRetCode = LoadKeyboardLayout('00000419', 1 )

		Endcase

		Run/N osk
	Endproc


	Procedure combo1.Init
		With This
			.AddItem("French")
			.AddItem("arabic")
			.AddItem("English")
			.AddItem("Russian")
			.ListIndex=1
			.Value=1
			.Style=2
		Endwith
	Endproc

Enddefine
*
*-- EndDefine: yodk



Windows keyboard on screen  -OSK.exe-
Windows keyboard on screen  -OSK.exe-

Published on Visual foxpro, osk, keyboard, API

To be informed of the latest articles, subscribe:
Comment on this post
V
Excellent !
Reply
Y
Thank you Vilhem.Have you seen the osk behavior ? some years ago i embed it easily on a vfp form.<br /> it seems that MS have changed many things.