Что нового

_WinAPI_PostMessage в цикле вызывает тормажение окна

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
может не самый лучший вариант того что я использую, но другого пока не нашёл, хочется сделать $WS_SIZEBOX без применения этого стиля, иначе появляется рамка вокруг окна - чего не хотелось бы, с помощью нажатия мышы в правом нижнем углу окна можно изменять размер окна, но это находится в цикле и мешает обработать сообщения окна такие как $WM_MOVE и $WM_SIZE, по этому я сам отправляю окну сообщение о том что размер изменился.

Код:
#Include <GUIConstantsEx.au3>
#Include <WindowsConstants.au3>
#include <WinAPIEx.au3>
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <Misc.au3>

$hForm = GUICreate("", 400, 300, -1, -1, $WS_POPUP, $WS_EX_COMPOSITED)
GUISetBkColor(0x709BB6)
$hPic = CreateBitmap(WinGetPos($hForm))
For $i = 0 To 8
    SetBitmap($hForm, $hPic[$i], @ScriptDir & "\" & $i + 1 & ".png")
	GUICtrlSetState($hPic[$i], 128)
Next
_WinAPI_SetWindowLong($hForm, -16, BitOR(_WinAPI_GetWindowLong($hForm, -16), $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS))
GUIRegisterMsg($WM_NCHITTEST, 'WM_NCHITTEST')
GUIRegisterMsg(0x0401, 'WM_USER')
GUISetState()

While 1
	$hInfo = GUIGetCursorInfo($hForm)
	If IsArray($hInfo) Then
		If $hInfo[2] Then
			$aMouse = MouseGetPos()
			$WinPos = WinGetPos($hForm)
			If ($aMouse[0] >= ($WinPos[0] + $WinPos[2] - 10)) And ($aMouse[1] >= ($WinPos[1] + $WinPos[3] - 10)) Then
				Do
					$iMouse = MouseGetPos()
					_WinAPI_PostMessage($hForm, 0x0401, 0, 0)
					If ($iMouse[0] <= ($WinPos[0] + 100)) Then $iMouse[0] = ($WinPos[0] + 100)
					If ($iMouse[1] <= ($WinPos[1] + 100)) Then $iMouse[1] = ($WinPos[1] + 100)
					WinMove($hForm, "", $WinPos[0], $WinPos[1], $WinPos[2] + $iMouse[0] - $aMouse[0], $WinPos[3] + $iMouse[1] - $aMouse[1])
				Until _IsPressed(1) < 1
			EndIf
		EndIf
	EndIf

	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd

Func WM_USER($hWnd, $iMsg, $wParam, $lParam)
    Switch $hWnd
        Case $hForm
            Local $hSize = _WinAPI_GetPosFromRect(_WinAPI_GetWindowRect($hForm))
            GUICtrlSetPos($hPic[0], 0, 0, 27, 27)
	        GUICtrlSetPos($hPic[1], 27, 0, $hSize[2] - 54, 27)
	        GUICtrlSetPos($hPic[2], $hSize[2] - 27, 0, 27, 27)
	        GUICtrlSetPos($hPic[3], 0, 27, 2, $hSize[3] - 29)
	        GUICtrlSetPos($hPic[4], 2, 27, $hSize[2] - 4, $hSize[3] - 29)
	        GUICtrlSetPos($hPic[5], $hSize[2] - 2, 27, 2, $hSize[3] - 29)
	        GUICtrlSetPos($hPic[6], 0, $hSize[3] - 2, 2, 2)
	        GUICtrlSetPos($hPic[7], 2, $hSize[3] - 2, $hSize[2] - 4, 2)
	        GUICtrlSetPos($hPic[8], $hSize[2] - 2, $hSize[3] - 2, 2, 2)
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam)
    Switch $hWnd
        Case $hForm
            Switch _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
                Case $HTCLIENT
                    Local $Info = GUIGetCursorInfo($hForm)
                    If (Not @error) And ($Info[1] < 27) Then
                        Return $HTCAPTION
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func CreateBitmap($hSize)
	Local $hPic[9]
	$hPic[0] = GUICtrlCreatePic('', 0, 0, 27, 27)
    $hPic[1] = GUICtrlCreatePic('', 27, 0, $hSize[2] - 54, 27)
    $hPic[2] = GUICtrlCreatePic('', $hSize[2] - 27, 0, 27, 27)
    $hPic[3] = GUICtrlCreatePic('', 0, 27, 2, $hSize[3] - 29)
    $hPic[4] = GUICtrlCreatePic('', 2, 27, $hSize[2] - 4, $hSize[3] - 29)
    $hPic[5] = GUICtrlCreatePic('', $hSize[2] - 2, 27, 2, $hSize[3] - 29)
    $hPic[6] = GUICtrlCreatePic('', 0, $hSize[3] - 2, 2, 2)
    $hPic[7] = GUICtrlCreatePic('', 2, $hSize[3] - 2, $hSize[2] - 4, 2)
    $hPic[8] = GUICtrlCreatePic('', $hSize[2] - 2, $hSize[3] - 2, 2, 2)
	Return $hPic
EndFunc

Func SetBitmap($hWnd, $hCtrl, $hBitmap)

	If Not IsHwnd($hCtrl) Then $hCtrl = GUICtrlGetHandle($hCtrl)
	Local $hSize = ControlGetPos($hWnd, "", $hCtrl)

	_GDIPlus_Startup()
	$hImage = LoadImage($hBitmap)
	$hThumb = _GDIPlus_GetImageThumbnail($hImage, $hSize[2], $hSize[3])
	$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hThumb)
	_WinAPI_DeleteObject(_SendMessage($hCtrl, 0x0172, 0, $hBitmap))
	_GDIPlus_Shutdown()
EndFunc

Func _GDIPlus_GetImageThumbnail($hImage, $iWidth, $iHeight)
    Local $Ret = DllCall($ghGDIPDll, 'int', 'GdipGetImageThumbnail', 'ptr', $hImage, 'int', $iWidth, 'int', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)
    If (@error) Or ($Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[4]
EndFunc

Func LoadImage($hImage)

	Local $sData, $hSize, $hStruct, $hData, $pData, $pStream, $pBitmap

	If StringLen($hImage) < 100 Then
		Return _GDIPlus_ImageLoadFromFile($hImage)
	Else
	    $sData = Binary($hImage)
	    $hSize = BinaryLen($sData)
	    $hStruct = DllStructCreate("byte[" & $hSize & "]")
	    DllStructSetData($hStruct, 1, $sData)
	    $hData = _MemGlobalAlloc($hSize, 2)
	    $pData = _MemGlobalLock($hData)
	    _MemMoveMemory(DllStructGetPtr($hStruct), $pData, $hSize)
	    _MemGlobalUnlock($hData)
	    $pStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "int", $hData, "long", 1, "Int*", 0)
	    $pBitmap = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromStream", "ptr", $pStream[3], "int*", 0)
		If Not @error Then Return $pBitmap[2]
	    _GDIPlus_BitmapDispose($pBitmap[2])
        _WinAPI_DeleteObject($pStream[3])
		_WinAPI_ReleaseStream($pStream[3])
        _MemGlobalFree($hData)
	EndIf

EndFunc


В архиве есть всё что требуется для запуска и анализа скрипта.


Добавлено:
Сообщение автоматически объединено:

Извиняюсь, разобрался, у меня процессор от чего то был загружен на 100%, разгрузил, работает отменно.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
Вы знаете чем отличается SendMessage() от PostMessage()?
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
В каком то смысле да
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
:smile:

Тогда зачем используете здесь PostMessage(), а не SendMessage()? Нужно как раз наоборот.
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Да я забыл поменять, когда возникла проблема, пробывал и тот и тот вариант, а потом когда разорался что не в скрипте дело, то забыл сменит PostMessage на SendMessage :smile:
 
Верх