2

I'm having a trouble with Windows Messages between a c# app and delphi app.

I did some examples with c# to c# and delphi to delphi but I cannot c# to delphi

Here is my related c# app which is WM sender codes

    void Game1_Exiting(object sender, EventArgs e)
    {
        Process[] Processes = Process.GetProcesses();

        foreach(Process p in Processes)
            if(p.ProcessName == Statics.MainAppProcessName)
                SendMessage(p.MainWindowHandle, WM_TOOTHUI, IntPtr.Zero, IntPtr.Zero);


    }

    private const int WM_TOOTHUI = 0xAAAA;
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int SendMessage(IntPtr hwnd, [MarshalAs(UnmanagedType.U4)] int Msg, IntPtr wParam, IntPtr lParam);

Here is my related delphi app which is WM reciever codes

    const
      WM_TOOTHUI = 43690;
    type
      private
        MsgHandlerHWND : HWND;
        procedure WndMethod(var Msg: TMessage);

    procedure TForm1.WndMethod(var Msg: TMessage);
    begin
      if Msg.Msg = WM_TOOTHUI then
      begin
        Caption := 'Message Recieved';
      end;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      MsgHandlerHWND := AllocateHWnd(WndMethod);
    end;

Thanks in advance.

1 Answer 1

5

You are sending the message to the main window handle. That's the handle of the instance of TForm1. But your window procedure is attached to a different window handle, the window handled created by your call to AllocateHWnd.

A simple fix would be to override WndProc in TForm1 rather than using AllocateHWnd.

// in your class declaration:
procedure WndProc(var Message: TMessage); override;

// the corresponding implementation:
procedure TForm1.WndProc(var Message: TMessage);
begin
  if Msg.Msg = WM_TOOTHUI then
  begin
    Caption := 'Message Recieved';
  end; 
  inherited;
end;

Or as Mason says, you can use the special message handling syntax of Delphi:

// in your class declaration:
procedure WMToothUI(var Message: TMessage); message WM_TOOTHUI;

// the corresponding implementation:
procedure TForm1.WMToothUI(var Message: TMessage);
begin
  Caption := 'Message Recieved';
end;

It's also possible that p.MainWindowHandle is not even the handle to your main window. If you are using an older version of Delphi then p.MainWindowHandle may locate the application's handle, Application.Handle. In which case you will need FindWindow or EnumWindows in your C# code to locate the desired window.

Also, your code would be clearer if you declared the message constant using hex in Delphi:

WM_TOOTHUI = $AAAA;
Sign up to request clarification or add additional context in comments.

10 Comments

Or, even simpler than that, create a message method on TForm1 that handles WM_TOOTHUI. No WndProc rewriting needed!
@David Heffernan I tried your first advice but it recieving some messages except my WM_TOOTHUI message
Is the handle of the TForm1 instance the same as the handle that your C# program is sending the message to? If so, then it will arrive. If not then, well, it won't.
I ask again. Is the handle that you send the message to the same as the handle of the Delphi form? One possible failure mode is that you are sending it to the Delphi Application.Handle. You might need to be more careful in how you get the handle to make sure you get the right one. Another possible failure mode is that your Delphi IDE runs as admin.
First of all check whether your two handles match. If not, you need FindWindow or EnumWindows. If they do match your message is being blocked by UIPI. Stop running your Delphi app elevated.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.