本帖最后由 seniors 于 2011-11-28 15:21 编辑
问题描述,我想自绘三角形按钮,用到了控件区域设置函数_WinAPI_SetWindowRgn
现在情况是,运行程序,第二图,第二个按钮把第一按钮覆盖,但点击任何按钮后,又不再覆盖,如第一图
不知道这个_WinAPI_SetWindowRgn应该放在什么地方才能解决此问题
窗口风格加上$WS_CLIPCHILDREN解决了
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <WinAPIEx.au3>
Dim $aPoint[3][2] = [[25, 0],[0, 40],[50, 40]];向上三角形区域
Dim $bPoint[3][2] = [[25, 40],[0, 0],[50, 0]];向下三角形区域
Global $hGUI, $nButton, $nButton2, $GUIMsg
GUIRegisterMsg($WM_DRAWITEM, "MY_WM_DRAWITEM")
Example()
Func Example()
Local Const $BS_OWNERDRAW = 0x0000000B
$hGUI = GUICreate("自绘按钮", 300, 200,-1,-1,BitOR($WS_MINIMIZEBOX,$WS_CAPTION,$WS_POPUP,$WS_SYSMENU,$WS_CLIPCHILDREN))
$nButton = GUICtrlCreateButton("上", 5, 5, 50, 40)
GUICtrlSetStyle($nButton, BitOR($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW)) ; 设置自绘标志
$hRgn = _WinAPI_CreatePolygonRgn($aPoint)
_WinAPI_SetWindowRgn(GUICtrlGetHandle($nButton), $hRgn, 1);重设按钮区域
$nButton2 = GUICtrlCreateButton("下", 40, 5, 50, 40)
GUICtrlSetStyle($nButton2, BitOR($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW)); 设置自绘标志
$hRgn2 = _WinAPI_CreatePolygonRgn($bPoint)
_WinAPI_SetWindowRgn(GUICtrlGetHandle($nButton2), $hRgn2, 1);重设按钮区域
GUISetState()
While 1
$GUIMsg = GUIGetMsg()
Switch $GUIMsg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $nButton
MsgBox(0, "点击消息", "按钮上点击了", -1, $hGUI)
Case $nButton2
MsgBox(0, "点击消息", "按钮下点击了", -1, $hGUI)
EndSwitch
WEnd
EndFunc ;==>Example
Func MY_WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
Local $stDrawItem = DllStructCreate("uint;uint;uint;uint;uint;uint;uint;int[4];dword", $lParam)
Local Const $ODT_BUTTON = 4
$nCtlType = DllStructGetData($stDrawItem, 1);要求自绘的控件类型$ODT_BUTTON 是Owner-drawn button
If $nCtlType = $ODT_BUTTON Then
$nCtrlID = DllStructGetData($stDrawItem, 2);控件ID,菜单自绘无此参数,3为itemID菜单ITEM,4为itemAction
$nItemState = DllStructGetData($stDrawItem, 5)
$hCtrl = DllStructGetData($stDrawItem, 6);控件句柄 A handle to the control for combo boxes, list boxes, buttons, and static controls. For menus, this member is a handle to the menu that contains the item.
$hDC = DllStructGetData($stDrawItem, 7);设备句柄 A handle to a device context; this device context must be used when performing drawing operations on the control
$nLeft = DllStructGetData($stDrawItem, 8, 1)
$nTop = DllStructGetData($stDrawItem, 8, 2)
$nRight = DllStructGetData($stDrawItem, 8, 3)
$nBottom = DllStructGetData($stDrawItem, 8, 4)
$nTextColor = 0xFFFFFFFF
$nBackColor = 0xFFEEDD
DrawButton($hWnd, $nCtrlID, $hDC, $nLeft, $nTop, $nRight, $nBottom, $nItemState, $nTextColor, $nBackColor)
$stDrawItem = 0
Return 1
EndIf
$stDrawItem = 0
Return $GUI_RUNDEFMSG ; Proceed the default Autoit3 internal message commands
EndFunc ;==>MY_WM_DRAWITEM
Func DrawButton($hWnd, $nCtrlID, $hDC, $nLeft, $nTop, $nRight, $nBottom, $nItemState, $nTextColor, $nBackColor)
;Local $bDefault = FALSE
Local Const $GWL_STYLE = -16
Local Const $ODS_SELECTED = 0x0001
Local Const $ODS_GRAYED = 0x0002
Local Const $ODS_DISABLED = 0x0004
Local Const $ODS_CHECKED = 0x0008
Local Const $ODS_FOCUS = 0x0010
Local Const $ODS_HOTLIGHT = 0x0040
Local Const $ODS_INACTIVE = 0x0080
Local Const $ODS_NOACCEL = 0x0100
Local Const $ODS_NOFOCUSRECT = 0x0200
Local Const $DFC_BUTTON = 4
Local Const $DFCS_BUTTONPUSH = 0x0010
Local $bChecked = BitAND($nItemState, $ODS_CHECKED)
Local $bFocused = BitAND($nItemState, $ODS_FOCUS)
Local $bGrayed = BitAND($nItemState, BitOR($ODS_GRAYED, $ODS_DISABLED))
Local $bSelected = BitAND($nItemState, $ODS_SELECTED)
$tRect = DllStructCreate("int;int;int;int")
DllStructSetData($tRect, 1, $nLeft)
DllStructSetData($tRect, 2, $nTop)
DllStructSetData($tRect, 3, $nRight)
DllStructSetData($tRect, 4, $nBottom)
$hBrush = _WinAPI_GetSysColorBrush($COLOR_BTNFACE)
Switch $nCtrlID
Case $nButton
_DrawTria($hDC, _MyTriangle($tRect, 2, 6, 8), $hBrush);绘制三角形边线,2,6,8分别是上中,左下,右下
Case $nButton2
_DrawTria($hDC, _MyTriangle($tRect, 7, 1, 3), $hBrush);绘制三角形边线,7,1,3,分别是下中,左上,右上
EndSwitch
_WinAPI_DrawText($hDC, @LF & GUICtrlRead($nCtrlID), $tRect, BitOR($DT_VCENTER, $DT_CENTER));绘制按钮文字
_WinAPI_DeleteObject($hBrush)
Return 1
EndFunc ;==>DrawButton
Func _MyTriangle($tRect, $T1, $T2, $T3);返回三角形三顶点坐标
Local $tTriA[3][2]
Switch $T1
Case 1
$tTriA[0][0] = DllStructGetData($tRect, 1)
$tTriA[0][1] = DllStructGetData($tRect, 2)
Case 2
$tTriA[0][0] = DllStructGetData($tRect, 3) / 2
$tTriA[0][1] = DllStructGetData($tRect, 2)
Case 3
$tTriA[0][0] = DllStructGetData($tRect, 3) - 1
$tTriA[0][1] = DllStructGetData($tRect, 2)
Case 4
$tTriA[0][0] = DllStructGetData($tRect, 1)
$tTriA[0][1] = DllStructGetData($tRect, 4) / 2
Case 5
$tTriA[0][0] = DllStructGetData($tRect, 3) - 1
$tTriA[0][1] = DllStructGetData($tRect, 4) / 2
Case 6
$tTriA[0][0] = DllStructGetData($tRect, 1)
$tTriA[0][1] = DllStructGetData($tRect, 4) - 1
Case 7
$tTriA[0][0] = DllStructGetData($tRect, 3) / 2
$tTriA[0][1] = DllStructGetData($tRect, 4) - 1
Case 8
$tTriA[0][0] = DllStructGetData($tRect, 3) - 1
$tTriA[0][1] = DllStructGetData($tRect, 4) - 1
EndSwitch
Switch $T2
Case 1
$tTriA[1][0] = DllStructGetData($tRect, 1)
$tTriA[1][1] = DllStructGetData($tRect, 2)
Case 2
$tTriA[1][0] = DllStructGetData($tRect, 3) / 2
$tTriA[1][1] = DllStructGetData($tRect, 2)
Case 3
$tTriA[1][0] = DllStructGetData($tRect, 3) - 1
$tTriA[1][1] = DllStructGetData($tRect, 2)
Case 4
$tTriA[1][0] = DllStructGetData($tRect, 1)
$tTriA[1][1] = DllStructGetData($tRect, 4) / 2
Case 5
$tTriA[1][0] = DllStructGetData($tRect, 3) - 1
$tTriA[1][1] = DllStructGetData($tRect, 4) / 2
Case 6
$tTriA[1][0] = DllStructGetData($tRect, 1)
$tTriA[1][1] = DllStructGetData($tRect, 4) - 1
Case 7
$tTriA[1][0] = DllStructGetData($tRect, 3) / 2
$tTriA[1][1] = DllStructGetData($tRect, 4) - 1
Case 8
$tTriA[1][0] = DllStructGetData($tRect, 3) - 1
$tTriA[1][1] = DllStructGetData($tRect, 4) - 1
EndSwitch
Switch $T3
Case 1
$tTriA[2][0] = DllStructGetData($tRect, 1)
$tTriA[2][1] = DllStructGetData($tRect, 2)
Case 2
$tTriA[2][0] = DllStructGetData($tRect, 3) / 2
$tTriA[2][1] = DllStructGetData($tRect, 2)
Case 3
$tTriA[2][0] = DllStructGetData($tRect, 3) - 1
$tTriA[2][1] = DllStructGetData($tRect, 2)
Case 4
$tTriA[2][0] = DllStructGetData($tRect, 1)
$tTriA[2][1] = DllStructGetData($tRect, 4) / 2
Case 5
$tTriA[2][0] = DllStructGetData($tRect, 3) - 1
$tTriA[2][1] = DllStructGetData($tRect, 4) / 2
Case 6
$tTriA[2][0] = DllStructGetData($tRect, 1)
$tTriA[2][1] = DllStructGetData($tRect, 4) - 1
Case 7
$tTriA[2][0] = DllStructGetData($tRect, 3) / 2
$tTriA[2][1] = DllStructGetData($tRect, 4) - 1
Case 8
$tTriA[2][0] = DllStructGetData($tRect, 3) - 1
$tTriA[2][1] = DllStructGetData($tRect, 4) - 1
EndSwitch
Return $tTriA
EndFunc ;==>_MyTriangle
Func _InflateTriA($tTriA, $Dx, $Dy);三角形缩放,未完成
Local $min, $max
$min = $tTriA[0][0]
$max = $tTriA[0][0]
If $tTriA[1][0] > $min Then
$max = $tTriA[1][0]
Else
$min = $tTriA[1][0]
EndIf
If $tTriA[2][0] > $max Then $max = $tTriA[2][0]
If $tTriA[2][0] < $min Then $min = $tTriA[2][0]
For $ii = 0 To 2
If $tTriA[$ii][0] == $min Then $tTriA[$ii][0] -= $Dx
If $tTriA[$ii][0] == $max Then $tTriA[$ii][0] += $Dx
Next
$min = $tTriA[0][1]
$max = $tTriA[0][1]
If $tTriA[1][1] > $min Then
$max = $tTriA[1][1]
Else
$min = $tTriA[1][1]
EndIf
If $tTriA[2][1] > $max Then $max = $tTriA[2][1]
If $tTriA[2][1] < $min Then $min = $tTriA[2][1]
For $ii = 0 To 2
If $tTriA[$ii][1] == $min Then $tTriA[$ii][1] -= $Dy
If $tTriA[$ii][1] == $max Then $tTriA[$ii][1] += $Dy
Next
Return $tTriA
EndFunc ;==>_InflateTriA
Func _DrawTria($hDC, $tTriA, $hBrush);绘制三角形
Local $hOldBrush = _WinAPI_SelectObject($hDC, $hBrush)
_WinAPI_SetBkMode($hDC, $TRANSPARENT)
_WinAPI_MoveTo($hDC, $tTriA[0][0], $tTriA[0][1])
_WinAPI_LineTo($hDC, $tTriA[1][0], $tTriA[1][1])
_WinAPI_LineTo($hDC, $tTriA[2][0], $tTriA[2][1])
_WinAPI_LineTo($hDC, $tTriA[0][0], $tTriA[0][1])
_WinAPI_SelectObject($hDC, $hOldBrush)
_WinAPI_DeleteObject($hBrush)
EndFunc ;==>_DrawTria
|