1

私は Delphi XE2 を使用しており、Shell32.dll から SHGetFolderPath をインポートしています。Windows Vista x64 を実行しています。SHGetFolderPathA実行時 結果は不明です。

いいえ:

uses
  Windows;

function SHGetFolderPath(hwnd: Cardinal; csidl: Integer; hToken: Cardinal; dwFlags: Cardinal; pszPath: PChar): Cardinal; stdcall;external 'Shell32.dll' name 'SHGetFolderPathA';

Var
  Path:Array [0..MAX_PATH] of Char;
  AppData:String;

begin
  SHGetFolderPath(0,$001A,0,0,@path[0]);
  MessageBox(0,Path,'a',0);
end.

結果は次のとおりです。

ここに画像の説明を入力

SHGetFolderPathW を使用する場合と比較:

Windows を使用します。

function SHGetFolderPath(hwnd: Cardinal; csidl: Integer; hToken: Cardinal; dwFlags: Cardinal; pszPath: PChar): Cardinal; stdcall;external 'Shell32.dll' name 'SHGetFolderPathW';

Var
  Path:Array [0..MAX_PATH] of Char;
  AppData:String;

begin
  SHGetFolderPath(0,$001A,0,0,@path[0]);
  MessageBox(0,Path,'a',0);
end.

結果には、問題なく AppData フォルダーへのパスが明確に示されています。

SHGetFolderPathA を使用して x32 Vista でこの同じコードを実行すると、問題なく動作します。

誰かがこれがなぜなのかに光を当てることができたら? 「W」API は通常、Unicode マシンで使用するためのものであるという印象を受けました...?


編集:

私は現在、同じエラーで次のコードを使用しています:

uses
  Windows;

function SHGetFolderPath(hwnd: HWND; csidl: Integer; hToken: THandle; dwFlags: DWord; pszPath: PAnsiChar): HRESULT; stdcall; external 'SHFolder.dll' name 'SHGetFolderPathA';

var
  path: array[0..MAX_PATH] of char;
begin
  SHGetFolderPath(0,$001A,0,0, @path[0]);
  MessageBox(0,path,'a',0);
end.

最終編集:

回答ありがとうございます。上記の SHGetFolderPath の宣言は問題ありません。すべての回答を調べ、それぞれの情報を取り入れた後、次の結果にたどり着きました。

uses
  Windows;

function SHGetFolderPath(hwnd: HWND; csidl: Integer; hToken: THandle; dwFlags: DWord; pszPath: PAnsiChar): HRESULT; stdcall; external 'shell32.dll' name 'SHGetFolderPathA';

var
  path: array[0..MAX_PATH] of ansichar;
  xRes:String;
begin
  If SHGetFolderPath(0,$001A,0,0, @path[0]) = S_OK Then Begin
    xRes := Path;
    MessageBox(0,PWideChar(xRes),'Result',0);
  End Else
    MessageBox(0,'An error has occurred.','Result',0);
end.

結果のメッセージ ボックスには、AppData パスへのパスが正しく表示されます。

すべての回答に感謝します。

4

3 に答える 3

4

SHGetFolderPathの最後のパラメータをタイプとして宣言しましたPChar。Delphi 2009以降(バージョンのDelphi XE2を含む)はのPCharエイリアスですが、宣言された関数を文字PWideCharを期待する「A」バージョンにリンクするようにDelphiに指示しました。AnsiChar

文字の種類に敏感な関数を宣言するときは、まったく使用PCharしないことをお勧めします。PWideCharまたはを明示的に使用しますPAnsiChar

「A」と「W」のサフィックスは、プログラムが実行されるマシンの種類に関するものではありません。サポートされているすべてのバージョンのWindowsは現在Unicodeです—最後の非UnicodeバージョンはWindowsMEでした。「A」と「W」は、引数の文字タイプを示します。

64ビットバージョンで失敗したときに32ビットバージョンのVistaでコードが機能した理由については、説明がありません。たぶんあなたは幸運で、OSはあなたのケースでたまたまうまくいくいくつかの変換をしました。

于 2012-10-31T22:19:13.920 に答える
1

Charは XE2 の Unicode ですが、Ansi バージョンをインポートしSHGetFolderPath()て Unicode 出力バッファを渡しています。これが、ごみを表示している理由MessageBox()です。Unicode ダイアログ ボックスに Ansi データを表示しようとしています。SHGetFolderPath()代わりに、次の Unicode バージョンをインポートする必要があります。

uses
  Windows;

function SHGetFolderPath(hwnd: HWND; csidl: Integer; hToken: THandle; dwFlags: DWord; pszPath: PWideChar): HRESULT; stdcall; external 'SHFolder.dll' name 'SHGetFolderPathW';

var
  path: array[0..MAX_PATH] of Char;
begin
  SHGetFolderPath(0, $001A, 0, 0, path);
  MessageBox(0, path,'a', 0);
end.

ところで、XE2 はすでに Ansi バージョンと Unicode バージョンの両方をインポートしSHGetFolderPath()、CSIDL 値を定義しているため、手動で行う必要はありません。

uses
  Windows, ShlObj, SHFolder;

var
  path: array[0..MAX_PATH] of Char;
begin
  SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, path);
  MessageBox(0, path, 'a', 0);
end.
于 2012-10-31T23:16:29.893 に答える
0

あなたのコードで私は見る2つの間違い1つの間違い:

-「パス」はローカル変数(つまりスタック上)として宣言されているため、「ランダム」/古いデータが含まれています。ゼロで初期化することをお勧めします:fillChar(path [0]、sizeOf(path)、#0)

  • SHGetFolderPathは関数です。値を返します。関数の結果をテストして、それが成功したかどうかを確認することは決してありません。「path」変数の内容を出力するだけです。しかし、SHGetFolderPathが何らかの理由で失敗した場合、内容は意味がありますか?
于 2012-10-31T23:01:06.553 に答える