Jump to content

Recommended Posts

I stumpled upon this thread while searching for a way to adjust parts of the FileOpenDialog.

My issue is, that I am using the "hwnd" of the FileOpenDialog and I am not receiving the $HSHELL_WINDOWCREATED event; instead I receive an event with the number 16 which I am not able to identify according to the Microsoft documentation and I cannot identify the meaning of the wParam in that case (e.g. to make sure I am adjusting the right window).
 

#include <GUIConstantsEx.au3>
#include <WinAPIEx.au3>
Global Const $sMessage = "Hold down Ctrl or Shift to choose multiple files." ;Must be global to allow compare
Global $hGUI

Example()

Func Example()
    $hGUI = GUICreate('An(other) example by guinness - 2013', Default, Default) ; Create a GUI.
    $iBtn1 = GUICtrlCreateButton("Select file with parent GUI", 5, 5, 250, 25)
    $iBtn2 = GUICtrlCreateButton("Select file without parent GUI", 5, 35, 250, 25)
    GUISetState(@SW_SHOW, $hGUI)

    GUIRegisterMsg(_WinAPI_RegisterWindowMessage('SHELLHOOK'), 'WM_SHELLHOOK') ; Define a window message and assign to the WM_SHELLHOOK function.
    _WinAPI_RegisterShellHookWindow($hGUI) ; Register the shell hook message to our GUI.

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $iBtn1
                ; Button will NOT be renamed
                _ShowDialog($hGUI)
            Case $iBtn2
                ; Button will be renamed
                _ShowDialog("")
        EndSwitch
    WEnd

    _WinAPI_DeregisterShellHookWindow($hGUI)
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func WM_SHELLHOOK($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg
    Local $sTitle = ""
    Switch $wParam

        Case $HSHELL_WINDOWCREATED
            $sTitle = WinGetTitle($lParam)
            If WinGetProcess($lParam) = @AutoItPID And $sTitle = $sMessage Then
                ControlSetText($sTitle, "", "Button1", "Button 1")
                ControlSetText($sTitle, "", "Button2", "Button 2")
            EndIf
    EndSwitch
EndFunc   ;==>WM_SHELLHOOK

Func _ShowDialog($p_hGui)
    Local $sFileOpenDialog = FileOpenDialog($sMessage, @WindowsDir & "\", "Images (*.jpg;*.bmp)|Videos (*.avi;*.mpg)", $FD_FILEMUSTEXIST + $FD_MULTISELECT, "", $p_hGui)
EndFunc   ;==>_ShowDialog

Is there anyway to achieve the same behavoiur (parent GUI disabled) without using the parameter within the function?

Edited by HurleyShanabarger
Link to post
Share on other sites

another function:

#include <GUIConstantsEx.au3>
#include <WinAPIEx.au3>
#include <WinAPISysWin.au3>
Global Const $sMessage = "Hold down Ctrl or Shift to choose multiple files." ;Must be global to allow compare
Global $hGUI
Global $sFileOpenDialog
Local $hTimerProc = DllCallbackRegister('_detectwindow', 'none', 'hwnd;uint;uint_ptr;dword')
Global $g_iCount = 0
Local $iTimerID = _WinAPI_SetTimer(0, 0, 1000, DllCallbackGetPtr($hTimerProc))
Example()
Func Example()
    $hGUI = GUICreate('An(other) example by guinness - 2013', Default, Default) ; Create a GUI.
    $iBtn1 = GUICtrlCreateButton("Select file with parent GUI", 5, 5, 250, 25)
    $iBtn2 = GUICtrlCreateButton("Select file without parent GUI", 5, 35, 250, 25)
    GUISetState(@SW_SHOW, $hGUI)

    GUIRegisterMsg(_WinAPI_RegisterWindowMessage('SHELLHOOK'), 'WM_SHELLHOOK') ; Define a window message and assign to the WM_SHELLHOOK function.
    _WinAPI_RegisterShellHookWindow($hGUI) ; Register the shell hook message to our GUI.

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $iBtn1
                ; Button will NOT be renamed
              _ShowDialog($hGUI)
            Case $iBtn2
                ; Button will be renamed

                 _ShowDialog("")
              EndSwitch

    WEnd

    _WinAPI_DeregisterShellHookWindow($hGUI)
    GUIDelete($hGUI)
EndFunc   ;==>Example
 Func _detectwindow($hWnd, $iMsg, $iTimerID, $iTime)
       ToolTip(DetectWindow())
EndFunc   ;==>_TimerProc


Func DetectWindow()
      $aListe = WinList();
               For $iae = 1 To $aListe[0][0] Step 1
                      If $aListe[$iae][0] <> "" And BitAND(WinGetState($aListe[$iae][1]), 2) Then
                         if $aListe[$iae][0] = $sMessage Then
                            Return $aListe[$iae][0] &@CRLF&"handle:"&WinGetHandle($aListe[$iae][0])
                            EndIf
                    EndIf
                 Next
EndFunc
Func _ShowDialog($p_hGui)
    Local $sFileOpenDialog = FileOpenDialog($sMessage, @WindowsDir & "\", "Images (*.jpg;*.bmp)|Videos (*.avi;*.mpg)", $FD_FILEMUSTEXIST + $FD_MULTISELECT, "")
    Return $sFileOpenDialog
EndFunc   ;==>_ShowDialog

 

Link to post
Share on other sites

@HurleyShanabarger  I tested your code both on Win7 and Win10 and it is working fine for me.  The event $HSHELL_WINDOWCREATED is sent correctly and the 2 buttons are changed as expected.  So I am not sure what your issue is...

Link to post
Share on other sites

I see.  Got confused with the number 16, which was not appearing to me.  Ok, now I understand your issue.   As stated in the documentation of the hook you were using it only appears on "A top-level, unowned window has been created."

One solution is to use another hook more appropriate with child windows.  Here an example based on your code :

#include <GUIConstants.au3>
#include <WinAPI.au3>

Opt("MustDeclareVars", 1)

Example()

Func Example()
  Local $hGui = GUICreate("Test", 300, 200, -1, 300)
  Local $idBut = GUICtrlCreateButton("Show", 100, 100, 80, 20)

  Local $hStub_MyProc = DllCallbackRegister(_MyProc, "LRESULT", "int;wparam;lparam")
  Global $hHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hStub_MyProc), 0, _WinAPI_GetCurrentThreadId())
  GUISetState()

  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
      Case $idBut
        FileOpenDialog("Title", @ScriptDir, "All (*.*)", $FD_FILEMUSTEXIST, "", $hGui)
    EndSwitch
  WEnd

  GUIDelete($hGui)
  _WinAPI_UnhookWindowsHookEx($hHook)
  DllCallbackFree($hStub_MyProc)
EndFunc   ;==>Example

Func _MyProc($nCode, $wParam, $lParam)
  Local $hWnd
  If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
  If $nCode = 5 Then ; HCBT_ACTIVATE
    ConsoleWrite($nCode & "/" & Hex($wParam) & "/" & $lParam & @CRLF)
    $hWnd = WinGetHandle("Title")
    If $hWnd Then
      ControlSetText($hWnd, "", "Button1", "Button 1")
      ControlSetText($hWnd, "", "Button2", "Button 2")
    EndIf
  EndIf
  Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>_MyProc

 

Link to post
Share on other sites
1 hour ago, HurleyShanabarger said:

Goal was to select the default filter type, instead of all the hook-magic it can be done much simpler using _WinAPI_OpenFileDlg; hope this is helpfule for other

No problem.  It was fun to find an alternative to the hook you were using :)

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...