[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl-Toolbox] Using an existing window with the Quickdraw



At 6:02 am -0600 23/03/00, David Steffen wrote:

>   Is there any way to use an existing window with QuickDraw?  I know 
>how to create a window using the Toolbox and to get QuickDraw output 
>into that window, but I'm wondering:
>
>1) If you create a window using:
>    open WINDOW, '>Dev:Console:WindowName';
>    ...can you QuickDraw in that?
>
>2) If so, what happens if you:
>    print WINDOW "This is a test\n";
>    ...?

The short answer is 'Yes': with MacPerl-ported QuickDraw functions 
you can draw absolutely anywhere, including the desktop surface 
itself, the menu bar, windows owned by other applications and 
specifically windows created by 'Dev:Console'. Whether it is 
permissible or useful to do so is however quite another matter.

The sequence:

	SetPort(GrafPtr)
	MoveTo(H, V)
	DrawString($tr)

will in all cases draw the string 'Str' at the point 'H, V'. The 
'GrafPtr' record will hold the origin of the local co-ordinates (used 
for V, V) and details of the fonts (used by DrawString).

If the object of the exercise is to draw a string in a specific 
window (be it a MacPerl window or some other application's window) 
the first problem is to get hold of the appropriate GrafPtr. There 
are two functions which can be used:

	(Code, GrafPtr) = FindWindow(Pt)
	(GrafPtr) = FrontWindow()

'FindWindow' is invariably the first function to be called by an 
application after a click. It will generally handle the mouse click 
at location 'Pt' by bringing that window to the front if 'Pt' (in 
global co-ordinates) occurred in one of its windows or ignoring it if 
it did not occur in one of its windows. (Ownership of the window is 
determined by inspecting the GrafPtr.) Behind the scenes the window 
manager looks after re-numbering all the windows on the desktop if a 
new window is brought to the front. From then on the click would be 
handled appropriately by the application according to whereabouts the 
point 'Pt' lay in the window (drag bar, zoom box etc.) indicated by 
'Code'. All of this is true of windows created by MacPerl's 
'Windows.pm'.

'FrontWindow' might be used by an application to check whether the 
window, to which it is about to draw, is at the front or not and 
(maybe) to bring it to the front if it is not. (Alternatively it can 
be used by an application to determine if the window at the front is 
one of its windows or belongs to someone else.)

Armed with a valid GrafPtr, QuickDraw (invoked via MacPerl or 
otherwise) can draw into that window (or more generally the region 
specified by the pointer, which can be even the whole desktop 
spanning several monitors). Generally speaking it would not be useful 
or permissible to do so.

In the first place the Toolbox Windows Manager would almost certainly 
immediately erase the drawing. When the system calls an Update Event 
(which occurs, broadly speaking, when anything happens which could 
alter the screen's appearance), the Window Manager erases what it 
considers to be the 'Update Region'. It is left up to the application 
to re-write its window. Usually an application would re-write the 
whole window (since the application would not necessarily know the 
shape and size of the update region) but the 'screen flicker' is 
restricted to the Update Region. An application can add to the update 
region using InvalRgn() (for instance the two rectangles previously 
occupied by scroll bars after a re-size) if it needs to add something 
the Windows Manager might not know about.

As an instance of an update consider what would happen if 
DrawString() was used to write to a window newly created by MacPerl. 
Firstly the window would be drawn on the desktop and then the string 
would be drawn in the window. Now the system, alert to these changes, 
would promptly call an Update Event. The Windows Manager, failing 
other information, would consider the whole of the contents region of 
the new window to be the Update Region and would therefore erase 
everything in the window. Visually the drawn string would flash 
momentarily in the window and then vanish for ever since there would 
be, in this scenario, no mechanism in place to redraw the string. 
'Windows.pm', however, via the 'redraw' function to which a script 
can be 'hooked', provides the missing mechanism.

So the longer answer to the question "Can you use QuickDraw to draw 
into an [arbitrary] window?" is "Yes, you can do this from MacPerl, 
if you possess a valid GrafPtr and provided you can properly handle 
all subsequent Events (particularly Update Events) generated by the 
system.

More often than not the problem is to _prevent_ QuickDraw drawing 
into the wrong window. For instance it can easily happen that in 
between MacPerl calling SetPort() another application (say BBEdit for 
example) calls SetPort() in response to an update event requiring one 
of its windows to be redrawn. Then, when MacPerl invokes a QuickDraw 
function, it stomps all over the BBEdit window since that is the 
window to which the active graphics port points. It is sometimes 
quite difficult for the programmer to ensure that the active graphics 
port hasn't been surreptitiously changed behind the scenes.

'Windows.pm' is essentially an intricate and highly sophisticated 
Event handling machine. Since Matthias wrote it (three years ago?) I 
don't think an exception to it (in the sense of a situation where it 
either failed to do the right thing or proved inflexible) has ever 
been found and I doubt very much one ever will be. In the MacPerl 
context only the very brave or maybe foolhardy would even contemplate 
sidestepping 'Windows.pm' in favour of a scheme of their own 
devising. The combination of 'Windows.pm' with 'Hooks.pm' and 
'Panes.pm' provides a extraordinarily elegant flexible scripting 
environment with a power that seems at times almost mystical.

HTH,

Alan Fry










==== Want to unsubscribe from this list?
==== Send mail with body "unsubscribe" to macperl-toolbox-request@macperl.org