Page 1 sur 1

[..] Déplacer un GUI sur une fenêtre Windows pour récupérer son Handle

Posté : ven. 30 nov. 2018 13:39
par franco
Coucou

Comme le titre l'indique, je souhaiterais déplacer une GUI (interface minimaliste avec image avec fond transparent) sur une fenpetre windows, afin de récupérer son handle...

Comme le fait au3info (^^) mais en plus simple.


J'ai donc crée mon interface, avec une image avec fond transparent PNG...
Je me suis aidée de ce topic d'ailleurs : https://www.autoitscript.com/forum/topi ... nt-1311891

EN résumé, j'ai récupéré un "curseur", que j'ai mis dans l'interface.
Et je souhaite donc déplacer cette interface (donc le "curseur") sur la dite fenêtre...


Bien entendu, comme à mon habitude, la fin coince ;)


Comment faire pour qu'il capte la bonne fenêtre ?

Voici le code :




#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>



_GDIPlus_Startup()
Global Const $SC_DRAGMOVE = 0xF012
Global $iW, $iH, $hImage, $hBitmap, $hGUI
$hImage = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\viseur\viseur (14).png")
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)


Global $hGUI = GUICreate("Form1", 32,32, 192, 124, $WS_POPUP, $WS_EX_LAYERED+$WS_EX_TOPMOST)


GUIRegisterMsg($WM_LBUTTONDBLCLK, "_WM_LBUTTONDBLCLK")
 GUISetState(@SW_SHOW)
_WinAPI_BitmapDisplayTransparentInGUI($hBitmap, $hGUI)
GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")


While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit

 EndSwitch


WEnd


Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc   ;==>_WM_LBUTTONDOWN

Func _WM_LBUTTONDBLCLK($hWnd, $iMsg, $iwParam, $ilParam)
    Local $iX = BitAND($ilParam, 0xFFFF), $iY = BitShift($ilParam, 16)

;~     $fDblClk = True
    ConsoleWrite("!Double click on: [" & $iX & "," & $iY & "]" & @CRLF)
        MouseClick("left")
    Return $GUI_RUNDEFMSG
EndFunc
Oui, le mouseclik est erroné, mais c'est surement une piste ^^



Disons que, si j'arrive à rendre la fenêtre "active", je pourrais aisément récupérer son handle.


++ et merci d'avance pour vos réponses. :)

Re: [..] Déplacer un GUI sur une fenêtre Windows pour récupérer son Handle

Posté : ven. 30 nov. 2018 16:01
par walkson
Bonjour,
Si ça peut vous aider, il y a viewtopic.php?f=6&t=4276&p=26006&hilit=au3info#p26006
Il faudra rajouter #include <WinAPISysWin.au3> à cause de 2 variables non reconnues

Re: [..] Déplacer un GUI sur une fenêtre Windows pour récupérer son Handle

Posté : sam. 01 déc. 2018 13:50
par franco
Salut.

J'ai testé le script que tu as donné, mais il y a comme un bug : si je glisse dépose l'icone sur une fenetre quelconque, j'obtiens bien les informations.
Mais si je réitère l'opération, ça reste figé : les informations ne changent plus.

De plus, j'ai essayé de modifier mon script avec.... En vain XD :mrgreen:


Ce que je pensais faire - mais que je sais pas faire (:/) - :
- Je glisse dépose l'image (gui) sur la bordure de la fenêtre en question
- je double clique et je détecte le positionnement de l'image - le curseur sur la fenêtre (la bordure par exemple).
- Et je simule ainsi un clic gauche pour sélectionner la dite fenêtre.

De là, rien de plus simple pour récupérer l'handle de la fenêtre active.


Je vais tenter d'approfondir la chose.


Encore merci pour ta réponse.

Re: [..] Déplacer un GUI sur une fenêtre Windows pour récupérer son Handle

Posté : sam. 01 déc. 2018 19:13
par walkson
Voilà un code "minimaliste" :mrgreen:
ça manque un peu de souplesse mais ça marche.

Code : Tout sélectionner

#include <WinAPISysWin.au3>
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Global Const $SC_DRAGMOVE = 0xF012
HotKeySet("!x","Sortie");alt x
Global $Form = GUICreate("", 50, 50,  @DesktopWidth - 50, @DesktopHeight/2 - 50,$WS_POPUP,$WS_EX_LAYERED)
GUISetBkColor(0xABCDEF)
_WinAPI_SetLayeredWindowAttributes($Form,0xABCDEF)
GUISetState(@SW_SHOW)

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($Form)
$hBrush = _GDIPlus_BrushCreateSolid(0xFFff0000)
_GDIPlus_GraphicsFillEllipse ( $hGraphic, 12.5, 12.5, 25, 25, $hBrush )
_GDIPlus_BrushSetSolidColor ($hBrush, 0xFF0000FF)
_GDIPlus_GraphicsFillEllipse ( $hGraphic, 20, 20, 10, 10, $hBrush )
$hPen = _GDIPlus_PenCreate(0xFF0000FF, 2)
_GDIPlus_GraphicsDrawRect ($hGraphic,0,0,50,50, $hPen)
_GDIPlus_PenSetColor($hPen,0xFF00FF00)
_GDIPlus_GraphicsDrawRect ($hGraphic,5,5,40,40, $hPen)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

GUIRegisterMsg ( $WM_MOVE, "_WM_MOVE" )
While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
	 Case $GUI_EVENT_PRIMARYDOWN
			ToolTip("")
             _SendMessage($Form, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)

	 Case $GUI_EVENT_PRIMARYUP
		 $pos = WinGetPos($Form)
		 If $pos[0] <> @DesktopWidth - 50 And $pos[1] <> @DesktopHeight/2 - 50 Then
			WinMove($Form, "", @DesktopWidth - 50, @DesktopHeight/2 - 50)
		 EndIf
 EndSwitch

WEnd

Func Sortie()
	Exit
EndFunc
Func Cherche()
    $tMP = _WinAPI_GetMousePos()
    $hWnd = _WinAPI_WindowFromPoint($tMP)
	ToolTip($hWnd & " => " & WinGetTitle($hWnd) & @CRLF & WinGetClassList($hWnd), 50,@DesktopHeight/4,"Handle")
EndFunc
Func _WM_MOVE ( $hWnd, $Msg, $wParam, $lParam ) ;réajuste positions fenêtres enfants
    $sPos = WinGetPos($Form, "")
	If $sPos[0] = @DesktopWidth - 50 And $sPos[1] = @DesktopHeight/2 - 50 Then Cherche()
    Return $GUI_RUNDEFMSG
EndFunc
La fenêtre s'ouvre à droite de l'écran et pour la fermer Alt + x

Re: [..] Déplacer un GUI sur une fenêtre Windows pour récupérer son Handle

Posté : dim. 02 déc. 2018 11:43
par franco
Salut.

Et merci beaucoup :)
Ca m'a aidé pour la suite.

Voici ce que j'en ai fait :
#include <WinAPISysWin.au3>
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>


Opt("TrayMenuMode", 3)

Global Const $SC_DRAGMOVE = 0xF012

Global $Form = GUICreate("", 50, 50, @DesktopWidth - 50, @DesktopHeight / 2 - 50, -1, $WS_EX_LAYERED)
GUISetBkColor(0xABCDEF)
_WinAPI_SetLayeredWindowAttributes($Form, 0xABCDEF)

Local $idContextmenu = GUICtrlCreateContextMenu()
Local $ShowHide = GUICtrlCreateMenuItem("Afficher / Masquer", $idContextmenu)
GUICtrlCreateMenuItem("", $idContextmenu)
Local $Exit = GUICtrlCreateMenuItem("Quitter", $idContextmenu)

Local $ShowHide_tray = TrayCreateItem("Afficher / Masquer")
TrayCreateItem("")
local $SystrayEXIT = TrayCreateItem("Quitter")

GUISetState(@SW_SHOW)

_GDIPlus_Startup()
Global $hImage_ = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\viseur\viseur (14).png")
Global $hImage = _GDIPlus_ImageResize($hImage_, 50, 50)
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($Form)
_WinAPI_RedrawWindow($Form, 0, 0, $RDW_UPDATENOW)
_GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, 0)
_WinAPI_RedrawWindow($Form, 0, 0, $RDW_VALIDATE)
_GDIPlus_Shutdown()

GUIRegisterMsg($WM_MOVE, "_WM_MOVE")

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE, $Exit
                        Exit
                Case $ShowHide
                        $st_gui = WinGetState($Form)

                        If BitAND($st_gui, 16) Then
                                GUISetState(@SW_SHOWNORMAL, $Form)
                        Else
                                GUISetState(@SW_MINIMIZE, $Form)
                        EndIf
                       


                Case $GUI_EVENT_PRIMARYDOWN
                        ToolTip("")
                        _SendMessage($Form, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)

                Case $GUI_EVENT_PRIMARYUP
                        $pos = WinGetPos($Form)
                        If $pos[0] <> @DesktopWidth - 50 And $pos[1] <> @DesktopHeight / 2 - 50 Then
                                WinMove($Form, "", @DesktopWidth - 50, @DesktopHeight / 2 - 50)
                        EndIf
        EndSwitch

                Switch TrayGetMsg()
                Case $SystrayEXIT ; Exit the loop.
                        Exit
;~              Case $Action_Move
;~                      _MoveThisWindow()
                Case  $ShowHide_tray
                        $st_gui = WinGetState($Form)

                        If BitAND($st_gui, 16) Then
                                GUISetState(@SW_SHOWNORMAL, $Form)

                        Else
                                GUISetState(@SW_MINIMIZE, $Form)
                        EndIf





                EndSwitch





WEnd


Func Cherche()
        $tMP = _WinAPI_GetMousePos()
        $hWnd = _WinAPI_WindowFromPoint($tMP)
;~      ToolTip($hWnd & " => " & WinGetTitle($hWnd) & @CRLF & WinGetClassList($hWnd), 50, @DesktopHeight / 4, "Handle")

        WinActivate($hWnd)
        Send("#+{LEFT}")

EndFunc   ;==>Cherche
Func _WM_MOVE($hWnd, $Msg, $wParam, $lParam) ;réajuste positions fenêtres enfants
        $sPos = WinGetPos($Form, "")
        If $sPos[0] = @DesktopWidth - 50 And $sPos[1] = @DesktopHeight / 2 - 50 Then Cherche()
        Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MOVE
Un seul petit souci : le fait de réduire la fenêtre, puis la ré-afficher, et l'image disparait...

Et apparemment, il faut mettre un " _GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, 0) "


Mais cela ne fonctionne pas.


Que faut-il faire ?


Merci :D


++

Re: [..] Déplacer un GUI sur une fenêtre Windows pour récupérer son Handle

Posté : dim. 02 déc. 2018 13:31
par walkson
Bonjour,
Il faut clouer l'image sur la GUI :mrgreen:

Code : Tout sélectionner

#include <WinAPISysWin.au3>
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>


Opt("TrayMenuMode", 3)

Global Const $SC_DRAGMOVE = 0xF012

Global $Form = GUICreate("", 50, 50, @DesktopWidth - 50, @DesktopHeight / 2 - 50, -1, $WS_EX_LAYERED)
GUISetBkColor(0xABCDEF)
$pic = GUICtrlCreatePic("",0,0,50,50)
$Hpic = GUICtrlGetHandle($pic)
_WinAPI_SetLayeredWindowAttributes($Form, 0xABCDEF)

Local $idContextmenu = GUICtrlCreateContextMenu()
Local $ShowHide = GUICtrlCreateMenuItem("Afficher / Masquer", $idContextmenu)
GUICtrlCreateMenuItem("", $idContextmenu)
Local $Exit = GUICtrlCreateMenuItem("Quitter", $idContextmenu)

Local $ShowHide_tray = TrayCreateItem("Afficher / Masquer")
TrayCreateItem("")
local $SystrayEXIT = TrayCreateItem("Quitter")

GUISetState(@SW_SHOW)

_GDIPlus_Startup()
Global $hImage_ = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\viseur\viseur (14).png")
Global $hImage = _GDIPlus_ImageResize($hImage_, 50, 50)
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($Form)
;_WinAPI_RedrawWindow($Form, 0, 0, $RDW_UPDATENOW)
_GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, 0)
;_WinAPI_RedrawWindow($Form, 0, 0, $RDW_VALIDATE)
$hHbitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
_WinAPI_DeleteObject(_SendMessage($Hpic, 0x0172, 0, $hHbitmap))
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_Shutdown()

GUIRegisterMsg($WM_MOVE, "_WM_MOVE")

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE, $Exit
                        Exit
                Case $ShowHide
                        $st_gui = WinGetState($Form)

                        If BitAND($st_gui, 16) Then
                                GUISetState(@SW_SHOWNORMAL, $Form)
                        Else
                                GUISetState(@SW_MINIMIZE, $Form)
                        EndIf



                Case $GUI_EVENT_PRIMARYDOWN
                        ToolTip("")
                        _SendMessage($Form, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)

                Case $GUI_EVENT_PRIMARYUP
                        $pos = WinGetPos($Form)
                        If $pos[0] <> @DesktopWidth - 50 And $pos[1] <> @DesktopHeight / 2 - 50 Then
                                WinMove($Form, "", @DesktopWidth - 50, @DesktopHeight / 2 - 50)
                        EndIf
        EndSwitch

                Switch TrayGetMsg()
                Case $SystrayEXIT ; Exit the loop.
                        Exit
;~              Case $Action_Move
;~                      _MoveThisWindow()
                Case  $ShowHide_tray
                        $st_gui = WinGetState($Form)

                        If BitAND($st_gui, 16) Then
                                GUISetState(@SW_SHOWNORMAL, $Form)

                        Else
                                GUISetState(@SW_MINIMIZE, $Form)
                        EndIf





                EndSwitch





WEnd


Func Cherche()
        $tMP = _WinAPI_GetMousePos()
        $hWnd = _WinAPI_WindowFromPoint($tMP)
;~       ToolTip($hWnd & " => " & WinGetTitle($hWnd) & @CRLF & WinGetClassList($hWnd), 50, @DesktopHeight / 4, "Handle")

        WinActivate($hWnd)
        Send("#+{LEFT}")

EndFunc   ;==>Cherche
Func _WM_MOVE($hWnd, $Msg, $wParam, $lParam) ;réajuste positions fenêtres enfants
        $sPos = WinGetPos($Form, "")
        If $sPos[0] = @DesktopWidth - 50 And $sPos[1] = @DesktopHeight / 2 - 50 Then Cherche()
        Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MOVE