How would I draw outside the client area of a window, and on the title bar. I know it can be done, but I am unsure of how to implement this effectively. Think google chrome, where the tabs are on the title bar.
When Windows asks you to draw the portion of the window that is outside your client area, it will send you an WM_NCPAINT message. Handle that message and draw whatever you want the non-client portion of your window to be. See the page I linked for an example of how to get a device context you can draw upon.
It may be worth mentioning WM_NCHITTEST also, if you plan on customizing where non-client elements are located.
Drawing a custom window caption DrawCaption
Related
I created a CEF browser within a borderless window (WS_POPUP style).
The CEF renderer overlaps my window's client area.
The problem is that I'd like to allow the user to resize the window but I can't
handle the WM_NCHITTEST message.
I found many topics on the Internet but there was no actual solution.
Of course, I could create a 1px border with WM_NCCALCSIZE but I don't want to, as I would need to change the color of the border depending on the browser's content.
Is there a way to subclass the renderer's window (used internally by CEF)?
Do I really need to handle the WM_NCHITTEST message? Is there another way of doing that?
Any help would be greatly appreciated.
winapiwrapper
I am working on a program that will replicate, and then extend the functionality of Aero Snap.
Aero Snap restores a maximized window, if the user "grabs" it's title bar, and I am having difficulties identifying this action.
Given a cursor position in screen coordinates, how would I check if the position is within the window's title bar? I am not really at home in the Win32 API, and could not find a way that works reliably for complicated scenarios such as:
Note that tabs that chrome inserts into the title bar. Office does something similar with the quick launch menu.
title bar hits are via the message "non client" messages - ie the area of a window that is not the client (or inner) window.
WM_NCLBUTTONDOWN is probably the message you want to trap.
You also probably want to set a window hook to hook mouse messages, if its the NC message you want, you handle it your way, if not - pass it on to the message chain.
Edit: if Chrome is using the DwmExtendFrameIntoClientArea calls to draw the tabs, then you will need to use WM_NCHITTEST.
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 ;)
I want to allow a user to drag my Win32 window around only inside the working area of the desktop. In other words, they shouldn't be able to have any part of the window extend outside the monitor(s) nor should the window overlap the taskbar.
I'd like to do it in a way that does cause any stuttering. Handling WM_MOVE messages and calling MoveWindow() to reposition the window if it goes off works, but I don't like the flickering effect that's caused by MoveWindow().
I also tried handling WM_MOVING which prevents the need to call MoveWindow() by altering the destination rectangle before the move actually happens. This resolves the flickering problem, but another issue I run into is that the cursor some times gets aways from the window when a drag occurs allowing the user to drag the window around while the cursor is not even inside the window.
How do I constrain my window without running into these issues?
Windows are, ultimately, positioned via the SetWindowPos API.
SetWindowPos starts by validating its parameters by sending the window being sized or moved a WM_WINDOWPOSCHANGING message, and then a WM_WINDOWPOSCHANGED message notifying the window proc of the changed size and/or position.
DefWindowProc handling of these messages is to, in turn, send WM_GETMINMAXINFO and then WM_SIZE or WM_MOVE messages.
Anyway, handle WM_WINDOWPOSCHANGING to filter both user, and code, based attempts to position a window out of bounds.
Keep in mind that users with multi-monitor setups may have a desktop that extends into negative x- and y-coordinates, or that is not rectangular. Also, some users use alternative window managers such as LiteStep, which implement virtual desktops by moving them off-screen; if you try to fight this, your application will break for these users.
You can do this by handling the WM_MOVING message and changing the RECT pointed to by the lParam.
lParam: Pointer to a RECT structure with the current position of the window, in screen coordinates. To change the position of the drag rectangle, an application must change the members of this structure.
you may also want to handle WM_ENTERSIZEMOVE to know when the window is beginning to move, and WM_EXITSIZEMOVE
WM_GETMINMAXINFO is what you seem to be looking for.
Normally, the thickness of a window is 4 pixels, which can be retrieved by GetSystemMetrics method. Can I change its value, for example 2 pixels?
Thank you very much!
Simple answer: No. Not for a specific window.
Complicated answer: The border is drawn as part of the "non-client" region of the window. This is all handled (under the hood) by the default processing (i.e. DefWindowProc), along with the caption, minimize, maximize buttons, etc. You can override this by handling the WM_NCPAINT message. You'll then be responsible for drawing the entire non-client area of your window. You'll also want to handle the WM_NCCALCSIZE message, so that Windows knows how much of the remaining space to give to your client area.
Alternatively, you can set the border style of your window to none. This will allow Windows to draw the caption for you, although it'll probably look slightly different. Unfortunately, by doing this, you lose the drag-to-resize functionality. For that, you'll need to handle the WM_NCHITTEST message.