AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Dual-Screen with Windows Seven on HTPC

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Bebert62
Guest





PostPosted: Mon Oct 26, 2009 2:21 pm    Post subject: Dual-Screen with Windows Seven on HTPC Reply with quote

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

PostPosted: Mon Oct 26, 2009 2:55 pm    Post subject: Reply with quote

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:
Code:
Send #p
Back to top
View user's profile Send private message Visit poster's website
Bebert62



Joined: 26 Oct 2009
Posts: 1
Location: North of France

PostPosted: Tue Oct 27, 2009 11:05 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group