1,183
社区成员
发帖
与我相关
我的任务
分享
ShowWindow(FindWindowEx(FindWindow('Shell_TrayWnd', nil), 0, 'Button', nil), SW_HIDE);
Windows.SetParent(FindWindowEx(FindWindow('Shell_TrayWnd', nil), 0, 'Button', nil), GetDesktopWindow);
.............
旋转屏幕90度ChangeDisplaySettingsEx实例——WinCE2010年03月14日 星期日 20:07 DEVMODE DevMode;
memset(&DevMode, 0, sizeof (DevMode));
DevMode.dmSize = sizeof (DevMode);
DevMode.dmFields = DM_DISPLAYORIENTATION;
if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))
{
RETAILMSG(1, (L"ChangeDisplaySettingsEx failed to get the supported rotation angles (error=%d).\n", GetLastError()));
}
else
{
if(DevMode.dmDisplayOrientation == 0)
{
DevMode.dmDisplayOrientation
.........
function ChangeDisplaySettingsEx(lpszDeviceName: PChar; var lpDevMode: TDeviceMode; wnd: HWND; dwFlags: DWORD; lParam: Pointer): Longint; stdcall;In MSDN, the documentation for ChangeDisplaySettingsEx has the following comment for lpDevMode: "If lpDevMode is NULL, all the values currently in the registry will be used for the display setting."My objective is to change the Primary monitor on a system with two active monitors, without changing anything else - resolution, bit depth, etc, should all remain the same. It seems like passing lpDevMode as null (nil) is the method that is provided to accomplish this.However, lpDevMode is defined as a packed record type (TDeviceMode), not a pointer type, in Delphi's Windows.pas. Apparently, the Delphi interface to the Windows API performs the translation to the pointers used by Windows API 'behind the scenes'.I tried calling it like this:var alldevs : array[0..maxdev] of TDisplayDevice; lpDevMode : pointer;begin lpDevMode := nil; lparam := nil; my_hwnd := nil; {... snip....} with alldevs[NewPri] do ChangeDisplaySettingsEx(devicename,TDeviceMode(lpDevMode),my_hwnd,CDS_SET_PRIMARY,lparam);
You could tryChangeDisplaySettingsEx(devicename, PDeviceMode(0)^, my_hwnd, CDS_SET_PRIMARY, lparam);
it does at least compile on Delphi 2009. I can't test it though.
Edit:
According to the scarce information on the net (this is the most detailed I could find) changing the primary display isn't a simple process, so you may be missing a step along the way. I have two monitors, but can't change the primary device at all, not even with the control panel - looks like the dual-head display card driver doesn't allow it. The following therefore isn't tested, but maybe it will help you:
In order to set a new primary display you have to move the current primary display away from the (0, 0) position first. This is more tricky than it needs to be, because the Delphi Windows.pas file has an incomplete TDeviceMode type. It is given as
_devicemodeA = record dmDeviceName: array[0..CCHDEVICENAME - 1] of AnsiChar; ... dmOrientation: SHORT; dmPaperSize: SHORT; dmPaperLength: SHORT; dmPaperWidth: SHORT; dmScale: SHORT; dmCopies: SHORT; dmDefaultSource: SHORT; dmPrintQuality: SHORT; dmColor: SHORT; ...end;
when it should instead be
_devicemodeA = record dmDeviceName: array[0..CCHDEVICENAME - 1] of AnsiChar; ... case boolean of FALSE: ( dmOrientation: SHORT; dmPaperSize: SHORT; dmPaperLength: SHORT; dmPaperWidth: SHORT; dmScale: SHORT; dmCopies: SHORT; dmDefaultSource: SHORT; dmPrintQuality: SHORT; ); TRUE: ( dmPosition: TPoint; dmDisplayOrientation: DWORD; dmDisplayFixedOutput: DWORD; ); dmColor: SHORT; ...end;
You should add the fixed record type to your sources, as you need dmPosition to adjust the origin of the displays. It should go something like this:
// get current display settingsEnumDisplaySettings(PChar(AOldPrimaryDevice), ENUM_REGISTRY_SETTINGS, DevMode1);EnumDisplaySettings(PChar(ANewPrimaryDevice), ENUM_REGISTRY_SETTINGS, DevMode2);// move old primary display to new positionDevMode1.dmFields := DM_POSITION;DevMode1.dmPosition.x := DevMode2.dmPelsWidth;DevMode1.dmPosition.y := 0;Win32Check(ChangeDisplaySettingsEx(PChar(AOldPrimaryDevice), DevMode1, 0, CDS_UPDATEREGISTRY or CDS_NORESET, nil)):// move old secondary display to (0, 0) and make the primary displayDevMode2.dmFields := DM_POSITION;DevMode2.dmPosition.x := 0;DevMode2.dmPosition.y := 0;Win32Check(ChangeDisplaySettingsEx(PChar(ANewPrimaryDevice), DevMode2, 0, CDS_SET_PRIMARY or CDS_UPDATEREGISTRY or CDS_NORESET or DM_DISPLAYFLAGS, nil)):// magic ???Win32Check(ChangeDisplaySettingsEx(nil, PDeviceMode(0)^, 0, 0, nil));