damien2008
Осваивающий
- Сообщения
- 178
- Репутация
- 34
всем привет. прошу помочь.
есть набросок по примерам..
пытаюсь создать окно произвольной формы из PNG рисунка, поверх него создаю дочернее с кнопкой.
проблемы: дочернее полностью перекрывает подложкой родительское окно.
code:
читал, что такие вещи делаются путем перерисовки например "кнопки" поверх "формы окна", а как тогда задать область нажатия?
подскажите, кто сталкивался с таким
есть набросок по примерам..
пытаюсь создать окно произвольной формы из PNG рисунка, поверх него создаю дочернее с кнопкой.
проблемы: дочернее полностью перекрывает подложкой родительское окно.
code:
Код:
#AutoIt3Wrapper_Res_File_Add=green.png, rt_rcdata, green
#AutoIt3Wrapper_Res_File_Add=grey.png, rt_rcdata, grey
#NoTrayIcon
#include <GDIPlus.au3>
#include <GuiComboBox.au3>
#include <File.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <ButtonConstants.au3>
#Include <Memory.au3>
#Include <WinAPIEx.au3>
#include <Constants.au3>
#Include <StaticConstants.au3>
#Include <StructureConstants.au3>
Opt("MustDeclareVars", 0)
Global Const $AC_SRC_ALPHA = 1
Global Const $RT_ACCELERATOR = 9
Global Const $RT_ANICURSOR = 21
Global Const $RT_ANIICON = 22
Global Const $RT_BITMAP = 2
Global Const $RT_CURSOR = 1
Global Const $RT_DIALOG = 5
Global Const $RT_DLGINCLUDE = 17
Global Const $RT_FONT = 8
Global Const $RT_FONTDIR = 7
Global Const $RT_GROUP_CURSOR = 12
Global Const $RT_GROUP_ICON = 14
Global Const $RT_HTML = 23
Global Const $RT_ICON = 3
Global Const $RT_MANIFEST = 24
Global Const $RT_MENU = 4
Global Const $RT_MESSAGETABLE = 11
Global Const $RT_PLUGPLAY = 19
Global Const $RT_RCDATA = 10
Global Const $RT_STRING = 6
Global Const $RT_VERSION = 16
Global Const $RT_VXD = 20
Global $hInstance = _WinAPI_GetModuleHandle('')
_GDIPlus_Startup()
$hImage = _LoadImage('green')
$width = _GDIPlus_ImageGetWidth($hImage)
$height = _GDIPlus_ImageGetHeight($hImage)
$GUI = GUICreate("simple png", 256, 256, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
SetBitmap($GUI, $hImage, 255)
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUISetState()
WinSetOnTop($GUI, "", 1)
For $i = 0 To 255 Step 10
SetBitmap($GUI, $hImage, $i)
Next
$controlGui = GUICreate("Управление", $width, $height, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $GUI)
$pic = GUICtrlCreatePic('', 200, 231, 56, 25)
_SetImageBinaryToCtrl($pic, _LoadString('grey'))
$exButton = GUICtrlCreateButton("Выход", 200, 231, 56, 25, $BS_DEFPUSHBUTTON)
GUICtrlSetBkColor(-1, 0x00FF00)
GUISetState()
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
ExitLoop
Case $msg = $exButton
ExitLoop
EndSelect
WEnd
GUIDelete($controlGui)
For $i = 255 To 0 Step -10
SetBitmap($GUI, $hImage, $i)
Next
_WinAPI_DeleteObject($hImage)
_GDIPlus_Shutdown()
Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
If ($hWnd = $GUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc ;==>WM_NCHITTEST
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
Func _LoadImage($iRes)
Local $hInfo, $hData, $pData, $hMem, $pMem, $iSize, $hStream, $hImage
$hInfo = _WinAPI_FindResource($hInstance, $RT_RCDATA, $iRes)
$hData = _WinAPI_LoadResource($hInstance, $hInfo)
$iSize = _WinAPI_SizeOfResource($hInstance, $hInfo)
$pData = _WinAPI_LockResource($hData)
If @error Then
Return 0
EndIf
$hMem = _MemGlobalAlloc($iSize, 2)
$pMem = _MemGlobalLock($hMem)
_MemMoveMemory($pData, $pMem, $iSize)
_MemGlobalUnlock($hMem)
$hStream = _WinAPI_CreateStreamOnHGlobal($hMem)
$hImage = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromStream', 'ptr', $hStream, 'ptr*', 0)
; _WinAPI_FreeResource($hData)
Return $hImage[2]
EndFunc ;==>_LoadImage
Func _LoadString($iRes)
Local $hInfo, $hData, $pData, $tData, $sData, $iSize
$hInfo = _WinAPI_FindResource($hInstance, $RT_RCDATA, $iRes)
$hData = _WinAPI_LoadResource($hInstance, $hInfo)
$iSize = _WinAPI_SizeOfResource($hInstance, $hInfo)
$pData = _WinAPI_LockResource($hData)
If @error Then
Return ''
EndIf
$tData = DllStructCreate('char[' & $iSize & ']', $pData)
$sData = DllStructGetData($tData, 1)
; _WinAPI_FreeResource($hData)
Return $sData
EndFunc ;==>_LoadString
;Authors: Prog@ndy, based on code by Zedna
Func _SetImageBinaryToCtrl($CtrlId, $Binary)
Local $picdata = Binary($Binary) ; Fetch the Data
Local $piclength = BinaryLen($picdata) ; Get Length
Local $picstruct = DllStructCreate("byte[" & $piclength & "]")
DllStructSetData($picstruct,1,$picdata)
Local $picmemory = DllStructGetPtr($picstruct)
_SetMemoryImageToCtrl($CtrlId, $picmemory, $piclength)
DllStructSetData($picstruct,1,0)
$picstruct = ""
EndFunc
; Authors: Zedna, based on code by Prog@ndy
Func _SetMemoryImageToCtrl($CtrlId, $Pointer, $nSize)
Local $hData, $pData, $pStream, $pBitmap, $hBitmap
; use GDI+ for converting to bitmap first
$hData = _MemGlobalAlloc($nSize,2)
$pData = _MemGlobalLock($hData)
_MemMoveMemory($Pointer,$pData,$nSize)
_MemGlobalUnlock($hData)
$pStream = DllCall( "ole32.dll","int","CreateStreamOnHGlobal", "int",$hData, "long",1, "Int*",0)
$pStream = $pStream[3]
_GDIPlus_Startup()
$pBitmap = DllCall($ghGDIPDll,"int","GdipCreateBitmapFromStream", "ptr",$pStream, "int*",0)
$pBitmap = $pBitmap[2]
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($pBitmap)
_SetBitmapToCtrl($CtrlId, $hBitmap)
If @error Then SetError(3, 0, 0)
_GDIPlus_BitmapDispose($pBitmap)
_GDIPlus_Shutdown()
_WinAPI_DeleteObject($pStream)
_MemGlobalFree($hData)
EndFunc
Func _SetBitmapToCtrl($CtrlId, $hBitmap)
Local Const $STM_SETIMAGE = 0x0172
Local Const $IMAGE_BITMAP = 0
Local Const $SS_BITMAP = 0xE
Local Const $GWL_STYLE = -16
Local $hWnd = GUICtrlGetHandle($CtrlId)
If $hWnd = 0 Then Return SetError(1, 0, 0)
; set SS_BITMAP style to control
Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE)
If @error Then Return SetError(2, 0, 0)
DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP))
If @error Then Return SetError(3, 0, 0)
Local $oldBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
If @error Then Return SetError(4, 0, 0)
If $oldBmp[0] <> 0 Then _WinAPI_DeleteObject($oldBmp[0])
Return 1
EndFunc
читал, что такие вещи делаются путем перерисовки например "кнопки" поверх "формы окна", а как тогда задать область нажатия?
подскажите, кто сталкивался с таким