找回密码
 加入
搜索
查看: 2278|回复: 1

[GUI管理] 请问怎么解决多个图片按钮时的闪烁问题

[复制链接]
发表于 2015-3-13 16:23:17 | 显示全部楼层 |阅读模式
本帖最后由 cxm23 于 2015-3-15 21:22 编辑

在seniors做的office风格TABhttp://www.autoitx.com/forum.php ... p;extra=&page=1的界面上放多个图片按钮,结果图片闪烁很严重,而且切换tab时会出现虚线框,不知有什么解决办法?

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <FontConstants.au3>
#include <WinAPIEx.au3>
#include <TabConstants.au3>
#include <GuiTab.au3>
#include <Constants.au3>
#include <GDIPlus.au3>


Global Const $SC_MOVE = 0xF010

Global $hGUI, $GUIMsg
 
Global $TabHover = False, $TABActiveID = 0, $TabHoverID = -1, $Count = 0
Global $WinWidth = 225, $WinHeight = 505, $TabWidth = 100, $TabHeight = 30, $Tabcount = 5
 
Global $hTABCallback = DllCallbackRegister("My_TABProc", "int", "hWnd;uint;wparam;lparam")
Global $tTABCallback = DllCallbackGetPtr($hTABCallback)
 
$hGUI = GUICreate("GUI1", $WinWidth, $WinHeight, -1, -1, BitOR($WS_SYSMENU, $WS_POPUP))

$Label2 = GUICtrlCreateLabel('×', 203, -4, 20, 30, $SS_CENTER)
GUICtrlSetBkColor(-1, 0xBFDBFF)
;~ GUICtrlSetColor(-1, 0xEFEFEF)
GUICtrlSetFont(-1, 20, 400, 0, 'Verdana')
$tab = GUICtrlCreateTab(0, 0, $WinWidth, $WinHeight, BitOR($TCS_FIXEDWIDTH, $TCS_OWNERDRAWFIXED))
$tabHwnd = GUICtrlGetHandle(-1)
_GUICtrlTab_SetItemSize($tab, $TabWidth, $TabHeight)
 
$tab_1 = GUICtrlCreateTabItem("项目一")

Global $pic_1[12][2]
$pic_1[0][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 42, 116, 33)
$pic_1[0][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 42, 116, 33)
$pic_1[1][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 80, 116, 33)
$pic_1[1][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 80, 116, 33)
$pic_1[2][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 117, 116, 33)
$pic_1[2][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 117, 116, 33)
$pic_1[3][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 155, 116, 33)
$pic_1[3][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 155, 116, 33)
$pic_1[4][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 193, 116, 33)
$pic_1[4][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 193, 116, 33)
$pic_1[5][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 230, 116, 33)
$pic_1[5][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 230, 116, 33)
$pic_1[6][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 268, 116, 33)
$pic_1[6][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 268, 116, 33)
$pic_1[7][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 305, 116, 33)
$pic_1[7][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 305, 116, 33)
$pic_1[8][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 343, 116, 33)
$pic_1[8][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 343, 116, 33)
$pic_1[9][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 381, 116, 33)
$pic_1[9][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 381, 116, 33)
$pic_1[10][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 418, 116, 33)
$pic_1[10][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 418, 116, 33)
$pic_1[11][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 456, 116, 33)
$pic_1[11][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 456, 116, 33)


$tab_2 = GUICtrlCreateTabItem("项目二")

Global $pic_2[8][2]
$pic_2[0][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 48, 116, 33)
$pic_2[0][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 48, 116, 33)
$pic_2[1][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 106, 116, 33)
$pic_2[1][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 106, 116, 33)
$pic_2[2][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 165, 116, 33)
$pic_2[2][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 165, 116, 33)
$pic_2[3][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 223, 116, 33)
$pic_2[3][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 223, 116, 33)
$pic_2[4][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 281, 116, 33)
$pic_2[4][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 281, 116, 33)
$pic_2[5][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 339, 116, 33)
$pic_2[5][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 339, 116, 33)
$pic_2[6][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 398, 116, 33)
$pic_2[6][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 398, 116, 33)
$pic_2[7][0] = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 456, 116, 33)
$pic_2[7][1] = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 456, 116, 33)

GUICtrlCreateTabItem("") 


For $i=0 To 11
        GUICtrlSetState($pic_1[$i][1], $GUI_HIDE)
Next

For $i=0 To 7
        GUICtrlSetState($pic_2[$i][1], $GUI_HIDE)
Next
 
$hdisplayDC = _WinAPI_CreateDC()
;初始化选项卡图像DC
$MyhImage = _WinAPI_LoadImage(0, @ScriptDir & "\OFFICE.bmp", $IMAGE_BITMAP, 0, 0, $LR_LOADFROMFILE)
$hBmpDC = _WinAPI_CreateCompatibleDC($hdisplayDC)
$hBmpSv = _WinAPI_SelectObject($hBmpDC, $MyhImage)
_WinAPI_DeleteObject($MyhImage)
;初始化临时DC,也就是二次缓冲,防止闪烁
$hTempDC = _WinAPI_CreateCompatibleDC($hdisplayDC)
$hTempImage = _WinAPI_CreateCompatibleBitmap($hdisplayDC, $TabWidth * $Tabcount, $TabHeight)
$hTempSv = _WinAPI_SelectObject($hTempDC, $hTempImage)
_WinAPI_DeleteObject($hTempImage)
_WinAPI_DeleteDC($hdisplayDC)
 
Global $TABCallProc = _WinAPI_SetWindowLong(GUICtrlGetHandle($tab), -4, $tTABCallback)
GUISetState()
WinSetOnTop($hGUI, "", 1)

While 1

        $GUIMsg = GUIGetMsg()
        Switch $GUIMsg
                                Case $GUI_EVENT_PRIMARYDOWN
                                                _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_MOVE + $HTCAPTION, 0)
                Case $GUI_EVENT_CLOSE
                        _myexitfunc()
                                Case $Label2
                        Exit
                                Case $pic_1[0][0]
                                                _dButton($pic_1, $pic_1[0][0])
                                Case $pic_1[1][0]
                                                _dButton($pic_1, $pic_1[1][0])
                                Case $pic_1[2][0]
                                                _dButton($pic_1, $pic_1[2][0])
                                Case $pic_1[3][0]
                                                _dButton($pic_1, $pic_1[3][0])
                                Case $pic_1[4][0]
                                                _dButton($pic_1, $pic_1[4][0])
                                Case $pic_1[5][0]
                                                _dButton($pic_1, $pic_1[5][0])
                                Case $pic_1[6][0]
                                                _dButton($pic_1, $pic_1[6][0])
                                Case $pic_1[7][0]
                                                _dButton($pic_1, $pic_1[7][0])
                                Case $pic_1[8][0]
                                                _dButton($pic_1, $pic_1[8][0])
                                Case $pic_1[9][0]
                                                _dButton($pic_1, $pic_1[9][0])
                                Case $pic_1[10][0]
                                                _dButton($pic_1, $pic_1[10][0])
                                Case $pic_1[11][0]
                                                _dButton($pic_1, $pic_1[11][0])

                                Case $pic_2[0][0]
                                                _dButton($pic_2, $pic_2[0][0])
                                Case $pic_2[1][0]
                                                _dButton($pic_2, $pic_2[1][0])
                                Case $pic_2[2][0]
                                                _dButton($pic_2, $pic_2[2][0])
                                Case $pic_2[3][0]
                                                _dButton($pic_2, $pic_2[3][0])
                                Case $pic_2[4][0]
                                                _dButton($pic_2, $pic_2[4][0])
                                Case $pic_2[5][0]
                                                _dButton($pic_2, $pic_2[5][0])
                                Case $pic_2[6][0]
                                                _dButton($pic_2, $pic_2[6][0])
                                Case $pic_2[7][0]
                                                _dButton($pic_2, $pic_2[7][0])

        EndSwitch
WEnd
;退出函数,退出前要改回TAB原来的处理函数,不然退出要报错
Func _myexitfunc()
        _WinAPI_SetWindowLong(GUICtrlGetHandle($tab), -4, $TABCallProc)
        DllCallbackFree($hTABCallback)
        ;删除DC
        _WinAPI_SelectObject($hBmpDC, $hBmpSv)
        _WinAPI_DeleteDC($hBmpDC)
        _WinAPI_SelectObject($hTempDC, $hTempSv)
        _WinAPI_DeleteDC($hTempDC)
        Exit
EndFunc   ;==>_myexitfunc

Func My_TABProc($hWnd, $Msg, $wParam, $lParam)
        Switch $Msg
                Case $WM_MOUSEMOVE
                        If Not $TabHover Then;
                                $TabHover = True
                                _WinAPI_TrackMouseEvent($hWnd, 0x00000002)
                        EndIf
                        $mx = _WinAPI_LoWord($lParam)
                        $my = _WinAPI_HiWord($lParam)
                        onMouseMove($hWnd, $mx, $my)
                        Return 0
                Case 0x2A3;WM_MOUSELEAVE
                        $TabHover = False
                        $TabHoverID = -1
                        RedrawAllTAB()
                        Return 0
                Case $WM_ERASEBKGND
                        _JiuGongDraw($wParam, 0, 0, $WinWidth, $WinHeight, $hBmpDC, 19, 25, 1, 2, 0, 0, 0, 0)
                        _JiuGongDraw($wParam, 0, 0, $WinWidth, $TabHeight, $hBmpDC, 0, 0, 1, 27, 0, 0, 0, 1)
                        Return 0
                Case $WM_LBUTTONDOWN
                        $mx = _WinAPI_LoWord($lParam)
                        $my = _WinAPI_HiWord($lParam)
                        onMouseDown($hWnd, $mx, $my)                                
                        Return _WinAPI_CallWindowProc($TABCallProc, $hWnd, $Msg, $wParam, $lParam)
                Case $WM_PAINT
                        If $Count = 0 Then
                                Local $tPAINTSTRUCT, $hDC
                                $Count += 1
                                $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
                                RedrawAllTAB()
                                _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
                                $Count -= 1
                                Return 0
                        EndIf
        EndSwitch
        Return _WinAPI_CallWindowProc($TABCallProc, $hWnd, $Msg, $wParam, $lParam)
EndFunc   ;==>My_TABProc
 
Func onMouseMove($hWnd, $mx, $my)
        If $my <= $TabHeight Then
                $Idx = Int($mx / $TabWidth)
                If $Idx >= 0 And $Idx <= $Tabcount - 1 Then
                        If $Idx <> $TabHoverID Then
                                $TabHoverID = $Idx
                                RedrawAllTAB()
                        EndIf
                Else
                        If $TabHoverID <> -1 Then
                                $TabHoverID = -1
                                RedrawAllTAB()
                        EndIf
                EndIf
        Else
                If $TabHoverID >= 0 Then
                        $TabHoverID = -1
                        RedrawAllTAB()
                EndIf
        EndIf
EndFunc   ;==>onMouseMove
 
Func onMouseDown($hWnd, $mx, $my)
        If $my <= $TabHeight Then
                $Idx = Int($mx / $TabWidth)
                If $Idx >= 0 And $Idx <= $Tabcount - 1 Then
                        $TABActiveID = $Idx
                EndIf
        EndIf
EndFunc   ;==>onMouseDown
 
Func RedrawAllTAB()
        For $i = 0 To $Tabcount - 1
                If $i = $TabHoverID Then
                        $stata = 1
                Else
                        $stata = 0
                EndIf
                DrawTAB($hTempDC, $i, $stata, $i * $TabWidth, 0, $TabWidth, $TabHeight)
        Next
        $hDC = _WinAPI_GetDC($tabHwnd)
        _WinAPI_BitBlt($hDC, 0, 0, $TabWidth * $Tabcount, $TabHeight, $hTempDC, 0, 0, $SRCCOPY)
        _WinAPI_ReleaseDC($tabHwnd, $hDC)
EndFunc   ;==>RedrawAllTAB
 
Func DrawTAB($hDC, $nTabID, $TabState, $nLeft, $nTop, $nRight, $nBottom)
        ;这里的数字是由于图像文件决定的
        If $nTabID = $TABActiveID Then;相等就是当前选项卡
                _JiuGongDraw($hDC, $nLeft, $nTop, $nRight, $nBottom, $hBmpDC, 13 + $TabState * 13, 0, 13, 27, 6, 5, 6, 2);$TabState是Hover标志
        Else
                If $TabState = 0 Then
                        _JiuGongDraw($hDC, $nLeft, $nTop, $nRight, $nBottom, $hBmpDC, 0, 0, 1, 27, 0, 0, 0, 1)
                Else
                        _JiuGongDraw($hDC, $nLeft, $nTop, $nRight, $nBottom, $hBmpDC, 0, 0, 13, 27, 6, 5, 6, 2)
                EndIf
        EndIf
        ;绘制选项卡文字
        $tRECT = DllStructCreate($tagRect)
        DllStructSetData($tRECT, "Left", $nLeft)
        DllStructSetData($tRECT, "Top", $nTop)
        DllStructSetData($tRECT, "Right", $nRight + $nLeft)
        DllStructSetData($tRECT, "Bottom", $nBottom)
        _WinAPI_SetBkMode($hDC, $TRANSPARENT)
        $hFont = _WinAPI_CreateFont(14, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _
                        $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')
        $hOldFont = _WinAPI_SelectObject($hDC, $hFont)
        _WinAPI_DrawText($hDC, _GUICtrlTab_GetItemText($tab, $nTabID), $tRECT, BitOR($DT_CENTER, $DT_VCENTER, $DT_SINGLELINE))
        _WinAPI_SelectObject($hDC, $hOldFont)
        _WinAPI_DeleteObject($hFont)
        Return 1
EndFunc   ;==>DrawTAB
 
;九宫格绘图,参数依次为:目标DC,左,上,长,高,图像DC,左,上,长,高,左上角的长,左上角的高,右下角的长,右下角的高
Func _JiuGongDraw($hDC, $dstX, $dstY, $dstWidth, $dstHeight, $hSrcDC, $SrcX, $SrcY, $srcWidth, $srcHeight, $gX1 = 0, $gY1 = 0, $gX2 = 0, $gY2 = 0)
        If $dstWidth = 0 Or $dstHeight = 0 Or $srcWidth = 0 Or $srcHeight = 0 Then Return
        Local $hmenDC = _WinAPI_CreateCompatibleDC($hDC)
        Local $hSource = _WinAPI_CreateCompatibleBitmap($hDC, $dstWidth, $dstHeight)
        Local $hSv = _WinAPI_SelectObject($hmenDC, $hSource)
        If $gX1 <= 0 And $gX2 <= 0 And $gY1 <= 0 And $gY2 <= 0 Then
                _WinApi_StretchBlt($hmenDC, 0, 0, $dstWidth, $dstHeight, $hSrcDC, $SrcX + $gX1, $SrcY + $gY1, $srcWidth - $gX2, $srcHeight - $gY2, $SRCCOPY)
        Else
                If $gX1 > 0 And $gY1 > 0 Then ;左上角
                        _WinAPI_BitBlt($hmenDC, 0, 0, $gX1, $gY1, $hSrcDC, $SrcX, $SrcY, $SRCCOPY)
                EndIf
                If $gX2 > 0 And $gY1 > 0 Then ;右上角
                        _WinAPI_BitBlt($hmenDC, $dstWidth - $gX2, 0, $gX2, $gY1, $hSrcDC, $SrcX + $srcWidth - $gX2, $SrcY, $SRCCOPY)
                EndIf
                If $gX1 > 0 And $gY2 > 0 Then ;左下角
                        _WinAPI_BitBlt($hmenDC, 0, $dstHeight - $gY2, $gX1, $gY2, $hSrcDC, $SrcX, $SrcY + $srcHeight - $gY2, $SRCCOPY)
                EndIf
                If $gX2 > 0 And $gY2 > 0 Then ;右下角
                        _WinAPI_BitBlt($hmenDC, $dstWidth - $gX2, $dstHeight - $gY2, $gX2, $gY2, $hSrcDC, $SrcX + $srcWidth - $gX2, $SrcY + $srcHeight - $gY2, $SRCCOPY)
                EndIf
                If $gX1 > 0 Then ;左边框
                        _WinApi_StretchBlt($hmenDC, 0, $gY1, $gX1, $dstHeight - $gY1 - $gY2, $hSrcDC, $SrcX, $SrcY + $gY1, $gX1, $srcHeight - $gY1 - $gY2, $SRCCOPY)
                EndIf
                If $gX2 > 0 Then ;右边框
                        _WinApi_StretchBlt($hmenDC, $dstWidth - $gX2, $gY1, $gX2, $dstHeight - $gY1 - $gY2, $hSrcDC, $SrcX + $srcWidth - $gX2, $SrcY + $gY1, $gX2, $srcHeight - $gY1 - $gY2, $SRCCOPY)
                EndIf
                If $gY1 > 0 Then ;上边框
                        _WinApi_StretchBlt($hmenDC, $gX1, 0, $dstWidth - $gX1 - $gX2, $gY1, $hSrcDC, $SrcX + $gX1, $SrcY, $srcWidth - $gX1 - $gX2, $gY1, $SRCCOPY)
                EndIf
                If $gY2 > 0 Then ;下边框
                        _WinApi_StretchBlt($hmenDC, $gX1, $dstHeight - $gY2, $dstWidth - $gX1 - $gX2, $gY2, $hSrcDC, $SrcX + $gX1, $SrcY + $srcHeight - $gY2, $srcWidth - $gX1 - $gX2, $gY2, $SRCCOPY)
                EndIf
                ;中间的伸展部分
                _WinApi_StretchBlt($hmenDC, $gX1, $gY1, $dstWidth - $gX1 - $gX2, $dstHeight - $gY1 - $gY2, $hSrcDC, $SrcX + $gX1, $SrcY + $gY1, $srcWidth - $gX1 - $gX2, $srcHeight - $gY1 - $gY2, $SRCCOPY)
        EndIf
        _WinAPI_BitBlt($hDC, $dstX, $dstY, $dstWidth, $dstHeight, $hmenDC, 0, 0, $SRCCOPY)
        _WinAPI_SelectObject($hmenDC, $hSv)
        _WinAPI_DeleteObject($hSource)
        _WinAPI_DeleteDC($hmenDC)
EndFunc   ;==>_JiuGongDraw
 
Func _WinAPI_CreateDC()
        Local $aResult = DllCall("gdi32.dll", "handle", "CreateDC", "str", "DISPLAY", "str", "", "str", "", "ptr", 0)
        If @error Then Return SetError(@error, @extended, 0)
        Return $aResult[0]
EndFunc   ;==>_WinAPI_CreateDC




Func _dButton($pic_array, $pic_id)
;~         GUISetState(@SW_LOCK, $hGUI)
        $count = UBound($pic_array, 1)
        For        $i = 0 To $count -1
                If $pic_array[$i][0] = $pic_id Then
                        GUICtrlSetState ($pic_array[$i][1],$GUI_SHOW)
                        GUICtrlSetState ($pic_array[$i][0],$GUI_HIDE)
                Else
                        GUICtrlSetState ($pic_array[$i][0],$GUI_SHOW)
                        GUICtrlSetState ($pic_array[$i][1],$GUI_HIDE)
                EndIf
        Next
;~         GUISetState(@SW_UNLOCK, $hGUI)
EndFunc   ;==>_dButton

本帖子中包含更多资源

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

×
发表于 2015-3-16 09:55:49 | 显示全部楼层
感谢楼主分享,辛苦了。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-4 11:28 , Processed in 0.076668 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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