Установка текущего монитора в Windows XP/7
Модератор: Модераторы
Установка текущего монитора в Windows XP/7
Уважаемые коллеги, доброго времени суток!
Суть задачи в следующем:
1. Имеется комп с парой мониторов.
2. Нужно заустить IE в режиме киоска на две траницы и так, чтобы каждое отображалось в своем мониторе да еще и в режиме киоска.
С киоском проблем нет. Но экспериментально было установлено, что новое окно создается непосредственно на основном мониторе. Т.о. мне нудно прикрутить юзверю "кнопку" на смену текущего монитора с последующим запуском программы...
Есть ли возможность программно сменить основной монитор?
Возможно мой вопрос будет тривиален, но для меня, из-за отсувия большого практического опыта, его пока сложно решить...
Заранее брагодарен!
Суть задачи в следующем:
1. Имеется комп с парой мониторов.
2. Нужно заустить IE в режиме киоска на две траницы и так, чтобы каждое отображалось в своем мониторе да еще и в режиме киоска.
С киоском проблем нет. Но экспериментально было установлено, что новое окно создается непосредственно на основном мониторе. Т.о. мне нудно прикрутить юзверю "кнопку" на смену текущего монитора с последующим запуском программы...
Есть ли возможность программно сменить основной монитор?
Возможно мой вопрос будет тривиален, но для меня, из-за отсувия большого практического опыта, его пока сложно решить...
Заранее брагодарен!
- Little_Roo
- энтузиаст
- Сообщения: 639
- Зарегистрирован: 27.02.2009 18:56:36
- Откуда: Санкт-Петербург
PapaNT писал(а):Нужно заустить IE в режиме киоска
Шо це за зверь?
Internet ExplorerLittle_Roo писал(а):PapaNT писал(а):Нужно заустить IE в режиме киоска
Шо це за зверь?
- Little_Roo
- энтузиаст
- Сообщения: 639
- Зарегистрирован: 27.02.2009 18:56:36
- Откуда: Санкт-Петербург
PapaNT писал(а):в режиме киоска
Я про ЭТО
Я нечто похожее делал, не для IE. И что такое киоск я тоже не заню (не понимаю термин).
А что бы получит дискрипторы окон:
Код: Выделить всё
ShowWindow(WinHandle,SW_SHOWNORMAL);
MoveWindow(WinHandle,0,0,Max(Screen.Width,Screen.DesktopWidth),Max(Screen.Height,Screen.DesktopHeight),true);
А что бы получит дискрипторы окон:
Код: Выделить всё
EnumWindows(@EnumWindowsProc,0);
EnumChildWindows(WinHandle, @EnumSubWindowsProc, 0);
Режим киоска - это когда IE раскрывается на весь экран и не позволяет использовать средства перемещения окна (у окна нет органов управления свернуть, развернуть, закрыть, переместить и т.д...)Little_Roo писал(а):PapaNT писал(а):в режиме киоска
Я про ЭТО
PapaNT писал(а):Режим киоска - это когда IE раскрывается на весь экран и не позволяет использовать средства перемещения окна (у окна нет органов управления свернуть, развернуть, закрыть, переместить и т.д...)Little_Roo писал(а):PapaNT писал(а):в режиме киоска
Я про ЭТО
То есть речь идет про стандартный "полноэкранный режим", который во всех браузерах вызывается кнопкой F11?
Методы управления как мне кажется те же, что я и предлагал. Возможно нужно запустить в обычном режиме, а потом у ИЕ отправить команду F11.
Суть режима киоска в том, что органов управления не показывается - как на платежных терминалах.
Можете сами попробовать запустить:
iexplore -k http://server_name
alexey38 Если не тудно, то можно ли более развернутый пример, а то у меня не собирается из-за ошибок...
Можете сами попробовать запустить:
iexplore -k http://server_name
alexey38 Если не тудно, то можно ли более развернутый пример, а то у меня не собирается из-за ошибок...
PapaNT писал(а):alexey38 Если не тудно, то можно ли более развернутый пример, а то у меня не собирается из-за ошибок...
У меня это встроено в большой проект. Все раскидано по модулям и компонентам.
Я просто перечислил основные функции, которые у меня использовались для управления окнами. Описание можете найти в инете.
У полноэкранных режимов возможно есть особенности, но суть от этого, как мне кажется, не меняется.
Можно еще покопать в сторону CreateProcess, там при запуске можно указать много параметров. Я это сам использую, но не для указания места на экране, хотя уверен, что можно задать координаты окна или номер экрана.
Импортируйте WebBrowser в IDE (как ActiveX), бросьте компонент на форму как alClient, уберите у формы все бордеры и строку заголовка. Затем разверните форму на экран (нужный) в StayOnTop. Можно вообще сделать развертывание на весь экран путем явного задания координат Monitor[1].Left, Monitor[1].Top, Monitor[1].Width, Monitor[1].Height и следить за потерей фокуса (например, открыть модально).
Так я делаю в приложении для тестирования студентов - все работает, если не дать им окно открытия файла, к примеру. Ваша форма с браузером (без контролов!) будет висеть всегда на развернутой на весь экран поверх других приложений.
Так я делаю в приложении для тестирования студентов - все работает, если не дать им окно открытия файла, к примеру. Ваша форма с браузером (без контролов!) будет висеть всегда на развернутой на весь экран поверх других приложений.
Увы, это для промышленной системы защищенной СЗИ от НСД с функционально-замкнутой средой (только разрешенные приложения). К сожалению, описанные манипуляции с ActiveX недопустимыTimid писал(а):Импортируйте WebBrowser в IDE (как ActiveX), бросьте компонент на форму как alClient, уберите у формы все бордеры и строку заголовка. Затем разверните форму на экран (нужный) в StayOnTop. Можно вообще сделать развертывание на весь экран путем явного задания координат Monitor[1].Left, Monitor[1].Top, Monitor[1].Width, Monitor[1].Height и следить за потерей фокуса (например, открыть модально).
Так я делаю в приложении для тестирования студентов - все работает, если не дать им окно открытия файла, к примеру. Ваша форма с браузером (без контролов!) будет висеть всегда на развернутой на весь экран поверх других приложений.
Сейчас копаю в сторону функций USER32.dll...
С устновкой текущего монитора разобрался. Переключает как доктор прописал:)
Переключалка собрана на базе примера: http://stackoverflow.com/questions/956870/using-changedisplaysettingsex-in-delphi-to-set-primary-monitor
За мой пример прошу не бросаться тухлыми яйцами - собрал для тестирования концепции и код пока не вылизывал. Желающие могут это сделать самостояятельно.
Но проблема в том, что хоть и переключает, но запускаемое после переключения окно нового запускаемого приложения не всегда появляется на новом активном мониторе.
Пробовал через
Но не работет...
Пробовал Задать позицию окна, но не получается.
Может ли кто-либо помочь разобраться?
Переключалка собрана на базе примера: http://stackoverflow.com/questions/956870/using-changedisplaysettingsex-in-delphi-to-set-primary-monitor
За мой пример прошу не бросаться тухлыми яйцами - собрал для тестирования концепции и код пока не вылизывал. Желающие могут это сделать самостояятельно.
Код: Выделить всё
Program SetActiveMonitor;
uses Windows,jwawinuser,JwaWinGDI;
Const
MaxMonCount = 2; //Максимальное число поддерживаемых мониторов
Var
MonCount : Byte; //Число обнаруженных мониторов
i : byte;
// Display Devices
DevMode1 , // Текущие видеорежимы
DevMode2 : TDeviceMode;//LPDevModeA; //}_DeviceModeA;
MonNameA : array [1..MaxMonCount] of PChar; // Список имен мониторов
MonP : byte; // Номер активного монитора
function GetVideoCard(cc : byte) : String; // Выдает имя устройства по номеру
Var
lpDisplayDevice : TDisplaydevice;
dwFlags : DWORD;
begin
lpDisplaydevice.cb := Sizeof(lpDisplayDevice);
dwFlags := 0;
if EnumDisplayDevices(nil,cc,lpDisplayDevice, dwFlags) then
GetVideoCard := lpDisplayDevice.DeviceName;
end;
Procedure ChangeDisplaySettingsExResult(res : DWord);
begin
case res of
Disp_Change_Successful : Writeln('Изменение видеорежима произошло успешно');
Disp_Change_BadDualView : Writeln('Изменение видеорежима было неудачным из-за включенного режима DualView');
Disp_Change_BadFlags : Writeln('Изменение видеорежима было неудачным из-за неверных флагов');
Disp_Change_BadMode : Writeln('Изменение видеорежима было неудачным из-за неподдерживаемого видеорежима');
Disp_Change_BadParam : Writeln('Изменение видеорежима было неудачным из-за неудачных параметров. Это может быть обусловлено ошибочным флагом или набором флагов');
Disp_Change_Failed : Writeln('Изменение видеорежима было неудачным из-за ошибки интерпретации нового видеорежима драйвером видеокарты');
Disp_Change_NotUpdated : Writeln('Изменение видеорежима было неудачным из-за невозможности произвести запись в системный реестр');
Disp_Change_Restart : Writeln('Изменение видеорежима будет произведено после перезапуска компьютера')
else
Writeln('Изменение видеорежима было неудачным из-за неизвестной причины')
end;
end;
Procedure Info;
begin
// Writeln('DevMode1.dmDeviceName = ',PChar(DevMode1.dmDeviceName));
Writeln('DevMode1.dmSpecVersion = ',DevMode1.dmSpecVersion);
Writeln('DevMode1.dmDriverVersion = ',DevMode1.dmDriverVersion);
Writeln('DevMode1.dmSize = ',DevMode1.dmSize);
Writeln('DevMode1.dmDriverExtra = ',DevMode1.dmDriverExtra);
Writeln('DevMode1.dmFields = ',DevMode1.dmFields);
Writeln('DevMode1.dmOrientation = ',DevMode1.dmOrientation);
Writeln('DevMode1.dmPaperSize = ',DevMode1.dmPaperSize);
Writeln('DevMode1.dmPaperLength = ',DevMode1.dmPaperLength);
Writeln('DevMode1.dmPaperWidth = ',DevMode1.dmPaperWidth);
Writeln('DevMode1.dmScale = ',DevMode1.dmScale);
Writeln('DevMode1.dmCopies = ',DevMode1.dmCopies);
Writeln('DevMode1.dmDefaultSource = ',DevMode1.dmDefaultSource);
Writeln('DevMode1.dmPrintQuality = ',DevMode1.dmPrintQuality);
Writeln('DevMode1.dmColor = ',DevMode1.dmColor);
Writeln('DevMode1.dmDuplex = ',DevMode1.dmDuplex);
Writeln('DevMode1.dmYResolution = ',DevMode1.dmYResolution);
Writeln('DevMode1.dmTTOption = ',DevMode1.dmTTOption);
Writeln('DevMode1.dmCollate = ',DevMode1.dmCollate);
// Writeln('DevMode1.dmFormName = ',DevMode1.dmFormName);
Writeln('DevMode1.dmLogPixels = ',DevMode1.dmLogPixels);
Writeln('DevMode1.dmBitsPerPel = ',DevMode1.dmBitsPerPel);
Writeln('DevMode1.dmPelsWidth = ',DevMode1.dmPelsWidth);
Writeln('DevMode1.dmPelsHeight = ',DevMode1.dmPelsHeight);
Writeln('DevMode1.dmDisplayFlags = ',DevMode1.dmDisplayFlags);
Writeln('DevMode1.dmDisplayFrequency = ',DevMode1.dmDisplayFrequency);
Writeln('DevMode1.dmICMMethod = ',DevMode1.dmICMMethod);
Writeln('DevMode1.dmICMINTENT = ',DevMode1.dmICMINTENT);
Writeln('DevMode1.dmMediaType = ',DevMode1.dmMediaType);
Writeln('DevMode1.dmDitherType = ',DevMode1.dmDitherType);
Writeln('DevMode1.dmICCManufacturer = ',DevMode1.dmICCManufacturer);
Writeln('DevMode1.dmICCModel = ',DevMode1.dmICCModel);
Writeln('DevMode1.dmPosition.x = ',DevMode1.dmPosition.x);
Writeln('DevMode1.dmPosition.y = ',DevMode1.dmPosition.y);
Writeln('DevMode1.dmDisplayOrientation = ',DevMode1.dmDisplayOrientation);
Writeln('DevMode1.dmDisplayFixedOutput = ',DevMode1.dmDisplayFixedOutput);
Writeln;
if MonCount <> 1 Then
begin
// Writeln('DevMode2.dmDeviceName = ',PChar(DevMode2.dmDeviceName));
Writeln('DevMode2.dmSpecVersion = ',DevMode2.dmSpecVersion);
Writeln('DevMode2.dmDriverVersion = ',DevMode2.dmDriverVersion);
Writeln('DevMode2.dmSize = ',DevMode2.dmSize);
Writeln('DevMode2.dmDriverExtra = ',DevMode2.dmDriverExtra);
Writeln('DevMode2.dmFields = ',DevMode2.dmFields);
Writeln('DevMode2.dmOrientation = ',DevMode2.dmOrientation);
Writeln('DevMode2.dmPaperSize = ',DevMode2.dmPaperSize);
Writeln('DevMode2.dmPaperLength = ',DevMode2.dmPaperLength);
Writeln('DevMode2.dmPaperWidth = ',DevMode2.dmPaperWidth);
Writeln('DevMode2.dmScale = ',DevMode2.dmScale);
Writeln('DevMode2.dmCopies = ',DevMode2.dmCopies);
Writeln('DevMode2.dmDefaultSource = ',DevMode2.dmDefaultSource);
Writeln('DevMode2.dmPrintQuality = ',DevMode2.dmPrintQuality);
Writeln('DevMode2.dmColor = ',DevMode2.dmColor);
Writeln('DevMode2.dmDuplex = ',DevMode2.dmDuplex);
Writeln('DevMode2.dmYResolution = ',DevMode2.dmYResolution);
Writeln('DevMode2.dmTTOption = ',DevMode2.dmTTOption);
Writeln('DevMode2.dmCollate = ',DevMode2.dmCollate);
// Writeln('DevMode2.dmFormName = ',DevMode2.dmFormName);
Writeln('DevMode2.dmLogPixels = ',DevMode2.dmLogPixels);
Writeln('DevMode2.dmBitsPerPel = ',DevMode2.dmBitsPerPel);
Writeln('DevMode2.dmPelsWidth = ',DevMode2.dmPelsWidth);
Writeln('DevMode2.dmPelsHeight = ',DevMode2.dmPelsHeight);
Writeln('DevMode2.dmDisplayFlags = ',DevMode2.dmDisplayFlags);
Writeln('DevMode2.dmDisplayFrequency = ',DevMode2.dmDisplayFrequency);
Writeln('DevMode2.dmICMMethod = ',DevMode2.dmICMMethod);
Writeln('DevMode2.dmICMINTENT = ',DevMode2.dmICMINTENT);
Writeln('DevMode2.dmMediaType = ',DevMode2.dmMediaType);
Writeln('DevMode2.dmDitherType = ',DevMode2.dmDitherType);
Writeln('DevMode2.dmICCManufacturer = ',DevMode2.dmICCManufacturer);
Writeln('DevMode2.dmICCModel = ',DevMode2.dmICCModel);
Writeln('DevMode2.dmPosition.x = ',DevMode2.dmPosition.x);
Writeln('DevMode2.dmPosition.y = ',DevMode2.dmPosition.y);
Writeln('DevMode2.dmDisplayOrientation = ',DevMode2.dmDisplayOrientation);
Writeln('DevMode2.dmDisplayFixedOutput = ',DevMode2.dmDisplayFixedOutput);
end;
end;
Procedure Usage;
begin
WriteLN('Утилита командной строки для управления монитором.');
WriteLN('(c) Геннадий Ольховой 2012 г.');
WriteLN('bf72 at yandex.ru');
Writeln;
WriteLN('Использование:');
Writeln;
WriteLN('SetActiveMonitor.exe');
WriteLN('Вызов без параметров командной строки производит смену текущего активного монитора в системах с двумя мониторами.');
WriteLN;
WriteLN('SetActiveMonitor.exe /?');
WriteLN('Выводит на экран эту справку.');
WriteLN;
WriteLN('SetActiveMonitor.exe /i или SetActiveMonitor.exe /I');
WriteLN('Выводит общую информацио о мониторах.');
end;
BEGIN
// Инициализация...
MonCount := GetSystemMetrics(SM_CMONITORS); // Получили число мониторов
// Получаем имена мониторов
MonNameA[1] := PChar(GetVideoCard(0));
Windows.EnumDisplaySettings(MonNameA[1],0,DevMode1);
if MonCount <> 1 Then
begin
MonNameA[2] := PChar(GetVideoCard(1));
Windows.EnumDisplaySettings(MonNameA[2],0,DevMode2);
end;
// get current display settings
Windows.EnumDisplaySettings(PChar(MonNameA[1]), ENUM_REGISTRY_SETTINGS, DevMode1);
if MonCount <> 1 Then
Windows.EnumDisplaySettings(PChar(MonNameA[2]), ENUM_REGISTRY_SETTINGS, DevMode2);
// Обработка параметров команденой строки...
if ParamCount <> 0 Then
begin
if ParamStr(1) = '/?' Then
begin
Usage;
exit
end;
if (ParamStr(1) = '/i') or (ParamStr(1) = '/I') Then
begin
if ParamCount > 1 Then
Usage
Else
Info;
exit
end;
Usage; // получили неизвестный параметр командной строки.
exit
end;
// Пара строк отладки (выводит на экран список мониторов)
for i := 0 to MonCount-1 do
Writeln(GetVideoCard(i));
if MonCount = 0 Then
begin
WriteLN('В системе установлен один монитор');
exit // Ничего делать не надо
end;
// Определяем какой монитор основной
if DevMode1.dmPosition.x <> 0 then MonP := 2 // Из-за того, что список мониторов формируется без сортировки по признаку основной/вторичный
else MonP := 1; // определяем признак активности через (_!_) по координатам позиции смещения... $)
// А теперь меняем мониторы местами...
if MonP = 1 Then
begin // "Активным" был первый монитор
// move old primary display to new position
DevMode1.dmFields := DM_POSITION;
WriteLN('Монитор 1 (основной):');
WriteLN('dmPosition.x изменяем с ', DevMode1.dmPosition.x, ' на ',DevMode2.dmPelsWidth);
WriteLN('dmPosition.y изменяем с ', DevMode1.dmPosition.y, ' на 0');
DevMode1.dmPosition.x := DevMode2.dmPelsWidth;
DevMode1.dmPosition.y := 0;
ChangeDisplaySettingsExResult(
Windows.ChangeDisplaySettingsEx(PChar(MonNameA[1]), DevMode1, 0,
CDS_UPDATEREGISTRY or CDS_NORESET, nil));
WriteLN;
// move old secondary display to (0, 0) and make the primary display
WriteLN('Монитор 2 (второй):');
WriteLN('dmPosition.x изменяем с ', DevMode2.dmPosition.x, ' на 0');
WriteLN('dmPosition.y изменяем с ', DevMode2.dmPosition.y, ' на 0');
DevMode2.dmFields := DM_POSITION;
DevMode2.dmPosition.x := 0;
DevMode2.dmPosition.y := 0;
ChangeDisplaySettingsExResult(
windows.ChangeDisplaySettingsEx(PChar(MonNameA[2]), DevMode2, 0,
CDS_SET_PRIMARY or CDS_UPDATEREGISTRY or CDS_NORESET {or DM_DISPLAYFLAGS}, nil));
WriteLN;
end
Else
begin // "Активным" был второй монитор
// move old primary display to new position
DevMode2.dmFields := DM_POSITION;
WriteLN('Монитор 2 (сновной):');
WriteLN('dmPosition.x изменяем с ', DevMode2.dmPosition.x, ' на ',DevMode1.dmPelsWidth);
WriteLN('dmPosition.y изменяем с ', DevMode2.dmPosition.y, ' на 0');
DevMode2.dmPosition.x := {1601;//}DevMode1.dmPelsWidth;
DevMode2.dmPosition.y := 0;
ChangeDisplaySettingsExResult(
Windows.ChangeDisplaySettingsEx(PChar(MonNameA[2]), DevMode2, 0,
CDS_UPDATEREGISTRY or CDS_NORESET, nil));
WriteLN;
// move old secondary display to (0, 0) and make the primary display
WriteLN('Монитор 1 (второй):');
WriteLN('dmPosition.x изменяем с ', DevMode1.dmPosition.x, ' на ',0);
WriteLN('dmPosition.y изменяем с ', DevMode1.dmPosition.y, ' на 0');
DevMode1.dmFields := DM_POSITION;
DevMode1.dmPosition.x := 0;
DevMode1.dmPosition.y := 0;
ChangeDisplaySettingsExResult(
windows.ChangeDisplaySettingsEx(PChar(MonNameA[1]), DevMode1, 0,
CDS_SET_PRIMARY or CDS_UPDATEREGISTRY or CDS_NORESET {or DM_DISPLAYFLAGS}, nil));
WriteLN;
end;
WriteLN('Фиксируем установленную конфигурацию.');
ChangeDisplaySettingsExResult(
windows.ChangeDisplaySettingsEx(nil, PDeviceMode(0)^, 0, 0, nil));
END.
Но проблема в том, что хоть и переключает, но запускаемое после переключения окно нового запускаемого приложения не всегда появляется на новом активном мониторе.
Пробовал через
Код: Выделить всё
Var
P1 : TProcess;
Begin
P1 := Tprocess.Create(nil);
P1.CommandLine := 'Some.exe';
P1.Desktop := '2';
\\или
\\P1.Desktop := '\\.\DISPLAY2';
P1.Execute;
....
End.
Но не работет...
Пробовал Задать позицию окна, но не получается.
Может ли кто-либо помочь разобраться?
Попробовал порыть в сторону:
так оно выдает для запущенного нотпада нули
куда рыть?
Код: Выделить всё
Var
P1 : TProcess;
Begin
P1 := Tprocess.Create(nil);
P1.CommandLine := 'c:\windows\notepad.exe';
P1.Options := P1.Options + [suoWaitOnExit];
writeln(P1.WindowHeight);
writeln(P1.WindowLeft);
writeln(P1.WindowWidth);
writeln(P1.WindowTop);
End.
так оно выдает для запущенного нотпада нули
куда рыть?
Решено.
Как получить число и размеры мониторов я уже публиковал.
Перемещение окна дочернего приложения решил через createprocess
на основе http://forum.pascalnet.ru/lofiversion/index.php/t26066.html
Как получить число и размеры мониторов я уже публиковал.
Перемещение окна дочернего приложения решил через createprocess
Код: Выделить всё
function myFunc(wnd:HWND; lParam: LPARAM): BOOL; stdcall;
begin
MoveWindow(wnd, 20, 20, 400, 400, True); // Ну, забрось окно куда нужно
result := False;
end;
...
// здесь создаешь процесс
WaitForInputIdle(ProcInfo.hProcess, INFINITE); // Ждем создания окна
EnumThreadWindows(ProcInfo.dwThreadId, @myFunc, 0);