[RESOLVED] Semi-Transparent Form
I've googled many procedures for this, and none of them work, information below.
Code:
'''WS_EX_LAYERED = &H80000
'''GWL_EXSTYLE = (-20)
'''Both these are properly defined constants
Dim lReturn As Long, lStyle As Long
lStyle = GetWindowLong(Me.hwnd, GWL_EXSTYLE)
'-->This seems to return everything OK
If Not (lStyle And WS_EX_LAYERED = WS_EX_LAYERED) Then
lStyle = Style Or WS_EX_LAYERED
lReturn = SetWindowLong(Me.hwnd, GWL_EXSTYLE, lStyle)
'-->SetWindowLong Returns 0, which apparently means an error
lReturn = GetLastError
'-->GetLastError, also returns 0?
End If
So, the basis of the question is, Why isn't SetWindowLong working?
Its just a plain form, Fixed ToolDialog border.
Re: Semi-Transparent Form
It isn't surprising that GetLastError returns 0, because it usually does in VB.
Instead of that, use Err.LastDllError
Re: Semi-Transparent Form
Never knew that existed, thanks :D
But alas, it still returns 0, and still doesn't actually set anything :(
Re: Semi-Transparent Form
This works:
Code:
'Declarations
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, ByVal crey As Byte, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const MF_BYPOSITION = &H400&
Private Const GWL_EXSTYLE = (-20)
Private Const WS_EX_LAYERED = &H80000
Private Const WS_EX_TRANSPARENT = &H20&
Private Const LWA_ALPHA = &H2&
Private Const HWND_TOPMOST = -1
Dim bTrans As Byte
'Form Load Code:
bTrans = 127
lOldStyle = SetWindowLong(Me.hwnd, GWL_EXSTYLE, WS_EX_LAYERED)
SetLayeredWindowAttributes Me.hwnd, 0, bTrans, LWA_ALPHA
The value of "bTrans" determines the transparency. I used 127 which is 50%. The valid range is 0 to 255.
Re: Semi-Transparent Form
Thanks, i think i finally figured it out, and since storm's code was much less than i had, it helped there too. I think my problem was i was firing this code a millisecond before my form was actually shown, so it may have had problems with the handle (although, other handles returned fine) I moved my execution around a bit and it seems to work fine now
Re: Semi-Transparent Form
Quote:
Originally Posted by
Teseng
I've googled many procedures for this, and none of them work, information below.
Code:
'''WS_EX_LAYERED = &H80000
'''GWL_EXSTYLE = (-20)
'''Both these are properly defined constants
Dim lReturn As Long, lStyle As Long
lStyle = GetWindowLong(Me.hwnd, GWL_EXSTYLE)
'-->This seems to return everything OK
If Not (lStyle And WS_EX_LAYERED = WS_EX_LAYERED) Then
lStyle = Style Or WS_EX_LAYERED
lReturn = SetWindowLong(Me.hwnd, GWL_EXSTYLE, lStyle)
'-->SetWindowLong Returns 0, which apparently means an error
lReturn = GetLastError
'-->GetLastError, also returns 0?
End If
So, the basis of the question is, Why isn't SetWindowLong working?
Its just a plain form, Fixed ToolDialog border.
1. Layered windows only apply to Win2K and above
2. Typo, missing the l in Style below
lStyle = Style Or WS_EX_LAYERED
Also this line is returning stuff you don't expect:
If Not (lStyle And WS_EX_LAYERED = WS_EX_LAYERED)
Substituting simple values
Code:
Debug.Print Not (3 And 1 = 1) ' expecting return a "false" value and returns -4
Debug.Print Not (3 And 8 = 8) ' expecting return a "true" value and returns -4
' now re-grouping, you get this
Debug.Print Not ((3 And 1) = 1) ' returns False
Debug.Print Not ((3 And 8) = 8) ' returns True
Re: Semi-Transparent Form
Typo? :eek:
I suggest reading the article What is Option Explicit, and why should I use it? from our Classic VB FAQs (in the FAQ forum)
Re: Semi-Transparent Form
Quote:
Originally Posted by
Teseng
Thanks, i think i finally figured it out, and since storm's code was much less than i had, it helped there too. I think my problem was i was firing this code a millisecond before my form was actually shown, so it may have had problems with the handle (although, other handles returned fine) I moved my execution around a bit and it seems to work fine now
You had at least 2 problems with the code you posted. Best to understand why yours failed. Which method you use is up to you of course.
Beware of the example posted by Storm. It has a flaw.
SetWindowLong(Me.hwnd, GWL_EXSTYLE, WS_EX_LAYERED)
With the above line, you are removing any WS_EX (extended style) bits currently set. For a form that is not using any extended style bits, this is not an issue obviously. But if, for example, the WS_EX_ToolWindow, WS_Ex_TopMost, or any other extended style bits were set, that line of code removes those bits and replaces them with just WS_EX_LAYERED
The correct solution to handle any type of form/window would be what you attempted first: Get the existing style and append the new style, then set the new style.
Re: Semi-Transparent Form
Ah, I see Lavolpe, I didn't even think of that, I use the bitwise operators all the time, just didnt dawn on me for some reason. Thanks everyone :D
Oh, and the missing L was a typo from me adding in some info after the copy/paste, it was correct in the program, Option Explicit is never off for me :D