Page 1 of 2

EasyPTR query

Posted: Thu Jul 17, 2014 6:19 pm
by JonS
Hi,
Is there a simple way to get the size of an application window in code? I know it's initial size but I want to call a function to get the size after a window is re-sized.

I need this to work in both SBASIC and QLIB.

Jon

Re: EasyPTR query

Posted: Thu Jul 17, 2014 9:06 pm
by pjw
Try PVAL

Re: EasyPTR query

Posted: Thu Jul 17, 2014 9:42 pm
by tofro
JonS wrote:Hi,
Is there a simple way to get the size of an application window in code?
Jon,
two ways to do this
  • Use MWDEF - this returns the address of the window working definition (that is, the low-level data structure). Thats's kind of complicated (i.e. definitively not the 'simple way' you asked for) now, as the working definition is held together by pointers and needs to be "walked" from the very beginning.
    PEEK_W (x+$6e) gives the number of application sub-windows
    app=PEEK_L(x+$70) points to the application sub-window definition list, which is just a 0-terminated list of long pointers to the actual definitions
    apw = peek_l(app+appl window #*4) points to a single application window's data structure
    PEEK_W(appw + (0..3)*2) gives x, y, size and origin of that window
    (See http://www.kilgus.net/smsqe/QPTR.pdf , page 136)
    The length of an application sub-window definition depends on the flags that tell you whether it has a menu or not or whether its pan- or scrollable.
  • This method is way easier but will only work if you know that the application window has had an event (i.e. the pointer must at least be in there and be moved or a click). If you have such a case, you can get the pointer record for that window using PVAL and the last 4 words starting at offset $10 will hold w, h, x, y
Whenever I have a chance, I use the latter method.

Hope this helps,

Tobias

Re: EasyPTR query

Posted: Fri Jul 18, 2014 9:13 am
by Derek_Stewart
Hi,

Norman Dunbar did a guide to EasyPtr, which may answer some of your questions. Available on Dilwyn's Web site.

Lots of Qptr information and articles in QL Today.

Re: EasyPTR query

Posted: Fri Jul 18, 2014 5:23 pm
by JonS
Thanks for the replies.

Yes, I've read Norman's document, but that's more a getting started guide...and this is beyond that...unless there's another document I've not seen.

I've tried PVAL, but as Tobias says, that relies on an event. I've tried to force one in my code, but it wasn't really what I wanted. Tobias' first suggestion seems the best. I just need to code a SBASIC procedure to make it simple. Will give it a go.

Thanks again.

Re: EasyPTR query

Posted: Fri Jul 18, 2014 6:57 pm
by pjw
An event could be as simple as RDPT#ch; 48. This call returns immediately. All you need is a channel. So:
DIM erec%(15)
open channel and OUTLine it, then
...
RDPT#ch; 48: pval#ch; erec%
orgx% = erec%(10): yorg% = erec%(11)

Re: EasyPTR query

Posted: Fri Jul 18, 2014 6:59 pm
by dilwyn
tofro wrote:This method is way easier but will only work if you know that the application window has had an event (i.e. the pointer must at least be in there and be moved or a click). If you have such a case, you can get the pointer record for that window using PVAL and the last 4 words starting at offset $10 will hold w, h, x, y
Whenever I have a chance, I use the latter method.
Hope this helps,
Tobias
Usually an 'event' can be
  • pointer in window
    pointer out of window
Although I've never tried it in this context, where I have used it this forces an immediate return using RDPT and PVAL which is very useful since it can be used to set a specific pointer position or to install a working area. It might allow access to the information you want.

Also, if you set the window channel temporarily to the area you want the size of, you might be able to use something like CHAN_W from DIY Toolkit to extract the size from the window channel definition block itself (again, never tried this, no idea if it will work):

MWINDOW #0,app_window_number
wide% = CHAN_W%(#0,28)
high% = chan_w%(#0,30)
xorigin%= CHAN_W%(#0,24)
yorigin%=CHAN_W%(#0,26)
MWINDOW #0,0 : rem back to full window outline

Re: EasyPTR query

Posted: Fri Jul 18, 2014 8:04 pm
by JonS
Pjw

That works fine for the window size. I want the size of one or more of the application sub windows. For PVAL to work with RDPT I'm pretty sure the pointer needs to be IN the sub window and I can't guarantee that and don't want to force a pointer position change just so it will work.

Jon

Re: EasyPTR query

Posted: Fri Jul 18, 2014 10:39 pm
by tofro
JonS wrote:I want the size of one or more of the application sub windows. For PVAL to work with RDPT I'm pretty sure the pointer needs to be IN the sub window
Jon,
that's right. If the pointer is IN the ASW, you'll get an event for anything happening to it. If it leaves the ASW, you get another one ("just left window"). For everything happening after the pointer left the ASW, you won't get any more events until the pointer moves back into the ASW.

On the other hand, when does the size of an ASW change? Only when you change the size of the primary (or when decorations like pan or scroll bars are added wich we should ignore for now). You normally know that new size and the position in the main window as well as the scaling flags and could recalculate the new ASW size - But that's probably just as complicated as the MWDEF method described above. That method is also quite nice to make yourself familiar with the working definition, as you definitively need to find your way around there when programming in assembler. (And you can do quite a lot of other fancy things with that data structure.... ;) )

Tobias

Re: EasyPTR query

Posted: Fri Jul 18, 2014 11:16 pm
by JonS
Tobias

The following proc seems to do the trick:
10000 DEFine PROCedure GET_APPW_SIZE(channel,appw_no,xsize%,ysize%)
10010 LOCal working_def,ww_nappl,ww_pappl,apw
10020 :
10030 working_def=MWDEF(#channel)
10040 :
10050 ww_nappl=PEEK_W(working_def+$6e)
10060 IF appw_no<1 OR appw_no>ww_nappl THEN
10070 xsize%=-1 : ysize%=-1
10080 ELSE
10090 ww_pappl=PEEK_L(working_def+$70)
10100 apw=PEEK_L(ww_pappl+((appw_no-1)*4))
10110 xsize%=PEEK_W(apw)
10120 ysize%=PEEK_W(apw+2)
10130 END IF
10140 :
10150 END DEFine GET_APPW_SIZE
10160 :

returning the size in xsize% and ysize% or -1 if it's an invalid app sub window no.

I take your point about the calculating on resize, but on the one program I've written to resize, it seemed not to be exact when scaling flag was not 4. Maybe I was calculating wrong, but using this I know it's going to be right every time.

Thanks again.