Form Position on Dual Monitor Setup

Started by mr nick, May 17, 2011, 06:29:26 AM

Previous topic - Next topic

mr nick

Is there a way to set the position of a dialog so that it appears in the middle of whichever monitor is displaying AutoCAD at the time? If I use dcl_Form_Center it displays the dialog in the centre of whichever monitor is defined as No.1 in Windows rather than the screen actually showing CAD. Not a massive problem when dealing with my own machine but when I'm dealing with multiple users each with their own specific configurations then the results can be problematic, often resulting in people thinking CAD has hung because nothing appears to be happening when in actual fact there is a dialog awaiting input on a different screen.

Fred Tomke

Hi, sure there should be. But I'm not sure if there's a chance via Lisp.
Just find out the location and the size of AutoCAD mainwindow. Then you compute the upper left corner of your form depending the size of your form. I currently see no other way.

Regards,
Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

owenwengerd

I'm not sure there's a foolproof way to determine which monitor is "displaying AutoCAD" in cases where the AutoCAD window displays on multiple monitors, but I suppose it's possible to come up with something that works for most cases. I don't use dual monitors, but this could be changed if there's a concensus among the community.
Owen Wengerd (Outside The Box) / ManuSoft

mr nick

Looking at the definition for the Control_SetPos method, it states "If the control is a child window, the specified coordinates are relative to the upper left corner of the parent window's client area; otherwise they are screen coordinates". What exactly is considered to be a 'child window' in terms of ODCL forms because if it looks like a child window is the only item that can be passed AutoCAD specific coordinates but I'm unsure as to whether this is of any use to me or not.

owenwengerd

"Child windows" are a Windows thing. In OpenDCL currently I think only modal dialogs and file dialogs are child windows. Actually, docked control bars are also child windows, but they can't be positioned manually.
Owen Wengerd (Outside The Box) / ManuSoft

mr nick

Hmm. I tried both modal and modeless forms but if I try and set the position, it always seems to adopt screen coordinates rather than parent. Looks like I'm out of luck with this one  :'(

Fred Tomke

Hello,

I can imagine two ways of solving this:

Either we add another addional function for returning the current location and size of AutoCAD main window similar to (dcl_form_getpos ...) so you can add additional arguments to (dcl_form_show ...) or (dcl_form_center ...) gets an additional optional argument T for centering the form in the center of AutoCAD main window (whereever it is currently placed).
Most of our customers are using Dual monitors because of the huge size of their land development plans.

Regards,
Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

owenwengerd

It's possible to get the position of the AutoCAD main window via lisp by using ActiveX, so I think with some work, you could do it with the existing ODCL functions.
Owen Wengerd (Outside The Box) / ManuSoft

Fred Tomke

#8
Hi, Owen,

I'm not sure if it is really possible to get the information via ActiveX because WindowLeft and WindowTop seem to return standard values if maximized to the screen:

;   Height = 1026
;   Width = 1696
;   WindowLeft = -8
;   WindowState = 3
;   WindowTop = -8


But how to get the information if it is on first or second screen?

Regards, Fred
Fred Tomke
Dipl.-Ing. (FH) Landespflege

[ landscaper - landscape developer - digital landscape and urban design]

owenwengerd

One idea would be to calculate the center of the AutoCAD window, then determine which monitor contains that point. There may not be a foolproof algorithm, but I think that would work for most cases.
Owen Wengerd (Outside The Box) / ManuSoft

mr nick

Quote from: owenwengerd on May 22, 2011, 06:42:40 PM
...then determine which monitor contains that point...
Any pointers on how I might go about doing this? I'm out of ideas about how to transpose AutoCAD coordinates to Windows coordinates and vice versa  ???

roy_043

#11
Quote from: Fred Tomke on May 22, 2011, 08:14:03 AM
I'm not sure if it is really possible to get the information via ActiveX because WindowLeft and WindowTop seem to return standard values if maximized to the screen:

I cannot say anything about the situation in AutoCAD but in Bricscad this is not true.
If I am running the cad application on my secondary monitor and have this monitor positioned above my primary monitor this:
(vla-get-windowtop (vlax-get-acad-object))
will return a large negative value (for a screen height of 1024 with the cad application maximized the value is -1028).

Using the fact that (dcl_GetScreenSize) returns values for the primary monitor it is possible to determine on which monitor the cad application is running.

But that information is not necessary: the center of the cad application window is enough to position a form.

Code (autolisp) Select

; returns the center of the application window (may not be the screen center)
(defun GetCadAppCenter ( / oCad result)
  (vl-load-com)
 (setq oCad (vlax-get-acad-object))
 (setq result
   (list
     (+ (vla-get-windowleft oCad) (/ (vla-get-width oCad) 2))
     (+ (vla-get-windowtop oCad) (/ (vla-get-height oCad) 2))
   )
 )
 (vlax-release-object oCad)
 result
)

; algorithm suggested by Owen Wengerd
; code will also return nil if the center of the application
; window is on the task bar of the primary monitor
(defun kg_odcl_CadAppOnPrimaryMonitorP ()
 (equal
   (mapcar
     '(lambda (app scr)
        (< 0 app scr)
     )
     (GetCadAppCenter)
     (dcl_GetScreenSize)
   )
   '(T T)
 )
)

; example: (kg_odcl_FormCenter_To_CadAppCenter MyProject_MyForm)
(defun kg_odcl_FormCenter_To_CadAppCenter (form)
 (apply
   'dcl_Control_SetPos
   (cons
     form
     (mapcar
       '-
       (GetCadAppCenter)
       (list
         (/ (dcl_Control_GetWidth form) 2)
         (/ (dcl_Control_GetHeight form) 2)
       )
     )
   )
 )
)


EDIT1: Something is going wrong with the code highlighting...
EDIT2: added (vl-load-com)

owenwengerd

Comment highlighting should now be fixed.
Owen Wengerd (Outside The Box) / ManuSoft

mr nick

Quote from: roy_043 on June 04, 2011, 09:22:58 AM

... Using the fact that (dcl_GetScreenSize) returns values for the primary monitor it is possible to determine on which monitor the cad application is running.

But that information is not necessary: the center of the cad application window is enough to position a form...


Fantastic. Your provided code does exactly what I need. Dragging AutoCAD between windows and using your FormCenter_To_CadAppCenter code makes my dialog appear in the centre of whichever monitor is displaying the app.

Many thanks for your input on this - it's very much appreciated  ;D

KKirk

Revisting a quite old thread here, but I'm struggling to get this to work in Autocad 2023. I'm relatively new to LISP and OpenDCL so I may be doing something dumb or missing something obvious, but is there anything in the code from Roy/Owen that is Bricscad specific that I would have to adjust to make it work in Autocad?