Что нового

Тащим окно за отключенные элементы

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Плюс заключается в том что даже если элемент на окне отключен то за него можно тащить окно.

Применение например в скиновых окнах, ставим на какую нибудь картинку и можно будет тащить окно, даже если состояние картинки Disable

Example.au3:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Parentdrag.au3>

$hForm = GUICreate("", 200, 100, -1, -1, $WS_POPUP)

$hParent1 = GUICtrlCreateLabel("", 0, 0, 200, 20)
GUICtrlSetBkColor($hParent1, 0x000000)
GUICtrlSetState($hParent1, $GUI_DISABLE)

$hParent2 = GUICtrlCreateLabel("", 0, 80, 200, 20)
GUICtrlSetBkColor($hParent2, 0x000000)
GUICtrlSetState($hParent2, $GUI_DISABLE)

GUISetState()

While 1
	GUICtrlSetParentdrag($hForm, $hParent1)
	GUICtrlSetParentdrag($hForm, $hParent2)
	
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
		Case $hParent1
			ConsoleWrite("$hParent1" & @CRLF)
		Case $hParent2
			ConsoleWrite("$hParent2" & @CRLF)			
    EndSwitch
WEnd

Parentdrag.au3:
Код:
#Include-once

If Not IsDeclared("WM_SYSCOMMAND") Then Global Const $WM_SYSCOMMAND = 0x0112
If Not IsDeclared("WM_PARENTDRAG") Then Global Const $WM_PARENTDRAG = 0xF009
If Not IsDeclared("WM_COMMAND") Then Global Const $WM_COMMAND = 0x0111

Global $iSwitch_Param[1][2] = [[0, 0]]

Func GUICtrlSetParentdrag($hWnd, $CtrlId)
	
	$iSwitch_Param[0][0] += 1
	ReDim $iSwitch_Param[$iSwitch_Param[0][0] + 1][UBound($iSwitch_Param, 2)]
	$iSwitch_Param[$iSwitch_Param[0][0]][0] = $CtrlId
	$iSwitch_Param[$iSwitch_Param[0][0]][1] = 1
	
	Local $hInfo = GUIGetCursorInfo($hWnd)
	If Not @error Then
	    If $hInfo[2] Then
			If __GetSwitch($CtrlId) Then 
				If $hInfo[4] = $CtrlId Then
					__SetSwitch($CtrlId, $hInfo[4]) 
				Else
					__SetSwitch($CtrlId, 0)				
				EndIf
			EndIf	
			If __GetSwitch($CtrlId) = $CtrlId Then
				DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", $WM_SYSCOMMAND, "int", $WM_PARENTDRAG, "int", 0)
				
				Local $hWndParent = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", GUICtrlGetHandle($CtrlId))
				If Not @error Then
				    DllCall("user32.dll", "bool", "PostMessage", "hwnd", $hWndParent[0], "uint", $WM_COMMAND, "wparam", $CtrlId, "lparam", GUICtrlGetHandle($CtrlId))
				EndIf	
			EndIf
		Else
			__SetSwitch($CtrlId, 1)
	    EndIf
	EndIf
EndFunc

Func __GetSwitch($CtrlID)
	For $i = 1 To $iSwitch_Param[0][0]
		If $iSwitch_Param[$i][0] = $CtrlID Then
			Return $iSwitch_Param[$i][1]
		EndIf
	Next
EndFunc	

Func __SetSwitch($CtrlID, $Param)
	For $i = 1 To $iSwitch_Param[0][0]
		If $iSwitch_Param[$i][0] = $CtrlID Then
			$iSwitch_Param[$i][1] = $Param
		EndIf
	Next
EndFunc
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Viktor1703
Процессор напрягает 30-40%
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Может можно как то сбавить? есть советы по этому вопросу?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Это обычно делается так:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

$hForm = GUICreate("", 200, 100, -1, -1, $WS_POPUP)

$hParent1 = GUICtrlCreateLabel("", 0, 0, 200, 20)
GUICtrlSetBkColor($hParent1, 0x000000)
GUICtrlSetState($hParent1, $GUI_DISABLE)

$hParent2 = GUICtrlCreateLabel("", 0, 80, 200, 20)
GUICtrlSetBkColor($hParent2, 0x000000)
GUICtrlSetState($hParent2, $GUI_DISABLE)

GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hParent1
            ConsoleWrite("$hParent1" & @CRLF)
        Case $hParent2
            ConsoleWrite("$hParent2" & @CRLF)           
    EndSwitch
WEnd

Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
	If $hWnd <> $hForm Or $iMsg <> $WM_NCHITTEST Then Return $GUI_RUNDEFMSG
	
	Local $iRet = _WinAPI_DefWindowProc($hWnd, $iMsg, $iwParam, $ilParam)
	If $iRet = 1 Then Return 2
	
	Return $iRet
EndFunc
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Да но нужно перемещать только если по какому то элементу кликнули и тащим, в любой части окна не нужно, а перенапригается скрипт наверное из-за ReDim'a
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Viktor1703
Может можно как то сбавить? есть советы по этому вопросу?
Хотя бы так... только при нажатии мыши
Код:
Switch GUIGetMsg()
		Case $GUI_EVENT_PRIMARYDOWN
			GUICtrlSetParentdrag($hForm, $hParent1)
			GUICtrlSetParentdrag($hForm, $hParent2)
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
В принципе можно и так:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;#include <Parentdrag.au3>

$hForm = GUICreate("", 200, 100, -1, -1, $WS_POPUP)
GUISetBkColor(0xB0B0B0)

$hParent1 = GUICtrlCreateLabel("", 0, 0, 200, 20)
GUICtrlSetBkColor($hParent1, 0x000000)
GUICtrlSetState($hParent1, $GUI_DISABLE)

$hParent2 = GUICtrlCreateLabel("", 0, 80, 200, 20)
GUICtrlSetBkColor($hParent2, 0x000000)
GUICtrlSetState($hParent2, $GUI_DISABLE)

GUISetState()

While 1
    GUICtrlSetParentdrag2($hForm, $hParent1)
	GUICtrlSetParentdrag2($hForm, $hParent2)
	
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit		
    EndSwitch
WEnd

Func GUICtrlSetParentdrag2($hWnd, $CtrlId)
	Local $hInfo = GUIGetCursorInfo($hWnd)
	If IsArray($hInfo) Then
		If $hInfo[2] Then
			If $hInfo[4] = $CtrlId Then
			    Local $hWndParent = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", GUICtrlGetHandle($CtrlId))
	            If Not @error Then
		            DllCall("user32.dll", "bool", "PostMessage", "hwnd", $hWndParent[0], "uint", 0x0111, "wparam", $CtrlId, "lparam", GUICtrlGetHandle($CtrlId))
	            EndIf	
			    DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", 0x0112, "int", 0xF009, "int", 0)			
		    EndIf
		EndIf
	EndIf	
EndFunc

Но тогда если зажать мышь по середине окна и не отжимая повести на Label то скрипт срабатывает и перемещает окно, нужно как то изначально проверку ставить если мышь нажали, то вычисляем id элемента, далее если id не совпадает с $hInfo[4] то функция пропускает перемещение окна
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Viktor1703 [?]
нужно перемещать только если по какому то элементу кликнули и тащим, в любой части окна не нужно
Тогда так:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

$hForm = GUICreate("Drag by controls demo", 240, 180, -1, -1, BitOR($WS_CAPTION, $WS_SYSMENU, $WS_POPUP))

GUICtrlCreateButton("Drag me", 20, 20, 60, 20)
GUICtrlSetState(-1, $GUI_DISABLE)

GUICtrlCreateLabel("Me too :)", 20, 60, -1, 15)
GUICtrlSetState(-1, $GUI_DISABLE)

GUISetState()
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")

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

Func WM_NCHITTEST($hWnd, $nMsg, $wParam, $lParam)
	Local $aInfo = GUIGetCursorInfo($hWnd)
	If IsArray($aInfo) And $aInfo[2] And $aInfo[4] <> 0 Then Return 2
	
    Return _WinAPI_DefWindowProc($hWnd, $nMsg, $wParam, $lParam)
EndFunc
 
Верх