Reputation: 2770
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
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
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