Indeed the 2 additional controls are there inside notepad.exe (the XP version) as a resource. And similarly in
C:\Windows\System32\en-US\notepad.exe.mui for Windows 7.
I've made my dialog able to handle window resize. I've also made the 2 additional control sizes/positions relative to controls already within the dialog (in case the user uses a big font).
In my txt file of AutoHotkey.chm ...
htm to txt, AutoHotkey Help (chm file) to txt - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 95#p132695
... I only see GetWindowRect mentioned once,
https://autohotkey.com/docs/commands/DllCall.htm, and MapWindowPoints not at all. I'm not quite sure I understood your sentence.
I now have the core functionality I want, my concerns now are:
- Setting the size of hDlg, not the main window, worked to increase the size of the window to that needed for the additional controls, I'm not sure if there is a better method for this.
- To set the overall window size before it's shown (I can change the position). It's the sort of the thing I'd want to have as a user option in software. There's a comment in the code regarding setting the size in the Init. It just created 'greyspace' ('grayspace') on the dialog's right and bottom.
- I only really wanted the 'Encoding' box for the Save As prompt, not the Open prompt. For the Open prompt, each time a different file is selected, the 'Encoding' ComboBox should be updated to reflect the file. I.e. the first 3 bytes are checked for the presence of a UTF-8/UTF-16 (LE/BE) BOM (byte order mark). This would need to be done on both the new/old dialogs.
- If it exists, to use a cleaner method for positioning/sizing the 2 additional controls (which may be affected by the user choosing a big font).
Code: Select all
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force
DetectHiddenWindows, On
VarSetCapacity(OPENFILENAMEW, (cbOFN := A_PtrSize == 8 ? 152 : 88), 0)
NumPut(cbOFN, OPENFILENAMEW,, "UInt") ; lStructSize
NumPut(A_ScriptHwnd, OPENFILENAMEW, A_PtrSize, "Ptr") ; hwndOwner
filters := [ "Text Documents", "*.txt"
,"Test", "*.nfo"
,"All files", "*.*"]
if (IsObject(filters) && Mod(filters.MaxIndex(), 2) == 0) {
finalFilterString := ""
for _, filter in filters
finalFilterString .= Mod(A_Index, 2) ? filter . " (" : filter . ")|" . filter . "|"
while ((char := DllCall("ntdll\wcsrchr", "Ptr", &finalFilterString, "UShort", Asc("|"), "CDecl Ptr")))
NumPut(0, char+0,, "UShort")
NumPut(&finalFilterString, OPENFILENAMEW, A_PtrSize*3, "Ptr") ; lpstrCustomFilter
NumPut(1, OPENFILENAMEW, A_PtrSize*(5 + (A_PtrSize == 4)), "UInt") ; nFilterIndex
}
VarSetCapacity(vPath, (260+2)*2, 0) ; if keeping the option to select multiple files, consider raising the size
vPath .= "*.txt"
NumPut(&vPath, OPENFILENAMEW, A_PtrSize*(6 + (A_PtrSize == 4)), "Ptr") ; lpstrFile
NumPut(260, OPENFILENAMEW, A_PtrSize*(7 + (A_PtrSize == 4)), "UInt") ; nMaxFile
initialDir := A_Desktop
title := "Open"
NumPut(&initialDir, OPENFILENAMEW, A_PtrSize*(10 + (A_PtrSize == 4)), "Ptr") ; lpstrInitialDir
NumPut(&title, OPENFILENAMEW, A_PtrSize*(11 + (A_PtrSize == 4)), "Ptr") ; lpstrTitle
NumPut((cb := RegisterCallback("OFNHookProc")), OPENFILENAMEW, A_PtrSize == 8 ? 120 : 68, "Ptr")
;OFN_ENABLESIZING := 0x00800000
;OFN_EXPLORER := 0x00080000
;OFN_ALLOWMULTISELECT := 0x00000200
;OFN_ENABLEHOOK := 0x00000020
;OFN_HIDEREADONLY := 0x00000004
vOFNFlags := 0x00880224
NumPut(vOFNFlags, OPENFILENAMEW, A_PtrSize*(12 + (A_PtrSize == 4)), "UInt") ; Flags
if (DllCall("comdlg32\GetOpenFileNameW", "Ptr", &OPENFILENAMEW)) {
dirOrFile := StrGet(&vPath,, "UTF-16")
if (InStr(FileExist(dirOrFile), "D")) {
; Multiple files selected
fileNames := &vPath + (NumGet(OPENFILENAMEW, A_PtrSize == 8 ? 100 : 56, "UShort") * 2)
while (*fileNames) {
MsgBox % dirOrFile . "\" . (filename := StrGet(fileNames,, "UTF-16"))
fileNames += (DllCall("ntdll\wcslen", "Ptr", fileNames, "CDecl Ptr") * 2) + 2
}
} else {
MsgBox %dirOrFile%
}
if (ColorSelection)
MsgBox % ColorSelection
}
DllCall("GlobalFree", "Ptr", cb, "Ptr")
return
;==================================================
OFNHookProc(hdlg, uiMsg, wParam, lParam)
{
DetectHiddenWindows, On
global ColorSelection
if (uiMsg == 0x0110) { ; WM_INITDIALOG
hWndParent := DllCall("GetParent", "Ptr", hdlg, "Ptr")
ControlGet, hCtl1, Hwnd, , Static4, % "ahk_id " hWndParent
ControlGet, hCtl2, Hwnd, , ComboBox3, % "ahk_id " hWndParent
JEE_ControlGetPosClient(hWndParent, hCtl1, vPosX1, vPosY1, vPosW1, vPosH1)
JEE_ControlGetPosClient(hWndParent, hCtl2, vPosX2, vPosY2, vPosW2, vPosH2)
WinMove, % "ahk_id " hdlg, , , , , % vPosH2+15
vPosX1 += 1, vPosY1 += vPosH1+15, vPosW1 *=0.69, vPosH1 *= 5
vPosY2 += vPosH2+8
Gui, Add, Text, x%vPosX1% y%vPosY1% w%vPosW1% h%vPosH1% hWndhCtl1, &Encoding:
;note: for 'Gui, Add, DropDownList', h determines the height of the popup list not the ComboBox
Gui, Add, DropDownList, x%vPosX2% y%vPosY2% w%vPosW2% hwndhCtl2 vColorSelection, ANSI||Unicode|Unicode big endian|UTF-8
DllCall("SetParent", "Ptr", hCtl1, "Ptr", hWndParent, "Ptr")
DllCall("SetParent", "Ptr", hCtl2, "Ptr", hWndParent, "Ptr")
;resize window - including this line will not resize the window as desired
;WinMove, % "ahk_id " hWndParent, , 0, 0, 800, 600
;centre window
;WinGetPos,,, Width, Height, % "ahk_id " hWndParent
;WinMove, % "ahk_id " hWndParent,, (A_ScreenWidth/2)-(Width/2), (A_ScreenHeight/2)-(Height/2)
} else if (uiMsg == 0x004E) {
if (NumGet(lParam+0, A_PtrSize * 2, "UInt") == 4294966690) { ; CDN_FILEOK
Gui submit
}
} else if (uiMsg == 0x0002) { ; WM_DESTROY
Gui Destroy
}
return 0
}
;==================================================
JEE_ControlGetPosClient(hWnd, hCtl, ByRef vPosX, ByRef vPosY, ByRef vPosW, ByRef vPosH)
{
VarSetCapacity(RECT, 16, 0)
DllCall("GetWindowRect", Ptr,hCtl, Ptr,&RECT)
DllCall("MapWindowPoints", Ptr,0, Ptr,hWnd, Ptr,&RECT, UInt,2)
vPosX := NumGet(RECT, 0, "Int"), vPosY := NumGet(RECT, 4, "Int")
vPosW := NumGet(RECT, 8, "Int")-vPosX, vPosH := NumGet(RECT, 12, "Int")-vPosY
return
}
==================================================
Btw re. Notepad (XP version). I never use it, it's there in case my scripts that grab the current file path from Notepad's address space ever break, subsequent to a Windows Update. Windows 7 did actually update Notepad at least once, but my function still worked, fortunately.
Notepad (XP version) is good to have on a dongle, in case you use a non-English computer. Although perhaps the English version is actually tucked away on such systems. Notepad (Win 7 version) wouldn't copy to the dongle.
Sometimes when on other computers, I have copies of Notepad in folders with ahk files, for quick drag-and-drop for editing. I could use shortcuts instead, but somehow my instinct tells me 'go with the files'.
It's good to have at least one program, that I know uses the old-style dialog, for testing purposes. It's good for the 'Bush hid the facts' error as well.
I like Notepad2, it's nice to hear when people know about it. It uses a Scintilla control. I plan to write my own Notepad, which looks like Notepad, but uses a Scintilla control, and which adds in some of the features I've added to Notepad via AutoHotkey, like ctrl+d copy line above and whole word search.
The WordPad and Paint, XP versions, have advantages over the Windows 7 versions e.g. WordPad XP strips formatting, Paint XP has no Ribbon. Also it is handy to copy other things like the games, I think on Windows 7, some complicated install is needed which I still haven't done. What is Windows without Minesweeper? Also sometimes older software with standard controls is easier to improve / fix / customise / make functional with AutoHotkey.
==================================================
[EDIT:]
Btw I like this notation for dealing with the redundant parameter in for loops, it's the best approach I've seen so far, I hadn't found a choice of name I was yet happy with:
for _, filter in filters
Regarding this, for debugging/checking purposes, I'm now moving to a different approach:
Before:
A_PtrSize*(11 + (A_PtrSize == 4))
After:
(A_PtrSize=8?88:48)
(A_PtrSize=8 ? 88:48)
Although I did discuss the earlier approach here:
key dll issues: calls and structs - Page 2 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 73#p126973
My script tells me the now startlingly obvious fact that:
vSize := 8+10*A_PtrSize
- ways of seeing -