Окно Максимум Максимизировать - PullRequest
1 голос
/ 02 сентября 2011

Я хочу создать программу, в которой я могу установить максимальный размер максимизации (например, размер окна, до которого максимизируется окно при нажатии кнопки максимизации) и положение максимизации (координаты X / Y для максимизированного окна) для всех окна, которые работают. Это сделано для того, чтобы я всегда мог видеть свой Rainmeter на дополнительном мониторе без необходимости вручную изменять размер каждого окна внутри него.

Мне удалось сделать это для простой программы, которую я написал, используя MINMAXSIZE из WinAPI. Этот метод, кажется, отлично работает для моей маленькой программы, но в ней очень мало документации, кроме 1 или 2 статей в Интернете. Мне было интересно, если это будет лучший способ установить максимальный размер максимизации, или есть ли другой способ сделать это.

То, как я планировал внедрить это во все приложения, было либо DLL Injection, либо Hooks (ни с одним из которых у меня не было опыта), так что мне было интересно узнать мнение ваших парней об этих методах.

Я знаю, что есть несколько приложений, которые уже делают это, но я подумал, что это может быть опытом обучения, и также, все приложения, которые я попробовал, не очень хорошо работают (хотя это может быть в случае с все из-за того, как работает Windows).

Если кто-то из вас все еще не уверен в том, о чем я говорю, MaxMax делает именно то, что я хочу (хотя это не работает так хорошо, как я говорил в моем предыдущем абзаце).

Спасибо всем заранее.

Ответы [ 2 ]

2 голосов
/ 02 сентября 2011

Вероятно, вам понадобится настройка рабочая область , которую вы можете установить / получить с помощью функции SystemParametersInfo, вызываемой с флагами SPI_SETWORKAREA / SPI_GETWORKAREA.

1 голос
/ 02 сентября 2011

То, что вы хотите сделать, это использовать глобальный хук окон для обработки WM_GETMINMAXINFO . Как вы, возможно, знаете, это сообщение:

Отправляется в окно, когда размер или положение окна менять. Приложение может использовать это сообщение для переопределения окна максимальный размер и положение по умолчанию или минимальное или максимальное значение по умолчанию размер отслеживания.

Лучший способ использовать это для переопределения максимального значения по умолчанию - заполнить структуру MINMAXINFO следующим образом:

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

Это позволит присваивать значения по умолчанию размерам, которые вас не интересуют (мин. Х / г) в этом случае, оставляя вам возможность выбирать максимальные значения по своему усмотрению. Ваш хук Windows должен быть сделан с помощью SetWindowsHookEx () и должен выглядеть примерно так:

SetWindowsHookEx(WH_CALLWNDPROC, hook_procedure, instance_handle, 0);

hMod (instance_handle) должен быть установлен только в зависимости от обстоятельств (проверьте документы для этого). DwThreadId требует глобального хука. Ваш CallWndProc может выглядеть примерно так:

__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);
}

К сожалению, вам придется иметь дело с тем, что единственные окна, которые будут подключены, это те, которые существовали, когда вы обращались к SetWindowsHookEx (). Мне не известен чистый способ обойти это, если не считать зацикливание вызова SetWindowsHookEx () (эх!).

Вы можете сделать это с помощью внедрения DLL и эффективно создать подклассы для каждого окна с EnumWindows , EnumChildWindow и SetWindowLongPtr / SetWindowSubclass . Но зачем идти на все эти неприятности, когда вы можете просто использовать SetWindowsHookEx? :)

Чтобы изменить x / y, вам может потребоваться добавить переопределение для WM_SYSCOMMAND и проверить SC_MAXIMIZE, а затем использовать SetWindowPos / MoveWindow , чтобы правильно расположить его (если вы не хотите его по умолчанию 0, 0).

...