To avoid windows showing on a deactived monitor:
External Function declarations (there might be more declarations than you need):
FUNCTION Longptr MonitorFromWindow ( &
Longptr hWnd, &
UnsignedLong dwFlags &
) LIBRARY "user32.dll"
FUNCTION Boolean GetMonitorInfo ( &
Longptr hMonitor , &
REF str_monitorinfo lstr_MonitorInfo ) &
LIBRARY "user32.dll" ALIAS FOR "GetMonitorInfoW"
str_rect object:
global type str_rect from structure
long l_left descriptor "comment" = "X-coordinate of upper-left corner of rectangle (can be negative)"
long l_top descriptor "comment" = "Y-coordinate of upper-left corner of rectangle (can be negative)"
long l_right descriptor "comment" = "X-coordinate of lower-right corner of rectangle (can be negative)"
long l_bottom descriptor "comment" = "Y-coordinate of lower-right corner of rectangle (can be negative)"
end type
str_monitorinfo structure object:
global type str_monitorinfo from structure
unsignedlong ul_structsize descriptor "comment" = "The size of this structure, in bytes (always 40)"
str_rect str_monitor descriptor "comment" = "The display monitor rectangle, in virtual screen coordinates"
str_rect str_workarea descriptor "comment" = "The work area rectangle of the display monitor, in virtual screen coordinates"
unsignedlong ul_flags descriptor "comment" = "Bit flags. Bit 1 (xxxx xxx1) = 1 when this is the primary monitor"
end type
wf_workspace_full function:
// boolean wf_workspace_full(ref long al_width, ref long al_height, ref long al_left, ref long al_right, ref long al_top, ref long al_bottom, readonly alptr_alptr_handle_frame)
str_monitorinfo lstruc_mon_info
setnull(al_width)
setnull(al_height)
lstruc_mon_info.ul_structsize = 40
if NOT GetMonitorInfo(alptr_handle_frame, ref lstruc_mon_info ) then
return FALSE
end if
al_width = lstruc_mon_info.str_workarea.l_right - lstruc_mon_info.str_workarea.l_left
al_height = lstruc_mon_info.str_workarea.l_bottom - lstruc_mon_info.str_workarea.l_top
al_left = lstruc_mon_info.str_workarea.l_left
al_right = lstruc_mon_info.str_workarea.l_right
al_top = lstruc_mon_info.str_workarea.l_top
al_bottom = lstruc_mon_info.str_workarea.l_bottom
al_width = PixelsToUnits(al_width, XPixelsToUnits!)
al_height = PixelsToUnits(al_height, YPixelsToUnits!)
al_left = PixelsToUnits(al_left, XPixelsToUnits!)
al_right = PixelsToUnits(al_right, XPixelsToUnits!)
al_top = PixelsToUnits(al_top, YPixelsToUnits!)
al_bottom = PixelsToUnits(al_bottom, YPixelsToUnits!)
if isnull(al_width) or isnull(al_height) then
return FALSE
end if
return TRUE
Code in an event that has been POSTED from the Open() event:
"gnv_app" is pfc classes related. Let me know if any of them need explanation.
// v2, mjl, 04/06/20: avoid response window always showing on primary window
// we want the x and y to always be within the boundaries of the frame window.
string ls_pfc_ancestor_window
// v2, mjl, 12/08/20: if the frame is not valid, do nothing (happens with w_logon and w_change_password):
if not isvalid(gnv_app.of_getframe()) then
return 0
end if
ls_pfc_ancestor_window = of_pfc_ancestor_window()
choose case ls_pfc_ancestor_window
case 'w_response', 'w_popup', 'w_child', 'w_main'
// continue
case else
// not for w_sheet nor w_frame as these cannot appear on deactivated monitor.
RETURN 0
end choose
Environment lEnv
// // for debug run on secondary monitor and uncomment these 2 lines:
// this.x -= 2500
// yield()
longptr lptr_handle, lptr_monitor_frame, lptr_monitor_this
long ll_frame_monitor_left, ll_frame_monitor_right, ll_frame_monitor_top, ll_frame_monitor_bottom
long ll_frame_monitor_width, ll_frame_monitor_height
long ll_this_x, ll_this_y, ll_this_width, ll_this_height
// frame dimensions:
lptr_monitor_frame = handle(gnv_app.of_getframe())
lptr_monitor_frame = MonitorFromWindow (lptr_monitor_frame, 0)
lptr_monitor_this = handle(this)
lptr_monitor_this = MonitorFromWindow (lptr_monitor_this, 0)
// If the window is visible on a monitor, check the boundaries
if lptr_monitor_frame > 0 then
if NOT wf_workspace_full(ll_frame_monitor_width, ll_frame_monitor_height, ll_frame_monitor_left, ll_frame_monitor_right, &
ll_frame_monitor_top, ll_frame_monitor_bottom, lptr_monitor_frame) then
return 0
end if
end if
ll_this_x = this.x
ll_this_y = this.y
ll_this_width = this.width
ll_this_height = this.height
long ll_x, ll_y
if NOT (ll_this_x > ll_frame_monitor_left AND ll_this_x < ll_frame_monitor_right) &
or lptr_monitor_frame <> lptr_monitor_this then
ll_x = ll_frame_monitor_left + round( (ll_frame_monitor_width - ll_this_width) / 2, 0)
if ll_x < ll_frame_monitor_left then
ll_x = ll_frame_monitor_left
end if
else
ll_x = this.x
end if
if NOT (ll_this_y > ll_frame_monitor_top AND ll_this_y < ll_frame_monitor_bottom) &
or lptr_monitor_frame <> lptr_monitor_this then
ll_y = ll_frame_monitor_top + round( (ll_frame_monitor_height - ll_this_height) / 2, 0)
if ll_y < ll_frame_monitor_top then
ll_y = ll_frame_monitor_top
end if
else
ll_y = this.y
end if
if ll_x <> this.x or ll_y <> this.y then
// you can't move a maximised or minimised window so first check on state:
boolean lb_reset_maximized, lb_resize
if this.windowstate = maximized! then
lb_reset_maximized = true
else
// When the window's size was saved on a bigger monitor, make sure the size is not bigger than the frame-monitor's resolution:
if ll_this_width > ll_frame_monitor_width then
lb_resize = true
ll_this_width = ll_frame_monitor_width
end if
if ll_this_height > ll_frame_monitor_height then
lb_resize = true
ll_this_height = ll_frame_monitor_height
end if
end if
f_redraw(this, false)
post f_redraw_window(this)
// set to normal!
if this.windowstate <> normal! then
// set to normal when maximized or minimized:
this.windowstate = normal!
end if
if lb_resize then
// resize so it fits on the monitor
this.Resize(ll_this_width, ll_this_height)
end if
this.Move(ll_x, ll_y)
// v2, mjl, 07/08/20: save the correct "normal" positions to avoid being restored wrongly in the future:
// if isvalid(gnv_app) and isvalid(inv_preference) then
// gnv_app.inv_display_props.of_saveWinProps(this, this.inv_preference)
// end if
if lb_reset_maximized then
this.windowstate = maximized!
// v2, mjl, 07/08/20: save the correct "maximized" positions to avoid being restored wrongly in the future:
// if isvalid(gnv_app) and isvalid(inv_preference) then
// gnv_app.inv_display_props.of_saveWinProps(this, this.inv_preference)
// end if
end if
end if
return 0
I got this code, standing on the shoulders of other great people in this forum. Maybe I can find which posts were involved, but this is the final product I made of that information.
Have fun!
Open event:
---------------
This.Hide() // make the window invisible
This.POST Move(50,100) // move to position after the Open() has finished
This.POST Show() // Make the window visible after the Move() has finished.
Thanks