Liberty BASIC Community Forum
« Opening Program In A 2nd Monitor »

Welcome Guest. Please Login or Register.
Sep 20th, 2017, 09:52am


Rules|Home|Help|Search|Recent Posts|Notification


« Previous Topic | Next Topic »
Pages: 1 2  Notify Send Topic Print
 hotthread  Author  Topic: Opening Program In A 2nd Monitor  (Read 483 times)
Tasp2
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 142
xx Opening Program In A 2nd Monitor
« Thread started on: Sep 21st, 2006, 4:32pm »

I have 2 monitors connected to a graphics card with two outputs, windows sees these as 2 seperate monitors,

My question is, is it possible to force a program to start in the 2nd monitor? The program is being made in LB, it's not another program that I'm starting.

I've posted this in the API board as I'm assuming it will need one. Sorry if this is the wrong place.
User IP Logged

Stefan Pendl
Global Moderator
ImageImageImageImageImage


member is offline

Avatar

Computers are like babies, you must teach them what you like them to do ...


Homepage PM

Gender: Male
Posts: 5295
xx Re: Opening Program In A 2nd Monitor
« Reply #1 on: Sep 22nd, 2006, 12:03am »

What is the configration you use ???
  • clone
  • horizontally or vertically
  • dualview

You should be able to use EnumMonitors to check if a second monitor is available.
Use GetDC with a handle of zero to get the screens DC.
Use GetDeviceCaps to get the phyical offsets of the second monitor.
Use ReleaseDC to free the DC of the screen.
Use MoveWindow or SetWindowPos to place the window on the second monitor.
Code:
    calldll #user32, "GetDC",_
        0   as ulong,_   ' entire screen
        hDC as ulong

    nIndex = ' the information you like to get

    calldll #gdi32, "GetDeviceCaps",_
        hDC    as ulong,_
        nIndex as ulong,_
        result as ulong

    calldll #user32, "ReleaseDC",_
        0      as ulong,_   ' entire screen
        hDC    as ulong,_
        result as ulong     ' 1 = success
 
User IP Logged

Stefan

Make sure to read and follow the Forum Guidelines

Liberty BASIC Pro 4.04, Windows 10 Professional x64, Intel Core i7-4710MQ 2.5GHz, 16GB RAM
Brent Thorn
Team Liberty BASIC


member is online

Avatar




Homepage PM


Posts: 562
xx Re: Opening Program In A 2nd Monitor
« Reply #2 on: Sep 22nd, 2006, 12:47am »

I posted the following code to the LB Yahoo group more than a year ago. I stated that I could not adequately test it because I have but one monitor attached. I never got a reply from the topic's originator, so I still don't know if it works. Code:
' Opens a window on every monitor.
' By Brent D. Thorn, 4/2005 
EDIT: Malfunctioning code removed. See Stefan's post below for a working demo.
« Last Edit: Sep 26th, 2006, 1:38pm by Brent Thorn » User IP Logged

—Brent
Bay Six Software & Forums
Home of the WMLiberty DLL and ViviFire language
Nov 2015: Working on VF AST & type checker
Stefan Pendl
Global Moderator
ImageImageImageImageImage


member is offline

Avatar

Computers are like babies, you must teach them what you like them to do ...


Homepage PM

Gender: Male
Posts: 5295
xx Re: Opening Program In A 2nd Monitor
« Reply #3 on: Sep 22nd, 2006, 01:01am »

Brent,
since I do have two machines with two monitors today (presentation), I will check if it works.
User IP Logged

Stefan

Make sure to read and follow the Forum Guidelines

Liberty BASIC Pro 4.04, Windows 10 Professional x64, Intel Core i7-4710MQ 2.5GHz, 16GB RAM
Tasp2
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 142
xx Re: Opening Program In A 2nd Monitor
« Reply #4 on: Sep 22nd, 2006, 01:04am »

I'm using the 2nd monitor as a horizontal expansion (so I can drag from mon 1 to 2) I assume this would be called dualview, windows just says "extend my desktop on this monitor",

Thanks guys, I will go and try these out right now.
User IP Logged

Tasp2
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 142
xx Re: Opening Program In A 2nd Monitor
« Reply #5 on: Sep 22nd, 2006, 01:48am »

Brent your code does work to a degree, it opens 2 windows, 1 in the left monitor at full size, the 2nd opens in the 1st monitor but it the size of the entire desktop (across both screens) but it has it be dragged across on to the 2nd monitor at which point it will cover both monitors, does that make sense?

I'm sure I can make this work. Many thanks.
User IP Logged

Tasp2
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 142
xx Re: Opening Program In A 2nd Monitor
« Reply #6 on: Sep 22nd, 2006, 04:42am »

I've run into a hugh problem,

Using UpperLeftY to equal anything over the screen resolution (1024) just pushes it to the far right of the first monitor rather than pushing it onto the 2nd monitor,

For instance,
Code:
UpperLeftY 1200]
Open "GUI" FOR Window As #main
WAIT
 

should display half way onto the 2nd monitor but doesn't.

Any ideas to force this?
User IP Logged

Stefan Pendl
Global Moderator
ImageImageImageImageImage


member is offline

Avatar

Computers are like babies, you must teach them what you like them to do ...


Homepage PM

Gender: Male
Posts: 5295
thumbup Re: Opening Program In A 2nd Monitor
« Reply #7 on: Sep 22nd, 2006, 12:56pm »

Here is Brents demo enhanced to make it work.

Changes:
  • corrected calculation of window width and height
  • used SetWindowPos API to locate window
    native LB seems to support only coordinates on the primary monitor


You must use DualView configuration, expanding the desktop horizontally or vertically won't work.

Code:
    ' Opens a window on every monitor.
    ' By Brent D. Thorn, 4/2005

    Global WindowCount 'Window management

    Struct MonitorInfo, _
        cbSize           As ULong, _
        rcMonitor.left   As Long, _
        rcMonitor.top    As Long, _
        rcMonitor.right  As Long, _
        rcMonitor.bottom As Long, _
        rcWork.left      As Long, _
        rcWork.top       As Long, _
        rcWork.right     As Long, _
        rcWork.bottom    As Long, _
        dwFlags          As ULong

    ' Get the address of our callback func.
    Callback lpfnEnumProc, _
        MonitorEnumProc( ULong, ULong, ULong, ULong ), Long

    ' Start enumerating monitors and opening windows.
    CallDLL #user32, "EnumDisplayMonitors", _
        _NULL        As ULong, _
        _NULL        As ULong, _
        lpfnEnumProc As ULong, _
        0            As ULong, _
        res          As Long

    Wait

Function MonitorEnumProc( hMonitor, hdcMonitor, lprcMonitor, dwData )
    ' Required before calling GetMonitorInfo.
    MonitorInfo.cbSize.struct = Len(MonitorInfo.struct)

    ' Get monitor info.
    CallDLL #user32, "GetMonitorInfoA", _
        hMonitor    As ULong, _
        MonitorInfo As Struct, _
        res         As Long

    ' Check MONITORINFOF_PRIMARY bit.
    bPrimary = ((MonitorInfo.dwFlags.struct And 1) <> 0)

    If bPrimary Then
        Title$ = "Primary Monitor"
    Else
        Title$ = "Secondary Monitor"
    End If

    ' Print monitor coords.
    Print Title$
    Print " Left: "; Using("####", MonitorInfo.rcMonitor.left.struct);
    Print " Top: "; Using("####", MonitorInfo.rcMonitor.top.struct);
    Print " Right: "; Using("####", MonitorInfo.rcMonitor.right.struct);
    Print " Bottom: "; Using("####", MonitorInfo.rcMonitor.bottom.struct)

    ' Place desktop coords into position vars
    ' taking LB peculiarities into account.
    UpperLeftX = Max(MonitorInfo.rcWork.left.struct, 1)
    UpperLeftY = Max(MonitorInfo.rcWork.top.struct, 1)
    WindowWidth = MonitorInfo.rcWork.right.struct - MonitorInfo.rcWork.left.struct
    WindowHeight = MonitorInfo.rcWork.bottom.struct - MonitorInfo.rcWork.top.struct

    ' Print desktop coords.
    Print "Work Area"
    Print " Left: "; Using("####", UpperLeftX);
    Print " Top: "; Using("####", UpperLeftY);
    Print " Right: "; Using("####", WindowWidth);
    Print " Bottom: "; Using("####", WindowHeight)
    Print

    ' Open a window.
    Open Title$ For Window As #w
    #w "TrapClose CloseMe"

    dummy = SetWindowPos(hWnd(#w), 0, UpperLeftX, UpperLeftY, 0, 0, _SWP_NOZORDER or _SWP_NOSIZE)

    ' Increment window count.
    WindowCount = WindowCount + 1

    ' Give each window a unique handle
    ' based on its window handle (HWND).
    MapHandle #w, Str$(HWnd(#w))

    ' We want more monitors.
    MonitorEnumProc = 1
End Function

Sub CloseMe Me$
    Close #Me$

    WindowCount = WindowCount - 1
    If WindowCount = 0 Then End
End Sub

function SetWindowPos(hWnd, hWndInsertAfter, PosX, PosY, Width, Height, uFlags)
    calldll #user32, "SetWindowPos", _
        hWnd            as ulong,_
        hWndInsertAfter as ulong,_
        PosX            as long,_
        PosY            as long,_
        Width           as long,_
        Height          as long,_
        uFlags          as ulong,_
        SetWindowPos    as boolean
end function 


EDIT: reverted a change to the handle mapping, which would indeed result in problems, when using more than two monitors
« Last Edit: Sep 23rd, 2006, 12:58pm by Stefan Pendl » User IP Logged

Stefan

Make sure to read and follow the Forum Guidelines

Liberty BASIC Pro 4.04, Windows 10 Professional x64, Intel Core i7-4710MQ 2.5GHz, 16GB RAM
Tasp2
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 142
xx Re: Opening Program In A 2nd Monitor
« Reply #8 on: Sep 22nd, 2006, 1:40pm »

Stefan, I cannot thank you enough for that code, quite honestly I have no idea how you did that, but by jove I intend to (attemp to) learn!

Many thanks Stefan for getting this code to work and thanks to Brent for creating it in the first place. grin
User IP Logged

Brent Thorn
Team Liberty BASIC


member is online

Avatar




Homepage PM


Posts: 562
xx Re: Opening Program In A 2nd Monitor
« Reply #9 on: Sep 22nd, 2006, 2:55pm »

Stefan, thanks for fixing my bugs!

However, I must disagree with one change. You changed Code:
MapHandle #w, Str$(HWnd(#w)) 
to Code:
MapHandle #w, word$(Title$, 1) 
I believe this would cause a fatal error if this is run on a system with three or more monitors.
User IP Logged

—Brent
Bay Six Software & Forums
Home of the WMLiberty DLL and ViviFire language
Nov 2015: Working on VF AST & type checker
Stefan Pendl
Global Moderator
ImageImageImageImageImage


member is offline

Avatar

Computers are like babies, you must teach them what you like them to do ...


Homepage PM

Gender: Male
Posts: 5295
wink Re: Opening Program In A 2nd Monitor
« Reply #10 on: Sep 23rd, 2006, 1:02pm »

on Sep 22nd, 2006, 2:55pm, Brent Thorn wrote:
However, I must disagree with one change. You changed Code:
MapHandle #w, Str$(HWnd(#w)) 
to Code:
MapHandle #w, word$(Title$, 1) 
I believe this would cause a fatal error if this is run on a system with three or more monitors.

Brent,
after a second look I totally agree with you, thanks for pointing that out.

And a very special thanks for giving me the opportunity to test your demo and fix some very minor problems.
User IP Logged

Stefan

Make sure to read and follow the Forum Guidelines

Liberty BASIC Pro 4.04, Windows 10 Professional x64, Intel Core i7-4710MQ 2.5GHz, 16GB RAM
Tasp2
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 142
xx Re: Opening Program In A 2nd Monitor
« Reply #11 on: Sep 23rd, 2006, 4:19pm »

Guys I'm truly thankful for this code but I'm stuck with even the basics,

Where do I place the control, menus, buttons etc, I have a huge code that I would like to implement this with.

I would normally have a point where the code "seperates" from pre open statement to post open statement, but in this code I can't seem to figure out where this is.

Any help would be gratefully recieved.
User IP Logged

Brent Thorn
Team Liberty BASIC


member is online

Avatar




Homepage PM


Posts: 562
xx Re: Opening Program In A 2nd Monitor
« Reply #12 on: Sep 23rd, 2006, 5:59pm »

Since you are interested only in the second monitor, I changed the callback function to continue until the second monitor is found, then sets UpperLeftX, UpperLeftY, WindowWidth, and WindowHeight. You can place the code to open your window after the call to "EnumDisplayMonitors." After you open the window, you must still call SetWindowPos. Code:
Function MonitorEnumProc( hMonitor, hdcMonitor, lprcMonitor, dwData )
    MonitorInfo.cbSize.struct = Len(MonitorInfo.struct)

    CallDLL #user32, "GetMonitorInfoA", _
        hMonitor As ULong, _
        MonitorInfo As Struct, _
        res As Long

    bPrimary = ((MonitorInfo.dwFlags.struct And 1) <> 0)


    If bPrimary Then
        ' Keep looking...
        MonitorEnumProc = 1
    Else
        ' Found secondary monitor.
        UpperLeftX = MonitorInfo.rcWork.left.struct
        UpperLeftY = MonitorInfo.rcWork.top.struct
        WindowWidth = MonitorInfo.rcWork.right.struct - _
                      MonitorInfo.rcWork.left.struct
        WindowHeight = MonitorInfo.rcWork.bottom.struct - MonitorInfo.rcWork.top.struct

        MonitorEnumProc = 0
    End If
End Function 
NOTE: This code may not work for LB 3.x.
User IP Logged

—Brent
Bay Six Software & Forums
Home of the WMLiberty DLL and ViviFire language
Nov 2015: Working on VF AST & type checker
Tasp2
Full Member
ImageImageImage


member is offline

Avatar




Homepage PM

Gender: Male
Posts: 142
xx Re: Opening Program In A 2nd Monitor
« Reply #13 on: Mar 11th, 2007, 10:03am »

I've tried everything with this code, has either of you tried to place buttons or controls within the windows that open? Because it's not working for me at all, when run thru the debugger I get a message in the debug screen that says can't pause while executing a call back.
User IP Logged

Stefan Pendl
Global Moderator
ImageImageImageImageImage


member is offline

Avatar

Computers are like babies, you must teach them what you like them to do ...


Homepage PM

Gender: Male
Posts: 5295
xx Re: Opening Program In A 2nd Monitor
« Reply #14 on: Mar 19th, 2007, 8:28pm »

Here is an example of using some handy functions to switch between monitors.
Code:
    'Multiple Monitors.bas
    'Author: Stefan Pendl
    'Date: 20.03.07

    ' Based on code provided by Brent D. Thorn, 4/2005
    ' http://libertybasic.conforums.com/index.cgi?board=api&action=display&num=1158874325

    nomainwin

    dim MonitorInfo(10,4)

    call MultiMonitorInit

    UpperLeftX = int((DisplayWidth-WindowWidth)/2)
    UpperLeftY = int((DisplayHeight-WindowHeight)/2)

    button #m.b1, "Monitor 1", SetMonitor, ul, 10, 10
    button #m.b2, "Monitor 2", SetMonitor, ul, 100, 10
    open "Multi Monitor Test" for window as #m
    #m "trapclose quit"

    if GetMonitorCount() = 1 then
        #m.b2 "!disable"
    end if
    wait

sub SetMonitor handle$
    Monitor = val(right$(handle$, 1))

    call SetWindowPos hWnd(#m), 0, _
        MonitorInfo(Monitor,1) + UpperLeftX, _
        MonitorInfo(Monitor,2) + UpperLeftY, _
        0, 0, _SWP_NOZORDER or _SWP_NOSIZE
    wait
end sub

sub quit handle$
    close #handle$
    end
end sub

sub MultiMonitorInit
    MonitorCount(0) = 0

    'get monitor configuration
    Struct MonitorInfo, _
        cbSize           As ULong, _
        rcMonitor.left   As Long, _
        rcMonitor.top    As Long, _
        rcMonitor.right  As Long, _
        rcMonitor.bottom As Long, _
        rcWork.left      As Long, _
        rcWork.top       As Long, _
        rcWork.right     As Long, _
        rcWork.bottom    As Long, _
        dwFlags          As ULong

    ' Get the address of our callback func.
    Callback lpfnEnumProc, _
        MonitorEnumProc( ULong, ULong, ULong, ULong ), boolean

    ' Start enumerating monitors and opening windows.
    CallDLL #user32, "EnumDisplayMonitors", _
        _NULL        As ULong, _
        _NULL        As ULong, _
        lpfnEnumProc As ULong, _
        dwData       As ULong, _
        resut        As boolean
end sub

Function MonitorEnumProc( hMonitor, hdcMonitor, lprcMonitor, dwData )
    'MonitorInfo(n,1) = UpperLeftX
    'MonitorInfo(n,2) = UpperLeftY
    'MonitorInfo(n,3) = DisplayWidth
    'MonitorInfo(n,4) = DisplayHeight

    ' Required before calling GetMonitorInfo.
    MonitorInfo.cbSize.struct = Len(MonitorInfo.struct)

    ' Get monitor info.
    CallDLL #user32, "GetMonitorInfoA", _
        hMonitor    As ULong, _
        MonitorInfo As Struct, _
        result      As Long

    ' Increment window count.
    MonitorCount(0) = MonitorCount(0) + 1

    ' Place desktop coords into position vars
    ' taking LB peculiarities into account.
    MonitorInfo(MonitorCount(0),1) = Max(MonitorInfo.rcWork.left.struct, 1)
    MonitorInfo(MonitorCount(0),2) = Max(MonitorInfo.rcWork.top.struct, 1)
    MonitorInfo(MonitorCount(0),3) = MonitorInfo.rcWork.right.struct - MonitorInfo.rcWork.left.struct
    MonitorInfo(MonitorCount(0),4) = MonitorInfo.rcWork.bottom.struct - MonitorInfo.rcWork.top.struct

    ' We want more monitors.
    MonitorEnumProc = 1
End Function

sub SetWindowPos hWnd, hWndInsertAfter, PosX, PosY, Width, Height, uFlags
    calldll #user32, "SetWindowPos", _
        hWnd            as ulong,_
        hWndInsertAfter as ulong,_
        PosX            as long,_
        PosY            as long,_
        Width           as long,_
        Height          as long,_
        uFlags          as ulong,_
        result          as boolean
end sub

function GetMonitorCount()
    'count physical monitors
    nIndex = 80 'SM_CMONITORS

    calldll #user32, "GetSystemMetrics",_
        nIndex          as long,_
        GetMonitorCount as long
end function 
User IP Logged

Stefan

Make sure to read and follow the Forum Guidelines

Liberty BASIC Pro 4.04, Windows 10 Professional x64, Intel Core i7-4710MQ 2.5GHz, 16GB RAM
Pages: 1 2  Notify Send Topic Print
« Previous Topic | Next Topic »

Rules|Home|Help|Search|Recent Posts|Notification

Donate $6.99 for 50,000 Ad-Free Pageviews!

| |

This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls