Having some annoying issues with API calls

This is a discussion on Having some annoying issues with API calls within the C# Programming forums, part of the General Programming Boards category; Quite simply, trying to get the window size of another window. Quite easy research told me to use GetWindowRect (and ...

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    129

    Having some annoying issues with API calls

    Quite simply, trying to get the window size of another window. Quite easy research told me to use GetWindowRect (and subsequently GetClientRect for other stuff I want to do).

    Code:
    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(int hwnd, ref RECT Rect);
    
    ...
    
    // down here somewhere I have successfully tracked the program window I want to look up (and in future affect) y = process from a list
    
    int hWnd = y.Handle.ToInt32(); // works, I get the correct handle
    RECT r = new RECT(); // created with blank/zero values
    GetWindowRect(hWnd, out r);
    
    // get to here and r is still a bunch of zero's...
    
    ...
    
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
    // ignore the values as such, i've found several different ways of doing this, if you know a way that works, let me know!
      public int X;
      public int Y;
      public int Width;
      public int Height; 
    }
    So I successfully track and locate the window I want to move, via a system of adding a program to a listview by it's full path, and then searching the processes for a match which works successfully. But it seems anything I try with API stuff (and not just GetWindowRect) just seems to do nothing. I would be grateful if someone could point out what's going wrong, or even give me a numpties crash course in API stuff...!
    He who asks is a fool for five minutes, but he who does not ask remains a fool forever.

    The fool wonders, the wise man asks. - Benjamin Disraeli

    There are no foolish questions and no man becomes a fool until he has stopped asking questions. Charles Steinmetz

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Code:
    static extern bool GetWindowRect(System.IntPtr hWnd, out RECT rect);
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    Registered User
    Join Date
    Jun 2003
    Posts
    129
    Changed, still zero's.
    He who asks is a fool for five minutes, but he who does not ask remains a fool forever.

    The fool wonders, the wise man asks. - Benjamin Disraeli

    There are no foolish questions and no man becomes a fool until he has stopped asking questions. Charles Steinmetz

  4. #4
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    y = process from a list
    A process is NOT a window, thus not having a location and a size.
    If y is indeed a window (form), then why not just call y.Bounds?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  5. #5
    Registered User
    Join Date
    Jun 2003
    Posts
    129
    What I'm doing is getting the process that is running that I want to affect (which becomes y) and then I get it's handle by

    Code:
    IntPtr hWnd = y.handle;
    This is then used for the hwnd in GetWindowRect
    He who asks is a fool for five minutes, but he who does not ask remains a fool forever.

    The fool wonders, the wise man asks. - Benjamin Disraeli

    There are no foolish questions and no man becomes a fool until he has stopped asking questions. Charles Steinmetz

  6. #6
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    WinAPI has handles to many things, including processes and windows. You cannot pass a process handle to GetWindowRect which expects a window handle.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  7. #7
    Registered User
    Join Date
    Jun 2003
    Posts
    129
    Ah! I'm now using FindWindow using this kind of method now. I wasn't using it before as I thought I had found the correct handle! Thanks!
    He who asks is a fool for five minutes, but he who does not ask remains a fool forever.

    The fool wonders, the wise man asks. - Benjamin Disraeli

    There are no foolish questions and no man becomes a fool until he has stopped asking questions. Charles Steinmetz

  8. #8
    Registered User
    Join Date
    Jun 2003
    Posts
    129
    Well, all that is working completely fine now. It even grabs the right window I'm looking for if there are multiple windows.

    But, there is something going on with the other API stuff that I can't quite put my finger on. This is the current code I've got :

    Code:
    int GWL_STYLE = -16;
    long WS_BORDER = -0x800000;
    long WS_DLGFRAME = -0x400000;
    long WS_THICKFRAME = -0x40000;
    long WS_SIZEBOX = -0x00040000;
    long WS_SYSMENU = -0x00080000;
    long WS_POPUP = -0x80000000;
    uint SWP_NOMOVE = 0x0002;
    uint SWP_NOZORDER = 0x0004;
    uint SWP_FRAMECHANGED = 0x0020;  /* The frame changed: send WM_NCCALCSIZE */
    long WS_CAPTION = WS_BORDER | WS_DLGFRAME;
    IntPtr hWndPtr = FindWindow(null, y.MainWindowTitle);
    Rectangle ScreenSize = myScreens[x.Monitor - 1].Bounds;
    
    long code = GetWindowLong(hWndPtr, GWL_STYLE);
    code= (code & WS_CAPTION & WS_BORDER & WS_THICKFRAME & WS_SIZEBOX & WS_SYSMENU) | WS_POPUP;
    // this line does the proper moving!
    MoveWindow(hWndPtr, ScreenSize.Left, ScreenSize.Top, ScreenSize.Right, ScreenSize.Bottom, 1);
    
    SetWindowLong(hWndPtr, GWL_STYLE, (int)code);
    SetWindowPos(hWndPtr, new IntPtr(-1), ScreenSize.Left, ScreenSize.Top, ScreenSize.Right, ScreenSize.Bottom, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
    It all works as it should. It grabs the correct window, gets the correct info for the destination screen (multi-monitor stuff), gets the window's style information and modifies it. MoveWindow moves the window to the selected monitor, setwindowlong removes the border stuff, and setwindowpos makes it fill that monitor. So you have a pseudo full screen.

    The strange thing is it doesn't work correctly the first time it moves the window. The contained controls in the window do not resize to fit the new dimensions (obvious by a test window mdi-child control not going all the way to the right and the bottom, by the same size as the now hidden borders). Except when you shift the window to another monitor selection, then it's perfect. But even looping this code twice to try and force it again doesn't work (well, it does, but by god is it ugly...).

    So um... Why won't it work first time round, and how do I make it work?
    He who asks is a fool for five minutes, but he who does not ask remains a fool forever.

    The fool wonders, the wise man asks. - Benjamin Disraeli

    There are no foolish questions and no man becomes a fool until he has stopped asking questions. Charles Steinmetz

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 26
    Last Post: 07-05-2010, 11:43 AM
  2. for loop with sort issues
    By redmondtab in forum C Programming
    Replies: 10
    Last Post: 10-09-2006, 11:36 AM
  3. Win32 API Speed Issues
    By samGwilliam in forum Windows Programming
    Replies: 7
    Last Post: 12-07-2005, 07:32 AM
  4. Adding your own API calls.
    By 0x7f in forum Windows Programming
    Replies: 1
    Last Post: 04-08-2003, 07:00 PM
  5. PlaySound Win API
    By INNEEDOFHELP in forum Windows Programming
    Replies: 9
    Last Post: 12-30-2002, 08:46 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21