Draw inside a win32 HRGN object - winapi

I am implementing a border control in win32, and I have implemented various styles for that border. I am using simple MoveTo() and LineTo() commands for drawing the border.
My problem is, when i select some new style for my border, it starts painting over the currently drawn border. I understand i need to refresh/repaint my window inorder to have a fresh canvas. I am using InvalidateRect() for now to achieve this purpose. But I am concerned, If i have other windows associated with my border control window (as child windows), how will this effect the child windows?i will need to repaint everything on this window, correct?
Secondly, Is there anyway I can draw lines inside a GDI Region (HRGN)? So far, all i have come across is how to fill up that HRGN with some fill color. Is there anyway i can retrieve HDC associated with that particular HRGN object??

This is not a concern, anything you draw is automatically clipped by the child window rectangles. No extra code is required. The underlying window style flag is WS_CLIPCHILDREN.
You cannot draw lines in a region nor are they associated with a device context. Other than by drawing the region and then drawing the lines in your paint message handler. You are probably interested in paths. The MSDN docs start here.

Related

Can we avoid WM_PAINT when using ScrollWindow in win32?

I am new to win32 programming and have a very naive question.
Say there is my application window of size 1920x1280 and I create a child window over it of size 1920x2560 (double of vertical screen size). Now I load an image onto this child window which has the same size as that of child window i.e 1920x2560.
Now my question is If I use ScrollWindow for vertical scroll, will I necessarily need to repaint the dirty rect (the bottom part), since the image would be already loaded? Is it not possible to avoid that and just move the screen buffers ? Or is there any other way possible to avoid redrawing, may be using bitmaps or something?
An application draws in a window when scrolling, changing, or
selecting a portion of the displayed
data
but you could only draw the differences in the Update Region.
It's also noted that disabling the default handling for the WM_ERASEBKGND message makes smooth.
The disadvantage of your idea is always drawing outside of client area and how to just move the screen buffers to avoid redrawing?

Common Controls on a Transparent Window?

While there are lots of variations of the question, there doesn't seem to be a specific answer to a simple case of wanting to use built-in common controls on a transparent window using Win32. I don't want the controls to be transparent, I just want the border around it to be transparent. I can't believe MS didn't update the .dll's to handle transparency when they added it, but I guess they forgot? Is there a specific method that works. A button can get close with WS_EX_TRANSPARENT, but flaky where it works most of the time but at times part of the border shows up. Edit controls, change depending on when get focus or not.
So the question is simply:
Is there a way to make common controls on transparent window so there is no white border around them?
If not, is there a good replacement library that does it via owner draw?
If some, which ones and what is the method?
Seems silly to reinvent the wheel just because of the area around the control.
TIA!!
If I am not mistaken, you can take the following steps to achieve this effect.
1.Create a GDI+ Bitmap object with the PixelFormat32bppPARGB pixel format.
2.Create a Graphics object to draw in this Bitmap object.
3.Do all your drawing into this object using GDI+.
4.Destroy the Graphics object created in step 2.
5.Call the GetHBITMAP method on the Bitmap object to get a Windows HBITMAP.
6.Destroy the Bitmap object.
7.Create a memory DC using CreateCompatibleDC and select the HBITMAP from step 5 into it.
8.Call UpdateLayeredWindow using the memory DC as a source.
9.Select previous bitmap and delete the memory DC.
10.Destroy the HBITMAP created in step 5.
This method should allow you to control the alpha channel of everything that is drawn: transparent for the background, opaque for the button.
A similar discussion: Transparent window containing opaque text and buttons

Draw themed combobox on windows

I try to emulate the look of a themed noneditable combobox (CBS_DROPDOWNLIST) using DrawThemeBackground. I supply the part CP_READONLY, which apparently draws the background of a themed combobox:
DrawThemeBackground(theme, dc, CP_READONLY, CBRO_NORMAL, &rectangle, nullptr);
However, it does not contain the dropdown arrow. So, I tried to paint the arrow myself the following way:
rectangle.left = rectangle.right - 20;
DrawThemeBackground(theme, dc, CP_DROPDOWNBUTTONRIGHT, CBXSR_NORMAL, &rectangle, nullptr);
But the above draws the arrow centered within the rectangle on a combobox background including the border, so I cannot use this without having a border within the combobox (which itself already has a border). I used theme-explorer to verify that the arrow is always on a background with borders.
In essence, my question is: How can I draw the background and the arrow at the appropriate position to emulate the look of a plain windows combobox?
What I have found out so far:
I can specify a clipping rectangle to clip away the aforementioned borders. But this poses the question of determining the exact position rectangle and the clipping rectangle: It seems that I can use GetThemeMargins to determine the margins, but that does not tell me how large the arrow is as a whole.
GetThemeBitmap might be useful in determining the exact size of the arrow, but as I read here and confirmed on my machine, using it with TMT_GLYPHDIBDATA does not work as advertised, and I would like to go without any workarounds, if possible.

Direct2D: leave a region of a window render target untouched

I am drawing to a regular HwndRengerTarget but other windows, which have nothing to do with Direct2D, overlap it.
The problem is that these windows get painted over when I draw to the HwndRengerTarget.
I would like to tell Direct2D not to touch a specific region of the HwndRengerTarget (i.e. don't touch the pixels that are already on the screen), so that these windows remain correctly visible.
Is that possible?
If I draw normally then call RedrawWindow on the windows, it flickers a lot.
Thanks.
If you want to manually restrict your rendering to a certain region you can use layers (ID2D1Layer objects).
More info here Layers Overview
If the visible region is rectangular it may be simpler to use axis aligned clips via methods PushAxisAlignedClip and PopAxisAlignedClip.
ID2D1RenderTarget::PushAxisAlignedClip
Another method of restricting drawing to a certain shape is to render it to a bitmap and then use this bitmap via a bitmap brush in the FillGeomtry method.
ID2D1RenderTarget::FillGeometry
Why not arrange the windows (HWNDs) so that the Direct2D one is at the bottom of the z-index? It should be the first child of its parent. Then clipping will be automatic. You may need the WS_CLIPSIBLINGS window style.
I had the same problem.
Fixed by calling CreateWindowEx LAST for the D2D child HWND.
So AFTER all the other child windows are created.

How to draw PNG over dialog controls

I need to make some thing like a SEMI-transparent glass layer over dialog's controls. The context is when my application wait for a long process to finish all other controls need to be disabled, and an animation is shown on glass layer as waiting-animation.
I am going to draw a semi-transparent PNG image with size of client area, overlapping all other controls. I do the drawing in OnPaint() but image is drawn as background of the dialog.
So my question is how can i draw png image overlap dialog's control??
LRs
You can try with fiddling the WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles, but I'm not sure that will work. I think you will need to draw a custom control on top of all other controls (at the top of the z-order stack) and draw your bitmap on that one (that's the approach I would take - the dialog is supposed to be behind the controls always, so your approach of drawing on the dialog is fighting the system, as it were).
So basically you would draw on the custom control that would cover all other controls, but you don't even need to draw it transparently; you can use the WS_EX_TRANSPARENT and/or WS_EX_LAYERED window style and SetLayeredWindowAttributes() method, as long as you don't need to support operating systems older than win2k.

Resources