Cross-platform transparent windows in C++? - c++

I'm wondering how to make a window transparent, not cutout holes or the same transparency overall.
Well, just say I want to slap a PNG image of a rose or something and have it blend nicely with stuff behind and allow stuff behind to redraw and have their changes shine through the transparent parts of the picture/window.
I could (or would like to) use something like wxWidgets or OpenGL. But rather not Qt or GTK.

I found out that it's actually pretty simple to throw up a transparent picture on the screen using wxW:
wxScreenDC dc;
wxBitmap bmp(wxT("test.png"), wxBITMAP_TYPE_PNG);
dc.DrawBitmap(bmp, 250, 100, true);
Now I has to find out how to handle updates and such, it has to be ( maybe partially redrawn ) when something beneath updates.
As it is right now it just redraws itself ontop of itself, making it become fully opacue in a while.
There was another version of wxScreenDC::DrawBitmap that took a window as an argument, maybe it's that one solves this?

How about using shaped frames?
wxBitmap m_bmp = wxBitmap(_T("redroseonwhite.png"), wxBITMAP_TYPE_PNG);
SetSize(wxSize(m_bmp.GetWidth(), m_bmp.GetHeight()));
wxRegion region(m_bmp, *wxWHITE);
bool m_hasShape = SetShape(region);
Look *wxWidgets-2.9.0\samples\shaped* for the full example.

See wxTopLevelWindow::SetTransparent.
If the platform supports it will set the window to be translucent.
So I guess wxWidgets can do it.

If you are willing to do something other than C++, there may be other cross platform options like JavaFx and Adobe AIR.

Related

Is there a way to customize what a button looks like in C++?

I have programmed in HTML, Java, CSS, C++, VB, an Python.
I'm looking to make button that looks completely the way I want it to look!
Like in HTML+Java+CSS, I can do that very thing!
I'm using Netbeans IDE. I was about to just use OpenGL to do the GUI programming for my programs, since it is so hard to find information on customized GUIs.
I just want to learn how to make the image and give button functionality to it. I want to be able to make the shape, color, and effects (when clicked, hovered over, etc).
Oh, and I program in Ubuntu Linux!
Any help would be appreciated!
Qt is a good idea, but you won't learn how it works, though it's not really important and far easier like that. Using C++ you will have libraries that respect the encapsulation principle, so you won't know at the first sight how do is work, just how to use it.
If you really want to code a button yourself, you can take a 2D drawing library such as SFML, with which you'll draw your button and handle events on it.
When I wrote a custom button class for my app, we (the C++ developers) were given PNG images from the designer department. They are much better with tools like Photoshop then we developers. We just showed image1.PNG by default, image2.PNG when the mouse was over the button ("hover"), and image3.PNG when the mouse was over the button and pressed. Drawing? Not necessary.
Color is trivial for designers. Shape isn't hard either. PNGs are rectangular, but can be transparent. So rounded edges are just a matter of a few transparent pixels there.

Draw OpenGL on the windows desktop without a window

I've seen things like this and I was wondering if this was possible, say I run my application
and it will show the render on whatever is below it.
So basically, rendering on the screen without a window.
Possible or a lie?
Note: Want to do this on windows and in c++.
It is possible to use your application to draw on other application's windows. Once you have found the window you want, you have it's HWND, you can then use it just like it was your own window for the purposes of drawing. But since that window doesn't know you have done this, it will probably mess up whatever you have drawn on it when it tries to redraw itself.
There are some very complicated ways of getting around this, some of them involve using windows "hooks" to intercept drawing messages to that window so you know when it has redrawn so that you can do your redrawing as well.
Another option is to use clipping regions on a window. This can allow you to give your window an unusual shape, and have everything behind it still look correct.
There are also ways to take over drawing of the desktop background window, and you can actually run an application that draws animations and stuff on the desktop background (while the desktop is still usable). At least, this was possible up through XP, not sure if it has changed in Vista/Win7.
Unfortunately, all of these options are too very complex to go in depth without more information on what you are trying to do.
You can use GetDesktopWindow(), to get the HWND of the desktop. But as a previous answer says (SoapBox), be careful, you may mess up the desktop because the OS expects that it owns it.
I wrote an open source project a few years ago to achieve this on the desktop background. It's called Uberdash. If you follow the window hierarchy, the desktop is just a window in a sort of "background" container. Then there is a main container and a front container. The front container is how windows become full screen or "always on top." You may be able to use Aero composition to render a window with alpha in the front container, but you will need to pass events on to the lower windows. It won't be pretty.
Also, there's a technology in some video cards called overlays/underlays. You used to be able to render directly to an overlay. Your GPU would apply it directly, with no interference to main memory. So even if you took a screen capture, your overlay/underlay would not show up in the screen cap. Unfortunately MS banned that technology in Vista...

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.

I have a wxwidgets that I want to add some cool effects. Using GDI would be impossibly hard. Could I use flash or something else?

I have an application that I want add some cool animations to show state changes. However, wxwidgets would be difficult because I'd have to program these animations in straight gdi. What's the best way to add these effect windows? Should I open a flash window and run a flash sequence or is maybe some other technology? Does .net have something I could code into a dll and run from my wxwidgets binary? I need something that is super easy to draw and set up the animation.
It's hard to say what the best approach would be to achieve "cool effects", but in most cases you would want a double-buffered drawing surface. That's what I've used in similar-sounding situations.
In wxWidgets, you would want wxBufferedDC.
You could prepare animation as a bunch of images (wxImage loaded from PNG, GIF, JPG or whatever files), and then use a timer and paint them on a control. Maybe it sounds like too much, you I believe you could do it in 50-70 lines of code.
Perhaps you just could make a single widget that has a custom paint-event that hand-draws the various widgets inside it? Then you could draw them at the appropriate locations/sizes without having to involve wxwidgets at all, it would just be a bunch of line-draw/rectangle-draw/text-draw commands to update the display for each frame of animation.

Strange behaviour of edit control background color when using WinXp common controls

I am having a strange problem ( well, at least i find it strange =) ). I am writing my own GUI library, which is a wrapper around windows api (and yes, i am aware of WTL and frameworks like MFC =) ). At the current stage i have incapsulated common controls in such manner: for example, Edit class consists of a simple window and an standard edit window above it ( MainWindow -> GhostWindow -> EditBox ). That is how i can for example change a background colour of an edit inside an edit class itself:
myedit->SetBkColor ( RGB ( 0, 0, 0 ) );
And it worked fine, until i called InitCommonControlsEx and attached manifest file to my program. After doing this, my edits become capable of changing colours only when they have focus. To be honest, i don't have a comprehensive thoughts about why do the behave like this and what am i doing wrong, so i will appreciate any help.
Thank you, #535.
When you attach the version 6 manifest, the call to InitcommonControlsEx becomes unnecessary.
Anyway. with the version 6 common controls loaded, XP theming is used even for the standard windows controls. The background colors for the controls are painted using the xp-theme color, so the WM_CTLCOLOR* messages are used less.
You are currently overriding the coolor of various control elements using the WM_CTLCOLOR* messages?
Well, everything is much easier, than i thought. I was just too inattentive =( When one don't use styling, one cane use ::SetBkColor(...) to change background colour, and return a brush from WM_CTLCOLOR* to change a border colour. Things become different after enabling styling. Now ::SetBkColor(...) correspond to focus colour and returning brush changes background colour. Shame on me =(