But since I wanted to find out also how to embed the nasty elusive built-in On-Screen Keyboard (OSK) of Windows which yesterday gave me a lot of frustration as surprisingly it is harder to control than said Free Virtual Keyboard, gleaming new codes from Vilhelm I decided to renew my failed attempts on how it can be done. Sometimes though when I do try to control things I do not need yet like this one, in the midst of it I wish I should have simply banged my head on the table; for again it seems I am unnecessarily stressing myself on something I myself do not need nor use (yet).
Anyhow, while finding ways like this sometimes makes my blood pressure go up due to frustrations, in the end when I find a way, I felt a bit of contentment as that is another understanding (to an extent) of these somewhat elusive WinAPIs. I have yet fully understood these things and just relies on my observations and trials and errors; but I think I am slowly getting there.
After adopting some technique and codes used by Vilhelm I am able to successfully embed OSK within our form under XP OS. However, trying the same codes inside Windows 7 renews my frustration as said OS does not respect the settings I have done earlier.
Finally, here are the codes that work on both XP and Windows 7 (32-bit, I do not have 64-bit to test it to):
* OSK inside VFP Form XP/Win 7 32-bit
Declare Integer FindWindow In user32;
STRING lpClassName, String lpWindowName
Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex
Declare Integer ShellExecute In shell32.Dll ;
INTEGER hndWin, ;
STRING cAction, ;
STRING cFileName, ;
STRING cParams, ;
STRING cDir, ;
INTEGER nShowWin
Declare Integer SetWindowLong In user32 Integer HWnd,;
INTEGER nIndex, Integer dwNewLong
Declare Integer SetWindowPos In user32;
INTEGER HWnd,;
INTEGER hWndInsertAfter,;
INTEGER x,;
INTEGER Y,;
INTEGER cx,;
INTEGER cy,;
INTEGER uFlags
Declare Integer SetParent In user32;
INTEGER hWndChild,;
INTEGER hWndNewParent
Declare Integer SetFocus In user32 Integer
Clear
Public oForm
oForm = Createobject('form1')
oForm.Show()
Define Class form1 As Form
Height = 400
Width = 900
Caption = "OSK Inside VFP Form"
Desktop = .T.
AutoCenter = .T.
Add Object text1 As TextBox With;
top = 20, Left = 10, Width = 100, Height = 28
Add Object tmr As Timer With Interval = 100
Procedure KeyPress
Lparameters nKeyCode, nCtrlShift
If nKeyCode = 27
Thisform.Release
Endif
Endproc
Procedure Load
ShellExecute(0,'open','osk.exe','','',1)
Endproc
Procedure tmr.Timer
Local nOSKHeight
nOSKHeight = 250 && initial OSK height
nHwnd = FindWindow(Null,'On-Screen Keyboard')
lnStyle = GetWindowLong(m.nHwnd, -16)
SetWindowLong (m.nHwnd, -16, Bitset(m.lnStyle,30)) && remove menu
SetWindowLong(m.nHwnd, -16, Bitxor(m.lnStyle, 0xCF0000))
* In Windows7, OSK is not positioned properly until you do this first and do another below later
SetWindowPos(m.nHwnd, 0, 0, Thisform.Height-m.nOSKHeight,Thisform.Width, m.nOSKHeight, 0x0020)
SetParent(m.nHwnd,Thisform.HWnd)
SetWindowPos(m.nHwnd, 0, 0, Thisform.Height-m.nOSKHeight,Thisform.Width+10, m.nOSKHeight, 0x0020)
This.Enabled = .F.
SetFocus(Thisform.HWnd)
Endproc
Enddefine
- on XP, it can be resized on-the-ply; on Window 7 it is fixed size
- on XP version of OSK, there is no word suggestion; while on Windows 7 there is
Excellent solution!
ReplyDeleteYou overestimated my contribution :-)
Oh no! Without your codes on the SetWindowLong flags on FreeVK, I do not think I will be able to work on OSK easy. Your post on FreeVK and this one will give them some options what to use.
Delete