EasyPTR query

Anything QL Software or Programming Related.
User avatar
JonS
Bent Pin Expansion Port
Posts: 76
Joined: Fri Nov 11, 2011 3:54 pm
Location: Cumbria

EasyPTR query

Post 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


User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: EasyPTR query

Post by pjw »

Try PVAL


Per
dont be happy. worry
- ?
User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: EasyPTR query

Post 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


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Derek_Stewart
Font of All Knowledge
Posts: 3928
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: EasyPTR query

Post 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.


Regards,

Derek
User avatar
JonS
Bent Pin Expansion Port
Posts: 76
Joined: Fri Nov 11, 2011 3:54 pm
Location: Cumbria

Re: EasyPTR query

Post 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.


User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: EasyPTR query

Post 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)


Per
dont be happy. worry
- ?
User avatar
dilwyn
Mr QL
Posts: 2753
Joined: Wed Dec 01, 2010 10:39 pm

Re: EasyPTR query

Post 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


User avatar
JonS
Bent Pin Expansion Port
Posts: 76
Joined: Fri Nov 11, 2011 3:54 pm
Location: Cumbria

Re: EasyPTR query

Post 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


User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: EasyPTR query

Post 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


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
JonS
Bent Pin Expansion Port
Posts: 76
Joined: Fri Nov 11, 2011 3:54 pm
Location: Cumbria

Re: EasyPTR query

Post 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.


Post Reply