Sign in to follow this  

I need to create a utility to drag windows from outside of the application.

This topic is 2829 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Sorry for the confusing title, but here is what I'm after and why. I work for a large family entertainment restaurant/game room. We use a very poorly designed (and I'm assuming cheap) point of sale (POS) software system. It would appear that the user interface was designed by trained monkeys. The main window for the new administrator software we just upgraded to requires a monitor with a resolution of 1024x768. The window can be resized, but nothing in the window resizes or reconfigures, and most odd, there are no scroll bars. Anyway, our tech manager uses a small netbook to diagnose games, but the screen size is less than 1024x768. Because of this, he can no longer get to the parts of the interface to do some of the work he needs to do. The company that wrote the software just doesn't seem to care to answer inquiries about the issues we are having. What he needs is a utility where he can press a hot key and then be able to click and drag the window to where he needs it, from any point in the window (title bar is out since it will need to be moved off screen). How to do this without hacking the program is what stumps me. I need to write a background app that sits and waits for a hot key to be pressed and then takes control of any mouse events in the active window until another hot key is pressed. I'm just too new to Windows programming. I'm still learning event handling, and this goes beyond my knowledge. MSDN is not too helpful since it requires you to know what you're looking for and I really have no idea. Any ideas would be appreciated.

Share this post


Link to post
Share on other sites
Tried Alt+Space+M? ;)

Edit: As for what you're trying to do.. How about using SetWindowsHookEx with WH_CALLWNDPROC and then intercepting WM_MOUSEMOVE/WM_LBUTTONDOWN/WM_LBUTTONUP? You could probably use WindowFromPoint to test whether you're in the client area of the window or over a child/control in the window and then MoveWindow appropriately.
But you will have to pay attention not to cause a deadlock; WindowFromPoint might send WM_NCHITTEST and MoveWindow will of course also send messages to the window, so you need to make sure never to call these in response to messages that they can cause.

Share this post


Link to post
Share on other sites
Quote:
Original post by pablo24
Tried Alt+Space+M? ;)


I wasn't aware of such a feature, but doing so forces the mouse to the title bar. That will not work as the window will need to be dragged from within the client rect.

Quote:
Original post by pablo24
Edit: As for what you're trying to do.. How about using SetWindowsHookEx with WH_CALLWNDPROC and then intercepting WM_MOUSEMOVE/WM_LBUTTONDOWN/WM_LBUTTONUP? You could probably use WindowFromPoint to test whether you're in the client area of the window or over a child/control in the window.


Thanks, I'll look into that.

Share this post


Link to post
Share on other sites
Quote:
I wasn't aware of such a feature, but doing so forces the mouse to the title bar. That will not work as the window will need to be dragged from within the client rect.

I find myself using this method to bring back windows to the desktop after I switched from a dual-monitor setup at home/office on a regular basis.

I am usually able to move any window type, even those without a title bar (unnecessary fancy GUIs etc.) using the cursor keys - you should at least give it a try.

Share this post


Link to post
Share on other sites
Quote:
Original post by maspeir

uses a small netbook


My EEE came with a tool that allows resolution to be full 1024x768, and will automatically scroll.

Some drivers also allow desktop to be larger than physical screen, check the display settings.

Google for "scrolling virtual desktop".

Share this post


Link to post
Share on other sites
I don't think alt+space+m will work (I hope it does though), because Windows will automatically move the window back when you press enter to ensure at least a small part of its title bar remains within the work area. However, this doesn't happen when you use something like SetWindowPos().

Share this post


Link to post
Share on other sites
Quote:
Original post by Amr0
I don't think alt+space+m will work (I hope it does though), because Windows will automatically move the window back when you press enter to ensure at least a small part of its title bar remains within the work area. However, this doesn't happen when you use something like SetWindowPos().


Yep. I'm at work and just verified this. :( Looks like I'll be writing a utility...

Share this post


Link to post
Share on other sites
Couple quick thoughts.

Try remote desktop from the small screen system to a large screen desktop running the app. I think it will give you the ability to scroll the whole desktop/window.

Or, simply re-parent the window into your own application window and add scroll bars. Should be trivial with a bit of C# and a few interop calls.

Share this post


Link to post
Share on other sites
Quote:
Original post by pjcast
Or, simply re-parent the window into your own application window and add scroll bars. Should be trivial with a bit of C# and a few interop calls.


I tried this and it seemed simple. It worked perfectly while under development in Visual C++ 2008, but the moment I tried the app from the desktop, it failed to work.

The problem is that I do not have the application on my home computer and it requires serves on our server to run, so I cannot get a copy. On top of that, I cannot install Visual Studio at work. As such, I'm trying to parent the top most window when my program runs. However, clicking on an icon on the desktop actives the desktop window and the program ends up parenting it instead.

I've tried just about every "GetXXWindow" function I can and none of them work. I'm guessing that the window list is tied to the current process.

Any idea how to get a handle to the window of another application under my main window?

Share this post


Link to post
Share on other sites
Quote:
Original post by maspeir
Any idea how to get a handle to the window of another application under my main window?


Look at the target application's window with Spy++ or the equivalent and get it's window class string and window text, and then have your app use FindWindow().

I don't think re-parenting a window across processes is going to work. What you would need to do would be to inject your code into the target process. There are several ways to do this, but I think this approach is way too much trouble for what you need.

Just write an app that gets a handle to the window and allows you to control it around with arrow keys. If you want to get fancier, instead of an app install a global hook. Use the low-level keyboard hook, WH_KEYBOARD_LL, and install a global hook that moves around the target application if it exists on certain keystrokes, maybe use the numeric keypad.

Share this post


Link to post
Share on other sites
If at all possible, I would rather stick to parenting the window. Again, this software was written by trained monkeys. God only knows what they've done with the code. I really do not want to inject code (not even sure how) and using keyboard hooks will probably break the app at some point.

I'm leaving the company at the end of the month, so I want to make something that is easy and cannot possibly intrude on or get interrupted by the app in question. However, I cannot be sure that the process name will stay the same or even the title to the window. That is why I was trying to grab a handle to the top most window before I create the parent window in my app. FindWindow may not work for long. How do I go about this? I've tried EnumWindows, but that returned every window that was open or might open, even the taskbar. Just FYI... Never try to parent the taskbar. Windows takes it personally.

Share this post


Link to post
Share on other sites
Quote:
Original post by maspeir
[...] However, I cannot be sure that the process name will stay the same or even the title to the window. [...]

If that's the case then the only thing you can do is have your app let the user select the target window. There is no way in Win32 to get the window that has one less level of z-order than a given window -- I mean you could try hiding your app's window (ShowWindow(h, SW_HIDE)) and then doing a GetForegroundWindow(), and then making your window visible again, but I have a feeling that that won't work.

The easiest way to get the functionality you want would be to write an app that is a tiny window containing only a button. When the user pushes the button the cursor changes into some weird cursor. The user then selects the main window of the target application with the weird cursor, and the cursor turns back to normal. After the selection is made the user can move around the target window with the arrow keys as long as the little application is active.

EDIT: I forgot to say, the key API call in that scenario is WindowFromPoint()

Share this post


Link to post
Share on other sites
ARRGGG!

OK, so I did the WindowFromPoint. Several things are frustrating. First, there is no way to tell if the returned window in a child window. The IsChildWindow *stupidly* will only check if the window is a child window of another window. Of course, that means that I must first have a handle to the parent window. This is asinine! Why can't I just supply the handle to the window in question? So, I cannot tell if the window in question is a child window. That's a problem. It completely takes away the option of moving the window via the keyboard.

Anyway, I try the app today and it works with the WindowFromPoint code. However, it looks like they used forms, so when the mouse is over the client rect, there is no way to avoid getting a child window. Not only that, but I changed my monitor's resolution to 800x600 to simulate the problem. They make the parent window fit the monitor and clip the form window. So, parenting the form window results in a clipped child window in the new parent window, nullifying the whole thing. I'm going to try to size the child window later today when I get home from work.

I take back what I said about TRAINED monkeys. That insults trained monkeys.

What I find odd is that getting a handle to a random window can be done, i.e., alt-print screen, alt-shift-m, but the capability is undocumented.

Share this post


Link to post
Share on other sites
Quote:
Original post by maspeir
First, there is no way to tell if the returned window in a child window.


Just iterate up the parents until you find one which doesn't have a parent. That will be the app's top-level window:

HWND GetTopLevelWindow(HWND child) {
HWND wnd = child, prev_child;
do {
prev_child = wnd;
wnd = GetParent(wnd);
} while (wnd != NULL);
return prev_child;
}


Share this post


Link to post
Share on other sites

This topic is 2829 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this