Specify window painting region in WINAPI - c

I'm using one 3rd party SDK which get hwnd (window handle) and paints something on my window. And i want to specify window painting region (left, right, top, bottom) ? How it's possible to do it ? I'm found WINAPI function SetWindowRgn, but it's not good for me because this function specify whole window region. I need specify just window painting area.

SetWindowRgn() is exactly what you need. You can create your region from a rectangle using CreateRectRgn(). A good introduction to window regions can be found here.
Alternatively you can modify the non-client area of your window, but I would not recommend that, because it has several side-effects.

If it's possible to give this library an HDC instead of the window handle - you should do this.
That is, get the drawing DC for your window's client area (GetDC), create the needed clipping region, and set it (SelectClipRgn).
In case your library insists on accepting the window handle - I can propose the following solution:
Inside your window create another child window, set the appropriate region for it. And give the handle of that window to your library.

Related

Determine if window is visible with High CPU

Background
I am trying to screenshot a specific window, however the OS where I need to accomplish this has very high CPU usage and sometimes my application determines this window as visible however in the screenshot it is either not shown or half drawn.
My Understanding
Since the CPU usage is very high it will not be able to provide enough resources to the process which opens this specific window. Therefore the check for window visibility succeeds it may just mean that the window was initiated for creation but not drawn yet (given the lack of resources).
My Code
HWND hWnd = FindWindowExA(0, 0, NULL, programdata->caption);
if (hWnd)
{
if (IsWindowVisible(hWnd))
{
RECT rect = { 0 };
GetWindowRect(hWnd, &rect);
// if window size also matches requirement then
TakeScreenshot();
Question
Is there any better way that I can determine if the window was fully drawn and visible to the human eye?
if the window was fully drawn and visible to the human eye?
To take screenshot you don't need the window to be visible. You only have to copy from its context. So just do GetWindowDC() and use it.
If you really need to check if it's "visible to human eye", you must also ensure that the window is at the top of Z-order. Otherwise, it could be overlayed by some other window.
If you want to check if window was fully repainted, you can test its GetUpdateRect() value.

GTK3 Set GtkButton size

I have a very simple code, wich create a GtkWindow and place in it a GtkButton.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(_window, 800, 450);
gtk_window_set_decorated(GTK_WINDOW (_window), FALSE);
gtk_window_set_position(GTK_WINDOW (_window),GTK_WIN_POS_CENTER_ALWAYS);
gtk_window_set_resizable(GTK_WINDOW (_window), FALSE);
_startbutton = gtk_button_new_with_label("myLabel");
gtk_container_add(GTK_CONTAINER(_window), _startbutton);
gtk_widget_show_all(_window);
Yet, this doesn't work as expected because the button fills the whole window.
I tried to find a way to change the button size, but all the methods that i found use some methods that are deprecated...
Can someone explain to me the way to do this ?
Because the GtkButton is the only control in the GtkWindow, it will be given the entire area of the GtkWindow to fill. If you want to do anything more complicated, you will need to use layout containers like GtkBox and GtkGrid to explicitly lay out the button, usually in relation to other controls that you will also have in the window.
Once you do lay out your controls, you can use expansion and alignment to control how the button makes use of its allotted space.

WPF Window HorizontalAlignent Stretch

I have a simple task that I want to accomplish: Have a WPF window launch with a Horizontal Alignment that is stretched to the total width of the current screen. I want to achieve a kind of custom Overlay MessageBox (I dont want to use third party controls such as MahApps), I am not using any third party references for this.
Please see what I have achieved so far (Not sure if the image will show, the link is http://imgur.com/e27DyNJ):
I have tried setting the width with a Controller object that I wrote which works, that basically sets the Width, Height, Left and Top to the width of the primary monitor. Downside is the window then pops up on the primary screen, not on the screen that is currently in use.
As far as I know, WPF doesn't have any multi-screen functions. You could PInvoke some native Multiple Display Monitor Functions, wrap them in a managed class and utilize them in that regard, though.
As a workaround, I have done the following:
var screen = System.Windows.Forms.Screen.FromRectangle(new System.Drawing.Rectangle((int)window.Left, (int)window.Top, (int)window.Width, (int)window.Height));
window.Width = screen.WorkingArea.Width;
window.Left = screen.WorkingArea.Left;
where window is the instance of my window I want to resize.
This works with the current screen the window was opened on.

Is this how I make custom controls both transparent and flicker-free in Windows? Or do I have one of these steps wrong?

I could begin by asking the question outright or by citing my sources (this, this, this, and this) descriptively, but I'll walk you ll through what I'm trying to do instead.
Let's start with a main window. It has its own window class whose hbrBackground is set to COLOR_BTNFACE + 1. Now let's do
EnableThemeDialogTexture(hwnd, ETDT_ENABLE | ETDT_USETABTEXTURE)
so the tab control we're about to add will be drawn with visual styles. (Try Windows XP with the standard Luna theme for best results.) Now let's add a tab control and two tabs.
On the first tab, we create an instance (let's call it container) of a new window class. This window class is going to hold various controls. I could set hbrBackground to COLOR_BTNFACE + 1, but then it will draw over the tab background. So I want this new child window to be transparent. So what I do is
set the class hbrBackground to GetStockObject(HOLLOW_BRUSH)
set container's extended style to WS_EX_TRANSPARENT
set the class WM_ERASEBKGND handler to do SetBkMode((HDC) wParam, TRANSPARENT); return 0; to set the device context and have Windows draw the transparent background.
So far so good, right? I'm not sure if I'm really doing all this correctly, and I'd like this to also be flicker-free, which doesn't seem to happen: when I resize the window (at least in wine) I get either flicker or garbage drawn (even in child controls, somehow!). Windows XP in a VM just shows flicker. I tried tweaking some settings but to no avail.
But wait, now I want to have another control, one that just draws some bitmap data. On the next tab, create another container, then have a third window class area as a child of that. area only draws in the upper-left 100x100 area and has scrollbars; the rest of the window area should be transparent.
Right now, what I have for area is:
the window class hbrBackground set to NULL and styles CS_HREDRAW and CS_VREDRAW set
the extended window style being 0
the WM_ERASEBKGND simply doing return 1;
the WM_PAINT filling the entire update rect with COLOR_BTNFACE + 1 before drawing, and rendering all of it
This is flicker-free, but obviously not transparent. NOW I'm really not sure what to do, because I want the area to be transparent in such a way that it shows the tab control background. Again, I tried tweaking settings to bring them closer to what I tried above with container, but I got either flicker or invalidation leftovers when I tried.
So how do I get both of these custom control types (the container and the drawing area) to be both flicker-free and transparent?
I presently must target Windows XP at a minimum, though if the solution would be easier with Vista+ only I'd be happy to keep that solution on the side in case I ever drop XP support (unfortunately Stack Overflow doesn't let me hand out silver medals...).
Thanks!
To paint your window in a manner that is "flicker free", you will need to paint your window to a bitmap, then copy the bitmap to the destination device context. On Windows XP, you will need to create a bitmap, adjust the origin of the drawing DC and then paint your window. On Vista and later you can use BeginBufferedPaint and its associated routines to do the buffering for you.
Once you have buffered painting working, you can then use WM_PRINTCLIENT to paint your window's parent window into the your drawing DC before you do any actual drawing. Unfortunately, not all windows will support WM_PRINTCLIENT.
You could consider using DrawThemeParentBackground, rather than WM_PRINTCLIENT directly.
Combining these two methods together will leave you with transparent flicker-free drawing.

Is there a way to capture a bitmap from a WPF window using native C++?

Imagine a document window in a MDI application which contains a child WPF window, say a sidebar for example. How can one get a bitmap containing both the WPF pixels AND the GDI (non-wpf) pixels?
I've discovered that when making my thumbnail preview for the Win7 taskbar app icon hover, I get black in the parts of the preview where the WPF pixels should be. My current method simply grabs a bitmap capture of the document window. Then I get a DC for the preview, make a memory DC from it and select my bitmap into it. Then I do some size adjustments and bitblt the memory dc to the real dc. I'm guessing that the BitBlt operation doesn't take into account the fact that the WPF pixels are hardware accelerated and therefore need to be grabbed from the graphics hardware. All the stuff in GDI is managed just fine, though and when there's no WPF child windows, the preview image looks fine.
I'm wondering if it's at all possible to grab a bitmap of the WPF window from native C++. Then I can blt that onto the black area of the previous preview.
Maybe I'm not understanding your current approach correctly, but could you do a BitBlt() from the screen DC to your memory DC? You'd need to get the screen rect of your window, but that shouldn't be too bad.
To solve this, I had to create an abstract class in native code containing a virtual method to get the bitmap that was implemented in C++/CLI. In the managed implementation, I used .NET's RenderTargetBitmap class to get a bitmap capture of the WPF window and then I filled up the passed in CBitmap object (see How to get an BITMAP struct from a RenderTargetBitmap in C++/CLI?). In the unmanaged caller routine, I used the virtual method to obtain the Bitmap.
In short, there was no way to get the bitmap by simply using unmanaged C++ since WPF and GDI really don't work together for all practical purposes.

Resources