I'm programming for Win7+ and using Direct2D for drawing. UpdateLayeredWindow requires a HDC, which means I'd better create a WICRenderTarget(not GPU accelerated). Is there any way to make a semi-transparent window without using UpdateLayeredWindow?
There are only two API functions for rendering layered windows: UpdateLayeredWindow() and SetLayeredWindowAttributes().
UpdateLayeredWindow() requires you to render your window contents to your own in-memory bitmap HDC which the OS then displays when needed.
SetLayeredWindowAttributes() relies on the traditional WM_PAINT model of requiring you to render to an OS-provided HDC instead, which is implemented as an in-memory bitmap HDC that the OS applies effects to after your rendering is finished.
Related
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
Is it possible to use the trick with overriding wm_nccalcsize to draw over entire window area with opengl?
I need to keep all aero features for windows (win 7 in this case), so i use (WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME) styles
It works fine for maximized mode, I can leave the border outside the screen by adjusting the Lparam.
But a regular window still has 8px borders around it, even though they are supposedly part of client rect (which I checked with GetClientRect()
Image: dark-grey border is visible
And this is all done before I init opengl context. So I dont know what's happening. Or if this even possible. Am I supposed to just create borderless and re-implement all aero features? (no way I'm doing that)
upd 2:
If I draw a rect with GDI right before I init Opengl context this is what i get:
a nice (0,0,200,200) rect, starting in the nonclient area
So it is opengl context issue. I saw in msdn docs, that opengl draws only in client area. And it still does that, ignoring that I extended the client rect to whole window. siiiigh.
The usual way to combine Aero with OpenGL is to set the window client area using the DWM API to zero. This allows you to draw to the whole window (including titlebar) using OpenGL. I have this test program to tinker with it as part of my wglarb wrapper:
https://github.com/datenwolf/wglarb/blob/master/test/layered.c
You may also be interested in my dwm_load wrapper, which allows to you call DWM functions without rigidly linking your program against DWM (which makes it incompatible with older Windows versions; you wouldn't believe how often I still get "must run on WinXP" as a feature requirement) https://github.com/datenwolf/dwm_load
I'm trying to create a borderless window using a WS_EX_LAYERED style window. The objective is to render graphics using DirectX directly to the desktop, using alpha to blend onto the current desktop windows.
Now on my system this technique seems to work perfectly. I can set various alpha levels and achieve different levels of transparency. Unfortunately several users have reported severe performance problems and low frame rate, making this technique unusable.
The code setup is as follows:
Create a layered (WS_EX_LAYERED extended-style) window.
Initialize DirectX using the window HWND.
Create a render target using the CreateRenderTarget DirectX method.
Then during the render loop:
Render graphics to the render target using DirectX calls.
Get the HDC handle to the DirectX render target surface using GetDC method.
Update the window contents using the UpdateLayeredWindow function, specifying the DirectX surface HDC.
My question is: Am I doing something wrong? Is there a way to improve the performance of the window update. I have tried various things, like locking the render target and manually copying the bits to a DIB section to display in the window area, without success.
How big is your window? Note MSDN's documentation at http://msdn.microsoft.com/en-us/library/windows/desktop/ms633556%28v=vs.85%29.aspx says "For best drawing performance by the layered window and any underlying windows, the layered window should be as small as possible."
You may be getting a performance boost if compositing (Aero) is enabled. If Windows is already compositing, it won't have to do as much extra work to draw layered windows.
If you're not seeing any difference in performance depending on compositing, then I am probably completely off base here.
So, I am working on a text editor. I use double buffering to paint on to the screen. So basically I have an offscreen bitmap, which I paint on, and then copy it to the screen. Now, when the window for the text editor resizes, I need to resize the offscreen bitmap as well. So what would be a good way to resize the bitmap? I was thinking to maybe delete the old object and create a new bitmap using CreateCompatibleBitmap, but I'm wondering if it's the correct way to do it.
Language : C++ using Win32 API
Using CreateCompatibleBitmap will work, and then you'll want to call BitBlt on it to copy the contents of your existing backbuffer to the resized buffer. I don't think there is a more efficient way to do it using GDI.
If are thinking about using CreateCompatibleBitmap with BitBlt, you might like to look at StretchBlt instead. StretchBlt works like BitBlt but resizes the source image to fit into the destination area.
I use GDI to create some custom textwidget. I draw directly to the screen, unbuffered.
now i'd like to implement some fast scrolling, that simply pixelshifts the respective part of the framebuffer (and only redraws the newly visible lines).
I noticed that for example the rich text controls does it like this. If i use some GDI drawing functions to directly draw to the framebuffer, over a rich text control, and then scroll the rich text, it will also scroll my drawing along with the text. so i assume the rich text simply pixelshifts it's part of the framebuffer.
I'd like to do the same, but don't know how to do so.
Can someone help? (independant of programming language))
thanks!
The ScrollWindowEx() API function is optimized to do this.
See BitBlt function:
The BitBlt function performs a
bit-block transfer of the color data
corresponding to a rectangle of pixels
from the specified source device
context into a destination device
context.
and the example at the end of its documentation: Capturing an Image:
You can use a bitmap to capture an
image, and you can store the captured
image in memory, display it at a
different location in your
application's window. [...]
In some cases, you may want your
application to capture images and
store them only temporarily. [...] To
store an image temporarily, your
application must call
CreateCompatibleDC to create a DC that
is compatible with the current window
DC. After you create a compatible DC,
you create a bitmap with the
appropriate dimensions by calling the
CreateCompatibleBitmap function and
then select it into this device
context by calling the SelectObject
function.
After the compatible device context is
created and the appropriate bitmap has
been selected into it, you can capture
the image. The BitBlt function
captures images. This function
performs a bit block transfer that is,
it copies data from a source bitmap
into a destination bitmap. [...]
To redisplay the image, call BitBlt a
second time, specifying the compatible
DC as the source DC and a window DC as
the target DC.