Determining the bottom right position of the active MapInfo window in Pixels

166 views
Skip to first unread message

giles...@googlemail.com

unread,
Aug 24, 2008, 5:47:51 PM8/24/08
to MapInfo-L
Dear List,

Does anybody know how to determine the bottom right of MapInfo
window? I have a dialog box which I would like to appear at a set
distance from the bottom right of the map window. I can determine the
distance from the top left corner using:

windowinfo(Frontwindow(),5) 'ht

windowinfo(Frontwindow(),4) 'width

However the results are returned in 'paper units' and the dialog
command's position clause uses pixels, is there any way to measure the
map window in pixels, or alternatively work around by converting paper
units to pixels?

Thanks in advance,

Giles

Aladar

unread,
Aug 24, 2008, 11:49:13 PM8/24/08
to MapInfo-L
Hi Giles,

Here is a little routine in mapbasic should solve your problem. It
shows simple dialog with OK button in lower left corner of focus
window. Final position depends on screen resolution as well, I haven't
explored how to detect screen resolution from mapbasic. I've used
my120ppi in my case. Most common value is 96ppi (windows default).
This example assumes that you have focus on any window before
execution.
_______________________
Include "MapBasic.def"

dim Map_width, Map_height as float
dim pos_top, pos_left as float
dim screen_res as integer

dim shift_left, shift_down as integer

screen_res=120 'PPI
shift_left = 6 'pixels
shift_down = 32 'pixels

Map_height = windowinfo(Frontwindow(),WIN_INFO_HEIGHT)
Map_width = windowinfo(Frontwindow(),WIN_INFO_WIDTH)
pos_left = windowinfo(Frontwindow(), WIN_INFO_X)
pos_top = windowinfo(Frontwindow(), WIN_INFO_Y)

dialog title "Floating dialog"
position (pos_left*screen_res)+shift_left,(pos_top*screen_res)+
(Map_height*120)+shift_down
control okbutton
_____________________________________

regards,
Aladar


On Aug 25, 7:47 am, "gilessut...@googlemail.com"

Giles Sutton

unread,
Aug 25, 2008, 6:06:14 AM8/25/08
to mapi...@googlegroups.com
Hi Aladar,

Thanks for that, that's great, first step completed.  I'm trying to work out some code for determining dpi.  I'll post it on the list once I get there

Regards,

Giles

Bill Thoen

unread,
Aug 25, 2008, 9:04:03 AM8/25/08
to mapi...@googlegroups.com
The real answer to getting window information in pixels is to use
Windows API functions. Here's a little scrapplication I wrote a while
ago that uses all the relevant Windows API functions. I think that all I
was doing here was to open the map window to fit exactly whatever space
was available in the current MapInfo application window without actually
maximizing the map window.

For more details, use Google or peruse Microsoft's MSDN web pages.

- Bill Thoen


'ScreenInfo.mb
Include "MapBasic.def"
Include "ScreenInfo.def"

Define LOGPIXELSX 88 ' Logical pixels/inch in X
Define LOGPIXELSY 90 ' Logical pixels/inch in Y

Define SM_CXSIZEFRAME 32
Define SM_CYSIZEFRAME 33
Define SM_CYHSCROLL 3
Define SM_CXVSCROLL 20
Define SM_CYCAPTION 4

Type RECT_t
left As Integer
top As Integer
right As Integer
bottom As Integer
End Type

Declare Function GetSystemMetrics Lib "User32" Alias "GetSystemMetrics" (
ByVal nIndex As Integer) As Integer
Declare Function GetClientRect Lib "user32" Alias "GetClientRect" (
ByVal hwnd As Integer, lpRect As RECT_t) As Integer
Declare Function GetDeviceCaps Lib "gdi32" Alias "GetDeviceCaps" (
ByVal hdc As Integer, ByVal nIndex As Integer) As Integer
Declare Function GetDC Lib "user32" Alias "GetDC" (
ByVal hwnd As Integer) As Integer
Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (
ByVal hwnd As Integer, ByVal hdc As Integer) As Integer


Sub GetMIClientRect (
fWidth As Float,
fHeight As Float)
' Returns the width and height (in inches) of the available space
' in the MapInfo client rectangle area
Dim hWnd As Integer
Dim hDC As Integer
Dim nStatus As Integer
Dim tRect As RECT_t
Dim nWidth, nHeight As Integer

hWnd = SystemInfo(SYS_INFO_MDICLIENTWND)
nStatus = GetClientRect (hWnd, tRect)
nWidth = tRect.right - 2*GetSystemMetrics (SM_CXSIZEFRAME)
nHeight = tRect.bottom - GetSystemMetrics (SM_CYCAPTION) -
2*GetSystemMetrics (SM_CYSIZEFRAME)

hDC = GetDC (hWnd)
fWidth = nWidth / GetDeviceCaps (hDC, LOGPIXELSX)
fHeight = nHeight / GetDeviceCaps (hDC, LOGPIXELSY)
nStatus = ReleaseDC (hWnd, hDC)
End Sub


Declare Sub Main
Sub Main
Dim fWidth, fHeight As Float

CLS
Close All Interactive

Call GetMIClientRect (fWidth, fHeight)

Open Table "States" Interactive
Map From USA
Set Window FrontWindow() Position (0,0) Width fWidth Height fHeight
End Sub


Maurice34

unread,
Aug 25, 2008, 5:39:15 PM8/25/08
to MapInfo-L
Hi Bill
Many thanks...but it's very difficult to compile...especially without
ScreenInfo.def !

Bill Thoen

unread,
Aug 26, 2008, 9:40:00 AM8/26/08
to mapi...@googlegroups.com
Sorry... Here's ScreenInfo.def

'ScreenInfo.def

Declare Sub GetMIClientRect (fWidth As Float, fHeight As Float)

Giles Sutton

unread,
Aug 28, 2008, 4:21:41 AM8/28/08
to mapi...@googlegroups.com
Bill, Tony and Aladar,

Thanks for the code snippits, I've put the various bits together and come up with a function and sub for determining the bottom right of the screen.  There are a few bodges, namely: I've calculated the width of dialog units by measuring the widths/ heights of the characters in pixels using a graphics package (I couldn't face navigating through Microsoft's web pages) and there is a correction factor of 10 and 145 pixels to take the dialog box to the bottom right of the MapInfo client window (bills code always seemed to put the dialog box at a consistant distance from the bottom right of the MapInfo client window). 

It works for me at the moment (on 2 different screens but it is not always exactly in the BR corner and can be a few pixles out depending on the size of the dialog box and the shape of the client window).  If anyone can see why the correction factors are needed / a way to get rid of them, or has a simple way of determining the dimensions of dialog units in pixels let me know.

Thanks,

G

zzzzzzzzzzzzzzzzzzzzzz

Call either the function:

GetBRtPixels(MI_WIN_BRX,Dialog width in paper units) - returns Base of MI window in Pixels'
GetBRtPixels(MI_WIN_BRY, Dialog height in paper units) - returns RHS of MI in Pixels

or the sub:

GetMICliRectPixForDiaPos(fWidth, fHeight) 'to return both

e.g.

'To place the dialog in the bottom RHS of screen:

Dim PosX, PosY  as integer

'Then either use:
PosX = GetBRtPixels(MI_WIN_BRX,EndLength)
PosY = GetBRtPixels(MI_WIN_BRY,EndHt)

'or
Dim fWidth, fHeight As float
Call GetMICliRectPixForDiaPos(fWidth, fHeight)

PosX = fWidth + 10 - (EndLength * 1.538) ' sub routine uses just returns a point in piexles at a set distance from the top right of the screen 
PosY = fHeight + 120 - (EndHt * 1.625) ' and the correction factors are needed after

'Then call your dialog box:

Dialog
Title AppName
Position PosX, PosY
Control OKButton

'and it should hopefully be in the bottom right of the MapInfo client window or thereabouts!

zzzzzzzzzzzzzzzzzzzzzzz

'Definition file:

'Definitions etc


Define LOGPIXELSX 88        '  Logical pixels/inch in X
Define LOGPIXELSY 90        '  Logical pixels/inch in Y

Define SM_CXSIZEFRAME 32
Define SM_CYSIZEFRAME 33
Define SM_CYHSCROLL 3
Define SM_CXVSCROLL 20
Define SM_CYCAPTION 4

Define MI_WIN_BRX "X"
Define MI_WIN_BRY "Y"


Type RECT_t
 left As Integer
 top As Integer
 right As Integer
 bottom As Integer
End Type

'Non MB functions


Declare Function GetSystemMetrics Lib "User32" Alias "GetSystemMetrics" (
   ByVal nIndex As Integer) As Integer
Declare Function GetClientRect Lib "user32" Alias "GetClientRect" (
   ByVal hwnd As Integer, lpRect As RECT_t) As Integer
Declare Function GetDeviceCaps Lib "gdi32" Alias "GetDeviceCaps" (
   ByVal hdc As Integer, ByVal nIndex As Integer) As Integer
Declare Function GetDC Lib "user32" Alias "GetDC" (
   ByVal hwnd As Integer) As Integer
Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (
   ByVal hwnd As Integer, ByVal hdc As Integer) As Integer

'MB Function and sub

Declare Function GetBRtPixels(Byval XY as string, ByVal DB_WH as integer) as float
Declare Sub GetMICliRectPixForDiaPos(fWidth As float, fHeight As float)


'Sub / function file:

Include "MapBasic.def"
Include 'the above defintion file

'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Function GetBRtPixels(Byval XY as string, ByVal DB_WH as integer) as float



Dim hWnd As Integer
Dim hDC As Integer
Dim nStatus As Integer
Dim tRect As RECT_t
Dim nWidth, nHeight As Integer
Dim PixRes,base_wnd,zero as integer

Dim MIHt, MIWidth as float

zero=0
base_wnd=GetDC(zero)
PixRes=GetDeviceCaps(base_wnd,88)


 hWnd = SystemInfo(SYS_INFO_MDICLIENTWND)
 nStatus = GetClientRect (hWnd, tRect)
 nWidth = tRect.right - 2*GetSystemMetrics (SM_CXSIZEFRAME)
 nHeight = tRect.bottom - GetSystemMetrics (SM_CYCAPTION) -
     2*GetSystemMetrics (SM_CYSIZEFRAME)

hDC = GetDC (hWnd)

'this second part is based upon counting / averaging pixels from a bitmap (A-Z in capitals and a-z in lower case - a bit dubious I know)
'which were then used to convert 'dialog units' to pixels.  This is where the code to calculate pixels per dialog units would be very useful
'The + 10 / + 145 parts of the equation are based on trial and error as the location of BRX and BRY are consistantly out by these numbers


if XY = "X" then
     MIWidth =  (nWidth / GetDeviceCaps (hDC, LOGPIXELSX)) * PixRes
    'see above note about this second part
    GetBRtPixels = MIWidth + 10 - (DB_WH * 1.538)

    elseif XY = "Y" then
   
    MIHt  =  (nHeight / GetDeviceCaps (hDC, LOGPIXELSY)) * PixRes
    'see above note about this second part
    GetBRtPixels = MIHt +120 - (DB_WH * 1.625)
    Else
    GetBRtPixels = 0
    End if


End Function
'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

Sub GetMICliRectPixForDiaPos(fWidth As float, fHeight As float)


Dim hWnd As Integer
Dim hDC As Integer
Dim nStatus As Integer
Dim tRect As RECT_t
Dim nWidth, nHeight As Integer
Dim PixRes,base_wnd,zero as integer

zero=0
base_wnd=GetDC(zero)
PixRes=GetDeviceCaps(base_wnd,88)


 hWnd = SystemInfo(SYS_INFO_MDICLIENTWND)
 nStatus = GetClientRect (hWnd, tRect)
 nWidth = tRect.right - 2*GetSystemMetrics (SM_CXSIZEFRAME)
 nHeight = tRect.bottom - GetSystemMetrics (SM_CYCAPTION) -
     2*GetSystemMetrics (SM_CYSIZEFRAME)

 hDC = GetDC (hWnd)
 fWidth = (nWidth / GetDeviceCaps (hDC, LOGPIXELSX)) * PixRes
 fHeight = (nHeight / GetDeviceCaps (hDC, LOGPIXELSY)) * PixRes

 nStatus = ReleaseDC (hWnd, hDC)


End Sub
'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Reply all
Reply to author
Forward
0 new messages