Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 08:53

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Sa Apr 17, 2004 19:50 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Tach,

ich hab da mal ne frage hat wer schon mit diesem API befehl gearbeitet, wenn ja... wie hat er es geschafft "Fehlerfrei" unendlich viele dateien per multiselect auszuwählen und in ne stringList zu speichern ?

ich kämpfe momentan damit, bekomme aber öfters eine access violation oder es passiert einfach nix.

Ich brauch das damit ich vollkommenen Unicode Support in Delphi realisieren kann und da muss man halt schon beim TOpenDialog anfangen :(

Hier ist source, als unit für den opendialog.

Code:
  1.  
  2. unit uniopendialog;
  3.  
  4. interface
  5.  
  6. uses
  7.   Windows,
  8.   Unicode; // Lischke-Unicode Lib
  9.  
  10. const
  11.   Ofn_allowmultiselect = 512;
  12.   Ofn_createprompt = 8192;
  13.   Ofn_enablehook = 32;
  14.   Ofn_enabletemplate = 64;
  15.   Ofn_enabletemplatehandle = 128;
  16.   Ofn_explorer = 524288;
  17.   Ofn_extensiondifferent = 1024;
  18.   Ofn_filemustexist = 4096;
  19.   Ofn_hidereadonly = 4;
  20.   Ofn_nochangedir = 8;
  21.   Ofn_nolongnames = 262144;
  22.   Ofn_nonetworkbutton = 131072;
  23.   Ofn_noreadonlyreturn = 32768;
  24.   Ofn_notestfilecreate = 65536;
  25.   Ofn_novalidate = 256;
  26.   Ofn_overwriteprompt = 2;
  27.   Ofn_pathmustexist = 2048;
  28.   Ofn_readonly = 1;
  29.   Ofn_shareaware = 16384;
  30.   Ofn_sharefallthrough = 2;
  31.   Ofn_sharenowarn = 1;
  32.   Ofn_sharewarn = 0;
  33.   Ofn_showhelp = 16;
  34.  
  35. type
  36.   TUniOpenDialog = class
  37.   private
  38.     fFiles : TWideStrings;
  39.   public
  40.     constructor Create;
  41.     destructor Destroy; override;
  42.     function Execute(_AppHandle, _FormHandle : HWND) : Boolean;
  43.   published
  44.     property Files : TWideStrings read fFiles write fFiles;
  45.   end;
  46.  
  47.   TOpenFileNameEx = packed record
  48.     lStructSize: DWORD;
  49.     hWndOwner: HWND;
  50.     hInstance: HINST;
  51.     lpstrFilter: PWideChar;
  52.     lpstrCustomFilter: PWideChar;
  53.     nMaxCustFilter: DWORD;
  54.     nFilterIndex: DWORD;
  55.     lpstrFile: PWideChar;
  56.     nMaxFile: DWORD;
  57.     lpstrFileTitle: PWideChar;
  58.     nMaxFileTitle: DWORD;
  59.     lpstrInitialDir: PWideChar;
  60.     lpstrTitle: PWideChar;
  61.     Flags: DWORD;
  62.     nFileOffset: Word;
  63.     nFileExtension: Word;
  64.     lpstrDefExt: PWideChar;
  65.     lCustData: LPARAM;
  66.     lpfnHook: function(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): UINT stdcall;
  67.     lpTemplateName: PWideChar;
  68.     pvReserved : Pointer;
  69.     dwReserved : DWORD;
  70.     FlagsEx : DWORD;
  71.   end;
  72.  
  73.   TWideStringDynArray = array of WideString;
  74.  
  75. function GetOpenFileNameEx(var OpenFile: TOpenFilenameEx): Bool; stdcall;
  76. function GetSaveFileNameEx(var OpenFile: TOpenFilenameEx): Bool; stdcall;
  77.  
  78. implementation
  79.  
  80. function GetOpenFileNameEx; external 'comdlg32.dll'  name 'GetOpenFileNameW';
  81. function GetSaveFileNameEx; external 'comdlg32.dll'  name 'GetSaveFileNameW';
  82.  
  83. function ExtractStringFromStringArray(var P: PWideChar; Separator: WideChar = #0): WideString;
  84. var
  85.   Start: PWideChar;
  86. begin
  87.   Start := P;
  88.   P := StrScanW(Start, Separator);
  89.   if P = nil then begin
  90.     Result := Start;
  91.     P := StrEndW(Start);
  92.   end else begin
  93.     SetString(Result, Start, P - Start);
  94.     Inc(P);
  95.   end;
  96. end;
  97.  
  98. function ExtractStringsFromStringArray(P: PWideChar; Separator: WideChar = #0): TWideStringDynArray;
  99. const
  100.   GROW_COUNT = 1024;
  101. var
  102.   Count: Integer;
  103.   Item: WideString;
  104. begin
  105.   Count := 0;
  106.   SetLength(Result, GROW_COUNT);
  107.   Item := ExtractStringFromStringArray(P, Separator);
  108.   While Item <> '' do begin
  109.     if Count > High(Result) then
  110.       SetLength(Result, Length(Result) + GROW_COUNT);
  111.     Result[Count] := Item;
  112.     Inc(Count);
  113.     Item := ExtractStringFromStringArray(P, Separator);
  114.   end;
  115.   SetLength(Result, Count);
  116. end;
  117.  
  118. constructor TUniOpenDialog.Create;
  119. begin
  120.   fFiles := TWideStringList.Create;
  121. end;
  122.  
  123. destructor TUniOpenDialog.Destroy;
  124. begin
  125.   fFiles.Free;
  126. end;
  127.  
  128. function TUniOpenDialog.Execute(_AppHandle, _FormHandle : HWND) : Boolean;
  129. var
  130.   ofn      : TOpenFileNameEx;
  131.   szFile   : array [0..255] of WideChar;
  132.   i        : integer;
  133.   data     : TWideStringDynArray;
  134.   P        : PWideChar;
  135. begin
  136.   Result := False;
  137.  
  138.   ZeroMemory(@ofn, SizeOf(TOpenFileNameEx));
  139.   ofn.hInstance := _AppHandle;
  140.   ofn.lStructSize := sizeof(ofn);
  141.   ofn.hwndOwner := _FormHandle;
  142.   ofn.lpstrFile := szFile;
  143.  
  144.   ofn.lpstrFile[0] := #0;
  145.   ofn.nMaxFile := SizeOf(szFile);
  146.   ofn.lpstrFilter := '';
  147.   ofn.nFilterIndex := 1;
  148.   ofn.lpstrFileTitle := '';
  149.   ofn.nMaxFileTitle := 0;
  150.   ofn.lpstrInitialDir := '';
  151.   ofn.Flags := Ofn_hidereadonly or OFN_ALLOWMULTISELECT or OFN_EXPLORER;
  152.  
  153.   if GetOpenFileNameEx(ofn) = true then
  154.   begin
  155.     P := szFile;
  156.     SetLength(data, 0);
  157.     data := ExtractStringsFromStringArray(P);
  158.     for I := 0 to high(data) do
  159.       fFiles.Add(data[I]);
  160.     Result := True;
  161.   end;
  162. end;
  163.  


wer da weiss wo der fehler steckt, der kann ja gern ne fixed version posten oder per mail senden.

matane,
Final


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Apr 17, 2004 20:03 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
k hab rausgefunden woran das liegt, habe aber keine idee wie ich das problem beseitigen soll.

die buffergrösse ist ausschlaggeben:

szFile : array [0..255] of WideChar;

diese vergrössern lässt schonmal mehr zu aber reicht noch nicht aus, bei vielen dateien:

szFile : array [0..65536] of WideChar;

wie macht man das dynamisch ?

matane,
Final


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Apr 17, 2004 20:43 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 02, 2002 18:06
Beiträge: 299
Wohnort: Dresden
Hab jetzt nich soviel Ahnung von API, aber einfach mit dynamsichen Arrays?

_________________
"Ich würde ja gern die Welt verändern, aber Gott gibt mir den Quelltext nicht"


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Apr 19, 2004 09:12 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 13, 2002 12:18
Beiträge: 1063
Ich würde einfach GetMem (und FreeMem) verwenden:

Code:
  1. type
  2.   TDynWideString = array[0..63] of TWideChar; // die Größe des Arrays ist egal - grad dass im Debugger die ersten paar Zeichen angezeigt werden
  3.   PDynWideString = ^TDynWideString;
  4.  
  5. var
  6.   MyString: PDynWideString;
  7.  
  8. begin
  9.   GetMem(MyString, nChars * sizeof(TWideChar));
  10.    // Speicher ist alloziert, MyString kann verwendet werden
  11.   FreeMem(MyString);
  12. end;


Du musst halt aufpassen, dass du mit GetMem allozierten Speicher auch selbst wieder frei gibst. Dynamische Arrays kannst du natürlich auch verwenden, solltest in Betriebssystemfunktionen dann aber die Adresse des ersten Elementes dereferenzieren (z.B. Addr(MyString[0]) )

_________________
Viel Spaß beim Programmieren,
Mars
http://www.basegraph.com/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Apr 19, 2004 13:31 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 28, 2002 19:27
Beiträge: 568
Wohnort: Chemnitz / Sachsen
wie wärs mit nem PChar ????

_________________
Aktuelles Projekt :
www.PicPlace.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Apr 19, 2004 13:40 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Der Type PWideChar ist vermutlich genau für so etwas vorgesehen. Man könnte aber auch einen WideString nehmen und die Läng evorher mti setlength extra setzen. Den Zeiger auf das erste Zeichen des WideStrings übergibt man dann.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Apr 19, 2004 14:10 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Okt 27, 2003 17:46
Beiträge: 788
und den array neu setzen (ne neue höhe bestimmen) kannste auch mit setlength(array, neue länge); Wenn dir das hilft ;) oder ich habe das dynamisch machen falsch verstanden


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Apr 19, 2004 17:05 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 02, 2002 18:06
Beiträge: 299
Wohnort: Dresden
PChar geht nicht, weil Char ja 0..255 ist, aber der Dialog ist ja für Unicode gedacht.

_________________
"Ich würde ja gern die Welt verändern, aber Gott gibt mir den Quelltext nicht"


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 20, 2004 15:03 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Danke für die vielen antworten aber ich habe da was festgestellt was nicht so toll ist.

Ich habe den array of widechar buffer auf die max. grösse gesetzt was geht.

Dann habe ich mal aus meiner ~5000 bilder sammlung die von 0-5000 durchnummeriert sind, alle markiert und in den unicode opendialog geladen.

Habe dann die Files aus dem opendialog in ne Listbox packen wollen.
Tja, leider werden aber nur um die ~1300 bilder geaddet.

Ich hab das dann auch noch mit nem normalen TOpenDialog probiert und siehe da, gleiches problem.

Habe mir dann nen sample mit dem normalen GetOpenFileName API befehl gemacht und da ist das gleiche.

Meiner meinung ist der Buffer der zugewiesen wird zu klein.
Ich hab nen wert von 0...65000 irgendwas eingeben und ne zahl zu viel, sagt mir delphi würde ich den stack überschreiten :(

Schon komisch, kann man diesen fehler einfach ignorieren oder soll man da dann ne eigene lösung bauen, sprich man baut sich seien opendialog ohne Winapi commands zusammne, zumindest nicht mit GetOpenFileNameW.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 20, 2004 15:16 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Das ist ja auch klar. Er muss ja alle Dateien in einen riesen Text schreiben.

Aber wie wäre es denn mit der SelectDirectory funktion? Zu finden ist diese in der Unit FileCtrl.
Und Vorsicht. Es gibt zwei Funktionien mit dem Namen SelectDirectory. Ich meine diese.
Code:
  1. function SelectDirectory(const Caption: string; const Root: WideString; var Directory: string): Boolean;

Die Andere ist ein Merkwürdig aussehender selbstgemachter Dialog.

Und dann kannst du dir alle Dateien mittes FindFirst, FindNext und FindClose suchen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 22, 2004 12:08 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
SelectDirectory kommt auch noch dazu, ich lass aber den opendialog nich weg, ich ignorier jetzt einfach das man nur ne bestimmte anzahl an dateien adden kann.

Da es kein fehler von mir ist, und der normale Delphi TOpenDialog auch nich geht, reicht mir das aus.

Ich brauch umbedingt noch den API Befehl für SelectDirectory !

Ach nochwas, FindFirst und TSearchRec kann ich nicht benutzen.
kann nur normale AnsiStrings :(

matane,
Final


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Apr 22, 2004 13:30 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also der Apiaufruf von SelectDirectory ist SHBrowseForFolder und das ganze geht über Shellobjekte. Ist ein wenig mehr als nur SHBrowseForFolder. Zu finden ist das ganze auch in den Quellen der VCL. Auf wunsch kann ich dir auch das Stück per PM zuschicken.

Zu FindFirst. Ich habe mal geschaut es gibt da auch eine Version die mit WideStrings klar kommt. Das ganze nennt sich FindFirstFile.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]