Jump to content

how get user click in show desktop, using WM_NOTIFY?


Recommended Posts

Here an example without WM_NOTIFY:

#include <Array.au3>
#include <Misc.au3>

If @OSVersion <> "WIN_7" Then Exit MsgBox(16, "Error", "Code is running only on Win7", 15)

Global $hWnd, $aPos, $aControls, $pos, $x1, $y1, $x2, $y2, $dll
$hWnd = WinGetHandle("[CLASS:Shell_TrayWnd]")
$aPos = WinGetPos($hWnd)
$aControls = _WinGetControls($hWnd)
$pos = _ArraySearch($aControls, "TrayShowDesktopButtonWClass", 0, 0, 0, 0, 1, 1)
$aCtrlPos = ControlGetPos($hWnd, "", $aControls[$pos][3])

$x1 = $aCtrlPos[0]
$y1 = $aPos[1]
$x2 = $aCtrlPos[0] + $aCtrlPos[2]
$y2 = $aPos[2]

HotKeySet("{ESC}", "_Exit")
$dll = DllOpen("user32.dll")

While Sleep(50)
    If _IsPressed("01", $dll) Then
        $aM = MouseGetPos()
        If $aM[0] > $x1 And $aM[0] < $x2 And $aM[1] > $y1 And $aM[1] < $y2 Then MsgBox(0, "Test", "Tray Show Desktop Button was clicked!")
    EndIf
WEnd

Func _Exit()
    DllClose($dll)
    Exit
EndFunc

; #DEMOFUNCTION# ================================================================================================================
; Name...........:  _WinGetControls
; Description ...:  Liefert ein 2D-Array für die Controls eines Fensters.
;                   Das Array enhält für jedes Control die folgenden Informationen:
;                   |[0] HWND    - HWND des Controls
;                   |[1] Class   - Klasse des Controls
;                   |[2] NN      - ClassNN des Controls
;                   |[3] ID      - ID des Controls
;                   |[4] Visible - Sichtbar? 1 = ja, 0 = nein
;                   Das Feld Array[0][0] enthält die Anzahl der Controls.
; Syntax.........:  _WinGetControls($hWnd)
; Parameters ....:  $hWnd   - HWND des Fensters (z.B. Rückgabewert von GUICreate)
; Return values .:  Erfolg: Controlarray
;                   Fehler: False, @error = 1
; Author ........:  Großvater (www.autoit.de)
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _WinGetControls($hWnd)
    Local $hCB
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, False)
    __WinGetControlsAddControl("Init", 0)
    $hCB = DLLCallbackRegister("__WinGetControlsAddControl", "Int", "HWND;LPARAM")
    DllCall("User32.dll", "Int", "EnumChildWindows", "HWND", $hWnd, "Ptr", DllCallbackGetPtr($hCB), "LPARAM", $hWnd)
    If @error Then Return SetError(DllCallbackFree($hCB), 0, False)
    DllCallbackFree($hCB)
    Return __WinGetControlsAddControl("Result", 0)
EndFunc

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........:  __WinGetControlsAddControl
; Description ...:  Callback-Funktion für DLLCall "EnumChildWindows" in _WinGetControls
; Remarks .......:  Weil ich globale Variable für die Rückgabe von Funktionswerten nicht mag und die Implementierung
;                   der statischen Arrays recht rudimentär ist, sind die maximale Anzahl von Controls auf 1024
;                   und die maximale Anzahl von Klassen auf 256 begrenzt.
; ===============================================================================================================================
Func __WinGetControlsAddControl($hWnd, $lParam)
    Local Static $UControls = 1024
    Local Static $UClasses = 256
    Local Static $aControls[$UControls + 1][5]
    Local Static $aClasses[$UClasses + 1][2]
    Local $aResult, $C, $Class, $ClassExist, $ID, $NN
    Switch $hWnd
        Case "Init"
            $aControls[0][0] = 0
            $aClasses[0][0] = 0
            Return
        Case "Result"
            $C = $aControls[0][0] + 1
            $aResult = $aControls
            Redim $aResult[$C][5]
            Return $aResult
    EndSwitch
    $aResult = DllCall("User32.dll", "Int", "GetClassNameW", "HWND", $hWnd, "WStr", "", "Int", 260)
    If @error Or $aResult[0] = 0 Then Return True
    $Class = $aResult[2]
    $aResult = DllCall("User32.dll", "Int", "GetDlgCtrlID", "HWND", $hWnd)
    If @error Or $aResult[0] = 0 Then Return True
    $ID = $aResult[0]
    $ClassExist = False
    $C = $aClasses[0][0]
    For $I = 1 To $C
        If $aClasses[$I][0] = $Class Then
            $NN = $aClasses[$I][1] + 1
            $aClasses[$I][1] = $NN
            $ClassExist = True
            ExitLoop
        EndIf
    Next
    If Not $ClassExist Then
        $NN = 1
        $C += 1
        If $C > $UClasses Then Return False
        $aClasses[0][0] = $C
        $aClasses[$C][0] = $Class
        $aClasses[$C][1] = $NN
    EndIf
    $C = $aControls[0][0] + 1
    If $C > $UControls Then Return False
    $aControls[0][0]  = $C
    $aControls[$C][0] = $hWnd
    $aControls[$C][1] = $Class
    $aControls[$C][2] = $NN
    $aControls[$C][3] = $ID
    $aControls[$C][4] = ControlCommand(HWnd($lParam), "", $ID, "IsVisible", "")
    Return True
EndFunc
; ===============================================================================================================================

Thanks to Großvater for the _WinGetControls() function.

Or this variant:

#include <Array.au3>
#include <Misc.au3>
#include <WinAPI.au3>

If @OSVersion <> "WIN_7" Then Exit MsgBox(16, "Error", "Code is running only on Win7", 15)

Global $__Data, $i, $ID, $x1, $x2, $y1, $y2

Global Const $dll = DllOpen("user32.dll")
Global Const $hWnd = WinGetHandle("[CLASS:Shell_TrayWnd]")
Global $aPos = WinGetPos($hWnd)

Global $aData = _WinAPI_EnumChildWindows($hWnd)
For $i = 1 To UBound($aData) - 1
    If $aData[$i][1] =  "TrayShowDesktopButtonWClass" Then
        $aResult = DllCall($dll, "Int", "GetDlgCtrlID", "HWND", $aData[$i][0])
        $ID = $aResult[0]
        ExitLoop
    EndIf
Next
$aCtrlPos = ControlGetPos($hWnd, "", $ID)

$x1 = $aCtrlPos[0]
$y1 = $aPos[1]
$x2 = $aCtrlPos[0] + $aCtrlPos[2]
$y2 = $aPos[2]

HotKeySet("{ESC}", "_Exit")

While Sleep(100)
    If _IsPressed("01", $dll) Then
        $aM = MouseGetPos()
        If $aM[0] > $x1 And $aM[0] < $x2 And $aM[1] > $y1 And $aM[1] < $y2 Then MsgBox(0, "Test", "Tray Show Desktop Button was clicked!")
    EndIf
WEnd

Func _Exit()
    DllClose($dll)
    Exit
EndFunc

Func _WinAPI_EnumChildWindows($hWnd, $fVisible = 1)
    If Not _WinAPI_GetWindow($hWnd, 5) Then SetError(1, 0, 0)
    Local $hEnumProc = DllCallbackRegister('__EnumWindowsProc','int','hwnd;lparam')
    Local $Error = 1

    Dim $__Data[101][2] = [[0]]
    DllCall('user32.dll', 'int', 'EnumChildWindows', 'hwnd', $hWnd, 'ptr', DllCallbackGetPtr($hEnumProc), 'lparam', $fVisible)
    If @error Then
        $__Data = 0
    Else
        $Error = 0
        If $__Data[0][0] Then
            ReDim $__Data[$__Data[0][0] + 1][2]
        Else
            $__Data = 0
        EndIf
    EndIf
    DllCallbackFree($hEnumProc)
    Return SetError($Error, 0, $__Data)
EndFunc   ;==>_WinAPI_EnumChildWindows

Func __EnumWindowsProc($hWnd, $fVisible)
    If ($fVisible) And (Not _WinAPI_IsWindowVisible($hWnd)) Then Return 1
    $__Data[0][0] += 1
    If $__Data[0][0] > UBound($__Data) - 1 Then
        ReDim $__Data[$__Data[0][0] + 100][2]
    EndIf
    $__Data[$__Data[0][0]][0] = $hWnd
    $__Data[$__Data[0][0]][1] = _WinAPI_GetClassName($hWnd)
    Return 1
EndFunc   ;==>__EnumWindowsProc

Thanks to Yashied for the WinAPIEx.au3.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...