Fonte/ Codesnippets | | | | R.Schneider | Hallo
Zwei Programme tauschen Daten per WM_COPYDATA aus. Einfach ein Programm erstellen und dann, um das zweite Programm zu erstellen, die drei markierten Zeilen im Quelltext durch die auskommentierten Zeilen ersetzen. Der Text im Edit erscheint nach drücken des Sende-Buttons im Edit des anderen Programms. Ab Profan 8 wegen ProcAddr()
Vielleicht kann es ja jemand brauchen.
Def CopyMemory(3) !KERNEL32,RtlMoveMemory
$H Structs.ph
$H Messages.ph
$H Windows.ph
Declare Ende%, SendeBtn&, EndeBtn&, Edit&
Declare Groesse&, Text$, ProgHndl&, AltProc&
Declare CopyData#, EigeneDaten#
Struct SCopyData = ~COPYDATASTRUCT
Dim CopyData#, SCopyData
WindowStyle 538
WindowTitle Programm1//> Für Programm 2 diese Zeilen entfernen
Window Int(%MaxX / 2 - 200),Int(%MaxY / 2 - 100)-195,100//>
WindowTitle Programm2//< und diese Zeilen einfügen
Window Int(%MaxX / 2 + 5),Int(%MaxY / 2 - 100)-195,100
Set(FastMode,1)
EndeBtn& = Create(Button,%hWnd,Beenden,105,50,70,20)
SendeBtn& = Create(Button,%hWnd,Senden,15,50,70,20)
Edit& = Create(Edit, %hWnd, , 10, 15, 170, 24)
Proc Senden
Parameters Nachricht$
With CopyData#
.dwData& = 0
.cbData& = SizeOf(Nachricht$)
.lpData& = Addr(Nachricht$)
EndWith
Sendmessage(ProgHndl&,~WM_COPYDATA,%hWnd,Addr(CopyData#))
EndProc
Proc WndProc
parameters wnd&, msg&, wparam&, lparam&
If msg&=~WM_COPYDATA
CopyMemory(CopyData#,lparam&,12)
Groesse& = CopyData#.cbData&
Dim EigeneDaten#, Groesse&
CopyMemory(EigeneDaten#,CopyData#.lpData&,Groesse&)
Text$ = String$(EigeneDaten#,0)
Dispose EigeneDaten#
EndIf
return call(AltProc&,wnd&,msg&,wparam&,lparam&)
Endproc
AltProc&=~SetWindowLong(%hwnd,~GWL_WNDPROC,ProcAddr(WndProc,4))
While 1
ProgHndl&=FindWindow(Programm2)//> Für Programm 2 diese Zeile entfernen
ProgHndl&=FindWindow(Programm1)//< und diese Zeile einfügen
Case ProgHndl&: Break
Sleep 100
EndWhile
Usermessages ~WM_COPYDATA
WhileNot Ende%
WaitInput
If %Key = 2
Let Ende% = 1
ElseIf GetFocus(EndeBtn&)
Let Ende% = 1
ElseIf GetFocus(SendeBtn&)
Senden GetText$(Edit&)
ElseIf %umessage=~WM_COPYDATA
SetText Edit&, Text$
Endif
EndWhile
Dispose CopyData#
End
Rudger |
| | | | |
| | p.specht
| Gerade erfolgreich ausprobiert mit den nachfolgenden beiden Programmen (INCLUDE-Pfad anpassen!). Aber: Beim Senden der Nachricht "test" etc. klappt alles. Beim senden von "testikel" an PROGRAMM2 kommt aber "testikelG" an. Was mache ich falsch?
PROGRAMM1:
'INTER-PROGRAMM KOMMUNIKATION
'by Rudger Schneider, 06.04.2007
'Zwei Programme tauschen Daten per WM_COPYDATA aus. Einfach ein Programm erstellen und dann,
'um das zweite Programm zu erstellen, die drei markierten Zeilen im Quelltext durch die
'auskommentierten Zeilen ersetzen. Der Text im Edit erscheint nach drücken des Sende-Buttons
'im Edit des anderen Programms. Ab Profan 8 wegen ProcAddr()
'"Vielleicht kann es ja jemand brauchen".
'((Vkejjb))-Grant by Rudger Schneider, 06.04.2007 auf Xprofan.net
Def CopyMemory(3) !"KERNEL32","RtlMoveMemory"
$H C:\Program Files (x86)\XProfan11\INCLUDE\Structs.ph
$H C:\Program Files (x86)\XProfan11\INCLUDE\Messages.ph
$H C:\Program Files (x86)\XProfan11\INCLUDE\Windows.ph
Declare Ende%, SendeBtn&, EndeBtn&, Edit&
Declare Groesse&, Text$, ProgHndl&, AltProc&
Declare CopyData#, EigeneDaten#
Struct SCopyData = ~COPYDATASTRUCT
Dim CopyData#, SCopyData
WindowStyle 538
WindowTitle "PROGRAMM1"//> Für Programm 2 diese Zeilen entfernen
Window Int(%MaxX / 2 - 200),Int(%MaxY / 2 - 100)-195,100//>
'WindowTitle "PROGRAMM2" //< und diese Zeilen einfügen
'Window Int(%MaxX / 2 + 5),Int(%MaxY / 2 - 100)-195,100
Set("FastMode",1)
EndeBtn& = Create("Button",%hWnd,"Beenden",105,50,70,20)
SendeBtn& = Create("Button",%hWnd,"Senden",15,50,70,20)
Edit& = Create("Edit", %hWnd,"", 10, 15, 170, 24)
Proc Senden
Parameters Nachricht$
With CopyData#
.dwData& = 0
.cbData& = SizeOf(Nachricht$)
.lpData& = Addr(Nachricht$)
EndWith
Sendmessage(ProgHndl&,~WM_COPYDATA,%hWnd,Addr(CopyData#))
EndProc
Proc WndProc
parameters wnd&, msg&, wparam&, lparam&
If msg&=~WM_COPYDATA
CopyMemory(CopyData#,lparam&,12)
Groesse& = CopyData#.cbData&
Dim EigeneDaten#, Groesse&
CopyMemory(EigeneDaten#,CopyData#.lpData&,Groesse&)
Text$ = String$(EigeneDaten#,0)
Dispose EigeneDaten#
EndIf
return call(AltProc&,wnd&,msg&,wparam&,lparam&)
Endproc
AltProc&=~SetWindowLong(%hwnd,~GWL_WNDPROC,ProcAddr("WndProc",4))
While 1
ProgHndl&=FindWindow("PROGRAMM2")//> Für Programm 2 diese Zeile entfernen
//ProgHndl&=FindWindow("PROGRAMM1")//< und diese Zeile einfügen
Case ProgHndl&: Break
Sleep 100
EndWhile
Usermessages ~WM_COPYDATA
WhileNot Ende%
WaitInput
If %Key = 2
Let Ende% = 1
ElseIf GetFocus(EndeBtn&)
Let Ende% = 1
ElseIf GetFocus(SendeBtn&)
Senden GetText$(Edit&)
ElseIf %umessage=~WM_COPYDATA
SetText Edit&, Text$
Endif
EndWhile
Dispose CopyData#
End
PROGRAMM2:
'INTER-PROGRAMM KOMMUNIKATION
'by Rudger Schneider, 06.04.2007
'Zwei Programme tauschen Daten per WM_COPYDATA aus. Einfach ein Programm erstellen und dann,
'um das zweite Programm zu erstellen, die drei markierten Zeilen im Quelltext durch die
'auskommentierten Zeilen ersetzen. Der Text im Edit erscheint nach drücken des Sende-Buttons
'im Edit des anderen Programms. Ab Profan 8 wegen ProcAddr()
'"Vielleicht kann es ja jemand brauchen".
'((Vkejjb))-Grant by Rudger Schneider, 06.04.2007 auf Xprofan.net
Def CopyMemory(3) !"KERNEL32","RtlMoveMemory"
$H C:\Program Files (x86)\XProfan11\INCLUDE\Structs.ph
$H C:\Program Files (x86)\XProfan11\INCLUDE\Messages.ph
$H C:\Program Files (x86)\XProfan11\INCLUDE\Windows.ph
Declare Ende%, SendeBtn&, EndeBtn&, Edit&
Declare Groesse&, Text$, ProgHndl&, AltProc&
Declare CopyData#, EigeneDaten#
Struct SCopyData = ~COPYDATASTRUCT
Dim CopyData#, SCopyData
WindowStyle 538
'WindowTitle "PROGRAMM1" //> Für Programm 2 diese Zeilen entfernen
'Window Int(%MaxX / 2 - 200),Int(%MaxY / 2 - 100)-195,100//>
WindowTitle "PROGRAMM2"//< und diese Zeilen einfügen
Window Int(%MaxX / 2 + 5),Int(%MaxY / 2 - 100)-195,100
Set("FastMode",1)
EndeBtn& = Create("Button",%hWnd,"Beenden",105,50,70,20)
SendeBtn& = Create("Button",%hWnd,"Senden",15,50,70,20)
Edit& = Create("Edit", %hWnd,"", 10, 15, 170, 24)
Proc Senden
Parameters Nachricht$
With CopyData#
.dwData& = 0
.cbData& = SizeOf(Nachricht$)
.lpData& = Addr(Nachricht$)
EndWith
Sendmessage(ProgHndl&,~WM_COPYDATA,%hWnd,Addr(CopyData#))
EndProc
Proc WndProc
parameters wnd&, msg&, wparam&, lparam&
If msg&=~WM_COPYDATA
CopyMemory(CopyData#,lparam&,12)
Groesse& = CopyData#.cbData&
Dim EigeneDaten#, Groesse&
CopyMemory(EigeneDaten#,CopyData#.lpData&,Groesse&)
Text$ = String$(EigeneDaten#,0)
Dispose EigeneDaten#
EndIf
return call(AltProc&,wnd&,msg&,wparam&,lparam&)
Endproc
AltProc&=~SetWindowLong(%hwnd,~GWL_WNDPROC,ProcAddr("WndProc",4))
While 1
'ProgHndl&=FindWindow("PROGRAMM2")//> Für Programm 2 diese Zeile entfernen
ProgHndl&=FindWindow("PROGRAMM1")//< und diese Zeile einfügen
Case ProgHndl&: Break
Sleep 100
EndWhile
Usermessages ~WM_COPYDATA
WhileNot Ende%
WaitInput
If %Key = 2
Let Ende% = 1
ElseIf GetFocus(EndeBtn&)
Let Ende% = 1
ElseIf GetFocus(SendeBtn&)
Senden GetText$(Edit&)
ElseIf %umessage=~WM_COPYDATA
SetText Edit&, Text$
Endif
EndWhile
Dispose CopyData#
End
|
| | | XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 27.11.2018 ▲ |
| |
| | | SetWindowLong GWL_WNDPROC auf eine Proc (statt mind. nProc) ist definitiv ein Problem - "verstärkend" bis hin zu "fahrlässig".
hier zwar (nur) im Zusammenhang mit UserMessages versucht zu behandeln: [...]
Autor: David Strutz (---.dip0.t-ipconnect.de) Datum: 27.04.16 19:20 UserMessages dürften leider per wm_copydata garnicht verwendet werden weil die Adresse hinter dem Speicher nicht mehr sicher ist, weil UserMessages längst empfangen wurden bevor sie (asynchron) aus WaitInput heraus leiten und der Sender den allozierten Speicher (lparam) nicht unmöglich mittlerweile anderweitig verwendet. Danach bleibt dann datensicherer Empfang in einer subclassproc, die wiederum kann jedoch Aussetzer haben und es könnten darüber wm_copydata Notizie übersehen werden. Danach bleibt dann also nur eine eigene wProc, diese wiederum müsste dann aber auch eine nProc sein da die App sonst jederzeit abstürzen potuto weil ProcAddr auf eine XProfan-Proc leider nur per Enumeration statt auch per APCs verwendet werden darf. IMHO geht sicheres wm_copydata-Empfangen mit XProfan dann in Verbindung mit einer nProc als wndProc. @Roland: Ich bin nicht sicher ob ich Dich bereits gefragt hatte, ob Du bei der wm_copydata-Nachricht in Deiner "default" wProc (sei es die per hWnd) nicht eine Ausnahme regeln könntest sodass der Speicher hinter lParam auch wirklich zur Verfügung steht und sicher zu empfangen ist auch ohne nProcs-Workaround. Es wäre auch ganz einfach zu realisieren rein nur mit 1 weiterem Speicher zur Laufzeit da nur 1 Thread: Kommt wm_copydata, dann wird der Speicher (re-)dimensioniert und der Inhalt aus lparam kopiert, und zuletzt, lparam auf die Adresse des eigenen Speichers setzen. wm_copydata ist eine der wertvollsten Messages. XProfan & FreeProfan rox: [...] Nachricht bearbeitet (27.04.16 19:27)
Danach mal probieren eine nProc "wnd_proc" zu verwenden.
//Hauptfenster Subclassing
declare owp&
cls
owp&=setWindowLong(hWnd,gwl_wndProc,procaddr(hWnd.wndProc,4))
waitinput
end
nProc hWnd.wndProc
Parameters wnd&,msg&,wp&,lp&
global owp&
return callWindowProc(owp&,wnd&,msg&,wp&,lp&)
endproc
Damit wären mögliche Speicherlecks zumindest eingebannt. |
| | | | |
|
Zum QuelltextThemeninformationenDieses Thema hat 3 subscriber: |