2010-10-04 2 views
11

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

Я могу исправить это, щелкнув правой кнопкой мыши на рабочем столе, выбрав Screen Resolution и нажав Detect. Это позволяет Windows обнаруживать подключенные дисплеи и настраивать оптимальное разрешение.

Я бы хотел написать небольшую утилиту, чтобы сделать это автоматически. Какой вызов Win32 API или объект C# следует использовать?

+0

У меня нет опции «Обновить». Это может быть дополнение от производителя видеокарты. –

+0

Извините, Ганс, на самом деле говорит 'Detect' - я отредактировал вопрос. Я считаю, что это стандартная кнопка. –

ответ

1

Вы можете попробовать:

  1. Вы можете использовать Spy ++ для поиска окон, которые открыты и смотрели на их свойства и сообщений.
  2. Используйте процесс для запуска «rundll32.exe shell32.dll, Control_RunDLL desk.cpl» или поэкспериментируйте с вызовом непосредственно, чтобы увидеть, можете ли вы получить дескриптор окна, проверьте ссылку ниже для идей.
  3. Используйте код "send button click to external app" и измените его, чтобы найти окно с надписью «Разрешение экрана» и отправить BN_CLICK на дочернее окно с надписью «Обнаруживать».
  4. Поскольку компьютер уже включен, вы можете запустить его автоматически при входе в систему, для чего используется планировщик задач.
+0

Если по какой-то причине это не работает с планировщиком задач, попробуйте настроить его для запуска в качестве пользователя как администратора, так как Win7 UAC может быть неприятным. – Marlon

1

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

[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 714)] 
public struct DISPLAY_DEVICE 
{ 
    [FieldOffset(0)] 
    public int cb; 
    [FieldOffset(4)] 
    public char DeviceName; 
    [FieldOffset(68)] 
    public char DeviceString; 
    [FieldOffset(324)] 
    public int StateFlags; 
    [FieldOffset(328)] 
    public char DeviceID; 
    [FieldOffset(584)] 
    public char DeviceKey; 
} 

[DllImport("User32.dll", SetLastError = true)] 
static extern Boolean EnumDisplayDevices(
     string lpDevice, 
     uint iDevNum, 
     ref DISPLAY_DEVICE lpDisplayDevice, 
     uint dwFlags 
); 

public void DetectDevices() 
{ 
    var flag = true; 
    for (uint i = 0; flag && i < 100; i++) 
    { 
     var device = new DISPLAY_DEVICE(); 
     device.cb = Marshal.SizeOf(device); 
     flag = EnumDisplayDevices(null, i, ref device, 1); 
    } 
} 
+0

gah, и это может быть один лайнер на C/C++, почему люди беспокоятся и уходят с пути с C#, когда C/C++ является естественным выбором здесь? –

+1

Возможно, потому что он попросил C#. –

1

Это поможет вам на полпути:

Execute: control.exe desk.cpl, Настройки, Настройки @

Это вызовет разрешение экрана панели непосредственно.

Я также могу предложить инструмент для создания сценариев, например http://en.wikipedia.org/wiki/Windows_Script_Host И напишите утилиту, которая откроет панель и нажмите кнопку.

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

1

Почему бы просто не использовать Do It Again и написать макрос, который сбрасывает разрешение для вас, записывая действия с мышью и клавиатурой?