Jump to content

Recommended Posts

Posted (edited)

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
Posted

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

 

none

Posted
Posted

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

 

Posted

I guess I should have stated, what I want to achieve in the first place instead of describing the issue I am having along the way. I should have known better.

 

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!

Posted
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 :)

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
×
×
  • Create New...