I have created a borderless window using these styles: WS_VISIBLE | WS_POPUP | WS_OVERLAPPED
The problem is that the window can't be moved. I know that I could do something like getting mouse click position, and then calculate where the window would end up everytime there comes a WM_MOUSEMOVE.
But this solution is not stable, because when I move my mouse too fast, it gets out of the window, and then it won't react. I dont want to set up a hook, because they are too slow. I have searched the internet, but nothing came up at all.
What I ideally want to, is to create a window, that is able to be moved without borders or captions, where I don't need to track the mouse myself, but where Windows does it for me, like making the whole window a caption.
I know that I could do something like getting mouse click position, and then calculate where the window would end up everytime there comes a WM_MOUSEMOVE. But this solution is not stable, because when I move my mouse too fast, it gets out of the window, and then it won't react.
You can fix that by calling SetCapture when you receive the mouse click. You then will continue to receive WM_MOUSEMOVE even after the mouse cursor leaves your window. When the user is finished dragging and release the mouse cursor, you then should call ReleaseCapture.
What I ideally want to, is to create a window, that is able to be moved without borders or captions, where I don't need to track the mouse myself, but where Windows does it for me, like making the whole window a caption.
If you really want to do that, you could respond to the WM_NCHITTEST message and return HTCAPTION.
try PostMessage(hwnd,WM_SYSCOMMAND,SC_SIZE+9,0) on WM_LBUTTONDOWN.
Related
I have a layered window that I want all clicks to pass through no matter where the mouse is located. Some parts of it are color keyed, and others are not. Clicks pass through the window whenever the mouse is on a transparent part but whenever the mouse is on a non-transparent part, the window captures the click. An easy solution would be just to add the WS_EX_TRANSPARENT flag to the window but I DO NOT want to do that. I tried returning -1 on WM_NCHITTEST in WndProc since WM_NCHITTEST is called every time the mouse enters a non-transparent zone but that didn't work and clicks still didn't pass through non-color keyed areas of the window.
Thanks in advance
I have created a window using the WS_EX_NOACTIVATE flag and it works great as far as not taking focus when you click the window. However when I drag the window or try to resize it, it doesn't redraw the window as your are moving and resizing it, only at the very end once you release the mouse button. Is there a way around this? I would like to see the window as I am resizing it. I have searched many documents, but I still don't find the resolution...
If you need a window that doesn't take focus when clicked, but can still be interacted with, you need to handle the WM_MOUSEACTIVATE, and return MA_NOACTIVATE.
Additional information and fully working sample code has been published by Raymond Chen. See How can I have a window that rejects activation but still receives pointer input?
It's a Windows bug. You need to call SetWindowPos(hwnd, 0, x, y, width, height, 0) on WM_MOVING. The coordinates to set are given to you in lParam which is a RECT*.
Note that doing this will activate the owned window and deactivate the owner, which is not what you want (and SWP_NOACTIVATE has no effect either).
To avoid that, you need to set WS_CHILD on the owned window. But set it after you created the window, via SetWindowLong(), otherwise your owned window will get clipped, like any child window.
And, as you probably already figured out, this only works for windows with WS_EX_TOOLWINDOW ex style. I wasn't able to make the owned window stay deactivated with any other style combination that doesn't include WS_EX_TOOLWINDOW.
That's winapi for you :(
I need to know if there is a code in c++ that allows to simulate a click, on a background window (if that's impossible, a foreground window will do fine), without moving the mouse.
I also need to click on specific coordinates, and drag an item to some other position (always without moving the mouse).
Example:
my mouse pointer is at (500,700),
but i need to left click at (100,150),
and drag to (700,300).
I need to be able to move my mouse pointer without affecting the program,
and the program must run correctly without moving, or locking, the mouse pointer.
If this action is impossible in c++, a VB code will be apreciated.
From a C++ Windows application, you can call Windows API directly by first finding the window using FindWindow that will give you the window handle you want, then finding the area within this window that you want to click. You can use API like GetWindowRect for this.
Finally, you can send this window, or an area within it, mouse messages using mouse_event function to cause the mouse to move, click, drag and let go at a new location.
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.
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.