-
2 Attachment(s)
[RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user control?
I know that RC5.Cairo, GDIPlus and GDI can draw smooth (anti-aliased) rounded rectangles in a Form or PictureBox. However, I don't know how to develop a rounded-rect button control with a smooth (anti-aliased) corner?
Any advice and suggestions would be greatly appreciated.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
-
1 Attachment(s)
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Quote:
Originally Posted by
The trick
Hi The trick, I studied your controls which are wonderful, but they don't seem to have special handling of the rounded-corners.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Recent threads have covered everything required: transparent UserControls and GDI antialiasing. If that isn't good enough then you could use GDI+ antialiasing.
The question is why?
All you do is guarantee that your programs look and act foreign on every version of Windows. You also have the problem of everything falling apart entirely when a user has one of the Accessibility Themes selected.
Programs shouldn't look like some 1990s web site full of random spinning flaming animated GIFs, mismatched fonts and garish colors.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Quote:
Originally Posted by
dilettante
Recent threads have covered everything required: transparent UserControls and GDI antialiasing. If that isn't good enough then you could use GDI+ antialiasing.
The question is why?
Hi dilettante, I studied your "AA GDI Drawing" and Olaf's "Aqua-Button", but I didn't see a thread that made the four corners of the button control transparent. I'll continue to search for relevant information in vbForums tomorrow. Thank you.
Quote:
Originally Posted by
dilettante
You also have the problem of everything falling apart entirely when a user has one of the Accessibility Themes selected.
I still don't understand the meaning of this sentence.
Quote:
Originally Posted by
dilettante
Programs shouldn't look like some 1990s web site full of random spinning flaming animated GIFs, mismatched fonts and garish colors.
Completely agree with you. I also like the clean, flat GUI, just like the button controls I showed on #1.
-
1 Attachment(s)
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
I need a button control similar to this green button.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
dreammanor, sorry i thought you can use a predefined picture to make the button like that:
https://s8.hostingkartinok.com/uploa...d7e2e07815.png
Anyway, you can use standard graphical buttons and process WM_CTLCOLORBTN, or use windowless control. To draw a rounded rectangle you can use either GDI+ paths or draw rectangle and two/four circles.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Well if you need your button to appear over anything but a solid-color background you can't use mask transparency.
If you want to use alpha transparency you might have to go through a lot of gymnastics to created an anti-aliased premultipled alpha image using GDI so that you can render via AlphaBlend().
So you are probably going to have to render your button shape using GDI+ and then render it during the UserControl's Paint event using GDI+ as well. You could still get away with AlphaBlend() but for that you need to convert the GDI+ Image to a premultiplied alpha GDI Bitmap.
So maybe LaVolpe or somebody will chime in. But there have been a lot of GDI+ threads here lately so you may already find the pieces and parts you need described in one of them. If not it is just a matter of cracking open the GDI+ Flat API documentation and working out the details.
How did programmers with inadequate documentation consumption skills even get by in the days before globally accessible forum sites? Back when I was hiring programmers in the 1980s-1990s we always required passing a reading test based on a "how to" question and a stack of reference manuals. Now we even have search engines.
Even the MSDN Library documentation has decent search capabilities. Do people even know about the search expressions accepting quoted strings, AND, OR, NOT, NEAR, wildcards, etc? Or the "Match similar words" checkbox? It isn't Google, but it is pretty good.
Sadly the GDI+ Flat API isn't covered in any detail even in the October 2001 edition, the best one for VB6 programmers. It was still sort of "too new."
-
1 Attachment(s)
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Quote:
Originally Posted by
dilettante
Well if you need your button to appear over anything but a solid-color background you can't use mask transparency.
If you want to use alpha transparency you might have to go through a lot of gymnastics to created an anti-aliased premultipled alpha image using GDI so that you can render via AlphaBlend().
So you are probably going to have to render your button shape using GDI+ and then render it during the UserControl's Paint event using GDI+ as well. You could still get away with AlphaBlend() but for that you need to convert the GDI+ Image to a premultiplied alpha GDI Bitmap.
So maybe LaVolpe or somebody will chime in. But there have been a lot of GDI+ threads here lately so you may already find the pieces and parts you need described in one of them. If not it is just a matter of cracking open the GDI+ Flat API documentation and working out the details.
How did programmers with inadequate documentation consumption skills even get by in the days before globally accessible forum sites? Back when I was hiring programmers in the 1980s-1990s we always required passing a reading test based on a "how to" question and a stack of reference manuals. Now we even have search engines.
Even the MSDN Library documentation has decent search capabilities. Do people even know about the search expressions accepting quoted strings, AND, OR, NOT, NEAR, wildcards, etc? Or the "Match similar words" checkbox? It isn't Google, but it is pretty good.
Sadly the GDI+ Flat API isn't covered in any detail even in the October 2001 edition, the best one for VB6 programmers. It was still sort of "too new."
Attachment 158097
http://leandroascierto.com/blog/esferas-con-gdi/
https://www.mediafire.com/file/n6b50...uttonMetro.zip
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
I always forget about OleTranslateColor() and end up rolling my own based on GetSysColor() instead. Thanks for the reminder.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Hi @xxdoc123, thank you for your information, the graphics drawn by GDIPlus are very beautiful. RC5.Cairo can also draw very beautiful graphics. However, these examples only draw the picture of a rounded button and can't make a real rounded button control. Because the button control is a rectangle window, I need to make the four corners of the window transparent.
http://www.vbforums.com/showthread.p...=1#post5254827
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Maybe the code used here could help you:
A class for creating round rectangles in GDI+ with pixel accurate symmetry
Quote:
Since rounded rectangles are not a native shape to GDI+, they are typically created using a GraphicsPath or some other mechanism. It doesn’t matter if you use AddArc, AddBezeir, Polygon points, Transformations etc., the asymmetry is there if any of the previously stated conditions are true. The reason none of these methods produce accurate results is because the problem is not in the definition of the points. All the methods above will accurately define the points. The problem occurs when the shape is rendered (drawn or filled). I won’t speculate on what the underlying cause of this asymmetry is.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Quote:
Originally Posted by
dilettante
Well if you need your button to appear over anything but a solid-color background you can't use mask transparency.
If you want to use alpha transparency you might have to go through a lot of gymnastics to created an anti-aliased premultipled alpha image using GDI so that you can render via AlphaBlend().
So you are probably going to have to render your button shape using GDI+ and then render it during the UserControl's Paint event using GDI+ as well. You could still get away with AlphaBlend() but for that you need to convert the GDI+ Image to a premultiplied alpha GDI Bitmap.
So maybe LaVolpe or somebody will chime in. But there have been a lot of GDI+ threads here lately so you may already find the pieces and parts you need described in one of them. If not it is just a matter of cracking open the GDI+ Flat API documentation and working out the details.
I don't need Alpha, I just need to make the four corners of the rounded button control transparent.
Quote:
Originally Posted by
dilettante
How did programmers with inadequate documentation consumption skills even get by in the days before globally accessible forum sites? Back when I was hiring programmers in the 1980s-1990s we always required passing a reading test based on a "how to" question and a stack of reference manuals. Now we even have search engines.
Even the MSDN Library documentation has decent search capabilities. Do people even know about the search expressions accepting quoted strings, AND, OR, NOT, NEAR, wildcards, etc? Or the "Match similar words" checkbox? It isn't Google, but it is pretty good.
Sadly the GDI+ Flat API isn't covered in any detail even in the October 2001 edition, the best one for VB6 programmers. It was still sort of "too new."
Reading documents is one of the ways to solve the problem, but VB6 is a product that has been abandoned by Microsoft for almost 20 years, and many documents are obsolete, incomplete or even wrong. When I just graduated, I read a lot of VB6 English reference manuals, but now I don't. For me, reading code is the quickest way, even faster than reading Chinese documents (although my Chinese is excellent).
Many times, when I ask a question, I don't necessarily want to get the final answer. I hope to learn about different ideas and different solutions by discussing these questions so that I and others can learn a lot of knowledge, and more importantly, I can communicate with others.
In fact, 12 years ago, I knew how to make the four corners of the rounded button control transparent, but the method I was using was very complicated and I hope that others can have a more professional and simple method.
If I can't find a professional and easy way, I'll use a stupid and simple method to hide the four corners of a rounded button control by setting the button backcolor to match the container backcolor. But if the container background is a picture (not monochrome) then my simple method will be ineffective.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Quote:
Originally Posted by
dilettante
Very useful information, thank you dilettante.
-
2 Attachment(s)
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
If you only need something simple (no alpha transparency or alpha anti-aliasing) here is an idea:
Attachment 158107
You can extract the few parts needed from the Drawing class used here and embed them into your UserControl, or discard most of it and use a hidden PictureBox as your canvas for drawing the large image to StretchBlt down to size with halftone mode.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Sorry, I didn't express my meaning clearly. I want a simple rounded button whose border is smooth (anti-aliased), which means that the border is alpha anti-aliased. Still thank you very much for your wonderful code, dilettante.
-
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
Quote:
Originally Posted by
The trick
dreammanor, sorry i thought you can use a predefined picture to make the button like that:
http://www.vbforums.com/images/ieimages/2018/04/1.png
Anyway, you can use standard graphical buttons and process WM_CTLCOLORBTN, or use windowless control. To draw a rounded rectangle you can use either GDI+ paths or draw rectangle and two/four circles.
Hi The trick, thanks for your suggestion. I learned a lot from your code. Thank you so much.
-
1 Attachment(s)
Re: How to develop a border smooth(anti-aliased) rounded-rect button user control?
As the first step (hastily no tested/error checking/and other things like no properties etc.):
Code:
Option Explicit
Private Const SmoothingModeAntiAlias As Long = 4
Private Const CombineModeReplace As Long = 0
Private Const CombineModeXor As Long = 3
Private Const CombineModeExclude As Long = 4
Private Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type
Private Declare Function GdiplusStartup Lib "gdiplus" ( _
ByRef token As Long, _
ByRef inputbuf As GdiplusStartupInput, _
Optional ByVal outputbuf As Long = 0) As Long
Private Declare Function GdipCreateFromHDC Lib "gdiplus" ( _
ByVal hdc As Long, _
ByRef graphics As Long) As Long
Private Declare Function GdipDeleteGraphics Lib "gdiplus" ( _
ByVal graphics As Long) As Long
Private Declare Function GdiplusShutdown Lib "gdiplus" ( _
ByVal token As Long) As Long
Private Declare Function GdipFillEllipse Lib "gdiplus" ( _
ByVal graphics As Long, _
ByVal brush As Long, _
ByVal x As Single, _
ByVal y As Single, _
ByVal Width As Single, _
ByVal Height As Single) As Long
Private Declare Function GdipSetSmoothingMode Lib "gdiplus" ( _
ByVal graphics As Long, _
ByVal SmoothingMd As Long) As Long
Private Declare Function GdipCreateSolidFill Lib "gdiplus" ( _
ByVal argb As Long, _
ByRef brush As Long) As Long
Private Declare Function GdipDeleteBrush Lib "gdiplus" ( _
ByVal brush As Long) As Long
Private Declare Function GdipSetSolidFillColor Lib "gdiplus" ( _
ByVal brush As Long, _
ByVal argb As Long) As Long
Private Declare Function GdipDrawEllipse Lib "gdiplus" ( _
ByVal graphics As Long, _
ByVal pen As Long, _
ByVal x As Single, _
ByVal y As Single, _
ByVal Width As Single, _
ByVal Height As Single) As Long
Private Declare Function GdipFillRectangle Lib "gdiplus" ( _
ByVal graphics As Long, _
ByVal brush As Long, _
ByVal x As Single, _
ByVal y As Single, _
ByVal Width As Single, _
ByVal Height As Single) As Long
Private Declare Function GdipSetClipRect Lib "gdiplus" ( _
ByVal graphics As Long, _
ByVal x As Single, _
ByVal y As Single, _
ByVal Width As Single, _
ByVal Height As Single, _
ByVal CombineMd As Long) As Long
Private mbIsPressed As Boolean
Private mhToken As Long
Private mhBrush As Long
Private Sub UserControl_HitTest( _
ByRef x As Single, _
ByRef y As Single, _
ByRef HitResult As Integer)
Dim fRadius As Single
If UserControl.ScaleWidth > UserControl.ScaleHeight Then
fRadius = UserControl.ScaleHeight - 1
Else
fRadius = UserControl.ScaleWidth - 1
End If
If x > fRadius / 2 And x < UserControl.ScaleWidth - fRadius / 2 Then
HitResult = vbHitResultHit
Else
y = y - fRadius / 2
If x < fRadius / 2 Then
x = x - fRadius / 2
Else
x = x - (UserControl.ScaleWidth - fRadius / 2)
End If
If Sqr(x ^ 2 + y ^ 2) > fRadius / 2 Then
HitResult = vbHitResultOutside
Else
HitResult = vbHitResultHit
End If
End If
End Sub
Private Sub UserControl_Initialize()
Dim tGpInput As GdiplusStartupInput
tGpInput.GdiplusVersion = 1
If GdiplusStartup(mhToken, tGpInput) Then
MsgBox "Unable to init GDI+"
Exit Sub
End If
GdipCreateSolidFill &HFF00FF00, mhBrush
End Sub
Private Sub UserControl_Resize()
UserControl.Refresh
End Sub
Private Sub UserControl_Terminate()
If mhBrush Then
GdipDeleteBrush mhBrush
End If
If mhToken Then
GdiplusShutdown mhToken
End If
End Sub
Private Sub UserControl_MouseDown( _
ByRef Button As Integer, _
ByRef Shift As Integer, _
ByRef x As Single, _
ByRef y As Single)
mbIsPressed = True
UserControl.Refresh
End Sub
Private Sub UserControl_MouseUp( _
ByRef Button As Integer, _
ByRef Shift As Integer, _
ByRef x As Single, _
ByRef y As Single)
mbIsPressed = False
UserControl.Refresh
End Sub
Private Sub UserControl_Paint()
Dim hGr As Long
Dim fRadius As Single
Dim lColor As Long
Dim lWidth As Long
Dim lHeight As Long
Dim sCaption As String
If mhToken = 0 Then Exit Sub
If GdipCreateFromHDC(UserControl.hdc, hGr) Then Exit Sub
GdipSetSmoothingMode hGr, SmoothingModeAntiAlias
If UserControl.ScaleWidth > UserControl.ScaleHeight Then
fRadius = UserControl.ScaleHeight - 1
Else
fRadius = UserControl.ScaleWidth - 1
End If
If mbIsPressed Then
lColor = &H8F0000FF
Else
lColor = &H8F00FF00
End If
GdipSetSolidFillColor mhBrush, lColor
GdipSetClipRect hGr, fRadius / 2, 0, UserControl.ScaleWidth - fRadius / 2, UserControl.ScaleHeight, CombineModeExclude
GdipFillEllipse hGr, mhBrush, 0, 0, fRadius, fRadius
GdipSetClipRect hGr, UserControl.ScaleWidth - fRadius / 2 - 1, 0, fRadius, UserControl.ScaleHeight, CombineModeReplace
GdipFillEllipse hGr, mhBrush, UserControl.ScaleWidth - fRadius - 1, 0, fRadius, fRadius
GdipSetClipRect hGr, fRadius / 2, 0, UserControl.ScaleWidth - fRadius - 1, UserControl.ScaleHeight, CombineModeReplace
GdipFillRectangle hGr, mhBrush, fRadius / 2 - 1, 0, UserControl.ScaleWidth - fRadius, UserControl.ScaleHeight
GdipDeleteGraphics hGr
sCaption = "Button"
lWidth = UserControl.TextWidth(sCaption)
lHeight = UserControl.TextHeight(sCaption)
UserControl.CurrentX = (UserControl.ScaleWidth - lWidth) / 2
UserControl.CurrentY = (UserControl.ScaleHeight - lHeight) / 2
UserControl.Print "Button"
End Sub
https://image.ibb.co/ntgiPx/b1.png
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Hi The trick, it's fantastic. Extremely grateful.
-
2 Attachment(s)
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
dreammanor
Hi The trick, it's fantastic. Extremely grateful.
Attachment 158137
Code:
Option Explicit
Dim penl As Long, brush As Long
Private Declare Function GdipDrawArcI _
Lib "gdiplus" (ByVal graphics As Long, _
ByVal pen As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal Width As Long, _
ByVal Height As Long, _
ByVal startAngle As Single, _
ByVal sweepAngle As Single) As GpStatus
Private Sub DrawRoundRectangle(graphics As Long, _
brush As Long, _
x As Long, _
y As Long, _
Width As Long, _
Height As Long, _
Optional RoundSize As Long = 30)
' GdipDrawArcI graphics, brush, x, y, RoundSize * 2, RoundSize * 2, 180, 90 '
GdipFillPieI graphics, brush, x, y, RoundSize * 2, RoundSize * 2, 180, 90 ''
' GdipDrawLineI graphics, brush, x + RoundSize, y, x + Width - RoundSize, y ''
GdipFillRectangleI graphics, brush, x + RoundSize - 1, y, Width - 2 * RoundSize + 2, RoundSize + 2 '
' GdipDrawArcI graphics, brush, x + Width - RoundSize * 2, y, RoundSize * 2, RoundSize * 2, 270, 90
GdipFillPieI graphics, brush, x + Width - RoundSize * 2, y, RoundSize * 2, RoundSize * 2, 270, 90
'GdipDrawLineI graphics, brush, x + Width, y + RoundSize, x + Width, y + Height - RoundSize
GdipFillRectangleI graphics, brush, x, y + RoundSize - 1, Width, Height - 2 * RoundSize + 2
' GdipDrawArcI graphics, brush, x + Width - RoundSize * 2, y + Height - RoundSize * 2, RoundSize * 2, RoundSize * 2, 0, 90
GdipFillPieI graphics, brush, x + Width - RoundSize * 2, y + Height - RoundSize * 2, RoundSize * 2, RoundSize * 2, 0, 90
' GdipDrawLineI graphics, brush, x + RoundSize, y + Height, x + Width - RoundSize, y + Height
' GdipDrawArcI graphics, brush, x, y + Height - RoundSize * 2, RoundSize * 2, RoundSize * 2, 90, 90
GdipFillPieI graphics, brush, x, y + Height - RoundSize * 2, RoundSize * 2, RoundSize * 2, 90, 90
' GdipDrawLineI graphics, brush, x, y + RoundSize, x, y + Height - RoundSize
GdipFillRectangleI graphics, brush, x + RoundSize - 1, y + Height - RoundSize - 2, Width - 2 * RoundSize + 2, RoundSize + 2
End Sub
Private Sub UserControl_Initialize()
InitGDIPlus
End Sub
Private Sub UserControl_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
UserControl.Refresh
End Sub
Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
UserControl.Refresh
End Sub
Private Sub UserControl_Paint()
Dim sCaption As String
Dim lWidth As Long
Dim lHeight As Long
Dim graphics As Long
GdipCreateFromHDC UserControl.hDC, graphics
GdipSetSmoothingMode graphics, SmoothingModeAntiAlias
GdipCreateSolidFill &HFF00FF00, brush
DrawRoundRectangle graphics, brush, 0, 0, UserControl.ScaleWidth, UserControl.ScaleHeight
GdipDeleteGraphics graphics '
sCaption = "Button"
lWidth = UserControl.TextWidth(sCaption)
lHeight = UserControl.TextHeight(sCaption)
UserControl.CurrentX = (UserControl.ScaleWidth - lWidth) / 2
UserControl.CurrentY = (UserControl.ScaleHeight - lHeight) / 2
UserControl.Print "Button"
End Sub
Private Sub UserControl_Resize()
UserControl.Refresh
End Sub
Private Sub UserControl_Terminate()
'GdipDeletePen penl
GdipDeleteBrush brush
TerminateGDIPlus
End Sub
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Thank you, xxdoc123. There is a small problem where the size of the rounded rectangle is inconsistent with the size of the control.
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
this looks great.
QUESTIONS
so, usercontrol.backstyle = transparent, clickbehaviour = none , autoredraw = false is all the magic sauce?
never used gdiplus, readed it is vista+ only, so forget about to maintain XP compatibility.
what if compatibility theme in windows is set, this doesn't work or what?
a gdiplus line to render from a stdpicture (which is loaded with PNG w/ alpha) to the rectangle of the usercontrol that it maintain the translucency like in these buttons?. (don't care the shape, the PNG already has the shape drawn).
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Just checked that the Windowless property of usercontrol must be activated for the buttons to work.
I wan't to set it to true or false programatically, but Usercontrol.Windowsless = true is not recognized, so, can't compile that.
Any workaround?.
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
flyguille
Just checked that the Windowless property of usercontrol must be activated for the buttons to work.
I wan't to set it to true or false programatically...
Why?
Olaf
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
Schmidt
Why?
Olaf
never mind, I figure out that I can set from IDE WindowLess property to true, and then control it programatically with BackStyle=opaque or transparent , being opaque the default (because I am implementing it in a control that must be retro-compatible with old skins wich won't use translucency.
Now, when using translucency the UserControl.Picture = doesn't work anymore.
So, I am looking for the equivalent in GDIPlus, having a PNG loaded in a StdPicture variable (loaded with special routine which loads alpha channel), so, basically need the rendering function.
Now, I looked some, but they doesn't accept the stdpic.Handle, it crashes if I do that.
So, the idea, is if the skin want to show a picture as a button, it must show the picture with translucency.
I also tryed, stdpic.render method without luck.
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
flyguille
never mind, I figure out that I can set from IDE WindowLess property to true, and then control it programatically with BackStyle=opaque or transparent , being opaque the default (because I am implementing it in a control that must be retro-compatible with old skins wich won't use translucency.
Now, when using translucency the UserControl.Picture = doesn't work anymore.
So, I am looking for the equivalent in GDIPlus, having a PNG loaded in a StdPicture variable (loaded with special routine which loads alpha channel), so, basically need the rendering function.
Now, I looked some, but they doesn't accept the stdpic.Handle, it crashes if I do that.
So, the idea, is if the skin want to show a picture as a button, it must show the picture with translucency.
I also tryed, stdpic.render method without luck.
This is not so easy to do.
If you load an alpha-transparent PNG as 32-bit DIB and create an StdPicture (vbPicTypeBitmap sub-type) you will get the alpha discarded on Render method or BitBlt API call.
If you load an alpha-transparent PNG as 32-bit DIB, create an alpha-transparent hIcon from it and then create an StdPicture (vbPicTypeIcon sub-type) you will get alpha discarded on Render method contrary to DrawIconEx API call which will alpha blend the image just ok.
Apparently Render method does not use DrawIconEx internally but fiddles with the hIcon manually applying transparency which is lame.
Another caveat with Windowless=True user-controls is that whether the current instance is actually windowless depends on the container it's placed into e.g. MS Access forms do not support windowless activation so your control will have a separate hWnd and will not support windowless controls transparency as implemented above by The trick.
Start a new thread outside this thread about smooth borders of rounded rectangles and ouside the CodeBank sub-forum and I'll try to post a link to a project/user-control which solves most of the problems above and does pretty much what you are trying to do in first place.
cheers,
</wqw>
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
But are dollybuttons worth all of the effort? If you want a radically non-standard user interface you may as well drop back and just create the entire thing by drawing via Direct2D or else use some 3rd party UI widgets library.
It might be far better to just use the existing VB/ActiveX wrappers and plumbing for Win32 controls... with just enough tweaking to match the look and feel of the Windows version you are running on. Put your effort into function rather than form to make your programs valuable to users.
"Hello world" programs don't add value by having a gauche UI. All I can think of now are those hilariously goofy "skins" that used to come with Windows Media Player, like that Big Green Head one.
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
dilettante
But are dollybuttons worth all of the effort? If you want a radically non-standard user interface you may as well drop back and just create the entire thing by drawing via Direct2D or else use some 3rd party UI widgets library.
It might be far better to just use the existing VB/ActiveX wrappers and plumbing for Win32 controls... with just enough tweaking to match the look and feel of the Windows version you are running on. Put your effort into function rather than form to make your programs valuable to users.
"Hello world" programs don't add value by having a gauche UI. All I can think of now are those hilariously goofy "skins" that used to come with Windows Media Player, like that Big Green Head one.
Well, is a "for gamers app", so fancy things sells it, so the EXE itself has no UI, what makes the UI is an external text file known as the skin, plus a directory of img files. So, building here more features over legacy code. That is why I don't shift it to a completely new language or UI method.
Anyway, I am looking for at GdipDrawImageRectRectI or GdipDrawImageRectI.
But, I has the StdPicture variable in one hand, and these functions expect a gdiplus formatted image handler in the other hand. I just needs to fill the gap, a function that convert one to the other. Without using the LOADFile method from gdiplus, because at this stage I don't has the filename, I have the just the StdPicture stored, idd several StdPicture, one for each status of the button.
Now, adding translucency, is one thing, and process the alpha channel from the PNG stored in the StdPic is another thing.
I will try to add translucency as a first goal, then care about the PNG alpha.
I searched but seen everybody get the gdiplus image directly from the file, if nobody did a stdpicture->gdiplus conversion, well, I will need to store the image twice in RAM, one for each scenario, translucency/no translucency and use separated variables, RAM storage, and slowdown the loading times!.
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
flyguille
I searched but seen everybody get the gdiplus image directly from the file, if nobody did a stdpicture->gdiplus conversion
You mean no one is simply using GdipCreateBitmapFromHBITMAP and GdipCreateBitmapFromHICON in their samples with the StdPicture handle?
That's because both of these drop alpha channel altogether when passing a 32-bit hDIB (wrapped in an hIcon or not) so the way to go is simply to call GdipCreateBitmapFromScan0 with PixelFormat32bppPARGB by using the array of ARGB quads backing the actual DIB, the so called lpBits.
cheers,
</wqw>
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
wqweto
You mean no one is simply using GdipCreateBitmapFromHBITMAP and GdipCreateBitmapFromHICON in their samples with the StdPicture handle?
That's because both of these drop alpha channel altogether when passing a 32-bit hDIB (wrapped in an hIcon or not) so the way to go is simply to call GdipCreateBitmapFromScan0 with PixelFormat32bppPARGB by using the array of ARGB quads backing the actual DIB, the so called lpBits.
cheers,
</wqw>
I have it working. The only thing that left, When using WindowsLess = true. the "usercontrol.HDC" is available ONLY if runs the event UserControl_Paint. The problem is I can't run the redraw procedure from a Timer, because reading usercontrol.hdc throws error. And the redraw procedure needs it to set up the target graphics class for GdiPlus.
any idea how to force usercontrol.hdc to be readable from a timer?
-
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
flyguille
any idea how to force usercontrol.hdc to be readable from a timer?
You mostly don't need painting code outside of Paint event.
Just call Refresh method in the timer proc and it will raise Paint event with hDC already setup.
cheers,
</wqw>
-
1 Attachment(s)
Re: [RESOLVED] How to develop a border smooth(anti-aliased) rounded-rect button user
Quote:
Originally Posted by
wqweto
You mostly don't need painting code outside of Paint event.
Just call Refresh method in the timer proc and it will raise Paint event with hDC already setup.
cheers,
</wqw>
PROBLEM1:
Yes, I figure out that, but it didn't work, and the surprice is , the _Timer event stop being triggered.
A timer object in windowsless usercontrol doesn't work anymore? ***?
PROBLEM2:
Just setting the usercontrol windowsless... it affects the whole parent form and others VB6 native objects in that parent form??????.
Now, normal native textboxes gets its background transparents, its text area is showing the Windows desktop or any other app background , as if it were a hole in the form. ***? how can be?, the VB.form is borderless/frameless, but it is not transparent, just normal vb.form without frame menues, etc.
It is WORSE, all the timers in the parent form stops working aswell!!!.
Attachment 182868
EDIT: Doing experiments, I removed from the transparent button the windowsless=true , it failed the same way.
remove the backstyle back to opaque, failed the same way
removed back click behaviour, back to Use Region, failed the same way.
ONLY when is back usercontrol.autoredraw = true , everything works again, textboxes are no more transparents, TIMERS in the form and the usercontrol now works, etc.
So, it has nothing to do with it being windowsless, but Autoredraw=false. It breaks the whole EXE functionality.
MISTERY SOLVED?
before doing these modification to allow transparents PNG to work in windowless button mode, so do EASIER skins. The button object supports applying a spot of light and/or darkness, as a skin option.
so, the button redraw procedure was doing a get bitmap using gdi32, from the usercontrol.image, then rework the bitmap in raw YUV math. and use SetBitmapBits to throw the bitmap back to the usercontrol buffer. But, it only works if there is a buffer, that is IF the usercontrol has AUTOREDRAW = TRUE ;) which wasn't anymore with these modifications.
So I suspect the SetBitmapBits was crashing the process thread in some way that it skipped a lot of work , but didn't throw a Windows Exception error, or VB6 error box.
AND THE CHERRY In THE CAKE?
usercontrol.refresh doesn't work if usercontrol.autoredraw = true (with windowsless=true), it doesn't call _paint, so _Paint can't execute Redraw.
Fixed this way.
If UserControl.AutoRedraw Then
Call Redraw
Else
UserControl.Refresh
End If
In every property LET SET, timer, etc.