1. Roland Smith
  2. PowerBuilder
  3. Monday, 27 June 2022 20:51 PM UTC

PowerBuilder 2019 Build 2170

We have a PFC based app and are having weirdness with response windows and where they are located.

Scenario:

Move the app's frame window to monitor #2.

Choose a menu item that opens a Main! window that inherits from w_sheet.

The window is centered over the frame window.

Click a button on the Main! window

A Response! window that inherits from w_reponse opens.

The response window is centered in monitor #1.

 

The window w_response event pfc_preopen calls of_center in pfc_n_cst_winsrv. I tried commenting that out and using the Center property but it didn't help.

I need to find a way to center the window on the monitor that the frame window is or on the frame itself.

Ideas?

Roland Smith Accepted Answer Pending Moderation
  1. Wednesday, 29 June 2022 13:23 PM UTC
  2. PowerBuilder
  3. # 1

I found a solution. Using Windows API functions, I find the coordinates of the monitor that the parent window is located on and center the current window using those instead of the screen size returned by the environment object.

forward
global type n_monitorinfo from nonvisualobject
end type
type rect from structure within n_monitorinfo
end type
type monitorinfoex from structure within n_monitorinfo
end type
end forward

type rect from structure
	long		left
	long		top
	long		right
	long		bottom
end type

type monitorinfoex from structure
	unsignedlong		cbsize
	rect		rcmonitor
	rect		rcwork
	unsignedlong		dwflags
	character		szdevice[32]
end type

global type n_monitorinfo from nonvisualobject autoinstantiate
end type

type prototypes
Function long MonitorFromWindow ( &
	long hwnd, &
	ulong dwFlags &
	) Library "user32.dll"

Function boolean GetMonitorInfo ( &
	long hMonitor, &
	Ref MONITORINFOEX lpmi &
	) Library "user32.dll" Alias For "GetMonitorInfoW"

end prototypes

forward prototypes
public subroutine of_centeronmonitor (window aw_window)
public subroutine of_centeronwindow (window aw_parent, window aw_window)
end prototypes

public subroutine of_centeronmonitor (window aw_window);// Center the window on the current monitor

Constant ULong MONITOR_DEFAULTTONULL = 0
MONITORINFOEX mi

Boolean lb_Result
Long ll_hWnd, ll_hMonitor
Long ll_MonWidth, ll_MonHeight
Long ll_WinWidth, ll_WinHeight
Long ll_XPos, ll_YPos

ll_hWnd = Handle(aw_window)

ll_hMonitor = MonitorFromWindow(ll_hWnd, MONITOR_DEFAULTTONULL)
If ll_hMonitor > 0 Then
	mi.cbSize = 104
	lb_Result = GetMonitorInfo(ll_hMonitor, mi)

	ll_MonWidth  = PixelsToUnits(mi.rcWork.Right  - mi.rcWork.Left, XPixelsToUnits!)
	ll_MonHeight = PixelsToUnits(mi.rcWork.Bottom - mi.rcWork.Top,  YPixelsToUnits!)

	ll_WinWidth  = aw_window.Width
	ll_WinHeight = aw_window.Height

	ll_XPos = PixelsToUnits(mi.rcWork.Left, XPixelsToUnits!) + ((ll_MonWidth  - ll_WinWidth) / 2)
	ll_YPos = PixelsToUnits(mi.rcWork.Top,  YPixelsToUnits!) + ((ll_MonHeight - ll_WinHeight) / 2)

	aw_window.X = ll_XPos
	aw_window.Y = ll_YPos
End If

end subroutine

public subroutine of_centeronwindow (window aw_parent, window aw_window);// Center the window on the current monitor of the parent window

Constant ULong MONITOR_DEFAULTTONULL = 0
MONITORINFOEX mi

Boolean lb_Result
Long ll_hWnd, ll_hMonitor
Long ll_MonWidth, ll_MonHeight
Long ll_WinWidth, ll_WinHeight
Long ll_XPos, ll_YPos

ll_hWnd = Handle(aw_parent)

ll_hMonitor = MonitorFromWindow(ll_hWnd, MONITOR_DEFAULTTONULL)
If ll_hMonitor > 0 Then
	mi.cbSize = 104
	lb_Result = GetMonitorInfo(ll_hMonitor, mi)

	ll_MonWidth  = PixelsToUnits(mi.rcWork.Right  - mi.rcWork.Left, XPixelsToUnits!)
	ll_MonHeight = PixelsToUnits(mi.rcWork.Bottom - mi.rcWork.Top,  YPixelsToUnits!)

	ll_WinWidth  = aw_window.Width
	ll_WinHeight = aw_window.Height

	ll_XPos = PixelsToUnits(mi.rcWork.Left, XPixelsToUnits!) + ((ll_MonWidth  - ll_WinWidth) / 2)
	ll_YPos = PixelsToUnits(mi.rcWork.Top,  YPixelsToUnits!) + ((ll_MonHeight - ll_WinHeight) / 2)

	aw_window.X = ll_XPos
	aw_window.Y = ll_YPos
End If

end subroutine

on n_monitorinfo.create
call super::create
TriggerEvent( this, "constructor" )
end on

on n_monitorinfo.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on
Comment
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Tuesday, 28 June 2022 01:52 AM UTC
  2. PowerBuilder
  3. # 2

What version of the PFC are you using, Roland?

There was code placed in the pfcPreOpen event in the pfc_w_response ancestor response window in version 12.5, purported to implement resizable response windows via the SetWindowLong API function.

Our PFC-based application centers a response window in a secondary monitor when the frame resides in the secondary monitor using PB 2019 R3 (I'll check the build number when I return to work tomorrow). The "Center" property is turned off and there is no code in place to manually center the window.

Regards, John

Comment
  1. John Fauss
  2. Tuesday, 28 June 2022 13:12 PM UTC
FWIW, we are using PB 2019 R3 Build 2703.
  1. Helpful
  1. Roland Smith
  2. Tuesday, 28 June 2022 13:15 PM UTC
I downloaded the latest PFC from Github and don't see any difference in the of_Center function. I think I'll center it on the frame window instead of the screen.
  1. Helpful
  1. John Fauss
  2. Tuesday, 28 June 2022 17:58 PM UTC
This issue may have been an outcome of the fix for Bug/Ticket ID's 5976, 5992, 6011, & 6015.
  1. Helpful
There are no comments made yet.
Olan Knight Accepted Answer Pending Moderation
  1. Monday, 27 June 2022 22:53 PM UTC
  2. PowerBuilder
  3. # 3

Have you tried to explicity SetFocus on the Frame  ....AND... also explicitly setting the CurrentActiveSheet to the Frame?

...all before opening the Reposnse window?

Comment
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Tuesday, 28 June 2022 06:24 AM UTC
  2. PowerBuilder
  3. # 4

I think Appeon has done more than one change related to this problem.

I you can't figure it out, I should have some code somewhere that deals with this problem (pfc based).

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.