1. Marc James
  2. PowerBuilder
  3. Tuesday, 4 February 2020 12:42 PM UTC

I've opened up my application, moved it to my secondary screen, then run PrintSetup() and it pops up on the original screen, what's the simplest way to make sure it pops up on the same screen as my application??

It does this for other windows I open separately too.

Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Tuesday, 4 February 2020 18:45 PM UTC
  2. PowerBuilder
  3. # 1

Hi Marc;

  Yes, any internal or O/S dialogue (like Message Box dialogue for example) will always appear on Monitor #1. You cannot control this aspect.

  Workarounds:

1) Code your own MsgBox, PrintSet-up, etc dialogues and then center them upon open with your App's current location or in the case of PowerServer Web App's, within where the web browser is located.

   FWIW: My STD Framework uses this approach - Including, IWA based Apps.  ;-)

2) Use the FindWindow O/S API call to locate the Handle of PB or O/S dialogues. Using the handle of the Window, you could now under program control relocate it to monitor #2.

  IMHO: This would make a great enhancement suggestion for the PB run-time.

Regards .. Chris

Comment
  1. Miguel Leeuwe
  2. Wednesday, 5 February 2020 01:36 AM UTC
Upvote for the enhancement suggestion (and the rest of the answer of course).
  1. Helpful
There are no comments made yet.
Andrew Barnes Accepted Answer Pending Moderation
  1. Wednesday, 5 February 2020 23:01 PM UTC
  2. PowerBuilder
  3. # 2

I don't know if the solution we use is necessarily the simplest; it depends on how comfortable one is calling Windows API functions. 

The first part of the process is to code a CenterOnParent() function in the window that you want centered.  Our windows mostly are inherited from a common base window, so that is where we put the function.  Without that sort of an inheritance hierarchy, one could just as easily create a global function taking two Windows as arguments, one being the parent window, the other being the window to be centered.  The basic idea to center a child window over its parent is to:

  • Call the WinAPI function GetWindowRect() for both ParentWindow and the child window to get their size and position on the screen.
  • Do the math to center the child window's rectangle over the parent window's rectangle.
  • Optional:  To make the function really universal for all window sizes, use the MonitorFromPoint() and GetMonitorInfo() WinAPI functions to determine the bounding rectangle of the monitor on which the parent window is located, and then do the math to make sure that the calculated child rectangle is not going to move past any of the monitors edges adjusting the child window's position as needed.
  • Clear the Center property on the child window.
  • Move the child window to the new, calculated child window coordinates.  Remember to use PixelsToUnits to get the right coordinate system!

The second part of the process is to write your own Printer Setup window calling in its Open event the CenterOnParent() function.  This is actually pretty easy with the highlights of the process below.

  • Use PB function PrintGetPrinters to get a list of available printers.
  • Make a DataWindow object to list the printers.  Needs three string columns for printername, drivername, and port.
  • Use the DataWindow ImportString() function to populate your DataWindow.
  • Call the PrintSetupPrinter() function from Setup button.

Alternatively, one can wait for a subsequent version of PB to include a CenterOnParent property.  This is not a far flung hope as the he PB Window's Center property which is quite handy in a single monitor environment was not always there.

 

Andy

Comment
There are no comments made yet.
Olan Knight Accepted Answer Pending Moderation
  1. Friday, 7 February 2020 00:59 AM UTC
  2. PowerBuilder
  3. # 3

I find that popups require far too much effort to position correctly. I would VERY much like to see an enhancement such that the positioning of any window, including a popup, can be specified with simple parameters:

CENTERED                                                  // Centered on the screen; i.e. today's PB default
CENTERED ON PARENT WINDOW
UPPER LEFT CORNER
UPPER LEFT CORNER OF PARENT WINDOW
UPPER RIGHT CORNER
UPPER RIGHT CORNER OF PARENT WINDOW
LOWER LEFT CORNER
LOWER LEFT CORNER OF PARENT WINDOW
LOWER RIGHT CORNER
LOWER RIGHT CORNER OF PARENT WINDOW

// Specify upper left corner of the popup window location on the screen
CUSTOM LOCATION ON WINDOW

// Specify upper left corner of the popup window location on the parent window
CUSTOM LOCATION ON PARENT WINDOW         


Opinions? Thoughts? Additions?

Thanks,

Olan

Comment
  1. Olan Knight
  2. Thursday, 6 August 2020 00:25 AM UTC
OK, what is the link to the Enhancement Request page?



Thanks In Advance,

Olan
  1. Helpful
  1. John Fauss
  2. Thursday, 6 August 2020 02:00 AM UTC
According to a button on PB Roadmap web page, send an emali to: product@appeon.com.
  1. Helpful
  1. Olan Knight
  2. Thursday, 6 August 2020 06:08 AM UTC
Thank you, John!
  1. Helpful
There are no comments made yet.
Michael Kramer Accepted Answer Pending Moderation
  1. Friday, 7 February 2020 12:17 PM UTC
  2. PowerBuilder
  3. # 4

Hi Olan, good idea!

Especially in multi-monitor setups.

I actually implemented similar positioning logic recently. Setup was multi-monitor. App used a light custom framework. Functionality included:

  • Snap new MDI sheet to edge or corner of MDI area
  • Snap new MDI sheet to right edge of MDI area and resize to leverage full height of that MDI area
  • Center new response window on top of its parent window

I could generalize (like independent of MDI metaphor), wrap in a self-contained NVO, and share with community via an article acting as documentation? Later extend to snap/center on monitor occupied by particular window? 

Wonder if anyone would leverage such code...

/Michael

Comment
  1. Olan Knight
  2. Thursday, 13 February 2020 00:01 AM UTC
I love to be able to steal, I mean "use", your code for positioning!

Pretty please?

:)



That;s a very kind offer! Thank you!
  1. Helpful
  1. Michael Kramer
  2. Thursday, 13 February 2020 00:05 AM UTC
Hi Olan, I will start up tomorrow. I have some notes in OneNote on how I wanted to generalize. Hopefully I put them on a well-named paged in a well-named section ...
  1. Helpful
  1. Olan Knight
  2. Thursday, 6 August 2020 00:22 AM UTC
Fabulous! I thank you!
  1. Helpful
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Wednesday, 5 August 2020 01:23 AM UTC
  2. PowerBuilder
  3. # 5

A bit late maybe, but I just solved a very similar problem. If anyone's interested I can make a small sample application which contains the solution. (indeed based upon windows API's).

It's cost me the whole "$£%^^£$"%l*())*F(F*D()FDF day trying to find out why things did not work:

Always Works!

FUNCTION boolean GetMonitorInfo(ulong hMonitor, ref str_moninfo lpmi) LIBRARY "User32.dll" alias for "GetMonitorInfoA;Ansi"

 

Never works, always returns FALSE:
FUNCTION boolean GetMonitorInfo(ulong hMonitor, ref str_moninfo lpmi) LIBRARY "User32.dll" alias for "GetMonitorInfoW"

 

Did anyone manage to get the Unicode version working?

TIA.

Comment
  1. Miguel Leeuwe
  2. Wednesday, 5 August 2020 15:02 PM UTC
Well GetMonitorInfoW does not work with 72, not even the first time.

  1. Helpful
  1. Miguel Leeuwe
  2. Wednesday, 5 August 2020 15:07 PM UTC
Funny fact:

I've done this and it returns a Success message with a value of 104 !!!

So maybe that webpage does give the correct information.



for li_i = 72 to 254

lstruc_mon_info.size = li_i // 72 for the "GetMonitorInfoA;ansi" API, (104 for the "GetMonitorInfoW" API)

ll_monitor_handle = MonitorFromWindow (aul_handle,1)

if GetMonitorInfo(ll_monitor_handle , ref lstruc_mon_info ) then

messagebox('debug', 'success ' + string(li_i))

exit

end if

next

The only problem is that GetmonitorInfoW with a value of 104 only seems to work correctly ONE time, so I'll keep using the GetMonitorInfoA (ansi) API.
  1. Helpful
  1. John Fauss
  2. Wednesday, 5 August 2020 15:46 PM UTC
Miguel, I just posted a response that includes a zipped PBL with a sample app that I hope you find helpful. I think the problem you are having is because the MONITORINFO structure size is 40 bytes. The size of the MONITORINFOEX structure is 104 bytes. The sample app uses both, in case anyone wants to see the difference in how they are called/used.
  1. Helpful
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 5 August 2020 15:42 PM UTC
  2. PowerBuilder
  3. # 6

Here is a single-window sample app (created using PB 2017 R2) that uses the Unicode version of the GetMonitorInfo WinAPI call with either the WinAPI MONITORINFO structure or the MONITORINFOEX structure.

Run the app & position the window in the monitor of your choice, then click either the "Monitor Info From Window" button or the "Monitor Info Ex From Window" button.

John

Attachments (1)
Comment
  1. Miguel Leeuwe
  2. Wednesday, 5 August 2020 15:51 PM UTC
Thank you so much John,

I'll let you know what was wrong with my code.
  1. Helpful
  1. Miguel Leeuwe
  2. Wednesday, 5 August 2020 16:44 PM UTC
All working great now.

I didn't use longptr but ulong.

The size has to be 40 effectively !! That was the main problem.

Thanks again, this makes up for my 24 hour workday yesterday. I can sleep now.

:)

  1. Helpful
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.