找回密码
 加入
搜索
查看: 3848|回复: 4

[GUI管理] 鼠标右键弹起的作用域,[已解决]

[复制链接]
发表于 2011-12-3 22:27:27 | 显示全部楼层 |阅读模式
本帖最后由 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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2011-12-3 22:39:25 | 显示全部楼层
又更新了,呵呵
发表于 2011-12-4 12:55:47 | 显示全部楼层
这么多代码啊,初学者有点吃力啊
发表于 2011-12-4 21:39:43 | 显示全部楼层
好长的代码.
 楼主| 发表于 2011-12-6 20:47:06 | 显示全部楼层
已经解决,顶一下
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-18 16:37 , Processed in 0.082538 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表