- The old-style Common File Dialog and new-style Common Item Dialog have numerous options. However, I could not see any options where the Save As dialog would allow you to choose a read-only file, and no way to disable the read-only file warning. (Apologies if I've overlooked an option.)
- However, the *Open* dialog does allow you to choose a read-only file, and doesn't show a warning.
- So, perhaps the best approach is to use an Open dialog, and tweak the window title/Open button to say 'Save As' and 'Save'.
- This is what I have done in the 2 examples below:
Code: Select all
q:: ;test save as dialog on read-only files
;modify open dialog to appear as a save as dialog
;vOpt := "S" ;save as dialog
vOpt := "O" ;open dialog (but with title/button label changed to look like a save as dialog)
if InStr(vOpt, "S")
{
;save as dialog:
CLSID_FileSaveDialog := "{C0B4E2F3-BA21-4773-8DBA-335EC946EB8B}"
IID_IFileSaveDialog := "{84BCCD23-5FDE-4CDB-AEA4-AF64B83D78AB}"
if !(pFD := ComObjCreate(CLSID_FileSaveDialog, IID_IFileSaveDialog))
return
}
else if InStr(vOpt, "O")
{
;open dialog:
CLSID_FileOpenDialog := "{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}"
IID_IFileOpenDialog := "{d57c7288-d4ad-4768-be02-9d969532d960}"
if !(pFD := ComObjCreate(CLSID_FileOpenDialog, IID_IFileOpenDialog))
return
vTitle := "Save As"
DllCall(NumGet(NumGet(pFD+0)+17*A_PtrSize), "Ptr",pFD, "WStr",vTitle) ;IFileDialog::SetTitle
vButtonLabel := "&Save"
DllCall(NumGet(NumGet(pFD+0)+18*A_PtrSize), "Ptr",pFD, "WStr",vButtonLabel) ;IFileDialog::SetOkButtonLabel
oFilters := ["Text Documents (*.txt)", "*.txt", "All Files", "*.*"]
VarSetCapacity(ArrayCOMDLG_FILTERSPEC, oFilters.Length()*A_PtrSize)
Loop % oFilters.Length()
{
VarSetCapacity(vFilter%A_Index%, StrLen(oFilters[A_Index])*2+2)
StrPut(oFilters[A_Index], &vFilter%A_Index%, "UTF-16")
NumPut(&vFilter%A_Index%, &ArrayCOMDLG_FILTERSPEC, (A_Index-1)*A_PtrSize, "Ptr")
}
DllCall(NumGet(NumGet(pFD+0)+4*A_PtrSize), "Ptr",pFD, "UInt",oFilters.Length()/2, "Ptr",&ArrayCOMDLG_FILTERSPEC) ;IFileDialog::SetFileTypes
}
vFlags := 0
DllCall(NumGet(NumGet(pFD+0)+9*A_PtrSize), "Ptr",pFD, "UInt",vFlags) ;IFileDialog::SetOptions
vRet1 := !DllCall(NumGet(NumGet(pFD+0)+3*A_PtrSize), "Ptr",pFD, "Ptr",hWnd) ;IFileDialog::Show
pSI := 0, vPath := ""
if vRet1
&& !DllCall(NumGet(NumGet(pFD+0)+20*A_PtrSize), "Ptr",pFD, "Ptr*",pSI) ;IFileDialog::GetResult
{
pText := 0
;SIGDN_DESKTOPABSOLUTEPARSING := 0x80028000 ;source: ShObjIdl.h
if !DllCall(NumGet(NumGet(pSI+0)+5*A_PtrSize), "Ptr",pSI, "UInt",0x80028000, "Ptr*",pText) ;IShellItem::GetDisplayName
vPath := StrGet(pText, "UTF-16"), DllCall("ole32\CoTaskMemFree", "Ptr",pText)
ObjRelease(pSI)
vTypeIndex := 0 ;1-based index
DllCall(NumGet(NumGet(pFD+0)+6*A_PtrSize), "Ptr",pFD, "UInt*",vTypeIndex) ;IShellItem::GetFileTypeIndex
vType := oFilters[vTypeIndex*2]
}
ObjRelease(pFD)
MsgBox, % vPath "`r`n" vType
return
;==================================================
w:: ;test save as dialog on read-only files
;modify open dialog to appear as a save as dialog
;vOpt := "S" ;save as dialog
vOpt := "O" ;open dialog (but with title/button label changed to look like a save as dialog)
;for O option:
;vAddHook := 0 ;on Windows Vista+, shows new-style Common Item Dialog
vAddHook := 1 ;shows old-style Common File Dialog
vSize := A_PtrSize=8?152:88
MAX_PATH := 260
vFlags := 0
pFunc := 0
pTitle := 0
if InStr(vOpt, "O") && vAddHook
{
vFlags := 0x20, OFN_ENABLEHOOK := 0x20
vFlags := 0x80020
pFunc := RegisterCallback("CFDOpenAppearAsSaveAs")
vTitle := "Save As"
VarSetCapacity(vTitleW, StrLen(vTitle)*2)
StrPut(vTitle, &vTitleW, "UTF-16")
pTitle := &vTitleW
}
VarSetCapacity(OPENFILENAMEW, vSize, 0)
VarSetCapacity(vPath, MAX_PATH*2, 0)
NumPut(vSize, &OPENFILENAMEW, 0, "UInt") ;lStructSize
NumPut(&vPath, &OPENFILENAMEW, A_PtrSize=8?48:28, "Ptr") ;lpstrFile
NumPut(MAX_PATH, &OPENFILENAMEW, A_PtrSize=8?56:32, "UInt") ;nMaxFile
NumPut(pTitle, &OPENFILENAMEW, A_PtrSize=8?88:48, "Ptr") ;lpstrTitle
NumPut(vFlags, &OPENFILENAMEW, A_PtrSize=8?96:52, "UInt") ;Flags
NumPut(pFunc, &OPENFILENAMEW, A_PtrSize=8?120:68, "Ptr") ;lpfnHook
if InStr(vOpt, "S")
DllCall("comdlg32\GetSaveFileNameW", "Ptr",&OPENFILENAMEW)
else if InStr(vOpt, "O")
DllCall("comdlg32\GetOpenFileNameW", "Ptr",&OPENFILENAMEW)
vPath := StrGet(&vPath, 260, "UTF-16")
MsgBox, % vPath
return
CFDOpenAppearAsSaveAs(hDlg, uMsg, wParam, lParam)
{
local
if (uMsg = 0x110) ;WM_INITDIALOG := 0x110
{
DetectHiddenWindows, On
hWnd := DllCall("user32\GetParent", "Ptr",hDlg, "Ptr")
ControlSetText, Button2, &Save, % "ahk_id " hWnd
}
}
;==================================================
Links (script examples):
FileSelectFile, add controls to the Open/Save As dialog - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=29934
AHKv2: Diálogos para seleccionar Icono, Fuente, Color y Más! [27/04/2018] - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=42&t=10802
Links (structs and interfaces):
list of structs with parameters (sizes and types) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=74&t=30497
list of interfaces with method numbers - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=74&t=67431
Links (constants):
_FILEOPENDIALOGOPTIONS (shobjidl_core.h) - Win32 apps | Microsoft Docs
https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-_fileopendialogoptions
OPENFILENAMEA (commdlg.h) - Win32 apps | Microsoft Docs
https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamea