Hallo Notes-User, Admins und Entwickler,
ich steh mal wieder vor einem Problem.
Ich habe ein kleines Programm, dem man per WM_COPYDATA Befehle rüberschieben kann und diese werden dann abgearbeitet.
Bis jetzt ist es so, dass ich eine kleine Delphi-DLL hab, welche von Notes angesprochen wird und den String übergibt. (Das funktioniert auch ohne Probleme.)
Nun ist es aber so, dass ich jedesmal sicherstellen muss, dass der User die DLL hat und diese auch aufgerufen werden kann.
Also dachte ich mir, dass man das ganze Zeug aus der DLL in LS neu schreibt (ist nicht viel, nur 1 Funktion) und die DLL somit überflüssig wird. (so dachte der kleine Markus)
Mein Problem sind die 2 Funktionen (FindWindow (http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/findwindow.asp), SendMessage (http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesfunctions/sendmessage.asp)) und die Struktur COPYDATASTRUCT (http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/dataexchange/datacopy/datacopyreference/datacopystructures/copydatastruct.asp).
Zu den zwei Funktionen hab ich hier im Forum schon die passenden Deklarationen gefunden. Mein Problem ist, wie ich folgenden Delphi Code in LS umsetzen kann.
hTargetWnd = FindWindow(nil,PChar('MyTestApp'))
function SendTextToWnd(hTargetWnd: HWND; Text : PChar): boolean;
var
MyCopyDataStruct: TCopyDataStruct;
begin
Result := true;
try
// TCopyDataStruct mit den Sende-Daten Infos ausfüllen
with MyCopyDataStruct do
begin
dwData := 0;
cbData := StrLen(Text) + 1;
lpData := Text
end;
// Die Struktur an den Empfänger schicken
if hTargetWnd <> 0 then
SendMessage(hTargetWnd, WM_COPYDATA, Longint(0), Longint(@MyCopyDataStruct));
except
Result := false;
end;
end;
Die C-Definition der Struktur ist folgende:
typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData;
DWORD cbData;
PVOID lpData;
}
Mein größtes Problem liegt darin, den String der Struktur zuzuordnen.
Mein bisherigen Versuche sahen so aus:
Private Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (Byval lpClassName&, Byval lpWindowName As String) As Long
Declare Function SendMessage Lib "user32.dll" (Byval hWnd As Long, Byval Msg As Long, Byval wParam As Long, lParam As Long) As Long
Keine Ahnung, wie das gehen soll :-:
Danke schonmal für eure Hilfe.
ps. Notes R5.0.11
Nun komm ich tatsächlich nicht mehr weiter ...
So sieht meine aktuelle Situation aus:
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (Byval lpClassName&, Byval lpWindowName As String) As Long
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, Byval cbCopy As Long)
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (Byval hwnd As Long, Byval wMsg As Long, Byval wParam As Long, lParam As Any) As Long
Private Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Const WM_COPYDATA = &H4A
Function SendData(Mode&, Data$) As Long
Dim DesthWnd As Long
Dim B(0 To 2048) As Integer
Dim CD As COPYDATASTRUCT
DesthWnd = FindWindow(0, "RecvWMCOPYDATA")
If DesthWnd = 0 Then
Msgbox ("AlphaCTI nicht gestartet! Bitte zuerst starten!")
Else
CD.dwData = Mode
Select Case Mode
Case 1: SendData = True 'String senden
Call CopyMemory(BArray(0), Byval Data, Len(Data))
CD.cbData = Len(Data) + 1
CD.lpData = B(0)
Case 2: SendData = True 'MsgBox anzeigen lassen
Case 3: SendData = True 'Anderen Prozeß sich selbst
'schließen lassen
End Select
If SendData Then
Call SendMessage(DesthWnd, WM_COPYDATA, 0, CD)
End If
End If
End Function
Mein Problem ist nun, dass ich B nicht als "Byte" definieren kann und zum 2. die Funktion VarPtr() nicht existiert.
Der VB-Code sieht folgendermaßen aus:
Private Function SendData(Mode&, Optional Data$) As Boolean
Dim DesthWnd As Long, B(0 To 255) As Byte
Dim CD As COPYDATASTRUCT
DesthWnd = FindWindow(vbNullString, "Destination")
If DesthWnd = 0 Then
MsgBox ("Das Zielfenster wurde nicht gefunden" & vbCrLf & _
"Bitte Starten sie erst das andere Projekt!")
Else
CD.dwData = Mode
Select Case Mode
Case 1: SendData = True 'String senden
Call CopyMemory(B(0), ByVal Data, Len(Data))
CD.cbData = Len(Data) + 1
CD.lpData = VarPtr(B(0))
Case 2: SendData = True 'MsgBox anzeigen lassen
Case 3: SendData = True 'Anderen Prozeß sich selbst
'schließen lassen
End Select
If SendData Then Call SendMessage(DesthWnd, WM_COPYDATA, _
Me.hwnd, CD)
End If
End Function
(Source stammt von http://www.activevb.de/tipps/vb6tipps/tipp0337.html)
Wäre nett, wenn mir einer von euch helfen könnte.