WINAPI MoveWindow trick - c++

Once I've been given a task to create application that doesn't have a regular window shown to user. All the navigation was held from taskbar, something like a Spotify app -> in order to listen to a playlist you do not need a window.
Everything was displayed in this small area. I tried many ways to achieve that but finally I simply invoked MoveWindow(hWnd, -10000, -100000, width, height, ...) and it worked! But something popped in my head -> is this solution even safe? It seems odd to me to draw things behind the screen. I initially thought that Windows doesn't even bother and simply ignores drawing calls for this window. But somehow I can see update in application on this small preview window above taskbar. I suspect that it might be actually redrawn behind the screen. Then is the following true -> Windows redraws window but doesn't send a request to the graphics driver to show application on screen? It seems quite logical in spite of efficiency.

Related

Draw on screen with GDI+ (or GDI) similar to Inspect

I'm trying to draw on the screen (the whole screen, on top of every other window) using GDI+.
I've passed NULL to GetDC to get a HDC to the screen, and then used that to create a Graphics object, and used DrawRectangle to draw rectangles on the screen.
Everything works..except...the inside of the rectangle won't update.
Like if I draw it over a command prompt, and move the command prompt, the inside of the rectangle remains black.
I expect to see whats under the rectangle.
Here's the code that's doing the drawing..
Pen BluePen(Color(255, 0, 255, 0), 2);
Graphics graphics(screenDC);
graphics.DrawRectangle(&BluePen, myRect);
Pretty simple, so is there something I have to do to get the inside of the rectangle to update when the screen does? Or to get it truely transparent.
================= EDIT =================
Well I had given up on this, and assumed it wasn't possible, until...I realized the Inspect tool that comes with the Windows SDK does this perfectly.
I would like to recreate something similar to the highlight rectangle, and if I select a window (such as Firefox) and then bring Inspect into focus I can move it around freely with everything being updated perfectly.
There's not even any flickering.
So...does anyone know how Inspect manages to do this?
Also answers in GDI instead of GDI+ are fine...
In windows the screen (and the windows ...) surface(s) are ... volatile, like sandboxes. The "overlapping" of windows and the re-painting of uncovered surfaces is an illusion made by proper event management.
Everything is drawn remain there until something else is drawn over it.
"Uncovering" a surface makes the window representing that surface to receive a WM_PAINT message. It's up to that window procedure to react to that message by re-painting everything is supposed to be under it.
Now, unless you intercept somehow the WM_PAINT message that is sent to the desktop window, you have mostly no chance to know the desktop needs a repaint and hence your paint code will not be called and no repaint will happen. Or better it happens following just the desktop window updating code, that's not aware of your paint.

How do I handle WM_NCCALCSIZE and make chrome-like interface?

I'm currently using Google Chrome as my main browser. I wondered how the developers put the custom titlebar, because I wanted to incorporate into one of my own applications.
If you guys don't know what I'm talking about, here's a picture:
I found an article about the interface, which is here:http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/33870516-9868-48d3-ab53-6269d9979598
However, I don't know how to do this. I'm currently using VC++ Express. Can anyone give me step by step instructions and how to get an interface like that? Except I don't want tabs on top.
I'm writing this in Win32.
If memory serves, the main things you need to handle aren't WM_NCCALCSIZE, but WM_NCHITTEST and WM_NCPAINT.
WM_NCHITTEST is what tells the system when the cursor is over the title bar, so you need to take a cursor position and decide whether it's over the area you consider "title bar". In particular, if the user clicks and drags with the cursor in this area, the whole window gets dragged.
WM_NCPAINT is just like WM_PAINT except for the non-client area -- i.e., this is when you need to actually draw whatever you're going to for the title bar (and window borders, if memory serves).
I should add that I haven't played with this in quite a while. There's almost certainly more I'm not remembering right now.
OK, the answer is simple:
Chomre simply does not use the Windows built in functionality for drawing a frame border, titlebar, titlebar buttons, etc..
When you call GetWindowRect(hChromeWindow) and GetClientRect(hChromeWindow) you will notice that the rectangles are identical. This means that Chrome turns off all Windows functionality for drawing a border (simply return 0 in WM_NCCALSIZE without doing anything else) and then they draw EVERYTHING into the client area.
So in WM_PAINT they draw the titlebar and the upper part of the window (URL bar, tabs, etc..) together. In WM_NCPAINT they do nothing.
This is not the common way to do it, but the easiest, and it is bullet-proof.
By the way: Java applications do the same.

Draw OpenGL on the windows desktop without a window

I've seen things like this and I was wondering if this was possible, say I run my application
and it will show the render on whatever is below it.
So basically, rendering on the screen without a window.
Possible or a lie?
Note: Want to do this on windows and in c++.
It is possible to use your application to draw on other application's windows. Once you have found the window you want, you have it's HWND, you can then use it just like it was your own window for the purposes of drawing. But since that window doesn't know you have done this, it will probably mess up whatever you have drawn on it when it tries to redraw itself.
There are some very complicated ways of getting around this, some of them involve using windows "hooks" to intercept drawing messages to that window so you know when it has redrawn so that you can do your redrawing as well.
Another option is to use clipping regions on a window. This can allow you to give your window an unusual shape, and have everything behind it still look correct.
There are also ways to take over drawing of the desktop background window, and you can actually run an application that draws animations and stuff on the desktop background (while the desktop is still usable). At least, this was possible up through XP, not sure if it has changed in Vista/Win7.
Unfortunately, all of these options are too very complex to go in depth without more information on what you are trying to do.
You can use GetDesktopWindow(), to get the HWND of the desktop. But as a previous answer says (SoapBox), be careful, you may mess up the desktop because the OS expects that it owns it.
I wrote an open source project a few years ago to achieve this on the desktop background. It's called Uberdash. If you follow the window hierarchy, the desktop is just a window in a sort of "background" container. Then there is a main container and a front container. The front container is how windows become full screen or "always on top." You may be able to use Aero composition to render a window with alpha in the front container, but you will need to pass events on to the lower windows. It won't be pretty.
Also, there's a technology in some video cards called overlays/underlays. You used to be able to render directly to an overlay. Your GPU would apply it directly, with no interference to main memory. So even if you took a screen capture, your overlay/underlay would not show up in the screen cap. Unfortunately MS banned that technology in Vista...

Windows not drawing above OpenGL windows

I have an application with an OpenGL window as a child window of the main window.
When I display a dialog box above the OpenGL window, it doesn't get drawn. It's like it's not getting WM_PAINT messages. If I can guess the title bar position of the dialog box, I can drag it and it's still responsive.
I realise this might be a vague question, but I was wondering if anyone else has seen this sort of behaviour before and knew of a solution?
I wondered if the Pixel Format Descriptor would make a difference - I had PFD_DRAW_TO_WINDOW, but changing to PDF_DRAW_TO_BITMAP didn't make any difference. I'm not sure what else I should be looking at?
Bugger. Should have given all the details. I was running Windows in a virtual machine on Mac OS X using Parallels. I upgrade from Parallels 3 to 4 and now everything is working fine. I suspect a Parallels video driver issue.
Thanks to all those who answered with suggestions.
Is your opengl window constantly rendering. It is possible that the 3D hardware is simply rendering into an overlay that is overdrawing your dialog box. If you position the dialog box so it overlaps your main window, can you see some of it?
Try to pause rendering into the main display to see if it effects the results.
You will also need to make sure that your window style ensures the results are clipped...
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
You should check though all the items mentioned in this MSDN article, as it covers a lot of the basics for getting opengl rendering in a window correctly.
http://msdn.microsoft.com/en-us/library/ms970745.aspx
You may need to switch overlay off. It can be done via forcing back buffer presenting method to copy instead of swap.
Use wglChoosePixelFormatARB and one of parameters should be
WGL_SWAP_METHOD_ARB with value WGL_SWAP_COPY_ARB
This may seems stupid but are you sure your OpenGL window is not flagged "topmost" ?
Does the dialog box disappear also behind borders of your window or just behind the OpenGL rendering rectangle ?

Force screen redraw after drawing to screen's DC C++

I'm creating a Windows Mobile custom SIP and as the user presses or "hovers" over a button on the keyboard I draw it's corresponding selected image (iPhone-esque) to the screen's DC using ::GetDC(NULL). It is developed in Win32 C++.
My problem is that I can never get the screen to repaint itself, erasing the previously drawn key. I've tried everything I could think of to force it, ::RedrawWindow() with all different combos of params using NULL or any of the Get..Window functions as the HWND, and all combo of flags (INVALIDATE | UPDATENOW | ERASENOW | ALLCHILDREN etc). I've also tried invalidating the rect and forcing a repaint of the underlying app using ::GetActiveWindow and ::GetForegroundWindow, variations using ::GetDesktopWindow, etc. I've essentially run out of ideas and it's the last thing holding me up from using it on my Windows Mobile device. Does anyone have any ideas? Any help would be greatly appreciated.
I've included some screenshots to illustrate my dilemma.
Before Screenshot
After Screenshot
Before http://img13.imageshack.us/img13/9861/cezoom1.png After http://img3.imageshack.us/img3/7481/cezoom2.png
Thanks in advance!
Rather than drawing to the background DC, why don't you create a temporary window and draw into that? When you destroy the window, the background should get repainted automatically.
I'm just guessing, because I don't know Windows Mobile, but it could be that Windows is caching the last thing that was drawn into the DC and repainting it every time you invalidate the window.
Have you tried InvalidateRect on the screen hWnd?