Strange winAPI behaviour - c++

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

Related

Keep Wingdi graphics permanent

I am making a C++ console application with lots of wingdi graphics mainly revolving around Rectangle() and FillRect() but as it is wingdi, the graphics are not permanent. The graphics get reset when i minimize the console, enlarge it, scroll down and whatsoever. I've seen in some threads that there is no predefined solution so you have to make one of your own.
One thing i tried, was drawing the rectangle once and then attaching a thread with infinite loop that checks the first pixel of rectangle in every iteration, if it's color is black, it draws whole rectangle again. As silly as it sounds, that's all i could think of. I know it's utterly inefficient. Is there any other solution for this?
Although you've been able to use GDI to draw on your application's console window (presumably by calling GetConsoleWindow and then GetDC), it isn't really designed for that. The system has code for the console window that tries to redraw the window itself whenever it needs to update. It's not aware of anything your program does through GDI, so it has no way to preserve that.
If you just need to draw colorful rectangles on a console window, you can do those kinds of things with the Console API. You can set the text colors as needed and draw blocks of spaces or block characters.
If you want to do more general graphics, your program will have to create a (non-console) window, and then you can draw whatever you want whenever your window receives a WM_PAINT message.

WinAPI: How to disable GroupBox's frame?

I need a GroupBox control for something else that showing it in application's window. That's why I want to disable the frame surrounding it (or at least make it invisible by, for example, drawing it with the color that matches with window's background). Both are harder than I thought though, I've been loking for the solution everywhere and found nothing. I don't want to use anything as straightforward as painting over it in WM_PAINT-case in window procedure because there will be that annoying sparkling when I move the window.
I'm running out of ideas, tried a few things on my own, none worked. Anyone have some tips?

Window regions, moving children, DWM, and the white blocky mess it can create

The setup: I have a top-level window with a region defined (created with SetWindowRgn()), and I have a child element that is moved (with SetWindowPos()) such that some of its pixels then overlap the clipped portion of the parent's window region.
The result: Those pixels become filled with fully opaque, fully white pixels, instead of remaining fully transparent (since it's outside its parent's region). It isn't that the child window is being drawn when it shouldn't, as the offending pixels are white regardless of what the child window looks like.
Below, the small orange child window has been moved around a bit along the edge of the parent. This only happens along the edges that have a transparent window region (so the white pixels are always constrained within the maximum rectangle of the parent window).
Things correct themselves if the parent window is hidden and then shown (just invalidating and forcing a redraw does not clear the white pixels).
This has been observed on both Vista and 7. This behavior goes away if I disable the Desktop Window Manager (DWM). In one case, it also went away after updating graphics drivers. Perhaps it's related to this issue?: Vista live thumbnail issue with SetWindowRgn. I was originally going to just file this away as a rare bug, but it's cropped up enough to warrant a lot more scrutiny.
Has anyone else run up against this before? Any insights into how DWM and window regions interact?
Also, I'm aware I can disable DWM per-application, but that disables it for everything while the app is running, in addition to causing the screen to blip on startup and shutdown, and that's really not a much better problem.
I hate to answer my own question again, but I've found a work-around. I found that setting the window's region again clears any of the stray white pixels without causing any ugly redrawing or flashing anywhere else. This works even if the region I am setting is the same as the existing region, so something as simple as this works:
HRGN hRgn = CreateRectRgn(0,0,0,0);
GetWindowRgn( hWnd, hRgn );
SetWindowRgn( hWnd, hRgn, true );
DeleteObject( hRgn );
As an added bonus (or rather as another bizarre aspect of this problem), if I call this shortly before moving the window, then none of the white pixels show up, but to just cover my bases I have it perform this step both before and after animating the translation of any windows.
It may be possible that the issue then lies with some state I'm putting the window into after its creation, which gets cleared by re-setting the region. It'd be nice to know the root cause, but as this feels like I'm working around a driver bug, perhaps I'll just never know what's the root cause.

Black flicker while resizing translucent Qt widget (only when Aero is enabled)?

I have a top-level Qt widget with the FramelessWindowHint flag and the WA_TranslucentBackground attribute set. It has several children, each of which draws an image on it. They are not in a layout. Instead, I simply move them around when something changes (it is not user-resizable).
There are two states to the window - a big state and a small state. When I switch between them, I resize the window and reposition the children. The problem is that as the window resizes, a black box is briefly flashed on the top-level window before the images are painted over it.
The problem goes away if I disable Aero. I found brief mention of this problem being fixed in an article describing a new release of Qt (this release is long past), but it still doesn't work.
Any ideas why?
Thanks!
I don't have experience with Qt specifically, but I have worked with other windowing toolkits. Typically you see this kind of flashing when you are drawing updates directly to the screen. The fix is to instead use Double buffering, which basically means that you render your updates into an offscreen buffer (a bitmap of some sort, in the purest sense of the word), and then copy the entire updated image to screen in a single, fast operation.
The reason you only see the flickering sometimes is simply an artifact of how quickly your screen refreshes versus how quickly the updates are drawn. If you get "lucky" then all the updates occur between screen refreshes and you may not see any flicker.

How to fix an MFC Painting Glitch?

I'm trying to implement some drag and drop functionality for a material system being developed at my work. Part of this system includes a 'Material Library' which acts as a repository, divided into groups, of saved materials on the user's hard drive.
As part of some UI polish, I was hoping to implement a 'highlight' type feature. When dragging and dropping, windows that you can legally drop a material onto will very subtly change color to improve feedback to the user that this is a valid action.
I am changing the bar with 'Basic Materials' (Just a CWnd with a CStatic) from having a medium gray background when unhighlighed to a blue background when hovered over. It all works well, the OnDragEnter and OnDragExit messages seem robust and set a flag indicating the highlight status. Then in OnCtrlColor I do this:
if (!m_bHighlighted) {
pDC->FillSolidRect(0, 0, m_SizeX, kGroupHeaderHeight, kBackgroundColour);
}
else {
pDC->FillSolidRect(0, 0, m_SizeX, kGroupHeaderHeight, kHighlightedBackgroundColour);
}
However, as you can see in the screenshot, the painting 'glitches' below the dragged object, leaving the original gray in place. It looks really ugly and basically spoils the whole effect.
Is there any way I can get around this?
Remote debugging is a godsend for debugging visual issues. It's a pain to set up, but having a VM ready for remote debugging will pay off for sure.
What I like to do is set a ton of breakpoints in my paint handling, as well as in the framework paint code itself. This allows you to effectively "freeze frame" the painting without borking it up by flipping into devenv. This way you can get the true picture of who's painting in what order, and where you've got the chance to break in a fill that rect the way you need to.
It almost looks like the CStatic doesn't know that it needs to repaint itself, so the background color of the draggable object is left behind. Maybe try to invalidate the CStatic, and see if that helps at all?
Thanks for the answers guys, ajryan, you seem to always come up with help for my questions so extra thanks.
Thankfully this time the answer was fairly straightforward....
ImageList_DragShowNolock(FALSE);
m_pDragDropTargetWnd->SendMessage(WM_USER_DRAG_DROP_OBJECT_DRAG_ENTER, (WPARAM)pDragDropObject, (LPARAM)(&dragDropPoint));
ImageList_DragShowNolock(TRUE);
This turns off the drawing of the dragged image, then sends a message to the window being entered to repaint in a highlighted state, then finally redraws the drag image over the top. Seems to have done the trick.