Nick Taylor
Nick Taylor

Reputation: 153

Window Maximum Maximise

I am looking to create a program where I can set the maximum maximize size (as in the size the window maximises to when you hit the maximise button) and maximize position (X/Y coordinated for the maximised window) for all of the windows that are running. This is so that I can have my Rainmeter visible at all times on my secondary monitor without having to manually resize every window fit inside of it.

I have managed to do this for a simple program I wrote using MINMAXSIZE from the WinAPI. This method seems to work perfectly for my little program, but there is very little documentation on it beside 1 or 2 articles on the internet. I was wondering if this would be the best way to set the maximum maximise size, or if there is another way to do this.

They way I planned to implement this into all of the applications was going to be either DLL Injection or Hooks (neither of which I have any experience with), so I was also wondering your guys' thoughts on these methods.

I know there are a few applications out there that already do this, but I thought this could be a learning experience, and as well, all of the applications I tried do not work very well (although this could be the case with all of them due to the way Windows functions).

If any of you are still unsure about what I am talking about, MaxMax does exactly what I want (although it doesn't work so well, as I stated in my previous paragraph).

Thank you all in advance.

Upvotes: 1

Views: 1892

Answers (2)

Matteo Italia
Matteo Italia

Reputation: 126817

What you're probably looking for is the work area setting, that you can set/retrieve with the SystemParametersInfo function, called with the flags SPI_SETWORKAREA/SPI_GETWORKAREA.

Upvotes: 2

Mike Kwan
Mike Kwan

Reputation: 24447

What you want to do is use a global windows hook to handle WM_GETMINMAXINFO. As you may be aware, this is the message that is:

Sent to a window when the size or position of the window is about to change. An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size.

The best way to use this to override the default maximum is to fill in the MINMAXINFO structure like so:

case WM_GETMINMAXINFO: {
  DefWindowProc(hWnd, message, wParam, lParam);
  MINMAXINFO* mmi = (MINMAXINFO*)lParam;
  mmi->ptMaxTrackSize.x = 100;
  mmi->ptMaxTrackSize.y = 100;
  return 0;
}

This will allow the default values to be assigned to the sizes you don't care about (min x/y) in this case, leaving you to fiddle with the max values as you please. Your windows hook should be done with SetWindowsHookEx() and should look something like this:

SetWindowsHookEx(WH_CALLWNDPROC, hook_procedure, instance_handle, 0);

hMod (instance_handle) should only be set depending on the circumstances (check the docs for this). The dwThreadId mandates a global hook. Your CallWndProc might looks something like this:

__declspec(dllexport) LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
  CWPSTRUCT* cwp = (CWPSTRUCT*)lParam;
  if(WM_GETMINMAXINFO == cwp->message) {
    DefWindowProc(hWnd, message, wParam, lParam);
    MINMAXINFO* mmi = (MINMAXINFO*)lParam;
    mmi->ptMaxTrackSize.x = 100;
    mmi->ptMaxTrackSize.y = 100;
    return 0;
  }

  return CallNextHookEx(next_hook, nCode, wParam, lParam);
}

Unfortunately something you are going to have to deal with is that the only windows that will be hooked are the ones that had were existing when you made your call to SetWindowsHookEx(). I'm not aware of a clean way of getting past this, short of looping a call to SetWindowsHookEx() (ergh!).

You could potentially do this with DLL injection and effectively subclass every window with EnumWindows, EnumChildWindow and SetWindowLongPtr/SetWindowSubclass. But why go to all that trouble when you could just use SetWindowsHookEx? :)

To alter the x/y, you might have to add an override for WM_SYSCOMMAND and check for SC_MAXIMIZE then use SetWindowPos/MoveWindow to position it properly (if you don't want it on the default 0, 0).

Upvotes: 1

Related Questions