本帖最后由 seniors 于 2011-12-6 20:45 编辑
问题描述:下面的代码,自绘按钮能正常运行,但是当点击按住左键不放,移出按钮区域后释放,仍然起作用
把WM_MOUSEMOVE及MOUSELEAVE的return 0,改成
Return _WinAPI_CallWindowProc($CallProc, $hWnd, $Msg, $wParam, $lParam)
让按钮处理函数处理解决问题
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <FontConstants.au3>
#include <WinAPIEx.au3>
#include <GDIPlusEx.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, $hRgn
Global $btnHover = False, $myBtOnID = $nButton
Global $sTrackMouseEvent = DllStructCreate('dword;dword;hwnd;dword')
Global $sTME_size = DllStructGetSize($sTrackMouseEvent)
DllStructSetData($sTrackMouseEvent, 1, $sTME_size)
DllStructSetData($sTrackMouseEvent, 2, 0x00000002)
;TME_CANCEL 0x80000000
;TME_HOVER 0x00000001
;TME_LEAVE 0x00000002
;TME_NONCLIENT 0x00000010
;TME_QUERY 0x40000000
DllStructSetData($sTrackMouseEvent, 4, 50)
Global $sTME_POINTER = DllStructGetPtr($sTrackMouseEvent)
Global $hCallback = DllCallbackRegister("My_btnProc", "int", "hWnd;uint;wparam;lparam")
Global $tCallback = DllCallbackGetPtr($hCallback)
$hGUI = GUICreate("自绘按钮", 300, 200)
$nButton = GUICtrlCreateButton("上", 5, 5, 50, 40)
GUICtrlSetStyle($nButton, $BS_OWNERDRAW) ; 设置自绘标志
$hRgn = _WinAPI_CreatePolygonRgn($aPoint)
_WinAPI_SetWindowRgn(GUICtrlGetHandle($nButton), $hRgn, 1);重设按钮区域
$nButton2 = GUICtrlCreateButton("下", 40, 5, 50, 40)
GUICtrlSetStyle($nButton2, $BS_OWNERDRAW) ; 设置自绘标志
$hRgn2 = _WinAPI_CreatePolygonRgn($bPoint)
_WinAPI_SetWindowRgn(GUICtrlGetHandle($nButton2), $hRgn2, 1);重设按钮区域
;按钮窗口子类化
Global $CallProc = _WinAPI_SetWindowLong(GUICtrlGetHandle($nButton), -4, $tCallback)
_WinAPI_SetWindowLong(GUICtrlGetHandle($nButton2), -4, $tCallback)
;绘制父窗口时不绘制子窗口,即按钮窗口
_WinAPI_SetWindowLong(GUICtrlGetHandle($nButton), -16, BitOR(_WinAPI_GetWindowLong(GUICtrlGetHandle($nButton), -16), $WS_CLIPCHILDREN))
_WinAPI_SetWindowLong(GUICtrlGetHandle($nButton2), -16, BitOR(_WinAPI_GetWindowLong(GUICtrlGetHandle($nButton2), -16), $WS_CLIPCHILDREN))
GUIRegisterMsg($WM_DRAWITEM, "MY_WM_DRAWITEM")
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
_WinAPI_SetWindowLong(GUICtrlGetHandle($nButton), -4, $CallProc)
_WinAPI_SetWindowLong(GUICtrlGetHandle($nButton2), -4, $CallProc)
DllCallbackFree($hCallback)
Exit
Func MY_WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
#forceref $Msg, $wParam, $lParam
Local $stDrawItem = DllStructCreate("uint;uint;uint;uint;uint;uint;uint;int[4];dword", $lParam)
Local Const $ODT_BUTTON = 4
Local $nCtlType = DllStructGetData($stDrawItem, 1)
If $nCtlType = $ODT_BUTTON Then
Local $nCtrlID = DllStructGetData($stDrawItem, 2)
Local $nItemState = DllStructGetData($stDrawItem, 5)
Local $hCtrl = DllStructGetData($stDrawItem, 6)
Local $hDC = DllStructGetData($stDrawItem, 7)
Local $nLeft = DllStructGetData($stDrawItem, 8, 1)
Local $nTop = DllStructGetData($stDrawItem, 8, 2)
Local $nRight = DllStructGetData($stDrawItem, 8, 3)
Local $nBottom = DllStructGetData($stDrawItem, 8, 4)
DrawButton($hWnd, $nCtrlID, $hDC, $nLeft, $nTop, $nRight, $nBottom, $nItemState)
$stDrawItem = 1
Return 0
EndIf
$stDrawItem = 0
Return $GUI_RUNDEFMSG ; Proceed the default Autoit3 internal message commands
EndFunc ;==>MY_WM_DRAWITEM
Func My_btnProc($hWnd, $Msg, $wParam, $lParam)
Switch $Msg
Case 0x200;WM_MOUSEMOVE
If Not $btnHover Then
$btnHover = True
$myBtOnID = _WinAPI_GetDlgCtrlID($hWnd)
_WinAPI_InvalidateRect($hWnd)
EndIf
DllStructSetData($sTrackMouseEvent, 2, 0x00000002)
DllStructSetData($sTrackMouseEvent, 3, $hWnd)
DllCall('user32.dll', 'bool', 'TrackMouseEvent', 'ptr', $sTME_POINTER)
Return _WinAPI_CallWindowProc($CallProc, $hWnd, $Msg, $wParam, $lParam)
Case 0x2A3;WM_MOUSELEAVE
$btnHover = False
$myBtOnID = 0
_WinAPI_InvalidateRect($hWnd)
Return _WinAPI_CallWindowProc($CallProc, $hWnd, $Msg, $wParam, $lParam)
EndSwitch
Return _WinAPI_CallWindowProc($CallProc, $hWnd, $Msg, $wParam, $lParam)
EndFunc ;==>My_btnProc
Func DrawButton($hWnd, $nCtrlID, $hDC, $nLeft, $nTop, $nRight, $nBottom, $nItemState)
Local $tRect = DllStructCreate("int;int;int;int")
DllStructSetData($tRect, 1, $nLeft)
DllStructSetData($tRect, 2, $nTop)
DllStructSetData($tRect, 3, $nRight)
DllStructSetData($tRect, 4, $nBottom)
Switch $nCtrlID
Case $nButton
_DrawTria($hDC, $nCtrlID, _MyTriangle($tRect, 2, 6, 8), $nItemState)
Case $nButton2
_DrawTria($hDC, $nCtrlID, _MyTriangle($tRect, 7, 1, 3), $nItemState)
EndSwitch
Return 1
EndFunc ;==>DrawButton
Func _MyTriangle($tRect, $T1, $T2, $T3);返回三角形三顶点坐标
Local $tTriA[3][2]
Switch $T1
Case 1
$tTriA[0][0] = DllStructGetData($tRect, 1) + 1
$tTriA[0][1] = DllStructGetData($tRect, 2) + 1
Case 2
$tTriA[0][0] = DllStructGetData($tRect, 3) / 2
$tTriA[0][1] = DllStructGetData($tRect, 2) + 1
Case 3
$tTriA[0][0] = DllStructGetData($tRect, 3) - 1
$tTriA[0][1] = DllStructGetData($tRect, 2) + 1
Case 4
$tTriA[0][0] = DllStructGetData($tRect, 1) + 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) + 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) + 1
$tTriA[1][1] = DllStructGetData($tRect, 2) + 1
Case 2
$tTriA[1][0] = DllStructGetData($tRect, 3) / 2
$tTriA[1][1] = DllStructGetData($tRect, 2) + 1
Case 3
$tTriA[1][0] = DllStructGetData($tRect, 3) - 1
$tTriA[1][1] = DllStructGetData($tRect, 2) + 1
Case 4
$tTriA[1][0] = DllStructGetData($tRect, 1) + 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) + 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) + 1
$tTriA[2][1] = DllStructGetData($tRect, 2) + 1
Case 2
$tTriA[2][0] = DllStructGetData($tRect, 3) / 2
$tTriA[2][1] = DllStructGetData($tRect, 2) + 1
Case 3
$tTriA[2][0] = DllStructGetData($tRect, 3) - 1
$tTriA[2][1] = DllStructGetData($tRect, 2) + 1
Case 4
$tTriA[2][0] = DllStructGetData($tRect, 1) + 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) + 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 _DrawTria($hDC, $nCtrlID, $tTriA, $nItemState);绘制三角形
;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)
Local $bHotlight = BitAND($nItemState, $ODS_HOTLIGHT)
_GDIPlus_Startup()
Local $hmenDC = _WinAPI_CreateCompatibleDC($hDC)
Local $hSource = _WinAPI_CreateCompatibleBitmapEx($hDC, 50, 40, _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_3DFACE)))
Local $hSv = _WinAPI_SelectObject($hmenDC, $hSource)
Local $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hmenDC);从DC创建图形对象
;_GDIPlus_GraphicsClear($hGraphic, 0x00000000);清空图形
_GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2);绘制质量 2 - 使用 8 X 8 矩形过滤器
_GDIPlus_GraphicsSetInterpolationMode($hGraphic, 7);插值法 7=High-quality, bicubic interpolation.
Local $hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddLine($hPath, $tTriA[0][0], $tTriA[0][1], $tTriA[1][0], $tTriA[1][1])
_GDIPlus_PathAddLine($hPath, $tTriA[1][0], $tTriA[1][1], $tTriA[2][0], $tTriA[2][1])
_GDIPlus_PathAddLine($hPath, $tTriA[2][0], $tTriA[2][1], $tTriA[0][0], $tTriA[0][1])
Local $tRect = _GDIPlus_RectFCreate(0, 0, 50, 40);设置区域色块
If $bSelected Or $myBtOnID == $nCtrlID Then
$hBrush = _GDIPlus_LineBrushCreateFromRect($tRect, 0x22FF22ff, 0xffFF22ff, 1, 3)
Else
$hBrush = _GDIPlus_LineBrushCreateFromRect($tRect, 0x222277ff, 0xff2277ff, 1, 3);设置渐变画刷
EndIf
DllCall($ghGDIPDll, "uint", "GdipFillPath", "hwnd", $hGraphic, "hwnd", $hBrush, "hwnd", $hPath);用画刷填充路径
_GDIPlus_BrushDispose($hBrush);销毁画刷
Local $hPen = _GDIPlus_PenCreate(0x88000000, 1, 0)
_GDIPlus_PenSetLineJoin($hPen, 2);2 - Line join produces a smooth, circular arc between the lines.
DllCall($ghGDIPDll, "uint", "GdipDrawPath", "hwnd", $hGraphic, "hwnd", $hPen, "hwnd", $hPath)
_GDIPlus_PenDispose($hPen)
If $bFocused Then
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixScale($hMatrix, 0.8, 0.8)
_GDIPlus_MatrixTranslate($hMatrix, 6, 4)
_GDIPlus_PathTransform($hPath, $hMatrix)
$hPen = _GDIPlus_PenCreate(0x99444444, 1, 0)
_GDIPlus_PenSetDashStyle($hPen, $GDIP_DASHSTYLEDASH)
_GDIPlus_PenSetLineJoin($hPen, 2);2 - Line join produces a smooth, circular arc between the lines.
DllCall($ghGDIPDll, "uint", "GdipDrawPath", "hwnd", $hGraphic, "hwnd", $hPen, "hwnd", $hPath)
_GDIPlus_PenDispose($hPen)
_GDIPlus_MatrixDispose($hMatrix)
EndIf
_GDIPlus_PathDispose($hPath)
$hFamily = _GDIPlus_FontFamilyCreate("黑体")
$hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
If $bSelected Then
$tLayout = _GDIPlus_RectFCreate(16, 12)
Else
$tLayout = _GDIPlus_RectFCreate(14, 10)
EndIf
$hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddString($hPath, GUICtrlRead($nCtrlID), $tLayout, $hFamily, 1, 16, 0);读取字体外形为路径;0是正常字,16是字号
DllCall($ghGDIPDll, "uint", "GdipFillPath", "hwnd", $hGraphic, "hwnd", $hBrush, "hwnd", $hPath)
_GDIPlus_PathDispose($hPath)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_WinAPI_TransparentBlt($hDC, 0, 0, 50, 40, $hmenDC, 0, 0, 50, 40, _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_3DFACE)))
;~ _WinAPI_BitBlt($hdc, 0, 0, 50, 40,$hmenDC,0 ,0 , $PATCOPY)
_WinAPI_SelectObject($hmenDC, $hSv)
_WinAPI_DeleteDC($hmenDC)
_WinAPI_DeleteObject($hSource)
_GDIPlus_Shutdown()
EndFunc ;==>_DrawTria
|