我在被调用的dll中向调用者(EXE程序)SendMessage了一个消息(自定义的)可是我的EXE的Form好像没有收到

解决方案 »

  1.   

    你是怎么得到句柄的?可用以下三者之一1.最简单的方法是用FindWindow()函数2.其次是写一个文本文件,在exe中把窗口的句柄写进取,在dll中发消息时把句柄读出来3.使用内存映像文件(推荐使用)
      

  2.   

    还是我回答你吧!在你EXE的FORM中重载下列函数
     procedure WndProc(var Message: TMessage); override;
     procedure TFormMain.WndProc(var Message: TMessage); 
     begin
       case message.msg of
         YOUR_DEFINE_MSG_CONST:
         begin
            ShowMessage('收到');
            // 处理 
         end;
       end;
       inherited WndProc(message);
     end;
      

  3.   

    1,定义了消息的处理了吗?如楼上;
    2,你发消息的HANDLE怎么来的?一定正确吗?
    3,你怎么发的消息啊?
      

  4.   

    以下是exe部分代码
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;  const
          SX_MY_CLOSE=WM_USER+100;
      type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }     procedure WndProc(var Message: TMessage); override;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation
          function myshow(Ahandle:Thandle;AForm:Thandle;ACaption:String):Longint; external 'mydll.dll';
          procedure myclose(AFormRef:Longint);external 'mydll.dll';
    {$R *.DFM}procedure TForm1.WndProc(var Message: TMessage);
    begin
       case message.msg of
         SX_MY_CLOSE:
         begin
            ShowMessage('收到');
         end;
       end;
       inherited WndProc(message);
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
       tmp:Longint;
    begin
        tmp:=myshow(application.Handle,Form1.Handle,'test');
    end;end.以下是dll部分代码unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;type
      TForm1 = class(TForm)
        Label1: TLabel;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }  public
        { Public declarations }
         mhandle: Thandle;
         melogint:Longint;
      end;
      const SX_MY_CLOSE = WM_USER+100;
      function myshow(Ahandle:Thandle;Aform:Thandle;ACaption:String):Longint;
      procedure myclose(AFormRef:Longint);implementation{$R *.DFM}function myshow(Ahandle:Thandle;Aform:Thandle;ACaption:String):Longint;
    var
      Form1: TForm1;
    begin
      Application.handle:=Ahandle;
      Form1.mhandle:=Aform;
      Form1:=TForm1.Create(Application);
      Form1.Caption:=ACaption;
      Result:=Longint(Form1);
      Form1.melogint:=Longint(Form1);
      Form1.Show;
    end;procedure myclose(AFormRef:Longint);
    begin
      if AFormRef>0 then
         TForm1(AFormRef).Release;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
       SendMessage(mhandle,SX_MY_CLOSE,0,0);
    end;end.请指出错误,thanks
      

  5.   

    句柄在这里传递是无效的把发消息的语句改为
    PostMessage(FindWindow(pchar('TForm1'), pchar('Form1')), SX_MY_CLOSE, 0, 0);应该没有问题了
      

  6.   

    这个函数有错:
    function myshow(Ahandle:Thandle;Aform:Thandle;ACaption:String):Longint;
    var
      Form1: TForm1;
    begin
      Application.handle:=Ahandle;
      Form1.mhandle:=Aform;
      Form1:=TForm1.Create(Application);
      Form1.Caption:=ACaption;
      Result:=Longint(Form1);
      Form1.melogint:=Longint(Form1);
      Form1.Show;
    end;
    应改为:function myshow(Ahandle:TApplication;Aform:Thandle;ACaption:String):Longint;
    var
      Form1: TForm1;
    begin
      Application:= Ahandle;
      Form1.mhandle:=Aform;
      Form1:=TForm1.Create(Application);
      Form1.Caption:=ACaption;
      Result:=Longint(Form1);
      Form1.melogint:=Longint(Form1);
      Form1.Show;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
       SendMessage(Application.MainForm.Handle,SX_MY_CLOSE,0,0);
    end;
      

  7.   

    谢谢 wisenowa(127.0.0.1) 可以了, wisenowa(127.0.0.1)能讲讲为什么?
    为什么我两个窗体都是TForm类的而且实例变量都是Form1他就能找到我的主窗体而不是dll的那个窗体呢
      

  8.   

    现在的问题是,整个程序退出时报非法操作,我在贴一下改过的代码大家看看
    exe部分unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;  const
          SX_MY_CLOSE=WM_USER+100;
      type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
         tmp:Longint;
         procedure WndProc(var Message: TMessage); override;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation
          function myshow(Ahandle:Thandle;AForm:Thandle;ACaption:String):Longint; external 'mydll.dll';
          procedure myclose(AFormRef:Longint);external 'mydll.dll';
    {$R *.DFM}procedure TForm1.WndProc(var Message: TMessage);
    begin
       case message.msg of
         SX_MY_CLOSE:
         begin
            myclose(tmp);
            tmp:=0;
         end;
       end;
       inherited WndProc(message);
    end;
    procedure TForm1.Button1Click(Sender: TObject);begin
        if tmp=0 then
        tmp:=myshow(application.Handle,Form1.Handle,'test');
    end;end.dll部分unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;type
      TForm1 = class(TForm)
        Label1: TLabel;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }  public
        { Public declarations }
         mhandle: Thandle;
         melogint:Longint;
      end;
      const SX_MY_CLOSE = WM_USER+100;
      function myshow(Ahandle:Thandle;Aform:Thandle;ACaption:String):Longint;
      procedure myclose(AFormRef:Longint);implementation{$R *.DFM}function myshow(Ahandle:Thandle;Aform:Thandle;ACaption:String):Longint;
    var
      Form1: TForm1;
    begin
      Application.handle:=Ahandle;
      Form1.mhandle:=Aform;
      Form1:=TForm1.Create(Application);
      Form1.Caption:=ACaption;
      Result:=Longint(Form1);
      Form1.melogint:=Longint(Form1);
      Form1.Show;
    end;procedure myclose(AFormRef:Longint);
    begin
      if AFormRef>0 then
         TForm1(AFormRef).Release;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      // SendMessage(Application.MainForm.Handle,SX_MY_CLOSE,0,0);
      PostMessage(FindWindow(pchar('TForm1'), pchar('Form1')), SX_MY_CLOSE, 0, 0);
    end;end.
      

  9.   

    原因就是不能把Dll看成是一个Exe,在Dll中全局变量好像不大好使,除非你在同一个Dll中且在同一次调用中可以,不过这样的话,全局变量还有社么意义?
    不过有一点可以确定,就是当你在一个函数中对一个控件的属性赋值时好像可以在别的函数中看到,原因:我也不太清楚。你在消息处理时调用MyClose干什么?要关闭Dll的窗体吗?直接在Button1Click事件里加上Close就行了
      

  10.   

    因为大部分调用dll中窗体的程序都是由主调程序创建实例,再由主调程序将实例设为nil,以控制重复打开窗口,可是一般的使用习惯,大家喜欢在要关闭的窗口上直接关闭该窗口,所以我为了避免实例重复就在关闭dll窗体的时候发了个消息给主程序,让主程序来关闭他,并将主程序中的实例变量(句柄)设为0
      

  11.   

    呵呵,你完全可以在发送给主窗体消息后关闭关闭窗体PostMessage(FindWindow(pchar('TForm1'), pchar('Form1')), SX_MY_CLOSE, 0, 0);
    Close;当你的主程序收到消息后将计数器减 1效果不一样吗?
      

  12.   

    我虽然没有Dll与EXE消息通讯的经验,但我有Application EXE与Service EXE消息通讯的经验,事实上,无法成功,我从Service中Sendmessage到一个已知的Window handle,根本收不到。查了半天资料,说是Service 与Application 之间不能通过消息来通讯。希望对你这个问题有些启发。
      

  13.   

    反过来也不行Application To Service也不可能成功!MS推荐说是要用Socket什么的,TMD,本机两个应用交互还要Socket,Faint!!!
      

  14.   

    to redbirdli(火鸟)
      两个进程间通信,用内存映像文件就可以了
       CreateFileMapping();
      MapViewOfFile();看一下Delphi的帮助。
      

  15.   

    我说一句!:)
    你自定义的消息要注册成为系统消息,这样就可以了!呵呵:)注册消息API:
    RegisterWindowMessage
    发送消息API:
    BroadcastSystemMessage这种消息可以跨进程传递。