请问怎么解决多个图片按钮时的闪烁问题
本帖最后由 cxm23 于 2015-3-15 21:22 编辑在seniors做的office风格TABhttp://www.autoitx.com/forum.php?mod=viewthread&tid=33574&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
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 42, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 42, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 80, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 80, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 117, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 117, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 155, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 155, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 193, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 193, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 230, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 230, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 268, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 268, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 305, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 305, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 343, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 343, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 381, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 381, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 418, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 418, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 456, 116, 33)
$pic_1 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 456, 116, 33)
$tab_2 = GUICtrlCreateTabItem("项目二")
Global $pic_2
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 48, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 48, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 106, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 106, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 165, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 165, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 223, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 223, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 281, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 281, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 339, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 339, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 398, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 398, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic1.bmp", 58, 456, 116, 33)
$pic_2 = GUICtrlCreatePic(@ScriptDir & "\pic2.bmp", 58, 456, 116, 33)
GUICtrlCreateTabItem("")
For $i=0 To 11
GUICtrlSetState($pic_1[$i], $GUI_HIDE)
Next
For $i=0 To 7
GUICtrlSetState($pic_2[$i], $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
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_1
_dButton($pic_1, $pic_1)
Case $pic_2
_dButton($pic_2, $pic_2)
Case $pic_2
_dButton($pic_2, $pic_2)
Case $pic_2
_dButton($pic_2, $pic_2)
Case $pic_2
_dButton($pic_2, $pic_2)
Case $pic_2
_dButton($pic_2, $pic_2)
Case $pic_2
_dButton($pic_2, $pic_2)
Case $pic_2
_dButton($pic_2, $pic_2)
Case $pic_2
_dButton($pic_2, $pic_2)
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
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] = $pic_id Then
GUICtrlSetState ($pic_array[$i],$GUI_SHOW)
GUICtrlSetState ($pic_array[$i],$GUI_HIDE)
Else
GUICtrlSetState ($pic_array[$i],$GUI_SHOW)
GUICtrlSetState ($pic_array[$i],$GUI_HIDE)
EndIf
Next
;~ GUISetState(@SW_UNLOCK, $hGUI)
EndFunc ;==>_dButton 感谢楼主分享,辛苦了。
页:
[1]