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

[GUI管理] 编辑框背景透明的代码不起作用的问题

[复制链接]
发表于 2014-10-10 23:32:34 | 显示全部楼层 |阅读模式
本帖最后由 gto250 于 2014-10-10 23:48 编辑

在网上下载了一个vb的编辑框背景透明的源码,它的原理就获取编辑框所在的窗体中的图片,拷贝编辑框所在位置的图片到编辑框上。
试着将vb的代码改成au3的代码,但是运行的结果是不起作用。
vb的代码是拷贝窗体的图片,我改成了直接拷贝窗体
希望坛里的兄弟帮忙看看问题出在哪里。
au3版本 3.3.13.19


Global Const $GWL_WNDPROC = 0xFFFFFFFC
Global Const $WM_COMMAND = 0x0111
Global Const $WM_CTLCOLOREDIT = 0x0133
Global Const $WM_DESTROY = 0x0002
Global Const $WM_ERASEBKGND = 0x0014
Global Const $WM_HSCROLL = 0x0114
Global Const $WM_VSCROLL = 0x0115
Global Const $SRCCOPY = 0x00CC0020

Global Const $tagRECT = "struct; long Left;long Top;long Right;long Bottom; endstruct"



$Form1 = GUICreate("Form1", 615, 438, 192, 124)
$Input1 = GUICtrlCreateInput("Input1", 152, 104, 193, 21)
$Button1 = GUICtrlCreateButton("Button1", 200, 168, 75, 25)
MakeTransparentTextbox($Input1)
GUISetState(@SW_SHOW)


While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case -3
                        Exit
                Case $Button1

                        
        EndSwitch
WEnd


#cs
Public Function MakeTransparentTextbox(aTxt As TextBox)

  CreateBGBrush aTxt
  

  If GetProp(GetParent(aTxt.hwnd), "OrigProcAddr") = 0 Then
    SetProp GetParent(aTxt.hwnd), "OrigProcAddr", SetWindowLong(GetParent(aTxt.hwnd), GWL_WNDPROC, AddressOf NewWindowProc)
  End If

  If GetProp(aTxt.hwnd, "OrigProcAddr") = 0 Then
    SetProp aTxt.hwnd, "OrigProcAddr", SetWindowLong(aTxt.hwnd, GWL_WNDPROC, AddressOf NewTxtBoxProc)
  End If
  
End Function
#ce
Func MakeTransparentTextbox($Input_id)
$Input_hwnd=GUICtrlGetHandle($Input_id)        

$NewWindowProcNew = DllCallbackRegister("NewWindowProc", "ptr", "hwnd;uint;long;ptr")
$NewTxtBoxProcNew = DllCallbackRegister("NewTxtBoxProc", "ptr", "hwnd;uint;long;ptr")

 CreateBGBrush($Input_id)
 
  If GetProp(GetParent($Input_hwnd), "OrigProcAddr") = 0 Then
    SetProp(GetParent($Input_hwnd), "OrigProcAddr", SetWindowLong(GetParent($Input_hwnd), $GWL_WNDPROC, DllCallbackGetPtr($NewWindowProcNew)))
  EndIf

  If GetProp($Input_hwnd, "OrigProcAddr") = 0 Then
    SetProp($Input_hwnd, "OrigProcAddr", SetWindowLong($Input_hwnd, $GWL_WNDPROC, DllCallbackGetPtr($NewTxtBoxProcNew)))
  EndIf
EndFunc

#cs
Private Sub CreateBGBrush(aTxtBox As TextBox)

  Dim screenDC As Long
  Dim imgLeft As Long
  Dim imgTop As Long
  Dim picDC As Long
  Dim picBmp As Long
  Dim aTempBmp As Long
  Dim aTempDC As Long
  Dim txtWid As Long
  Dim txtHgt As Long
  Dim SolidBrush As Long
  Dim aRect As RECT
  
  If aTxtBox.Parent.Picture Is Nothing Then Exit Sub
  
  txtWid = aTxtBox.Width / Screen.TwipsPerPixelX
  txtHgt = aTxtBox.Height / Screen.TwipsPerPixelY
  imgLeft = aTxtBox.Left / Screen.TwipsPerPixelX
  imgTop = aTxtBox.Top / Screen.TwipsPerPixelY
  
  screenDC = GetDC(0)
  picDC = CreateCompatibleDC(screenDC)
  picBmp = SelectObject(picDC, aTxtBox.Parent.Picture.Handle)

  aTempDC = CreateCompatibleDC(screenDC)
  aTempBmp = CreateCompatibleBitmap(screenDC, txtWid, txtHgt)
                                                                  
  DeleteObject SelectObject(aTempDC, aTempBmp)
                                                  
  

  BitBlt aTempDC, 0, 0, txtWid, txtHgt, picDC, imgLeft, imgTop, vbSrcCopy
  

  If GetProp(aTxtBox.hwnd, "CustomBGBrush") <> 0 Then
    DeleteObject GetProp(aTxtBox.hwnd, "CustomBGBrush")
  End If
  SetProp aTxtBox.hwnd, "CustomBGBrush", CreatePatternBrush(aTempBmp)
  

  DeleteDC aTempDC
  DeleteObject aTempBmp
  SelectObject picDC, picBmp
  DeleteDC picDC
  DeleteObject picBmp
  ReleaseDC 0, screenDC
  
End Sub
#ce
Func CreateBGBrush($Input_id)
 
  $Input_hwnd=GUICtrlGetHandle($Input_id)
  $NewRect=GetWindowRect ($Input_hwnd)
  
  $txtWid = DllStructGetData($NewRect,"Right")-DllStructGetData($NewRect,"Left")
  $txtHgt = DllStructGetData($NewRect,"Bottom")-DllStructGetData($NewRect,"Top")
  
  ScreenToClient (GetParent ($Input_hwnd),$NewRect)
  
  $imgLeft = DllStructGetData($NewRect,"Left")
  $imgTop = DllStructGetData($NewRect,"Top")
  
  
  
  $screenDC = GetDC(0)
  $picDC = CreateCompatibleDC($screenDC)
  $picBmp = SelectObject($picDC, GetParent ($Input_hwnd))

  $aTempDC = CreateCompatibleDC($screenDC)
  $aTempBmp = CreateCompatibleBitmap($screenDC, $txtWid, $txtHgt)
                                                                  
  DeleteObject(SelectObject($aTempDC, $aTempBmp))
                                                  
  

  BitBlt($aTempDC, 0, 0, $txtWid, $txtHgt, $picDC, $imgLeft, $imgTop, $SRCCOPY)
  

  If GetProp($Input_hwnd, "CustomBGBrush") <> 0 Then
    DeleteObject(GetProp($Input_hwnd, "CustomBGBrush"))
  EndIf
  SetProp($Input_hwnd, "CustomBGBrush", CreatePatternBrush($aTempBmp)) 
  

  DeleteDC($aTempDC)
  DeleteObject($aTempBmp)
  SelectObject($picDC, $picBmp)
  DeleteDC($picDC)
  DeleteObject($picBmp)
  ReleaseDC(0, $screenDC)        
        
EndFunc



#cs
Private Function NewWindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  
  Dim origProc As Long
  Dim isSubclassed As Long
  
  origProc = GetProp(hwnd, "OrigProcAddr")
  
  If origProc <> 0 Then
  
    If (uMsg = WM_CTLCOLOREDIT) Then
      isSubclassed = (GetProp(lParam, "OrigProcAddr") <> 0)
      If isSubclassed Then
        CallWindowProc origProc, hwnd, uMsg, wParam, lParam
        SetBkMode wParam, 1
        NewWindowProc = GetProp(lParam, "CustomBGBrush")
      Else
        NewWindowProc = CallWindowProc(origProc, hwnd, uMsg, wParam, lParam)
      End If
      
    ElseIf uMsg = WM_COMMAND Then
      isSubclassed = (GetProp(lParam, "OrigProcAddr") <> 0)
      If isSubclassed Then
        LockWindowUpdate GetParent(lParam)
        InvalidateRect lParam, 0&, 1&
        UpdateWindow lParam
      End If
      NewWindowProc = CallWindowProc(origProc, hwnd, uMsg, wParam, lParam)
      If isSubclassed Then LockWindowUpdate 0&
      
    ElseIf uMsg = WM_DESTROY Then
    
      SetWindowLong hwnd, GWL_WNDPROC, origProc
      NewWindowProc = CallWindowProc(origProc, hwnd, uMsg, wParam, lParam)
      RemoveProp hwnd, "OrigProcAddr"
      
    Else
      NewWindowProc = CallWindowProc(origProc, hwnd, uMsg, wParam, lParam)
    End If
  Else

    NewWindowProc = DefWindowProc(hwnd, uMsg, wParam, lParam)
  End If
  
End Function
#ce

Func NewWindowProc($hwnd, $uMsg, $wParam, $lParam)
  $origProc = GetProp(hwnd, "OrigProcAddr")
  
  If $origProc <> 0 Then
  
    If ($uMsg = $WM_CTLCOLOREDIT) Then
      $isSubclassed = (GetProp($lParam, "OrigProcAddr") <> 0)
      If $isSubclassed Then
        CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
        SetBkMode($wParam, 1)
        Return GetProp($lParam, "CustomBGBrush")
      Else
        Return CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
      EndIf
      
    ElseIf $uMsg = $WM_COMMAND Then
      $isSubclassed = (GetProp($lParam, "OrigProcAddr") <> 0)
      If $isSubclassed Then
        LockWindowUpdate( GetParent($lParam))
        InvalidateRect ($lParam, 0, 1)
        UpdateWindow ($lParam)
      EndIf
      Return CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
      If $isSubclassed Then LockWindowUpdate(0)
      
    ElseIf $uMsg = $WM_DESTROY Then
    
      SetWindowLong ($hwnd, $GWL_WNDPROC, $origProc)
       Return CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
      RemoveProp ($hwnd, "OrigProcAddr")
      
    Else
      Return CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
    EndIf
  Else

    Return DefWindowProc($hwnd, $uMsg, $wParam, $lParam)
  EndIf

EndFunc

#cs
Private Function NewTxtBoxProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 
  Dim aRect As RECT
  Dim origProc As Long
  Dim aBrush As Long
  

  origProc = GetProp(hwnd, "OrigProcAddr")
  
  If origProc <> 0 Then
    If uMsg = WM_ERASEBKGND Then
      aBrush = GetProp(hwnd, "CustomBGBrush")
      If aBrush <> 0 Then
        GetClientRect hwnd, aRect
        FillRect wParam, aRect, aBrush
        NewTxtBoxProc = 1
      Else
        NewTxtBoxProc = CallWindowProc(origProc, hwnd, uMsg, wParam, lParam)
      End If
      
    ElseIf uMsg = WM_HSCROLL Or uMsg = WM_VSCROLL Then

      LockWindowUpdate GetParent(hwnd)
      NewTxtBoxProc = CallWindowProc(origProc, hwnd, uMsg, wParam, lParam)
      InvalidateRect hwnd, 0&, 1&
      UpdateWindow hwnd
      LockWindowUpdate 0&
      
    ElseIf uMsg = WM_DESTROY Then
    
      aBrush = GetProp(hwnd, "CustomBGBrush")
      DeleteObject aBrush
      RemoveProp hwnd, "OrigProcAddr"
      RemoveProp hwnd, "CustomBGBrush"
      SetWindowLong hwnd, GWL_WNDPROC, origProc
      NewTxtBoxProc = CallWindowProc(origProc, hwnd, uMsg, wParam, lParam)
      
    Else
      NewTxtBoxProc = CallWindowProc(origProc, hwnd, uMsg, wParam, lParam)
    End If
  Else
    NewTxtBoxProc = DefWindowProc(hwnd, uMsg, wParam, lParam)
  End If
  
End Function
#ce
Func NewTxtBoxProc($hwnd, $uMsg, $wParam, $lParam)

  $origProc = GetProp($hwnd, "OrigProcAddr")
  
  If $origProc <> 0 Then
    If $uMsg = $WM_ERASEBKGND Then
      $aBrush = GetProp($hwnd, "CustomBGBrush")
      If $aBrush <> 0 Then
       $aRect= GetClientRect($hwnd) 
           
        FillRect($wParam, $aRect, $aBrush)
        Return 1
      Else
        Return CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
      EndIf
      
    ElseIf $uMsg = $WM_HSCROLL Or $uMsg = $WM_VSCROLL Then

      LockWindowUpdate (GetParent(hwnd))
      Return CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
      InvalidateRect ($hwnd, 0, 1)
      UpdateWindow (hwnd)
      LockWindowUpdate (0)
      
    ElseIf $uMsg = $WM_DESTROY Then
    
      $aBrush = GetProp($hwnd, "CustomBGBrush")
      DeleteObject ($aBrush)
      RemoveProp ($hwnd, "OrigProcAddr")
      RemoveProp ($hwnd, "CustomBGBrush")
      SetWindowLong ($hwnd, $GWL_WNDPROC, $origProc)
     Return CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
      
    Else
      Return CallWindowProc($origProc, $hwnd, $uMsg, $wParam, $lParam)
    EndIf
  Else
    Return DefWindowProc($hwnd, $uMsg, $wParam, $lParam)
  EndIf

EndFunc



Func GetWindowRect($hWnd)
        Local $tRECT = DllStructCreate($tagRECT)
        Local $aRet = DllCall("user32.dll", "bool", "GetWindowRect", "hwnd", $hWnd, "struct*", $tRECT)
        If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)

        Return $tRECT
EndFunc   ;==>GetWindowRect

Func ScreenToClient($hWnd, ByRef $tPoint)
        Local $aResult = DllCall("user32.dll", "bool", "ScreenToClient", "hwnd", $hWnd, "struct*", $tPoint)
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>ScreenToClient

Func SetWindowLong($hWnd, $iIndex, $iValue)
        SetLastError(0) ; as suggested in MSDN
        Local $sFuncName = "SetWindowLongW"
        If @AutoItX64 Then $sFuncName = "SetWindowLongPtrW"
        Local $aResult = DllCall("user32.dll", "long_ptr", $sFuncName, "hwnd", $hWnd, "int", $iIndex, "long_ptr", $iValue)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>SetWindowLong

Func CallWindowProc($pPrevWndFunc, $hWnd, $iMsg, $wParam, $lParam)
        Local $aResult = DllCall("user32.dll", "lresult", "CallWindowProc", "ptr", $pPrevWndFunc, "hwnd", $hWnd, "uint", $iMsg, _
                        "wparam", $wParam, "lparam", $lParam)
        If @error Then Return SetError(@error, @extended, -1)

        Return $aResult[0]
EndFunc   ;==>CallWindowProc

Func DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
        Local $aResult = DllCall("user32.dll", "lresult", "DefWindowProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, _
                        "lparam", $lParam)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>DefWindowProc

Func BitBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iROP)
        Local $aResult = DllCall("gdi32.dll", "bool", "BitBlt", "handle", $hDestDC, "int", $iXDest, "int", $iYDest, "int", $iWidth, _
                        "int", $iHeight, "handle", $hSrcDC, "int", $iXSrc, "int", $iYSrc, "dword", $iROP)
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>BitBlt

Func CreateCompatibleBitmap($hDC, $iWidth, $iHeight)
        Local $aResult = DllCall("gdi32.dll", "handle", "CreateCompatibleBitmap", "handle", $hDC, "int", $iWidth, "int", $iHeight)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>CreateCompatibleBitmap

Func CreateCompatibleDC($hDC)
        Local $aResult = DllCall("gdi32.dll", "handle", "CreateCompatibleDC", "handle", $hDC)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>CreateCompatibleDC

Func CreatePatternBrush($hBitmap)
        Local $aResult = DllCall("gdi32.dll", "handle", "CreatePatternBrush", "handle", $hBitmap)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>CreatePatternBrush

Func CreateSolidBrush($iColor)
        Local $aResult = DllCall("gdi32.dll", "handle", "CreateSolidBrush", "INT", $iColor)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>CreateSolidBrush

Func DeleteDC($hDC)
        Local $aResult = DllCall("gdi32.dll", "bool", "DeleteDC", "handle", $hDC)
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>DeleteDC

Func DeleteObject($hObject)
        Local $aResult = DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hObject)
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>DeleteObject

Func GetDC($hWnd)
        Local $aResult = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hWnd)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>GetDC

Func GetSysColor($iIndex)
        Local $aResult = DllCall("user32.dll", "INT", "GetSysColor", "int", $iIndex)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>GetSysColor

Func ReleaseDC($hWnd, $hDC)
        Local $aResult = DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWnd, "handle", $hDC)
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>ReleaseDC

Func SelectObject($hDC, $hGDIObj)
        Local $aResult = DllCall("gdi32.dll", "handle", "SelectObject", "handle", $hDC, "handle", $hGDIObj)
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>SelectObject

Func GetProp($hWnd, $sProperty)
        Local $iResult = DllCall("User32.dll", "long", "GetPropW", "hwnd", $hWnd, "wstr", $sProperty)
        Return $iResult[0]
EndFunc  

Func SetProp($hWnd, $sProperty, $vData)
        Local $iResult = DllCall("User32.dll", "bool", "SetPropW", "hwnd", $hWnd, "wstr", $sProperty, "long", $vData)
        Return $iResult[0]
EndFunc  

Func RemoveProp($hWnd, $sProperty)
        Local $iResult = DllCall("User32.dll", "bool", "RemovePropW", "hwnd", $hWnd, "wstr", $sProperty)
        Return $iResult[0]
EndFunc  

Func FillRect($hDC, $pRECT, $hBrush)
        Local $aResult
        If IsPtr($hBrush) Then
                $aResult = DllCall("user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $pRECT, "handle", $hBrush)
        Else
                $aResult = DllCall("user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $pRECT, "dword_ptr", $hBrush)
        EndIf
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>FillRect

Func GetClientRect($hWnd)
        Local $tRECT = DllStructCreate($tagRECT)
        Local $aRet = DllCall("user32.dll", "bool", "GetClientRect", "hwnd", $hWnd, "struct*", $tRECT)
        If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)

        Return $tRECT
EndFunc   ;==>GetClientRect

Func GetParent($hWnd)
        Local $aResult = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", $hWnd)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>GetParent

Func InvalidateRect($hWnd, $tRECT = 0, $bErase = True)
        Local $aResult = DllCall("user32.dll", "bool", "InvalidateRect", "hwnd", $hWnd, "struct*", $tRECT, "bool", $bErase)
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>InvalidateRect

Func LockWindowUpdate($hWnd)
        Local $aRet = DllCall('user32.dll', 'bool', 'LockWindowUpdate', 'hwnd', $hWnd)
        If @error Then Return SetError(@error, @extended, False)
        ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

        Return $aRet[0]
EndFunc   ;==>LockWindowUpdate

Func SetBkMode($hDC, $iBkMode)
        Local $aResult = DllCall("gdi32.dll", "int", "SetBkMode", "handle", $hDC, "int", $iBkMode)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aResult[0]
EndFunc   ;==>SetBkMode

Func UpdateWindow($hWnd)
        Local $aResult = DllCall("user32.dll", "bool", "UpdateWindow", "hwnd", $hWnd)
        If @error Then Return SetError(@error, @extended, False)

        Return $aResult[0]
EndFunc   ;==>UpdateWindow

Func WindowFromDC($hDC)
        Local $aRet = DllCall('user32.dll', 'hwnd', 'WindowFromDC', 'handle', $hDC)
        If @error Then Return SetError(@error, @extended, 0)

        Return $aRet[0]
EndFunc   ;==>WindowFromDC

Func SetLastError($iErrorCode, Const $_iCurrentError = @error, Const $_iCurrentExtended = @extended)
        DllCall("kernel32.dll", "none", "SetLastError", "dword", $iErrorCode)
        Return SetError($_iCurrentError, $_iCurrentExtended, Null)
EndFunc   ;==>SetLastError
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-4-29 19:30 , Processed in 0.073843 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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