空腹おやじのログと備忘録

VBA(主にExcel)でいろいろな実験的な事とか、Linuxのコマンドとか設定とかについて忘れないように、あれこれと・・・

【VBA】FindFirstFileW、FindNextFileWを使ってファイルリストを取得する(Unicode 文字 対応版、64bit版)

FindFirstFileW による Unicode対応してみた

以前の記事で、FindFirstFile を使って、ファイルリストを取得するコードを書いたが、Unicode文字が含まれると文字化けするため修正してみた。
処理としては、ざっくりいうと、FindFirstFileA、FindNextFileA を使用していたものを、FindFirstFileW、FindNextFileW に変えた + 64bit対応したものである。
z1000s.hatenablog.com

2GB超のファイルサイズを求める

ついでなので、2GBを超えるファイルサイズを求める方法も追加してある。
以下の部分です。
fd.nFileSizeLow、fd.nFileSizeHigh が Long なので、&H7FFFFFFF ( 2,147,483,647 ) を超えると負数となるため、それを補正する必要がある。
そこで、LongLong 型の &HFFFFFFFF^、&H7FFFFFFF^ と And を取って Long 型ではなく、LongLong 型にキャストして処理している。
ちなみに、CLngLngは、下図の通りなので却下。

    Dim llFileSize As LongLong
    llFileSize = fd.nFileSizeLow And &HFFFFFFFF^
    llFileSize = llFileSize + (fd.nFileSizeHigh And &H7FFFFFFF^) * &H100000000^


VBA (64bit) で FindFirstFileW (Unicode対応) を使用してファイ…

失敗

2GB超対応で最初に考えたのは、WIN32_FIND_DATAW の、nFileSizeHigh と nFileSizeLow を合わせて、「LongLong のメンバーにまとめてしまえばいいのでは?」と考えたが、VBA の構造体が 4Byte パックなので、LongLong のメンバーにするとその境界を跨ぐため、あっさりと失敗に終わった。
あとから気が付いたが、リトルエンディアンだから、nFileSizeHigh が先にある時点で駄目なんだろう。

Private Type WIN32_FIND_DATAW
    dwFileAttributes        As Long
    ftCreationTime          As FILETIME
    ftLastAccessTime        As FILETIME
    ftLastWriteTime         As FILETIME
    nFileSizeHigh           As Long
    nFileSizeLow            As Long
    dwReserved0             As Long
    dwReserved1             As Long
    cFileName(MAX_PATH * 2 - 1) As Byte
    cAlternateFileName(27)      As Byte
    dwFileType              As Long
    dwCreatorType           As Long
    wFinderFlags            As Integer
End Type