Win32 API 日本語リファレンス
ホームUI.Shell › SHGetFileInfoA

SHGetFileInfoA

関数
ファイルのアイコンや種類名などの情報を取得する。
DLLSHELL32.dll文字セットANSI (-A)呼出規約winapi対応OSWindows XP 以降

シグネチャ

// SHELL32.dll  (ANSI / -A)
#include <windows.h>

UINT_PTR SHGetFileInfoA(
    LPCSTR pszPath,
    FILE_FLAGS_AND_ATTRIBUTES dwFileAttributes,
    SHFILEINFOA* psfi,   // optional
    DWORD cbFileInfo,
    SHGFI_FLAGS uFlags
);

パラメーター

名前方向説明
pszPathLPCSTRin

パスとファイル名を含む、最大長 MAX_PATHnull 終端文字列へのポインターです。絶対パスと相対パスのどちらも有効です。

uFlags パラメーターに SHGFI_PIDL フラグが含まれている場合、このパラメーターは、Shell の名前空間内でファイルを一意に識別する項目識別子のリストを含む ITEMIDLIST(PIDL)構造体のアドレスでなければなりません。この PIDL は完全修飾 PIDL である必要があります。相対 PIDL は使用できません。

uFlags パラメーターに SHGFI_USEFILEATTRIBUTES フラグが含まれている場合、このパラメーターは有効なファイル名である必要はありません。この関数は、指定された名前と、dwFileAttributes パラメーターで渡されたファイル属性を持つファイルが存在するものとして処理を進めます。これにより、pszPath に拡張子のみを渡し、dwFileAttributesFILE_ATTRIBUTE_NORMAL を渡すことで、ファイルの種類に関する情報を取得できます。

この文字列には、短い形式(8.3 形式)と長いファイル名のどちらも使用できます。

dwFileAttributesFILE_FLAGS_AND_ATTRIBUTESin1 つ以上の ファイル属性フラグ(Winnt.h で定義されている FILE_ATTRIBUTE_ 値)の組み合わせです。uFlagsSHGFI_USEFILEATTRIBUTES フラグが含まれていない場合、このパラメーターは無視されます。
psfiSHFILEINFOA*inoutoptionalファイル情報を受け取る SHFILEINFO 構造体へのポインターです。
cbFileInfoDWORDinpsfi パラメーターが指す SHFILEINFO 構造体のサイズ(バイト単位)です。
uFlagsSHGFI_FLAGSin

取得するファイル情報を指定するフラグです。このパラメーターには、次の値の組み合わせを指定できます。

SHGFI_ADDOVERLAYS (0x000000020)

バージョン 5.0。ファイルのアイコンに適切なオーバーレイを適用します。SHGFI_ICON フラグも設定する必要があります。

SHGFI_ATTR_SPECIFIED (0x000020000)

SHGFI_ATTRIBUTES を変更し、psfi にある SHFILEINFO 構造体の dwAttributes メンバーに、取得したい特定の属性が含まれていることを示します。これらの属性は IShellFolder::GetAttributesOf に渡されます。このフラグが指定されていない場合、IShellFolder::GetAttributesOf には 0xFFFFFFFF が渡され、すべての属性が要求されます。このフラグは SHGFI_ICON フラグと同時に指定できません。

SHGFI_ATTRIBUTES (0x000000800)

項目の属性を取得します。属性は psfi パラメーターで指定された構造体の dwAttributes メンバーにコピーされます。これらは IShellFolder::GetAttributesOf から取得される属性と同じものです。

SHGFI_DISPLAYNAME (0x000000200)

ファイルの表示名を取得します。これは Windows エクスプローラーに表示される名前です。名前は psfi で指定された構造体の szDisplayName メンバーにコピーされます。返される表示名は、長いファイル名がある場合はそれを使用し、8.3 形式のファイル名は使用しません。なお、表示名は拡張子を表示するかどうかなどの設定の影響を受ける場合があります。

SHGFI_EXETYPE (0x000002000)

pszPath が実行可能ファイルを示している場合、その実行可能ファイルの種類を取得します。情報は戻り値にパックされます。このフラグは他のどのフラグとも同時に指定できません。

SHGFI_ICON (0x000000100)

ファイルを表すアイコンのハンドルと、システムイメージリスト内のアイコンのインデックスを取得します。ハンドルは psfi で指定された構造体の hIcon メンバーにコピーされ、インデックスは iIcon メンバーにコピーされます。

SHGFI_ICONLOCATION (0x000001000)

pszPath で指定されたファイルを表すアイコンを含むファイルの名前を、そのファイルのアイコンハンドラーの IExtractIcon::GetIconLocation メソッドが返すとおりに取得します。また、そのファイル内のアイコンのインデックスも取得します。アイコンを含むファイルの名前は psfi で指定された構造体の szDisplayName メンバーにコピーされます。アイコンのインデックスはその構造体の iIcon メンバーにコピーされます。

SHGFI_LARGEICON (0x000000000)

SHGFI_ICON を変更し、関数がファイルの大きいアイコンを取得するようにします。SHGFI_ICON フラグも設定する必要があります。

SHGFI_LINKOVERLAY (0x000008000)

SHGFI_ICON を変更し、関数がファイルのアイコンにリンクオーバーレイを追加するようにします。SHGFI_ICON フラグも設定する必要があります。

SHGFI_OPENICON (0x000000002)

SHGFI_ICON を変更し、関数がファイルの開いた状態のアイコンを取得するようにします。また、SHGFI_SYSICONINDEX を変更し、関数がファイルの小さい開いた状態のアイコンを含むシステムイメージリストへのハンドルを返すようにするためにも使用されます。コンテナーオブジェクトは、コンテナーが開いていることを示すために開いた状態のアイコンを表示します。SHGFI_ICON フラグまたは SHGFI_SYSICONINDEX フラグ(あるいは両方)も設定する必要があります。

SHGFI_OVERLAYINDEX (0x000000040)

バージョン 5.0。オーバーレイアイコンのインデックスを返します。オーバーレイインデックスの値は、psfi で指定された構造体の iIcon メンバーの上位 8 ビットに返されます。このフラグを使用するには、SHGFI_ICON も設定する必要があります。

SHGFI_PIDL (0x000000008)

pszPath がパス名ではなく ITEMIDLIST 構造体のアドレスであることを示します。

SHGFI_SELECTED (0x000010000)

SHGFI_ICON を変更し、関数がファイルのアイコンをシステムのハイライト色とブレンドするようにします。SHGFI_ICON フラグも設定する必要があります。

SHGFI_SHELLICONSIZE (0x000000004)

SHGFI_ICON を変更し、関数が Shell サイズのアイコンを取得するようにします。このフラグが指定されていない場合、関数はシステムメトリック値に従ってアイコンのサイズを決定します。SHGFI_ICON フラグも設定する必要があります。

SHGFI_SMALLICON (0x000000001)

SHGFI_ICON を変更し、関数がファイルの小さいアイコンを取得するようにします。また、SHGFI_SYSICONINDEX を変更し、関数が小さいアイコンイメージを含むシステムイメージリストへのハンドルを返すようにするためにも使用されます。SHGFI_ICON フラグまたは SHGFI_SYSICONINDEX フラグ(あるいは両方)も設定する必要があります。

SHGFI_SYSICONINDEX (0x000004000)

システムイメージリストのアイコンのインデックスを取得します。成功した場合、インデックスは psfiiIcon メンバーにコピーされます。戻り値はシステムイメージリストへのハンドルです。インデックスが iIcon に正常にコピーされたイメージのみが有効です。システムイメージリスト内の他のイメージにアクセスしようとすると、未定義の動作になります。

SHGFI_TYPENAME (0x000000400)

ファイルの種類を説明する文字列を取得します。この文字列は psfi で指定された構造体の szTypeName メンバーにコピーされます。

SHGFI_USEFILEATTRIBUTES (0x000000010)

関数が pszPath で指定されたファイルにアクセスを試みるべきではないことを示します。代わりに、pszPath で指定されたファイルが dwFileAttributes で渡されたファイル属性を持って存在するかのように動作します。このフラグは SHGFI_ATTRIBUTESSHGFI_EXETYPESHGFI_PIDL の各フラグと組み合わせることはできません。

戻り値の型: UINT_PTR

公式ドキュメント

ファイル、フォルダー、ディレクトリ、ドライブのルートなど、ファイルシステム内のオブジェクトに関する情報を取得します。(ANSI)

戻り値

型: DWORD_PTR

意味が uFlags パラメーターに依存する値を返します。

uFlagsSHGFI_EXETYPE または SHGFI_SYSICONINDEX が含まれていない場合、戻り値は成功した場合は 0 以外、それ以外の場合は 0 になります。

uFlagsSHGFI_EXETYPE フラグが含まれている場合、戻り値は実行可能ファイルの種類を指定します。次のいずれかの値になります。

戻りコード 説明
0
実行不可能なファイル、またはエラー状態。
LOWORD = NE または PE、HIWORD = Windows のバージョン
Windows アプリケーション。
LOWORD = MZ、HIWORD = 0
MS-DOS の .exe または .com ファイル
LOWORD = PE、HIWORD = 0
コンソールアプリケーションまたは .bat ファイル

解説(Remarks)

この関数はバックグラウンドスレッドから呼び出す必要があります。そうしないと、UI が応答しなくなる可能性があります。

SHGetFileInfopsfi が指す SHFILEINFO 構造体の hIcon メンバーにアイコンハンドルを返した場合、不要になった時点で DestroyIcon でそれを解放する責任があります。

システムイメージリストへのハンドルを取得すれば、Image List API を使用して、他のイメージリストと同様に操作できます。システムイメージリストはプロセスごとに作成されるため、読み取り専用オブジェクトとして扱う必要があります。システムイメージリストへの書き込みを行うと、システムイメージのいずれかが上書きまたは削除され、そのプロセスの残りの期間中、利用できなくなったり正しくなくなったりする可能性があります。
SHGetFileInfo を呼び出す前に、CoInitialize または OleInitialize でコンポーネントオブジェクトモデル(COM)を初期化する必要があります。

SHGFI_EXETYPE フラグを Windows アプリケーションに対して使用すると、その実行可能ファイルの Windows バージョンが戻り値の HIWORD に格納されます。このバージョンは 16 進数の値として返されます。この値を特定の Windows バージョンに対応付ける方法の詳細については、Using the Windows Headers を参照してください。

次のコード例では、SHGetFileInfo を使用して、PIDL で識別されるごみ箱の表示名を取得します。

LPITEMIDLIST pidl = NULL;
hr = SHGetFolderLocation(NULL, CSIDL_BITBUCKET, NULL, 0, &pidl);

if (SUCCEEDED(hr))                    
{
    SHFILEINFOW sfi = {0};
    hr = SHGetFileInfo((LPCTSTR)pidl,
                        -1,
                        &sfi,
                        sizeof(sfi),
                        SHGFI_PIDL | SHGFI_DISPLAYNAME)
            
    if (SUCCEEDED(hr))
    {
        // The display name is now held in sfi.szDisplayName.
    }
}

ILFree(pidl);
メモ

shellapi.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして SHGetFileInfo を定義しています。エンコーディング中立のエイリアスの使用を、エンコーディング中立ではないコードと混在させると、コンパイルエラーや実行時エラーを引き起こす不一致が生じる可能性があります。詳細については、Conventions for Function Prototypes を参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// SHELL32.dll  (ANSI / -A)
#include <windows.h>

UINT_PTR SHGetFileInfoA(
    LPCSTR pszPath,
    FILE_FLAGS_AND_ATTRIBUTES dwFileAttributes,
    SHFILEINFOA* psfi,   // optional
    DWORD cbFileInfo,
    SHGFI_FLAGS uFlags
);
[DllImport("SHELL32.dll", CharSet = CharSet.Ansi, ExactSpelling = true)]
static extern UIntPtr SHGetFileInfoA(
    [MarshalAs(UnmanagedType.LPStr)] string pszPath,   // LPCSTR
    uint dwFileAttributes,   // FILE_FLAGS_AND_ATTRIBUTES
    IntPtr psfi,   // SHFILEINFOA* optional, in/out
    uint cbFileInfo,   // DWORD
    uint uFlags   // SHGFI_FLAGS
);
<DllImport("SHELL32.dll", CharSet:=CharSet.Ansi, ExactSpelling:=True)>
Public Shared Function SHGetFileInfoA(
    <MarshalAs(UnmanagedType.LPStr)> pszPath As String,   ' LPCSTR
    dwFileAttributes As UInteger,   ' FILE_FLAGS_AND_ATTRIBUTES
    psfi As IntPtr,   ' SHFILEINFOA* optional, in/out
    cbFileInfo As UInteger,   ' DWORD
    uFlags As UInteger   ' SHGFI_FLAGS
) As UIntPtr
End Function
' pszPath : LPCSTR
' dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES
' psfi : SHFILEINFOA* optional, in/out
' cbFileInfo : DWORD
' uFlags : SHGFI_FLAGS
Declare PtrSafe Function SHGetFileInfoA Lib "shell32" ( _
    ByVal pszPath As String, _
    ByVal dwFileAttributes As Long, _
    ByVal psfi As LongPtr, _
    ByVal cbFileInfo As Long, _
    ByVal uFlags As Long) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

SHGetFileInfoA = ctypes.windll.shell32.SHGetFileInfoA
SHGetFileInfoA.restype = ctypes.c_size_t
SHGetFileInfoA.argtypes = [
    wintypes.LPCSTR,  # pszPath : LPCSTR
    wintypes.DWORD,  # dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES
    ctypes.c_void_p,  # psfi : SHFILEINFOA* optional, in/out
    wintypes.DWORD,  # cbFileInfo : DWORD
    wintypes.DWORD,  # uFlags : SHGFI_FLAGS
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('SHELL32.dll')
SHGetFileInfoA = Fiddle::Function.new(
  lib['SHGetFileInfoA'],
  [
    Fiddle::TYPE_VOIDP,  # pszPath : LPCSTR
    -Fiddle::TYPE_INT,  # dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES
    Fiddle::TYPE_VOIDP,  # psfi : SHFILEINFOA* optional, in/out
    -Fiddle::TYPE_INT,  # cbFileInfo : DWORD
    -Fiddle::TYPE_INT,  # uFlags : SHGFI_FLAGS
  ],
  Fiddle::TYPE_UINTPTR_T)
#[link(name = "shell32")]
extern "system" {
    fn SHGetFileInfoA(
        pszPath: *const u8,  // LPCSTR
        dwFileAttributes: u32,  // FILE_FLAGS_AND_ATTRIBUTES
        psfi: *mut SHFILEINFOA,  // SHFILEINFOA* optional, in/out
        cbFileInfo: u32,  // DWORD
        uFlags: u32  // SHGFI_FLAGS
    ) -> usize;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("SHELL32.dll", CharSet = CharSet.Ansi)]
public static extern UIntPtr SHGetFileInfoA([MarshalAs(UnmanagedType.LPStr)] string pszPath, uint dwFileAttributes, IntPtr psfi, uint cbFileInfo, uint uFlags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'SHELL32_SHGetFileInfoA' -Namespace Win32 -PassThru
# $api::SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags)
#uselib "SHELL32.dll"
#func global SHGetFileInfoA "SHGetFileInfoA" sptr, sptr, sptr, sptr, sptr
; SHGetFileInfoA pszPath, dwFileAttributes, varptr(psfi), cbFileInfo, uFlags   ; 戻り値は stat
; pszPath : LPCSTR -> "sptr"
; dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "sptr"
; psfi : SHFILEINFOA* optional, in/out -> "sptr"
; cbFileInfo : DWORD -> "sptr"
; uFlags : SHGFI_FLAGS -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "SHELL32.dll"
#cfunc global SHGetFileInfoA "SHGetFileInfoA" str, int, var, int, int
; res = SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags)
; pszPath : LPCSTR -> "str"
; dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "int"
; psfi : SHFILEINFOA* optional, in/out -> "var"
; cbFileInfo : DWORD -> "int"
; uFlags : SHGFI_FLAGS -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; UINT_PTR SHGetFileInfoA(LPCSTR pszPath, FILE_FLAGS_AND_ATTRIBUTES dwFileAttributes, SHFILEINFOA* psfi, DWORD cbFileInfo, SHGFI_FLAGS uFlags)
#uselib "SHELL32.dll"
#cfunc global SHGetFileInfoA "SHGetFileInfoA" str, int, var, int, int
; res = SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags)
; pszPath : LPCSTR -> "str"
; dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "int"
; psfi : SHFILEINFOA* optional, in/out -> "var"
; cbFileInfo : DWORD -> "int"
; uFlags : SHGFI_FLAGS -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	shell32 = windows.NewLazySystemDLL("SHELL32.dll")
	procSHGetFileInfoA = shell32.NewProc("SHGetFileInfoA")
)

// pszPath (LPCSTR), dwFileAttributes (FILE_FLAGS_AND_ATTRIBUTES), psfi (SHFILEINFOA* optional, in/out), cbFileInfo (DWORD), uFlags (SHGFI_FLAGS)
r1, _, err := procSHGetFileInfoA.Call(
	uintptr(unsafe.Pointer(windows.BytePtrFromString(pszPath))),
	uintptr(dwFileAttributes),
	uintptr(psfi),
	uintptr(cbFileInfo),
	uintptr(uFlags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // UINT_PTR
function SHGetFileInfoA(
  pszPath: PAnsiChar;   // LPCSTR
  dwFileAttributes: DWORD;   // FILE_FLAGS_AND_ATTRIBUTES
  psfi: Pointer;   // SHFILEINFOA* optional, in/out
  cbFileInfo: DWORD;   // DWORD
  uFlags: DWORD   // SHGFI_FLAGS
): NativeUInt; stdcall;
  external 'SHELL32.dll' name 'SHGetFileInfoA';
result := DllCall("SHELL32\SHGetFileInfoA"
    , "AStr", pszPath   ; LPCSTR
    , "UInt", dwFileAttributes   ; FILE_FLAGS_AND_ATTRIBUTES
    , "Ptr", psfi   ; SHFILEINFOA* optional, in/out
    , "UInt", cbFileInfo   ; DWORD
    , "UInt", uFlags   ; SHGFI_FLAGS
    , "UPtr")   ; return: UINT_PTR
●SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags) = DLL("SHELL32.dll", "int SHGetFileInfoA(char*, dword, void*, dword, dword)")
# 呼び出し: SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags)
# pszPath : LPCSTR -> "char*"
# dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "dword"
# psfi : SHFILEINFOA* optional, in/out -> "void*"
# cbFileInfo : DWORD -> "dword"
# uFlags : SHGFI_FLAGS -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "shell32" fn SHGetFileInfoA(
    pszPath: [*c]const u8, // LPCSTR
    dwFileAttributes: u32, // FILE_FLAGS_AND_ATTRIBUTES
    psfi: [*c]SHFILEINFOA, // SHFILEINFOA* optional, in/out
    cbFileInfo: u32, // DWORD
    uFlags: u32 // SHGFI_FLAGS
) callconv(std.os.windows.WINAPI) usize;
proc SHGetFileInfoA(
    pszPath: cstring,  # LPCSTR
    dwFileAttributes: uint32,  # FILE_FLAGS_AND_ATTRIBUTES
    psfi: ptr SHFILEINFOA,  # SHFILEINFOA* optional, in/out
    cbFileInfo: uint32,  # DWORD
    uFlags: uint32  # SHGFI_FLAGS
): uint {.importc: "SHGetFileInfoA", stdcall, dynlib: "SHELL32.dll".}
pragma(lib, "shell32");
extern(Windows)
size_t SHGetFileInfoA(
    const(char)* pszPath,   // LPCSTR
    uint dwFileAttributes,   // FILE_FLAGS_AND_ATTRIBUTES
    SHFILEINFOA* psfi,   // SHFILEINFOA* optional, in/out
    uint cbFileInfo,   // DWORD
    uint uFlags   // SHGFI_FLAGS
);
ccall((:SHGetFileInfoA, "SHELL32.dll"), stdcall, Csize_t,
      (Cstring, UInt32, Ptr{SHFILEINFOA}, UInt32, UInt32),
      pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags)
# pszPath : LPCSTR -> Cstring
# dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> UInt32
# psfi : SHFILEINFOA* optional, in/out -> Ptr{SHFILEINFOA}
# cbFileInfo : DWORD -> UInt32
# uFlags : SHGFI_FLAGS -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
uintptr_t SHGetFileInfoA(
    const char* pszPath,
    uint32_t dwFileAttributes,
    void* psfi,
    uint32_t cbFileInfo,
    uint32_t uFlags);
]]
local shell32 = ffi.load("shell32")
-- shell32.SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags)
-- pszPath : LPCSTR
-- dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES
-- psfi : SHFILEINFOA* optional, in/out
-- cbFileInfo : DWORD
-- uFlags : SHGFI_FLAGS
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('SHELL32.dll');
const SHGetFileInfoA = lib.func('__stdcall', 'SHGetFileInfoA', 'uintptr_t', ['str', 'uint32_t', 'void *', 'uint32_t', 'uint32_t']);
// SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags)
// pszPath : LPCSTR -> 'str'
// dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> 'uint32_t'
// psfi : SHFILEINFOA* optional, in/out -> 'void *'
// cbFileInfo : DWORD -> 'uint32_t'
// uFlags : SHGFI_FLAGS -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("SHELL32.dll", {
  SHGetFileInfoA: { parameters: ["buffer", "u32", "pointer", "u32", "u32"], result: "usize" },
});
// lib.symbols.SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags)
// pszPath : LPCSTR -> "buffer"
// dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "u32"
// psfi : SHFILEINFOA* optional, in/out -> "pointer"
// cbFileInfo : DWORD -> "u32"
// uFlags : SHGFI_FLAGS -> "u32"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
size_t SHGetFileInfoA(
    const char* pszPath,
    uint32_t dwFileAttributes,
    void* psfi,
    uint32_t cbFileInfo,
    uint32_t uFlags);
C, "SHELL32.dll");
// $ffi->SHGetFileInfoA(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags);
// pszPath : LPCSTR
// dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES
// psfi : SHFILEINFOA* optional, in/out
// cbFileInfo : DWORD
// uFlags : SHGFI_FLAGS
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Shell32 extends StdCallLibrary {
    Shell32 INSTANCE = Native.load("shell32", Shell32.class, W32APIOptions.ASCII_OPTIONS);
    long SHGetFileInfoA(
        String pszPath,   // LPCSTR
        int dwFileAttributes,   // FILE_FLAGS_AND_ATTRIBUTES
        Pointer psfi,   // SHFILEINFOA* optional, in/out
        int cbFileInfo,   // DWORD
        int uFlags   // SHGFI_FLAGS
    );
}
@[Link("shell32")]
lib LibSHELL32
  fun SHGetFileInfoA = SHGetFileInfoA(
    pszPath : UInt8*,   # LPCSTR
    dwFileAttributes : UInt32,   # FILE_FLAGS_AND_ATTRIBUTES
    psfi : SHFILEINFOA*,   # SHFILEINFOA* optional, in/out
    cbFileInfo : UInt32,   # DWORD
    uFlags : UInt32   # SHGFI_FLAGS
  ) : LibC::SizeT
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef SHGetFileInfoANative = UintPtr Function(Pointer<Utf8>, Uint32, Pointer<Void>, Uint32, Uint32);
typedef SHGetFileInfoADart = int Function(Pointer<Utf8>, int, Pointer<Void>, int, int);
final SHGetFileInfoA = DynamicLibrary.open('SHELL32.dll')
    .lookupFunction<SHGetFileInfoANative, SHGetFileInfoADart>('SHGetFileInfoA');
// pszPath : LPCSTR -> Pointer<Utf8>
// dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> Uint32
// psfi : SHFILEINFOA* optional, in/out -> Pointer<Void>
// cbFileInfo : DWORD -> Uint32
// uFlags : SHGFI_FLAGS -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function SHGetFileInfoA(
  pszPath: PAnsiChar;   // LPCSTR
  dwFileAttributes: DWORD;   // FILE_FLAGS_AND_ATTRIBUTES
  psfi: Pointer;   // SHFILEINFOA* optional, in/out
  cbFileInfo: DWORD;   // DWORD
  uFlags: DWORD   // SHGFI_FLAGS
): NativeUInt; stdcall;
  external 'SHELL32.dll' name 'SHGetFileInfoA';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "SHGetFileInfoA"
  c_SHGetFileInfoA :: CString -> Word32 -> Ptr () -> Word32 -> Word32 -> IO CUIntPtr
-- pszPath : LPCSTR -> CString
-- dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> Word32
-- psfi : SHFILEINFOA* optional, in/out -> Ptr ()
-- cbFileInfo : DWORD -> Word32
-- uFlags : SHGFI_FLAGS -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let shgetfileinfoa =
  foreign "SHGetFileInfoA"
    (string @-> uint32_t @-> (ptr void) @-> uint32_t @-> uint32_t @-> returning size_t)
(* pszPath : LPCSTR -> string *)
(* dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> uint32_t *)
(* psfi : SHFILEINFOA* optional, in/out -> (ptr void) *)
(* cbFileInfo : DWORD -> uint32_t *)
(* uFlags : SHGFI_FLAGS -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library shell32 (t "SHELL32.dll"))
(cffi:use-foreign-library shell32)

(cffi:defcfun ("SHGetFileInfoA" shget-file-info-a :convention :stdcall) :uint64
  (psz-path :string)   ; LPCSTR
  (dw-file-attributes :uint32)   ; FILE_FLAGS_AND_ATTRIBUTES
  (psfi :pointer)   ; SHFILEINFOA* optional, in/out
  (cb-file-info :uint32)   ; DWORD
  (u-flags :uint32))   ; SHGFI_FLAGS
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $SHGetFileInfoA = Win32::API::More->new('SHELL32',
    'WPARAM SHGetFileInfoA(LPCSTR pszPath, DWORD dwFileAttributes, LPVOID psfi, DWORD cbFileInfo, DWORD uFlags)');
# my $ret = $SHGetFileInfoA->Call($pszPath, $dwFileAttributes, $psfi, $cbFileInfo, $uFlags);
# pszPath : LPCSTR -> LPCSTR
# dwFileAttributes : FILE_FLAGS_AND_ATTRIBUTES -> DWORD
# psfi : SHFILEINFOA* optional, in/out -> LPVOID
# cbFileInfo : DWORD -> DWORD
# uFlags : SHGFI_FLAGS -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

文字セット違い
使用する型