找回密码
 加入
搜索
查看: 8173|回复: 24

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

 火.. [复制链接]
发表于 2012-6-5 15:48:53 | 显示全部楼层 |阅读模式
本帖最后由 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[0], $startPos[1], $currentPos[0], $currentPos[1], 1, 0xFF)
                                        inviseRect($startPos[0], $startPos[1], $currentPos[0], $currentPos[1], 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

本帖子中包含更多资源

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

×
 楼主| 发表于 2012-6-5 15:50:20 | 显示全部楼层
一不小心发到无意义问题区了,这里重新发一个
发表于 2012-6-5 16:03:36 | 显示全部楼层
似乎少了个函数
发表于 2012-6-5 16:29:33 | 显示全部楼层
GDI邪恶啊 不会
发表于 2012-6-5 17:18:57 | 显示全部楼层
看看autoit3udf.exe里的guibox怎么玩的吧
发表于 2012-6-5 18:57:29 | 显示全部楼层
GDI邪恶啊 不会
ooxxgod 发表于 2012-6-5 16:29



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


#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[0], $aPosMouseInitial[1], $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_LAYERED,$WS_EX_TOPMOST))

    MouseMove($aPosMouseInitial[0]+100, $aPosMouseInitial[1]+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[0] >= $aPosMouseInitial[0]) AND ($aPosMouse[1] >= $aPosMouseInitial[1])
                WinMove($gui_Drag, "", $aPosMouseInitial[0], $aPosMouseInitial[1], $aPosMouse[0] - $aPosMouseInitial[0], $aPosMouse[1] - $aPosMouseInitial[1])
            Case ($aPosMouse[0] < $aPosMouseInitial[0]) AND ($aPosMouse[1] >= $aPosMouseInitial[1])
                WinMove($gui_Drag, "", $aPosMouse[0], $aPosMouseInitial[1], $aPosMouseInitial[0] - $aPosMouse[0], $aPosMouse[1] - $aPosMouseInitial[1])
            Case ($aPosMouse[0] >= $aPosMouseInitial[0]) AND ($aPosMouse[1] < $aPosMouseInitial[1])
                WinMove($gui_Drag, "", $aPosMouseInitial[0], $aPosMouse[1], $aPosMouse[0] - $aPosMouseInitial[0], $aPosMouseInitial[1] - $aPosMouse[1])
            Case ($aPosMouse[0] < $aPosMouseInitial[0]) AND ($aPosMouse[1] < $aPosMouseInitial[1])
                WinMove($gui_Drag, "", $aPosMouse[0], $aPosMouse[1], $aPosMouseInitial[0] - $aPosMouse[0], $aPosMouseInitial[1] - $aPosMouse[1])
        EndSelect

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


Func _Exit()
    Exit
EndFunc

评分

参与人数 1金钱 +18 贡献 +4 收起 理由
lpxx + 18 + 4

查看全部评分

发表于 2012-6-5 19:15:38 | 显示全部楼层
回复 6# happytc


    高人  画后 中间MSG 点击不到
发表于 2012-6-5 19:27:50 | 显示全部楼层
回复  happytc


    高人  画后 中间MSG 点击不到
ooxxgod 发表于 2012-6-5 19:15


没懂你说的啥?点了‘确定’?能呀!
 楼主| 发表于 2012-6-5 21:17:56 | 显示全部楼层
3# hai神少了什么函数啊?
 楼主| 发表于 2012-6-5 21:20:02 | 显示全部楼层
突然懂了3#说的少了个函数是什么意思了,inviseRect函数暂时没有意义,所以没把函数贴出来,可以注释掉。
 楼主| 发表于 2012-6-5 21:21:28 | 显示全部楼层
4#这算不上GDI吧,就是用API函数画四条直线,根据鼠标的移动更新四条直线,思路很简单。
 楼主| 发表于 2012-6-5 21:23:18 | 显示全部楼层
回复 6# happytc
果然邪恶,可是我这个思路更简单,等待大神。
 楼主| 发表于 2012-6-5 21:25:33 | 显示全部楼层
回复 3# haijie1223
那个inviseRect函数可以注释掉不用管,我现在没办法在画最新的矩形时把之前的矩形清除掉,因为这个窗口是直接建立在桌面的,所以没有GUI来进行重绘之类的操作。
发表于 2012-6-5 22:51:02 | 显示全部楼层
本帖最后由 happytc 于 2012-6-5 22:57 编辑

回复 11# whuzqAI


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

在我的“Live Capture”小程序里的‘截图并加标注’模式里,就用到了你一楼提的问题:http://www.autoitx.com/forum.php ... ight=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[1], $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
发表于 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[0], $startPos[1], $currentPos[0], $currentPos[1], 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
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-19 13:23 , Processed in 0.109815 second(s), 29 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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