Что нового

Чем заменит $WS_SIZEBOX или $WS_THICKFRAME

Viktor1703

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

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

_GDIPlus_Startup()

Global $hCur

Dim $hPart[10][3]
$hPart[0][0] = UBound($hPart)
$hPart[1][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\1.png")
$hPart[1][1] = _GDIPlus_ImageGetWidth($hPart[1][0])
$hPart[1][2] = _GDIPlus_ImageGetHeight($hPart[1][0])
$hPart[2][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\2.png")
$hPart[2][1] = _GDIPlus_ImageGetWidth($hPart[2][0])
$hPart[2][2] = _GDIPlus_ImageGetHeight($hPart[2][0])
$hPart[3][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\3.png")
$hPart[3][1] = _GDIPlus_ImageGetWidth($hPart[3][0])
$hPart[3][2] = _GDIPlus_ImageGetHeight($hPart[3][0])
$hPart[4][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\4.png")
$hPart[4][1] = _GDIPlus_ImageGetWidth($hPart[4][0])
$hPart[4][2] = _GDIPlus_ImageGetHeight($hPart[4][0])
$hPart[5][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\5.png")
$hPart[5][1] = _GDIPlus_ImageGetWidth($hPart[5][0])
$hPart[5][2] = _GDIPlus_ImageGetHeight($hPart[5][0])
$hPart[6][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\6.png")
$hPart[6][1] = _GDIPlus_ImageGetWidth($hPart[6][0])
$hPart[6][2] = _GDIPlus_ImageGetHeight($hPart[6][0])
$hPart[7][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\7.png")
$hPart[7][1] = _GDIPlus_ImageGetWidth($hPart[7][0])
$hPart[7][2] = _GDIPlus_ImageGetHeight($hPart[7][0])
$hPart[8][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\8.png")
$hPart[8][1] = _GDIPlus_ImageGetWidth($hPart[8][0])
$hPart[8][2] = _GDIPlus_ImageGetHeight($hPart[8][0])
$hPart[9][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\9.png")
$hPart[9][1] = _GDIPlus_ImageGetWidth($hPart[9][0])
$hPart[9][2] = _GDIPlus_ImageGetHeight($hPart[9][0])

$hForm = GUICreate("Example", 400, 300, -1, -1, BitOR($WS_POPUP, $WM_SYSMENU), $WS_EX_LAYERED)
GUISetBkColor(0xFF00DC)
$hPic = GUICtrlCreatePic('', 0, 0, 400, 300)
ComposeBitmap($hPic, 400, 300, "Example", $hPart)
GUICtrlSetState($hPic, 128)
_WinAPI_SetWindowLong($hForm, -16, BitOR(_WinAPI_GetWindowLong($hForm, -16), $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS))
_WinAPI_SetLayeredWindowAttributes($hForm, 0xFF00DC, 255, $LWA_COLORKEY)
$hButton = GUICtrlCreateButton('Exit', 30, 40, 60, 20)
GUIRegisterMsg($WM_NCHITTEST, 'WM_NCHITTEST')
GUIRegisterMsg(0x0401, 'WM_USER')
GUISetState()

While 1
	$hInfo = GUIGetCursorInfo($hForm)
	If IsArray($hInfo) Then
		$WinPos = WinGetPos($hForm)
		If ($hInfo[0] >= ($WinPos[2] - 10)) And ($hInfo[1] >= ($WinPos[3] - 10)) Then
            If Not $hCur Then
			    GUISetCursor(12)
				$hCur = True
			EndIf
		Else
			If $hCur Then
			    GUISetCursor(2)
				$hCur = False
			EndIf
		EndIf
		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()
					If ($iMouse[0] <= ($WinPos[0] + 100)) Then $iMouse[0] = ($WinPos[0] + 100)
					If ($iMouse[1] <= ($WinPos[1] + 100)) Then $iMouse[1] = ($WinPos[1] + 100)
					_SendMessage($hForm, 0x0401, 0, 0)
					WinMove($hForm, '', $WinPos[0], $WinPos[1], $WinPos[2] + $iMouse[0] - $aMouse[0], $WinPos[3] + $iMouse[1] - $aMouse[1])
				Until _IsPressed(01) < 1
				_SendMessage($hForm, 0x0401, 0, 0)
			EndIf
		EndIf
	EndIf

	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE, $hButton
			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, $hSize[2], $hSize[3])
            ComposeBitmap($hPic, $hSize[2], $hSize[3], WinGetTitle($hWnd), $hPart)
    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] < 25) Then
                        Return $HTCAPTION
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func ComposeBitmap($iCtrl, $iWidth, $iHeight, $sTitle, ByRef $hPart)
    Local $hGraphic, $hImage, $hThumb, $hBitmap

    If IsArray($hPart) Then
        $hImage = _GDIPlus_CreateBitmapFromScan0($iWidth, $iHeight)
        $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hPart[1][0], 0, 0, $hPart[1][1], $hPart[1][2])
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hPart[3][0], $iWidth - $hPart[3][1], 0, $hPart[3][1], $hPart[3][2])
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hPart[9][0], $iWidth - $hPart[9][1], $iHeight - $hPart[9][2], $hPart[9][1], $hPart[9][2])
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hPart[7][0], 0, $iHeight - $hPart[7][2], $hPart[7][1], $hPart[7][2])
        $hThumb = _GDIPlus_GetImageThumbnail($hPart[2][0], $iWidth - ($hPart[1][1] + $hPart[3][1]), $hPart[2][2])
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, $hPart[1][1], 0, $iWidth - ($hPart[1][1] + $hPart[3][1]), $hPart[2][2])
        _GDIPlus_ImageDispose($hThumb)
        $hThumb = _GDIPlus_GetImageThumbnail($hPart[6][0], $hPart[6][1], $iHeight - ($hPart[3][2] + $hPart[7][2]))
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, $iWidth - $hPart[6][1], $hPart[3][2], $hPart[6][1], $iHeight - ($hPart[3][2] + $hPart[7][2]))
        _GDIPlus_ImageDispose($hThumb)
        $hThumb = _GDIPlus_GetImageThumbnail($hPart[8][0], $iWidth - ($hPart[7][1] + $hPart[9][1]), $hPart[8][2])
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, $hPart[7][1], $iHeight - $hPart[8][2], $iWidth - ($hPart[7][1] + $hPart[9][1]), $hPart[8][2])
        _GDIPlus_ImageDispose($hThumb)
        $hThumb = _GDIPlus_GetImageThumbnail($hPart[4][0], $hPart[4][1], $iHeight - ($hPart[1][2] + $hPart[7][2]))
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, 0, $hPart[1][2], $hPart[4][1], $iHeight - ($hPart[1][2] + $hPart[7][2]))
        _GDIPlus_ImageDispose($hThumb)
        $hThumb = _GDIPlus_GetImageThumbnail($hPart[5][0], $iWidth - ($hPart[4][1] + $hPart[6][1]), $iHeight - ($hPart[1][2] + $hPart[7][2]))
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, $hPart[4][1], $hPart[1][2], $iWidth - ($hPart[4][1] + $hPart[6][1]), $iHeight - ($hPart[1][2] + $hPart[7][2]))
        _GDIPlus_ImageDispose($hThumb)

        $hIcon = _WinAPI_ShellExtractIcon(@AutoItExe, 99, 16, 16)
		If Not IsHWnd($hIcon) Then $hIcon = _WinAPI_ShellExtractIcon(@AutoItExe, -99, 16, 16)
        $aInfo = _WinAPI_GetIconInfo($hIcon)
        $tBits = DllStructCreate('byte[' & (4 * 16 * 16) & ']')
        $pBits = DllStructGetPtr($tBits)
        _WinAPI_GetBitmapBits($aInfo[5], DllStructGetSize($tBits), $pBits)
        $hBitmap = _GDIPlus_CreateBitmapFromScan0(16, 16, 4 * 16, $GDIP_PXF32ARGB, $pBits)
        _WinAPI_DestroyIcon($hIcon)
        For $i = 4 To 5
            _WinAPI_DeleteObject($aInfo[$i])
        Next
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 5, 4, 16, 16)
        _GDIPlus_ImageDispose($hBitmap)

        $hBrush = _GDIPlus_BrushCreateSolid(0xFF404040)
        $hFormat = _GDIPlus_StringFormatCreate()
        $hFamily = _GDIPlus_FontFamilyCreate('Arial')
        $hFont = _GDIPlus_FontCreate($hFamily, 10, 0)
        $tLayout = _GDIPlus_RectFCreate(25, 5, 0, 0)
        $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sTitle, $hFont, $tLayout, $hFormat)
        _GDIPlus_GraphicsDrawStringEx($hGraphic, $sTitle, $hFont, $aInfo[0], $hFormat, $hBrush)
        $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sTitle, $hFont, $tLayout, $hFormat)
		_GDIPlus_BrushDispose($hBrush)
        DllStructSetData($aInfo[0], 1, 25 - 1)
        DllStructSetData($aInfo[0], 2, 5 - 1)
        $hBrush = _GDIPlus_BrushCreateSolid(0xFFE0E0E0)
        _GDIPlus_GraphicsDrawStringEx($hGraphic, $sTitle, $hFont, $aInfo[0], $hFormat, $hBrush)
        _GDIPlus_FontDispose($hFont)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
        _GDIPlus_BrushDispose($hBrush)

        $hResult = _WinAPI_CreateBitmap(_GDIPlus_ImageGetWidth($hImage), _GDIPlus_ImageGetHeight($hImage), 1, 32)
        $hDC = _WinAPI_CreateCompatibleDC(0)
	    $hSv = _WinAPI_SelectObject($hDC, $hResult)
		$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
        _WinAPI_DrawBitmap($hDC, 0, 0, $hBitmap, $MERGECOPY)
        _WinAPI_SelectObject($hDC, $hSv)
		_WinAPI_DeleteObject(GUICtrlSendMsg($iCtrl, 0x0172, 0, $hResult))
        _GDIPlus_GraphicsDispose($hGraphic)
        _GDIPlus_ImageDispose($hImage)
        _WinAPI_DeleteDC($hDC)
    EndIf
EndFunc

Func _GDIPlus_CreateBitmapFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
    Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $iWidth, 'int', $iHeight, 'int', $iStride, 'int', $iPixelFormat, 'ptr', $pScan0, 'ptr*', 0)
    If (@error) Or ($Ret[0]) Then
        Return SetError(@error, @extended, 0)
    EndIf
    Return $Ret[6]
EndFunc

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

CreatoR

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

или какие системные сообщения отвечают за изменение размера окна
WM_SIZE, WM_SIZING, WM_WINDOWPOSCHANGING, WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Вот именно что рамка есть, её нужно убрать
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Viktor1703 [?]
Вот именно что рамка есть, её нужно убрать
У тебя в примере не используется WS_SIZEBOX, это путает.
Нет смысла в примере если он не показывает проблему.

Я не думаю что можно так просто убрать рамку.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Вот пример с оффорума :

Код:
#include <GuiConstants.au3>
#include <windowsconstants.au3>

Global Const $margin = 12; distance from edge of window where dragging is possible
$Gui = GUICreate("Drag sides to resize", 420, 200, -1, -1, $WS_POPUP)
GUISetBkColor(0xf1f100)

$chk1 = GUICtrlCreateCheckbox("allow resizing and dragging", 140, 40)
GUICtrlSetResizing(-1, $GUI_DOCKWIDTH)
$Button = GUICtrlCreateButton("Exit", 140, 90, 150, 30)

GUISetState(@SW_SHOW, $Gui)

GUIRegisterMsg($WM_LBUTTONDOWN, "WM_LBUTTONDOWN")
GUIRegisterMsg($WM_MOUSEMOVE, "SetCursor")

While 1
	$msg = GUIGetMsg()
	Select
		Case $msg = $Button
			Exit
	EndSelect
WEnd

;GetMousePosType returns a code depending on the border the mouse cursor is near
Func GetMousePosType()
	Local $cp = GUIGetCursorInfo()
	Local $wp = WinGetPos($Gui)
	Local $side = 0
	Local $TopBot = 0
	Local $curs
	If $cp[0] < $margin Then $side = 1
	If $cp[0] > $wp[2] - $margin Then $side = 2
	If $cp[1] < $margin Then $TopBot = 3
	If $cp[1] > $wp[3] - $margin Then $TopBot = 6
	Return $side + $TopBot
EndFunc

Func SetCursor()
	Local $curs
	If GUICtrlRead($chk1) <> $GUI_CHECKED Then Return
	Switch GetMousePosType()
		Case 0
			$curs = 2
		Case 1, 2
			$curs = 13
		Case 3, 6
			$curs = 11
		Case 5, 7
			$curs = 10
		Case 4, 8
			$curs = 12
	EndSwitch
	GUISetCursor($curs, 1)
EndFunc


Func WM_LBUTTONDOWN($hWnd, $iMsg, $StartWIndowPosaram, $lParam)
	If GUICtrlRead($chk1) <> $GUI_CHECKED Then Return $GUI_RUNDEFMSG
	Local $drag = GetMousePosType()
	If $drag > 0 Then
		DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", $WM_SYSCOMMAND, "int", 0xF000 + $drag, "int", 0)
	Else
		DllCall("user32.dll", "long", "SendMessage", "hwnd", $hWnd, "int", $WM_SYSCOMMAND, "int", 0xF012, "int", 0)
	EndIf
EndFunc
 
Верх