Что нового

Перемещение и масштабирование картинки в пределах GUI

passwd

Новичок
Сообщения
30
Репутация
0
Обновление вопроса. Вот так выглядит моя форма. На фоне ставится скриншот другого окна. Сверху накладывается картинка. Как сделать так, чтобы картинка, которую помещаю поверх фона можно было перемещать мышкой и масштабировать колесом мышки?
Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
Global Const $AC_SRC_ALPHA = 1

$Form1_1 = GUICreate("Document", 701, 671, -1, -1)
GUISetBkColor(0xFFFFFF)
$Pic1 = GUICtrlCreatePic("", 8, 8, 409, 657)
$Button1 = GUICtrlCreateButton("Take Picture", 424, 8, 161, 33)

GUISetState(@SW_SHOW)


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

Func Generate()
    Local $hBMP, $hBitmap, $hGraphic, $WindowToCapture

    WinActivate("Notepad")
    $WindowToCapture = ControlGetHandle("Notepad", "", "[CLASS:Edit; INSTANCE:1]")
    $hBMP = _ScreenCapture_CaptureWnd ( '', $WindowToCapture,4,4,400,470,False)

    ; Initialize GDI+ library
    _GDIPlus_Startup()

$PicHandle = GUICtrlGetHandle($Pic1)
$myGuiHandle = ControlGetHandle("Document", "", $PicHandle)
$TransparentButtonTest = GUICreate("", 0, 0, 390, 130, $WS_EX_MDICHILD, $WS_EX_LAYERED, $myGuiHandle)
$hImageButton = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\2-f.png")
SetBitMap($TransparentButtonTest, $hImageButton, 255)
GUISetState()

    WinActivate("Document")
    ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND(GUICtrlGetHandle($Pic1))
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 100)

    ; Clean up resources
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BitmapDispose($hBitmap)
    _WinAPI_DeleteObject($hBMP)

    ; Shut down GDI+ library
    _GDIPlus_Shutdown()

EndFunc

Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc   ;==>SetBitmap
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
passwd
перемещать мышкой и масштабировать колесом мышки
Разбирайте пример в английской справке к функции
Код:
_GDIPlus_GraphicsRotateTransform()
 
Автор
passwd

passwd

Новичок
Сообщения
30
Репутация
0
Спасибо большое, буду разбирать пример, там всё работает как нужно мне =)


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

А вот можете подсказать?
Я сделал как в примере и всё отлично подходит. Но, мне нужно чтобы в форме на фоне этой картинки была еще одна картинка, которую двигать не нужно.
Код:
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>
Global Const $AC_SRC_ALPHA = 1
Global $g_hGUI, $g_hGraphics, $g_hBmp_Buffer, $g_hGfx_Buffer, $g_hImage
Global $g_iMouseX, $g_iMouseY

Example()

Func Example()
AutoItSetOption("GUIOnEventMode", 1)


    Local $sFile = @ScriptDir & "\2-f.png"
    If Not FileExists($sFile) Then
        MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", $sFile & " not found!", 30)
        Exit
    EndIf
	Local $sFile2 = @ScriptDir & "\1.png" ; просто для примера, потом я буду брать эту картинку из скриншота
	    If Not FileExists($sFile2) Then
        MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", $sFile2 & " not found!", 30)
        Exit
    EndIf

$g_hGUI = GUICreate("Document", 701, 671, -1, -1)
GUISetBkColor(0xFFFFFF)
$Graphic1 = GUICtrlCreateGraphic("", 8, 8, 409, 657)
$Button1 = GUICtrlCreateButton("Calculate", 424, 8, 161, 33)


    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetOnEvent($GUI_EVENT_SECONDARYDOWN, "_ResetGraphicsTransform")
    GUISetState(@SW_SHOW)

    _GDIPlus_Startup()
    $g_hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI)
    $g_hBmp_Buffer = _GDIPlus_BitmapCreateFromGraphics(409, 657, $g_hGraphics)
    $g_hGfx_Buffer = _GDIPlus_ImageGetGraphicsContext($g_hBmp_Buffer)

    $g_hImage = _GDIPlus_ImageLoadFromFile($sFile)

    GUIRegisterMsg($WM_LBUTTONDOWN, "WM_LBUTTONDOWN")
    GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL")
    GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE")
    GUISetState(@SW_SHOW)

    _Draw()

    While Sleep(10)
    WEnd
EndFunc   ;==>Example

Func _ResetGraphicsTransform()
    _GDIPlus_GraphicsResetTransform($g_hGfx_Buffer)
    _Draw()
EndFunc   ;==>_ResetGraphicsTransform

Func WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam

    $g_iMouseX = BitAND($lParam, 0x0000FFFF)
    $g_iMouseY = BitShift($lParam, 16)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_LBUTTONDOWN

Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg

    Switch BitAND($wParam, 0x0000FFFF)
        Case 1
            Local $iX = BitAND($lParam, 0x0000FFFF)
            Local $iY = BitShift($lParam, 16)

            _GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, $iX - $g_iMouseX, $iY - $g_iMouseY, True)

            $g_iMouseX = $iX
            $g_iMouseY = $iY

            _Draw()
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOUSEMOVE

Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $lParam

    Switch BitAND($wParam, 0x0000FFFF)
        Case 1
            Local $iAngle = -3
            If BitShift($wParam, 16) < 0 Then $iAngle = 3

            Local $aMousePos[2][2] = [[1]]
            $aMousePos[1][0] = $g_iMouseX
            $aMousePos[1][1] = $g_iMouseY
            _GDIPlus_GraphicsTransformPoints($g_hGfx_Buffer, $aMousePos)

            _GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, $aMousePos[1][0], $aMousePos[1][1])
            _GDIPlus_GraphicsRotateTransform($g_hGfx_Buffer, $iAngle)
            _GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, -$aMousePos[1][0], -$aMousePos[1][1])

        Case Else
            Local $aInfo = GUIGetCursorInfo($g_hGUI)
            Local $iScale = 1.1
            If BitShift($wParam, 16) < 0 Then $iScale = 0.9

            _GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, -$aInfo[0], -$aInfo[1], True)
            _GDIPlus_GraphicsScaleTransform($g_hGfx_Buffer, $iScale, $iScale, True)
            _GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, $aInfo[0], $aInfo[1], True)
    EndSwitch

    _Draw()
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOUSEWHEEL

Func _Draw()
    _GDIPlus_GraphicsClear($g_hGfx_Buffer, 0xFFFFFFFF)

    _GDIPlus_GraphicsDrawImage($g_hGfx_Buffer, $g_hImage, 60, 70)

    _GDIPlus_GraphicsDrawImage($g_hGraphics, $g_hBmp_Buffer, 0, 0)

EndFunc   ;==>_Draw


Func _Exit()
    _GDIPlus_ImageDispose($g_hImage)
    _GDIPlus_GraphicsDispose($g_hGfx_Buffer)
    _GDIPlus_BitmapDispose($g_hBmp_Buffer)
    _GDIPlus_GraphicsDispose($g_hGraphics)
    _GDIPlus_Shutdown()
    GUIDelete($g_hGUI)
    Exit
EndFunc   ;==>_Exit


Каким образом лучше всего поместить статическую картинку на фон за PNG?
 
A

Alofa

Гость
passwd сказал(а):
...Но, мне нужно чтобы в форме на фоне этой картинки была еще одна картинка, которую двигать не нужно.

Так наверно:
Код:
#include <ScreenCapture.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $g_hGUI, $g_hGraphics, $g_hBmp, $g_hGfx_Buffer, $hBitmap, $hBackground, $g_iMouseX, $g_iMouseY, $hIA, $hWnd, $aPos
Global $iGUIWidth = 800 ; Ширина GUI окна
Global $iGUIHeight = 600 ; Высота GUI окна
Global $iScreenWidth = 500 ; Желаемая ширина скрина
Global $iScreenHeight = 500 ; Желаемая высота скрина
Global $iARGBLow = 0x00000000 ; Цвет нижней границы диапазона прозрачности
Global $iARGBHigh ; Цвет верхней границы диапазона прозрачности (при желании)

$hWnd = WinWait('[CLASS:FaceGenMainWinClass]', '', 60)
If Not $hWnd Then Exit MsgBox(16, 'Ошибка!', 'Окно программы так и не появилось.')

AutoItSetOption("GUIOnEventMode", 1)

Local $sFileName = @ScriptDir & "\2-f.png"

$g_hGUI = GUICreate("GDI+", $iGUIWidth, $iGUIHeight)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUISetOnEvent($GUI_EVENT_SECONDARYDOWN, "_ResetGraphicsTransform")
GUISetState(@SW_SHOW)

_GDIPlus_Startup()
$hWnd = WinActivate($hWnd)
$aPos = ControlGetPos($hWnd, '', '[CLASS:FanWin3dClass; INSTANCE:1]')

$g_hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) ; Создаёт графический объект из дескриптора окна
$g_hBmp = _GDIPlus_BitmapCreateFromGraphics($iGUIWidth, $iGUIHeight, $g_hGraphics) ; Создает объект Bitmap на основе графического объекта, с указанием ширины и высоты
$g_hGfx_Buffer = _GDIPlus_ImageGetGraphicsContext($g_hBmp) ; Возвращает графический контекст изображения

; Для изображения фона
$hBackground = _GDIPlus_BitmapCreateFromFile($sFileName) ; Создаёт объект Bitmap  из файла

; Для скрина
Local $hHBmp = _ScreenCapture_CaptureWnd('', $hWnd, $aPos[0] + 15, $aPos[1] + 55, $aPos[2] + 5, $aPos[3] + 45, False) ; Захватывает область экрана указанного окна и возвращает дескриптор hBitmap
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) ; Создает объект Bitmap используя дескриптор Bitmap
$hIA = _GDIPlus_ImageAttributesCreate() ; Создаёт новый объект ImageAttribute и возвращает указатель
_GDIPlus_ImageAttributesSetColorKeys($hIA, 0, True, $iARGBLow, $iARGBHigh) ; Устанавливает цветовой ключ (диапазон прозрачности)
_WinAPI_DeleteObject($hHBmp)

GUIRegisterMsg($WM_LBUTTONDOWN, "WM_LBUTTONDOWN")
GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL")
GUIRegisterMsg($WM_MOUSEMOVE, "WM_MOUSEMOVE")
GUISetState()

_Draw()

While Sleep(10)
WEnd

;====================== Ф У Н К Ц И И ===============================

Func _ResetGraphicsTransform() ; Реакция на нажатие правой кнопки мыши
	_GDIPlus_GraphicsResetTransform($g_hGfx_Buffer)
	_Draw()
EndFunc   ;==>_ResetGraphicsTransform

Func _Draw()
	_GDIPlus_GraphicsClear($g_hGfx_Buffer, 0x00000000) ; Очищает графический объект указанным цветом
	_GDIPlus_DrawImagePoints($g_hGraphics, $hBackground, 0, 0, $iGUIWidth, 0, 0, $iGUIHeight) ; Рисует Фон.
	_GDIPlus_GraphicsDrawImageRectRect($g_hGfx_Buffer, $hBitmap, 0, 0, $iScreenWidth, $iScreenHeight, 216, 80, $iScreenWidth, $iScreenHeight, $hIA) ; Рисует объект содержащий изображение с учетом прозрачности
	_GDIPlus_GraphicsDrawImage($g_hGraphics, $g_hBmp, 0, 0) ; Рисует объект изображения
EndFunc   ;==>_Draw

Func _Exit()
	_WinAPI_DeleteObject($hBackground)
	_GDIPlus_ImageDispose($hBitmap)
	_GDIPlus_ImageAttributesDispose($hIA)
	_GDIPlus_GraphicsDispose($g_hGfx_Buffer)
	_GDIPlus_BitmapDispose($g_hBmp)
	_GDIPlus_GraphicsDispose($g_hGraphics)
	_GDIPlus_Shutdown()
	GUIDelete($g_hGUI)
	Exit
EndFunc   ;==>_Exit

Func WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $wParam
	$g_iMouseX = BitAND($lParam, 0x0000FFFF)
	$g_iMouseY = BitShift($lParam, 16)
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_LBUTTONDOWN

Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg
	Switch BitAND($wParam, 0x0000FFFF)
		Case 1
			Local $iX = BitAND($lParam, 0x0000FFFF)
			Local $iY = BitShift($lParam, 16)
			_GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, $iX - $g_iMouseX, $iY - $g_iMouseY, True)
			$g_iMouseX = $iX
			$g_iMouseY = $iY
			_Draw()
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOUSEMOVE

Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg, $lParam
	Switch BitAND($wParam, 0x0000FFFF)
		Case 1
			Local $iAngle = -3
			If BitShift($wParam, 16) < 0 Then $iAngle = 3
			Local $aMousePos[2][2] = [[1]]
			$aMousePos[1][0] = $g_iMouseX
			$aMousePos[1][1] = $g_iMouseY
			_GDIPlus_GraphicsTransformPoints($g_hGfx_Buffer, $aMousePos)
			_GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, $aMousePos[1][0], $aMousePos[1][1])
			_GDIPlus_GraphicsRotateTransform($g_hGfx_Buffer, $iAngle)
			_GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, -$aMousePos[1][0], -$aMousePos[1][1])
		Case Else
			Local $aInfo = GUIGetCursorInfo($g_hGUI)
			Local $iScale = 1.1
			If BitShift($wParam, 16) < 0 Then $iScale = 0.9
			_GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, -$aInfo[0], -$aInfo[1], True)
			_GDIPlus_GraphicsScaleTransform($g_hGfx_Buffer, $iScale, $iScale, True)
			_GDIPlus_GraphicsTranslateTransform($g_hGfx_Buffer, $aInfo[0], $aInfo[1], True)
	EndSwitch
	_Draw()
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOUSEWHEEL
<Вариант довольно "сырой" и требует доводки>
 
Автор
passwd

passwd

Новичок
Сообщения
30
Репутация
0
Получилось вроде бы то что нужно =) А сложно ли здесь поменять местами фон с картинкой? Чтобы скриншот становился в фон, а картинка была поверх фона =) Может тогда и мерцать не будет? Будет ли это работать так же, только в определенной области GUI, к примеру на пол окна? Может это вообще проще сделать через какой нибудь child window?
 
Автор
passwd

passwd

Новичок
Сообщения
30
Репутация
0
Сделал в итоге как в третьем спойлере из этого сообщения http://autoit-script.ru/index.php?topic=22208.msg130083#msg130083
 
Верх