BroadCast



  • die eine komponente ist ein TTreeView (von TCustomTreeView) und die andere eine TListView (von TCustomListView).

    das Handle der ParentForm ist vorhanden.

    komischerweise funktioniert es nun schon fast. das verschieben von inherited::WndProc hat nix geholfen...

    wenn ich die message sende, dann übergebe ich noch eine struktur, die der empfänger auswerten und dann damit weiterarbeiten soll.

    // message
    #define  RSM_TV_NODECHANGED    (WM_USER + 1000)
    
    // struktur
    typedef struct _TNodeData
    {
      LPSHELLFOLDER ShellFolder;
      LPITEMIDLIST  FullID;
      LPITEMIDLIST  ID;
      LPITEMIDLIST  ParentID;   // !!! mit diesem parameter kommt die message nicht an ?!?
    } TNodeData, *P_TNodeData;
    

    bsp. im TreeView

    // im OnChanging-Ereignis
    // Data ist eine weitere struktur die verschiedene daten enthält...
    TNodeData NodeData;
    
    NodeData.ShellFolder = Data->ShellFolder; // LPSHELLFOLDER
    NodeData.ID          = Data->ID;          // LPITEMIDLIST
    NodeData.FullID      = Data->FullID;      // LPITEMIDLIST
    NodeData.ParentID    = NULL;
    
    // message senden
    // funktion siehe obigen post
    BroadcastMessage(RSM_TV_NODECHANGED, (WPARAM) &NodeData, 0);
    

    im listview dann

    void __fastcall TShellListView::WndProc(Messages::TMessage &Message)
    {
      if (Message.Msg == RSM_TV_NODECHANGED)
      {
        TNodeData *NodeData = (P_TNodeData) Message.WParam;
    
        // daten aus der message lesen
        LPSHELLFOLDER ParentShellFolder = NodeData->ShellFolder;
        LPITEMIDLIST  ParentID          = NodeData->ID;
        LPITEMIDLIST  ParentFullID      = NodeData->FullID;
    
        // listview neu füllen
        Reload(ParentShellFolder, ParentID, ParentFullID);
      }
    
      // geerbte Fensterprozedur aufrufen
      inherited::WndProc(Message);
    }
    

    wenn ich in der Struktur TNodeData, das Element ParentID entferne, kommt die message bei der ListView an. wenn ich sie dagegen einfüge, komischerweise nicht.

    erstelle ich die struktur falsch, bzw. übergebe ich sie falsch?



  • habs jetzt mit RegisterWindowMessage probiert und eine anderen struktur (die 4 int und 1 ansistring enthielt), jedoch komme ich zum selben ergebnis. die message kommt nicht an.

    mit 3 elementen in der struktur gehts, mit mehreren nicht... *haarerauf*



  • ha, hatte das selbe Problem.

    -> Das ist ein BUG !

    Teste folgendes:

    1. Mach mal ne Schleife mit Parent->ComponentsCount

    du wirst feststellen, dass ComponentCount 0 ist, obwohl da Steuerelemete drauf sind.

    2. Jetzt zahl mal mit ControlCount -> Verblüffend....

    3. Jetzt geh mal hin und nehm alle anderen Komponeten vom Parent deiner Objekte. Ausser deine Objekte selbst. Mach nun mal ein ComponentCount auf den Parent -> es geht !

    Ich sag nur Stichwort TLabel !

    Hat mir auch Haare gekostet....

    Wenn du eine Lösung ausser COntrolCount (was man ja eigentlich nicht mehr verwenden sollte) so gib bitte Bescheid.



  • naja ControlCount gibt mir 5 zurück und ComponentCount 11.

    habe in meiner testform 2 panels, auf denen sich buttons befinden. die werden von controlcount nicht gefunden, lediglich die beiden panels, der treeview, listview und ein splitter. componentcount findet alles.

    und das ist auch wieder was, was ich nicht verstehe, der treeview wird gefunden, erhält aber nie die botschaft die ich abschicke...

    und broadcast schickt nur an alle elemente die controlcount findet, d.h. wenn der treeview oder listview auf nem panel liegt, kommt die nachricht nie an. 😞



  • AndreasW schrieb:

    1. Mach mal ne Schleife mit Parent->ComponentsCount

    du wirst feststellen, dass ComponentCount 0 ist, obwohl da Steuerelemete drauf sind.

    ComponentCount gibt die Zahl der Elemente zurück, die dem betreffenden Objekt gehören.

    Parent <> Owner

    Ein Label auf einem Panel gehört standardmässig weiterhin der Form, es sei denn, es wurde explizit mit dem Panel als Owner erzeugt. ControlCount gibt dagegen die Zahl der Elemente zurück, für die das betreffende Objekt Parent ist.

    COntrolCount (was man ja eigentlich nicht mehr verwenden sollte)

    Wer sagt das?



  • hah... wenn ich in der TMessage-Struktur vor dem Broadcast noch

    Msg.Result = 0;
    

    setze, kommen die messages an...

    bleibt nur das problem mit dem broadcast und dem fall, dass die komponente auf nem panel liegt, da hilft wahrscheinlich nur, das broadcast selber zu machen und an jede windowproc() aller komponenten der form die message zu schicken...



  • Hi,

    @Jansen: das stand irgendwo in der Hilfe oder in der newsgroup...

    Erklär mir mal, warum Brodcast auf einmal funktioniert, wenn man Label vom Panel entfernt. Die Objekte empfangen dann die Message. Nimmt man ein Label auf den Parent wieder drauf gehts nicht mehr. Da kann doch was nicht stimmen.
    Der Sinn von Brodcast ist, nachrichten an alle Komponenten auf den Objekt zu senden. Das macht er aber nur, wenn kein Label drauf ist. Das kann doch nicht richtig sein.

    @Sunday: Hast du diese Phänomen auch ?



  • also bei mir machen die labels keine probleme. probiere es mal mit dem Msg.Result = 0;



  • ok, probier ich Montag. Hab gerad Stress... 😞



  • Hi,

    bin jetzt erst dazu gekommen, dass zu überprüfen 🙄

    Brodcast von TWinControl ist so definiert:

    procedure TWinControl.Broadcast(var Message);
    var
      I: Integer;
    begin
      for I := 0 to ControlCount - 1 do
      begin
        Controls[I].WindowProc(TMessage(Message));
        if TMessage(Message).Result <> 0 then Exit;
      end;
    end;
    

    das erklärt einiges.
    Wenn man nicht explizit Result auf 0 setzt ist Rsult undefiniert und damit <>0.



  • ja, genau... hab mir daher ne eigene broadcast-funktion geschrieben, bei der auch die komponenten erreicht werden, wenn sie auf einem panel oder in einer groupbox liegen.

    //---------------------------------------------------------------------------
    // Funktion sendet eine Message an alle, der ParentForm des übergebenen
    // Steuerelementes, untergeordneten Steuerelemente
    // -> wenn Message.Result != 0 ist, wird das Versenden abgebrochen
    //---------------------------------------------------------------------------
    void ComponentBroadcast(TControl *Source, TMessage &Message)
    {
      TCustomForm *Form = GetParentForm(Source);
    
      if (Form && Source)
      {
        for (int i = 0; i < Form->ComponentCount; i++)
        {
          TControl *Control = dynamic_cast <TControl*> (Form->Components[i]);
    
          if (Control)
          {
            Control->WindowProc(Message);
            if (Message.Result != 0) return;
          }
        }
      }
    }
    


  • Funktioniert das auch, wenn, wie oben beschrieben, ein Control explizit mit abweichendem Owner erzeugt wird?

    TLabel *label = new TLabel(Panel1);
    

    Im ComponentCount von Form1 taucht dieses Label jedenfalls nicht mit auf.



  • hm dafür bräuchte man sicher noch ne zweite schleife über ControlCount der einzelnen Komponenten. hab jeze aber keine zeit zum probieren, denn ich fahre 2 wochen in urlaub...



  • hm, vielleicht besser so, wenn du schon die harte Tour gehst:

    void ComponentBroadcast(TWinControl *Source, TMessage &Message)
    {
      if (Source)
      {
        Source->Broadcast(Message);
        if (Message.Result != 0) return;
        for (int i = 0; i < Source->ComponentCount; i++)
        {      
         TWinControl *WinControl = dynamic_cast <TWinControl*> (Form->Components[i]);
         if (WinControl)
          {
            ComponentBroadcast(WinControl,Message));  
            if (Message.Result != 0) return;
          }
        }
      }
    }
    

    Es ist allerding nicht immer erwünscht, die Komponeten auf allen Ebenen (wie Panels GroupBox usw.) anzusprechen .



  • Nachtrag:
    ...sonst würdest du nur die erste Ebene abdecken, was unter Umständen zu Verwirrung führen kann...


Anmelden zum Antworten