2009-09-14 9 views
4

Bonjour, J'ai utilisé cette fonction dans Delphi 2006, mais maintenant avec D2010, il y a une erreur. Je pense que c'est lié au passage à Unicode.Problèmes Unicode avec Delphi 2009/2010 et les appels de l'API Windows

Que dois-je faire pour que cela fonctionne?

EDIT

je reçois une 'violation d'accès' lorsque le ChangeFileExt est appelé

+0

Vous devriez éditer votre question pour inclure le message d'erreur (une bonne habitude - logique, non?) – Argalatyr

+1

S'il vous plaît voir le lien suivant à la fois pour une discussion du problème (presque le même code) et une meilleure version qui prend en compte un peu plus de ce que dit la documentation de l'API concernant la taille maximale du tampon. https://forums.embarcadero.com/thread.jspa?threadID=18246 –

Répondre

6

Windows.pas

function GetTempFileName(lpPathName, lpPrefixString: PWideChar; 
    uUnique: UINT; lpTempFileName: PWideChar): UINT; stdcall; 

function GetTempPath(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; stdcall; 

SysUtils.pas

function ChangeFileExt(const FileName, Extension: string): string; 

Essayez cette

Function TWinUtils.GetTempFile(Const Extension: STRING): STRING; 
    Var 
    Buffer: ARRAY [0 .. MAX_PATH] OF WideChar; 
    Begin 
    Repeat 
     GetTempPath(Length(Buffer), Buffer); 
     GetTempFileName(Buffer, '~~', 0, Buffer); 
     Result := ChangeFileExt(Buffer, Extension); 
    Until not FileExists(Result); 
    End; 

ou cette

Function GetTempFile(Const Extension: String): String; 
    Var 
    Buffer: String; 
    Begin 
     SetLength(Buffer,MAX_PATH); 
    Repeat 
     GetTempPath(MAX_PATH, PChar(Buffer)); 
     GetTempFileName(PChar(Buffer), '~~', 0, PChar(Buffer)); 
     Result := ChangeFileExt(Buffer, Extension); 
    Until not FileExists(Result); 
    End; 

Pour les types Delphi, Char et PChar sont les types WideChar et PWideChar, respectivement.

Si vous utilisez des API Windows qui renvoient des données dans des buffers char, ces buffers doivent être redéclarés comme des tableaux d'octets ou un tableau d'AnsiChar.

Si vous appelez ces API Windows et que vous envoyez des tampons, utilisez la fonction sizeof lorsque vous indiquez à l'API la durée de votre tampon. Ces appels doivent être remplacés par la fonction Longueur, car les API widechar de Windows requièrent le nombre de caractères, pas le nombre d'octets.

Salut.

+4

Et la raison pour laquelle l'ancien code était un problème est le SizeOf (Buffer) - 1 dans GetTempPath(). SizeOf un tableau de Chars était le même que la longueur pour Delphi avant 2009, parce que SizeOf (AnsiChar) = 1. Avec Delphi 2009 et plus tard, SizeOf (Char) = SizeOf (WideChar) = 2, donc le code demandait GetTempPath() pour remplir le tampon avec plus de caractères qu'il pourrait contenir. – jasonpenny

+0

la deuxième option fonctionne merci :) –

+0

J'ai essayé les deux options dans "Delphi 2010", et ils ont bien fonctionné. ;) – RRUZ

0

Avec Delphi 2009, Char est unicode omble chevalier. La fonction nécessite probablement un tableau d'AnsiChar.

Je viens de le vérifier. Les deux GetTempFilename et GetTempPath nécessitent un PWideString.

Quel est le message d'erreur?

+0

Est-ce que tu ne devrais pas dire 'PWideChar'? 'PWideString' est quelque chose d'autre entièrement. –

0

Utiliser GetTempPathA et GetTempFileNameA, les versions Ansi de GetTempPath et GetTempFileName. Ils sont toujours disponibles dans Delphi 2009 et mentionnés dans le fichier d'aide Delphi 2009, mais pas annoncés.

+0

Sur les versions de système d'exploitation Windows NT la plupart sinon toutes * Les versions des fonctions API ne sont que des stubs qui convertissent les paramètres et appellent les versions * W de la même fonction. Ainsi, dans Delphi 2009+, vous convertissez les données de caractères larges internes en Ansi, appelez * Une fonction, qui convertit en interne les caractères larges et retour, et le programme prend le résultat et le convertit en caractères larges. Diriez-vous que cette route a un sens? – mghie

0

Je recommande de toujours, et je veux dire toujours, d'aller voir dans les documents les attentes exactes de chaque fonction de l'API concernant le paramètre dwSize et/ou la valeur de retour. Malheureusement, il y a beaucoup de cas différents, donc juste dire que "toutes les fonctions de chaîne doivent/retourner nombre de caractères" n'est pas tout à fait correct et peut envoyer le lecteur dans un cauchemar de AV ponctuels sporadiques invalides.

  • La plupart des fonctions d'API s'attendent/retournent le nombre de caractères, mais pas .
  • Certains comptent le caractère nul final et d'autres non.
  • Certaines fonctions se comportent différemment lorsqu'un pointeur nul est transmis ou lorsqu'un pointeur non nul est transmis.
  • Et il y a aussi quelques fonctions qui n'offrent aucun moyen d'indiquer la taille de tampon requise.

Toutes ces choses peuvent être trouvées dans les docs facilement, mais il faut le lire. Vraiment. Cela peut vous faire économiser des heures.

Questions connexes