 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Bebert62 Guest
|
Posted: Mon Oct 26, 2009 2:21 pm Post subject: Dual-Screen with Windows Seven on HTPC |
|
|
DUAL-SCREEN WITH WINDOWS SEVEN
Hello
1. I m a noob with AHK
2. I m french and i don t speak (and write) a very good english
My problem :
When I was running VISTA 32bits on my HTPC and i haven't problem with a script.
Now my HTPC is under SEVEN 32bits and the script doesn t work anymore.
HTPC Config :
- "ZALMAN HD160XT plus" case with incorporated 7inch screen 800x600
- "SANYO PLVZ4" Projector 1280x720 (HD Ready)
- "GYRATION GYR3101" Remote (WMC compatible)
- "WINDOWS MEDIA CENTER" for the software
To consult TV guide, to schedule my TV recordings and to listen music, i use the small 7inch screen in 800x600.
But when i want to watch a TV program or a DVD i use my projector in 1280x720 resolution. I never use the two screens together
Using the AHK forums, i made a script which do :
1. Detects double-push on '#' key (=key '3') of the remote control to start point 2
2. Toggle screens : switch OFF screen N°1 (or 2) and switch ON screen N°2 (or 1)
3. Detects the supported resolutions of the screen (which is ON)
- if 1280x720 possible so the active screen is my projector
- if not it is the 7inch screen of the HTPC which is ON
4. Adjust the resolution, if 1280x720 possible, so use it else use 800x600
5. double-push on '*' key (=key '8') of the remote control, the HTPC displays the current resolution (only for checking)
The script (i m not the author of all the Subroutines, i m just the author of the compilation)
| Code: |
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
currentMode = 0
Gui +LastFound +AlwaysOnTop -Caption +ToolWindow
Gui, Color, FFFFAA
Gui, Font, s60, Arial Black
Gui, Add, Text, vMyText cLime, XXXXX x YYYYY
WinSet, TransColor, FFFFAA 150
3::
if Key01 > 0
Key01 = Key01 + 1
else
Key01 = 1
SetTimer, SubKey01 , 500
return
8::
if Key02 > 0
Key02 = Key02 + 1
else
Key02 = 1
SetTimer, SubKey02 , 500
return
; Subroutines for Key Pressed
SubKey01:
SetTimer, SubKey01, off
if Key01 > 1
{
SoundBeep, 50, 25
if (currentMode = 0) {
EnableDisplayDevice("\\.\DISPLAY2", 1)
EnableDisplayDevice("\\.\DISPLAY1", 0)
currentMode = 1
} else if (currentMode = 1) {
EnableDisplayDevice("\\.\DISPLAY1", 1)
EnableDisplayDevice("\\.\DISPLAY2", 0)
currentMode = 0
}
struct_devicemode_size = 156
VarSetCapacity( device_mode, struct_devicemode_size, 0 )
EncodeInteger( struct_devicemode_size, 2, &device_mode, 36 )
Mode_800_600_32_60fps = 0
Mode_1024_768_32_60fps = 0
Mode_1280_720_32_60fps = 0
loop,
{
success := DllCall( "EnumDisplaySettings", "uint", 0, "uint", A_Index-1, "uint", &device_mode )
if ( ErrorLevel or !success )
break
mode?width := DecodeInteger( "uint4", &device_mode, 108, false )
mode?height := DecodeInteger( "uint4", &device_mode, 112, false )
mode?quality := DecodeInteger( "uint4", &device_mode, 104, false )
mode?frequency := DecodeInteger( "uint4", &device_mode, 120, false )
if (mode?width=800 and mode?height=600 and mode?quality=32 and mode?frequency=60)
Mode_800_600_32_60fps = 1
if (mode?width=1024 and mode?height=768 and mode?quality=32 and mode?frequency=60)
Mode_1024_768_32_60fps = 1
if (mode?width=1280 and mode?height=720 and mode?quality=32 and mode?frequency=60)
Mode_1280_720_32_60fps = 1
}
if (Mode_1280_720_32_60fps = 1)
{
ScrQuality = 32
ScrWidth = 1280
ScrHeight = 720
ScrFrequency = 60
}
else if (Mode_800_600_32_60fps = 1)
{
ScrQuality = 32
ScrWidth = 800
ScrHeight = 600
ScrFrequency = 60
}
EncodeInteger( 0x00040000|0x00080000|0x00100000|0x00400000, 4, &device_mode, 40 )
EncodeInteger( ScrQuality , 4, &device_mode, 104 )
EncodeInteger( ScrWidth , 4, &device_mode, 108 )
EncodeInteger( ScrHeight , 4, &device_mode, 112 )
EncodeInteger( ScrFrequency , 4, &device_mode, 120 )
result := DllCall( "ChangeDisplaySettings", "uint", &device_mode, "uint", 0 )
if ( ErrorLevel )
MsgBox, [ChangeDisplaySettings] failure: EL = %ErrorLevel%
else
{
if ( result = 0 )
{
LV_Modify( current?index, "Icon0" )
current?index := A_EventInfo
LV_Modify( current?index, "Icon1" )
result = DISP_CHANGE_SUCCESSFUL
}
else if ( result = 1 )
result = DISP_CHANGE_RESTART
else if ( result = -1 )
result = DISP_CHANGE_FAILED
else if ( result = -2 )
result = DISP_CHANGE_BADMODE
else if ( result = -3 )
result = DISP_CHANGE_NOTUPDATED
else if ( result = -4 )
result = DISP_CHANGE_BADFLAGS
else if ( result = -5 )
result = DISP_CHANGE_BADPARAM
else if ( result = -6 )
result = DISP_CHANGE_BADDUALVIEW
}
}
Key01 = 0
return
SubKey02:
SetTimer, SubKey02, off
if Key02 > 1
{
SoundBeep, 50, 25
ResolutionDisplay()
}
Key02 = 0
return
; Subroutine for display resolution
ResolutionDisplay()
{
Gui, Show, x0 y0 NoActivate
SysGet, VirtualScreenWidth, 78
SysGet, VirtualScreenHeight, 79
GuiControl,, MyText, %VirtualScreenWidth% x %VirtualScreenHeight%
Sleep, 1000
Gui, Hide
}
; Enables, disables or toggles a display device.
;
; DeviceName: The name of the device, e.g. \\.\DISPLAY1
; Alternatively, it can be the index of the device, which might
; not be the same as the number shown in Display Settings.
; Action: The action to take.
; 0 Disable (false is synonymous with 0)
; 1 Enable (true is synonymous with 1)
; -1 Toggle
; NoReset: If true, settings will be saved to the registry, but not applied.
;
; The following can be used to apply settings saved in the registry:
; DllCall("ChangeDisplaySettings", "uint", 0, "uint", 1)
;
; Return values:
; DISP_CHANGE_SUCCESSFUL 0
; DISP_CHANGE_RESTART 1
; DISP_CHANGE_FAILED -1
; DISP_CHANGE_BADMODE -2
; DISP_CHANGE_NOTUPDATED -3
; DISP_CHANGE_BADFLAGS -4
; DISP_CHANGE_BADPARAM -5
;
EnableDisplayDevice(DeviceName, Action=1, NoReset=false)
{
if (Action = -1) || (DeviceName+0 != "")
{
VarSetCapacity(DisplayDevice, 424), NumPut(424, DisplayDevice, 0)
VarSetCapacity(ThisDeviceName, 32, 0)
Index = 0
Loop {
if !DllCall("EnumDisplayDevices", "UInt", 0, "UInt", A_Index-1, "UInt", &DisplayDevice, "UInt", 0)
return -5
ThisDeviceState := NumGet(DisplayDevice, 164)
Index += 1
DllCall("lstrcpynA", "Str", ThisDeviceName, "UInt", &DisplayDevice+4, "int", 32)
if (DeviceName = Index || DeviceName = ThisDeviceName)
{
if Action = -1
Action := !(ThisDeviceState & 1)
DeviceName := ThisDeviceName
break
}
}
}
VarSetCapacity(devmode, 156, 0), NumPut(156, devmode, 36, "UShort")
if (Action){
NumPut(0x000020, devmode, 40) ; Enable by setting position = {0,0}
VarSetCapacity(Point,8,0)
Numput(A_ScreenWidth + 1,Point)
Numput(&point,devmode,44)
}
else
NumPut(0x180020, devmode, 40) ; Disable by setting size = {0,0}
err := DllCall("ChangeDisplaySettingsEx", "str", DeviceName, "uint", &devmode, "uint", 0, "uint", 0x10000001, "uint", 0)
if !err && !NoReset
err := DllCall("ChangeDisplaySettings", "uint", 0, "uint", 1)
return err, ErrorLevel:=Action
}
DecodeInteger( p_type, p_address, p_offset, p_hex=true )
{
old_FormatInteger := A_FormatInteger
if ( p_hex )
SetFormat, Integer, hex
else
SetFormat, Integer, dec
sign := InStr( p_type, "u", false )^1
StringRight, size, p_type, 1
loop, %size%
value += ( *( ( p_address+p_offset )+( A_Index-1 ) ) << ( 8*( A_Index-1 ) ) )
if ( sign and size <= 4 and *( p_address+p_offset+( size-1 ) ) & 0x80 )
value := -( ( ~value+1 ) & ( ( 2**( 8*size ) )-1 ) )
SetFormat, Integer, %old_FormatInteger%
return, value
}
EncodeInteger( p_value, p_size, p_address, p_offset )
{
loop, %p_size%
DllCall( "RtlFillMemory"
, "uint", p_address+p_offset+A_Index-1
, "uint", 1
, "uchar", ( p_value >> ( 8*( A_Index-1 ) ) ) & 0xFF )
}
|
Under XP and VISTA, this script works fine. But now under SEVEN it doesn't work anymore...
I think it is the sub-routine which toggle the screens which seems to be inoperate (but i m not sure)
Someone can help me ? |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 4366 Location: Qld, Australia
|
Posted: Mon Oct 26, 2009 2:55 pm Post subject: |
|
|
I don't know if it will be of help, but...
When I tried EnableDisplayDevice and a few slight variations on Windows 7, I found that as I toggled monitors on and off, they would seem to randomly switch - #1 became #2 and vice versa. I was unable to find a good solution in AutoHotkey, but I stopped looking when I stumbled upon the Win+P hotkey. If you press Win+P on Windows 7, it will bring up a menu with "Computer only", "Duplicate", "Extend", "Projector only" and pictures to match. I frequently use "Computer only" (secondary monitor disabled) and "Extend" (secondary monitor enabled).
Btw, this also triggers the menu:
|
|
| Back to top |
|
 |
Bebert62
Joined: 26 Oct 2009 Posts: 1 Location: North of France
|
Posted: Tue Oct 27, 2009 11:05 am Post subject: |
|
|
Hi Lexikos,
Thanks a lot for the WIN+P key.
It's very easy to jump from one screen to another one and the differents resolutions of my 2 screens are keeped.
Just one small problem :
Computer only -> my projector is ON and my HTPC screen is OFF
Projector only -> my projector is OFF and my HTPC screen is ON
The two screens are inverted...
I think i will unplugg my projector and reinstall SEVEN with 7inch screen.
Thanks |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|