How to use DrawTransparentBitmap() in C++ Builder - c++

Just trying to figure out how to use DrawTransparent in C++ Builder to draw a bitmap or tbitmap with an alpha channel so that the drawn image is semi-transparent with the background image.
I looked all over the place and on this site but can't find anything other than a note that this as well as DrawTransparentBitmap exists..
In the help it is listed as follows:
virtual void __fastcall DrawTransparent(TCanvas* ACanvas, const
System::Types::TRect &Rect, System::Byte Opacity);
However there are no code examples. The compiler doesn't recognize the procedure name and it does not appear as a method of tbitmap...
I am still new to C++ and I could really use some help with this...

DrawTransparent is a protected method so you can't call it directly, but this should work:
// opacity 50
destination_bitmap->Canvas->Draw(0, 0, source_bitmap->Picture->Graphic, 50);
You may need to do source_bitmap->Transparent = true; too.

Related

How to draw a line under the title cells on TDBGrid using C++ in Rad Studio?

I am trying to draw a line under TDBGrid title cells but can't seem to get it to work. I am doing this in the OnDrawColumnCell event like this:
Canvas->Pen->Color = TColor(RGB(0, 0, 0));
Canvas->MoveTo(Rect.Left, Rect.Bottom);
Canvas->LineTo(Rect.Right, Rect.Bottom);
It's signature looks like this:
void __fastcall TfrmModelDetails::dbGridModelMapDrawColumnCell(TObject *Sender, const TRect &Rect,
int DataCol, TColumn *Column, TGridDrawState State)
I am sure that the method is being called after checking the debug information yet nothing gets drawn. Why could this be?
OnDrawColumnCell is not called for title cells. As far as I can see in TCustomDBGrid source code, title drawing is done by an inner procedure you can't change from the outside. Probably you have to derive a new component and override DrawCell which does all the processing.
You didn't show your complete code for dbGridModelMapDrawColumnCell... Be sure to call DefaultDrawColumnCell in front of it and then do your own drawing.
Also, the last pixel line is Rect.Bottom - 1. You are drawing out of view.
And finally, Canvas alone refers to the form, not the grid. You have to either qualify with the DBGrid instance you use or cast the Sender argument to TDBGrid to refer to it's Canvas property.

GTKMM: Take a screen shot of an DrawingArea?

I Have a Drawing Area that I draw some figures or images inside, so I have this callback to take screenshots:
void CanvasToolBox::actionCanvasCamera()
{
auto root = Gdk::Window::get_default_root_window();
int height = root->get_height();
int width = root->get_width();
auto pixels = Gdk::Pixbuf::create(root, 0, 0, width, height);
pixels->save("s.png", "png");
}
That code takes a screenshot of the whole screen..
But I need to take the screenshot of a especific window a Gtk::DrawingArea in my case.. so the function create needs a Gdk::Window as a parameter.
Is there any way to take a screenshot of a Gtk especific window?
Thanks
I'm not used to GTKmm (I use C and Python APIs instead), but with your example, that looks pretty straightforward. You just want to use your Gtk::DrawingArea instead of the root window. So you search in the documentation of Gdk::Window::get_default_root_window and find that it returns a Gdk::Window.
Now you have to find how to get a Gdk::Window out of a Gtk::DrawingArea. So you go to the documentation of Gtk::DrawingArea and search for a function that returns a Gdk::Window, and then find this is Gtk::Widget::get_window, which is inherited from Gtk::Widget. BTW, you may prefer the const version, as you don't modify the window, just read it.
You can then replace code that gets the root windows with a call to get the Gdk::Window of the widget you care about, and you're done. If you want to go further, instead of using Gdk::Pixbuf, there may be a way to use a cairo context.

Qt How to create a QBrush using a RGB Color with QColor and change it later?

At the moment I use this to create a QBrush:
QBrush *goldBrush = new QBrush(QColor(212,175,55));
scene->addRect(0,415,20,50,noPen,*goldBrush);
But apparently this leaks memory.
How else could you do it? I've tried this:
QBrush greyBrush(QColor(212,175,55));
greyBrush.setColour(QColor(120,60,55))
But that hasn't worked either. I want to be able to declare the brush as one colour then be able to change it.
Edit: full problem my bad.
The only way to change the color of a brush is via QBrush::setColor. The brush takes a copy of the color you specify and not a reference.
QBrush my_brush;
QColor red(Qt::red);
my_brush.setColor(red); // my_brush has its own color member internally
// and _not_ a reference to red
Maybe you are used to other programming languages like Java where basically everything is a reference. In C++ there are values semantics.

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);
}

How to save to a bitmap in MFC C++ application?

I am just starting with MFC so please be tolerant ;).
I have wrote (it was mostly generated to be honest) a simple application which should do the Paint chores: drawing lines, rectangulars, ellipses, changing a color of object to be drawn etc.
I need to save what has been drawn on the screen into a bmp file. Any ideas how can I achieve this ?
I do not know if that's relevant but I am drawing objects on the screen without the use of any CBitmaps or things like that. Here is a part of code responsible for drawing :
CPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
Anchor.x=point.x;
Anchor.y=point.y;
OldPoint.x=Anchor.x;
OldPoint.y=Anchor.y;
if(pDoc->shapeCount>=MAX_SHAPES) return;
pDoc->shapeCount++;
if(bFreehand)
{
pDoc->m_shape[pDoc->shapeCount-1] = new Shape;
pDoc->m_shape[pDoc->shapeCount-1]->shape = ePoint;
}
if(bLine)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CLine;
pDoc->m_shape[pDoc->shapeCount-1]->shape = eLine;
}
if(bRectangle)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CRectangle;
pDoc->m_shape[pDoc->shapeCount-1]->shape = eRectangle;
}
if(bEllipse)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CEllipse;
pDoc->m_shape[pDoc->shapeCount-1]->shape=eEllipse;
}
pDoc->m_shape[pDoc->shapeCount-1]->x=point.x;
pDoc->m_shape[pDoc->shapeCount-1]->y=point.y;
pDoc->m_shape[pDoc->shapeCount-1]->x2=point.x;
pDoc->m_shape[pDoc->shapeCount-1]->y2=point.y;
pDoc->m_shape[pDoc->shapeCount-1]->Pen=CurrentPen;
pDoc->m_shape[pDoc->shapeCount-1]->Brush=CurrentBrush;
bButtonDown=true;
SetCapture();
I have found this way to do it but I don't know how to obtain screen width and height to fill it in the CreateBitmap parameter's list
CBitmap *bitmap;
bitmap.CreateBitmap(desktopW, desktopH, 1, 32, rgbData);
CImage image;
image.Attach(bitmap);
image.Save(_T("C:\\test.bmp"), Gdiplus::ImageFormatBMP);
The CreateBitmap call only requires the desktop width and height if the image you wish to save is actually the entire size of the screen. If that's indeed your intent, you can use CWnd::GetDesktopWindow() to get a CWnd object that you can query for its width and height:
http://msdn.microsoft.com/en-us/library/bkxb36k8(v=VS.80).aspx
That gets dodgy in general...if for no other reason than multi-monitor scenarios...so I'd recommend against it unless you really feel like writing a screen capture app.
What you probably want to do isn't to take a full screen shot, but just save the contents of your program's window. Typically you'd do this by breaking out the drawing logic of your program so that in the paint method you call a helper function that is written to take a CDC device context. Then you can either call that function on the window-based DC you get in the paint call or on a DC you create from the bitmap to do your save. Note that you can use a CBitmap in CDC::SelectObject:
http://msdn.microsoft.com/en-us/library/432f18e2(v=VS.71).aspx
(Though let me pitch you on not using MFC. Try Qt instead. Way better.)