Jump to content

SendMessage Datastructure


Recommended Posts

Hi. I'm in need to control my program through SendMessages using autoit. My program is written in delphi, and the way I do a sendmessage is

procedure TForm1.Button1Click(Sender: TObject);
var
  MyCopyDataStruct: TCopyDataStruct;
  hTargetWnd: HWND;
begin
  with MyCopyDataStruct do
  begin
    dwData := 1;
    cbData := StrLen(PChar(Edit1.Text)) + 1;  
    lpData := PChar(Edit1.Text)
  end;
  hTargetWnd := FindWindow(nil,PChar('PowerVoice Receiver'));
  SendCopyData(hTargetWnd, MyCopyDataStruct);
end;

Now, when I actually try to do this is AutoIt, I get nothing, probably due to the data structure that I am using.

Does anyone have a way to translate this into the sendmessage used by autoit?

Thanks :)

Link to comment
Share on other sites

@0l33l

Is this helping you out ?

#include <misc.au3>

_Main()

Func _Main()
    Local Const $Off = 2, $On = -1

    Opt("WinTitleMatchMode", 4)
    $hwnd = WinGetHandle('classname=Progman')
    _ToggleMonitor($hWnd, $Off)
    Sleep ( 3000 )
    _ToggleMonitor($hWnd, $On)
EndFunc

Func _ToggleMonitor($hwnd, $OnOff)
    Local Const $WM_SYSCOMMAND = 274
    Local Const $SC_MONITORPOWER = 61808
    _SendMessage($hWnd, $WM_SYSCOMMAND, $SC_MONITORPOWER, $OnOff)
    If @error Then
        MsgBox(0,"_ToggleMonitor", "_SendMessage Error: " & @error)
        Exit
    EndIf
EndFunc

See helpfile for _SendMessage function

Regards

ptrex

Link to comment
Share on other sites

I changed the code to

Func _ToggleMonitor($hwnd, $OnOff)
    Local Const $WM_SYSCOMMAND = 274
    Local Const $SC_MONITORPOWER = 61808
    _SendMessage($hWnd, "?", "?", $OnOff)
    If @error Then
        MsgBox(0,"_ToggleMonitor", "_SendMessage Error: " & @error)
        Exit
    EndIf
EndFunc

;_Main()
Opt("WinTitleMatchMode", 4)
_ToggleMonitor(WinGetHandle("PowerVoice Receiver") , "?")

But nothing happens after I execute the script. I have a feeling that it is because the data structure is wrong.

Link to comment
Share on other sites

Hi. I'm in need to control my program through SendMessages using autoit. My program is written in delphi, and the way I do a sendmessage is

procedure TForm1.Button1Click(Sender: TObject);
var
  MyCopyDataStruct: TCopyDataStruct;
  hTargetWnd: HWND;
begin
  with MyCopyDataStruct do
  begin
    dwData := 1;
    cbData := StrLen(PChar(Edit1.Text)) + 1;  
    lpData := PChar(Edit1.Text)
  end;
  hTargetWnd := FindWindow(nil,PChar('PowerVoice Receiver'));
  SendCopyData(hTargetWnd, MyCopyDataStruct);
end;

Now, when I actually try to do this is AutoIt, I get nothing, probably due to the data structure that I am using.

Does anyone have a way to translate this into the sendmessage used by autoit?

Thanks :)

I think what you need will be something like this. I don't know what I'm talking about here really, but I think it will be something near.

Const $MW_COPYDATA=???

Func sendMyData($stringtosend)

$str1   = "int var1;int var2;int var3"
$a = DllStructCreate($str1);make a structure like the MyCoptDataStruct


$sl = stringlen($stringToSend)

$str2 = "char $var4[" & $sl & "]"
$b   = DllStructCreate($str2);make a struct for the string so we can get a pointer to it
DllStructSetData($b,"var4",$stringToSend)
$p1 = DllStructGetPtr($b);the pointer to the string

;fill the struct
DllStructSetData($a,"var1",1)
DllStructSetData($a,"var2",$sl)
DllStructSetData($a,"var3",$sp1)

_SendMessage(WinGetHandle("yourDelphiWindowTitle"),$WM_COPYDATA,$formgui,DllStructGetPtr($a)))

;free the structs
$a = 0
$b = 0
EndFunc

$formgui is the id of the form you create in autoit.

I don't know what the value of WM_COPYDATA is either but it will be in one of the Delphi modules or maybe the Windows SDK

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure SendCopyData(hTargetWnd: HWND; ACopyDataStruct:TCopyDataStruct);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.SendCopyData(hTargetWnd: HWND; ACopyDataStruct:TCopyDataStruct);
begin
  if hTargetWnd <> 0 then
    SendMessage(hTargetWnd, WM_COPYDATA, Longint(Handle), Longint(@ACopyDataStruct))
  else
    ShowMessage('No Recipient found!');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyCopyDataStruct: TCopyDataStruct;
  hTargetWnd: HWND;
begin
  with MyCopyDataStruct do
  begin
    dwData := 1;
    cbData := StrLen(PChar(Edit1.Text)) + 1;  
    lpData := PChar(Edit1.Text)
  end;
  hTargetWnd := FindWindow(nil,PChar('PowerVoice Receiver'));
  SendCopyData(hTargetWnd, MyCopyDataStruct);
end;

end.

Is the actual code. I guess that's what happens when you type your message at 1am :)

martin: why do you need the $MW_COPYDATA? I see it in the program, but its not declared anywhere as you can now see with my full code.

Link to comment
Share on other sites

  • 3 weeks later...

Bump? Please :)

If you just want to send a simple integer from an AutoIt script to a Delphi app then it can be done like this

;AutoIt
#include <misc.au3>

;send the two numbers 367 and 891 using message number 2000
_SendMessage(WinGetHandle("getMessage"),2000,367,891,0,'int','int')

//Delphi - form title is 'getMessage'
//just a form with 2 labels on it
unit DElphiMess001;

interface

uses
  Windows, SysUtils,  Messages,Classes,  Forms,
  StdCtrls, Controls;     //   Variants,   Dialogs, Graphics,

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;

  private
      procedure WMCopyData(var Message: TMessage); message 2000;//WM_COPYDATA;

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.WMCopyData(var Message: TMessage);
begin
   label1.Caption := intToStr(Message.WParam);
   label2.Caption := intToStr(Message.LParam);
end;

end.
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

martin: thank you for the reply :)

The problem is that your code only works for numbers, and I definitely need a way to transfer strings.

The good thing is that the current code isn't too interwoven in the program, and I can replace it with code that you can give me.

Thanks again,

David

Link to comment
Share on other sites

Look here

That's a good find Zedna. I tried using that and changed it a bit to produce this

Autoit simple send a string to Delphi

#include <misc.au3>

; Windows Definitions
Global Const $StructDef_COPYDATA = "dword var1;dword var2;ptr var3";I have changed piccaso's structure
Global Const $WM_COPYDATA = 0x4A


$TextToSend = "Something for us to shout about!"
$CDString = DllStructCreate("char var1[256]");the array to hold the string we are sending

DllStructSetData($CDString,1,$TextToSend)
$pCDString = DllStructGetPtr($CDString);the pointer to the string

$vs_cds = DllStructCreate($StructDef_COPYDATA);create the message struct
DllStructSetData($vs_cds,"var1",0);0 here indicates to the receiving program that we are sending a string 
DllStructSetData($vs_cds,"var2",StringLen($TextToSend) + 1);tell the receiver the length of the string
DllStructSetData($vs_cds,"var3",$pCDString);the pointer to the string
$pStruct = DllStructGetPtr($vs_cds)
_SendMessage(WinGetHandle("getMessage"),$WM_COPYDATA,0,$pStruct)

MsgBox(0,'Done','String sent')

$vs_cds = 0;free the struct
$CDString = 0;free the struct

Delphi code to get the string, just a form with one label on it

//Delphi - form title is 'getMessage'
unit DElphiMess002

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    
    Label1: TLabel;
  private
    procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
    { Private-Declarations }
  public
    { Public-Declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMCopyData(var Msg: TWMCopyData);
var
  sText: array[0..255] of Char;
 
begin
  case Msg.CopyDataStruct.dwData of
    0: //we are being sent a string
      begin
        StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData);
        label1.Caption := sText;
      end;

  end;
end;

end.
Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...