Attribute VB_Name = "MVW4TouchKeyBoard" Option Explicit '--- Vorsicht bei Änderungen in diesem Modul --- Public gsngKeySize As Single 'Vegrößerungsfaktor für die Tastengröße Public gnPosition As EPosition 'Positionierung der Tastatur: Public gfShowLimits As Boolean Public Enum EPosition vwScreenCorners vwAtControl vwCenter End Enum Public Enum EPad 'Aufzählung der Tastaturtypen vwNumPad vwAlphaPad vwHexPad vwBinPad End Enum Public glHwndController As Long 'Fensterkennung im VWTouchCtrl.OCX Public glThreadID As Long 'Thread-ID der Applikation Public gsVWProjectName As String 'VisiWin-Projektname Public gsVWProjectPath As String 'Projektpfad Public gsVWTouchKeyboardINI As String 'Parameter zur aktuellen Sprache Public glLCID As Long 'Windows-Sprachkennung Public gnCharset As Integer 'Font-Characterset 'automatisch ermittelte Nachrichtennummern Public glVWM_KeyboardHandle As Long Public glVWM_TerminateKeyboard As Long Public glVWM_HideKeyboard As Long Public glVWM_NotifyKeyboard As Long Public glVWM_Language As Long Public glVWM_TouchKeyboardHides As Long Public glVWM_TouchPosition As Long Public glVWM_TouchShowLimits As Long Public glVWM_TouchKeySize As Long '>>> 4.02.0003 16.01.2002 Public glVWM_CancelInput As Long '<<< 'Instanz des Schnittstellenformulars Public gfrmVWTouchKeyBoard As FVW4TouchKeyboard 'dessen alte Fensterprozedur Public gPrevWindowProcVWTouchKeyBoard As Long 'Fensterkennung des Steuerelementes in der Applikation mit dem Fokus Public glHwndControl As Long Public gsLimitMin As String Public gsLimitMax As String Public gudtRectControl As RECT Public gsItem As String Public gsDescription As String Public gsAddText As String Public gvValue As Variant Public gsStringValue As String Public Const CmdLine_Controller = "/Controller:" Public Const CmdLine_Thread = "/Thread:" Public Const CmdLine_Project = "/Project:" Public Const OC_BIT = &H131 Public Const OC_DIGI = &H131 Public Const OC_CHAR = &H132 Public Const OC_UCHAR = &H172 Public Const OC_BYTE = &H172 Public Const OC_INT = &H133 Public Const OC_UINT = &H173 Public Const OC_WORD = &H173 Public Const OC_BCD = &H164 Public Const OC_LONG = &H136 Public Const OC_ULONG = &H176 Public Const OC_DWORD = &H176 Public Const OC_FLOAT = &H127 Public Const OC_TEXT = &H109 Public Const OC_DOUBLE = &H128 Public Type TEditInfo SizeOfStruct As Integer DataType As Integer 'Typ der Prozessvariablen (Konstante OC_...) OutputFormat As Integer 'Formatierung im VWVarIn (Wert der Format-Eigenschaft) LimitMin(254) As Byte 'ASCII-String der LimitMin-Eigenschaft LimitMax(254) As Byte 'ASCII-String der LimitMax-Eigenschaft Position As RECT Item(255) As Byte Description(255) As Byte AddText(255) As Byte Value As Variant StringValue(255) As Byte End Type Public Type TTouchValue SizeOfStruct As Integer Value As Variant StringValue(254) As Byte End Type Public Sub Main() '--- in dieser Prozedur keine Änderungen vornehmen --- 'Startprozedur des Programms 'Eingabe: ' Command$: Parameter in der Kommandozeile ' VWTouchKeyboard.ini: Programmeinstellungen 'Ausgabe: ' folgende globale Variablen (siehe oben): ' glKeySize, gfAutoPosition ' gsProjectName, glHwndController, glThreadID ' glVWM_KeyboardHandle, glVWM_TerminateKeyboard, glVWM_HideKeyboard, ' glVWM_NotifyKeyboard, glVWM_Language ' gfrmVWTouchKeyBoard Dim nPos As Integer, scPuffer As String * 255, lR As Long gsVWTouchKeyboardINI = App.Path & "\VW4TouchKeyboard.ini" gsngKeySize = 1 'Kommandozeile auswerten nPos = InStr(Command$, CmdLine_Project) + Len(CmdLine_Project) gsVWProjectName = Trim$(Mid$(Command$, nPos)) nPos = InStr(gsVWProjectName, "/") If nPos Then gsVWProjectName = Trim$(Left$(gsVWProjectName, nPos - 1)) End If nPos = InStr(Command$, CmdLine_Controller) + Len(CmdLine_Controller) glHwndController = Val(Mid$(Command$, nPos)) nPos = InStr(Command$, CmdLine_Thread) + Len(CmdLine_Thread) glThreadID = Val(Mid$(Command$, nPos)) 'Nachrichtennummern ermitteln glVWM_KeyboardHandle = RegisterWindowMessage("VWM32_1_KEYBOARDHANDLE") glVWM_TerminateKeyboard = RegisterWindowMessage("VWM32_1_TERMINATEKEYBOARD") glVWM_HideKeyboard = RegisterWindowMessage("VWM32_1_HIDEKEYBOARD") glVWM_NotifyKeyboard = RegisterWindowMessage("VWM32_1_NOTIFYKEYBOARD") glVWM_Language = RegisterWindowMessage("VWM1_LANGUAGE") glVWM_TouchKeyboardHides = RegisterWindowMessage("VWM32_1_TOUCHKEYBOARDHIDES") glVWM_TouchPosition = RegisterWindowMessage("VWM32_1_TOUCHPOSITION") glVWM_TouchShowLimits = RegisterWindowMessage("VWM32_1_TOUCHSHOWLIMITS") glVWM_TouchKeySize = RegisterWindowMessage("VWM32_1_TOUCHKEYSIZE") '>>> 4.02.0003 16.01.2002 glVWM_CancelInput = RegisterWindowMessage("VWM32_1_CANCELINPUT") '<<< Load FHexPad DoEvents Load FAlphaPad DoEvents Load FNumPad DoEvents Load FBinPad DoEvents 'Schnittstellenformular erzeugen CreateVWTouchKeyBoard End Sub Public Function CreateVWTouchKeyBoard() As Boolean '--- in dieser Prozedur keine Änderungen vornehmen --- 'Erzeugt das Schnittstellenformular für die Kommunikation 'vom VWTouchCtrl.ocx zum VWTouchKeyboard.exe 'Eingabe: ' glHwndController: VWTouchCtrl.ocx 'Ausgabe: ' gfrmVWTouchKeyBoard: Instanz des Schnittstellenformulars ' gPrevWindowProcVWTouchKeyBoard: Adresse der Originalfensterprozedur Dim f As Boolean, lR As Long f = True If gfrmVWTouchKeyBoard Is Nothing Then Set gfrmVWTouchKeyBoard = New FVW4TouchKeyboard f = f And (Not gfrmVWTouchKeyBoard Is Nothing) gPrevWindowProcVWTouchKeyBoard = GetWindowLong(gfrmVWTouchKeyBoard.hwnd, GWL_WNDPROC) f = f And (gPrevWindowProcVWTouchKeyBoard <> 0) lR = SetWindowLong(gfrmVWTouchKeyBoard.hwnd, GWL_WNDPROC, AddressOf WindowProcVWTouchKeyBoard) f = f And (lR <> 0) AttachThreadInput App.ThreadID, glThreadID, True SendMessage glHwndController, glVWM_KeyboardHandle, gfrmVWTouchKeyBoard.hwnd, ByVal 0& End If CreateVWTouchKeyBoard = f End Function Public Function DestroyVWTouchKeyBoard() As Boolean '--- in dieser Prozedur keine Änderungen vornehmen --- 'Löscht das Schnittstellenformular 'vom VWTouchCtrl.ocx zum VWTouchKeyboard.exe 'Eingabe: ' gfrmVWTouchKeyBoard: Instanz des Schnittstellenformulars ' gPrevWindowProcVWTouchKeyBoard: Adresse der Originalfensterprozedur ' glHwndController: VWTouchCtrl.ocx 'Ausgabe: ' keine If Not gfrmVWTouchKeyBoard Is Nothing Then AttachThreadInput App.ThreadID, glThreadID, False SetWindowLong gfrmVWTouchKeyBoard.hwnd, GWL_WNDPROC, gPrevWindowProcVWTouchKeyBoard Unload gfrmVWTouchKeyBoard Set gfrmVWTouchKeyBoard = Nothing End If DestroyVWTouchKeyBoard = (gfrmVWTouchKeyBoard Is Nothing) End Function Public Function WindowProcVWTouchKeyBoard(ByVal hwnd As Long, _ ByVal Msg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long '--- Vorsicht bei Änderungen in dieser Prozedur --- 'Neue Fensterprozedur für das Schnittstellenformular: 'Hier kommen die Nachrichten an, die das VWTouchCtrl.ocx in der Applikation 'an die VWTouchKeyboard.exe schickt. 'Eingabe: ' hwnd: das eigene Fensterkennung ' Msg: Nummer der Nachricht ' wParam: 1. Parameter (abhängig von der Nachricht) ' lParam: 2. Parameter (abhängig von der Nachricht) 'Nachricht auswerten Select Case Msg Case glVWM_TerminateKeyboard 'Die Applikation wurde beendet, bzw. das VWTouchCtrl.ocx abgemeldet: DestroyVWTouchKeyBoard 'Schnittstellenformular entfernen 'Alle Tastaturfenster entladen UnloadPads WindowProcVWTouchKeyBoard = 0 'Jetzt ist alles aufgeräumt Exit Function '=> nach nächstem Befehl ist Programmende Case glVWM_HideKeyboard 'Tastaturfenster verstecken, weil in der Applikation der Fokus auf 'ein Steuerelement gesetzt wurde, welches keine Tastaturbedienung 'benötigt. '>>> 4.02.0003 16.01.2002 SendMessage glHwndControl, glVWM_CancelInput, 0, ByVal 0& '<<< HidePads Case glVWM_Language 'In der Applikation wurde die Sprache umgeschaltet: 'wParam: LCID (VWLanguage.Language) 'lParam: Charset glLCID = wParam SetKeyboardLayout UnloadPads LoadPads ChangeLanguage Case glVWM_TouchPosition gnPosition = lParam Case glVWM_TouchShowLimits gfShowLimits = lParam Case glVWM_TouchKeySize CopyMemory gsngKeySize, lParam, 4 UnloadPads LoadPads Case WM_COPYDATA Dim uCopyData As COPYDATASTRUCT CopyMemory uCopyData, ByVal lParam, Len(uCopyData) Select Case uCopyData.dwData Case glVWM_NotifyKeyboard 'Es soll eine Tastatur angezeigt werden. 'wParam: Fensterkennung des Steuerelementes in der Applikation. 'lParam: nur bei VWVarIn: Zeiger auf eine TEditInfo-Struktur '>>> 4.02.0003 16.01.2002 SendMessage glHwndControl, glVWM_CancelInput, 0, ByVal 0& '<<< Dim uEditInfo As TEditInfo CopyMemory uEditInfo, ByVal uCopyData.lpData, uCopyData.cbData glHwndControl = wParam gsLimitMin = StrConv(uEditInfo.LimitMin, vbUnicode) gsLimitMin = Left$(gsLimitMin, InStr(gsLimitMin, vbNullChar) - 1) gsLimitMax = StrConv(uEditInfo.LimitMax, vbUnicode) gsLimitMax = Left$(gsLimitMax, InStr(gsLimitMax, vbNullChar) - 1) gudtRectControl = uEditInfo.Position gsItem = StrConv(uEditInfo.Item, vbUnicode) gsItem = Left$(gsItem, InStr(gsItem, vbNullChar) - 1) gsDescription = StrConv(uEditInfo.Description, vbUnicode) gsDescription = Left$(gsDescription, InStr(gsDescription, vbNullChar) - 1) gsAddText = StrConv(uEditInfo.AddText, vbUnicode) gsAddText = Left$(gsAddText, InStr(gsAddText, vbNullChar) - 1) gvValue = uEditInfo.Value gsStringValue = StrConv(uEditInfo.StringValue, vbUnicode) gsStringValue = Left$(gsStringValue, InStr(gsStringValue, vbNullChar) - 1) Select Case uEditInfo.DataType Case OC_BIT, OC_DIGI ShowPad vwNumPad Case OC_CHAR, OC_UCHAR, OC_BYTE, OC_INT, OC_UINT, OC_WORD, OC_LONG, OC_ULONG, OC_DWORD Select Case uEditInfo.OutputFormat Case 0 'Number ShowPad vwNumPad Case 1 'Binary ShowPad vwBinPad Case 2 'Hex ShowPad vwHexPad Case 3 'Oktal ShowPad vwNumPad End Select Case OC_BCD ShowPad vwNumPad Case OC_FLOAT, OC_DOUBLE ShowPad vwNumPad Case OC_TEXT ShowPad vwAlphaPad Case Else ShowPad vwAlphaPad End Select APISetFocus glHwndControl End Select End Select 'Nachrichten weiterreichen an die Original-Fensterprozedur WindowProcVWTouchKeyBoard = CallWindowProc(gPrevWindowProcVWTouchKeyBoard, hwnd, Msg, wParam, lParam) End Function Public Sub ShowPad(enmPad As EPad) '--- Vorsicht bei Änderungen in dieser Prozedur --- 'Anzeigen der ausgewählten Tastatur, alle anderen werden versteckt. 'Die neue Tastatur wird positioniert. 'Eingabe: ' enmPad: Tastaturtyp, der angezeigt werden soll ' gnPosition: Positionsart der Tastatur ' Screen.ActiveForm: aktuell angezeigte Tastatur 'Ausgabe: ' keine Dim frmNew As Form, frmRecent As Form Dim udtRectPad As RECT, udtRectDest As RECT Dim lLeft As Long, lTop As Long, lBottom As Long 'bisherige Tastatur Set frmRecent = Screen.ActiveForm 'Festlegung der neuen Tastatur Select Case enmPad Case vwNumPad Set frmNew = FNumPad Case vwAlphaPad Set frmNew = FAlphaPad Case vwHexPad Set frmNew = FHexPad Case vwBinPad Set frmNew = FBinPad End Select 'bisherige Tastatur verstecken If Not frmNew Is frmRecent Then If (Not frmRecent Is Nothing) And (Not frmRecent Is FVW4TouchKeyboard) Then frmRecent.Hide End If End If frmNew.CheckLimits 'neue Tastatur positionieren If Not frmNew Is Nothing Then GetWindowRect glHwndControl, gudtRectControl 'Koordinaten in Twips umrechnen gudtRectControl.Left = frmNew.ScaleX(gudtRectControl.Left, vbPixels, vbTwips) gudtRectControl.Top = frmNew.ScaleY(gudtRectControl.Top, vbPixels, vbTwips) gudtRectControl.Right = frmNew.ScaleX(gudtRectControl.Right, vbPixels, vbTwips) gudtRectControl.Bottom = frmNew.ScaleY(gudtRectControl.Bottom, vbPixels, vbTwips) Select Case gnPosition Case vwAtControl '1. unterhalb vom Control lLeft = gudtRectControl.Left If (lLeft + frmNew.Width) > Screen.Width Then '1a. bündig zum rechten Bildschirmrand lLeft = Screen.Width - frmNew.Width End If lTop = gudtRectControl.Bottom + Screen.TwipsPerPixelY If (lTop + frmNew.Height) > Screen.Height Then '2. oberhalb vom Control lTop = gudtRectControl.Top - Screen.TwipsPerPixelY - frmNew.Height End If If lTop < 0 Then '3. rechts vom Control lTop = gudtRectControl.Top If (lTop + frmNew.Height) > Screen.Height Then '3a. bündig zum unteren Bildschirmrand lTop = Screen.Height - frmNew.Height End If lLeft = gudtRectControl.Right + Screen.TwipsPerPixelX If (lLeft + frmNew.Width) > Screen.Width Then '4. links vom Control lLeft = gudtRectControl.Left - Screen.TwipsPerPixelX - frmNew.Width End If End If 'Sicherheitshalber nochmal prüfen, ob die Tastatur auch innerhalb des Bildschirms liegt. If lLeft < 0 Then lLeft = 0 End If If lTop < 0 Then lTop = 0 End If 'endlich anzeigen frmNew.Move lLeft, lTop Case vwScreenCorners udtRectPad.Left = frmNew.Left udtRectPad.Right = udtRectPad.Left + frmNew.Width - Screen.TwipsPerPixelX udtRectPad.Top = frmNew.Top udtRectPad.Bottom = udtRectPad.Top + frmNew.Height - Screen.TwipsPerPixelY If IntersectRect(udtRectDest, udtRectPad, gudtRectControl) Then '1. links oben frmNew.Move 0, 0 udtRectPad.Left = frmNew.Left udtRectPad.Right = udtRectPad.Left + frmNew.Width - Screen.TwipsPerPixelX udtRectPad.Top = frmNew.Top udtRectPad.Bottom = udtRectPad.Top + frmNew.Height - Screen.TwipsPerPixelY If IntersectRect(udtRectDest, udtRectPad, gudtRectControl) Then '2. links unten frmNew.Top = Screen.Height - frmNew.Height udtRectPad.Left = frmNew.Left udtRectPad.Right = udtRectPad.Left + frmNew.Width - Screen.TwipsPerPixelX udtRectPad.Top = frmNew.Top udtRectPad.Bottom = udtRectPad.Top + frmNew.Height - Screen.TwipsPerPixelY If IntersectRect(udtRectDest, udtRectPad, gudtRectControl) Then '3. rechts oben frmNew.Move Screen.Width - frmNew.Width, 0 udtRectPad.Left = frmNew.Left udtRectPad.Right = udtRectPad.Left + frmNew.Width - Screen.TwipsPerPixelX udtRectPad.Top = frmNew.Top udtRectPad.Bottom = udtRectPad.Top + frmNew.Height - Screen.TwipsPerPixelY If IntersectRect(udtRectDest, udtRectPad, gudtRectControl) Then '4. rechts unten frmNew.Top = Screen.Height - frmNew.Height 'Das muss jetzt passen, ansonsten ist die Tastatur zu groß. End If End If End If End If Case vwCenter frmNew.Move (Screen.Width - frmNew.Width) / 2, (Screen.Height - frmNew.Height) / 2 End Select 'und anzeigen '>>> 4.02.0003 17.01.2002 On Error Resume Next frmNew.fShow = True '<<< frmNew.Show End If End Sub Public Sub FormResize(frm As Form) '--- Vorsicht bei Änderungen in dieser Prozedur --- 'Einstellungen für ein Tastaturfenster setzen. 'Eingabe: ' frm: Verweis auf das Tastaturformular 'Ausgabe: ' frm: Geändertes Formular Dim ctr As Control On Error Resume Next 'Tastengröße und Schriftgröße anpassen For Each ctr In frm.Controls ctr.Move ctr.Left * gsngKeySize, ctr.Top * gsngKeySize, ctr.Width * gsngKeySize, ctr.Height * gsngKeySize ctr.Font.Size = ctr.Font.Size * gsngKeySize Next ctr 'Fenstergröße anpassen frm.Width = frm.Width - frm.ScaleWidth + gsngKeySize * frm.ScaleWidth frm.Height = frm.Height - frm.ScaleHeight + gsngKeySize * frm.ScaleHeight 'Fenster permanent und hartnäckig in den Vordergrund bringen SetWindowPos frm.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE End Sub Public Sub SetKeyboardLayout() 'Sucht ein Tastaturlayout passend zur gewünschten Sprachkennung 'und ermittelt den Font-Characterset für die Tastenbeschriftung 'Eingabe: ' glLCID: gewünschte Sprachkennung (Windows locale identifier) 'Ausgabe: ' gnCharset: Characterset Dim lKbLayoutFirst As Long, lKbLayout As Long Dim lLCID As Long, l As Long Dim f As Boolean lLCID = GetPrivateProfileInt("Replace", CStr(glLCID), glLCID, gsVWTouchKeyboardINI) gnCharset = GetPrivateProfileInt("CharSet", CStr(lLCID), 0, gsVWTouchKeyboardINI) f = False lKbLayoutFirst = GetKeyboardLayout(0) lKbLayout = lKbLayoutFirst 'alle installierten Keyboard-Layouts durchlaufen Do l = lKbLayout And &HFFFF& If l = lLCID Then 'und bei passendem Layout Schleife verlassen und Einstellung beibehalten. f = True Exit Do End If ActivateKeyboardLayout HKL_NEXT, 0 lKbLayout = GetKeyboardLayout(0) Loop Until lKbLayout = lKbLayoutFirst If Not f Then End If End Sub Public Sub ReadKeyParams(arrKey As Variant, PadType As String, KeyType As String) Dim key As VWKey, lLCID As Long Dim lR As Long, scBuffer As String * 255 Dim sText As String, sKeyCode As String lLCID = GetPrivateProfileInt("Replace", CStr(glLCID), glLCID, gsVWTouchKeyboardINI) sText = lLCID & " " & PadType & " Text" sKeyCode = lLCID & " " & PadType & " KeyCode" For Each key In arrKey 'Beschriftung der Tasten einlesen lR = GetPrivateProfileString(sText, KeyType & key.Index, "", scBuffer, Len(scBuffer), gsVWTouchKeyboardINI) If lR Then key.Caption = Left$(scBuffer, lR) key.Font.Charset = gnCharset End If 'Keycode für die Tasten einlesen Select Case KeyType Case "Std", "End" lR = GetPrivateProfileString(sKeyCode, KeyType & key.Index, "", scBuffer, Len(scBuffer), gsVWTouchKeyboardINI) If lR Then key.Tag = Left$(scBuffer, lR) End If End Select If KeyType = "Extra" Then 'nur sichtbar schalten, wenn sie beschriftet sind key.Visible = Len(key.Caption) End If Next key End Sub Public Sub ReadLimitParams(frm As Form) Dim lR As Long, scBuffer As String * 255 '>>> 4.04.0300 26.08.2002 'Max und Min vertauscht lR = GetPrivateProfileString(glLCID & " Text", "Max", "Maximum", scBuffer, Len(scBuffer), gsVWTouchKeyboardINI) frm.idxLabelLimits(0).TextOff = Left$(scBuffer, lR) lR = GetPrivateProfileString(glLCID & " Text", "Min", "Minimum", scBuffer, Len(scBuffer), gsVWTouchKeyboardINI) '>>> 4.04.0300 26.08.2002 frm.idxLabelLimits(1).TextOff = Left$(scBuffer, lR) frm.idxLabelLimits(0).Font.Charset = gnCharset frm.idxLabelLimits(1).Font.Charset = gnCharset frm.idxLimitMin.Font.Charset = gnCharset frm.idxLimitMax.Font.Charset = gnCharset End Sub Public Sub ChangeLanguage() FHexPad.ChangeLanguage FAlphaPad.ChangeLanguage FNumPad.ChangeLanguage FBinPad.ChangeLanguage End Sub Public Sub HidePads() FHexPad.Hide FAlphaPad.Hide FNumPad.Hide FBinPad.Hide End Sub Public Sub LoadPads() Load FHexPad Load FAlphaPad Load FNumPad Load FBinPad End Sub Public Sub UnloadPads() Unload FHexPad Unload FAlphaPad Unload FNumPad Unload FBinPad End Sub #If test = 1 Then Public Sub Log(ByVal Text As String) Dim nFNo As Integer nFNo = FreeFile Open App.Path & "\VWTouchKeyboard.log" For Append As #nFNo Print #nFNo, Now, Text Close #nFNo End Sub #End If