Jump to content

Centered FileOpenDialog() using ShellProc hook


Recommended Posts

Hiho Forum,

different approach, same result as with

Hopefully useful for someone 😉.

Global $__a_Global_SHEx[3]
; $__a_Global_SHEx[0] = SHELLHOOK registered
; $__a_Global_SHEx[1] = hWnd for Hook
; $__a_Global_SHEx[2] = Dialog title
_SHEx_RegisterWindowMessage_Init()

Local $s_Selected_File = _FileOpenDialog_Wrapper("Select File", @ScriptDir, "All (*.*)", 1 + 2 + 4)
If Not @error Then MsgBox(0, "", $s_Selected_File)

Func _FileOpenDialog_Wrapper($sTitle, $sInitDir, $sFilter, $iOptions = 0, $sDefaultName = "", $hWnd = 0)
    ; https://groups.google.com/forum/?hl=en&fromgroups=#!topic/microsoft.public.vc.mfc/HafQr4gIRY0
    ; The problem is that GetOpenFileName changes the current directory to the last browsed one. The current directory and any of its parents cannot be deleted.

    If Not $sInitDir Then $sInitDir = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" ; CLSID for "My Computer"

    Local $sWorkingDir = @WorkingDir

    $__a_Global_SHEx[2] = $sTitle

    _SHEx_ShellHookWindow($__a_Global_SHEx[1], 1) ; activate hook

    Local $sFilename = FileOpenDialog($sTitle, $sInitDir, $sFilter, $iOptions, $sDefaultName, $hWnd)
    Local $iError = @error

    _SHEx_ShellHookWindow($__a_Global_SHEx[1], 0) ; de-activate hook

    FileChangeDir($sWorkingDir)

    If Not $iError Then
        If StringInStr($sFilename, "|", 2) Then ; multiple selection
            Local $aFilename = StringSplit($sFilename, "|")
        Else
            Local $sPath = StringTrimRight($sFilename, StringLen($sFilename) - StringInStr($sFilename, "\", 2, -1))
        EndIf
    EndIf

    Return SetError($iError, 0, $sFilename)
EndFunc   ;==>_FileOpenDialog_Wrapper

Func _SHEx_RegisterWindowMessage_Init()
    $__a_Global_SHEx[0] = GUIRegisterMsg(_SHEx_RegisterWindowMessage("SHELLHOOK"), "_SHEx_HShellWndProc")
    Local $old_GUISwitch = GUISwitch(0)
    $__a_Global_SHEx[1] = GUICreate("SHELLHOOK GUI - " & @ScriptName)
    GUISwitch($old_GUISwitch)
EndFunc   ;==>_SHEx_RegisterWindowMessage_Init

Func _SHEx_RegisterWindowMessage($sText)
    Local $aRet = DllCall('user32.dll', 'int', 'RegisterWindowMessage', 'str', $sText)
    Return $aRet[0]
EndFunc   ;==>_SHEx_RegisterWindowMessage

Func _SHEx_ShellHookWindow($hWnd, $bFlag)
    Local $sFunc = 'DeregisterShellHookWindow'
    If $bFlag Then $sFunc = 'RegisterShellHookWindow'
    Local $aRet = DllCall('user32.dll', 'int', $sFunc, 'hwnd', $hWnd)
    ; ConsoleWrite("_SHEx_ShellHookWindow: " & $aRet[0] & @crlf)
    Return $aRet[0]
EndFunc   ;==>_SHEx_ShellHookWindow

Func _SHEx_HShellWndProc($hWnd, $Msg, $wParam, $lParam)
    ; ShellProc callback function
    ; https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644991(v=vs.85)
    ConsoleWrite($hWnd & @TAB & $Msg & @TAB & $wParam & @TAB & $lParam & @CRLF)
    If $wParam = 1 Then ; 1 = $HSHELL_WINDOWCREATED
        If $lParam = WinGetHandle("[TITLE:" & $__a_Global_SHEx[2] & ";CLASS:#32770]", "") Then
            ConsoleWrite("WinMove= " & WinMove($lParam, "", (@DesktopWidth - (@DesktopWidth / 4 * 3)) / 2, (@DesktopHeight - (@DesktopHeight / 4 * 3)) / 2, @DesktopWidth / 4 * 3, @DesktopHeight / 4 * 3) & @CRLF)
        EndIf
    EndIf
    ; https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644991(v=vs.85)
    Return 0 ; The return value should be zero unless the value of nCode is HSHELL_APPCOMMAND and the shell procedure handles the WM_COMMAND message. In this case, the return should be nonzero.
EndFunc   ;==>_SHEx_HShellWndProc

 

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...