rollsch
rollsch

Reputation: 2770

GetWindowRect returns wrong values on one application, all other applications are correct

I am using GetWindowRect from the windows API to get the bounds of a running application, I then use these bounds to screenshot the application.

My code works for about 10 programs I have tested, notepad.exe and a few others, however the one app I want to use it with RocLink800 it returns static values that are incorrect regardless of the applications location.

Code is C# .NET

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int X;
        public int Y;
        public int Width;
        public int Height;
    }

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect);

    IntPtr error = GetWindowRect(proc.MainWindowHandle, ref rect);

    ... main code
    while (error == (IntPtr)0)
    {
        error = GetWindowRect(proc.MainWindowHandle, ref rect);
    }

    int width = rect.right - rect.left;
    int height = rect.bottom - rect.top;

Now all applications this returns the correct width and height, with roclink800 it returns an error value of 1 indicating successs but it returns the following values regardless of the applications location:

rect.right = 960 rect.left = 960 rect.bottom = 600 rect.top = 600

I am completely stumped why this is happening or how to rectify it, roclink800 is an old program ported from the windows95 days so perhaps it is using some odd api, if this is the case are there any alternatives from the windows API (user32.dll) to obtaining its screen coordinates?

I guess I could force the application to go fullscreen and screen capture it this way but it is less elegant.

Ideas anyone?

edit: My code for getting the handle

        Process roclink = new Process();
        roclink.StartInfo.FileName = "C:/Program Files (x86)/ROCLINK800/Roclink.exe";
        //roclink.StartInfo.FileName = "notepad.exe";
        roclink.Start();
        IntPtr error = GetWindowRect(roclink.MainWindowHandle, ref rect);

OR

        try
        {
            proc = Process.GetProcessesByName("roclink")[0];
        }
        catch (IndexOutOfRangeException e)
        {
            return null;
        }

Both chunks of code return the same IntPtr and they both return 960,960,600,600 however if I call

int error = SetWindowPos(roclink.MainWindowHandle, HWND_TOPMOST, 0, 0, 25,50, SWP_SHOWWINDOW);

Then I get the returned coordinates being 0,0,25,50 yet the applications size does not change.

I have tried breaking the program, closing roclink and the SetWindowPos and GetWindowRect both return 0 and do not return the false values indicating that the handle is indeed the correct handle.

So it seems this application cannot have its windowsize set or gotten via windowsAPI, anyone got any clues why this may be?

roclink.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;

This also is ignored and the application will not open in fullscreen, simply the size it was last opened in.

edit: The only solution I can come up with is to make a copy of roclink.exe and open it manually by hand fullscreen then close it, providing no one else opens this file it will always open full screen, this is dodgy and I do not like it but unless anyone has any ideas why this is the case I may have to go with this. :(

Upvotes: 4

Views: 7651

Answers (2)

Antonio Bakula
Antonio Bakula

Reputation: 20693

Looking at the screenshot of this RockLink800 application it seems that this is a Delphi application, and old versions of Delphi had a hidden window that was Application.Handle.

Here is a SO answer how to get main window handle for old Delphi applications :

Retrieving Delphi Window Handles

Upvotes: 5

Rotem
Rotem

Reputation: 21917

I think it is obvious that in the case of your application the MainWindowHandle is not the actual 'main window' the application launches.

Upvotes: 5

Related Questions