本帖最后由 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
|