Buchempfehlung
MySQL kurz & gut
MySQL kurz & gut
Das preiswerte Taschen- buch stellt MySQL-rele- vante Inhalte systematisch und knapp dar, sodass es sich optimal zum Nach- schlagen beim Pro- grammieren eignet. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Dateien und Laufwerke

Nutzung des Windows - Message - Systems zur Datenübertragung

Lizenz:Erster Autor:Letzte Bearbeitung:
WTFPLMitgliedgrindstone 18.11.2014

Neben Pipes und Filemapping besteht auch die Möglichkeit, das Message - System von Windows zu benutzen, um Daten zwischen verschiedenen Prozessen auszutauschen. Der Vorteil ist, daß sich das Betriebssystem weitgehend um die Verteilung und Synchronisation der Daten kümmert, so daß man sich über Threadsicherheit keine Gedanken machen muß.

Für einen Datenaustausch muß neben dem Einbinden der Sende-/Empfangsroutinen lediglich senderseitig die ThreadID des Empfängerthreads bekannt sein.

Zunächst einmal die Sende-/Empfangsroutinen:
msg_se.bi:

#Include Once "windows.bi"

Sub stringSenden(threadId As Integer, text As String)
    Dim As Integer tp = 0 'pointer auf test

    Do While tp < Len(text) - 7 'verbleibender text ist >= 8 zeichen
        PostThreadMessage(threadId, WM_USER+1, _
        Cvi(Chr(text[tp],text[tp + 1],text[tp + 2],text[tp + 3])), _
        Cvi(Chr(text[tp + 4],text[tp + 5],text[tp + 6],text[tp + 7]))) '8 zeichen senden
        tp += 8 'pointer setzen
    Loop

    Do While tp < Len(text) - 3 'verbleibender text ist >= 4 zeichen
        PostThreadMessage(threadId, WM_USER+2, _
        Cvi(Chr(text[tp],text[tp + 1],text[tp + 2],text[tp + 3])), Cvi(Chr(0,0,0,4))) '4 zeichen senden
        tp += 4 'pointer setzen
    Loop
    'restliche zeichen und endekennzeichen senden
    PostThreadMessage(threadId, WM_USER+2, Cvi(Right(Chr(0,0,0,0) + Mid(text,tp + 1),4)),Cvi(Chr(0,0,1,Len(text) - tp)))

End Sub

Function stringEmpfangen(timeout As UInteger) As String
    Dim As Double zeit = Timer + timeout / 1000
    Dim As String text = "", g
    Dim As MSG nachricht

    Do 'endlosschleife
        Do While PeekMessage(@nachricht,NULL,0,0,PM_NOREMOVE) = 0 'keine nachricht
            If Timer > zeit Then 'timeout
                Return text
            EndIf
            Sleep 1
        Loop
        GetMessage(@nachricht,NULL,0,0) 'nachricht holen
        With nachricht
            Select Case .message
                Case WM_USER+1 'text übertragen (8 zeichen)
                    text += Mki(.wparam) + Mki(.lparam)
                Case WM_USER+2 'text übertragen (0 bis 4 zeichen)
                    g = Mki(.lparam) 'niederwertigstes byte enthält die anzahl der zeichen
                    text += Right(Mki(.wparam),g[3]) 'angegebene anzahl von zeichen an den text anhängen
                    Select Case g[2] 'vorletztes byte enthält ein steuerzeichen
                        Case 1 'textübertragung beendet
                            Return text
                    End Select
            End Select
        End With
    Loop
End Function

Und zwei Programme als Anwendungsbeispiel:
Der Elternprozess msg_parent:

#Include "windows.bi"
#Include "msg_se.bi"

Dim As HWND hWndChild, hWndDiesesFenster
Dim As Integer threadId
Dim As String message, antwort

hWndDiesesFenster = GetConsoleWindow() 'fensterhandle ermitteln
SetWindowText(hWndDiesesFenster,"Sender") 'fenstertitel setzen zur identifizierung

Shell "start " + ExePath + "\msg_child.exe" 'kindprogramm starten
Do
    hWndChild = FindWindow(0,"Empfaenger")
    Sleep 1
Loop Until hWndChild 'warten, bis kindprozess läuft
threadId = GetWindowThreadProcessId(hWndChild,0) 'thread - ID des kindprozesses ermitteln
SetForegroundWindow(hWndDiesesFenster) 'elternprogramm in den Vordergrund holen

Do
    Input "Nachricht ";message
    stringSenden(threadID,message) 'nachricht an kindprozess schicken
    If message = "quit" Then 'programm beenden
        End
    EndIf
    antwort = stringEmpfangen(INFINITE) 'antwort von kindprozess holen (timeout 1 sekunde)
    Print antwort 'antwort ausgeben
    Print
Loop

Der Kindprozess msg_child:

#Include "windows.bi"
#Include "msg_se.bi"

Dim As HWND hWndParent, hWndDiesesFenster
Dim As String text
Dim As Integer threadId

hWndDiesesFenster = GetConsoleWindow() 'fensterhandle ermitteln
SetWindowText(hWndDiesesFenster,"Empfaenger") 'fenstertitel setzen zur identifizierung
ShowWindow(hWndDiesesFenster,SW_HIDE) 'fenster unsichtbar machen

hWndParent = FindWindow(0,"Sender") 'fensterhandle des elternprozesses ermitteln
threadId = GetWindowThreadProcessId(hWndParent,0) 'thread - ID des elternprozesses ermitteln

Do
    text = stringEmpfangen(-1) 'gesendeten text holen
    If text <> "" Then
        If text = "quit" Then 'programm beenden
            End
        EndIf
        stringSenden(threadId,"ECHO " + text) 'text als echo zurückschicken
        text = ""
    EndIf
Loop

Vor dem Start von msg_parent muß msg_child kompiliert und im selben Verzeichnis wie msg_parent abgelegt werden.

Die Eingaben von msg_parent werden über die Message-queue an msg_child und von dort mit dem Präfix "ECHO " versehen wieder zurückgeschickt.

Wenn ein in der Message-queue befindlicher Text sicher erkannt werden soll, sollte der Timeout-Wert von stringEmpfangen nicht kleiner sein als 100. Ein Timeout-Wert von -1 oder "INFINITE" bedeutet "kein Timeout".


Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 16.11.2014 von Mitgliedgrindstone angelegt.
  • Die aktuellste Version wurde am 18.11.2014 von Mitgliedgrindstone gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen