-
Re: How to Make nice buttons ?
You'll have to handle double clicks manually, using flags as needed to let you know a double click occurred.
Here's how VB's picutrebox records double clicks:
-- mouseDown, mouseUp, Click, DblClick, mouseUp
Notice that you get 1 mouse down and 2 mouse up events. This means for every double click, you are moving the control up twice, but down just once; hence why it slowly sneaks up. You may want to treat a DblClick event as a mouseDown event. But play with it.
-
Re: How to Make nice buttons ?
Ah now i Understand, thanks Lavolpe for explication, Once back home, I will try to edit the code to solve this problem and will let you know what it gave.
I got some questions please
1- In case I want to give the same shape to many buttons is it better to load my template photos of the button (pressed and unpressed),into two different image boxes, and on form load event of the form, i use the PaintPicture to copy it to each button ? and I use the Picture1.Print "My Caption" to give them caption
Or its better to create for each button 2 images like i did in the zip i attached ?
What is more performant and better to do ?
2- Is it possible with your class Lavolpe to load two different pictures for each button or your class just move the image inside the picture box ?
3- If i want to make an effect that the picture is pressed without moving it, is it doable ? to make it act like pressed and unpressed without moving it the 1px ?
4- can i add a 3rd state which is the mouse hover with red border of the picture ? if yes at which event i should do this ?
5- Any explication for why i see black color flash from time to other ? is it due to speed of vb to refresh pictures ?
-
Re: How to Make nice buttons ?
For your questions:
1) It is best to use just 1 image control (hidden or not) for each image, no matter how many controls may be using that image. Simply uses less resources
2) You can call the RegionFromBitmap routine each time the shape changes, simply include the picture handle of the new shape. If the shape doesn't change, but the picture does, then just use Set Picture or PaintPicture to get the image into the picturebox
Example: The following just references your image control. Set Picture1.Picture = Image1.Picture. Any number of controls can reference the same picture.
3) If you are not changing the image nor moving the control, nor offsetting the drawn image, how will it imitate some pressed state? With a typical button, the image & caption are drawn 1 pixel down/right and the 3D borders (if any) are drawn to the opposite edges of the button.
4) To add any border to your picturebox, you will have to either a) shift the image 1 pixel & have your picturebox 2 pixels larger than needed to display the border without it drawing over the image; or b) simply draw the border and don't care if it covers a bit of the image. Regarding mouse hover, you get a mouse move event, correct? If you use a flag, if the flag is false when mouse move happens, it is the first time mouse enters the control & set flag=true. However, tracking when mouse leaves the control is problematic. But there are ways, some easier with windowed controls. Search for examples: "mouse enter exit SetCapture"
5) Probably, toggling visibility between your buttons is most likely the reason.
-
Re: How to Make nice buttons ?
Thanks again LaVolpe for your support and answers.
Here are my notes about these points
1) I am trying to doing this,Putting 2 images control (1 with the pic of pressed and one with unpressed)
using the
vb Code:
Picture1.PaintPicture Image1.Picture, 1, 1
to copy these pictures as needed to all buttons in my application, but when I do this, I get an ugly background arround the image which is not what i want.
The background that appears is black if I set the transparency of my .gif a value between 1 and 255, and White if i set transparency to 0 (i am setting the transparency using Paint.net) ! By the way, in the image control,I don't see the background,it's just after appliying the PaintPicture
Is there anyway to avoid this ? If not, then I think my only choice will be to create as much pics as I have buttons and use them directly in picture box but it will require much more ressources (2 pics / boutton)
2)Thanks a lot for explication,i got you
3) I didn't say I don't want to offset etc...I wanted to know what are the steps I can do to imitate a real button behaviors , maybe reduce size of image from all sides once clicked ?
4) didn't understand it well how to make a red border,I should draw the border in the picture itself or the picture box border ?
I found this about
mouse enter exit SetCapture, I will try to apply it, thanks for the hint
5) I think the same
-
Re: How to Make nice buttons ?
For your questions.
1) You are not going to avoid the background. Even if you use .Picture.Render vs. PaintPicture, you will avoid that black/white background, but then the picturebox backcolor will show.
3) Reducing the image is one option. Personally, I like the control moving myself, but that's my preference.
4) Drawing the border around the shape of the image will be challenging. The RegionFromBitmap can help there since it can return a region handle vs. shaping a window. With the returned region handle the API FrameRgn can be used to outline the region, then destroying the region & brush handles when done.
Good night, good luck. Heading to bed a bit early tonight; guess I'm getting old ;)
-
Re: How to Make nice buttons ?
LaVolpe, thanks again
1) What are the remaining options ? to load for each button it's own picture right ? do I have other choice ?
From what you say, I may also try to use .Picture.Render and set the background of the image box to the same color as the form so that it won't appear right ? I will search about how to use the .Render and test
3) What functions do I need to reduce the size ? Just to learn how to do and see what it give as effect
4) I think the week-end I will work on that part but before let me end from previous problems :)
-
Re: How to Make nice buttons ?
1) .Picture.Render will draw the GIF with transparency. You can look at the link in my signature below: "stdPicture Render Usage". Making your picbox backcolor same as form should fake picbox transaprency well, but won't help if your picbox is placed over graphics or gradient background. In that case, more complex code required to transfer form background contents to the picbox to fake transparency.
3) None. .Picture.Render can draw an image stretched/scaled as can PaintPicture
-
Re: How to Make nice buttons ?
LaVolpe, thanks a lot, I am reading now about the render at least to learn, but guess what :
1)If i use what you said in post #63
vb Code:
Set Picture1.Picture = Image1.Picture
I won't get a background like with paintpicture, so I think this will be better than looking for complicated things right ?
Please can you explain to me the advantage of using the class you provided me, if I compare it to : create a gif with transparent background (alpha 0), then loading it into picture box ? I am asking because it's time for me now to decide what methode to use.
-
Re: How to Make nice buttons ?
The only advantage of using that class is to shape the window to an image. That's all, in this case.
-
Re: How to Make nice buttons ?
You mean by "window" the picture box ? so that it's changing the rectangle of picture box to give it the shape of the image inside it instead of beeing rectangle ?
-
Re: How to Make nice buttons ?
Yes, of course. I thought you played with the example I posted awhile back?
-
Re: How to Make nice buttons ?
I have tried it before, but yesterday i wanted to take a decision so i started messing with it again and realized that if the picturebox has a border the class doesn't change anything, that's why
-
Re: How to Make nice buttons ?
Not true exactly. If the picturebox has a border, the left/top edges of the border may be left over. Same applies to shaping whole forms. Use borderless windows.
-
Re: How to Make nice buttons ?
Can you explain me why?
Can we use your class also to shape a whole form or only stdpicture ?
I am asking because even if i didnt use it to make my buttons now, surely i will use it for later projects, because simply its very fast and nice
-
Re: How to Make nice buttons ?
A form is a window, a picturebox is a window. A window is a window. Applying a region via the API SetWindowRgn doesn't care what kind of window it is as long as it has a window handle. The class works for all windows that have a window handle. How the region is created/shaped is important to the overall effect. Borderless windows should be used and if not, the region should be offset to account for borders. A region can be created from a bitmap as is done in that RegionFromBitmap routine, it can be circular, rectangular, oval, etc, etc using Windows region-based APIs too.
But regions can be used for far more than shaping windows as briefly described in previous posts. If you want to play with regions more, got to PSC and search for: LaVolpe Regions. You'll find several projects of mine that use regions in unusual ways.
-
Re: How to Make nice buttons ?
I am trying to create a border to my button based on what you said but I am not succeeding !
I tried to use the region class, that way :
I read that if i pass second parameter 0 to your class that it returns the hwd of the shaped region, based on this I did the follwing :
vb Code:
Dim hBrush As Long
Dim RegionHandle as Long
Dim cRgn As New clsRegions
hBrush = CreateSolidBrush(vbRed)
Me.BackColor = vbYellow ' just to show the picturebox is indeed shaped
RegionHandle = cRgn.RegionFromBitmap(Picture1.Picture.Handle, Picture1.hWnd) 'to shape
RegionHandle = cRgn.RegionFromBitmap(Picture1.Picture.Handle, 0) 'to get the 'handle
FrameRgn Picture1.Picture.Handle, RegionHandle, hBrush, 1, 1
by the way, when I pass 0, the background of the image appears so it seems it's not 'shaped , but didn't understand how to get the handle if i don't pass 0 ! SO i did these 2 lines
vb Code:
RegionHandle = cRgn.RegionFromBitmap(Picture1.Picture.Handle, Picture1.hWnd) 'to shape
RegionHandle = cRgn.RegionFromBitmap(Picture1.Picture.Handle, 0)
-
Re: How to Make nice buttons ?
In your 1st example. Caching RegionHandle in line 7 is unnecessary as it will be the result of SetWindowRgn when called to shape a window (see section of RegionFromBitmap where that API is called). Line 8 is correct. Line 9 is incorrect. The first parameter of FrameRgn is a DC
Code:
FrameRgn Picture1.hDC, RegionHandle, hBrush, 1, 1
Do not forget to destroy the region handle and brush handle
-
1 Attachment(s)
Re: How to Make nice buttons ?
Thanks, but it still not working(check attached pic) , it seems that I am still missing something , here is what i did :
vb Code:
Private Sub Command1_Click()
Dim hBrush As Long
Dim RegionHandle As Long
Dim cRgn As New clsRegions
hBrush = CreateSolidBrush(vbRed)
Me.BackColor = vbYellow ' just to show the picturebox is indeed shaped
RegionHandle = cRgn.RegionFromBitmap(Picture1.Picture.Handle, 0) 'to get the 'handle
FrameRgn Picture1.hDC, RegionHandle, hBrush, 1, 1
DeleteObject hBrush
DeleteObject RegionHandle
End Sub
is this the good way to delete the region and brush ? i saw this in your code at pscode, but want to make sure and if they are other ways to delete or not !
vb Code:
DeleteObject hBrush
DeleteObject RegionHandle
-
Re: How to Make nice buttons ?
I don't see anything wrong, I'd expect to see a red border hugging the image shape. Ensure Regionhandle is non-zero. If AutoRedraw=True, try refereshing your picbox. Ensure you are not drawing over the border with any later lines of code. You are deleteing the handles correctly.
-
Re: How to Make nice buttons ?
Thanks LaVolpe , I could make it works but there are things am not understanding :
I added the to previous code and this made the red border appears. I tried to change autoredraw from true to false, nothing changed same effet, it's only the .Refresh that gives effect.
The problem is that there is a background arround the picture (the grey background you see), to avoid this, i had to make after the Picture1.Refresh, the following :
vb Code:
cRgn.RegionFromBitmap Picture1.Picture.Handle, Picture1.hWnd
otherwise i get always the background !
Any explication what autredraw is not changing anything and why i had to call again the RegionFromBitmap to avoid the background ?
Here is thefinal code that worked to give the border arround
vb Code:
Private Sub Command1_Click()
Dim hBrush As Long
Dim RegionHandle As Long
Dim cRgn As New clsRegions
hBrush = CreateSolidBrush(vbRed)
Me.BackColor = vbYellow ' just to show the picturebox is indeed shaped
RegionHandle = cRgn.RegionFromBitmap(Picture1.Picture.Handle, 0) 'to get the 'handle
Debug.Print RegionHandle
FrameRgn Picture1.hDC, RegionHandle, hBrush, 1, 1
Picture1.Refresh
cRgn.RegionFromBitmap Picture1.Picture.Handle, Picture1.hWnd
DeleteObject hBrush
DeleteObject RegionHandle
End Sub
-
Re: How to Make nice buttons ?
When you supply the picbox hWnd to the RegionFromBitmap, you are shaping the picturebox; therefore, the background disappears because it is cut away from the picturebox. The picturebox is no longer a rectangle; this is the key for understanding why you don't get the background color. The region once applied to a window to shape it is no longer yours to play with. Windows owns the region and per MSDN, you are never to reference that region again and are not to delete that region. If you are not setting the region to shape a window, always destroy that region at some point.
So to draw a border also, you'd call the routine 1 more time and frame the region, a different handle will be returned each time you call that routine. Whether you use AutoRedraw or not is up to you. AutoRedraw will keep the border should you minimize then restore the form or drag another window over your "button"; otherwise, it will be erased and you'll have to draw it again.
Last but not least, since this is your first time playing with creating GDI objects that need to be destroyed, I'd strongly suggest you spend some time reading my tutorial on Memory Leaks (linked in my signature below). I'd say it is an extremely high probability that you will write leaky code until you become fully aware of how leaks are created and how to prevent them. That tutorial will help.
As for the order of what you want to do
1) Shape the window first
2) Frame the region
3) Refresh the picturebox as needed
If you want to get a little more efficient, here's what you can do to call the routine only once
Code:
...
' AutoRedraw should be True for this method
RegionHandle = cRgn.RegionFromBitmap(Picture1.Picture.Handle)
FrameRgn Picture1.hDC, RegionHandle, hBrush, 1, 1
SetWindowRgn Picture1.hWnd, RegionHandle, True
DeleteObject hBrush
' don't delete the RegionHandle because you used it to shape the window with SetWindowRgn above
-
Re: How to Make nice buttons ?
LaVolpe Thanks a lot for your explications, I will read the mentioned tutorial, am learning lots of things from you, thanks a lot.
1) Still I don't understand why if i pass the second parameter to 0 to RegionFromBitmap, the picturebox is not shaped and the backgrounds remain ?
2) I didn't understand why not to do this :
Quote:
' don't delete the RegionHandle because you used it to shape the window with SetWindowRgn above
I mean if i Called After the SetWindowRgn ,what is wrong with that ?
vb6 Code:
DeleteObject RegionHandle
This Code works good
vb Code:
Private Sub Command2_Click()
Dim RegionHandle As Long
Dim cRgn As New clsRegions
hBrush = CreateSolidBrush(vbRed)
Me.BackColor = vbYellow ' just to show the picturebox is indeed shaped
' AutoRedraw should be True for this method
RegionHandle = cRgn.RegionFromBitmap(Picture1.Picture.Handle)
Debug.Print RegionHandle
FrameRgn Picture1.hDC, RegionHandle, hBrush, 1, 1
Picture1.Refresh
SetWindowRgn Picture1.hwnd, RegionHandle, True
DeleteObject hBrush
End Sub
-
Re: How to Make nice buttons ?
1) It isn't shaped because you didn't pass an hWnd. Passing zero returns the region handle, it doesn't apply the handle to a window because zero was passed. Shaping a window is like taking scissors to it and cutting around the image, excluding the color that is to appear as "transparent"
2) Reference
Quote:
Originally Posted by MSDN
After a successful call to SetWindowRgn, the system owns the region specified by the region handle hRgn. The system does not make a copy of the region. Thus, you should not make any further function calls with this region handle. In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.
3) You shouldn't have to call Picture1.Refresh in your sample code. That's what that True parameter in the SetWindowRgn API call is suppose to do
-
Re: How to Make nice buttons ?
1) thanks , so calling it with 0, it will just return the handle without shaping it , right ?Thus, if i want to only use this method, i have to call it twice once to shape and once to get the region handle to be able to use it by FrameRgn ,right ?
2) lol, ok thanks :), in fact if i asked this question it's because i tried to delete the handle and no error occured, all worked well, so i said why not to delete it :)
but after i see that msdn confirms that they will automatically deleted it, then ok no need let windows do it by its own , i won't help it :D
-
Re: How to Make nice buttons ?
Quote:
Originally Posted by
justgreat
1) thanks , so calling it with 0, it will just return the handle without shaping it , right ?Thus, if i want to only use this method, i have to call it twice once to shape and once to get the region handle to be able to use it by FrameRgn ,right ?
Yes. That class was not designed solely to shape windows, but to return regions that could be used for a myriad of other purposes.
Calling it twice? Depends on whether you use just the class to do the work.
Either a) call it twice, once to shape the window, once to frame the region & delete handle or b) call it once, frame the region & use same handle in SetWindowRgn call & don't delete handle.
Edited: Note that the full version of the class (mentioned/linked much earlier in this thread @ post#23) had functions/calls that included about 99.9% of all region-related API calls, including FrameRgn for example. Even if you don't want to use the full version of the class, it can still be a good reference for region-related functions.
-
Re: How to Make nice buttons ?
Thanks a lot LaVolpe.
Is there a way to make nice fonts on the button ? because the fonts i showed above are generated by the website as picture, but now i have to be able to make my own caption to change it depending on the button ?
-
Re: How to Make nice buttons ?
You can use whatever fonts your system makes available to you and at whatever size you need. Simply set the usercontrol's Font property to that font and then something like this:
Code:
UserControl.CurrentX = someValue
UserControl.CurrentY = someValue
UserControl.Print sCaption
To create fancy fonts where the font interior is filled with color or patterns, then you will want to research paths.
To use APIs to create fonts and draw text with more advanced options, research DrawText & CreateFontIndirect APIs.
-
Re: How to Make nice buttons ?
Thank you,
? does this mean search the forum ?
Yes it seems what i want is what you called fancy fonts(sometimes i don't find the right english words :blush:), like the font used on the picture that i attached above and that i used in my button.
I will look at pscode for fancy fonts, but didn't get something interesting yet, i will keep searching, if u got any thread about, please let me know.
-
Re: How to Make nice buttons ?
"Fancy" is just a word I used. Paths are graphics objects, similar to regions, that can be filled and outlined using APIs. By paths, I'm referring this
-
Re: How to Make nice buttons ?
Thanks ,
I started searching for on pscode and guess what !
what usually I find that you did already what i want !! You made something called word art HERE !! it's exactly maybe what i want, write something like this on my button !! so if i want to avoid the complicated code in your project what part should i focus on it ?
-
Re: How to Make nice buttons ?
Don't recommend jumping to that wordart project. It uses GDI+ and is pretty dang complicated. I'm not supporting the project either. So if you want to use the code therein, use at your own risk. I developed that for self-education purposes.
-
1 Attachment(s)
Re: How to Make nice buttons ?
So what do you suggest me ? simply print a normal caption on the buttons ? or i try to make nice captions by searching for paths ? is it hard to use paths ? or it's simple ?
Can you check the attached code and tell me if you think it's good to do this effet I used in the attached code the idea you suggested first, to have 3 images (normal, mouse down, hover) and I loaded the 3 images based on the event...using the set property ...
Plz check (not the code, but the effect) and tell me what do you think ? :)
if yes then only thing I still should work on, is the caption :(
-
Re: How to Make nice buttons ?
1- Please Can someone Tell me how when I want to write my caption on the picture box button, to specify the size and color of the Caption ?
2- Is there a way to use an imagecontrol instead of Picture box ? And to be able to write a caption on it ?
Because I found that the stretch method that has the image control is easiar to make on design time the button size !
I tried to use the render method of Velop it's stretching the picture, but I can't understand why the stretch of the image control is not exactly the same (maybe it's the ident ?) !
3)Is there a way when I copy from imagebox to picture box, to make a code that ensure that i have the same stretch and image size as the picture inside the image box ? Thus, i can use the imagebox to strech my image and copy it to use it inside a picture box with beeing sure i have same size, settings, ident etc...
-
Re: How to Make nice buttons ?
LaVolpe, Is there a way to use your class to make a frame or an option box or such controls transparents ?
-
Re: How to Make nice buttons ?
Quote:
Originally Posted by
baja_yu
Create an image you want to use as a button, then load it into a borderless picturebox and use the pictburebox as a button.
To get the windows look and feel you can manifest your application to get the XP styles (using regular controls), but the upper method gives you more freedom.
EDIT: You can do pretty much anything with images. Here's a very old example where I illustrated how to create a custom tab control with images (attachment in post #14)
http://www.vbforums.com/showthread.php?t=309279
EDIT2: In addition, you can create several version of the image like: normal, selected, pressed_down, and use MouseDown event for example to show it pressed down while you hold the mouse then switch back to normal (or to selected) on MouseUp (or Click).
Thanks this helped me btw. :bigyello: