AutoHotkey Community

It is currently May 26th, 2012, 10:22 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: October 26th, 2009, 3:21 pm 
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 ?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 26th, 2009, 3:55 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 27th, 2009, 12:05 pm 
Offline

Joined: October 26th, 2009, 3:51 pm
Posts: 3
Location: North of France
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 3rd, 2010, 7:47 pm 
Offline
User avatar

Joined: May 18th, 2010, 3:10 pm
Posts: 1179
Location: Sweden
Bebert62 wrote:
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


I don't know what people think about reviving old threads, but I'd like to request some help on the same issue. My screens are inverted. As I installed windows 7, I almost killed myself in frustration, since the installation seemed to halt just before it was finished (after a reboot). It turned out that the HDTV was connected, and detected as "primary monitor". From there, I just kept on going (looking at the TV instead) and solved it.

I still have to use "Extended mode" all the time, and apparantly my graphic card sends data in vain to my secondary monitor (I bet?) even when it is turned off. What I would like to do, anyway, is to make my computer screen my main monitor.

I use Windows 7, Radeon 4800 series dual GFX card, CCC (Cataclysm Control Center) and what-else-do-ya-need?

Yeah, I know it's not an AHK question :)

I can toss one in though, so you won't roundkick me or something silly: I once saw a script that can display a minipicture of what happens on your other monitor. What/where is that script?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 5th, 2010, 2:45 pm 
Offline

Joined: October 26th, 2009, 3:51 pm
Posts: 3
Location: North of France
Hi sumon,

I never succeed to solve my problem with my two screens wich are inverted. As soon as my projector is running, it takes the number 1 and my HTPC incorporated screen becomes number 2. And I don t know why... sorry !

Now I use it like that !


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: AndyJenk, Google [Bot], JSLover, Leef_me, patgenn123, rbrtryn, Yahoo [Bot] and 70 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group