|
|
I am trying to build an app, but since vista is out, i may as well build it for vista, so I am using wpf, VS2005/C# to build it. But most of my customers would be running xp sp2, hence if i do a glass effect for vista crowd, it will be unfair for the XP crowd. I am sure there are ways to get glass effect using wpf for xp sp2.
If you know of any pointers, I will be glad to try them out.
Thanks anyways for the article.
|
|
|
|
|
Hi nitstheone:
Ahhhhhhhh, maybe you are right, but I've no idea with how to do this in xp.
And, by the way, I don't think it will be unfair for the XP crowd, Vista crowd paid more money for their system, so they will have better effect ~~~~~~
Regards
Pang Wu
|
|
|
|
|
Could you show us how to draw on the non-client area as well? Office 2007 draws the QAT and its "File" menu button ontop of the non-client area...it'd be nice to know how to do something similar.
|
|
|
|
|
|
I've converted the DrawGlowingText function from the c# version that was in "GlassText.cs" to Vb.net
Every thing seems to work but the text is drawn using japaneese signs, Not normal letters
Can anyone tell me whats wrong?
Here's The code:
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Public Class VistaAeroAPI
Public Declare Function DwmIsCompositionEnabled Lib "dwmapi.dll" (ByRef en As Integer) As Integer
Public Declare Function DwmExtendFrameIntoClientArea Lib "dwmapi.dll" (ByVal hWnd As IntPtr, ByRef margins As MARGIN_STRUCT) As Integer
Public Declare Function DrawThemeTextEx Lib "UxTheme.dll" (ByVal hTheme As IntPtr, ByVal hdc As IntPtr, ByVal iPartId As Integer, ByVal iStateId As Integer, ByVal text As String, ByVal iCharCount As Integer, ByVal dwFlags As Integer, ByRef pRect As RECT, ByRef pOptions As S_DTTOPTS) As Integer
Public Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal hdc As IntPtr, ByVal pbmi As BITMAPINFO, ByVal iUsage As Int32, ByVal ppvBits As Integer, ByVal hSection As IntPtr, ByVal dwOffset As Int32) As IntPtr
Public Declare Function BitBlt Lib "gdi32.dll" (ByVal hdc As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Int32) As Boolean
Public Declare Function SelectObject Lib "gdi32.dll" (ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
Public Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As IntPtr) As Boolean
Public Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hDC As IntPtr) As IntPtr
Public Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As IntPtr) As Boolean
<structlayout(layoutkind.sequential)> _
Public Structure RECT
Public Sub New(ByVal tLeft As Integer, ByVal tTop As Integer, ByVal tRight As Integer, ByVal tBottom As Integer)
Left = tLeft
Top = tTop
Right = tRight
Bottom = tBottom
End Sub
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
<runtime.interopservices.structlayout(runtime.interopservices.layoutkind.sequential)> _
Public Class BITMAPINFO
Public biSize As Integer
Public biWidth As Integer
Public biHeight As Integer
Public biPlanes As Short
Public biBitCount As Short
Public biCompression As Integer
Public biSizeImage As Integer
Public biXPelsPerMeter As Integer
Public biYPelsPerMeter As Integer
Public biClrUsed As Integer
Public biClrImportant As Integer
Public bmiColors_rgbBlue As Byte
Public bmiColors_rgbGreen As Byte
Public bmiColors_rgbRed As Byte
Public bmiColors_rgbReserved As Byte
End Class
<runtime.interopservices.structlayout(runtime.interopservices.layoutkind.sequential)> _
Public Structure S_DTTOPTS
Dim dwSize As Integer
Dim dwFlags As Integer
Dim crText As Integer
Dim crBorder As Integer
Dim crShadow As Integer
Dim iTextShadowType As Integer
Dim ptShadowOffset As POINT
Dim iBorderSize As Integer
Dim iFontPropId As Integer
Dim iColorPropId As Integer
Dim iStateId As Integer
Dim fApplyOverlay As Boolean
Dim iGlowSize As Integer
Dim pfnDrawTextCallback As Integer
Dim lParam As IntPtr
End Structure
Private Const DTT_COMPOSITED As Integer = 8192
Private Const DTT_GLOWSIZE As Integer = 2048
Private Const DTT_TEXTCOLOR As Integer = 1
<runtime.interopservices.structlayout(runtime.interopservices.layoutkind.sequential)> _
Public Structure POINT
Dim cx, cy As Integer
Sub New(ByVal X As Integer, ByVal Y As Integer)
cx = X
cy = Y
End Sub
End Structure
<runtime.interopservices.structlayout(runtime.interopservices.layoutkind.sequential)> _
Public Structure MARGIN_STRUCT
Dim cxLeftWidth, cxRightWidth, cyTopHeight, cyBottomHeight As Integer
Sub New(ByVal Left As Integer, ByVal Right As Integer, ByVal Top As Integer, ByVal Bottom As Integer)
cxLeftWidth = Left
cxRightWidth = Right
cyTopHeight = Top
cyBottomHeight = Bottom
End Sub
End Structure
Public Shared Sub DrawGlowingText(ByVal Graphics As Graphics, ByVal text As String, ByVal fnt As Font, ByVal bounds As Rectangle, ByVal Clr As Color, ByVal flags As TextFormatFlags)
Dim primaryHdc As IntPtr = Graphics.GetHdc
'
'' Create a memory DC so we can work offscreen
Dim memoryHdc As IntPtr = CreateCompatibleDC(primaryHdc)
'' Create a device-independent bitmap and select it into our DC
Dim info As BITMAPINFO = New BITMAPINFO
info.biSize = Marshal.SizeOf(info)
info.biWidth = bounds.Width
info.biHeight = -bounds.Height
info.biPlanes = 1
info.biBitCount = 32
info.biCompression = 0 '' BI_RGB
Dim dib As IntPtr = CreateDIBSection(primaryHdc, info, 0, 0, IntPtr.Zero, 0)
SelectObject(memoryHdc, dib)
' Create and select font
Dim fontHandle As IntPtr = fnt.ToHfont
SelectObject(memoryHdc, fontHandle)
'' Draw glowing text
Dim renderer As System.Windows.Forms.VisualStyles.VisualStyleRenderer = New System.Windows.Forms.VisualStyles.VisualStyleRenderer(System.Windows.Forms.VisualStyles.VisualStyleElement.Window.Caption.Active)
Dim dttOpts As S_DTTOPTS = New S_DTTOPTS
dttOpts.dwSize = Marshal.SizeOf(GetType(S_DTTOPTS))
dttOpts.dwFlags = DTT_COMPOSITED Or DTT_GLOWSIZE Or DTT_TEXTCOLOR
dttOpts.crText = ColorTranslator.ToWin32(Clr)
dttOpts.iGlowSize = 15 '' This is about the size Microsoft Word 2007 uses(15)
Dim textBounds As RECT = New RECT(0, 0, bounds.Right - bounds.Left, bounds.Bottom - bounds.Top)
DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, text, -1, flags, textBounds, dttOpts)
'DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, text, -1, (int)flags, ref textBounds, ref dttOpts);
'' Copy to foreground
Dim SRCCOPY As Integer = 13369376 ' old C# Value was: 0x00CC0020
BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, SRCCOPY)
'' Clean up
DeleteObject(fontHandle)
DeleteObject(dib)
DeleteDC(memoryHdc)
Graphics.ReleaseHdc(primaryHdc)
End Sub
End Class
|
|
|
|
|
Hi SuperDude84:
It's not "japaneese signs" but the result of unicode string reads as ansi string. Don't use "Public declare function XXXXXX". Because DrawThemeTextEx is an Unicode function and "Public declare function XXXX" just declare the function as an Ansi function,and,you know,.net string is unicode.So you have to declare it like this:
<DllImport("UxTheme.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Unicode)> _
Shared Function DrawThemeTextEx(ByVal hTheme As IntPtr, ByVal hdc As IntPtr, ByVal iPartId As Integer, ByVal iStateId As Integer, ByVal text As String, ByVal iCharCount As Integer, ByVal dwFlags As Integer, ByRef pRect As RECT, ByRef pOptions As S_DTTOPTS) As Integer
End Function
And there are some other problems in your code, I've fixed them for you, I'll send it to you later, just check your email.
Regards
Pang Wu
|
|
|
|
|
Thanks for the help!
Regards
SveFro (previously SuperDude84)
|
|
|
|
|
Anyway of sharing the updated vb.net code? I get errors when running the above code trying to get the size of the dib.
|
|
|
|
|
Here is the updated VB.net Version:
Usage exsample:
call TextOnGlass.DrawGlowingText(Me.CreateGraphics, "Test text", Me.Font, New Rectangle(20, 20, 300, 20), Color.Black, 8, TextFormatFlags.Default)
Code:
Imports System.Runtime.InteropServices
Public Class TextOnGlass
#Region " Structures "
Public Structure RECT
Public Sub New(ByVal tLeft As Integer, ByVal tTop As Integer, ByVal tRight As Integer, ByVal tBottom As Integer)
Left = tLeft
Top = tTop
Right = tRight
Bottom = tBottom
End Sub
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
Public Structure BITMAPINFOHEADER
Dim biSize As Integer
Dim biWidth As Integer
Dim biHeight As Integer
Dim biPlanes As Short
Dim biBitCount As Short
Dim biCompression As Integer
Dim biSizeImage As Integer
Dim biXPelsPerMeter As Integer
Dim biYPelsPerMeter As Integer
Dim biClrUsed As Integer
Dim biClrImportant As Integer
End Structure
Public Structure RGBQUAD
Dim rgbBlue As Byte
Dim rgbGreen As Byte
Dim rgbRed As Byte
Dim rgbReserved As Byte
End Structure
Public Structure BITMAPINFO
Dim bmiHeader As BITMAPINFOHEADER
Dim bmiColors As RGBQUAD
End Structure
Public Structure S_DTTOPTS
Dim dwSize As Integer
Dim dwFlags As Integer
Dim crText As Integer
Dim crBorder As Integer
Dim crShadow As Integer
Dim iTextShadowType As Integer
Dim ptShadowOffset As Point
Dim iBorderSize As Integer
Dim iFontPropId As Integer
Dim iColorPropId As Integer
Dim iStateId As Integer
Dim fApplyOverlay As Boolean
Dim iGlowSize As Integer
Dim pfnDrawTextCallback As Integer
Dim lParam As IntPtr
End Structure
#End Region
#Region " Constants "
Private Const DTT_COMPOSITED As Integer = 8192
Private Const DTT_GLOWSIZE As Integer = 2048
Private Const DTT_TEXTCOLOR As Integer = 1
#End Region
#Region " Declares "
Public Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal hdc As IntPtr, ByRef pbmi As BITMAPINFO, ByVal iUsage As UInt32, ByVal ppvBits As Integer, ByVal hSection As IntPtr, ByVal dwOffset As UInt32) As IntPtr
Public Declare Function BitBlt Lib "gdi32.dll" (ByVal hdc As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Int32) As Boolean
Public Declare Function SelectObject Lib "gdi32.dll" (ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
Public Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As IntPtr) As Boolean
Public Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hDC As IntPtr) As IntPtr
Public Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As IntPtr) As Boolean
<dllimport("user32.dll", exactspelling:="True," setlasterror:="True)"> _
Public Shared Function GetDC(ByVal hWnd As IntPtr) As IntPtr
End Function
Public Declare Unicode Function DrawThemeTextEx Lib "UxTheme.dll" (ByVal hTheme As IntPtr, ByVal hdc As IntPtr, ByVal iPartId As Integer, ByVal iStateId As Integer, ByVal text As String, ByVal iCharCount As Integer, ByVal dwFlags As Integer, ByRef pRect As RECT, ByRef pOptions As S_DTTOPTS) As Integer
#End Region
Public Shared Sub DrawGlowingText(ByVal Graphics As Graphics, ByVal text As String, ByVal fnt As Font, ByVal bounds As Rectangle, ByVal Clr As Color, ByVal GlowSize As Integer, ByVal flags As TextFormatFlags)
Dim primaryHdc As IntPtr = Graphics.GetHdc
Dim bitmapOld As IntPtr = IntPtr.Zero
Dim hfontOld As IntPtr = IntPtr.Zero
'' Create a memory DC so we can work offscreen
Dim memoryHdc As IntPtr = CreateCompatibleDC(primaryHdc)
Dim textBounds As RECT
Dim screenBounds As RECT
screenBounds = New RECT()
screenBounds.Top = bounds.Top - GlowSize
screenBounds.Left = bounds.Left - GlowSize
screenBounds.Right = bounds.Right + GlowSize
screenBounds.Bottom = bounds.Bottom + GlowSize
textBounds = New RECT( _
GlowSize, _
GlowSize, _
screenBounds.Right - screenBounds.Left - GlowSize, _
screenBounds.Bottom - screenBounds.Top - GlowSize _
)
'' Create a device-independent bitmap and select it into our DC
Dim info As BITMAPINFO = New BITMAPINFO
info.bmiHeader.biSize = Marshal.SizeOf(info.bmiHeader)
info.bmiHeader.biWidth = screenBounds.Right - screenBounds.Left 'bounds.Width '+ 30
info.bmiHeader.biHeight = -screenBounds.Bottom - screenBounds.Top '- bounds.Height '- 30
info.bmiHeader.biPlanes = 1
info.bmiHeader.biBitCount = 32
info.bmiHeader.biCompression = 0 '' BI_RGB
Dim dib As IntPtr = CreateDIBSection(primaryHdc, info, 0, 0, IntPtr.Zero, 0)
bitmapOld = SelectObject(memoryHdc, dib)
' Create and select font
Dim fontHandle As IntPtr = fnt.ToHfont
hfontOld = SelectObject(memoryHdc, fontHandle)
'' Draw glowing text
Dim renderer As System.Windows.Forms.VisualStyles.VisualStyleRenderer = New System.Windows.Forms.VisualStyles.VisualStyleRenderer(System.Windows.Forms.VisualStyles.VisualStyleElement.Window.Caption.Active)
Dim dttOpts As S_DTTOPTS = New S_DTTOPTS
dttOpts.dwSize = Marshal.SizeOf(dttOpts)
dttOpts.dwFlags = DTT_COMPOSITED Or DTT_GLOWSIZE Or DTT_TEXTCOLOR
dttOpts.crText = ColorTranslator.ToWin32(Clr)
dttOpts.iGlowSize = GlowSize '' Microsoft Word 2007 uses 15
DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, text, -1, flags, textBounds, dttOpts)
'' Copy to foreground
Dim SRCCOPY As Integer = &HCC0020 ' old C# Value was: 0x00CC0020
BitBlt(primaryHdc, screenBounds.Left, screenBounds.Top, _
screenBounds.Right - screenBounds.Left, screenBounds.Bottom - screenBounds.Top, memoryHdc, 0, 0, SRCCOPY)
'' Clean up
'*********fist, select this old dibsection and font back and free current dib and font***************
SelectObject(memoryHdc, bitmapOld)
SelectObject(memoryHdc, hfontOld)
'******************* then delete then********************************
DeleteObject(fontHandle)
DeleteObject(dib)
DeleteDC(memoryHdc)
Graphics.ReleaseHdc(primaryHdc)
End Sub
End Class
-- modified at 6:22 Wednesday 28th March, 2007
|
|
|
|
|
Thank You!!
|
|
|
|
|
Is the correct code to get the glass effect on VB.net 2008. I really need to do this in vb.net 2008. Will you help me please. thanks.
|
|
|
|
|
Very interesting and easy to understand. Excellent work.
|
|
|
|
|
Thanks ^_^
Regards
Pang Wu
|
|
|
|
|
so that it does not get the warning prompt for unsafe code.. Anyone have a clue?
|
|
|
|
|
Readers of this post might be interested in how to correctly draw glowing text over glass, like Word does and in fact like Aero does in the titlebar. I bloggest this including a managed sample that shows how it's done.
http://styli.sh/blogs/divil/archive/2006/10/18/4.aspx[^]
|
|
|
|
|
|
Hi Tim
I've updated this article and add some info about DrawThemeTextEx.
Regards
Pang Wu
|
|
|
|
|
Hi Pang Wu,
Trough many help in article (and also in this threads) I'm facing issue with DrawThemeTextEx. The problem is, that the text printed on glass has always black background. This still in spite of your FillBlackRegion function.
My method of creating windows glassy:
Dim c As Color = Color.FromArgb(255, 221, 220, 220)
Me.TransparencyKey = c
DwmExtendFrameIntoClientArea(Me.Handle, myMargins)
Me.BackColor = c
As you see, I using other color as transparent color (Gainsboro) because of that I've got some control (textboxes, commandbuttons etc...) on glass. When I use black as transparent color, then all black on forms goes glass (including text on controls), so that is why I using gainsboro as transparent color.
My method of printing text to glass:
Public Shared Sub DrawGlowingText(ByVal g As Graphics, ByVal text As String, ByVal fnt As Font, ByVal bounds As Rectangle, ByVal Clr As Color, ByVal GlowSize As Integer, ByVal flags As TextFormatFlags)
Dim primaryHdc As IntPtr = g.GetHdc
Dim bitmapOld As IntPtr = IntPtr.Zero
Dim hfontOld As IntPtr = IntPtr.Zero
Dim memoryHdc As IntPtr = CreateCompatibleDC(primaryHdc)
Dim textBounds As RECT
Dim screenBounds As RECT
screenBounds = New RECT()
screenBounds.Top = bounds.Top - GlowSize
screenBounds.Left = bounds.Left - GlowSize
screenBounds.Right = bounds.Right + GlowSize
screenBounds.Bottom = bounds.Bottom + GlowSize
textBounds = New RECT( _
GlowSize, _
GlowSize, _
screenBounds.Right - screenBounds.Left - GlowSize, _
screenBounds.Bottom - screenBounds.Top - GlowSize _
)
Dim info As BITMAPINFO = New BITMAPINFO
info.bmiHeader.biSize = Marshal.SizeOf(info.bmiHeader)
info.bmiHeader.biWidth = screenBounds.Right - screenBounds.Left 'bounds.Width '+ 30
info.bmiHeader.biHeight = -screenBounds.Bottom - screenBounds.Top '- bounds.Height '- 30
info.bmiHeader.biPlanes = 1
info.bmiHeader.biBitCount = 32
info.bmiHeader.biCompression = 0
Dim dib As IntPtr = CreateDIBSection(primaryHdc, info, 0, IntPtr.Zero, IntPtr.Zero, 0)
bitmapOld = SelectObject(memoryHdc, dib)
Dim fontHandle As IntPtr = fnt.ToHfont
hfontOld = SelectObject(memoryHdc, fontHandle)
Dim renderer As System.Windows.Forms.VisualStyles.VisualStyleRenderer = New System.Windows.Forms.VisualStyles.VisualStyleRenderer(System.Windows.Forms.VisualStyles.VisualStyleElement.Window.Caption.Active)
Dim dttOpts As S_DTTOPTS = New S_DTTOPTS
dttOpts.dwSize = Marshal.SizeOf(dttOpts)
dttOpts.dwFlags = DTT_COMPOSITED Or DTT_GLOWSIZE
'dttOpts.crText = ColorTranslator.ToWin32(Clr)
dttOpts.iGlowSize = 10 '' Microsoft Word 2007 uses 15
DrawThemeTextEx(renderer.Handle, memoryHdc, 0, 0, text, -1, flags, textBounds, dttOpts)
Dim SRCCOPY As Integer = &HCC0020 ' old C# Value was: 0x00CC0020
BitBlt(primaryHdc, screenBounds.Left, screenBounds.Top, _
screenBounds.Right - screenBounds.Left, screenBounds.Bottom - screenBounds.Top, memoryHdc, 0, 0, SRCCOPY)
SelectObject(memoryHdc, bitmapOld)
SelectObject(memoryHdc, hfontOld)
DeleteObject(fontHandle)
DeleteObject(dib)
DeleteDC(memoryHdc)
g.ReleaseHdc(primaryHdc)
End Sub
Calling:
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
DrawGlowingText(Me.CreateGraphics, "Hello Aero", Me.Font, New Rectangle(10, 10, 100, 50), Color.Black, 8, TextFormatFlags.SingleLine Or TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter Or TextFormatFlags.NoPrefix)
End Sub
I've already found that Yuban had similar problem here (Please see the last, third from three posts) but I've got no idea how he solved this.
Your article really helps me a lot and when you fill up DrawThemeTextEx part with some sample which works on todays Vistas, it will be the best and most robust article about "How to with Glass on Vista" that I've ever found.
|
|
|
|
|
Hi,
Let me confirm something: If black is used as transparent color, everything will be allright, but if we use other color, black background will display?
I haven't got Vista on my computer now, but I will try my best to help you.
Regards
Pang Wu
|
|
|
|
|
No, even if we use black color as transparent color it won't be correct.
Here's[^] an example what raises when black color is used as transparent color.
|
|
|
|
|
|
Yop, you're right. It was in that "hack". Now I use glass extending in default way (with black transparency) and the DrawThemeTextEx works great.
As you mentioned, now my problem is with painting controls on glass. So, hurra go ahead
Thank you for links and also for help.
I really appreciate it
Have a nice day
|
|
|
|
|
Okay, I give up... Spent 20 hours to figure out how I can use that bufferedpaint from Kenny's blog. Nothing works. My C++ knowledge is just on school level so you could figure out, that is not too much.
My question is: Anyone have C# or VB.NET code scratch where is that bufferedPaint showed?
Also I googled many times, but nowhere seems to be any language than C++.
Thanks for help!
|
|
|
|
|
I have a dll written in C++ that can hook your window and buffer painted all the controls. But I haven't got the code at hand, if you want a copy and don't mind waiting, maybe I can give it to you after March.
Regards
Pang Wu
|
|
|
|
|