Zugriffsverletzung comctl32.dll in Verbinung mit TCategoryPanel



  • Hallo zusammen,

    wiedereinmal zwingt mich der C++ Builder XE7 in die Knie und ich suche vergeblich nach einer Lösung für folgendes Problem.

    Edit

    Das Problem hat anscheinend eine andere Ursache (siehe unten). Die nachfolgende Beschreibung lasse ich für die Nachvollziehbarkeit des Threads bestehen.

    Ich habe ein Formular mit u.a. zwei TComboBox-Komponenten darauf. Hin und wieder erhalte ich, wenn ich ein Item auswähle, die

    Exception

    ---------------------------
    Benachrichtigung über Debugger-Exception
    ---------------------------
    Im Projekt Moman6.exe ist eine Exception der Klasse $C0000005 mit der Meldung 'access violation at 0x7156761f: read of address 0x0000000c' aufgetreten.
    ---------------------------
    Anhalten Fortsetzen Hilfe
    ---------------------------

    mit der Meldung

    Zugriffsverletzung bei Adresse 7156761F in Modul 'comctl32.dll'. Lesen von Adresse 0000000C.

    Die ComboBoxen liegen auf einem TPanel, welches sich in einem TCategoryPanel innerhalb einer TCategoryPanelGroup befindet. Die Adressen, auf die nicht zugegriffen werden kann, variieren.

    Das Interessante an der ganzen Geschichte ist, dass der Fehler nur auftritt,
    wenn die Anwendung mit Debugger ausgeführt wird.

    Ich hoffe jemand von euch hat eine Idee, wie ich an das Problem herangehen kann.
    Rebuild und Austauschen der Komponenten hat nichts gebracht und auch die DFM sieht in Ordnung aus. Im Internet findet man den ein oder anderen Beitrag dazu,
    aber diese haben mir nicht weitergeholfen.

    Beste Grüße
    Kerem

    Anhang:

    Aufruf-Stack:

    :7156761f ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
    :71588c10 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
    :715686c0 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
    :769062fa ; C:\Windows\syswow64\USER32.dll
    :76906d3a USER32.GetThreadDesktop + 0xd7
    :76910d27 USER32.GetClientRect + 0xc5
    :76910d4d USER32.CallWindowProcW + 0x1b
    :505c77cf vcl210.@Vcl@Controls@TWinControl@DefaultHandlerqqrpv + 0xeb :505c76bf ; C:\\Program Files (x86)\\Embarcadero\\Studio\\15.0\\bin\\vcl210.bpl :505e5ed0 ; C:\\Program Files (x86)\\Embarcadero\\Studio\\15.0\\bin\\vcl210.bpl :505c6cf7 vcl210.@Vcl@Controls@TWinControl@MainWndProcqqrr24Winapi@Messages@TMessage + 0x2f
    :5016e216 rtl210.@System@Classes@TDataModule@WriteHeight$qqrp22System@Classes@TWriter + 0x22
    :769062fa ; C:\Windows\syswow64\USER32.dll
    :76906d3a USER32.GetThreadDesktop + 0xd7
    :7690965e ; C:\Windows\syswow64\USER32.dll
    :769096c5 USER32.SendMessageW + 0x4c
    :7155aec4 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
    :7151e16b ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
    :7151e30e ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
    :7151ee1b ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
    :769062fa ; C:\Windows\syswow64\USER32.dll
    :76906d3a USER32.GetThreadDesktop + 0xd7
    :769077c4 ; C:\Windows\syswow64\USER32.dll
    :7690788a USER32.DispatchMessageW + 0xf
    :50716338 ; C:\Program Files (x86)\Embarcadero\Studio\15.0\bin\vcl210.bpl



  • Hallo,
    werden Ereignisse beim Click auf ein Item ausgelöst (OnChange, OnClick, OnDrawItem....)?
    Wenn ja, was passiert darin? Bitte Sourcecode zeigen.



  • Hallo und danke für deine Antwort.

    Ich werte das OnSelect-Ereignis der ComboBox aus.
    Danach passiert schon einiges, d.h. ich rufe danach eine Funktion auf, die
    eine Reihe von Initialisierungen vornimmt und unter anderem auch Objekte(auch VCL-Controls) löscht und neue erzeugt. Natürlich werden in diesem Zuge auch einige Ereignisse ausgelöst.

    Den Code bekomm ich hier nicht in einer übersichtlichen Form unter . Ich werde jetzt wohl ein Minimalprojekt basteln müssen, um der Sache näherzukommen. Ich poste den Code, sobald ich das Problem reproduzieren kann.

    Was mich vielmehr interessiert ist, was das ganze zu bedeuten hat? Nach der Fehlermeldung läuft das Programm einwandfrei und ohne Debugger tritt er garnicht erst auf.


  • Mod

    Hallo

    wenn der Fehler nur im Zusammenhang mit dem Debugger auftritt
    ist dies vermutlich nur eine Einstellung im Builder

    Der Fehler wird im normalen Ablauf ohne Debugger abgefangen

    Da gibts irgendeine Einstellung die verhindert, das abgefangene Fehler angezeigt werden

    Ist leider schon sehr lange her - aber da gabs irgendwas

    Mfg
    Klaus



  • KlausB schrieb:

    Da gibts irgendeine Einstellung die verhindert, das abgefangene Fehler angezeigt werden

    Tools -> Options -> Debugger Options -> Native OS Exceptions -> Handled by



  • Vielen Dank für eure Beiträge.

    Mit der Einstellung der Debugger Einstellung bin ich nicht an mein Ziel gekommen. Entweder die Meldung wird trotzdem angezeigt oder mein Programm
    hängt sich auf.

    Ich denke ich habe etwas unsauber programmiert und werde mich dem in kürze
    annehmen. Sobald ich näheres weiß, melde ich mich wieder.

    VG
    Kerem



  • Hallo,

    Ich kann den Fehler jetzt reproduzieren und habe deswegen den Titel des Threads geändert.

    Ich habe eine TCategoryGroup-Komponente auf einem Formular abgelegt und ein CatgoryPanel hinzugefügt. Auf das Panel habe ich eine ComboBox mit gelegt und ein Item hinzugefügt. In der OnSelect-Behandlung der ComboBox wird folgender Code ausgeführt:

    for (int i = CategoryPanelGroup1->Panels->Count-1; i >=1; i--) {
       delete ((TCategoryPanel*)CategoryPanelGroup1->Panels->Items[1]);
    }
    
    for (int i = 0; i < 5; i++) {
       TCategoryPanel* Panel = new TCategoryPanel(this);
       Panel->Height = 20;
       Panel->PanelGroup = CategoryPanelGroup1;
    }
    

    Wenn ich nun einige male das Item in der ComboBox auswähle tritt die oben genannte Exception auf. Das ganze lässt sich anscheinend beschleunigen, wenn das Formular nur so hoch ist, dass nach dem Hinzufügen der Panels die ScrollBar der CategoryGroup angezeigt wird.

    Der Fehler tritt anscheinend auch nur auf, wenn sich die ComboBox auf dem Panel befindet.

    Ich habe das gleiche auch mit einem TButton, in dessen OnClick-Ereignis ich den Code habe ausführen lassen, ausprobiert. Auch hier kann ich das Verhalten nicht reproduzieren.

    Der Versuch zwischen dem Löschen und Hinzufügen der Panels

    Application->ProcessMessages
    

    oder

    CategoryPanelGroup1->Update()
    

    aufzurufen, hat nichts bewirkt.

    Hat jemand eine Ahnung, woran das liegen kann? Ich habe Gefühl, dass TCategoryPanel das dynamische Hinzufügen bzw. Entfernen von Panels nicht mag...



  • Ich vermute mal, das du hier:

    TCategoryPanel* Panel = new TCategoryPanel(this);
    

    den falschen Parent (this) übergibst, da ja die CategoryPanelGroup1 Komponente die von die dir hinzugefügten TCategoryPanel Objekte verwalten soll.

    Übergib als Parent CategoryPanelGroup1:

    TCategoryPanel* Panel = new TCategoryPanel(CategoryPanelGroup1);
    


  • Hallo,

    daran lags leider nicht...

    Mittlerweile verwende ich zwei ComboBoxen. Die erste erzeugt im OnSelect-Ereignis die Panels, die zweite löscht sie wieder. Die Zugriffsverletzung tritt beim Erzeugen der Panels auf. Dennoch vermute ich, dass das Problem am Löschen der Panels liegt.

    In Vcl.ExtCtrls ist das Entfernen von Panels so implemetiert

    procedure TCustomCategoryPanelGroup.RemovePanel(Panel: TCustomCategoryPanel);
    begin
      Panel.FPanelGroup := nil;
      FPanels.Remove(Panel);
      RemoveControl(Panel);
    end;
    

    Die Methode ist aber private und nicht virtuell. Außerdem erlaubt mir die CategoryPanel-Komponente nicht, seinen Parent zur Laufzeit auf NULL setzen.

    Die Verlockung ist groß, eine eigene Komponenten von TCustomCategoryPanelGroup abzuleiten, aber das möchte ich eigentlich nur machen, wenn es garnicht anders geht.

    Was ich sehr seltsam finde, ist das der Fehler nicht auftritt, wenn die ComboBoxen auf dem Formular und nicht auf dem ersten Panel liegen 😕



  • Hat dein CategoryPanel denn überhaupt einen Parent?
    Mit

    TCategoryPanel* Panel = new TCategoryPanel(this);
    

    setzt du ja nur den Owner. Meiner Meinung nach fehlt da noch ein

    Panel->Parent = ...;
    


  • Der Parent wird nach dem Aufruf von

    Panel->PanelGroup = ...;
    

    implizit gesetzt.

    Das ganze sieht mir doch sehr nach einem Bug in der VCL aus.
    Ich konnte den Fehler bisher nur hervorrufen, wenn ich das Erzeugen/Entfernen der Panels nach einem ComboBox-Event(OnSelect und OnChange) durchgeführt habe, und auch nur bei Bedienung mit der Maus. Wenn ich es aus dem Code heraus(z.B. in einer Schleife) mache, tritt der Fehler nicht auf.

    Es wäre wirklich sehr nett, wenn sich jemand kurz die Mühe machen würde das zu reproduzieren.

    Meint ihr, das ist ein Fall für QC?



  • Kerem schrieb:

    ...
    Es wäre wirklich sehr nett, wenn sich jemand kurz die Mühe machen würde das zu reproduzieren.

    Meint ihr, das ist ein Fall für QC?

    Dann wäre es von dir nett, wenn du uns hierfür ein kleines Testprojekt zur Verfügung stellen könntest. Das solltest du dann auch ruhig an QC melden.



  • Das würde ich liebend gerne, wenn ich die Erlaubnis dazu hätte die Dienste eines Filehosting-Anbieters zu nutzen.

    Eine Anleitung für die Erstellung der GUI und der Code der ausgeführt werden muss, habe ich weiter oben gepostet.


Anmelden zum Antworten