一个多线程程序中,一个线程里怎么“合理”发送消息呢?举例说吧:窗口(模态显示)
FormMain 主窗口
FormA
FormB
FormC
....
FormJ线程(执行功能基本一样)
Thread1
Thread2
Thread3
.....
Thread16消息
WM_Message001
WM_Message002
WM_Message003
.....
WM_Message006后台线程的Execute()中:while true do
begin
  //检查线程是否要退出
  .....  for i:=0 to MaxCount-1 do
  begin
    //如果满足了某一条件,向需要处理Message002消息的窗口发送消息
    PostMessage(FMessage002Handle,WM_Message002,0,0); //FMessage002Handle是线程中一个私有变量,对应一个
                                                      //Message002Handle属性
    .....    //如果满足了某一条件,向需要处理Message003消息的窗口发送消息
   PostMessage(FMessage003Handle,WM_Message003,0,0); //FMessage003Handle是线程中一个私有变量,对应一个
                                                      //Message003Handle属性
    .....
  end;
  ....
  //如果满足了某一条件,向所有当前窗口发送消息
  PostMessage(Screen.ActiveForm.Handle,WM_Message001,0,0);
  ...
end;我的问题:
这儿就有一个设置消息目的窗口句柄的问题,除了WM_Message001是所有窗口都要处理的,还有FormA要处理WM_Message002和WM_Message003,FormB要处理WM_Message002,FormC要处理WM_Message003,等等,而且这些窗口有些是模态窗口,关闭后就释放了,有些窗口关闭后只是隐藏了,未释放。
我现在的做法是,在每个窗口的OnShow事件或OnActived事件里,设置所有线程的属性Message002Handle,Message003Handle, 感觉这样好零乱,增加一个消息,线程里就得增加一个属性。这程序肯定还得变动,刚开始试用。1、能不能在线程里全部用PostMessage(Screen.ActiveForm.Handle,WM_MessageXXX,0,0)来发送?窗口只处理自己需要处理的消息。这样会不会影响性能(大概最多会有16个线程)2、还有个蛋疼的想法:是不是自己能再做个消息转发分配中心什么的(也就是一个线程,专门用于消息分配和转发),也就是所有线程的消息先转发到这个“消息处理线程”,然后在这里再分配发送,感觉这个“消息处理线程”有画蛇添足之嫌,而且也影响了程序性能。大家碰到类似的问题,是怎么解决的?请指教啊

解决方案 »

  1.   

    http://topic.csdn.net/u/20110217/11/56577c65-2e77-4f8f-b541-0be47cdb4d60.html
      

  2.   

    用 IsWindow 检查句柄是否有效,有效再postmessage
      

  3.   

    2楼3楼的,你们回答的不是我需要的啊,只有1楼给了贴近的,不过太简单了,呵呵我的意思是说,一个程序里,当前窗口可能不是只有一个MAINFORM或某一个FORM,可能是FormA,也可能是FormB/FormC,而且,这些个Form可能显示完了就释放了,下次再显示再创建。而线程里的消息是要发给这些窗口中的所有窗口或者是某一个或一个以上的窗口,我目前的写法比较“零乱”,功能是实现了。我想问的是不是有什么比较“规范”的技巧,来统一消息的发送。置顶贴说的不是我的问题……
      

  4.   

    消息发主程序,由主程序决定向哪个窗口转发:
    PostMessage(Application.Handle, WM_MessageXXX, 0, 0);
      

  5.   

    一个笨办法; 把你那些变量用结构体数组代替,改成全局变量
    用它保存窗体的handle和窗体的关系,增加/减少窗体只要改变下标就行了
    窗体打开时设置handle,关闭时设置0;线程取值时加上锁,handle不是0的就发送消息出去
      

  6.   


    KK的想法还是与众不同,我记得我问的几个SQL问题都是你帮助解决的,开始试验你的“笨方法”,哈哈
      

  7.   

    向主线程所有窗口广播消息
    function __BroadcastMessageEnumProc(AHandle: HWND; AParam: lParam): Boolean; stdcall;
    var
      lpMsg: PMessage;
    begin
      if (AParam <> 0) and IsWindow(AHandle) then
      begin
        lpMsg := Pointer(AParam);
        PostMessage(AHandle, lpMsg.Msg, lpMsg.wParam, lpMsg.lParam);
      end;
      Result := True;
    end;procedure BroadcastMessage(Msg: UINT; wParam: wParam; lParam: lParam);
    var
      mtid: DWORD;
      lpMsg: PMessage;
    begin
      mtid := GetMainThreadID;
      new(lpMsg);
      try
        lpMsg.Msg := Msg;
        lpMsg.wParam := wParam;
        lpMsg.lParam := lParam;
        EnumThreadWindows(mtid, @__BroadcastMessageEnumProc, Integer(lpMsg));
      finally
        Dispose(lpMsg);
      end;
    end;