What's a simple way to implement a c++ Win32 program to...
- display an 800x600x24 uncompressed bitmap image
- in a window without borders (the only thing visible is the image)
- that closes after ten seconds
- and doesn't use MFC
If you're targeting modern versions of Windows (Windows 2000) and above, you can use the UpdateLayeredWindow function to display any bitmap (including one with an alpha channel, if so desired).
I blogged a four-part series on how to write a C++ Win32 app that does this. If you need to wait for exactly ten seconds to close the splash screen (instead of until the main window is ready), you would need to use Dan Cristoloveanu's suggested technique of a timer that calls DestroyWindow.
Register a class for the splash window and create a window using these styles:
WS_POPUPWINDOW: will make sure your window has no caption/sysmenu
WS_EX_TOPMOST: will keep the splash screen on top of everything. Note that this is a bit intrusive. It might be better to just make the splash window a child of your main window. You may have to manipulate the z-order, though, to keep any other popup windows (if you create any) below the splash screen.
Use CreateDIBSection to load the bitmap. It should be easy, since BMP files are essentially dumps of DIB structures. Or do what Ken said and use LoadImage.
Handle the WM_PAINT or WM_ERASEBKGND message to draw the bitmap on the window.
On WM_CREATE set a timer of 10 seconds and when Windows sends the WM_TIMER message, have the window destroy itself.
The key point here is to use layered window.
You can start with a win32 wizard generated project and change CreateWindow call to CreateWindowEx and set WS_EX_LAYERED as extended window style and combination of WS_POPUP and WS_SYSMENU as window style. When you do that launch your application it will be invisible. Then you should use UpdateLayeredWindow to paint your image. You may also need AlphaBlend function if you want use PNG image with alpha layer.
Hope this helps!
You can:
Create a dialog in your resource file
Have it contain a Picture control
Set the picture control type to Bitmap
Create/import your bitmap in the resource file and set that bitmap ID to the picture control in your dialog
Create the window by using CreateDialogParam
Handle the WM_INITDIALOG in order to set a timer for 10 seconds (use SetTimer)
Handle WM_TIMER to catch your timer event and to destroy the window (use DestroyWindow)
Use LoadImage to load the bitmap
Use CreateWindowEx to create the window.
In the window proc capture the WM_PAINT. Use BitBlt to paint the bitmap.
It's a Win32 api FAQ
See professional Win32api forum
news://194.177.96.26/comp.os.ms-windows.programmer.win32
where it has been answered hundreds of times for 20 years..
Related
My application is a fullscreen window rendering a specified window or the desktop.
I would like to know if it's possible to fetch the window bitmap (like i'm already doing) but without the render of my window's application ?
There is the idea : dwm.giveBitmapWithoutRendering(HWND myApplicationHandler)
Working on Windows 7/8/8.1, QTCreator C++ MINGW
You can use the PrintWindow function with your own memory DC. The success of this method will depend on how the window and its child windows have implemented the WM_PRINT message.
This doesn't use DWM but rather gets the window to repaint itself. Since it's not repainting to the screen I hope it meets your requirements.
In windows: I would like to know if it is possible (and if so, how) to make a program in C++ that displays images/text on the screen directly, meaning no window; if you are still confused about what I am after some examples are: Rocketdock and Rainmeter.
you can do it certainly without using Qt or any other framework. Just Win32 API helps you do that and internally, every framework calls these API so there is no magic in any of these frameworks
First of all, understand that no image or text can be displayed without a window. Every program uses some kind of window to display text or image. You can verify it using the Spy++ that comes with windows SDK. click the cross-hair sign, click the image or text you think is displayed without any windows. The Spy++ will show you the window it is contained in.
Now how to display such image or text that seems like not contained in any window. Well you have to perform certain steps.
Create a window with no caption bar, resize border, control box, minimize, maximize or close buttons. Use the CreateWindowEx() and see the various windows style WS_EX_XXX, WS_XXX for the desired window style.
Once the window is there you need to cut the window. Much like a cookie cutter. for this you need to define an area. This area is called region and you can define it using many functions like CreateEllipticRgn(), CreatePolygonRgn(), CreateRectRgn(), CreateRoundRectRgn() etc. all these functions return a HRGN which is the handle to the region. Elliptical or rectangle regions are OK as starter.
Now the last part. You have to cut the window like that particular region. Use the SetWindowRgn() function which requires a handle to your window and a handle to that region (HRGN). This function will cut the window into your desired shape.
Now for the image or text. Draw the image or text inside the window. I assume you must have cut the window according to your image, You just need to give window a face. so just draw the image either on WM_ERRASE BACKGROUND or WM_PAINT messages
Use the SetWindowPos() to move the window to the location you wish to on screen. If you have used correct parameters in CreateWindowEx() then this step is not necessary
You can set any further styles of windows using SetWindowLong() function.
Congratulations, you have your image displayed without using any windows ;)
This is a screenshot of Steam's client window being resized.
Steam's client window has two cool features.
Custom window which is very responsive.
Cool glass resize effect, different from standard windows (Thought it might be a side effect strongly related to 1)
Let's say I wanna create similar window using winapi. How can I do it?
I don't ask about widget-management related stuff, but about technical winapi tricks.
Basically, you can do almost anything with your window. But most of the tricks are to be implemented manually.
What is 'very responsive' I don't know. If you mean that the window has no standart border, it is easy to implement: do not specify WS_BORDER and WS_CAPTION when creating a WS_POPUP window. After that you will have to draw a border and a caption yourself. Handle WM_ERASEBKGND and WM_PAINT messages, draw background, menus, all as usual.
This effect seems to me more like a bug. It happens this way: the window is resized, it gets a WM_SIZE message, processes it, Windows sends a WM_ERASEBKGND message which the window ignores. Thus, the system draws a new shadow around new window frame which is not yet filled with new window image. And here we get this cool glass effect: old image of underlaying windows with a windows aero shadow. You can try to disable windows shadows and look at this effect.
In order to create a custom resizing border, you might find useful these functions: LoadCursor, SetCursor, MoveWindow.
In order to draw your custom borders, you can use standart GDI functions. Also you can create a handful of child windows and delegate drawing to them. This is basics of winapi.
When exactly is WM_PAINT called? Im trying to create a dialog based slot machine application, but i've run into a couple of logical issues. My application will consist of:
"Spin" Button
Exit Button
Three BMP images to display the results of the spin(coin/heart/soldier)
How will i show the final result of the spin using the BMP images? Am i correct in using WM_PAINT to attempt to display the images, how will i refresh the screen each time the user presses the spin button to show the new images? I really appreciate the help!
Dialog boxes normally use DefDlgProc as the window procedure. You can't handle WM_PAINT in your DialogProc (it isn't a window procedure). You can use your own window procedure with a dialog but that's probably more trouble than it's worth.
The simplest way to display a bitmap on a dialog is to use a static control with the SS_BITMAP style.
You can change the displayed bitmap by sending the STM_SETIMAGE message to the static control. The control will take care of repainting itself with the new bitmap.
This is OK if you just want to display the result of a spin, but won't work very well if you want to animate the spinning of the reels. To handle this you could create your own static control (i.e. a window for each reel) that would display a portion of a reel bitmap.
I have a program which is not written by me. I dont have its source and the developer of that program is developing independently. He gives me the HWND and HINSTANCE handles of that program.
I have created a child window ON his window, using win32 api.
First thing I need is to make this child window have transparency on some area and opaque on other area(like a Heads up display(HUD) for a game), so that the user may see things in both windows.
The second thing that I need is to direct all the input to the parent window. My child window needs no input.
I know that WS_EX_TRANSPARENT only makes the child draw at the end like in painters algorithm.
I cant use WS_EX_LAYERED because its a child window.
p.s.
I have looked everywhere but didn't find any solution though there were similar questions around the internet.
Actually this is a HUD like thing for that game. I can't draw directly on parent window because of the complexity with multi-threads any many other reasons.
-- EDIT ---------------------------
I am still working on it. I am trying different ways with what you all suggested. Is there a way to combine directX and SetWindowRgn() function or directx with BitBlt() function? I think that will do the trick. Currently I am testing all the stuff as a child window and a Layered window.
You can use WS_EX_LAYERED for child windows from Windows 8 and up.
To support earlier versions of windows, just create a level layered window as a popup (With no chrome) and ensure its positioned over the game window at the appropriate location. Most users don't move the windows they are working with all the time, so, while you will need to monitor for the parent window moving, and re position the HUD, this should not be a show stopper.
Not taking focus (in the case of being a child window) or activation (in the case of being a popup) is more interesting, but still quite do-able:- The operating system does not actually automatically assign either focus, or activation, to a clicked window - the Windows WindowProc always takes focus, or activation, by calling SetFocus, or some variant of SetActiveWindow or SetForegroundWindow on itself. The important thing here is, if you consume all mouse and non client mouse messages without passing them on to DefWindowProc, your HUD will never steal activation or keyboard focus from the Game window as a result of a click.
As a popup window, or a window on another thread, you might have to manually handle any mouse messages that your window proc does get, and post them to the game window. Otherwise, responding to WM_NCHITTEST with HTTRANSPARENT (a similar effect to that which WS_EX_TRANSPARENT achieves) can get the system to keep on passing the mouse message down the stack until it finds a target.
OK friends, finally I did some crazy things to make it happen. but its not very efficient, like using DirectX directly for drawing.
What I dis:
Used (WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_ TOOLWINDOW) and () on CreateWindowEx
After creating the window, removed (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE) from window styles, and also removed (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_APPWINDOW) from extended window styles.
This gives me a window with no borders and its also now shown in the taskbar. also the hittest is passed to whatever that is behind my window.
Subclassed the window procedure of the other window and got the
WM_CLOSE,WM_DESTROY, to send the WM_CLOSE or WM_DESTROY respectively to my window
WM_SIZE,WM_MOVE, to resize and move my window according to the other window
WM_LBUTTONUP,WM_RBUTTONUP,WM_MBUTTONUP, to make my window brought to the top, and still keep focus on the other window, so that my window doesn't get hidden behind the other window
Made the DirectX device have two passes:
In the first pass it draws all the elements in black on top of a white background and copy the backbuffer data to an another surface (so it give a binary image of black & white).
In the second pass it draws the things normally.
Another thread is created to keep making the window transparency by reading that black & white surface, using the SetWindowRgn() function.
This is working perfectly, the only thing is it's not very good at making things transparent.
And the other issue is giving alpha blending to the drawn objects.
But you can easily set the total alpha (transparency) using the SetLayeredWindowAttributes() function.
Thanks for all the help you guys gave, all the things you guys told me was used and they guided me, as you can see. :)
The sad thing is we decided not to use this method because of efficiency problems :(
But I learned a lot of things, and it was an awesome experience. And that's all that matters to me :)
Thank You :)
You can make a hole in the parent window using SetWindowRgn.
Also, just because it is not your window doesn't mean you can't make it a layered window.
http://msdn.microsoft.com/en-us/library/ms997507.aspx
Finally, you can take control of another window by using subclassing - essentially you substitute your Wndproc in place of theirs, to handle the messages you wish to handle, then pass the remainder to their original wndproc.