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 

Secondary Monitor
Goto page Previous  1, 2, 3
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Tue Mar 11, 2008 1:34 pm    Post subject: Reply with quote

jamn wrote:
Thank you! But I get an error:
call to nonexistent function
specifically: NumPut(424, DisplayDevice, 0)

AutoHotkey Changelog wrote:
1.0.47 - June 19, 2007
...
Added NumGet() and NumPut(), which retrieve/store binary numbers with much greater speed than Extract/InsertInteger.
-> AutoHotkey Download
Back to top
View user's profile Send private message
jamn
Guest





PostPosted: Wed Mar 12, 2008 9:35 pm    Post subject: Reply with quote

Shocked I ran a much older version than I thought... Sorted now. The script now gives no error, but it does not seem to do much either. At least it does not enable my second display (a LCD TV). Is there some setting I could/should change?
Back to top
canta



Joined: 30 May 2006
Posts: 49

PostPosted: Thu Mar 13, 2008 5:52 am    Post subject: Reply with quote

I put EnableDisplayDevice.ahk & EnumDisplayDevices.ahk in my lib and ran
Code:
EnableDisplayDevice("\\.\DISPLAY2", -1)
It disables my second monitor just fine, but wont enable it again. Changing -1 to 1 doesnt help either.
Back to top
View user's profile Send private message Visit poster's website
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Thu Mar 13, 2008 6:14 am    Post subject: Reply with quote

If EnableDisplayDevice doesn't work, try the more primitive registry method I mentioned earlier in this thread. If it fails to enable the display by name, it is probably a quirk of your display drivers, so the registry method might not work either.

Btw, the most recent version of EnableDisplayDevice does not use EnumDisplayDevices.ahk (though EnumDisplayDevices example 2 may still be used to determine the existing display devices.)
Quote:
The script now gives no error, but it does not seem to do much either.
Can the LCD TV be seen in Display Settings? If not, you will probably have to resort to using whatever utility came with your display drivers.

If it shows in Display Settings, try passing whatever number is shown there to EnableDisplayDevice. For instance,
Code:
EnableDisplayDevice(2, -1) ; not "\\.\DISPLAY2"
I realise now my previous comment is inaccurate since Display Settings also shows disabled displays. (The numbers are less likely to differ than I thought, though it is still a possibility.)
In the code, I wrote:
Alternatively, it can be the index of the device, which might not be the same as the number shown in Display Settings, since it includes displays that aren't currently enabled.
Back to top
View user's profile Send private message
Superfraggle



Joined: 02 Nov 2004
Posts: 962
Location: London, UK

PostPosted: Sun Mar 16, 2008 10:48 pm    Post subject: Reply with quote

Lexikos wrote:
Superfraggle wrote:
I also tried this and couldnt get it to work.

I used
Code:
EnableDisplayDevice("\\.\DISPLAY2", 1)


where \\.\DISPLAY2 is the name reported by enumdisplay adapters when my second monitor was on. But it did nothing.
If your second monitor was already on, attempting to turn it on should do nothing. Razz Use -1 to toggle or 0 to turn it off. Sorry for not replying sooner; I guess I missed your post.



I turned it off before trying to turn it on, don't worry I'm not that bad. It just wasnt detecting it when it was off.

Ill try the new one next time I am in work.
_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Sun Mar 16, 2008 11:59 pm    Post subject: Reply with quote

Make sure the display can be enabled via Display Settings. If it cannot, it is likely that your display drivers remove the display device, and you must use whatever utility that came with them to re-enable it. I suspect this is how it would work if your video card has multiple inputs (e.g. VGA, DVI and S-Video) but doesn't support all of them simultaneously.

Something I forgot to mention: check the return value of EnableDisplayDevice.
Back to top
View user's profile Send private message
Superfraggle



Joined: 02 Nov 2004
Posts: 962
Location: London, UK

PostPosted: Wed Apr 16, 2008 12:21 am    Post subject: Reply with quote

Oh well, I guess it just doesnt like my display driver.

Return value is always 0. It can be turned on normally by windows. Although enumdisplaydevices cannot pick it up unless it is on. So I'm guessing the video driver does disable it for this

I can turn it off, but I just can't turn it on.

EDIT:::: Ive finally cracked it, I noticed this quote on MSDN
Quote:
When adding a display monitor to a multiple-monitor system programmatically, set DEVMODE.dmFields to DM_POSITION and specify a position (in DEVMODE.dmPosition) for the monitor you are adding that is adjacent to at least one pixel of the display area of an existing monitor. To detach the monitor, set DEVMODE.dmFields to DM_POSITION but set DEVMODE.dmPelsWidth and DEVMODE.dmPelsHeight to zero. For more information, see Multiple Display Monitors.


Then I realised your code had the comment

Quote:
; Enable by setting position = {0,0}


So I added some extra info to the structure positioning it to the right of my monitor.

Specifically the lines,

Code:
VarSetCapacity(Point,8,0)
Numput(A_ScreenWidth + 1,Point)
Numput(&point,devmode,44)


just after the line with the above comment.

This is now working spot on for me and I can enable/disable my second monitor on the fly.

The full very slightly adjust code, is as follows.

Code:
; 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
}


I'm sure it could be enhanced more to allow better positioning.
_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle
Back to top
View user's profile Send private message MSN Messenger
jamn
Guest





PostPosted: Wed Apr 16, 2008 8:27 pm    Post subject: Reply with quote

With the last changes from superfraggle this now works perfectly on my system. Thank you!
Back to top
ProsperousOne



Joined: 19 Sep 2005
Posts: 100

PostPosted: Fri Apr 18, 2008 6:09 pm    Post subject: Reply with quote

OK, I've got it working. Unfortunatly, it's extending my destkop. I'm looking to just clone it (aka unchecking "Extend my Windows Desktop onto this monitor." in the Display Properties Settings dialog).

Any suggestions?
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Sat Apr 19, 2008 2:03 am    Post subject: Reply with quote

So "Extend the desktop onto this monitor" toggles clone mode? On my computer, unchecking it just disables the monitor...

If you have an nVidia card, you could use the NvCpl API. (Edit: On Vista, I get "Error: API not supported on this version of Windows.")
Back to top
View user's profile Send private message
Clash



Joined: 27 Jun 2006
Posts: 182

PostPosted: Sat Apr 19, 2008 10:24 am    Post subject: Reply with quote

Lexikos's script worked for me, but my primary monitor flashed funny shaped black boxes on the screen (not sure if that could damage it) and it switches the secondary screen to be on the opposite side.
_________________
Back to top
View user's profile Send private message
ProsperousOne



Joined: 19 Sep 2005
Posts: 100

PostPosted: Mon Apr 21, 2008 2:36 pm    Post subject: Reply with quote

Lexikos wrote:
So "Extend the desktop onto this monitor" toggles clone mode? On my computer, unchecking it just disables the monitor...

If you have an nVidia card, you could use the NvCpl API. (Edit: On Vista, I get "Error: API not supported on this version of Windows.")


Correct. Running the script has the effect of toggling th e"Extend Destop on to this monitor" checkbox. I'll play iwth the nVidia card and see if I can get that to work. Unfortunatly, I'm running VISTA, so I'll see if there's updated Vista drivers....
Back to top
View user's profile Send private message
nod5
Guest





PostPosted: Fri Jun 06, 2008 8:48 am    Post subject: Reply with quote

I have made a script based on superfraggles function and with some custom icons. Available here:
http://nod5.dcmembers.com/tv_out.html

Now I'm looking for some way to place the second display to the left of the display (not to the right which is the default position).

I think this is the crucial line of code from superfraggle:
Code:
Numput(A_ScreenWidth + 1,Point)


I've tried changing the first value in the paranthesis to a negative (like -1360) but then it doesn't work. Can anyone see a solution for this?
Back to top
TheQwerty



Joined: 12 Sep 2007
Posts: 1

PostPosted: Tue Jun 10, 2008 7:25 pm    Post subject: Reply with quote

nod5 wrote:
Now I'm looking for some way to place the second display to the left of the display (not to the right which is the default position).

I think this is the crucial line of code from superfraggle:
Code:
Numput(A_ScreenWidth + 1,Point)


I've tried changing the first value in the paranthesis to a negative (like -1360) but then it doesn't work. Can anyone see a solution for this?
Okay, this was driving me nuts today, but I think I got it figured out.

The following was never actually using the value put into Point, instead it was using the pointer directly to position the monitor:
Code:
VarSetCapacity(Point,8,0)
Numput(A_ScreenWidth + 1,Point)
Numput(&point,devmode,44)


What is really wanted is to put the X and Y values directly into devmode, so replace those 3 lines with:
Code:
NumPut(X, devmode, 44, "Int")
NumPut(Y, devmode, 48, "Int")
Now either adjust the function call to accept X and Y parameters, or replace them with the new X-Y coordinates of the monitor. This seems to be working for me, so hopefully it's a solution for you.

EDIT: Just to note, it seems to disable the monitor (without error) if you set it to a position already occupied, or at least 0,0, so perhaps it's only disabled if it conflicts with the primary monitor.
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
Goto page Previous  1, 2, 3
Page 3 of 3

 
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