473,396 Members | 1,975 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Help with GetWindowRect()

HaLo2FrEeEk
404 256MB
I'm working on a program that needs to check the bounding rectangle of external application windows. I've found multiple API methods that do just that, GetWindowRect(), GetWindowPlacement(), and GetWindowInfo() to name a few. For the most part they works very well. I pass a MainWindowHandle to the method and they returns some information about the window. I'm gonna explain what each of the methods return, so if you want to skip it, scroll til you see MY QUESTION in bold.

GetWindowRect() returns a RECT object, not to be confused with a Rectangle. RECT contains the top, left, right, and bottom coordinates instead of top, left, width, and height. (I know that Rectangle does contain right and bottom, but it returns width and height instead)

GetWindowPlacement() returns a WINDOWPLACEMENT object, which contains a bit more information including flags to determine if the window is maximized, minimized, or normal and what state to restore it to. It also contains a RECT that tells what the window's normal position is, that is, the size and location of the window when it is returned to it's normal (not maximized or minimized) state.

Finally, GetWindowInfo() returns a WINDOWINFO object. This contains the most information yet. It still has a RECT object containing the size and location of the window, but it also has another RECT with the size and location of the client area of the window. There's also two values that hold the size of the window's borders.

MY QUESTION

Ok, sorry for that, I wanted to make sure you were familiar with what I'm working with.

Here's my issue, when a window is maximized it's borders are not visible, but all of the methods that return a window rectangle still appear to take those into account. I have two monitors each with a resolution of 1920x1200, for a total of 3840x1200, set up in dual screen. When I maximize a window in the left monitor and get it's RECT I get this (assuming no task bar):

{Left=-8,Top=-8,Right=1928,Bottom=1208}

I should get:

{Left=0,Top=0,Right=1920,Bottom=1200}

Now it's simple enough to detect if the values of Left and Top are negative and invert and subtract them from the right and bottom. But what if I have a window maximized in the right monitor? In that case I get this RECT (again assuming no task bar):

{Left=1912,Top=-8,Right=3848,Bottom=1208}

I should get:

{Left=1920,Top=0,Right=3840,Bottom=1200}

In this case the "-8" pixels are actually part of the left monitor, so they don't read as negative, though they are outside of that screen's bounds.

I'm at a complete loss as to how I could detect and fix this problem, so I'm hoping that some of the smart helpful people here could...well, help me out.

Thank you in advance, and I apologize for the length of the post, I just thought thorough explanation would help me get the answer I need.
Nov 18 '10 #1
10 11976
GaryTexmo
1,501 Expert 1GB
As I understand it, this only happens when a window is maximized... is there a way to tell if this is the case?

The problem with what you're doing now is a negative top-left corner of a window is actually valid, even if the window isn't maximized. It's easy enough to do, just grab the lower right part of the title bar for any window and drag it up and to the right.

Now, C# itself has flags to tell whether or not a window is maximized or minimized, but I don't know if this exists in the Windows API or not. A quick google search turned up this...

http://www.tek-tips.com/viewthread.c...1542276&page=2

If that doesn't work, take a look around (or maybe someone else here will know).

If there's no way to tell if the window is maximized, I guess you can do a few tricks. What you're already doing could be expanded a bit, something like...

Expand|Select|Wrap|Line Numbers
  1. Rectangle window = GetWindowDimensions();
  2. Rectangle screenRect = GetScreenDimensions();
  3. int numScreensWide = GetNumberOfScreensWide();
  4. int numScreensHight = GetNumberOfScreensHigh();
  5.  
  6. if (window.Width > screenRect.Width / numScreensWide &&
  7.     window.Height > screenRect.Height / numScreensHigh &&
  8.    ( /* any windows top-left corner is around the top-left corner of any of the screens */))
  9. {
  10.   // window is "likely" maximized
  11. }
I'd look into detecting if the window was maximized first, 'cause with the math stuff I'm pretty sure you could fake it out. Probably a rare case, but still.
Nov 18 '10 #2
HaLo2FrEeEk
404 256MB
I got it. WINDOWPLACEMENT's showCmd holds information about the window's show state. A show state of 3 is maximized, so what I ended up doing is passing the border width and height and the showCmd to my ToRectangle() method (inside the RECT struct.) If the showCmd is 3 then I add the borders to the top and left and subtract it from the right and bottom. That gives me the correct window size every time. I have to call GetWindowPlacement anyway because I need to restore the window to a visible show state if it isn't currently in one, then bring it to the front of the z-order. Basically I just check if the showCmd is 2 (minimized) and then I check the flags. A 2 flag means that the window was maximized before it was minimized, a 0 flag means that it was normal before it was minimized.

In doing all this, I also learned how I can move and resize other windows using SetWindowPlacement, which is another thing I needed to know.

Thanks for the reply though, I was about to resort to checking screen dimensions :/

One other problem I'm having, if I might (it's related.) the process explorer.exe technically always has a visible window: the task bar. If I open up an explorer window though (the C drive, for example,) GetWindowRect doesn't return the proper rectangle for that window, it returns the taskbar. I can't figure out how to get explorer windows to give off their own coordinates. Maybe I'll just have to live without that, but I'd really like to be able to "see" explorer windows like I can with other windows.
Nov 18 '10 #3
GaryTexmo
1,501 Expert 1GB
How does your app differentiate between two windows in the same program? Like, if I made a C# app that launched two windows under the same executable name, "blah.exe" does it find both, or only one of them?

Is that the same problem you're having with explorer, or somewhat different?
Nov 18 '10 #4
HaLo2FrEeEk
404 256MB
Hmmm...good point. Child windows are not detected, only parent windows. For example, I opened a program that I wrote that has a main control form and a secondary, child form. Only the main control form was detected. That's probably the issue I'm having with Explorer.exe, the main window is the taskbar, all other windows (like the C drive or a folder) are children of the taskbar.

Damn, I guess I'll have to detect whether or not a window has any children windows. Crap. I don't know how to do that.
Nov 18 '10 #5
HaLo2FrEeEk
404 256MB
You win...forever.

Thanks. My program is gonna be AWESOME! You might have been the one that helped me with it:

http://infectionist.com/extras/cshar...shot_1.4.0.zip

Move and resize the rectangle and click the button in the main form to screenshot that portion of the screen. Now you'll be able to drag it over a window and lock it to that window's size and location. I've got some work to do tonight : )

Now if only I could figure out how to detect when a window is minimized or closed and release the lock...
Nov 18 '10 #7
GaryTexmo
1,501 Expert 1GB
I remember seeing an earlier version of it from another thread. Is the same version as that? So you'll throw the bounds window over any running window and it'll expand/position to encompass it? That's nifty :)

That window command thing won't help you with that? Maybe when you lock to a window, record the important information. Then stick a timer in there, maybe every second or so, see if that window's state has changed and unlock if so? Just throwing ideas out.
Nov 18 '10 #8
HaLo2FrEeEk
404 256MB
It's a different version, added a bunch of cool features. Double click the middle to expand full screen, double click any of the handles to expand to that edge or corner of the screen, check a box to hide the screenshot bounds but keep it active (good for taking screenshots of movies.) It'll also detect whether the control form is overlapping the screenshot area and try to move it out of the way, and hide it when you take a screenshot if it still overlaps.

And I can detect if a form's show state is changed (minimized), but I don't know how to detect if it's been closed.
Nov 19 '10 #9
GaryTexmo
1,501 Expert 1GB
I found a few of those (just couldn't remember if it did it before) but not others, cool :D For the double click one, check out the... Screens (?) object in C#, I think you can get the monitor configuration from there. I noticed that if you double click a handle when it's spanning monitors, it still sizes to the first screen. Unless that's' intentional :)

If you've got the handle to the window, and it closes, what happens when you try to do something with it? Will it throw an exception, or does it appear to work but just do nothing?
Nov 19 '10 #10
HaLo2FrEeEk
404 256MB
It's intentional, but I'll probably have a user-selectable setting in a future version that will allow you to specify expanding to the current screen or to all screens.

And I'm not sure what happens when I try to query the handle of a closed window. The handle shows up as invalid, I'm sure, so I could probably just catch an exception and deal with it.

I crashed when I got home last night, so I didn't work on it at all, but I'll try to tonight if I have time. Stay tuned.
Nov 19 '10 #11

Sign in to post your reply or Sign up for a free account.

Similar topics

21
by: Dave | last post by:
After following Microsofts admonition to reformat my system before doing a final compilation of my app I got many warnings/errors upon compiling an rtf file created in word. I used the Help...
6
by: wukexin | last post by:
Help me, good men. I find mang books that introduce bit "mang header files",they talk too bit,in fact it is my too fool, I don't learn it, I have do a test program, but I have no correct doing...
3
by: Colin J. Williams | last post by:
Python advertises some basic service: C:\Python24>python Python 2.4.1 (#65, Mar 30 2005, 09:13:57) on win32 Type "help", "copyright", "credits" or "license" for more information. >>> With...
7
by: Corepaul | last post by:
Missing Help Files When I enter "recordset" as the keyword and search the Visual Basic Help index, I get many topics of interest in the resulting list. But there isn't any information available...
0
by: adrian maull | last post by:
I'm using the GetWindowRect in my screen capture utility: private static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle); My Rect Struct: public struct Rect {
2
by: Stoic | last post by:
Im creating a desktop ticker in C# that I wont to be displayed running along active applications, on the right hand side of the screen (similar to the longhorn sidebar). My question is that when...
4
by: ZhangZQ | last post by:
how to remove the apply and help button from propertysheet? I tried to this->m_psh.dwFlags &= ~PSH_HASHELP; this->m_psh.dwFlags |= PSH_NOAPPLYNOW; this->m_psh.dwFlags |= PSH_NOCONTEXTHELP; ...
1
by: dipak22101980 | last post by:
HI, below is a piece of code. HWND hVWnd; RECT rRect; GetWindowRect(hVWnd,&rRect); diff_val = rRect.bottom-rRect.top;
1
by: Kodiak | last post by:
I have this code snippet below and what I am trying to due is return the sum of the byte returned from the GetDIBits() method. What I am trying to due is if you open up notepad and leave the text...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.