Jump to content

Drag Box UDF


martin
 Share

Recommended Posts

post-3602-1242131385_thumb.png

I couldn't see how to get these dots that are in some windows so I made this little udf.

Note that the udf registers messages $WM_LBUTTONDOWN and $WM_SIZE so if your script needs these you will have to call the registered functions yourself.

Example of use

#include <GUIConstantsEx.au3>
          #include <WindowsConstants.au3>
          #include "DragDots.au3"
          
          $MainGui = GUICreate("example drag dots")
          _CreateDragDots($MainGui)
          
          GUISetState()
          While GUIGetMsg() <> -3
              Sleep(20)
          WEnd

The UDF DragDots.au3

;by martin
       #include <GUIConstantsEx.au3>
      #include <WindowsConstants.au3>
      
      Global Const $WM_LBUTTONDOWN = 0x201
      Global $DotWin, $DotWinParent
      
  ; Create the drag dots bottom right of window $hgui
      Func _CreateDragDots($hgui)
          Local $wclient, $k, $lc, $p, $n
      
          $wclient = WinGetClientSize($hgui)
      
          $DotWinParent = $hgui
          $DotWin = GUICreate("", 12, 12, $wclient[0] - 12, $wclient[1] - 12, $WS_CHILD, -1, $DotWinParent)
          GUISetCursor(12, 1);NWSE
          $lc = 0xB8B4A1;the grey dot colour
          For $k = 0 To 1
              For $n = 0 To 2
                  For $p = 0 To 2 - $n
                      GUICtrlCreateLabel("", 8 - 4 * $n + $k, 8 - 4 * $p + $k, 2, 2)
                      GUICtrlSetBkColor(-1, $lc)
                      GUICtrlSetState(-1, $GUI_DISABLE);so that we catch left mouse down
                  Next
              Next
              $lc = 0xffffff;the white border for the dots
      
          Next
          GUISetState()
          GUISwitch($DotWinParent)
          GUIRegisterMsg($WM_LBUTTONDOWN, "lmdown")
          GUIRegisterMsg($WM_SIZE, "DotShift")
      
      EndFunc;==>_CreateDragDots
      
  ;respond to left mouse button down
      Func lmdown($hWnd, $iMsg, $wP, $lP)
      
          If $hWnd = $DotWin Then DllCall("user32.dll", "long", "SendMessage", "hwnd", $DotWinParent, "int", $WM_SYSCOMMAND, "int", 0xF008, "int", 0)
      
          Return $GUI_RUNDEFMSG
      EndFunc;==>lmdown
      
  ;respond to window moving and move the dots with it.
      Func DotShift($hWnd, $iMsg, $wP, $lP)
          Local $wclient = WinGetClientSize($DotWinParent)
          ControlMove($DotWinParent, "", $DotWin, $wclient[0] - 12, $wclient[1] - 12)
      
          Return $GUI_RUNDEFMSG
      EndFunc;==>DotShift

EDIT: See post #7 by trancexx for the correct way to do this.

mgrefdragbox

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Nice work, martin. But is there not another way to get these dots except GUICtrlCreateLabel()?

I'm sure there is. Labels seemed the easiest way to me, but they could be drawn using a graphic for example, or did you mean that there should be a way to do it that's much simpler? I thought there would be but I couldn't find anything and then I noticed that not all windows that have these dots have the same dot design so I concluded they were constructed by the gui designer.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

A quick look at various windows on my desktop would suggest that they're drawn by the status bar of the window (if there is one).

WBD

Link to comment
Share on other sites

  • Moderators

Looks like resize mode in the status bar to me.

Edit:

Although I have to admit, a unique approach :) ...

Edit2:

(Without the window messaging to move the scroll bar)

#include <GUIConstantsEx.au3>
#include <GUIStatusBar.au3>
#include <windowsconstants.au3>

Global $h_gui = GUICreate("example", -1, -1, -1, -1, $WS_SIZEBOX)
Global $h_scroll = _GUICtrlStatusBar_Create($h_gui)
GUIRegisterMsg($WM_SIZE, "_WM_SIZE")
GUISetState()

While GUIGetMsg() <> -3
WEnd

Func _WM_SIZE($h_wnd, $u_msg, $w_param, $l_param)
    _GUICtrlStatusBar_Resize($h_scroll)
    Return $GUI_RUNDEFMSG
EndFunc
Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

@ WBD and SmOke_N

I hadn't realised those dots came with a staus bar. So that's the answer for Yashied then.

I future I'll think of that, but for the script I wrote this for I have vertical and horizontal scroll bars, and an empty square in the bottom right-hand corner and, of course, no staus bar. So I thought it would be a good idea to put these dots there.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

This is obviously great. Very stimulating too.

So, when you think of it, it could be done like this:

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

Global $hGui = GUICreate("Test", 200, 200, -1, -1, $WS_OVERLAPPEDWINDOW)
Global $k, $aLabelResize[6]

Global $aClientSize = WinGetClientSize($hGui); ...this is obviously not needed but still... for testing purposes
For $i = 1 To 3
    For $j = 1 To 3
        If $i + $j < 5 Then
            $aLabelResize[$k] = GUICtrlCreateLabel("", $aClientSize[0] - $i * 3, $aClientSize[1] - $j * 3, 3, 3, 0x8001000)
            GUICtrlSetCursor(-1, 12); NWSE
            GUICtrlSetState(-1, $GUI_ENABLE)
            GUICtrlSetResizing(-1, 836); $GUI_DOCKRIGHT|$GUI_DOCKBOTTOM|$GUI_DOCKWIDTH|$GUI_DOCKHEIGHT
            $k += 1
        EndIf
    Next
Next

GUISetState()

While 1
    Switch GUIGetMsg()
        Case - 3
            ExitLoop
        Case $aLabelResize[0], $aLabelResize[1], $aLabelResize[2], $aLabelResize[3], $aLabelResize[4], $aLabelResize[5]
            DllCall("user32.dll", "dword", "SendMessageW", "hwnd", $hGui, "int", $WM_SYSCOMMAND, "int", 0xF008, "int", 0)
    EndSwitch
WEnd

I'm curious martin, where did you find that 0xF008 for SendMessage?

By the way, after reading this and some testing, another option won:

Opt("WinWaitDelay", 0); will use WinSetState() function and don't want delays.
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global Const $SBS_SIZEBOX = 8
Global Const $SBS_SIZEBOXTOPLEFTALIGN = 2
Global Const $SBS_SIZEBOXBOTTOMRIGHTALIGN = 4
Global Const $SBS_SIZEBOXOWNERDRAWFIXED = 16; ...actually, I made this one up.

Global $hGui = GUICreate("Test", 600, 400, -1, -1, $WS_OVERLAPPEDWINDOW)
Global $hDots = _CreateDragDots($hGui)
Global $hButton = GUICtrlCreateButton("FileOpenDialog", 380, 360, 150, 25)


GUIRegisterMsg($WM_SIZE, "_AdditionalSizing")

GUISetState()

While 1
    Switch GUIGetMsg()
        Case - 3
            ExitLoop
        Case $hButton
            FileOpenDialog("", "", "(*)", 8, "", $hGui)
    EndSwitch
WEnd


; Functions:

Func _AdditionalSizing($hWnd, $iMsg, $wParam, $lParam)

    If $hWnd = $hGui Then
        If $hDots Then
            Switch $wParam
                Case 0
                    Local $aClientSize[2] = [BitAND($lParam, 65535), BitShift($lParam, 16)]
                    WinMove($hDots, 0, $aClientSize[0] - 17, $aClientSize[1] - 17); 17 looks nice
                    WinSetState($hDots, 0, @SW_RESTORE)
                Case 2; SIZE_MAXIMIZED
                    WinSetState($hDots, 0, @SW_HIDE)
            EndSwitch
        EndIf
    EndIf

EndFunc  ;==>_AdditionalSizing


Func _CreateDragDots($hGui)

    Local $aCall = DllCall("user32.dll", "hwnd", "CreateWindowExW", _
            "dword", 0, _
            "wstr", "Scrollbar", _
            "ptr", 0, _
            "dword", BitOR($WS_CHILD, $WS_VISIBLE, $SBS_SIZEBOX, $SBS_SIZEBOXBOTTOMRIGHTALIGN, $SBS_SIZEBOXOWNERDRAWFIXED), _; 0x5000001C
            "int", 0, _
            "int", 0, _
            "int", 0, _
            "int", 0, _
            "hwnd", $hGui, _
            "hwnd", 0, _
            "hwnd", 0, _
            "int", 0)

    If @error Or Not $aCall[0] Then
        Return SetError(1, 0, 0)
    EndIf

    Local $hDots = $aCall[0]

    Return SetError(0, 0, $hDots)

EndFunc  ;==>_CreateDragDots

I must not forget... thanks martin.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

EDIT: Code removed as it did not fit the intended purpose.

Edited by eltorro
Link to comment
Share on other sites

This is obviously great. Very stimulating too.

So, when you think of it, it could be done like this:

#include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    
    Global $hGui = GUICreate("Test", 200, 200, -1, -1, $WS_OVERLAPPEDWINDOW)
    Global $k, $aLabelResize[6]
    
    Global $aClientSize = WinGetClientSize($hGui); ...this is obviously not needed but still... for testing purposes
    For $i = 1 To 3
        For $j = 1 To 3
            If $i + $j < 5 Then
                $aLabelResize[$k] = GUICtrlCreateLabel("", $aClientSize[0] - $i * 3, $aClientSize[1] - $j * 3, 3, 3, 0x8001000)
                GUICtrlSetCursor(-1, 12); NWSE
                GUICtrlSetState(-1, $GUI_ENABLE)
                GUICtrlSetResizing(-1, 836); $GUI_DOCKRIGHT|$GUI_DOCKBOTTOM|$GUI_DOCKWIDTH|$GUI_DOCKHEIGHT
                $k += 1
            EndIf
        Next
    Next
    
    GUISetState()
    
    While 1
        Switch GUIGetMsg()
            Case - 3
                ExitLoop
            Case $aLabelResize[0], $aLabelResize[1], $aLabelResize[2], $aLabelResize[3], $aLabelResize[4], $aLabelResize[5]
                DllCall("user32.dll", "dword", "SendMessageW", "hwnd", $hGui, "int", $WM_SYSCOMMAND, "int", 0xF008, "int", 0)
        EndSwitch
    WEnd

I'm curious martin, where did you find that 0xF008 for SendMessage?

By the way, after reading this and some testing, another option won:

Opt("WinWaitDelay", 0); will use WinSetState() function and don't want delays.
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    
    Global Const $SBS_SIZEBOX = 8
    Global Const $SBS_SIZEBOXTOPLEFTALIGN = 2
    Global Const $SBS_SIZEBOXBOTTOMRIGHTALIGN = 4
    Global Const $SBS_SIZEBOXOWNERDRAWFIXED = 16; ...actually, I made this one up.
    
    Global $hGui = GUICreate("Test", 600, 400, -1, -1, $WS_OVERLAPPEDWINDOW)
    Global $hDots = _CreateDragDots($hGui)
    Global $hButton = GUICtrlCreateButton("FileOpenDialog", 380, 360, 150, 25)
    
    
    GUIRegisterMsg($WM_SIZE, "_AdditionalSizing")
    
    GUISetState()
    
    While 1
        Switch GUIGetMsg()
            Case - 3
                ExitLoop
            Case $hButton
                FileOpenDialog("", "", "(*)", 8, "", $hGui)
        EndSwitch
    WEnd
    
    
  ; Functions:
    
    Func _AdditionalSizing($hWnd, $iMsg, $wParam, $lParam)
    
        If $hWnd = $hGui Then
            If $hDots Then
                Switch $wParam
                    Case 0
                        Local $aClientSize[2] = [BitAND($lParam, 65535), BitShift($lParam, 16)]
                        WinMove($hDots, 0, $aClientSize[0] - 17, $aClientSize[1] - 17); 17 looks nice
                        WinSetState($hDots, 0, @SW_RESTORE)
                    Case 2; SIZE_MAXIMIZED
                        WinSetState($hDots, 0, @SW_HIDE)
                EndSwitch
            EndIf
        EndIf
    
    EndFunc;==>_AdditionalSizing
    
    
    Func _CreateDragDots($hGui)
    
        Local $aCall = DllCall("user32.dll", "hwnd", "CreateWindowExW", _
                "dword", 0, _
                "wstr", "Scrollbar", _
                "ptr", 0, _
                "dword", BitOR($WS_CHILD, $WS_VISIBLE, $SBS_SIZEBOX, $SBS_SIZEBOXBOTTOMRIGHTALIGN, $SBS_SIZEBOXOWNERDRAWFIXED), _; 0x5000001C
                "int", 0, _
                "int", 0, _
                "int", 0, _
                "int", 0, _
                "hwnd", $hGui, _
                "hwnd", 0, _
                "hwnd", 0, _
                "int", 0)
    
        If @error Or Not $aCall[0] Then
            Return SetError(1, 0, 0)
        EndIf
    
        Local $hDots = $aCall[0]
    
        Return SetError(0, 0, $hDots)
    
    EndFunc;==>_CreateDragDots

I must not forget... thanks martin.

That's great trancexx, thanks for showing me the correct way to do it. I will scrap my UDF immediately :) I hadn't thought about the maximized state so I like that addition.

I found the 0xF008 message and some others when I read that 0xF012 can be used to drag a window and I wondered what else there was around that number. So I experimented and found what I thought were some interesting messages and posted what I found here. What I find interesting doesn't exactly set the world on fire though :party:

What does the style 0x8001000 you used for labels do?

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Do you mean the "marching ants"?

I didn't think I did. What does your script do? I can drag a rectangle with it but should it do more than that? Holding down Alt or Shift seems to give the same effect. Anyway it doesn't appear to be connected with resizing a window by dragging.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

... it doesn't appear to be connected with resizing a window by dragging.

Your right, I missed that when I initially read your post. My code draws the selection box, screen captures the region, and then places it on the clipboard. I removed the code from the post as to not confuse others. I'll clean it up a little more and post it in a separate topic.

Edited by eltorro
Link to comment
Share on other sites

That's great trancexx, thanks for showing me the correct way to do it. I will scrap my UDF immediately :) I hadn't thought about the maximized state so I like that addition.

I found the 0xF008 message and some others when I read that 0xF012 can be used to drag a window and I wondered what else there was around that number. So I experimented and found what I thought were some interesting messages and posted what I found here. What I find interesting doesn't exactly set the world on fire though :party:

What does the style 0x8001000 you used for labels do?

I planted that to see if it would trigger anyone's reaction. I do that often, it's my professional deformation, you may say.

It's just combination of $WS_DISABLED and $SS_SUNKEN styles - that's why I do GUICtrlSetState(-1, $GUI_ENABLE) two lines down. Completely unneeded for that script to work properly, but helps me evaluate... environment.

Btw, you noticing it wasn't unexpected.

♡♡♡

.

eMyvnE

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