Visual C++ Transparent BackColor of Button - c++

I know this question has been already asked quite some times, but i would like to specify it. I got an image, which displays a circle blue X and I would like to make my own exit button in a Windows application form.
To do that, i added a button in the form and loaded the image on the button. However, the backcolor of the button ruins the image as it is grey. So i have tried:
private: System::Void button1_Paint(System::Object^ sender,
System::Windows::Forms::PaintEventArgs^ e) {
this->TransparencyKey = BackColor;
}
This doesn't work at all (The backcolor is still grey). So i have tried this:
private: System::Void button1_Paint(System::Object^ sender,
System::Windows::Forms::PaintEventArgs^ e) {
this->BackColor = System::Drawing::Color::Transparent;
}
Here i got a message: This control doesn't support transparent colors
Ok, so how am i gonna do this?
thanks

In WPF as well as win32, controls or child windows in general can't have color transparency.
But they can have a non rectangular region. Any shape, including holes.
Use the control's region property to change it's region. There's an example in this link on how to draw a round button.
FYI, pixels that are outside the region are NOT receiving any messages/notifications.
Examples of crazy shaped controls:
Button shaped like a person's head.
Spiral shape.
3 triangles that do not touch each other.
Chess board - every 2nd pixel is transparent.
Also, a region is dynamic, can be changed after object creation, so your button can grow and shrink...
It's also pretty fast.
Limitations:
No alpha blending - either opaque or fully transparent.
I wrote a function (C++/win32) that takes a control and a BMP, both have the same size, scan the BMP for a "tranparent" color (you decide which color) and remove all pixels in that color from the region of the control. This is about half a screen of code.

Set the Background-property to Transparent:
btn->Background = System::Drawing::Color::Transparent;
By the way, don't do this in the Paint-Handler. Instead, do it in the constructor or any initialization function.
Update:
Ok, got it - it's a Windows Forms application. See this C# Windows Form Application Transparent button link for some solutions for your problem.
Another possibility (that I have used in projects before) would be to use a PictureBox instead and listen to the MouseClick-event.

Related

MITK Segmentation draw Rectangle

I have to segment a few things in a dataset I have (.nrrd-file) by drawing a rectangle around the area of interest and saving the segments (also as .nrrd-files).
I tried everything in the Segmentation-Tool that comes with MITK but I cannot seem to find a way to draw rectangles. I also tried to do some key combos (like holding shift, ctrl or alt) while drawing but in vain.
I know I can use the Measurement-Tool to select rectangles and save them (as .pf-files), but using that I'd have to write a some code to convert those selected rectangles into rectangle segmentations later on.
Does anyone know whether there's a possibility (that I didnt find yet) to draw rectangles in the Segmentation tool, or some other way so there's no need to write a workaround?
You can use the Image Cropper plugin in MITK 2016.11 for rectangular image masking and cropping (scissors icon).
Open the plugin, select your image in the Data Manager and click on the New button in the plugin to create a bounding object. You can modify the rectangular bounding shape in the render windows by dragging its red handles. You can move the whole shape by hovering over the bounding shape (it will turn green), click, and than drag.
Click on the Mask button if you want to get an image with the same dimensions in which all pixels outside the bounding shape are set to a user defined value (see the Advanced settings in the plugin). Click on the Crop button otherwise.
Note that you can always press F1 in any active MITK plugin to open a help page with detailed instructions.

Draw on screen with GDI+ (or GDI) similar to Inspect

I'm trying to draw on the screen (the whole screen, on top of every other window) using GDI+.
I've passed NULL to GetDC to get a HDC to the screen, and then used that to create a Graphics object, and used DrawRectangle to draw rectangles on the screen.
Everything works..except...the inside of the rectangle won't update.
Like if I draw it over a command prompt, and move the command prompt, the inside of the rectangle remains black.
I expect to see whats under the rectangle.
Here's the code that's doing the drawing..
Pen BluePen(Color(255, 0, 255, 0), 2);
Graphics graphics(screenDC);
graphics.DrawRectangle(&BluePen, myRect);
Pretty simple, so is there something I have to do to get the inside of the rectangle to update when the screen does? Or to get it truely transparent.
================= EDIT =================
Well I had given up on this, and assumed it wasn't possible, until...I realized the Inspect tool that comes with the Windows SDK does this perfectly.
I would like to recreate something similar to the highlight rectangle, and if I select a window (such as Firefox) and then bring Inspect into focus I can move it around freely with everything being updated perfectly.
There's not even any flickering.
So...does anyone know how Inspect manages to do this?
Also answers in GDI instead of GDI+ are fine...
In windows the screen (and the windows ...) surface(s) are ... volatile, like sandboxes. The "overlapping" of windows and the re-painting of uncovered surfaces is an illusion made by proper event management.
Everything is drawn remain there until something else is drawn over it.
"Uncovering" a surface makes the window representing that surface to receive a WM_PAINT message. It's up to that window procedure to react to that message by re-painting everything is supposed to be under it.
Now, unless you intercept somehow the WM_PAINT message that is sent to the desktop window, you have mostly no chance to know the desktop needs a repaint and hence your paint code will not be called and no repaint will happen. Or better it happens following just the desktop window updating code, that's not aware of your paint.

MFC Image Button with transparency

I'm updating an MFC dialog with a number of buttons on it.
At present, the dialog has a Picture control covering the whole dialog providing a patterned background. On top of that, each button is a CBitmapButton using (opaque) images carefully generated to match the area of background they cover.
It would obviously be much easier if the images could be created as mostly transparent, so the background shows through automatically. However, I can't work out how to get MFC to render transparent images correctly in this case.
I understand that I might want a different class to CBitmapButton, or need to write a custom subclass; that's fine, but I don't know where to start. It would be nice to support 32-bit BMP or PNG with alpha channel, but I'd settle for the "specified colour should be transparent" type.
It may not be the best way to do it, but what I'd do is create a custom CButton derived class (assuming that you're actually using the rest of the CButton functionality), then override the DrawItem function to put your custom draw code in.
For the image itself I'd use a Bitmap GDI+ object (which will allow you to load either BMPs or PNGs with alpha channels) then use the regular DrawImage function to draw the bitmap.
If you're going to put PNGs into your resource file then you need to put them in as a "PNG" type. Make sure when you look in the resource file code that the entry looks like
IDB_PNG1 PNG "C:\temp\test.png"
and doesn't try to treat it as a BITMAP resource otherwise you'll have problems loading them.
Edit
Putting my response here so I can post code. Yes, I meant to derive a custom class from CButton, then add a Gdiplus::Bitmap member variable. Here is roughly what you'll need to do to get it to work, though I haven't checked that the code actually compiles and works, but hopefully you'll get the idea. It's not the most efficient way to do it, but if you've not done much custom drawing before then it does have the advantage of being simple!
void CMyButton::LoadImage(const int resourceID)
{
m_pBitmap = Gdiplus::Bitmap::FromResource(NULL, MAKEINTRESOURCE(resourceID));
ASSERT(m_pBitmap);
}
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);
CRect rcClient;
GetClientRect(&rcClient);
if (lpDrawItemStruct->itemState & ODS_SELECTED)
{
// If you want to do anything special when the button is pressed, do it here
// Maybe offset the rect to give the impression of the button being pressed?
rcClient.OffsetRect(1,1);
}
Graphics gr(lpDrawItemStruct->hDC);
gr.DrawImage(m_pBitmap, rcClient.left, rcClient.top);
}

Strange winAPI behaviour

I have sub classed a tab control to give it a background. I have used the clipping functions to clip the drawing area to the update region. This works, except for when I move the window of the screen and back again.
When it does this, it occasionally sets the clipping region to the whole screen. This is fine except that none of the controls redraw and end up hidden behind the background. How do I know whether or not to redraw the background when I get this update region. It would be 100x easier to develop this if I saw the source code for the tab control, but that isn't going to happen.
All help or suggestions welcome, but I really do need a straight-forward answer.
By "clipping region" I assume you mean the area that has to be redrawn that windows passes to you.
Try this: The paint message handler should bitblit the area of the background image that corresponds to the part of the window that needs to be refreshed (so you don't draw over things that don't need updating). Then let the base class handle the rest.
If it's setting the repaint region to the entire window the tab control code should redraw everything after you've painted the background.
Having code to look at would help

Custom draw button using uxtheme.dll

I have implemented my custom button inheriting from CButton and drawing it by using uxtheme.dll (DrawThemeBackground with BP_PUSHBUTTON).
Everything works fine but I have two statuses (Normal and Pressed) which Hot status is the same. It means when the user places the cursor over the button it is drawn alike regardless the button status (Pressed or not).
This is a bit confusing to the user and I would like to change the way the button is drawn in Pressed & Hot status. Does anybody know a way?
I have also thought about custumizing the whole drawing but the buttons use gradients, borders, shadows, etc. So it is not easy to achive the same look&feel drawing everything by myself. Is there a way to find the source code of the dll or know how to do it?
Thanks in advance.
Javier
Note: I think I could be able to achive what I want to do by using CMFCButton and overriding the OnDraw method. Let the control draw the button on OnDrawBorder and then drawing the inside button myself. But I need to know how the control draws the inside button when pressed. It is a gradient and I can't guess how it's done. Does anybody have a clue?
In answer to your second question, if you derive from CMFCButton instead of CButton you can override OnDraw() or OnDrawText() instead of the usual DrawItem(). That way the default button background will be drawn, and then your drawing code is executed.
The only way I know of to really tackle this is to use 'custom draw', rather than 'owner draw'. Custom draw came in with Windows 2000, but is only used by button controls with comctrl32 6.0 (so Windows XP onwards), isn't very clearly documented, and isn't something MFC goes out of its way to support.
Anyway, the good thing about custom draw is that it lets you hook in at various points in the drawing process, unlike owner draw, which makes you deal with the whole thing. Have a look in MSDN at the NM_CUSTOMDRAW notification message.
For the other part of your problem, detecting the 'hot' state, the easiest way to do this is to use WM_MOUSEMOVE messages and the TrackMouseEvent() function to track whether the mouse is over your button.
Unfortunately this is a bit of a vague answer: the amount of code you need to demonstrate a button that uses custom draw is a bit too much to type into these answer boxes! I do have a project that demonstrates such techniques, using a custom draw button (falling back to owner draw on older Windows versions) that adds a little arrow to the button. You can have a look at the source code by getting
Windows_UI_source.zip
Open it and have a look at the "DropArrowButton" class. The important bit is the OnCustomDraw() handler and its helper function DrawControl(): these get called at the various button drawing phases, and use UxTheme to draw the control appropriately.
I finally figured out how to achive what I want to do. It's pretty easy indeed.
I use two calls to DrawThemeBackground. The first one with PBS_PRESSED and the second one with state PBS_HOT. Then I make a ExcludeClipRect to avoid from drawing over the center of the button.
Something like this:
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_PRESSED,
&pCustomDraw->rc,
NULL);
CDC *pDC = CDC::FromHandle(pCustomDraw->hdc);
CRect rectClient;
GetClientRect(rectClient);
CRect rectInternal = rectClient;
rectInternal.DeflateRect(4,4);
pDC->SelectClipRgn(NULL);
pDC->ExcludeClipRect(&rectInternal);
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_HOT,
&pCustomDraw->rc,
NULL);
pDC->SelectClipRgn(NULL);
Of course this is not the whole code but I think is enough to make my point.
Thanks.