当与多个好友聊天时,客户端接收到好友发来的聊天信息后,如何准确地在好友的聊天框里显示。
现在我已经实现:当有好友发送聊天信息时,先判断是否存在与这个好友聊天的窗口,如果没有就新建一个聊天
窗口,并将窗口的caption属性设置为: 与XXXX聊天中,并将窗口的name属性设置为:'frm_'+ID(ID为用户的帐号)。
打个比如:有一个帐号为123456的好友发来信息,那么客户端就会新建一个name为frm_123456的聊天窗口,
当再有123456好友发来的信息后就直接显示在这个frm_123456聊天窗口就行了,
但是这个frm_123456是在新建聊天窗口时,是由'frm_'+ID生成的,如何帐号不同,生成的也不同。
现在一直困扰我的就是,如何向这个动态生成的聊天窗口发送信息?具体代码如何实现?
希望大家能给我一个思路。
说的很乱,希望大家能看懂。呵呵 

解决方案 »

  1.   

    你不显示窗口自身的标题,由'frm_'+ID 当标题绘上去,
    使用FINDOWS的时候用原来的标题查找,和这个'frm_'+ID无关了 
      

  2.   

    两个问题分别回答你
    1、首先每个好友聊天时候,弹出聊天窗体的时候会检测是否已经打开聊天窗体,没有则弹出,有的话,弹到前台显示(因为可能最小化到任务栏了)。
    2、如何向窗体传消息。其实很简单,那就是你收到数据后,窗体显示聊天内容你总会吧,就是把收到的信息,用自己格式化的格式显示到收到者的窗体聊天区内即可。
    第一问题的实现方式,就是每次产生的窗体都用数组来保存好友id和对应窗体的handle,可以实现新聊天的时候来检查是否新建还是弹到前台。
    第二个问题的实现其实就是delphi+html+webbrowser,至于显示的样式,其实就可以用div+css+jsp实现。
      

  3.   

    使用findwindows查找,得到的是窗口的句柄,
    你的意思是通过句柄向窗口发送聊天信息?
    我看过一个多窗口的聊天服务器的源代码,它大概是这样实现的:
    以下是部分代码:frmchat为聊天窗口
     // frmIndex:integer;//聊天对话框索引,唯一值procedure TfrmMain.ShowChatFrm(ID:string);
    begin
      frmIndex:=FindFormByID(ID);
      frmChat[frmIndex]:=CreateChatFrm(ID,frmIndex,false);
      if (FIFOIndex.Count >0) and (FIFOIndex.IndexOf(inttostr(frmIndex))>-1) then
        FIFOIndex.Delete(FIFOIndex.IndexOf(inttostr(frmIndex)));
      if IsIconic(frmChat[frmIndex].Handle) then
        frmChat[frmIndex].WindowState := wsNormal
      else
        frmChat[frmIndex].show;  if (FIFOIndex.Count<=0) then
      begin
        Tray1.Animate :=false;
        Tray1.IconIndex :=0;
      end;
    end;
    **********************************
    function TfrmMain.FindFormByID(ID: string): integer;
    var
      i:integer;
    begin
      result:=-1;
      for i:=0 to high(UserInfo^) do
        if ID=strpas(UserInfo^[i].ID) then
        begin
          result:=i;
          break;
        end
    end;
    ****************************
    function TfrmMain.CreateChatFrm(ID:string;Index:integer;ExecGame:Boolean):TfrmChat;
    begin
      if Index>-1 then
      begin
        if UserInfo^[Index].Logined='0' then
        begin
          frmmain.Information('连接失败,对方可能下线!');
          abort;
        end;
        if not assigned(frmChat[Index]) then
          result:=TfrmChat.Create(self)
        else
          result:=frmChat[Index];
        if ExecGame then//执行游戏要放在返回用户信息之前
          result.RzBitBtn5.Enabled :=false
        else
          result.RzBitBtn5.Enabled :=true;
        result.UserHandle:=STRPAS(UserInfo^[Index].Handle);
        result.Name :='Frm_'+ID;
        result.ID :=ID;
        result.Index :=Index;
        tray1.IconIndex :=0;
        send('U',myHandle,UserInfo^[Index].Handle,UserInfo^[Index].ID,'','','','');//获得聊天用户IP
      end
      else
        result:=nil;
    end;
    ******************************
    我是自学delphi的,以下这句代码的写法,我想也想不明白。
    frmChat[frmIndex].WindowState := wsNormal
      

  4.   

    使用findwindows查找,得到的是窗口的句柄,
    你的意思是通过句柄向窗口发送聊天信息?
    我看过一个多窗口的聊天服务器的源代码,它大概是这样实现的:
    以下是部分代码:frmchat为聊天窗口
     // frmIndex:integer;//聊天对话框索引,唯一值procedure TfrmMain.ShowChatFrm(ID:string);
    begin
      frmIndex:=FindFormByID(ID);
      frmChat[frmIndex]:=CreateChatFrm(ID,frmIndex,false);
      if (FIFOIndex.Count >0) and (FIFOIndex.IndexOf(inttostr(frmIndex))>-1) then
        FIFOIndex.Delete(FIFOIndex.IndexOf(inttostr(frmIndex)));
      if IsIconic(frmChat[frmIndex].Handle) then
        frmChat[frmIndex].WindowState := wsNormal
      else
        frmChat[frmIndex].show;  if (FIFOIndex.Count<=0) then
      begin
        Tray1.Animate :=false;
        Tray1.IconIndex :=0;
      end;
    end;
    **********************************
    function TfrmMain.FindFormByID(ID: string): integer;
    var
      i:integer;
    begin
      result:=-1;
      for i:=0 to high(UserInfo^) do
        if ID=strpas(UserInfo^[i].ID) then
        begin
          result:=i;
          break;
        end
    end;
    ****************************
    function TfrmMain.CreateChatFrm(ID:string;Index:integer;ExecGame:Boolean):TfrmChat;
    begin
      if Index>-1 then
      begin
        if UserInfo^[Index].Logined='0' then
        begin
          frmmain.Information('连接失败,对方可能下线!');
          abort;
        end;
        if not assigned(frmChat[Index]) then
          result:=TfrmChat.Create(self)
        else
          result:=frmChat[Index];
        if ExecGame then//执行游戏要放在返回用户信息之前
          result.RzBitBtn5.Enabled :=false
        else
          result.RzBitBtn5.Enabled :=true;
        result.UserHandle:=STRPAS(UserInfo^[Index].Handle);
        result.Name :='Frm_'+ID;
        result.ID :=ID;
        result.Index :=Index;
        tray1.IconIndex :=0;
        send('U',myHandle,UserInfo^[Index].Handle,UserInfo^[Index].ID,'','','','');//获得聊天用户IP
      end
      else
        result:=nil;
    end;
    ******************************
    我是自学delphi的,以下这句代码的写法,我想也想不明白。
    frmChat[frmIndex].WindowState := wsNormal
      

  5.   

    创建一个TStringList对象,向其中添加向你发送信息的ID,并添加与之关联的窗口。
    然后,以后收到消息,就到TStringList当中查询,有,就发送给绑定的窗口;
    没有,就创建窗口并向TStringList添加ID和窗口。
    形如,
    var
      strl: TStringList;
      ID: string;
    ... {可能的其他操作}begin
      ...{可能的其他操作}
      if strl.IndexOf(ID)> -1 then
      begin
        XXForm(strl.GetObject[strs.IndexOf(ID)]).GetMessage(strChatMessage);
        ...{可能的其他操作}
      end;
      ...{可能的其他操作, 向TStringList中添加的操作就不用我罗嗦了吧?}
    end;
        
      

  6.   

    XXForm(strl.GetObject[strs.IndexOf(ID)]).GetMessage(strChatMessage); 
    应为:XXForm(strl.GetObject[strl.IndexOf(ID)]).GetMessage(strChatMessage); 
    笔误,抱歉。
    另外GetMessage应为自定义函数,我给出的是伪代码,仅供提供思路。也许叫GetChatMessage更贴切。