AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme mit SHGetKnownFolderPath

Ein Thema von Andidreas · begonnen am 22. Nov 2013 · letzter Beitrag vom 25. Nov 2013
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Andidreas
Andidreas

Registriert seit: 27. Okt 2005
1.110 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 10:20
Delphi-Version: XE
Hallo zusammen,

ich habe mir vor einiger Zeit eine Funktion gebastelt über die ich unter Windows 7 die Standard Pfade von Windows auslesen kann:

Delphi-Quellcode:

  //Constants
  const
    FOLDERID_Desktop: KNOWNFOLDERID = '{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}'; //CSIDL_DESKTOPDIRECTORY
    FOLDERID_LocalAppData: KNOWNFOLDERID = '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}'; //CSIDL_LOCAL_APPDATA
    FOLDERID_ProgramData: KNOWNFOLDERID = '{62AB5D82-FDC1-4DC3-A9DD-070D1D495D97}'; //CSIDL_COMMON_APPDATA
    FOLDERID_PuplicDesktop: KNOWNFOLDERID = '{C4AA340D-F20F-4863-AFEF-F87EF2E6BA25}'; //CSIDL_COMMON_DESKTOPDIRECTORY
    FOLDERID_Fonts: KNOWNFOLDERID = '{FD228CB7-AE11-4AE3-864C-16F3910AB8FE}'; //CSIDL_FONTS


//******************************************************************************
// fnGetKnownFolderPath --> Get Constant Special Item ID Path from Windows *
// *
// Only for WIN 7 *
// WIN XP has to use fnGetShellFolder in this Unit *
// *
// Parameter --> iCSIDL (Constant Special Item ID) *
// Return --> Boolean True/False *
//******************************************************************************

function fnGetKnownFolderPath(sKnownFolderID : String) : String;

var
sPath : LPWSTR;

begin

  //Set Result
  Result := EmptyStr;

  {$IFDEF VER220}
  If sKnownFolderID = 'FOLDERID_Desktop'        Then SHGetKnownFolderPath(FOLDERID_Desktop,0, 0, sPath);
  If sKnownFolderID = 'FOLDERID_LocalAppData'   Then SHGetKnownFolderPath(FOLDERID_LocalAppData,0, 0, sPath);
  If sKnownFolderID = 'FOLDERID_ProgramData'    Then SHGetKnownFolderPath(FOLDERID_ProgramData,0, 0, sPath);
  If sKnownFolderID = 'FOLDERID_PuplicDesktop'  Then SHGetKnownFolderPath(FOLDERID_PuplicDesktop,0, 0, sPath);
  If sKnownFolderID = 'FOLDERID_Fonts'          Then SHGetKnownFolderPath(FOLDERID_Fonts,0, 0, sPath);
  {$ENDIF}

  //Set Result
  Result := sPath;

end;
Nun hab ich mit der Funktion das folgende Problem...

Wir haben ein Hauptprogramm was das UI darstellt...
Über das UI kann der User diverse Module aufrufen die in DLLs ausgelagert sind (die DLLs werden dynamisch gelinkt)...

Rufe ich die Funktion im Hauptprogramm auf, habe ich kein Problem...
Rufe ich die Funktion aber in einer DLL auf bekomme ich einen Runtime Error 216...

Woran kann das liegen? Ist in der Funktion was falsch Programmiert?
Ein Programmierer Programmiert durchschnittlich 15 Code Zeilen pro Tag
Wir sind hier doch nicht bei SAP!!!

Aber wir habens bald
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 10:25
Was mir zuerst auffällt:
Delphi-Quellcode:
{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss die erste
  Unit in der USES-Klausel Ihrer Bibliothek UND in der USES-Klausel Ihres Projekts
  (wählen Sie 'Projekt-Quelltext anzeigen') sein, wenn Ihre DLL Prozeduren oder Funktionen
  exportiert, die Strings als Parameter oder Funktionsergebnisse übergeben. Dies
  gilt für alle Strings, die an oder von Ihrer DLL übergeben werden, auch für solche,
  die in Records und Klassen verschachtelt sind. ShareMem ist die Interface-Unit zur
  gemeinsamen BORLNDMM.DLL-Speicherverwaltung, die zusammen mit Ihrer DLL
  weitergegeben werden muss. Übergeben Sie String-Informationen mit PChar- oder ShortString-Parametern, um die Verwendung von BORLNDMM.DLL zu vermeiden.
}
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Andidreas
Andidreas

Registriert seit: 27. Okt 2005
1.110 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 10:31
Ich hab folgendes gemacht...

main_form --> Ruft alle DLLs auf
update_form --> Form der DLL in ders knallt (und die die Funktion aufruft)
Global_unit --> Unit in der sich die Funktion befindet

Überall habe ich in der Uses Klausel "ShareMem" als erste Uses hinzugefügt...
Der beschriebene Fehler kommt trotzdem...
Ein Programmierer Programmiert durchschnittlich 15 Code Zeilen pro Tag
Wir sind hier doch nicht bei SAP!!!

Aber wir habens bald
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 10:34
Auch in der *.dpr?

[edit] Nachtrag: evtl. solltest Du die Aufrufkonvention noch auf stdcall setzen. [/edit]
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Andidreas
Andidreas

Registriert seit: 27. Okt 2005
1.110 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#5

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 10:34
... oder muss das hier rein???

Delphi-Quellcode:

library updatecomdata;

uses
  ShareMem,
  Forms,
  ...;

Mist Deddy war schneller
Ein Programmierer Programmiert durchschnittlich 15 Code Zeilen pro Tag
Wir sind hier doch nicht bei SAP!!!

Aber wir habens bald
  Mit Zitat antworten Zitat
Benutzerbild von Andidreas
Andidreas

Registriert seit: 27. Okt 2005
1.110 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 10:43
Der Fehler kommt immer noch...

In den Units der Forms habe ich ShareMem wieder entfernt, war das falsch?

So sieht es jetzt aus:

*.dpr des Hauptprogrammes
Delphi-Quellcode:
program Main;

uses
  ShareMem,
  Forms,


Aufruf der DLL
Delphi-Quellcode:
procedure Tmain_form.prOfflineModuleLoad_Single(sDLLModulePath : String);

type
TMyFormClass    = function : TFormClass; stdcall;
TSQLiteFileConnection = procedure(SQLiteFileConnection : TUniConnection); stdcall;
TSQLiteMemoryConnection = procedure(SQLiteMemoryConnection : TUniConnection); stdcall;
TParms = procedure(Language, UserSewingPlant, UserEANCheckPlantID : String) stdcall;

var
i : Integer;
lMyFormClass : TMyFormClass;
lSQLiteFileConnection : TSQLiteFileConnection;
lSQLiteMemoryConnection : TSQLiteMemoryConnection;
lParms : TParms;

begin

  //Define Variables
  gsDLL := sDLLModulePath;
  hDLL := LoadLibrary(PChar(gsDLL));
  gblDLLLoaded := True;

  //SQLite File Connection
  lSQLiteFileConnection := GetProcAddress(hDLL, 'prSQLiteFileConnect');
  If Assigned (lSQLiteFileConnection) Then
  Begin
    lSQLiteFileConnection(dmsqlite.SQLiteFile);
  End;

  //SQLite Memory Connection
  lSQLiteMemoryConnection := GetProcAddress(hDLL, 'prSQLiteMemoryConnect');
  If Assigned (lSQLiteMemoryConnection) Then
  Begin
    lSQLiteMemoryConnection(dmsqlite.SQLiteMemory);
  End;

  //Parameters
  lParms := GetProcAddress(hDLL, 'prModuleParameters');
  If Assigned (lParms) Then
  Begin
    lParms(gsPSTLanguage, gsPSTUserSewingPlant, gsPSTUserEANCheckPlantID);
  End;

  //Load DLL Form
  lMyFormClass := GetProcAddress(hDLL, 'fnForm');
  If @lMyFormClass <> Nil Then
  Begin
    frmLoadedForm   := lMyFormClass.Create(nil);
    frmLoadedForm.Position := poScreenCenter;
    frmLoadedForm.ShowModal;
  End Else
  Begin
    fnDisplayMyActionBox('ERR', 'System Error', 'prOfflineModuleLoad_Single', 'Could not load Module:', sDLLModulePath, EmptyStr, True);
  End;

end;


*.dpr der DLL
Delphi-Quellcode:
library updatecomdata;

uses
  ShareMem,
  Forms,
  Globals in '..\..\..\Globals\Globals.pas',
  Messages in '..\..\01_Globals\Messages.pas',
  myactionbox in '..\..\01_Globals\myactionbox.pas{actionbox_form},
  myerrorbox in '..\..\01_Globals\myerrorbox.pas{errorbox_form},
  Globals in '..\..\01_Globals\Globals.pas',
  updatecomdata in 'updatecomdata.pas{updatecomdata_form},
  updatecomdata_info in 'updatecomdata_info.pas{updatecomdata_info_form};

{$R *.res}

exports
  fnForm, prSQLiteFileConnect, prSQLiteMemoryConnect, prModuleParameters;

begin
end.
Ein Programmierer Programmiert durchschnittlich 15 Code Zeilen pro Tag
Wir sind hier doch nicht bei SAP!!!

Aber wir habens bald

Geändert von Andidreas (22. Nov 2013 um 10:47 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 10:47
Das Gedöns mit der Formklasse erscheint mir etwas merkwürdig. Versuchst Du da Klassen/Objekte zwischen Anwendung und DLL auszutauschen?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Andidreas
Andidreas

Registriert seit: 27. Okt 2005
1.110 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#8

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 10:56
Nein...
Eigentlich werden nur die Connections zu den DBs übergeben?!
Oder welche Stelle meinst Du?
Ein Programmierer Programmiert durchschnittlich 15 Code Zeilen pro Tag
Wir sind hier doch nicht bei SAP!!!

Aber wir habens bald
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 11:11
Das hier meine ich:
Zitat:
Delphi-Quellcode:
//Load DLL Form
  lMyFormClass := GetProcAddress(hDLL, 'fnForm');
  If @lMyFormClass <> Nil Then
  Begin
    frmLoadedForm := lMyFormClass.Create(nil);
    frmLoadedForm.Position := poScreenCenter;
    frmLoadedForm.ShowModal;
  End Else
  Begin
    fnDisplayMyActionBox('ERR', 'System Error', 'prOfflineModuleLoad_Single', 'Could not load Module:', sDLLModulePath, EmptyStr, True);
  End;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Andidreas
Andidreas

Registriert seit: 27. Okt 2005
1.110 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#10

AW: Probleme mit SHGetKnownFolderPath

  Alt 22. Nov 2013, 11:18
Das ist ja nur dazu da um die Form anzuzeigen...
Wir haben hier zwei Varianten... entweder wird die Form als eigenständiges Fenster angezeigt oder in einem Bereich der Hauptform...


Was ich kurios finde...
Die Funktion die ich oben beschrieben habe, habe ich auch für Windows XP:

Delphi-Quellcode:
//******************************************************************************
// fnGetShellFolder --> Get Constant Special Item ID Path from Windows *
// *
// Only for WIN XP *
// WIN7 has to use fnGetKnownFolderPath in this Unit *
// *
// Parameter --> iCSIDL (Constant Special Item ID) *
// Return --> Boolean True/False *
//******************************************************************************

function fnGetShellFolder(iCSIDL: integer): string;

var
pIDL : PItemIdList;
sFolderPath : string;
iSystemFolder : Integer;
Malloc : IMalloc;
  
begin

  Malloc := nil;
  sFolderPath := '';
  SHGetMalloc(Malloc);

  If Malloc = nil Then
  Begin
    Result := sFolderPath;
    Exit;
  End;

  Try
    iSystemFolder := iCSIDL;
    If SUCCEEDED(SHGetSpecialFolderLocation(0, iSystemFolder, pIDL)) then
    Begin
      SetLength(sFolderPath, max_path);
      If SHGetPathFromIDList(pidl, PChar(sFolderPath)) Then
      Begin
        SetLength(sFolderPath, length(PChar(sFolderPath)));
      End;
    End;
    Result := sFolderPath;
  Finally
    Malloc.Free(pIDL);
  End;

end;
Ich hab die gleiche DLL jetzt unter Windows XP getestet... hier kommt kein Fehler! Also kein Runtime Error...

Liegt der Fehler dann nicht eher in der Funktion für Windows 7, das diese einen Speicherfehler verursacht?
Ein Programmierer Programmiert durchschnittlich 15 Code Zeilen pro Tag
Wir sind hier doch nicht bei SAP!!!

Aber wir habens bald
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:15 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz