Hi
In recent weeks we have seen customization examples for the classic GetOpenFileName, GetSaveFileName and co. APIs.
There is, however, an alternative that MS recommends. COM programmers designed a way to reduce the complexity of the customization. The core idea is to get access to the file dialogs and their customization using COM interfaces.
In the following example, I only examined the IFileOpenDialog interface defined in the ShObjIDL.inc file. There are interfaces for IFileSaveDialog, IFileOperationProgressSink and many more. I will complete the translation in the next few days, but for this example, it contains all the necessary definitions.
The following code snippet shows how to redefine the Open File dialog box.
COMDLG_FILTERSPEC struc
pszName LPCWSTR ?
pszSpec LPCWSTR ?
COMDLG_FILTERSPEC ends
MultiFileSpec struc
FS0 COMDLG_FILTERSPEC {}
FS1 COMDLG_FILTERSPEC {}
FS2 COMDLG_FILTERSPEC {}
FS3 COMDLG_FILTERSPEC {}
MultiFileSpec ends
Method Application.OnCommand, uses rbx rsi, wParam:WPARAM, lParam:LPARAM
local pIFODlg: POINTER, MFS:MultiFileSpec
local pISIArr:POINTER, dCount:DWORD, pIShellItem:POINTER, pDisplayName:POINTER
SetObject rsi
mov rax, wParam
.if ax == IDM_OPEN
invoke CoCreateInstance, offset CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, \
offset IID_IFileOpenDialog, addr pIFODlg
m2m MFS.FS0.pszName, $OfsCStr("All")
m2m MFS.FS0.pszSpec, $OfsCStr("*.*")
m2m MFS.FS1.pszName, $OfsCStr("Assembly")
m2m MFS.FS1.pszSpec, $OfsCStr("*.asm")
m2m MFS.FS2.pszName, $OfsCStr("Include")
m2m MFS.FS2.pszSpec, $OfsCStr("*.inc")
m2m MFS.FS3.pszName, $OfsCStr("Text")
m2m MFS.FS3.pszSpec, $OfsCStr("*.txt")
ICall pIFODlg::IFileOpenDialog.SetFileTypes, MultiFileSpec/COMDLG_FILTERSPEC, addr MFS
ICall pIFODlg::IFileOpenDialog.SetFileTypeIndex, 2
ICall pIFODlg::IFileOpenDialog.SetOptions, FOS_ALLOWMULTISELECT
ICall pIFODlg::IFileOpenDialog.SetTitle, $OfsCStr("Select a file...")
ICall pIFODlg::IFileOpenDialog.SetOkButtonLabel, $OfsCStr("Select")
ICall pIFODlg::IFileOpenDialog.SetFileNameLabel, $OfsCStr("Selected file name: ")
ICall pIFODlg::IFileOpenDialog.Show, [rsi].hWnd
.if SUCCEEDED(eax)
ICall pIFODlg::IFileOpenDialog.GetResults, addr pISIArr
ICall pISIArr::IShellItemArray.GetCount, addr dCount
xor ebx, ebx
.while ebx < dCount
ICall pISIArr::IShellItemArray.GetItemAt, ebx, addr pIShellItem
ICall pIShellItem::IShellItem.GetDisplayName, SIGDN_NORMALDISPLAY, addr pDisplayName
mov rax, pDisplayName
DbgStr rax
inc ebx
.endw
.endif
…
The attachment contains the executable version of the demo.
Regards, Biterider