Создать окно больше рабочего стола (разрешение экрана) - PullRequest
7 голосов
/ 15 января 2009

Мне нужно изменить размер окна больше, чем разрешение экрана или размер рабочего стола, программно и желательно также вручную.

Поскольку в MS-Windows XP / Vista размер окна больше размера экрана, есть ли у кого-нибудь идеи обойти это ограничение?

Я пытаюсь создать эффект панорамирования на ноутбуке, чтобы дать мне больше места для работы. У старого ноутбука с меньшим размером ЖК-дисплея была такая возможность.

Смотрите это: http://www.experts -exchange.com / OS / Microsoft_Operating_Systems / Windows / 98 / Q_21832063.html

Ответы [ 9 ]

12 голосов
/ 09 ноября 2011

Если вы хотите изменить размер окна, которым вы не владеете (и без использования каких-либо перехватчиков), вы можете использовать Windows SetWindowPos API с установленным флагом SWP_NOSENDCHANGING (0x0400):

BOOL WINAPI SetWindowPos(
__in      HWND hWnd,
__in_opt  HWND hWndInsertAfter,
__in      int X,
__in      int Y,
__in      int cx,
__in      int cy,
__in      UINT uFlags // ** SWP_NOSENDCHANGING must be passed here **
);

Это предотвратит отправку сообщения WM_WINDOWPOSCHANGING, которое вызывает ограничение WM_GETMINMAXINFO. Любое другое изменение размера окна приведет к тому, что ограничение вернет окно к ограниченным размерам рабочего стола, так как сообщение будет отправлено и размер окна будет принудительно установлен.

Окно Resizer (C #)

Ниже приведен небольшой пример программы, которая изменит размер Блокнота на 6000x6000 (измените строку «Без названия - Блокнот» на заголовок окна, размер которого вы хотите изменить, или извлеките имя окна и желаемый размер из аргументов командной строки)

namespace Example
{
 class Program
 {
  [DllImport("USER32.DLL")]
  public static extern IntPtr FindWindow(String className, String windowName);

  [DllImport("USER32.DLL", SetLastError = true)]
  public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int left, int top, int width, int height, uint flags);

  static void Main(string[] args)
  {
   var TOP = new IntPtr(0);
   uint SHOWWINDOW = 0x0040, NOCOPYBITS = 0x0100, NOSENDCHANGING = 0x0400;
   var hwnd = FindWindow(null, "Untitled - Notepad");
   SetWindowPos(hwnd, TOP, 0, 0, 6000, 6000, NOCOPYBITS | NOSENDCHANGING | SHOWWINDOW);
  }
 }
}

Ограничения и предостережения

Этот подход, как правило, функционален, но есть ряд ограничений, которые могут помешать изменению размера окна или изменению размера любым полезным способом.

Безопасность

Начиная с Windows Vista, Microsoft внедрила повышенную безопасность вокруг оконных сообщений. Исполняемый файл может взаимодействовать только с окнами в своем собственном контексте безопасности или ниже. Например, чтобы изменить размер окна «Управление компьютером» (которое всегда выполняется с повышенными правами), эта программа должна также работать с повышенными правами.

Исправлена ​​логика Windows и макета

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

Windows с active принудительно контролирует размер, либо перехватывая сообщения Windows, такие как WM_SIZE, либо в более сложной логике компоновки. Эти окна могут принимать сообщение, но ограничивают или ограничивают окончательный размер в своем собственном коде.

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

WPF

Класс Window в WPF имеет HwndSource, который обрабатывает оконные сообщения, отправленные в окно WPF. Приватный метод LayoutFilterMessage перехватывает сообщения WM_SYSCOMMAND, WM_SIZING, WM_WINDOWPOSCHANGING и WM_SIZE. В этом случае сообщение WM_SIZE затем обрабатывается закрытым Process_WM_SIZE, который фактически обходит флаг NOSENDCHANGING и изменяет RenderSize клиентской области WPF. Это часть общего процесса адаптации старых сообщений Win32 к событиям WPF.

Чистый эффект заключается в том, что размер окна Win32 host изменяется (если для параметра SizeToContent не установлено значение SizeToContent.WidthAndHeight), но область рендеринга WPF заблокирована для области рабочего стола, так как если флаг NOSENDCHANGING не был установлен. Когда приведенный выше пример кода запускается для приложения WPF, вы можете увидеть окно 6000x6000 в Aero Peek на панели задач или предварительный просмотр окна в переключателе Windows-Tab, но вы также можете увидеть, что содержимое WPF и логика макета обрезаны до область рабочего стола. Таким образом, окно WPF похоже на активно принудительное окно, но вместо принудительного применения определенного размера обеспечивает применение определенного максимального (для RenderArea) и не учитывает WM_WINDOWPOSCHANGING сообщение.

Если это ваше собственное приложение и вы размещаете WPF в окне Windows Forms (через ElementHost), вы можете изменить размер окна, и содержимое WPF будет соответствовать большему окно формы Windows для рабочего стола.

Другие рамки

Другие структуры, такие как GTK и Qt, могут или не могут применять поведение и ограничения размера, и могут иметь различные обходные пути, позволяющие преодолеть эти ограничения. Любая данная программа может игнорировать, переписывать или обходить оконное сообщение, и инфраструктура может применять его ко всему классу приложений, например, с WPF выше.

Подробнее об API SetWindowPos:

Справочный источник для Process_WM_SIZE метод HwndSource:

http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Interop/HwndSource.cs,da4aa32ad121c1b9,references

2 голосов
/ 07 апреля 2016

Вы можете сделать что-то вроде следующего кода в WinProc ();

case WM_GETMINMAXINFO:
    {
        LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam; 
        GetWindowRect(GetDesktopWindow(), &actualDesktop);
        lpmmi->ptMaxTrackSize.x = 3000;// set the value that you really need.
        lpmmi->ptMaxTrackSize.y = 3000;// set the value that you really need.
    }
    break;

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

2 голосов
/ 25 января 2011

Этот код в C # делает то, что вы просите. Окно намного шире рабочего стола.

 protected override void WndProc(ref Message m) {
        if (m.ToString().Contains("GETMINMAXINFO")) {
            //Hent data
            MINMAXINFO obj = (MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(MINMAXINFO));
            //Endre
            if (obj.ptMaxSize.X > 0) {
                obj.ptMaxSize.X = 60000;
                obj.ptMaxSize.Y = 60000;
                obj.ptMaxTrackSize.X = 60000;
                obj.ptMaxTrackSize.Y = 60000;
                //Oppdater
                Marshal.StructureToPtr(obj, m.LParam, true);
            }
        }
        if (m.ToString().Contains("WINDOWPOSCHANGING")) {
            //Hent data
            WINDOWPOS obj = (WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));
            //Endre
            if (obj.cx > 0) {
                obj.cx = 8000;
                //Oppdater
                Marshal.StructureToPtr(obj, m.LParam, true);
            }
        }
        //Debug.WriteLine(m.ToString());
        base.WndProc(ref m);
    }











    [StructLayout(LayoutKind.Sequential)]
    internal struct WINDOWPOS {
        internal IntPtr hwnd;
        internal IntPtr hWndInsertAfter;
        internal int x;
        internal int y;
        internal int cx;
        internal int cy;
        internal uint flags;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct MINMAXINFO {
        internal POINT ptReserverd;
        internal POINT ptMaxSize;
        internal POINT ptMaxPosition;
        internal POINT ptMinTrackSize;
        internal POINT ptMaxTrackSize;
    }
    [StructLayout(LayoutKind.Sequential)]
    internal struct POINT {
        internal int X;
        internal int Y;
    }
1 голос
/ 07 ноября 2011

В списке указаны только рекомендуемые разрешения экрана. Для дополнительных настроек нажмите кнопку Advanced на вкладке Settings, нажмите Adapter tab и затем нажмите List all Modes. Выберите нужное разрешение, уровень цвета и частоту обновления.

Я только что сделал это, здесь вы можете найти ответ в последнем пункте.

http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/display_change_screen_resolution.mspx?mfr=true

1 голос
/ 28 декабря 2009

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

0 голосов
/ 12 ноября 2018

Мне нужно было отодвинуть часть окна за верхнюю часть экрана, и я наконец смог сделать это, используя скрипт AutoHotKey:

SetTitleMatchMode, 2
WinTitle := "Visual Studio Code"

; --- WinMove version

; WinMove, %WinTitle%, , 0, -64, 1280, 1504

; -- DLL version

WinGet, id, , %WinTitle%
Result := DllCall("SetWindowPos", "uint", id, "uint", HWND_TOP, "Int", 0, "Int", -64, "Int", 1280, "Int", 1504, "UInt", 0x400)

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

0 голосов
/ 06 января 2010

Размер окна зависит от размера рабочего стола, а не от разрешения экрана; однако рабочий стол соответствует разрешению. Хитрость заключается в том, чтобы изменить размер рабочего стола или начать с него.

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

Что такое SDesk? SDesk не является многопользовательская программа. Это программа который создает один гигантский рабочий стол который выходит за пределы видимой области монитора. Только часть SDesk виден одновременно, как определено по настройкам рабочего стола Windows.

Исходная домашняя страница программного обеспечения SDesk архивирована здесь В Интернете нет текущей страницы (которую я мог бы найти), но эта архивированная версия доступна через Way Back Machine , которая кеширует много интернета.

Продукт SDesk является бесплатным. Хотя исходный код не был включен. Вы можете посетить его страницу контактов (также доступную в заархивированной версии), чтобы узнать, доступен ли источник или его можно приобрести для вашего исследования.

0 голосов
/ 16 января 2009

хорошо, я попробовал использовать клавиши для перемещения, изменения размера окон. Но система автоматически переместит окна обратно в видимую область рабочего стола в моем XP. Я также попробовал SetWindowPos API, и не помогает. Наилучшим шансом будет написать видеодрайвер, но это может потребовать дополнительного изучения. Рабочий стол 360 утверждает, что вы можете расширить рабочий стол по горизонтали. Но на самом деле это просто панорамирование текущего рабочего стола в более широком виртуальном пространстве. Любые окна внутри по-прежнему имеют ограничение размера не больше, чем ваше разрешение экрана.

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

0 голосов
/ 15 января 2009

Для конкретного случая, когда вам нужно более дружественное к экрану представление MSDN или на любом другом сайте (например, StackOverflow), который плохо использует экранное пространство, я бы предложил применить пользовательскую таблицу стилей к странице, используя такие инструменты, как IE7Pro (IE), Greasemonkey (Firefox), Stylish (Fireox) или встроенный инструмент выбора таблиц стилей в Opera.

...