Jump to content

How to hide a form automatically when it is close to the edge of the screen


 Share

Recommended Posts

Hi,erverybody friends,I want to find an example, it is like this:

1, when the form is close to the edge of the screen, it will be automatically hidden immediately, leaving only one boundary or icon

2. When the mouse touches the above boundary or icon, the form can automatically display or return to its original state

3. When the mouse stays in the form area, it can carry out various form control operations

4. After the mouse moves out of the form area, the form can automatically pull over and hide again.

I used the keywords "form close to the boundary automatically hide", "form automatic pull over" and so on did not find.

please help

thanks in advance!

Link to comment
Share on other sites

#NoTrayIcon
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)
Opt('GUIOnEventMode', 1)

Local $hGui = GUICreate("", 180, 135, @DesktopWidth + 190, @DesktopHeight - 200, -1, $WS_EX_TOPMOST + $WS_EX_CLIENTEDGE + $WS_EX_TOOLWINDOW)

GUICtrlCreateGroup("", 5, 0, 168, 70)
Local $idCbox = GUICtrlCreateCombo("", 12, 16, 95, 20)
GUICtrlSetData($idCbox, "Blueberry|Cherry|Pistachio|Strawberry", "")
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUISetOnEvent(-3, "_Exit")
GUICtrlSetOnEvent($idCbox, "_GetComboSel")

GUISetState(@SW_SHOW)


AdlibRegister("_DoCycles", 250)
While 1
    Sleep(250)
WEnd
AdlibUnRegister("_DoCycles")

;------------------------------------------------------------------------------------------------------------
func _Exit()
    Exit
EndFunc
func _GetComboSel()
    msgbox(4096,"",GUICtrlRead($idCbox,0) & "is Selected!")
EndFunc
Func _DoCycles()
    _WinHide($hGui, 360, 1, 500)
    ;_WinAPI_SetWindowPos($hGui,$HWND_TOP, 0, 0, 0, 0, 3) ;WinSetOnTop($hGui, "", 1);,_WinAPI_BringWindowToTop($hGui)
EndFunc   ;==>_DoCycles

Func _WinHide($hWnd, $Gap, $Edg, $iDelay = 0)
    Local $Wp = WinGetPos($hWnd)
    Local $wL = $Wp[0]
    Local $wT = $Wp[1]
    Local $wW = $Wp[2]
    Local $wH = $Wp[3]
    Local $Mp = MouseGetPos()
    Local $mX = $Mp[0]
    Local $mY = $Mp[1]
    Local $iPos = _WindowToScreen($wL, $wT, $wW, $wH, $Gap)
    Switch $iPos
        Case 0 ;Near Left Edge
            If _MouseOnWindow($wL, $wT, $wW, $wH, $mX, $mY) Then
                WinMove($hWnd, "", 0, $wT)
            Else
                If $iDelay > 0 Then Sleep($iDelay)
                WinMove($hWnd, "", -$wW + $Edg, $wT)
            EndIf
        Case 1 ;Near Top Edge
            If _MouseOnWindow($wL, $wT, $wW, $wH, $mX, $mY) Then
                WinMove($hWnd, "", $wL, 0)
            Else
                If $iDelay > 0 Then Sleep($iDelay)
                WinMove($hWnd, "", $wL, -$wH + $Edg)
            EndIf
        Case 2 ;Near Right Edge
            If _MouseOnWindow($wL, $wT, $wW, $wH, $mX, $mY) Then
                WinMove($hWnd, "", @DesktopWidth - $wW, $wT)
            Else
                If $iDelay > 0 Then Sleep($iDelay)
                WinMove($hWnd, "", @DesktopWidth - $Edg, $wT)
            EndIf
        Case 3 ;Near Bottom Edge
            If _MouseOnWindow($wL, $wT, $wW, $wH, $mX, $mY) Then
                WinMove($hWnd, "", $wL, @DesktopHeight - $wH)
            Else
                If $iDelay > 0 Then Sleep($iDelay)
                WinMove($hWnd, "", $wL, @DesktopHeight - $Edg)
            EndIf
    EndSwitch
EndFunc   ;==>_WinHide

Func _MouseOnWindow($iwL, $iwT, $iwW, $iwH, $imX, $imY);the GUI Rect($iwL, $iwT, $iwW, $iwH);the mouse position($imX, $imY)
    Local $bInW
    If $imX >= $iwL And $imX <= $iwL + $iwW And $imY >= $iwT And $imY <= $iwT + $iwH Then
        $bInW = True
    Else
        $bInW = False
    EndIf
    Return $bInW
EndFunc   ;==>_MouseOnWindow
Func _WindowToScreen($iwL, $iwT, $iwW, $iwH, $iGap);the GUI Rect($iwL, $iwT, $iwW, $iwH);$iGap:the distance between GUI border with Screen edge
    Local $iRet
    Select
        Case $iwL <= $iGap
            $iRet = 0
        Case $iwT <= $iGap
            $iRet = 1
        Case $iwL >= (@DesktopWidth - $iGap - $iwW)
            $iRet = 2
        Case $iwT >= (@DesktopHeight - $iGap - $iwH)
            $iRet = 3
        Case Else
            $iRet = 4
    EndSelect
    Return $iRet
EndFunc   ;==>_WindowToScreen

 

Link to comment
Share on other sites

On 12/26/2019 at 9:11 PM, Nine said:

What have you tried so far ?

The code shown above.

feel It isn't good. There are two problems:

1. When the combo box options Expanded, the form is hidden, but the combo box is still in the same place.As shown in the picture below:

20191228000113.png.a3d75d58a209ad12c18cef251465da4d.png

2、when the form is Set-Top, it would affects the behavior of the internal controls of itself, such as the inability to expand the combo box options

Edited by Letraindusoir
Link to comment
Share on other sites

Link to comment
Share on other sites

17 hours ago, Nine said:

To solve 1 - add this when you hide the window 

ControlCommand ($hGui, "", $idCbox, "HideDropDown", "")

I cannot replicate 2, maybe I don't understand the issue...

thank Nine for providing the solution. 
1,

but there are still doubts about the first question. Previously I thought the control was attached to the form, the form was hidden, and the control was immediately hidden with the form.

but What is the cause of this phenomenon?

If simply solve the problem by sending commands to the control, it does not seem to solve the problem from the root.


2.

The second problem has been solved because the top-setting function is running in the loop body, which directly affects the control behavior in the form 

Link to comment
Share on other sites

Try this code:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#AutoIt3Wrapper_UseX64=y

Opt( "MustDeclareVars", 1 )

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>

Global $hGui, $hLeft, $hTop, $hRight, $hBottom, $idGuiNearEdge, $bGuiNearEdge = False

Example()

Func Example()
  ; Small window along the left desktop edge
  $hLeft = GUICreate( "", 24, 50, 0, -1, $WS_POPUP, $WS_EX_TOPMOST )
  Local $hLeftLbl = GUICtrlGetHandle( GUICtrlCreateLabel( "4", 0, 0, 24, 50, $SS_CENTER+$SS_CENTERIMAGE ) )
  GUICtrlSetFont( -1, 16, 400, 0, "Webdings" )
  Local $aLeftRgn[4][2] = [ [0, 0], [24, 10], [24, 40], [0, 50] ]
  Local $hRgn = _WinAPI_CreatePolygonRgn( $aLeftRgn )
  _WinAPI_SetWindowRgn( $hLeft, $hRgn, 0 )

  ; Small window along the top desktop edge
  $hTop = GUICreate( "", 50, 24, -1, 0, $WS_POPUP, $WS_EX_TOPMOST )
  Local $hTopLbl = GUICtrlGetHandle( GUICtrlCreateLabel( "6", 0, 0, 50, 24, $SS_CENTER+$SS_CENTERIMAGE ) )
  GUICtrlSetFont( -1, 16, 400, 0, "Webdings" )
  Local $aTopRgn[4][2] = [ [0, 0], [50, 0], [40, 24], [10, 24] ]
  $hRgn = _WinAPI_CreatePolygonRgn( $aTopRgn )
  _WinAPI_SetWindowRgn( $hTop, $hRgn, 0 )

  ; Small window along the right desktop edge
  $hRight = GUICreate( "", 24, 50, @DesktopWidth-24, -1, $WS_POPUP, $WS_EX_TOPMOST )
  Local $hRightLbl = GUICtrlGetHandle( GUICtrlCreateLabel( "3", 0, 0, 24, 50, $SS_CENTER+$SS_CENTERIMAGE ) )
  GUICtrlSetFont( -1, 16, 400, 0, "Webdings" )
  Local $aRightRgn[4][2] = [ [0, 10], [24, 0], [24, 50], [0, 40] ]
  $hRgn = _WinAPI_CreatePolygonRgn( $aRightRgn )
  _WinAPI_SetWindowRgn( $hRight, $hRgn, 0 )

  ; Small window along the bottom desktop edge
  $hBottom = GUICreate( "", 50, 24, -1, @DesktopHeight-24, $WS_POPUP, $WS_EX_TOPMOST )
  Local $hBottomLbl = GUICtrlGetHandle( GUICtrlCreateLabel( "5", 0, 0, 50, 24, $SS_CENTER+$SS_CENTERIMAGE ) )
  GUICtrlSetFont( -1, 16, 400, 0, "Webdings" )
  Local $aBottomRgn[4][2] = [ [10, 0], [40, 0], [50, 24], [0, 24] ]
  $hRgn = _WinAPI_CreatePolygonRgn( $aBottomRgn )
  _WinAPI_SetWindowRgn( $hBottom, $hRgn, 0 )

  ; Larger GUI window
  $hGui = GUICreate( "Tools", 500, 400 )
  $idGuiNearEdge = GUICtrlCreateDummy()
  GUIRegisterMsg( $WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED" )
  GUISetState( @SW_SHOW, $hGui )

  Local $iPos, $tPoint = DllStructCreate( $tagPOINT ), $hWin

  While 1
    Switch GUIGetMsg()
      Case $idGuiNearEdge
        ; GUI window detected near a desktop edge
        $iPos = GUICtrlRead( $idGuiNearEdge )
        GUIRegisterMsg( $WM_WINDOWPOSCHANGED, "" )
        While Sleep( 10 )
          ; Loop until the mouse hovers over one of the small edge windows on the desktop
          DllStructSetData( $tPoint, "x", MouseGetPos( 0 ) )
          DllStructSetData( $tPoint, "y", MouseGetPos( 1 ) )
          $hWin = _WinAPI_WindowFromPoint( $tPoint )
          If $hWin = $hTopLbl Or $hWin = $hLeftLbl Or $hWin = $hRightLbl Or $hWin = $hBottomLbl Then ExitLoop
        WEnd
        ; Mouse hovers over an edge window
        Switch $iPos
          Case 1 ; Left
            GUISetState( @SW_HIDE, $hLeft )
            WinMove( $hGui, "", 25, Default )
          Case 2 ; Top
            GUISetState( @SW_HIDE, $hTop )
            WinMove( $hGui, "", Default, 25 )
          Case 3 ; Right
            GUISetState( @SW_HIDE, $hRight )
            WinMove( $hGui, "", @DesktopWidth-25-WinGetPos( $hGui )[2], Default )
          Case 4 ; Bottom
            GUISetState( @SW_HIDE, $hBottom )
            WinMove( $hGui, "", Default, @DesktopHeight-25-WinGetPos( $hGui )[3] )
        EndSwitch
        GUIRegisterMsg( $WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED" )
        GUISetState( @SW_SHOW, $hGui )
        $bGuiNearEdge = False

      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  GUIDelete( $hGui )
EndFunc

; Observe the position of the GUI window
Func WM_WINDOWPOSCHANGED( $hWnd, $iMsg, $wParam, $lParam )
  Local $tWindowPos = DllStructCreate( "hwnd hWnd;hwnd InsertAfter;int X;int Y;int CX;int CY;int Flags", $lParam )
  Switch True
    Case DllStructGetData( $tWindowPos, "X" ) < 24
      ; GUI window close to left desktop edge
      If Not $bGuiNearEdge Then
        GUICtrlSendToDummy( $idGuiNearEdge, 1 )
        GUISetState( @SW_HIDE, $hGui )
        WinMove( $hLeft, "", Default, DllStructGetData( $tWindowPos, "Y" ) + DllStructGetData( $tWindowPos, "CY" ) / 2 )
        GUISetState( @SW_SHOW, $hLeft )
        $bGuiNearEdge = True
      EndIf
    Case DllStructGetData( $tWindowPos, "Y" ) < 24
      ; GUI window close to top desktop edge
      If Not $bGuiNearEdge Then
        GUICtrlSendToDummy( $idGuiNearEdge, 2 )
        GUISetState( @SW_HIDE, $hGui )
        WinMove( $hTop, "", DllStructGetData( $tWindowPos, "X" ) + DllStructGetData( $tWindowPos, "CX" ) / 2, Default )
        GUISetState( @SW_SHOW, $hTop )
        $bGuiNearEdge = True
      EndIf
    Case DllStructGetData( $tWindowPos, "X" ) + DllStructGetData( $tWindowPos, "CX" ) > @DesktopWidth-24
      ; GUI window close to right desktop edge
      If Not $bGuiNearEdge Then
        GUICtrlSendToDummy( $idGuiNearEdge, 3 )
        GUISetState( @SW_HIDE, $hGui )
        WinMove( $hRight, "", Default, DllStructGetData( $tWindowPos, "Y" ) + DllStructGetData( $tWindowPos, "CY" ) / 2 )
        GUISetState( @SW_SHOW, $hRight )
        $bGuiNearEdge = True
      EndIf
    Case DllStructGetData( $tWindowPos, "Y" ) + DllStructGetData( $tWindowPos, "CY" ) > @DesktopHeight-24
      ; GUI window close to bottom desktop edge
      If Not $bGuiNearEdge Then
        GUICtrlSendToDummy( $idGuiNearEdge, 4 )
        GUISetState( @SW_HIDE, $hGui )
        WinMove( $hBottom, "", DllStructGetData( $tWindowPos, "X" ) + DllStructGetData( $tWindowPos, "CX" ) / 2, Default )
        GUISetState( @SW_SHOW, $hBottom )
        $bGuiNearEdge = True
      EndIf
  EndSwitch
  #forceref $hWnd, $iMsg, $wParam
EndFunc

Points 3 and 4 are not coded. It shouldn't be that hard.

Edited by LarsJ
Link to comment
Share on other sites

On 12/30/2019 at 6:43 AM, LarsJ said:

Try this code:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#AutoIt3Wrapper_UseX64=y

Opt( "MustDeclareVars", 1 )

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>

Global $hGui, $hLeft, $hTop, $hRight, $hBottom, $idGuiNearEdge, $bGuiNearEdge = False

Example()

Func Example()
  ; Small window along the left desktop edge
  $hLeft = GUICreate( "", 24, 50, 0, -1, $WS_POPUP, $WS_EX_TOPMOST )
  Local $hLeftLbl = GUICtrlGetHandle( GUICtrlCreateLabel( "4", 0, 0, 24, 50, $SS_CENTER+$SS_CENTERIMAGE ) )
  GUICtrlSetFont( -1, 16, 400, 0, "Webdings" )
  Local $aLeftRgn[4][2] = [ [0, 0], [24, 10], [24, 40], [0, 50] ]
  Local $hRgn = _WinAPI_CreatePolygonRgn( $aLeftRgn )
  _WinAPI_SetWindowRgn( $hLeft, $hRgn, 0 )

  ; Small window along the top desktop edge
  $hTop = GUICreate( "", 50, 24, -1, 0, $WS_POPUP, $WS_EX_TOPMOST )
  Local $hTopLbl = GUICtrlGetHandle( GUICtrlCreateLabel( "6", 0, 0, 50, 24, $SS_CENTER+$SS_CENTERIMAGE ) )
  GUICtrlSetFont( -1, 16, 400, 0, "Webdings" )
  Local $aTopRgn[4][2] = [ [0, 0], [50, 0], [40, 24], [10, 24] ]
  $hRgn = _WinAPI_CreatePolygonRgn( $aTopRgn )
  _WinAPI_SetWindowRgn( $hTop, $hRgn, 0 )

  ; Small window along the right desktop edge
  $hRight = GUICreate( "", 24, 50, @DesktopWidth-24, -1, $WS_POPUP, $WS_EX_TOPMOST )
  Local $hRightLbl = GUICtrlGetHandle( GUICtrlCreateLabel( "3", 0, 0, 24, 50, $SS_CENTER+$SS_CENTERIMAGE ) )
  GUICtrlSetFont( -1, 16, 400, 0, "Webdings" )
  Local $aRightRgn[4][2] = [ [0, 10], [24, 0], [24, 50], [0, 40] ]
  $hRgn = _WinAPI_CreatePolygonRgn( $aRightRgn )
  _WinAPI_SetWindowRgn( $hRight, $hRgn, 0 )

  ; Small window along the bottom desktop edge
  $hBottom = GUICreate( "", 50, 24, -1, @DesktopHeight-24, $WS_POPUP, $WS_EX_TOPMOST )
  Local $hBottomLbl = GUICtrlGetHandle( GUICtrlCreateLabel( "5", 0, 0, 50, 24, $SS_CENTER+$SS_CENTERIMAGE ) )
  GUICtrlSetFont( -1, 16, 400, 0, "Webdings" )
  Local $aBottomRgn[4][2] = [ [10, 0], [40, 0], [50, 24], [0, 24] ]
  $hRgn = _WinAPI_CreatePolygonRgn( $aBottomRgn )
  _WinAPI_SetWindowRgn( $hBottom, $hRgn, 0 )

  ; Larger GUI window
  $hGui = GUICreate( "Tools", 500, 400 )
  $idGuiNearEdge = GUICtrlCreateDummy()
  GUIRegisterMsg( $WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED" )
  GUISetState( @SW_SHOW, $hGui )

  Local $iPos, $tPoint = DllStructCreate( $tagPOINT ), $hWin

  While 1
    Switch GUIGetMsg()
      Case $idGuiNearEdge
        ; GUI window detected near a desktop edge
        $iPos = GUICtrlRead( $idGuiNearEdge )
        GUIRegisterMsg( $WM_WINDOWPOSCHANGED, "" )
        While Sleep( 10 )
          ; Loop until the mouse hovers over one of the small edge windows on the desktop
          DllStructSetData( $tPoint, "x", MouseGetPos( 0 ) )
          DllStructSetData( $tPoint, "y", MouseGetPos( 1 ) )
          $hWin = _WinAPI_WindowFromPoint( $tPoint )
          If $hWin = $hTopLbl Or $hWin = $hLeftLbl Or $hWin = $hRightLbl Or $hWin = $hBottomLbl Then ExitLoop
        WEnd
        ; Mouse hovers over an edge window
        Switch $iPos
          Case 1 ; Left
            GUISetState( @SW_HIDE, $hLeft )
            WinMove( $hGui, "", 25, Default )
          Case 2 ; Top
            GUISetState( @SW_HIDE, $hTop )
            WinMove( $hGui, "", Default, 25 )
          Case 3 ; Right
            GUISetState( @SW_HIDE, $hRight )
            WinMove( $hGui, "", @DesktopWidth-25-WinGetPos( $hGui )[2], Default )
          Case 4 ; Bottom
            GUISetState( @SW_HIDE, $hBottom )
            WinMove( $hGui, "", Default, @DesktopHeight-25-WinGetPos( $hGui )[3] )
        EndSwitch
        GUIRegisterMsg( $WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED" )
        GUISetState( @SW_SHOW, $hGui )
        $bGuiNearEdge = False

      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  GUIDelete( $hGui )
EndFunc

; Observe the position of the GUI window
Func WM_WINDOWPOSCHANGED( $hWnd, $iMsg, $wParam, $lParam )
  Local $tWindowPos = DllStructCreate( "hwnd hWnd;hwnd InsertAfter;int X;int Y;int CX;int CY;int Flags", $lParam )
  Switch True
    Case DllStructGetData( $tWindowPos, "X" ) < 24
      ; GUI window close to left desktop edge
      If Not $bGuiNearEdge Then
        GUICtrlSendToDummy( $idGuiNearEdge, 1 )
        GUISetState( @SW_HIDE, $hGui )
        WinMove( $hLeft, "", Default, DllStructGetData( $tWindowPos, "Y" ) + DllStructGetData( $tWindowPos, "CY" ) / 2 )
        GUISetState( @SW_SHOW, $hLeft )
        $bGuiNearEdge = True
      EndIf
    Case DllStructGetData( $tWindowPos, "Y" ) < 24
      ; GUI window close to top desktop edge
      If Not $bGuiNearEdge Then
        GUICtrlSendToDummy( $idGuiNearEdge, 2 )
        GUISetState( @SW_HIDE, $hGui )
        WinMove( $hTop, "", DllStructGetData( $tWindowPos, "X" ) + DllStructGetData( $tWindowPos, "CX" ) / 2, Default )
        GUISetState( @SW_SHOW, $hTop )
        $bGuiNearEdge = True
      EndIf
    Case DllStructGetData( $tWindowPos, "X" ) + DllStructGetData( $tWindowPos, "CX" ) > @DesktopWidth-24
      ; GUI window close to right desktop edge
      If Not $bGuiNearEdge Then
        GUICtrlSendToDummy( $idGuiNearEdge, 3 )
        GUISetState( @SW_HIDE, $hGui )
        WinMove( $hRight, "", Default, DllStructGetData( $tWindowPos, "Y" ) + DllStructGetData( $tWindowPos, "CY" ) / 2 )
        GUISetState( @SW_SHOW, $hRight )
        $bGuiNearEdge = True
      EndIf
    Case DllStructGetData( $tWindowPos, "Y" ) + DllStructGetData( $tWindowPos, "CY" ) > @DesktopHeight-24
      ; GUI window close to bottom desktop edge
      If Not $bGuiNearEdge Then
        GUICtrlSendToDummy( $idGuiNearEdge, 4 )
        GUISetState( @SW_HIDE, $hGui )
        WinMove( $hBottom, "", DllStructGetData( $tWindowPos, "X" ) + DllStructGetData( $tWindowPos, "CX" ) / 2, Default )
        GUISetState( @SW_SHOW, $hBottom )
        $bGuiNearEdge = True
      EndIf
  EndSwitch
  #forceref $hWnd, $iMsg, $wParam
EndFunc

Points 3 and 4 are not coded. It shouldn't be that hard.

thanks Larsj for your help!

Your code extends the hidden edge function, but seems to be able to run only once, not successfully repeating the contraction and expanding the Form.

Link to comment
Share on other sites

Since I've only implemented points 1 and 2, always move the window near an edge to hide it and hover your mouse over the small edge window to show it. As you can see in the code. Tested on Windows 7/10 64 bit.

Link to comment
Share on other sites

On 12/31/2019 at 9:57 PM, LarsJ said:

Since I've only implemented points 1 and 2, always move the window near an edge to hide it and hover your mouse over the small edge window to show it. As you can see in the code. Tested on Windows 7/10 64 bit.

Oh, I got it:points 1 and 2,is Required to Place in circulatory-body ,then it  can Hide-display repeatedly

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