Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Absturz bei Opendialog


achi 3.0 - Di 22.09.09 07:28
Titel: Absturz bei Opendialog
Hallo,

habe in letzter Zeit das Problem das wenn ich im Opendialogfenster das Verzeichnis wechseln will das Programm abstürzt. Mir ist aufgefallen dass dies nur passiert wenn ich das Programm in Delphi laufen habe. Wenn ich nur die Exe ausführe klappt es.

Gruß


Gausi - Di 22.09.09 07:31

Wie macht sich der Absturz denn genau bemerkbar? Kommt eine Fehlermeldung, reagiert das Programm nicht mehr, Bluescreen...?


achi 3.0 - Di 22.09.09 08:17

Das programm reagiert nicht mehr, ich bekomme keine Fehlermeldung. Es geht einfach nix mehr.


jaenicke - Di 22.09.09 08:18

Ein ähnliches Problem hatte ich auch, konnte es auch reproduzieren, aber nicht beheben. Bei mir kam eine Zugriffsverletzung dabei.

Nachdem ich mein Backup wieder zurückgespielt hatte, funktionierte es wieder. Woran es letztlich gelegen hatte, konnte ich nicht herausfinden, habe allerdings auch nicht besonders lange gesucht.


PreMarT - Di 22.09.09 08:20

Hi,

Kannst du vielleicht mal den Code dazu posten?

Hast du irgendwelche optionen eingestellt, oder andere Parameter?


jaenicke - Di 22.09.09 08:22

Also bei mir gab es keinen zusätzlichen Code. Leider finde ich gerade den Thread dazu nicht mehr. :nixweiss:
Es gab den Fehler schon mit einer neuen leeren Anwendung nur mit dem angezeigten Dialog in einem Button-Klick.


achi 3.0 - Di 22.09.09 08:31

genau so ist es bei mir auch. ich habe den fehler auch bei einer leeren anwendung nur mit einem opendialog. mittels buttonclick.


thepaine91 - Di 22.09.09 08:36

Schreib mal den Code wie du drauf zugreifst...


jaenicke - Di 22.09.09 08:39

Ich würde dazu raten einfach ein Backup aufzuspielen, wenn du eins hast. Wenn nicht: Nun ja, vielleicht denkst du dann ja beim nächsten Mal rechtzeitig dran eins zu machen, aus Schaden wird man klug. Denn letztendlich bleibt dir ja vermutlich dann nur eine Neuinstallation. ;-)

Das ist bei dir auch noch unter XP, wie ich es seinerzeit auch noch hatte? Und wie sieht es, wenn das Programm hängt, mit der Prozessauslastung aus? Tut es da noch etwas (im TaskManager)?

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Schreib mal den Code wie du drauf zugreifst...
Also bei mir sah der Code so aus:

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject);
begin
  OpenDialog1.Execute;
end;


PreMarT - Di 22.09.09 08:46

Muss da net mindestens das stehen?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TfrmMain.mmLoadClick(Sender: TObject);
begin

  OpenDialog := TOpenDialog.Create(self);

  if OpenDialog.Execute then
    try
      z.B. imgage1.Picture.Loadfromfile(OpenDialog.Filename);
    except
      ShowMessage('Error while Loading File!');
    end
  else
    ShowMessage('Load File was cancelled');

end;


Moderiert von user profile iconGausi: Code- durch Delphi-Tags ersetzt


Gausi - Di 22.09.09 08:48

Also damit hast du schonmal ein tolles Speicherleck gebaut. ;-)


jaenicke - Di 22.09.09 08:48

Wenn der Dialog auf dem Formular liegt, muss er nicht erzeugt werden. Bei diesem Code werden immer wieder neue Dialoge erzeugt, aber erst beim Programmende wieder freigegeben... keine gute Idee.
Und ob man den Rückgabewert auswertet und danach weiteren Code ausführt, hat nichts mit dem Problem zu tun, da das Problem bereits im Execute auftritt.


PreMarT - Di 22.09.09 08:51

wenn ich den Code wie Ihr den gepostet hab schreibe kommt bei mir Exeption Fehler....
naja ich hab keine probs :P

EDIT : :/ jetzt weis ich was ihr meint......naja dann packt man das

OpenDialog := TOpenDialog.Create(self); halt ins FormCreate aber das muss man haben...sonnst kann man garkein Dialog öffnen...


Narses - Di 22.09.09 08:59

Moin!

user profile iconachi 3.0 hat folgendes geschrieben Zum zitierten Posting springen:
genau so ist es bei mir auch. ich habe den fehler auch bei einer leeren anwendung nur mit einem opendialog. mittels buttonclick.
Da du leider weder die Delphi-Version noch das Betriebssystem angegeben hast, rate ich mal zumindest das OS: WinXP?

Wenn dem so ist, dann mach mal folgendes:Muss nicht zwangsweise helfen, kann aber. :idea:

cu
Narses


jaenicke - Di 22.09.09 09:12

user profile iconPreMarT hat folgendes geschrieben Zum zitierten Posting springen:
naja dann packt man das

OpenDialog := TOpenDialog.Create(self); halt ins FormCreate aber das muss man haben...sonnst kann man garkein Dialog öffnen...
Doch, einfach den Dialog aufs Formular legen...


thepaine91 - Di 22.09.09 09:34

Jaenicke hast du mal mit dem Compiler durchgesteppt wo er genau rausspringt. Also im Execute selbst?


achi 3.0 - Di 22.09.09 09:56

Hi, ich nutze win Xp und Delphi5 (ich weiß ist alt aber die Umstellung kommt noch)

Also das Programm hängt sich genau im Execute auf. Habe leider kein Backup. das muss doch an windows liegen, da der dialog von windows ist oder.


thepaine91 - Di 22.09.09 10:08


Delphi-Quelltext
1:
2:
3:
type
  TForm1 = class(TForm)
    OpenDialog1: TOpenDialog; // Wird erzeugt wenn man die Komponente aufs Formular zieht.


So hier ist der Aufruf des Executes ;) und dort mal nachsehen wo genau der Fehler ausgelöst wird.

Unit: Dialogs

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
function TOpenDialog.DoExecute(Func: Pointer): Bool;
const
  MultiSelectBufferSize = High(Word) - 16;
  OpenOptions: array [TOpenOption] of DWORD = (
    OFN_READONLY, OFN_OVERWRITEPROMPT, OFN_HIDEREADONLY,
    OFN_NOCHANGEDIR, OFN_SHOWHELP, OFN_NOVALIDATE, OFN_ALLOWMULTISELECT,
    OFN_EXTENSIONDIFFERENT, OFN_PATHMUSTEXIST, OFN_FILEMUSTEXIST,
    OFN_CREATEPROMPT, OFN_SHAREAWARE, OFN_NOREADONLYRETURN,
    OFN_NOTESTFILECREATE, OFN_NONETWORKBUTTON, OFN_NOLONGNAMES,
    OFN_EXPLORER, OFN_NODEREFERENCELINKS, OFN_ENABLEINCLUDENOTIFY,
    OFN_ENABLESIZING, OFN_DONTADDTORECENT, OFN_FORCESHOWHIDDEN);

  OpenOptionsEx: array [TOpenOptionEx] of DWORD = (OFN_EX_NOPLACESBAR);
var
  Option: TOpenOption;
  OptionEx: TOpenOptionEx;
  OpenFilename: TOpenFilename;

  function AllocFilterStr(const S: string): string;
  var
    P: PChar;
  begin
    Result := '';
    if S <> '' then
    begin
      Result := S + #0;  // double null terminators
      P := AnsiStrScan(PChar(Result), '|');
      while P <> nil do
      begin
        P^ := #0;
        Inc(P);
        P := AnsiStrScan(P, '|');
      end;
    end;
  end;

var
  TempFilter, TempFilename, TempExt: string;
begin
  FFiles.Clear;
  FillChar(OpenFileName, SizeOf(OpenFileName), 0);
  with OpenFilename do
  begin
    if (Win32MajorVersion >= 5and (Win32Platform = VER_PLATFORM_WIN32_NT) or { Win2k }
    ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and (Win32MajorVersion >= 4and (Win32MinorVersion >= 90)) then { WinME }
      lStructSize := SizeOf(TOpenFilename)
    else
      lStructSize := SizeOf(TOpenFilename) - (SizeOf(DWORD) shl 1) - SizeOf(Pointer); { subtract size of added fields }

    hInstance := SysInit.HInstance;
    TempFilter := AllocFilterStr(FFilter);
    lpstrFilter := PChar(TempFilter);
    nFilterIndex := FFilterIndex;
    FCurrentFilterIndex := FFilterIndex;
    if ofAllowMultiSelect in FOptions then
      nMaxFile := MultiSelectBufferSize else
      nMaxFile := MAX_PATH;
    SetLength(TempFilename, nMaxFile + 2);
    lpstrFile := PChar(TempFilename);
    FillChar(lpstrFile^, nMaxFile + 20);
    StrLCopy(lpstrFile, PChar(FFileName), nMaxFile);
    if (FInitialDir = ''and ForceCurrentDirectory then
      lpstrInitialDir := '.'
    else
      lpstrInitialDir := PChar(FInitialDir);
    lpstrTitle := PChar(FTitle);
    Flags := OFN_ENABLEHOOK;
    FlagsEx := 0;

    for Option := Low(Option) to High(Option) do
      if Option in FOptions then
        Flags := Flags or OpenOptions[Option];
    if NewStyleControls then
    begin
      Flags := Flags xor OFN_EXPLORER;
      if (Win32MajorVersion >= 5and (Win32Platform = VER_PLATFORM_WIN32_NT) or { Win2k }
      ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and (Win32MajorVersion >= 4and (Win32MinorVersion >= 90)) then { WinME }
        for OptionEx := Low(OptionEx) to High(OptionEx) do
          if OptionEx in FOptionsEx then
            FlagsEx := FlagsEx or OpenOptionsEx[OptionEx]; 
    end
    else
      Flags := Flags and not OFN_EXPLORER;
    TempExt := FDefaultExt;
    if (TempExt = ''and (Flags and OFN_EXPLORER = 0then
    begin
      TempExt := ExtractFileExt(FFilename);
      Delete(TempExt, 11);
    end;
    if TempExt <> '' then lpstrDefExt := PChar(TempExt);
    if (ofOldStyleDialog in Options) or not NewStyleControls then
      lpfnHook := DialogHook
    else
      lpfnHook := ExplorerHook;

    if Template <> nil then
    begin
      Flags := Flags or OFN_ENABLETEMPLATE;
      lpTemplateName := Template;
    end;
    hWndOwner := Application.Handle;
    Result := TaskModalDialog(Func, OpenFileName);
    if Result then
    begin
      GetFileNames(OpenFilename);
      if (Flags and OFN_EXTENSIONDIFFERENT) <> 0 then
        Include(FOptions, ofExtensionDifferent) else
        Exclude(FOptions, ofExtensionDifferent);
      if (Flags and OFN_READONLY) <> 0 then
        Include(FOptions, ofReadOnly) else
        Exclude(FOptions, ofReadOnly);
      FFilterIndex := nFilterIndex;
    end;
  end;
end;


jaenicke - Di 22.09.09 10:21

Es kann im Grunde nur die Zeile sein, in der der Dialog tatsächlich angezeigt wird. Denn die Vorbereitung passiert vorher, die Auswertung danach. Der Fehler passiert aber ja während der Dialog sichtbar ist. :nixweiss:
Wobei die Frage ist, ob da irgendein Callback dazwischenfunkt oder sowas.

Da ich das Problem durch eine Wiederherstellung des Backups wieder behoben hatte (und mittlerweile XP auch gar nicht mehr einsetze), kann ich das nachträglich auch nicht mehr untersuchen.


thepaine91 - Di 22.09.09 10:27

Achso ;) ich hatte verstanden das es im Execute selbst abbricht. Jetzt nochmal nachgelesen.... okay dann ist das natürlich was anderes.


achi 3.0 - Di 22.09.09 10:27

also habe es nochmal getestet. er stürzt nur ab wenn ich in der listbox das verzeichnis ändern will, d.h. wenn ich die liste mit desktop arbeitzplatz usw. aufmachen möchte.
alles andere geht.

PS. Man kann gar nicht sehen wo er abstürzt denn man läuft gar nicht in die funktion.

habe zwar halte punkte gesetzt aber es geschieht nix


jaenicke - Di 22.09.09 10:30

user profile iconachi 3.0 hat folgendes geschrieben Zum zitierten Posting springen:
PS. Man kann gar nicht sehen wo er abstürzt denn man läuft gar nicht in die funktion.
Dann hast du Debug-DCUs in den Projektoptionen nicht aktiviert.


achi 3.0 - Di 22.09.09 10:35

sieht man leider trotzdem nicht. da erst abstürzt wenn ich die liste öffnen will.

muss gucken was im opendialog passiert wenn man auf die liste clickt.


Xentar - Di 22.09.09 10:38

- Passiert das auch in anderen Anwendungen?
- Was passiert, wenn du ein neues Delphi Projekt anlegst, dort nur einen OpenDialog aufs Formular platzierst, und diesen z.B. per Buttonclick aufrust? Wenn es dann geht, hast du wohl ein Problem in deiner anderen Anwendung.
- Hast du vielleicht ein Netzlaufwerk eingebunden, dass der bei jedem Aufruf des Dialogs gesucht wird?


achi 3.0 - Di 22.09.09 10:54

wie oben geschrieben hat es nix mit der anwendung zu tun. es passiert auch wenn ich nur einen opdialog und einen button auf ein formular lege. sobald ich die liste lösche stürzt es ab.