AutoHotkey Community

It is currently May 25th, 2012, 4:49 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 71 posts ]  Go to page 1, 2, 3, 4, 5  Next
Author Message
 Post subject: Secondary Monitor
PostPosted: August 6th, 2007, 1:19 am 
Is it possible to enable/disable a secondary monitor using a hotkey?
If so can someone please explain.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: August 6th, 2007, 6:08 am 
Offline

Joined: November 2nd, 2004, 2:43 pm
Posts: 1019
Location: London, UK
This can be done by one of two methods I believe

1st would be by automating the usual process of enabling the second monitor, script recorder could make a basic one.

2nd would be several dll calls I believe

EnumDisplayDevices
and
ChangeDisplaySettingsEx

I am still learning the dllcalls side so the second is beyond me :(

_________________
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 8th, 2007, 9:41 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
I figured out how to enable a monitor by using ChangeDisplaySettingsEx, but not how to disable it. Fortunately there is a solution using RegWrite. The following script should disable or enable the secondary monitor when run. (To be more accurate, it disables or enables the "Extend the desktop onto this monitor" setting.)
Code:
;
; AutoHotkey Version: 1.0.47.02
; Language:       English
; Platform:       Win9x/NT ??
; Author:         Lexikos
;
; Script Function:
;   Enable or disable a secondary monitor. ("Extend the desktop onto this monitor")
;

#NoEnv
#NoTrayIcon

GetDisplayDeviceList("Display", false)

if Display2
{
    RegRead, Attached, HKEY_CURRENT_CONFIG
        , System\CurrentControlSet\Control\VIDEO\%Display2ID%\0001
        , Attach.ToDesktop
   
    ; This part is in case I get the Display..ID wrong,
    ; so I don't write junk into the registry.
    if (ErrorLevel) {
        MsgBox, Error getting display attached status.
        return
    }
   
    Attached := ! Attached
   
    RegWrite, REG_DWORD, HKEY_CURRENT_CONFIG
        , System\CurrentControlSet\Control\VIDEO\%Display2ID%\0001
        , Attach.ToDesktop
        , %Attached%
   
    ; Apply display settings from registry.
    DllCall("ChangeDisplaySettings", "UInt", 0, "UInt", 0)
}

ExitApp


; Creates a global array using ArrayName as the base.
;   %ArrayName%             Number of display devices.
;   %ArrayName%Primary      The index of the primary display device.
;   %ArrayName%%N%          Name of display device (used by ChangeDisplaySettingsEx.)
;   %ArrayName%%N%ID        {GUID} value required for some registry operations.
; Only set if DesktopOnly=false:
;   %ArrayName%%N%Attached  =1 if "Extend the desktop onto this monitor" is enabled.
GetDisplayDeviceList(ArrayName, DesktopOnly=true)
{
    local DisplayDevice, Count, DeviceName, StateFlags, DeviceKey
   
    ; DISPLAY_DEVICE DisplayDevice
    VarSetCapacity(DisplayDevice, 424)
    ; lpDisplayDevice.cb := sizeof(DISPLAY_DEVICE)
    NumPut(424, DisplayDevice, 0)
   
    if %ArrayName%Primary
        %ArrayName%Primary =
   
    VarSetCapacity(DeviceName,  32, 0)
    VarSetCapacity(DeviceKey , 128, 0)
   
    Loop
    {
        if ! DllCall("EnumDisplayDevices"
            , "UInt", 0         ; lpDevice (NULL: use iDevNum to identify devices)
            , "UInt", A_Index-1 ; iDevNum
            , "UInt", &DisplayDevice ; lpDisplayDevice
            , "UInt", 0)        ; dwFlags
            break
       
        StateFlags := NumGet(DisplayDevice, 164)
       
        ; Useful DISPLAY_DEVICE.StateFlags:
        ;   #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
        ;   #define DISPLAY_DEVICE_PRIMARY_DEVICE      0x00000004
        ;   #define DISPLAY_DEVICE_MIRRORING_DRIVER    0x00000008

        if (StateFlags & 8) ; always exclude pseudo-devices
            continue
        if (DesktopOnly && !(StateFlags & 1))
            continue
       
        Count += 1

        DllCall("lstrcpynA", "Str", DeviceName  , "UInt", &DisplayDevice+4  , "int", 32)
        DllCall("lstrcpynA", "Str", DeviceKey   , "UInt", &DisplayDevice+296, "int", 128)
       
        %ArrayName%%Count% := DeviceName
       
        ; DeviceKey is something like:
        ;   \Registry\Machine\System\CurrentControlSet\Control\Video\{device-specific-value}\0000
        ; We want the:
        ;   {device-specific-value}
        SplitPath, DeviceKey,, DeviceKey ; "up one level"
        SplitPath, DeviceKey, %ArrayName%%Count%ID
       
        if (StateFlags & 4)
            %ArrayName%Primary := Count
       
        if (!DesktopOnly)
            %ArrayName%%Count%Attached := (StateFlags&1)
        ; else: function only returns attached monitors, no need for %..%Attached.
    }
   
    %ArrayName% := Count
}

If the GetDisplayDeviceList() function seems overly complex, that's probably because it's not specifically written for this script. For the RegWrite solution, it's only required because different display devices need a different path in the registry.

Note the "\0001" part of the registry key is the four digit zero-based index of the monitor.

Also, this won't necessarily work the same on all multi-monitor setups. It should at least work on any setups where one graphics card is powering multiple monitors.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2007, 3:12 pm 
i think this is what im looking for. could you show how to bind a hotkey to this function? thanks

also is it possible to switch off primary and switch to secondary instead of extend?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 1st, 2007, 4:00 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
The registry-editing approach doesn't work for the primary monitor. Since my last post, I've figured out how to use ChangeDisplaySettingsEx to enable or disable a display device. Unfortunately it doesn't preserve the position(s) of the display(s).

For instance, if I disable and re-enable my secondary display, it will move from the right side of my primary to the left side. (If it's already on the left side, it should stay where it is.) Disabling and re-enabling my primary display seems to work without problems, though.

The hotkeys I use are:
Code:
#+NumpadMult::EnableDisplayDevice("\\.\DISPLAY1", -1)  ; toggle primary
#+NumpadDiv::EnableDisplayDevice("\\.\DISPLAY2", -1)  ; toggle secondary
Since the device names might be different, this might not work for you. If that is the case, let me know and I'll post a (better) function for getting the right device name (or you could use GetDisplayDeviceList() from my previous post.)

EnableDisplayDevice.ahk:
Code:
; Enables, disables or toggles a display device.
;
; DeviceName:   The name of the device, e.g. \\.\DISPLAY1
; Action:       The action to take.
;                    0   Disable
;                    1   Enable
;                   -1   Toggle (may not be reliable if NoReset=true)
; 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
;
; Examples:
;   ; disable display 2
;     EnableDisplayDevice("\\.\DISPLAY2", 0)
;     Sleep, 10000
;
;   ; simultaneously enable display 2 and disable display 1
;     EnableDisplayDevice("\\.\DISPLAY2", 1, true)
;     EnableDisplayDevice("\\.\DISPLAY1", 0)
;     Sleep, 10000
;
;   ; ensure both are enabled
;     EnableDisplayDevice("\\.\DISPLAY2", 1, true)
;     EnableDisplayDevice("\\.\DISPLAY1")
;
; Note: DeviceNames may vary. Rather than hard-coding the device name,
;       EnumDisplayDevices() should be used to enumerate the devices.
;
EnableDisplayDevice(DeviceName, Action=1, NoReset=false)
{
    if (Action = -1)
    {   ; Determine if the display should be enabled or disabled.
        Loop {
            if ! EnumDisplayDevices(A_Index, this_name, this_state)
                break
            if (this_name = DeviceName) {
                Action := !(this_state & 1) ; DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
                break
            }
        }
        ; If Action is still -1, an invalid DeviceName was specified.
        ; The script will attempt to enable the display device, but
        ; ChangeDisplaySettingsEx() will most likely return error -5.
    }

    VarSetCapacity(devmode, 156, 0)
    NumPut(156, devmode, 36, "UShort")

    ; Set DEVMODE.dmFields to indicate which fields are valid.
    if (Action) ; Enable
        NumPut(0x000020, devmode, 40)   ; position={0,0}
    else        ; Disable
        NumPut(0x180020, devmode, 40)   ; width=0, height=0, position={0,0}

    ; Since CDS_NORESET is specified here, if NoReset=true, the user must
    ; manually call ChangeDisplaySettings(NULL,1) or restart the computer.
    err := DllCall("ChangeDisplaySettingsEx", "str", DeviceName
        , "uint", &devmode, "uint", 0, "uint", 0x10000001, "uint", 0)
   
    ; ChangeDisplaySettings() is called here for two reasons:
    ;   - A restart is otherwise required to enable a secondary display device.
    ;       See: http://support.microsoft.com/kb/308216
    ;   - Disabling display devices with just ChangeDisplaySettingsEx()
    ;     tends to leave them turned on.
    if (!err && !NoReset)
        err := DllCall("ChangeDisplaySettings", "uint", 0, "uint", 1)
   
    return err
}

I have it saved as EnableDisplayDevice.ahk in my user library, so that no #include is necessary.


To bind my previous script to a hotkey (to toggle the secondary display), simply put the hotkey (e.g. #+NumpadMult::) before
Code:
GetDisplayDeviceList("Display", false)
and return instead of ExitApp.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 2nd, 2007, 6:07 pm 
Quote:
#+NumpadMult::EnableDisplayDevice("\\.\DISPLAY1", -1) ; toggle primary
#+NumpadDiv::EnableDisplayDevice("\\.\DISPLAY2", -1) ; toggle secondary


thank you

Quote:
Unfortunately it doesn't preserve the position(s) of the display(s).

np in my case. i got a plasma on dvi#2 for movies so i dont want the primary display to be on at all after the switch.

My matrox driver only let me Extend even though they call it "independent mode". With my old quadro card and nvidia driver i could simple choose to switch to the other display ie change output from DVI1 to DVI2... such a simple task must be possible?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 1:24 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
novis wrote:
My matrox driver only let me Extend even though they call it "independent mode". With my old quadro card and nvidia driver i could simple choose to switch to the other display ie change output from DVI1 to DVI2... such a simple task must be possible?
You mean have only one display on at a time? There's an expample in the comments of my script how to simultaneously enable one display and disable the other (i.e. swap.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 5:24 am 
yes thats what i need! its a nice script ..i just need it to work.

i get a error enumerating the device. how do i hardcode it for my display? or do u know what might be the problem?

Quote:
--> if ! EnumDisplayDevices(A_Index, this_name, this_state)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 8:03 am 
Offline
User avatar

Joined: August 30th, 2005, 8:43 pm
Posts: 8657
Location: Salem, MA
what is the error? function not found or some syntax issue? what version of ahk are you using?

_________________
Image
(Common Answers) - New Tutorials Forum - Humongous FAQ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 10:48 am 
Offline

Joined: April 22nd, 2007, 6:33 pm
Posts: 1832
i recommend just using wizmo:

http://www.grc.com/wizmo/wizmo.htm

and putting it in the same folder as your ahk, and then just running it with the argument to turn off your 2nd monitor.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 1:28 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
novis wrote:
i get a error enumerating the device. how do i hardcode it for my display? or do u know what might be the problem?
You need EnumDisplayDevices, which I hadn't posted.
Code:
; EnumDisplayDevices(Index [, ByRef Name, ByRef StateFlags ] )
;
; Index:        One-based index of device to get info for.
; DeviceName:   [out] The name of the device.
; StateFlags:   [out] Any reasonable combination of the following flags:
;   0x00000001      DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
;   0x00000004      DISPLAY_DEVICE_PRIMARY_DEVICE
;   0x00000008      DISPLAY_DEVICE_MIRRORING_DRIVER
; DeviceKey:    [out] Path to the device's registry key relative to HKEY_LOCAL_MACHINE.
;
; Returns true if the display device exists, otherwise false.
;
/* Example 1 (requires EnableDisplayDevice()):
    SecondaryDevice =
    count = 0
    Loop {
        if ! EnumDisplayDevices(A_Index, DeviceName, StateFlags)
            break
        if !(StateFlags & 8) ; not a pseudo-device
            if (++count = 2) ; second device
                break
    }
    if DeviceName
        EnableDisplayDevice(DeviceName, -1) ; toggle
*/
/* Example 2:
    Loop {
        if ! EnumDisplayDevices(A_Index, DeviceName, StateFlags)
            break
        if (StateFlags & 4)
            text .= DeviceName " is the primary display device.`n"
        else if (StateFlags & 1)
            text .= "The desktop extends onto " DeviceName ".`n"
        if (StateFlags & 8)
            text .= DeviceName " is a pseudo-device.`n"
    }
    MsgBox %text%
*/
EnumDisplayDevices(Index, ByRef DeviceName, ByRef StateFlags="", ByRef DeviceKey="")
{
    ; DISPLAY_DEVICE DisplayDevice
    VarSetCapacity(DisplayDevice, 424)
    ; lpDisplayDevice.cb := sizeof(DISPLAY_DEVICE)
    NumPut(424, DisplayDevice, 0)
   
    VarSetCapacity(DeviceName, 32, 0)
    VarSetCapacity(DeviceKey, 128, 0)
    ; For consistency, clear StateFlags in case of failure.
    StateFlags = 0
   
    if ! DllCall("EnumDisplayDevices"
        , "UInt", 0
        , "UInt", Index-1
        , "UInt", &DisplayDevice
        , "UInt", 0)
        return false
   
    StateFlags := NumGet(DisplayDevice, 164)
    DllCall("lstrcpynA", "Str", DeviceName, "UInt", &DisplayDevice+4,   "int", 32)
    DllCall("lstrcpynA", "Str", DeviceKey,  "UInt", &DisplayDevice+296, "int", 128)
    if (SubStr(DeviceKey,1,18)="\Registry\Machine")
        DeviceKey := SubStr(DeviceKey,19)
    return true
}
Example 2 (in the comments) can be used to list all of the display devices.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 3:31 pm 
just got back from work so i havent tested anything yet but thanks everyone helping me out. Nice community!


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2007, 5:30 pm 
this might be too much for my fragile little mind ...how should i use example2 in the EnumDisplayDevices-code, replace it in the 2nd script?

Is this a pseudo/place-holding-name that i should replace: \\.\DISPLAY1 ?
should i un-comment anything before i can run it?

-----
Version 1.0.47.04 of AHK
Winxp sp2
Matrox p650 pci-e


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 4th, 2007, 4:25 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
No, \\.\DISPLAY1 is an actual display device name. EnumDisplayDevices Example 2 outputs this on my system:
Quote:
\\.\DISPLAY1 is the primary display device.
The desktop extends onto \\.\DISPLAY2.
\\.\DISPLAYV1 is a pseudo-device.
\\.\DISPLAYV2 is a pseudo-device.
\\.\DISPLAY1 is my primary display, while \\.\DISPLAY2 is my secondary. \\.\DISPLAYV1 and \\.\DISPLAYV2 are "mirroring drivers," i.e. they don't exist. It may be possible for the desktop to extend onto a pseudo-device, in which case the script would output something like:
Quote:
The desktop extends onto \\.\DISPLAYV1.
\\.\DISPLAYV1 is a pseudo-device.
The exact code I use for my hotkeys is just what I wrote in my previous post:
Code:
#+NumpadMult::EnableDisplayDevice("\\.\DISPLAY1", -1)
#+NumpadDiv::EnableDisplayDevice("\\.\DISPLAY2", -1)
\\.\DISPLAY1 is a display device name, and -1 means "toggle." 0 is disable, and 1 is enable.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 4th, 2007, 4:58 am 
damn. then it doesnt work for me :/

just to be sure. i got this in a new .ahk and i press: LWin+*, LWin+\ (on Numpad)

Code:

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.


#+NumpadMult::EnableDisplayDevice("\\.\DISPLAY1", -1)
#+NumpadDiv::EnableDisplayDevice("\\.\DISPLAY2", -1)


; EnumDisplayDevices(Index [, ByRef Name, ByRef StateFlags ] )
;
; Index:        One-based index of device to get info for.
; DeviceName:   [out] The name of the device.
; StateFlags:   [out] Any reasonable combination of the following flags:
;   0x00000001      DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
;   0x00000004      DISPLAY_DEVICE_PRIMARY_DEVICE
;   0x00000008      DISPLAY_DEVICE_MIRRORING_DRIVER
; DeviceKey:    [out] Path to the device's registry key relative to HKEY_LOCAL_MACHINE.
;
; Returns true if the display device exists, otherwise false.
;
/* Example 1 (requires EnableDisplayDevice()):
    SecondaryDevice =
    count = 0
    Loop {
        if ! EnumDisplayDevices(A_Index, DeviceName, StateFlags)
            break
        if !(StateFlags & 8) ; not a pseudo-device
            if (++count = 2) ; second device
                break
    }
    if DeviceName
        EnableDisplayDevice(DeviceName, -1) ; toggle
*/
/* Example 2:
    Loop {
        if ! EnumDisplayDevices(A_Index, DeviceName, StateFlags)
            break
        if (StateFlags & 4)
            text .= DeviceName " is the primary display device.`n"
        else if (StateFlags & 1)
            text .= "The desktop extends onto " DeviceName ".`n"
        if (StateFlags & 8)
            text .= DeviceName " is a pseudo-device.`n"
    }
    MsgBox %text%
*/
EnumDisplayDevices(Index, ByRef DeviceName, ByRef StateFlags="", ByRef DeviceKey="")
{
    ; DISPLAY_DEVICE DisplayDevice
    VarSetCapacity(DisplayDevice, 424)
    ; lpDisplayDevice.cb := sizeof(DISPLAY_DEVICE)
    NumPut(424, DisplayDevice, 0)
   
    VarSetCapacity(DeviceName, 32, 0)
    VarSetCapacity(DeviceKey, 128, 0)
    ; For consistency, clear StateFlags in case of failure.
    StateFlags = 0
   
    if ! DllCall("EnumDisplayDevices"
        , "UInt", 0
        , "UInt", Index-1
        , "UInt", &DisplayDevice
        , "UInt", 0)
        return false
   
    StateFlags := NumGet(DisplayDevice, 164)
    DllCall("lstrcpynA", "Str", DeviceName, "UInt", &DisplayDevice+4,   "int", 32)
    DllCall("lstrcpynA", "Str", DeviceKey,  "UInt", &DisplayDevice+296, "int", 128)
    if (SubStr(DeviceKey,1,18)="\Registry\Machine\")
        DeviceKey := SubStr(DeviceKey,19)
    return true
}

; Enables, disables or toggles a display device.
;
; DeviceName:   The name of the device, e.g. \\.\DISPLAY1
; Action:       The action to take.
;                    0   Disable
;                    1   Enable
;                   -1   Toggle (may not be reliable if NoReset=true)
; 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
;
; Examples:
;   ; disable display 2
;     EnableDisplayDevice("\\.\DISPLAY2", 0)
;     Sleep, 10000
;
;   ; simultaneously enable display 2 and disable display 1
;     EnableDisplayDevice("\\.\DISPLAY2", 1, true)
;     EnableDisplayDevice("\\.\DISPLAY1", 0)
;     Sleep, 10000
;
;   ; ensure both are enabled
;     EnableDisplayDevice("\\.\DISPLAY2", 1, true)
;     EnableDisplayDevice("\\.\DISPLAY1")
;
; Note: DeviceNames may vary. Rather than hard-coding the device name,
;       EnumDisplayDevices() should be used to enumerate the devices.
;
EnableDisplayDevice(DeviceName, Action=1, NoReset=false)
{
    if (Action = -1)
    {   ; Determine if the display should be enabled or disabled.
        Loop {
            if ! EnumDisplayDevices(A_Index, this_name, this_state)
                break
            if (this_name = DeviceName) {
                Action := !(this_state & 1) ; DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
                break
            }
        }
        ; If Action is still -1, an invalid DeviceName was specified.
        ; The script will attempt to enable the display device, but
        ; ChangeDisplaySettingsEx() will most likely return error -5.
    }

    VarSetCapacity(devmode, 156, 0)
    NumPut(156, devmode, 36, "UShort")

    ; Set DEVMODE.dmFields to indicate which fields are valid.
    if (Action) ; Enable
        NumPut(0x000020, devmode, 40)   ; position={0,0}
    else        ; Disable
        NumPut(0x180020, devmode, 40)   ; width=0, height=0, position={0,0}

    ; Since CDS_NORESET is specified here, if NoReset=true, the user must
    ; manually call ChangeDisplaySettings(NULL,1) or restart the computer.
    err := DllCall("ChangeDisplaySettingsEx", "str", DeviceName
        , "uint", &devmode, "uint", 0, "uint", 0x10000001, "uint", 0)
   
    ; ChangeDisplaySettings() is called here for two reasons:
    ;   - A restart is otherwise required to enable a secondary display device.
    ;       See: http://support.microsoft.com/kb/308216
    ;   - Disabling display devices with just ChangeDisplaySettingsEx()
    ;     tends to leave them turned on.
    if (!err && !NoReset)
        err := DllCall("ChangeDisplaySettings", "uint", 0, "uint", 1)
   
    return err
}



Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 71 posts ]  Go to page 1, 2, 3, 4, 5  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], LazyMan, tank, vinniel, Yahoo [Bot] and 15 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