Использование WM_COPYDATA с приложениями Delphi-Prism

У кого-нибудь есть хороший пример delphi-prism для получения и интерпретации сообщения WM_COPYDATA? Меня особенно интересует, как работать со структурой данных сообщения.


person Warren Stanley    schedule 20.09.2010    source источник


Ответы (1)


Уоррен, ключ для расшифровки сообщения, зависит от того, как вы определяете свой COPYDATASTRUCT запись в приложениях отправителя и получателя и использование GetLParam.

проверьте этот код

//the sender application, this is a simple console app
namespace ConsoleApplication_PrismSendData;

interface
uses
    System.Runtime.InteropServices;
type
  [StructLayout(LayoutKind.Sequential)]
  CopyDataStruct = public record //the record to be passed by the WM_COPYDATA message. 
  public
    var     dwData: IntPtr;
    var     cbData: System.Int32;
    var     [MarshalAs(UnmanagedType.LPStr)] //in this case using a pointer to a null-terminated array of ANSI characters.
    lpData: System.String;
  end;

  ConsoleApp = class
  public
    const     WM_COPYDATA: System.Int32 = $4a;//WM_COPYDATA  0x004A
    class method Main(args: array of string);
    [DllImport('user32.dll', EntryPoint := 'FindWindow')]
    class method FindWindow(lpClasName: System.String; lpWindowName: System.String): System.IntPtr; external;
    [DllImport('user32.dll', EntryPoint := 'SendMessage')]
    class method SendMessage(hWnd: System.IntPtr; Msg: System.Int32; wParam: System.Int32; var lParam: CopyDataStruct): System.Int32; external;
  end;


implementation

class method ConsoleApp.Main(args: array of string);
var
 cd   : CopyDataStruct;
 WHnd : IntPtr; 
begin
 cd.dwData := IntPtr(0);//Dummy
 cd.lpData := 'Hello from Delphi Prism - Console Application';//message to send
 cd.cbData := cd.lpData.Length;//set the length of the message
 WHnd      := FindWindow(nil, 'PrismForm');//find the handle for the window of the receiver app
 if (WHnd<>System.IntPtr.Zero) then //check if <> to 0
 begin
  SendMessage(WHnd, WM_COPYDATA, 0, var cd); //Send the message to the app
  Console.WriteLine('Message sent');
 end
 else
 Console.WriteLine('Window not found');
 Console.ReadKey();
end;

end. 

Теперь код для приложения-приемника.

сначала вы должны переопределить WndProc method , для этого просто напишите что-то вроде этого.

  MainForm = partial class(System.Windows.Forms.Form) //this is your form
  private
    const     WM_COPYDATA: System.Int32 = $4a; //declare the const for WM_COPYDATA message
  protected
    method Dispose(disposing: Boolean); override;
    method WndProc(var m: Message); override;//override WndProc method to process the messages
  public
    constructor;
  end;

затем объявите ту же структуру приложения-отправителя для обработки сообщения

  [StructLayout(LayoutKind.Sequential)] 
  CopyDataStruct = public record
  public
    var     dwData: IntPtr;
    var     cbData: System.Int32;
    var     [MarshalAs(UnmanagedType.LPStr)]
    lpData: System.String;
  end;

и, наконец, реализовать метод WndProc, подобный этому

method MainForm.WndProc(var m: Message);
var 
cd: CopyDataStruct;
s : System.String;
begin
  case m.Msg of 
    WM_COPYDATA:  
                begin
                  //the  GetLParam function convert the LParam value an object.
                  //the  typeof function obtains the type of an object
                  cd:= m.GetLParam(typeof(CopyDataStruct)) as CopyDataStruct;
                  s := cd.lpData.Substring(0,cd.cbData);
                  // do your stuff here
                end;
  end;
  inherited WndProc(var m);
end;
person RRUZ    schedule 23.09.2010
comment
Это отлично работает, спасибо, но у меня, похоже, проблемы, если переменная lpData не является строкой. Любые идеи, как я мог бы сделать это с переменной lpData, например, с массивом целых чисел? Я безуспешно пытался сортировать как LPArray ByValArray и SafeArray. - person Warren Stanley; 27.09.2010