type
  TSuperClientForm = class(TForm, IChatEvents)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Label3: TLabel;
    LabelState: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label10: TLabel;
    Label4: TLabel;
    Label9: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    edUsers: TListBox;
    SendButton: TButton;
    LogonButton: TButton;
    LogoffButton: TButton;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    EditServerIP: TEdit;
    EditServerPort: TEdit;
    EditAgentCode: TEdit;
    EditQueueList: TEdit;
    EditLoginTime: TEdit;
    EditRestTypeCode: TEdit;
    EditUserCode: TEdit;
    RadioButton1: TRadioButton;
    RadioButtonAuto: TRadioButton;
    ListView1: TListView;
    edText: TMemo;
    EditReqReason: TEdit;
    Memo1: TMemo;
    Memo2: TMemo;
    ROMessage: TROBinMessage;
    ROChannel: TROSuperTCPChannel;
    RORemoteService: TRORemoteService;
    ROEventReceiver: TROEventReceiver;
    cdsCustomers: TClientDataSet;
    dsCustomers: TDataSource;
    RODataSnapConnection1: TRODataSnapConnection;
    HTTPChannel: TROWinInetHTTPChannel;
    ConnectButton: TBitBtn;
    DisconnectButton: TBitBtn;
    ROBinMessage: TROBinMessage;
    gProducts: TDBGrid;
    Panel1: TPanel;
    ButtonOK: TButton;
    Button1: TButton;
    Label13: TLabel;
    Edit1: TEdit;
    procedure FormDestroy(Sender: TObject);
    procedure SendButtonClick(Sender: TObject);
    procedure LogonButtonClick(Sender: TObject);
    procedure LogoffButtonClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure EditQueueListChange(Sender: TObject);
    procedure EditLoginTimeChange(Sender: TObject);
    procedure EditRestTypeCodeChange(Sender: TObject);
    procedure EditUserCodeChange(Sender: TObject);
    procedure RadioButtonAutoClick(Sender: TObject);
    procedure RadioButton1Click(Sender: TObject);
    procedure EditReqReasonChange(Sender: TObject);
    procedure EditServerIPChange(Sender: TObject);
    procedure ButtonOKClick(Sender: TObject);
    procedure DisconnectButtonClick(Sender: TObject);
    procedure ConnectButtonClick(Sender: TObject);
    procedure ApplyUpdatesButtonClick(Sender: TObject);
    procedure OnEnableApplyUpdates(DataSet: TDataSet);
    procedure cdsCustomersAfterEdit(DataSet: TDataSet);
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FSendMsg,aUserName: string;
    FMessageServer: TMessageServer;
    FConnected: Boolean;
    lLogin: ILoginService;
    lChat: IChatServerService;
    { Private declarations }
    procedure MakeReqMessage;
  public
    //注册EVENT,在单独的程序中正常,但在DLL中不能正常返回
    procedure Message(const From: Widestring; const Target: Widestring;
      const Message: Widestring);
    procedure UserLogin(const Nickname: Widestring);
    procedure UserLogout(const Nickname: Widestring);
    procedure ShutdownServer;
    procedure DecodeMsg(aMsg: string);
    //收到消息
    procedure SyncCall(var Msg: TMessage); message WM_USER;    property MessageServer: TMessageServer write FMessageServer;  end;  TSyncType = (stMessage, stUserLogin, stUserLogout);
  TStringArray = array of Widestring;实现部分      lLogin := CoLoginService.Create(ROMessage, ROChannel);
      lChat := CoChatServerService.Create(ROMessage, ROChannel);
      ROEventReceiver.RegisterEventHandlers([EID_ChatEvents], [Self]);
      ROEventReceiver.Activate;在单独的程序每次调用LLogin和LChat,procedure Message 都能被解发并返回值。但被这些同样的代码和窗体弄到一个DLL中,一点变化都没有,就会出现procedure Message 无法被触发的情况! 搞了两天了没解决,谢谢大家了!

解决方案 »

  1.   

    这个程序就是RemObjects的 Super Tcp Chat 改的,结构没什么变化!
      

  2.   

    我只是搞不懂为什么单独的程序接收事件正常,封装进DLL就不行啦!  ROEventReceiver.RegisterEventHandlers([EID_ChatEvents], [Self]); 这句就把接收事件的对象赋给RoEventReceiver, 接收事件的窗体实现了IChatEvents这个接口,然后收到事件后会解发   procedure Message(const From: Widestring; const Target: Widestring;
      const Message: Widestring);
      

  3.   

    好像是因为dll没有自己的消息循环,所以消息没有被正确处理吧
    LZ可以试着由外部发送消息给dll窗体或者更改目前的消息处理机制,比如说内部消息触发改为函数触发~
      

  4.   

    Dll中窗体和程序中的窗体都是可以接收消息的,这个只有自己慢慢调试了
      

  5.   

    function CreateMessageConnection(IP: PChar; Port: integer; CallForm: THandle): Integer;stdcall;
    var
       mMessageServer: TMessageServer;
    begin
       result := 0;
       try
           mMessageServer.IP := IP;
           mMessageServer.Port := Port;
           mMessageServer.CallForm := CallForm;
           Application.Handle := CallForm;
           if SuperClientForm = nil then
           begin
               SuperClientForm := TSuperClientForm.Create(Application);
               SuperClientForm.ParentWindow := CallForm;
               SuperClientForm.MessageServer := mMessageServer;
               SuperClientForm.InitRemoteObjects;
               Result := SuperClientForm.Handle;
           end;   finally   end;
    end;这是DLL中修改的代码,加上了一个Timmer,在Timmer中添加procedure TSuperClientForm.Timer1Timer(Sender: TObject);
    begin
      Timer1.Enabled := false;
      try
        CheckSynchronize(1000);
      finally
        Timer1.Enabled := true;
      end;
    end;是实例了接收消息没问题了,但主程序由于加上这个Timer反应很慢,不知为什么?
      

  6.   

    楼主不能做个小demo,让大家下载调试看看?两种模式的。大家大多都没空给弄相同的环境,很费时间的。