whuzqAI 发表于 2012-6-5 15:48:53

drawline画出的矩形框重绘问题 [已解决]

本帖最后由 whuzqAI 于 2012-6-8 10:34 编辑


先上图。我想在拖拽鼠标的时候画一个矩形框来表示当前鼠标拖拽选择的区域,用了各种方法刷新重绘,这个矩形框总是达不到理想的左图效果,总是会出现右图的效果。画线用的是_winapi_drawline(),重绘用的是_winapi_redrawwindow()。总感觉重绘函数没什么用,求教大神。程序贴在下面。#include <Misc.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Local $clearRECT = DllStructCreate( "ushort Left;ushort Top;ushort Right;ushort Bottom")
DllStructSetData($clearRECT, 1, 0)
DllStructSetData($clearRECT, 2, 0)
DllStructSetData($clearRECT, 3, @DesktopWidth)
DllStructSetData($clearRECT, 4, @DesktopHeight)

While 1
                If _IsPressed("01") Then
                        $startPos = MouseGetPos()
                        While 1
                              If _IsPressed("01") Then
                                        $currentPos = MouseGetPos()
                                        showRect($startPos, $startPos, $currentPos, $currentPos, 1, 0xFF)
                                        inviseRect($startPos, $startPos, $currentPos, $currentPos, 2, 0xFF)
                              Else
                                        ExitLoop
                              EndIf
                        WEnd
                EndIf
      WEnd

Func showRect($startX, $startY, $endX, $endY, $width, $color)
      $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop)
      $hPen = _WinAPI_CreatePen($PS_SOLID, $width, $color)
      $obj_orig = _WinAPI_SelectObject($hDC, $hPen)
      _WinAPI_DrawLine($hDC, $startX, $startY, $startX, $endY)
      _WinAPI_DrawLine($hDC, $startX, $startY, $endX, $startY)
      _WinAPI_DrawLine($hDC, $endX, $startY, $endX, $endY)
      _WinAPI_DrawLine($hDC, $startX, $endY, $endX, $endY)
      sleep(50)
      _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN)
      _WinAPI_SelectObject($hDC, $obj_orig)
      _WinAPI_DeleteObject($hPen)
      _WinAPI_ReleaseDC(0, $hDC)
EndFunc

whuzqAI 发表于 2012-6-5 15:50:20

一不小心发到无意义问题区了,这里重新发一个

haijie1223 发表于 2012-6-5 16:03:36

似乎少了个函数

ooxxgod 发表于 2012-6-5 16:29:33

GDI邪恶啊 不会{:face (270):}

netegg 发表于 2012-6-5 17:18:57

看看autoit3udf.exe里的guibox怎么玩的吧

happytc 发表于 2012-6-5 18:57:29

GDI邪恶啊 不会
ooxxgod 发表于 2012-6-5 16:29 http://www.autoitx.com/images/common/back.gif


    那就用更邪恶的方式来解决问题,你看看怎么样?


#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Winapi.au3>
#include <Misc.au3>

Opt("GUIOnEventMode", 1)

HotKeySet("{ESC}", "_Exit")

While True
    Sleep(5)
    If _IsPressed("01") Then
      While _IsPressed("01")
            Sleep(5)
      WEnd
      _CreateDragGui()
    EndIf
WEnd


Func _CreateDragGui()
    $aPosMouseInitial = MouseGetPos()
    $gui_Drag = GUICreate("GuiDrag", 100, 100, $aPosMouseInitial, $aPosMouseInitial, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_LAYERED,$WS_EX_TOPMOST))

    MouseMove($aPosMouseInitial+100, $aPosMouseInitial+100,0)

    GUICtrlCreateLabel("", 0, 0, 100, 1)
    GUICtrlSetBkColor(-1, 0xff0000)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)

    GUICtrlCreateLabel("", 0, 0, 1, 100)
    GUICtrlSetBkColor(-1, 0xff0000)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKWIDTH)

    GUICtrlCreateLabel("", 0,99,100,1)
    GUICtrlSetBkColor(-1, 0xff0000)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)

    GUICtrlCreateLabel("", 99,0,1,100)
    GUICtrlSetBkColor(-1, 0xff0000)
    GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKWIDTH)

    GUISetBkColor(0xABCDEF)
    GUISetState(@SW_SHOW)
    _WinAPI_SetLayeredWindowAttributes($gui_Drag, 0xABCDEF, 255)

    While True
      Sleep(5)
      $aPosMouse = MouseGetPos()
      Select
            Case ($aPosMouse >= $aPosMouseInitial) AND ($aPosMouse >= $aPosMouseInitial)
                WinMove($gui_Drag, "", $aPosMouseInitial, $aPosMouseInitial, $aPosMouse - $aPosMouseInitial, $aPosMouse - $aPosMouseInitial)
            Case ($aPosMouse < $aPosMouseInitial) AND ($aPosMouse >= $aPosMouseInitial)
                WinMove($gui_Drag, "", $aPosMouse, $aPosMouseInitial, $aPosMouseInitial - $aPosMouse, $aPosMouse - $aPosMouseInitial)
            Case ($aPosMouse >= $aPosMouseInitial) AND ($aPosMouse < $aPosMouseInitial)
                WinMove($gui_Drag, "", $aPosMouseInitial, $aPosMouse, $aPosMouse - $aPosMouseInitial, $aPosMouseInitial - $aPosMouse)
            Case ($aPosMouse < $aPosMouseInitial) AND ($aPosMouse < $aPosMouseInitial)
                WinMove($gui_Drag, "", $aPosMouse, $aPosMouse, $aPosMouseInitial - $aPosMouse, $aPosMouseInitial - $aPosMouse)
      EndSelect

      If _IsPressed("01") Then
            $aPosWin = WinGetPos($gui_Drag)
            MsgBox(0, "", $aPosWin & "x" & $aPosWin & @CRLF & $aPosWin & "x" & $aPosWin)
            ExitLoop
      EndIf
    WEnd
    GUIDelete()
EndFunc


Func _Exit()
    Exit
EndFunc

ooxxgod 发表于 2012-6-5 19:15:38

回复 6# happytc


    高人画后 中间MSG 点击不到

happytc 发表于 2012-6-5 19:27:50

回复happytc


    高人画后 中间MSG 点击不到
ooxxgod 发表于 2012-6-5 19:15 http://www.autoitx.com/images/common/back.gif

没懂你说的啥?点了‘确定’?能呀!

whuzqAI 发表于 2012-6-5 21:17:56

3# hai神少了什么函数啊?

whuzqAI 发表于 2012-6-5 21:20:02

突然懂了3#说的少了个函数是什么意思了,inviseRect函数暂时没有意义,所以没把函数贴出来,可以注释掉。

whuzqAI 发表于 2012-6-5 21:21:28

4#这算不上GDI吧,就是用API函数画四条直线,根据鼠标的移动更新四条直线,思路很简单。

whuzqAI 发表于 2012-6-5 21:23:18

回复 6# happytc
果然邪恶,可是我这个思路更简单,等待大神。

whuzqAI 发表于 2012-6-5 21:25:33

回复 3# haijie1223
那个inviseRect函数可以注释掉不用管,我现在没办法在画最新的矩形时把之前的矩形清除掉,因为这个窗口是直接建立在桌面的,所以没有GUI来进行重绘之类的操作。

happytc 发表于 2012-6-5 22:51:02

本帖最后由 happytc 于 2012-6-5 22:57 编辑

回复 11# whuzqAI


    给你个好玩的,看明白了下面的,就知道如何整你的一楼的, 若你再不能举一反三的话,就自己Google:双缓冲吧

在我的“Live Capture”小程序里的‘截图并加标注’模式里,就用到了你一楼提的问题:http://www.autoitx.com/forum.php?mod=viewthread&tid=25502&highlight=live%2Bcapture
但我并不想直接把代码发给你,等你看明白下面的代码,才会学得更多

#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)
Global $GuiSizeX = 500, $GuiSizeY = 500, $var = True

$hGui = GUICreate("Double Buffer", $GuiSizeX, $GuiSizeY)
GUISetState(@SW_SHOW, $hGui)

_GDIPlus_Startup()

$hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui)
$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)

$hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)

GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")

While Sleep(10)
    DrawBoy()
WEnd

Func DrawBoy()
        _GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8)
        $pos = MouseGetPos()
    _GDIPlus_GraphicsDrawEllipse ($hGraphic, 100, 70, 50, 50, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, 125, 120, 125, 200, $hPen)

    _GDIPlus_GraphicsDrawLine ($hGraphic, 125, 135, 100, 160, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, 100, 160, 170, $pos, $hPen)

    _GDIPlus_GraphicsDrawLine ($hGraphic, 125, 120, 125, 200, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, 125, 120, 125, 200, $hPen)

    _GDIPlus_GraphicsDrawLine ($hGraphic, 125, 200, 90, 280, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, 125, 200, 160, 280, $hPen)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
EndFunc

Func WM_ERASEBKGND($hWnd, $msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    Return 1
EndFunc

Func _Exit()
    GUIRegisterMsg($WM_ERASEBKGND, "")
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _WinAPI_DeleteObject($hBMPBuff)
    _GDIPlus_Shutdown()
    Exit
EndFunc

298311657 发表于 2012-6-5 23:43:34

回复 14# happytc
这个好玩,涂鸦了一份
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>

$hGui = GUICreate("Double Buffer", @DesktopWidth, @DesktopHeight,0,0,$WS_POPUP)
GUISetState(@SW_SHOW, $hGui)
WinSetTrans($hGui,"",120)
_GDIPlus_Startup()

$hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui)
$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics(@DesktopWidth, @DesktopHeight, $hGraphicGUI)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)

$hPen = _GDIPlus_PenCreate(0xFFFF0000, 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")

Do
        If _IsPressed("01") Then
                $startPos = MouseGetPos()
                While 1
                        If _IsPressed("01") Then
                                $currentPos = MouseGetPos()
                                showRect($startPos, $startPos, $currentPos, $currentPos, 0xFFEFEFEF)
                        Else
                                ExitLoop
                        EndIf
                WEnd
        EndIf
Until GUIGetMsg()=-3

Func showRect($startX, $startY, $endX, $endY, $color)
        _GDIPlus_GraphicsClear($hGraphic, $color)
       
    _GDIPlus_GraphicsDrawLine ($hGraphic, $startX, $startY, $startX, $endY, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, $startX, $startY, $endX, $startY, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, $endX, $startY, $endX, $endY, $hPen)
    _GDIPlus_GraphicsDrawLine ($hGraphic, $startX, $endY, $endX, $endY, $hPen)
        _GDIPlus_GraphicsDrawString($hGraphic, "按 ESC 键退出", $startX, $endY+12)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
EndFunc

Func WM_ERASEBKGND($hWnd, $msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    Return 1
EndFunc

Func _Exit()
    GUIRegisterMsg($WM_ERASEBKGND, "")
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _WinAPI_DeleteObject($hBMPBuff)
    _GDIPlus_Shutdown()
    Exit
EndFunc
页: [1] 2
查看完整版本: drawline画出的矩形框重绘问题 [已解决]