怠日記

写真・金魚・昆虫・プログラミングの趣味を語るサイトです。似たようなことをnoteにも書いたり書いてなかったり。

スマホの100倍ズームで満月を撮る

外が明るいと思ったら月明かりだった。

酔っぱらいでもこのぐらいは撮れてしまうスマホのカメラ、おそるべし。

この写真は100倍ズームだが、それだとフレームにおさめるのが大変なので、80倍程度にしておくともっと楽に撮れると思う。

冷凍庫で割れるグラス

知りませんでした。

飲み物を入れたグラスを冷凍庫に入れると、
なんと割れます!

ただギリッと冷やしたかっただけなんですけどね。

残念ながら、庫内で割れていました。

わかってるよ、Win10のサポートが切れてるなんて

2025年10月14日で Windows 10 のサポートは終了となった。

まぁそんなことはわかっている。
重々承知である。

1分間隔で通知を入れてくるのは、はっきり言って余計なお世話。

16:23に通知が来て、16:24にも通知が来た。
わかってるって、そんなことは!

ちなみに、駆け込みで Windows 11 買おうかなと思ったが、やめた。
なんか魅力的な端末が見つからなくてね。

とりあえず、拡張セキュリティ更新プログラムに登録して、様子を見ながら1年以内に買い替えることにした。

treeコマンドで一部のファイル名が出力されない

Windows の tree コマンドの話。

tree コマンドは次のように /F オプションを付けると、各フォルダにあるファイル名も出力する。

tree /F

しかし、場合によってファイル名が出力されないことがある。
フォルダも含めたファイル名のパスの長さによって、出力されたりされなくなったりするようである。

具体的にはパスの長さが260文字以上となった場合に、ファイル名が出力されなくなる。
(259文字までは出力された)

これは Windows では全体のパスの長さが260文字に制限されていることから来ているのだろう。
(260文字以上はアウト。259文字以下にしなければならない)

検証

パスの長さが259文字と260文字になるファイルを準備して tree コマンドの動きを確かめる。

準備したファイルは次の2つ。
「ファイル名の文字数制限テスト1~」がパスの長さが259文字になるファイル。
「ファイル名の文字数制限テスト2
~」がパスの長さが260文字になるファイル。

C:\Users\username> dir /B C:\test\length
ファイル名の文字数制限テスト1_12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv.txt
ファイル名の文字数制限テスト2_12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw.txt

tree コマンドを実行した結果、パスの長さが259文字のファイルは出力されたが、260文字のファイルは出力されなかった。

C:\Users\username> tree /f C:\test
フォルダー パスの一覧
ボリューム シリアル番号は 9Z99-ZZ9Z です
C:\TEST
└─length
        ファイル名の文字数制限テスト1_12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv.txt

対処法はない(と思う)。
パスが長くなり過ぎないよう気を付けるしかない。

修理受付終了: ニンテンドークラシックミニ ファミコン&スーファミ

2025年9月4日をもって、ニンテンドークラシックミニのファミコンとスーパーファミコンの修理受付を終了したと任天堂が発表した。

え? もう?? と思ったが、実はファミコンは2016年11月発売、スーファミは2017年10月発売で、少なくとも発売から8年は経過していたのだった。

一般的に補修部品の保有・供給は7年だったはずなので、任天堂の修理打ち切りの発表は普通っちゃ普通のことなんだろう。

いや、それにしても早いね。
発売されたばかりのころは絶対コレ欲しい! って思っていたのに、手に入れることなく修理受付終了とはね……。

VBA: Unicodeのiniファイルに書き込むには | WritePrivateProfileStringW関数

VBA で ANSI の ini ファイルに書き込む方法は以下のページに書いたとおり。

nmk365.hatenablog.jp

それと同様に Unicode の ini ファイルに文字列を書き込むには、Win32API の WritePrivateProfileStringW 関数を使う。

サンプルコード

以下に WritePrivateProfileStringW 関数を使った書き込みのサンプルを示す。

Option Explicit

Private Declare PtrSafe Function WritePrivateProfileStringW Lib "kernel32" ( _
    ByVal lpAppName As LongPtr, _
    ByVal lpKeyName As LongPtr, _
    ByVal lpString As LongPtr, _
    ByVal lpFileName As LongPtr _
) As Long

Public Sub Main()

    'マクロブックと同じ場所の app.ini ファイルを対象とする
    Dim iniFilePath As String
    iniFilePath = ThisWorkbook.Path & "\app.ini"

    '値を書き込む
    '  関数の戻り値は正常終了なら0以外、異常終了なら0となる。
    Dim ret As Long
    ret = WritePrivateProfileStringW(StrPtr("TestSection"), _
                                     StrPtr("TestKey"), _
                                     StrPtr("書き込みテスト" & ChrW$(9825)), _
                                     StrPtr(iniFilePath))

    If ret = 0 Then
        Debug.Print "書き込み失敗"
    Else
        Debug.Print "書き込み成功"
    End If

End Sub

事前準備としてマクロを実行する前に、マクロブックと同じ場所に以下のような内容で app.ini ファイルを作っておく。
文字コードは Unicode(UTF-16 LE)にしておくこと。

; iniファイルテスト
[TestSection]
TestKey=設定値

マクロを実行すると TestSection セクションの TestKey キーに「書き込みテスト♡」が設定される。
「♡」は Unicode 文字だが問題なく書き込まれている。

; iniファイルテスト
[TestSection]
TestKey=書き込みテスト♡

もし app.ini ファイルがなかったり、ファイルの文字コードが Unicode でなかったりすると、ANSI 文字が書き込まれる。
Unicode 文字の「♡」は ? になっている。

[TestSection]
TestKey=書き込みテスト?

解説

WritePrivateProfileStringW 関数は次のように定義されている。

BOOL WritePrivateProfileStringW(
  [in] LPCWSTR lpAppName,
  [in] LPCWSTR lpKeyName,
  [in] LPCWSTR lpString,
  [in] LPCWSTR lpFileName
);

データ型の LPCWSTR は Unicode 文字列を表す。

VBA から LPCWSTR に Unicode 文字列を渡すためには、文字列のポインタを渡すようにしなければならない。

よって WritePrivateProfileStringW を VBA の宣言セクションで宣言するときは、データ型を LongPtr にする。
ここを LongPtr ではなく String にしてしまうと正しく動かないので注意してほしい。

Private Declare PtrSafe Function WritePrivateProfileStringW Lib "kernel32" ( _
    ByVal lpAppName As LongPtr, _
    ByVal lpKeyName As LongPtr, _
    ByVal lpString As LongPtr, _
    ByVal lpFileName As LongPtr _
) As Long


WritePrivateProfileStringW 関数は以下のように呼び出す。

StrPtr 関数を使って、VBA の文字列のポインタを引数に渡すのがポイントである。

ret = WritePrivateProfileStringW(StrPtr("TestSection"), _
                                 StrPtr("TestKey"), _
                                 StrPtr("書き込みテスト" & ChrW$(9825)), _
                                 StrPtr(iniFilePath))

戻り値は、書き込みができたら 0 以外、できなかったら 0 になる。


実は WritePrivateProfileStringW 関数は ANSI と Unicode のどちらにも対応している。
どちらを対象とするかは、引数 lpFileName の指定によって決まるらしい。

リファレンスには次のように書かれている。

[in] lpFileName

初期化ファイルの名前。

ファイルが既に存在し、Unicode 文字で構成されている場合、この関数は Unicode 文字をファイルに書き込みます。 それ以外の場合、関数は ANSI 文字を書き込みます。

要は Unicode の ini ファイルがあれば Unicode、それ以外なら ANSI となるようだ。

VBA: Unicodeのiniファイルを読み取るには | GetPrivateProfileStringW関数

VBA で ANSI の ini ファイルを読み取る方法は以下のページに書いたとおり。

nmk365.hatenablog.jp

それと同様に Unicode の ini ファイルから文字列を読み取るには、Win32API の GetPrivateProfileStringW 関数を使う。

サンプルコード

以下に GetPrivateProfileStringW 関数を使った読み取りのサンプルを示す。

Option Explicit

Private Declare PtrSafe Function GetPrivateProfileStringW Lib "kernel32" ( _
    ByVal lpAppName As LongPtr, _
    ByVal lpKeyName As LongPtr, _
    ByVal lpDefault As LongPtr, _
    ByVal lpReturnedString As LongPtr, _
    ByVal nSize As Long, _
    ByVal lpFileName As LongPtr _
) As Long

Public Sub Main()

    'マクロブックと同じ場所の app.ini ファイルを対象とする
    Dim iniFilePath As String
    iniFilePath = ThisWorkbook.Path & "\app.ini"

    'バッファを確保する
    Dim buffer As String
    buffer = String$(512, Chr$(0))

    Dim bufferLength As Long
    bufferLength = Len(buffer)

    '値を読み込む
    '  関数の戻り値はバッファに入れた文字数
    '  読み込んだ文字列は引数 buffer に入れられる
    Dim retLength As Long
    retLength = GetPrivateProfileStringW(StrPtr("TestSection"), _
                                         StrPtr("TestKey"), _
                                         StrPtr("デフォルト値"), _
                                         StrPtr(buffer), _
                                         bufferLength, _
                                         StrPtr(iniFilePath))

    'バッファから読み込んだ文字列を抽出する
    '  このようにしないと不要な値 (バッファ確保で使ったChr$(0)) も一緒に取得してしまうため
    MsgBox Left$(buffer, InStr(buffer, Chr$(0)) - 1), title:="GetPrivateProfileStringW()"

End Sub

マクロを実行する前に、マクロブックと同じ場所に以下のような内容で app.ini ファイルを作っておく。
文字コードは Unicode(UTF-16 LE)にしておくこと。

; iniファイルテスト
[TestSection]
TestKey=読み取りテスト♡

マクロ実行で「読み取りテスト♡」と表示された。
「♡」は Unicode 文字だが問題なく読み取られた。

…となってほしかったが、「♡」は「?」になっていた。
VBA の MsgBox 関数では Unicode 文字が表示できないのかもしれない。

Win32API の MessageBoxW 関数を使ったところ、問題なく表示できた。

解説

ANSI 版と大差ないので、異なる部分を中心に解説する。

まず、GetPrivateProfileStringW 関数は次のように定義されている。

DWORD GetPrivateProfileStringW(
  [in]  LPCWSTR lpAppName,
  [in]  LPCWSTR lpKeyName,
  [in]  LPCWSTR lpDefault,
  [out] LPWSTR  lpReturnedString,
  [in]  DWORD   nSize,
  [in]  LPCWSTR lpFileName
);

データ型が LPWSTR、LPCWSTR の引数には、文字列のポインタを渡すようにしなければならない。

なので VBA で宣言するときは、次のようにデータ型を LongPtr にする。

Private Declare PtrSafe Function GetPrivateProfileStringW Lib "kernel32" ( _
    ByVal lpAppName As LongPtr, _
    ByVal lpKeyName As LongPtr, _
    ByVal lpDefault As LongPtr, _
    ByVal lpReturnedString As LongPtr, _
    ByVal nSize As Long, _
    ByVal lpFileName As LongPtr _
) As Long


GetPrivateProfileStringW 関数は以下のように呼び出す。

StrPtr 関数を使って、VBA の文字列のポインタを引数に渡すのがポイントである。

retLength = GetPrivateProfileStringW(StrPtr("TestSection"), _
                                     StrPtr("TestKey"), _
                                     StrPtr("デフォルト値"), _
                                     StrPtr(buffer), _
                                     bufferLength, _
                                     StrPtr(iniFilePath))

戻り値は、バッファに設定された文字数になる。