Solved

API SendMessage Help

Posted on 2002-06-04
10
833 Views
Last Modified: 2008-02-01
I'm trying to learn about sendmessage.  I see this in all my books and all over the web but nowhere is it explained..

SendMessage(...)
LRESULT SendMessage(
  HWND hWnd,      // handle to destination window
  UINT Msg,       // message
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);


--------
From mIRC's help file
--------
SendMessage(mHwnd, WM_MCOMMAND, cMethod, 0L)

mHwnd - the handle of the main mIRC window, or the handle of a Channel, Query, etc. window.

WM_MCOMMAND - which should be defined as WM_USER + 200

cMethod - the way in which you want mIRC to process the message, where:
        1 = As if typed in editbox
        2 = As if typed in editbox, send as plain text
        4 = Use flood protection if turned on, can be or'd with 1 or 2

Returns - 1 if success, 0 if fail
---

{Parameters}

1. I have no problem with the handle, My target app (mIRC) is ready to receive a message and I have it's handle.

2. WM_MCOMMAND = UINT Msg....
I want to send a string here, I assume it must be a pointer but "which should be defined as WM_USER+200"
is killing me.  What does that mean?
 
3. No help needed

4. "0L", do you suppose this is just expecting a 0 as if it were not used?

---------

Also, does my app have to be a COM Object to use Sendmessage?


Example source would help but my primary need is an explanation of the second parameter.  

Thanks in advance.

Don
0
Comment
Question by:d32coder
10 Comments
 

Author Comment

by:d32coder
ID: 7053327
I see now that this involves creating a mapped file..  
Still could use an example though...
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7053352
type sendmessage in delphi. press F1 and you will get help on the function.

Now you should know what message you want to send(receive).
If you dont, tell what you want to do and may be I can help
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7053358
:) I seen that it's 500 point question (too big for what I mean). May be I misunderstand the question, so you should ask more clearly :)
0
 

Author Comment

by:d32coder
ID: 7053373
I want to pass a string to mirc.exe in a mapped file via Sendmessage.

Mirc wants it in this format..
SendMessage(mHwnd, WM_MCOMMAND, cMethod, 0L)
...
WM_MCOMMAND - which should be defined as WM_USER + 200
^^ this is causing me some trouble, need to declare some kind of varible to use there.  

I tried..  wmC: LongInt = WM_USER + 200;
but it doesn't seem to work.


----------
Second half.

I created a mapped file as instructed, now I need to set a string of variable length as data inside the mapped file.  The mapped file needs to be 1024 bytes in length.

Here is what I tried.

hMapFile := CreateFileMapping($FFFFFFFF,
    nil,  Page_ReadWrite, 0,
    SizeOf(byte) * 1024, 'mIRC');

if hMapFile = 0 then
  raise Exception.Create('Error creating Mapped File.');

 ShareData := MapViewOfFile(hMapFile,
    File_Map_Write, 0, 0, SizeOf(byte) * 1024);

-------
That part SEEMS to work.

Now I want to...
  ShareData^ := 'My text string';
   ^^  This is very wrong.

-------  

500 points for being a multipart question.

_________________________
APPENDIX from the mirc help file

The following call to SendMessage() makes mIRC perform the commands that you specify.

   SendMessage(mHwnd, WM_MCOMMAND, cMethod, 0L)

   mHwnd - the handle of the main mIRC window, or the handle of a Channel, Query, etc. window.

   WM_MCOMMAND - which should be defined as WM_USER + 200

   cMethod - the way in which you want mIRC to process the message, where:
        1 = As if typed in editbox
        2 = As if typed in editbox, send as plain text
        4 = Use flood protection if turned on, can be or'd with 1 or 2

   Returns - 1 if success, 0 if fail




The application that sends these messages must create a mapped file named mIRC with CreateFileMapping().

When mIRC receives the above messages, it will open this file and use the data that this mapped file contains to perform the command or evaluation. In the case of an evaluation, mIRC will output the results to the mapped file.

The mapped file must be at least 1024 bytes in length.





0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7053431
it's weird that lParam isn't used


var ShareData: PChar = nil;


ShareData := MapViewOfFile(hMapFile,
   File_Map_Write, 0, 0, SizeOf(byte) * 1024);

StrPLCopy(ShareData, MyString, Length(MyString));

if SendMessage(hWinMirc, WM_MCOMMAND, cMethod, 0) = 1 then
  ResultString:=string(ShareData); // in case of a query function

hope it helps :)
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:d32coder
ID: 7053466
Still not working..  here's my code.
---------------------------------------
var
  Form1: TForm1;
  ChanList: TStringlist;
  MircHandle: LongInt;
  hMapFile: THandle;
  ShareData: PChar = nil;
  mCOMMAND: LongInt = WM_USER + 200;
  MC: LongInt;

const
 VirtualName = 'mIRC';

implementation

{$R *.dfm}

Procedure TForm1.FormCreate(Sender: TObject);
Begin
 ChanList := TStringlist.Create;
 UpdateActives1Click(self);
 MC := WM_USER + 200;
 hMapFile := CreateFileMapping($FFFFFFFF, nil, Page_ReadWrite, 0, SizeOf(byte) * 1024, virtualname);
 if hMapFile = 0 then
  raise Exception.Create('Error creating Memory Mapped File, this program can only be run in WinNT, 2000 or XP');
  ShareData := MapViewOfFile(hMapFile, File_Map_Write, 0, 0, SizeOf(byte) * 1024);
End;

Procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
Begin
 ChanList.Free;
 UnMapViewOfFile(Sharedata);
 CloseHandle(hMapFile);
End;

function TForm1.TaskList(FirstHandle: THandle; ListAll: Boolean): string;
var
  lngLen:longint;
  strBuffer, This, All:string;
  TaskHandle: THandle;
begin
  MircHandle := 0;
  cbChans.ItemIndex := -1;
  cbChans.Items.Clear;
  ChanList.Clear;
  TaskHandle := GetWindow(FirstHandle,GW_HWNDFIRST);
  while TaskHandle > 0 do
  begin
     if (TaskHandle <> FirstHandle) and (TaskHandle <> Application.Handle) then
     begin
        lngLen := GetWindowTextLength(TaskHandle) + 1;
        SetLength(strBuffer,lngLen);
        lngLen := GetWindowText(TaskHandle,PChar(strBuffer),lngLen);
        if lngLen > 0 then
        begin
           This := TrimRight(strBuffer);
           if pos('#',This) = 1 then
             begin
             ChanList.Append(IntToStr(TaskHandle));
             cbChans.Items.Append(Copy(This,1,(pos(' ',This)-1)));
             end;
          if pos('mIRC',This) = 1 then MircHandle := TaskHandle;
        end;
     end;
     TaskHandle := GetWindow(TaskHandle,GW_HWNDNEXT);
  end;
  if MircHandle = 0 then ShowMessage('Mirc Handle Not found!');
end;

Procedure TForm1.UpdateActives1Click(Sender: TObject);
Begin
  TaskList(Application.Handle,TRUE);
  if cbChans.Items.Count > 0 then cbChans.ItemIndex := 0;
End;

procedure TForm1.buttonSendThisClick(Sender: TObject);
 var T: String;
Begin
 T := '/msg _Psych Hello!';
 StrPLCopy(ShareData, T,Length(T));
 if SendMessage(mirchandle,MC,2,0) = 0
  then Showmessage('SendMessage returned ERROR!');
End;

procedure TForm1.GetShareData(P: Pchar);
Begin
  // TODO
End;

procedure TForm1.SetShareData(P: PChar);
Begin
  // TODO
End;

procedure TForm1.Exit1Click(Sender: TObject);
Begin
  Application.Terminate;
End;

END.

0
 
LVL 3

Accepted Solution

by:
Slavak earned 500 total points
ID: 7053483
This is working code:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    MircH   : HWND;
    MapFile : THandle;
    Buffer  : PChar;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

Const
 mIRC           = 'mIRC';
 WM_MCOMMAND    = WM_USER + 200;
 BufSize        = 1024;

procedure TForm1.Button1Click(Sender: TObject);
begin
  StrLCopy(Buffer, PChar(Edit1.Text), BufSize);

  SendMessage(MircH, WM_MCOMMAND, 1, 0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Caption := 'mIRC not found';

 MircH := FindWindow(mIRC, nil);
 If MircH = 0 Then
   Exit;

 MapFile := CreateFileMapping(Cardinal(-1), nil, PAGE_READWRITE, 0, BufSize, mIRC);
 if MapFile = 0 Then
  Exit;

 Buffer := MapViewOfFile(MapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
 If Buffer = nil then
  Exit;

 Caption := 'Connected to mIRC';
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 UnmapViewOfFile(Buffer);
 CloseHandle(MapFile);
end;

end.


Regards.
0
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 7053504
You simply send a message to mIRC and it starts to handle the mapped file.
"WM_MCOMMAND - which should be defined as WM_USER + 200"
is simply the Windows message to send.

const
  WM_MCOMMAND = WM_USER+200;


There is NO way to send a string through any Windows message parameter except WM_COPYDATA.
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 7055441
Check this out

http://necroman.wot.net/dllhelp.htm#_SendMessage

It seems to use WM_USER + 201 instead, though.
0
 

Author Comment

by:d32coder
ID: 7055765
Works fine.  Thank you!

Thanks to everyone else as well.  If I had enough points to spread around I'd give you all the same.  

Don
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Convert Jpg /PNG To GIF 5 120
Communication Between RC4 Delphi <-> PHP 3 100
Is anyone willing to have a look through this code and help debug? 25 60
Base1 Encode/Decode 3 68
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now