|
■No67567 (Azulean さん) に返信
> 回答ではありませんが、Windows 7 あたりから Initial directory に関する仕様が変更されています。
過去の SDK も含めて調べてみました。
Windows 7 どころか、以前から少しずつ変更されていたようですね。
(Win8, Win8.1 向けの記述は見つけられませんでした…)
Windows 95/NT:
1. lpstrInitialDir メンバで指定されたディレクトリが初期ディレクトリになります。
2. lpstrInitialDir メンバが 0 (NULL) であり、かつ、lpstrFile メンバが指すバッファに
パスが格納されている場合、そのパスが初期ディレクトリになります。
3. カレントディレクトが初期ディレクトリになります。
Windows 98/Me:
1. lpstrInitialDir メンバで指定されたディレクトリが初期ディレクトリになります。
2. lpstrInitialDir メンバが 0 (NULL) であり、かつ、lpstrFile メンバが指すバッファに
パスが格納されている場合、そのパスが初期ディレクトリになります。
3. 指定されたフィルタタイプのファイルがカレントディレクトに存在する場合には、
カレントディレクトリが初期ディレクトリになります。
4. 現在のユーザーのパーソナルファイルディレクトリが初期ディレクトリになります。
Windows 2000/XP/Vista:
1. lpstrFile メンバが指すバッファにパスが格納されている場合、そのパスが初期ディレクトリになります。
2. lpstrInitialDir メンバで指定されたディレクトリが初期ディレクトリになります。
3. 以前に『開く』または『名前を付けて保存』ダイアログボックスを使用している場合には、
最後に使用したパスが初期ディレクトリとして選択されます。ただし、アプリケーションが
長い間実行されていない場合には、保存されている選択パスの情報は破棄されます。
4. lpstrInitialDir メンバが 0 (NULL) であり、かつ、指定されたフィルタタイプのファイルが
カレントディレクトに存在する場合には、カレントディレクトリが初期ディレクトリになります。
5. 現在のユーザーのパーソナルファイルディレクトリが初期ディレクトリになります。
6. デスクトップフォルダが初期ディレクトリになります。
Windows 7:
1. lpstrInitialDir メンバが、以前に『開く』または『名前を付けて保存』ダイアログボックスを
初回起動した時の値と同じ場合、最後に使用したパスが初期ディレクトリになります。
2. lpstrFile メンバにパス情報が含まれている場合、それが初期ディレクトリになります。
3. lpstrInitialDir が 0 (NULL) でない場合、それが初期ディレクトリになります。
4. lpstrInitialDir が 0 (NULL) であり、かつ、指定されたフィルタタイプのファイルが
カレントディレクトに存在する場合には、カレントディレクトリが初期ディレクトリになります。
5. 現在のユーザーのパーソナルファイルディレクトリが初期ディレクトリになります。
6. デスクトップフォルダが初期ディレクトリになります。
以前のパスが使われる件、2000/XP/Vista の第3項では、
However, if an application is not run for a long time, its saved selected path is discarded.
(ただし、アプリが長い間実行されていない場合には、保存されていた選択パスの情報は破棄される)
と書かれていましたが、Win7 の第1項には見当たりませんね…。
■No67591 (Azulean さん) に返信
> ファイルメニューから exe を作成していただき、それで実行すれば再現させられるはずです。
> (うまく再現できない場合は exe 名を変えてみてください。すでに別の InitDir でキャッシュされている可能性があるため)
再現できました。ありがとうございます。
> このあたりはレジストリに記録されています。
> HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32
バイナリで読み難かったので、WshShell で列挙。こちらも確認できました。
Option Explicit
Private Sub Form_Load()
Dim S As String
S = "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\FirstFolder\"
List1.Clear
On Error Resume Next
Dim L As Long, Path As String
Dim value() As Variant
With CreateObject("WScript.Shell")
L = 0
Do
value = .RegRead(S & CStr(L))
If Err.Number <> 0 Then
Exit Do
End If
Path = Replace(CStr(ToBinary(value)), vbNullChar, "|")
List1.AddItem Path
L = L + 1
Loop
End With
End Sub
Private Function ToBinary(ByRef value() As Variant) As Byte()
Dim bin() As Byte
ReDim bin(UBound(value))
Dim n As Long
For n = 0 To UBound(bin)
bin(n) = CByte(value(n))
Next
ToBinary = bin
End Function
> それに逆らってでもディレクトリを固定したいのであれば、MSDN 記述のアルゴリズムを理解した上でうまく特性をつかないといけないと思います。
スマートな回避策は思いつきませんが、無理矢理逆らってみました。
Option Explicit
Private Sub Form_Load()
With Me.CommonDialog1
'.Flags = cdlOFNHideReadOnly Or cdlOFNExplorer Or cdlOFNNoChangeDir
.Flags = 0
.DefaultExt = ".txt"
.Filter = "Text|*.txt|Batch|*.cmd;*.bat"
.FilterIndex = 1
.InitDir = "C:\Tools"
.FileName = "Sample.txt"
End With
End Sub
Private Static Sub Command1_Click()
Dim cyclic As Boolean
cyclic = Not cyclic
If cyclic Then
Me.CommonDialog1.InitDir = "C:\.\"
Else
Me.CommonDialog1.InitDir = "C:\"
End If
Me.CommonDialog1.FileName = ""
Me.CommonDialog1.ShowOpen
End Sub
|