Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Rhinorhino on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Positioning VB6 app on secondary monitor

Status
Not open for further replies.

AndyGroom

Programmer
Joined
May 23, 2001
Messages
972
Location
GB
I don't have a dual monitor setup here (which will make testing this impossible) but our clients use dual-screen systems and they run our application on the secondary monitor, but all the messages and popups appear on the primary monitor.

The good news is that I have control over the positioning of the popup windows and message boxes (I wrote my own), but how do I centre them on the secondary monitor rather than the primary?

Current code:
Code:
  CentreLeft& = (Screen.Width - CentreMe.Width) / 2
  CentreTop& = (Screen.Height - CentreMe.Height) / 2
  CentreMe.Move CentreLeft&, CentreTop&

- Andy
___________________________________________________________________
If you think nobody cares you're alive, try missing a couple of mortgage payments
 
You could use global variables to hold the .Top and .Left of the main form, then use those variables to position your messages/popups when they're kicked off, (center your message box on the main form, maybe?).
 
Yes, that was my fall-back solution if it's not possible to obtain the XYWH of the secondary screen.

- Andy
___________________________________________________________________
If you think nobody cares you're alive, try missing a couple of mortgage payments
 
I don't have access to vb6 at the moment, but....

Could you set the "startup position" of the form to be center owner, and then NOT move the position at all? Just let windows handle it. I'm not 100% sure this will work, but it's worth a try.



-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
While I can't test on a second monitor at the moment I think George's suggestion might work. It may also depend on how you have dual monitors setup as I've seen some strange behaviours in previous places with different video cards etc. running the same application (to do with how they handled pop ups, and positioning from start and the like).

HarleyQuinn
---------------------------------
Carter, hand me my thinking grenades!

You can hang outside in the sun all day tossing a ball around, or you can sit at your computer and do something that matters. - Eric Cartman

Get the most out of Tek-Tips, read FAQ222-2244: How to get the best answers before posting.

 
>I don't have a dual monitor setup - I think you'll need one!

This may not be exactly what you want but it should help.

'adapted, and now not very similar, from code in
Option Explicit

Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

'Constants for the return value when finding a monitor
Private Enum dwFlags
MONITOR_DEFAULTTONULL = &H0 'If the monitor is not found, return 0
MONITOR_DEFAULTTOPRIMARY& = &H1 'If the monitor is not found, return the primary monitor
MONITOR_DEFAULTTONEAREST = &H2 'If the monitor is not found, return the nearest monitor
End Enum

Private Const MONITORINFOF_PRIMARY = 1

'Structure for the position of a monitor
Private Type tagMONITORINFO
cbSize As Long 'Size of structure
rcMonitor As RECT 'Monitor rect
rcWork As RECT 'Working area rect
dwFlags As Long 'Flags
End Type

Type UDTMonitor
handle As Long
Left As Long
Right As Long
Top As Long
Bottom As Long

WorkLeft As Long
WorkRight As Long
WorkTop As Long
Workbottom As Long

Height As Long
Width As Long

WorkHeight As Long
WorkWidth As Long

IsPrimary As Boolean
End Type

Private Declare Function MonitorFromRect Lib "user32" (rc As RECT, ByVal dwFlags As dwFlags) As Long
Private Declare Function GetMonitorInfo Lib "user32" Alias "GetMonitorInfoA" (ByVal hMonitor As Long, MonInfo As tagMONITORINFO) As Long

Public Sub EnsureFormIsInsideMonitor(Frm As Form, Optional RefForm As Form)

'typically used to determine if the previously saved position/size of a Form needs adjustment re the current monitor layout
' if a Form is mapped to a disconnected monitor the Form is remapped to the Primary monitor

'typical usage:
'Private Sub Form_Load()
' retrieve previous left and top positions from file and apply them to Me.Left and Me.Top Properties
' EnsureFormIsInsideMonitor Me
'End Sub

'If Reform is not specified Frm is positioned to be displayed entirely within the monitor on which most of it is currently mapped
'If Reform is specified Frm is positioned to be displayed entirely on the same monitor as that on which most of Reform is mapped

'adjusts Frm Left and Top so that all the borders of Frm are contained within the same Monitor

' if Frm.Width or Height exceed monitor.width or height Frm is positioned at Left/ Top of monitor and
' Width/ Height of Frm may be adjusted if Frm is Sizable

Dim VFlag As Boolean, HFlag As Boolean
Dim cMonitor As UDTMonitor

If RefForm Is Nothing Then Set RefForm = Frm

cMonitor = MonitorProperties(RefForm)

With Frm
If .Width > cMonitor.WorkWidth Then
If .BorderStyle = vbSizable Or .BorderStyle = vbSizableToolWindow Then
.Width = cMonitor.WorkWidth
Else
.Left = cMonitor.WorkLeft: HFlag = True
End If
End If
If .Height > cMonitor.WorkHeight Then
If .BorderStyle = vbSizable Or .BorderStyle = vbSizableToolWindow Then
.Height = cMonitor.WorkHeight
Else
.Top = cMonitor.WorkTop: VFlag = True
End If
End If

If Not HFlag Then
If .Left < cMonitor.WorkLeft Then .Left = cMonitor.WorkLeft
If (.Left + .Width) > cMonitor.WorkRight Then .Left = cMonitor.WorkRight - .Width
End If
If Not VFlag Then
If .Top < cMonitor.WorkTop Then .Top = cMonitor.WorkTop
If (.Top + .Height) > cMonitor.Workbottom Then .Top = cMonitor.Workbottom - .Height
End If
End With

End Sub

Public Function MonitorProperties(Frm As Form) As UDTMonitor

'Return the properties (in Twips) of the monitor on which most of Frm is mapped

Dim hMonitor As Long
Dim MonitorInfo As tagMONITORINFO
Dim tppx&, tppy&
Dim Frect As RECT

GetWindowRect Frm.hWnd, Frect
hMonitor = MonitorFromRect(Frect, MONITOR_DEFAULTTOPRIMARY) 'get handle for monitor containing most of Frm
' if disconnected return handle (and properties) for primary monitor
tppx = Screen.TwipsPerPixelX
tppy = Screen.TwipsPerPixelY

On Error GoTo GetMonitorInformation_Err
MonitorInfo.cbSize = Len(MonitorInfo)
GetMonitorInfo hMonitor, MonitorInfo
With MonitorProperties
.handle = hMonitor
'convert all dimensions from pixels to twips
.Left = MonitorInfo.rcMonitor.Left * tppx
.Right = MonitorInfo.rcMonitor.Right * tppx
.Top = MonitorInfo.rcMonitor.Top * tppy
.Bottom = MonitorInfo.rcMonitor.Bottom * tppy

.WorkLeft = MonitorInfo.rcWork.Left * tppx
.WorkRight = MonitorInfo.rcWork.Right * tppx
.WorkTop = MonitorInfo.rcWork.Top * tppy
.Workbottom = MonitorInfo.rcWork.Bottom * tppy

.Height = (MonitorInfo.rcMonitor.Bottom - MonitorInfo.rcMonitor.Top) * tppy
.Width = (MonitorInfo.rcMonitor.Right - MonitorInfo.rcMonitor.Left) * tppx

.WorkHeight = (MonitorInfo.rcWork.Bottom - MonitorInfo.rcWork.Top) * tppy
.WorkWidth = (MonitorInfo.rcWork.Right - MonitorInfo.rcWork.Left) * tppx

.IsPrimary = MonitorInfo.dwFlags And MONITORINFOF_PRIMARY
End With

Exit Function
GetMonitorInformation_Err:
Beep
If Err.Number = 453 Then
'should be handled if pre win2k compatibility is required
'Non-Multimonitor OS, return -1
'GetMonitorInformation = -1
'etc
End If
End Function

> but all the messages and popups appear on the primary monitor
And all vbToolTipText messages for the light-weight controls like Images and Labels will refuse to display on a secondary monitor (they will appear around the edge of the primary monitor), if ToolTips are required for such controls you will have to use API calls (and that has its qwirks for lightweight controls too!)
 
I'll get our client to try that code out, thanks.

The issue you mention with tooltips - presumably that happens regardless of how you position your form on the secondary monitor and will apply to any solution to this problem?

- Andy
___________________________________________________________________
If you think nobody cares you're alive, try missing a couple of mortgage payments
 
For tooltips, a borderless, captionless, controlboxless, form with or without a label that has the backcolor that equals vbInfoBackground. Then you can control the Left/Top properties.

Good Luck

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top