Jump to content

Macintosh Toolbox programming questions


Recommended Posts

Having worked as an intern at Apple in the late ‘90s where part of my job was writing example code (for OpenDoc, but never mind that), sadly, I would not necessarily have complete faith that Apple’s example code is sacrosanct. :) 

 

If you can provide your entire source code somewhere, I would be happy to browse it more carefully.

 

Good point, yes, since you’re writing a code resource, THINK C’s debugger won’t help.  You’d want to use Macsbug.  In Macsbug, once your control strip loads, I would hit the interrupt switch and enter “ATB _ControlStripDispatch”.  This should break any time a control strip call Iike SBTrackSlider() is called.  Then, mouse down on your slider, “S” to step into the SBTrackSlider code, and see what’s going on in there and exactly what got passed to it on the stack.   You’d need to learn a bit of 68k assembly to be able to follow along if you haven’t already.  Apple’s original Macsbug Reference and Debugging Guide is terrific and may tell you most of what you’d need to know.

Link to post
Share on other sites
Posted (edited)

Wow, cool to hear that you worked at Apple in the 90's! Must have been fascinating.

 

Well… all I can do at this point is trust the examples provided :) although I try my best to fully understand how they work.

 

Thank you for the instructions on Macsbug. Very helpful, once I get started with it (have yet to install it :)). I'm a little bit familiar with assembly and the inner workings of CPU's in general (on a broad level – haven't done any actual coding), so that shouldn't be too difficult to learn I think.

 

I included the full project in my post earlier ;)

 

Thank you for helping out!

Edited by PB170
Link to post
Share on other sites

Sorry had missed that - just looked at your code now.

 

I see that sliderSetting is indeed not initialized anywhere and that feels quite problematic to me, would suggest triple-checking that this problem indeed recurs once that's set properly, or even just set to 0 in the SBTrackSlider() call for test purposes.

 

One thing that makes me a bit uncomfortable is in main(), if you somehow get handed NIL in globs on an sdevMouseClick, you don't do any error checking -- you'll call HandleMouseClick with an uninitialized pointer in gb, then pass random stuff to SBTrackSlider().  I realize that feels unlikely and is probably not what's happening, but I would add an error check there and alert/fail gracefully somehow if that happens.

Link to post
Share on other sites

Like I said, I just missed it when I went back to Apple's example for my post here – it's been initialized properly throughout all my tests :) It's initialized to 0 during the initialization call to the module after the global variables are allocated.

 

Regarding the globals, is this level of error checking necessary? Isn't it enough to check if the allocation was successful, like it's done in the program, as long as the values are initialized properly?

 

Would you mind having a look at what happens when SBTrackSlider() is called while the code is running? If so, I can upload a version with the proper initialization included. Otherwise, I guess this could be a good point for me to get familiar with Macsbug :) (Though I still lean towards this being a bug in the Control Strip software.)

 

By the way, I have had the initial value for the slider continuously set to 0 during all of my testing, since the slider won't appear when the value is less than 0.

Link to post
Share on other sites

Yeah I can probably try to debug it this weekend.

 

Personally when writing a CODE resource that's handed a pointer when the system invokes it, I would always check to ensure it's not NIL before dereferencing it just in case something weird happened somewhere outside my code (or in case I allocated it in my Init... routine but then forgot to return it in some edge cases, or something!), just to prevent having to chase down weird cases where my variables hold random nonsense.  Again though I think it's unlikely this is happening.

Edited by Crutch
Link to post
Share on other sites
Posted (edited)

Oh, it's buggy alright :) After having a first look at MacsBug, I played around a bit with a version of the control strip module that sets the initial value to "0" if the previously returned value is out of range (not using of MacsBug at this point) and discovered that if the module is just clicked on very quickly (without bringing up the slider (not possible every time) ), it returns the value "2". After that the slider works properly one time (positive values in the range specified). Bringing the slider up again a second time (now with a positive value passed as the initial value) makes the handle on the slider appear outside of the slider (makes sense, I guess…). Setting it to a new value makes it go back to negative values. However, if no new setting is made, the value returned appears to decrease by 2 and 3 alternately for each click, until it reaches "0". That is, unless the starting value is odd, in which case it appears to decrease by 4 the first time…

 

Also, if it's clicked on again after "2" is returned, it returns "−1" and then does so for all of the following clicks.

 

All of this seem to occur only when the initial value is positive.

 

Getting around this would involve patching the Control Strip software, I imagine. So odd that this bug isn't mentioned anywhere in the developer documentation… Surely, I can't be the first one to try out the slider function…?

 

Here's a version of the module that displays the value of the sliderSetting variable in place of the icon in Apple's example, and works as described above.

Module2.sit

Edited by PB170
Link to post
Share on other sites
16 hours ago, PB170 said:

Oh, it's buggy alright :) After having a first look at MacsBug, I played around a bit with a version of the control strip module that sets the initial value to "0" if the previously returned value is out of range (not using of MacsBug at this point) and discovered that if the module is just clicked on very quickly (without bringing up the slider (not possible every time) ), it returns the value "2". After that the slider works properly one time (positive values in the range specified). Bringing the slider up again a second time (now with a positive value passed as the initial value) makes the handle on the slider appear outside of the slider (makes sense, I guess…). Setting it to a new value makes it go back to negative values. However, if no new setting is made, the value returned appears to decrease by 2 and 3 alternately for each click, until it reaches "0". That is, unless the starting value is odd, in which case it appears to decrease by 4 the first time…

 

Also, if it's clicked on again after "2" is returned, it returns "−1" and then does so for all of the following clicks.

 

All of this seem to occur only when the initial value is positive.

 

Getting around this would involve patching the Control Strip software, I imagine. So odd that this bug isn't mentioned anywhere in the developer documentation… Surely, I can't be the first one to try out the slider function…?

 

Here's a version of the module that displays the value of the sliderSetting variable in place of the icon in Apple's example, and works as described above.

Module2.sit

Would be fun to raise a ticket at Apples support site and report this as a software bug :lol:

Interesting to see if there is anyone left with a sense of humour at Apple or if all those guys are retired by now..

 

Anyway, keep reporting! It's a very interesting and fun read 8-)

Link to post
Share on other sites
17 hours ago, John_A said:

Would be fun to raise a ticket at Apples support site and report this as a software bug :lol:

Interesting to see if there is anyone left with a sense of humour at Apple or if all those guys are retired by now..

 

Anyway, keep reporting! It's a very interesting and fun read 8-)

Haha :lol: Well, while I like the thought of it, the company that brags about having having 90-ish percent of their users on their latest OS and do all they can get away with to improve that number, would probably ditch bug reports about anything older than the second latest version unless it's critical. And you know, if it's humor, it's got to be market oriented. :wink: Anyone with any thoughts about the the past in their head are probably not retired, but fired :) But maybe I'm being too pessimistic.

 

Anyway, glad to hear you enjoy the thread! I had a feeling maybe it was getting a bit too specific to be of general interest :)

Link to post
Share on other sites

It looks like my suspicion was correct and your statusRect is somehow getting nuked. SBTrackControl has no idea what to do with the nonsense Rect so pukes back a negative value. Here’s the statusRect Macsbug shows you passing in. I got this by noticing that you are putting the Rect at an offset of $000C to A6 on the stack for SBTrackControl, and doing “DM A6+C Rect” in Macsbug. I’ll look at your code again later and try to figure out what’s causing this. 
 

62D25396-DF2B-49FF-BDE4-AAEA24BFEA0E.jpeg

Link to post
Share on other sites

OK I'm pretty sure the problem is in this weird implementation of DrawCurrentIcon.  Is this really Apple sample code?

 

This writes over the statusRect that was passed in by MacOS.  That seems weird.  I think this code should allocate a new Rect on the stack, set its coordinates, and call PlotIconSuite/DrawPicture with that.  What happens if you try your control strip module with all the lines after "arrowHeight = ..." commented out?  I think you should avoid every modifying the statusRect that gets passed in by the system and if you need to draw things elsewhere, set up a separate Rect on the stack or that.

 

From the Macsbug screen above, it looks like statusRect->top is good, and everything else is nonsense.  When I run this multiple times, statusRect->left and bottom are random nonsense values; statusRect->right is always -256.

Quote

 

void DrawCurrentIcon(Globals *gb, Rect *statusRect) {
    short            arrowHeight;

//    draw the current icon

    statusRect->right = statusRect->left + IconWidth;
    (void) PlotIconSuite(statusRect, atNone, ttNone, gb->lastIcon);

//    draw an ‘up arrow’ to show that the module has a popup menu

    arrowHeight = (**gb->popupArrowPicture).picFrame.bottom - (**gb->popupArrowPicture).picFrame.top;
    statusRect->left = statusRect->right;
    statusRect->right += (**gb->popupArrowPicture).picFrame.right - (**gb->popupArrowPicture).picFrame.left;
    statusRect->top = (statusRect->top + statusRect->bottom - arrowHeight) >> 1;
    statusRect->bottom = statusRect->top + arrowHeight;
    DrawPicture(gb->popupArrowPicture, statusRect);
}

 

 

Link to post
Share on other sites

Typo in the Macsbug command above, should have been "DM (A6+C)^ Rect" with the caret.

 

Anyway, pretty sure that was the issue.  I rebuilt your sdev with the attached code that just manipulated a new Rect on the stack instead of messing with the one pointed to by statusRect.  Seems to work in my tests?

 

Hope this helps!

ControlStripSample.c

Link to post
Share on other sites
Posted (edited)

Huge thanks for your effort and for looking into it!

 

Interesting to read about the results of your test. At first it felt like great news if the error was indeed in the code and easily fixed. However… when trying it out on my machine, the updated code doesn't change anything :( Very confusing this …

 

The code is indeed Apple's sample code. Moreover, it seems to work just fine on my setup. It appears that the statusRect gets restored with each new call to the module, so changing it in the meantime doesn't seem to do any harm (well, at least not on my machine …).

 

This far I've basically been debugging my code by simply printing any problematic variables out on the screen. Below is a video of a modified version of the module that displays 1) the result from the SBTrackSlider() function as stored in the sliderSetting variable, 2) the values of four members of the statusRect, 3) the ticks value passed to the function 4) another instance of the result from the function, stored in a local variable inside the HandleMouseClick() function (where SBTrackSlider() is called), and 5) a counter that's increased before and after the function, just to keep track of things.

 

The display is updated both before and after the SBTrackSlider() function is called, as well as during update calls to the module (in the DrawCurrentIcon() function). I've added two 1 second delays after the SBTrackSlider() function ends, just to be able to see the update after the function. After the first update/delay, I set all members of the rect variable to 0. As you can see, they revert to the correct values with the next call to the module.

 

Here's a brief description of what you see in the video:
First click: Making a setting on the slider returns a negative value (–131). After the SBTrackSlider() function ends, the statusRect values are all set to 0 in the code, and then immediately restored during the next call to the module.
Second click: Making a new setting returns another negative value. (Since the value of the sliderSetting is out of range after the first call, I reset it to 0 in the code before calling the function to have the menu appear.)
Third click: A quick click (mouse down/up) makes the SBTrackSlider() return the value '2'.
Fourth click: Now, when making a setting on the slider, the value returned is correct.
Fifth click: The value returned from the function is negative again.

 

 

I also activated Macsbug and typed in the commands you used (without understanding exactly what they do or if they are applicable with my setup, at this point), and the result looks all right:

 

Macsbug.jpg.dc6a0b7eb7ddb72f0148eb6fd5aa2807.jpg

 

Any further ideas about what to make of all this…?

 

To me is still seems like the bug is in the Control Strip software, since the module works properly under Mac OS 9, and the few changes I made to the code seem to be okay. But I really have know idea… Very odd that we are getting different results when testing it.

 

I really wish I could get this to work properly.

 

By the way, what setup are you doing your test on?

Edited by PB170
Link to post
Share on other sites
  • 4 months later...

After the lack of success with fixing the slider back in May (@Crutch, or anyone else: if you have any ideas about my post above, feel free to comment), I went back to the less elegant but slightly more functional popup menu instead.

 

I then moved on to develop a second control strip module that displays the system voltage and allows you to see the battery voltage remaining until sleep. Naturally, this led to more issues :) The main obstacle I've encountered is as follows (I'll include a second, minor one, in a separate post after this one):

 

After finishing the module, I thought it would be a natural development to extend its functionality to include other battery types. In short, Apple tackled this by developing additional routines for communicating with the Power Manager indirectly. The problem I have is that they don't seem to be supported on my system (System 7.1.1 / PowerBook 170), while according to Apple's documentation, they should.

 

The PowerBook 520/540 developer note (first PowerBooks with a NiMH battery) and the PowerBook 5300 developer note (first Powerbook with a LiIon battery) mentions:

"Starting with the Macintosh PowerBook 520 and 540 computers, the system software includes interface routines for program access to the Power Manager functions, so it is no longer necessary for applications to deal directly with the Power Manager’s data structures."

 

From what I can tell, the PowerBook 520/540 shipped with System 7.1/7.1.1.

 

The developer note, as well as Apple's documentation for the Power Manager also includes the following code for checking if the dispatch routines exist:
 

long   pmgrAttributes;
Boolean routinesExist;

routinesExist = false;
if (! Gestalt(gestaltPowerMgrAttr, &pmgrAttributes))
    if (pmgrAttributes & (1<<gestaltPMgrDispatchExists))
        routinesExist = true;

 

However, when I run this under System 7.1.1 on my PowerBook 170, the check fails. Same thing with System 7.5 under emulation. Only with Mac OS 9 (on my PowerMac G4 Quicksilver) do I get a positive result.

 

Moreover, the definition of gestaltPMgrDispatchExists (4) is not supported under Think C 5. According to my research, it is included in the header file Gestalt.h, which replaces the earlier version called GestaltEqu.h. Unfortunately, all versions of Think C up to and including version 7 use the old header file, and presumable also don't include support for the new routines.

 

I guess it would be possible to get around the lack of support in Think C by using direct references to the power manager dispatch routines (not exactly sure about how to do that, but the function I'm interested in (GetBatteryVoltage) is listed with the routine selector $1B), but that would of course only work if the system software itself supports them.

 

Anyone here who can shine some light on this issue?

 

In return, I could share a nifty control strip module for checking the system voltage :)

 

Voltage_CSM_1.jpg

 

Voltage_CSM_2.jpg

Edited by PB170
Link to post
Share on other sites

(Part 2 of the post above)

 

A second issue that I encountered (and was able to work around) while developing the module is the following:

 

When I moved over to work the voltage module, a need to deal with floating point numbers emerged. My first idea was to use the standard C functions. However, it turns out that all C functions dealing with floating point numbers are unsupported when developing non-applications in Think C. Bummer.

 

Okay, surely then, there must be some useful toolbox function to do this (specifically, convert floating point numbers to text strings). When looking into Apple's documentation, I found the following:
 

Quote

If you are working with floating-point numbers, or if you want to accommodate the possible differences in output formats for numbers in different countries and regions of the world, you need to work with number format specification strings. […] To use number format specification strings and convert numbers, you need to follow these steps:

 

1. You first define the format of numbers with a number format specification string. An example of such a string is ###,###.##;-###,###.##;0. This string specifies three number formats: for positive number values, for negative number values, and for zero values. The section "Using Number Format Specification Strings," which begins on page 5-39, describes these definitions in detail.

 

2. You must also define the syntactic components of numeric string formats using a number parts table. This table is part of the tokens ('itl4') resource for each script system. It includes definitions of which characters are used in numeric strings for displaying the percent sign, the minus sign, the decimal separator, the less than or equal sign, and other symbols. The number parts table is described with the tokens resource in the appendix "International Resources" in this book.

 

3. You then use Text Utilities routines to convert the number format specification string into an internal representation that is stored in a NumFormatStringRec record. This is a private data type that is used by the number conversion routines. You convert a number format specification string into a NumFormatStringRec record with the StringToFormatRec function, and you perform the opposite conversion with the FormatRecToString function. Both of these functions are described in the section "Converting Number Format Specification Strings Into Internal Numeric Representations," which begins on page 5-43.

 

4. Once you have a NumFormatStringRec record that defines the format of numbers for a certain country or region, you can convert floating-point numbers into numeric strings and numeric strings into floating-point numbers. The StringToExtended and ExtendedToString functions perform these conversions; these are described in the section "Using Number Format Specification Strings," which begins on page 5-39.

 

 

Needless to say, I developed my own function for the conversion.

 

I can see the that this amount of flexibility could be useful when developing more advanced applications, but when just performing simple conversions, I would have imagined that the system functions would just use whatever numerical format was specified in the Numbers control panel.

 

Is this convoluted method really the only way Apple provided for converting simple floating point numbers to strings?

Link to post
Share on other sites

Hi @PB170, first of all I’m sorry I never noticed the above updates back in May, I remember recently wondering if this ever worked out for you.  It definitely feels like there is some weird bugginess in the Control Strip software.  (I was running tests on my PowerBook 550c running 7.5.5 and THINK C 6.)

 

I haven’t really done development with PowerBook-specific things much and don’t know much about the Power Manager.  Is it possible it lives in the PowerBook system extension?  Do you have that?

 

I would have normally used the SANE function num2str() to convert a float to a string (#include <SANE.h>).  Is that also not available from a non-application?

 

Based on this description http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/Devices/Devices-291.html here’s how you could call PowerMgrDispatch from C (I haven’t tried running this, typos possible).  As you point out, this solves the problem of THINK C not having the relevant headers/glue, but you still need the routine to exist:

 

long voltage;

asm {
    move.l 0x0000001b, d0     // hi word is battery number (here, 0), low word is routine selector 0x1b
    dc.w 0xA09E                // _PowerMgrDispatch
    move.l d0, voltage
}

 

You should first check if A09E is a valid trap like this:

#include <Traps.h>
...
Boolean trapExists = (NGetTrapAddress(0xA09E, OSTrap) != NGetTrapAddress(_Unimplemented, ToolTrap));

 

Edited by Crutch
Link to post
Share on other sites

No problem! We all help each other voluntarily here so I'm thankful for any response I get. I'm constantly surprised by all the great feedback. When I doubt that I will get any response at all, I get great replies like this. (There is however another open question that I would be happy to get a response to, but I'll get back to that later :))

 

Checking for the existence of the trap with the code you shared returns a negative result. (I assume this basically accomplishes the same thing as the Gestalt() method I included in my post above?)

 

I do have all the relevant extensions installed. I also tried installing a version of System 7.1.1 specifically for the PowerBook 520/540 under emulation, but that didn't change anything.

 

While the available documentation indicates that the dispatch routines are a part of the system software, I suspect that they're actually tied to, or a part of the power manager hardware itself. I found the following piece of information online which seems to support that. I don't own any other PowerBooks so that makes further development difficult :(

 

(excerpt from: http://www.rgaros.nl/gestalt/chapters/ch-09.html)

Quote

powr (System [6.0.4])
     gestaltPowerMgrAttr
     Returns information about the Power Manager, if present.

 

     enum {
     #define gestaltPowerMgrAttr 'powr' /* Power Mgr attributes */
     gestaltPMgrExists         = 0,  /* Power Mgr is present */
     gestaltPMgrCPUIdle        = 1,  /* CPU can idle */
     gestaltPMgrSCC            = 2,  /* can stop SCC clock */
     gestaltPMgrSound          = 3,  /* can shut off sound circuits */
     gestaltPMgrDispatchExists = 4,  /* dispatch routines are present */
     gestaltPMgrSupportsAVPowerStateAtSleepWake = 5}; /* &AS28 */

 

     NOTE:
     Bit 4 seen set on Power Macs (starting with System 7.5.2?)
     This is because some desktop machines support the Power Manager for
     things like Energy Star compliance.
(Two anonymous contributors)

 

     See also the 'pwrv' selector.

 

 

 

By the way, I discovered that the PowerBook 520/540 developer note includes a listing of a sample header file for the dispatch routines at the end. In it, the following glue code is listed for the GetBatteryVoltage() function:

 

Fixed GetBatteryVoltage(short whichBattery)
= {0x4840, 0x303C, 0x001B, 0xA09E};

 

This was the type of code I had I mind when I mentioned directly referencing the dispatch routines. However, while I have a broad understanding of assembly language, I don't understand how the syntax works here. How is it used, and what information is required within the curly braces?

 

 

I wasn't aware of the existence of the SANE library (though I have a feeling I've come across the acronym somewhere). I haven't seen it mentioned anywhere in Inside Macintosh or in the literature I've been reading. Thanks for introducing me to it. What's the syntax for the num2str() function?

 

 

Ps. Curiously, in newer versions of the Traps.h header file (including the one that comes with Think C 7), under the "Power Manager" section, there is a routine called _PowerDispatch located at 0xA09F. Very close to 0xA09E, but probably a completely different thing. Also, in even newer versions, where _PowerMgrDispatch is included, it (_PowerMgrDispatch) is listed together with _ControlStripDispatch, separate from the rest of the Power Manager traps.

Link to post
Share on other sites

Just a quick side question here :) (main post above)

 

As a side project, I just started making some modifications to the MacCalendar calendar module that comes with the Control Strip development kit, to make it more visually pleasing (have been using it for many years but don't really like how it looks).

 

One change I'd like to make is to replace the custom window design (a plainDBox with an extra frame drawn inside it) with the standard popup menu design. I thought an altDBoxProc (plain box with shadow) would fix this, but it draws a large two pixel shadow instead of the one pixel shadow that all standard menus and windows have.

 

So, how do I make a window with a one pixel shadow? Or is this some sort of custom design despite being applied all over the system? (I see that the offset for the shadows vary between windows — document windows have a one pixel offset, drop down menus three pixels, and the popup menus in the control strip seem to have an offset of either one or three pixels).

Link to post
Share on other sites

Lots of great stuff up there.  I will respond to what I can offhand!

 

Yeah SANE (the Standard Apple Numerics Environment) was always a weird beast that was only a pseudo-official member of the Mac standard libraries in terms of documentation. I’m not sure why. It’s documented in the Apple Numerics Handbook, not IM.  Try here:  https://vintageapple.org/inside_o/pdf/Apple_Numerics_Manual_Second_Edition_1988.pdf

 

In THINK C 6, you can find it in SANE.h in the “THINK #includes” directory.

 

Menus, including popup menus, aren’t actually windows at all in classic Mac OS.  The Menu Manager draws them itself.  If you want a popup-menu-like thing that vanishes when you release the mouse, I would draw it directly to the screen probably.  Save what’s under it first by copying it to an offscreen PixMap with _CopyBits, and restore it later (this is what _MenuSelect and _PopUpMenuSelect do).

 

Yes, if you want to just specifically check for one particular trap, the code I wrote is the easiest way.  If you want to check for a whole collection of features, like the Power Manager, you are better off using Gestalt (but then you have to check for Gestalt if you want to run on older systems - but you probably don’t need to bother in a Control Strip module).

 

The syntax used in your GetBatteryVoltage() example is literally just telling the compiler to use that exact 8-byte chunk of machine code whenever you call GetBatteryVoltage().  If you want to know what assembly instructions that corresponds to, I would write a little application that calls that routine, put a call to _Debugger at the start of it to drop into Macsbug, then type “IL” (instruction list) to see how Macsbug disassembles the following few instructions.  It’s going to look very similar to the asm{...} block I wrote above, you can see it does a couple things than calls 0xA09E.

 

Link to post
Share on other sites
  • 2 weeks later...

Thanks for the reply! Sorry for the late response on my part.

 

I didn't assume that menus are windows. However, the popup menu in the calendar module is implemented as a window, and I just thought it would make sense if the altDBoxProc (plain box with shadow) had the same type of shadow as all standard windows and menus. What would be the best way to create a plainDBox type window with a standard 1 pixel shadow? Just getting the window's coordinates and manually draw the lines? Or is there a more appropriate way of doing it?

 

On a related note, I'm also interested in creating a slider (such as the volume slider in the sound control panel (or the vertical one in the control strip)) as well as a palette window (such as the ones used in ClarisWorks, Photoshop etc.). However, I haven't been able to find any information about how to create any of them in any of Apple's documentation. Are they not part of the system/Toolbox? Is not, is there some sample code for creating them available elsewhere?

Link to post
Share on other sites

If you literally want a window that looks like that, I think you will need to create a custom Window Definition Function (WDEF).  That would certainly be the “correct” way.

 

If you are only going to use it as a popup menu, though, I wouldn’t bother.  I would use CopyBits() to grab whatever’s on the screen there, then draw a nicely drop-shadowed rectangle straight to the screen with QuickDraw.  Then track the mouse until it’s released.  When done, just use CopyBits() again to put back whatever was supposed to be there originally.  (Again, this is what the Menu Manager itself does in _MenuSelect.)

 

I am not aware that sliders were ever added to the Toolbox, I think those were always done with custom CDEFs.  Same with pallete windows, as far as I know.  (Maybe they were added much later?  Certainly they weren’t part of the Toolbox in the earlier generations of System 7 or before, anyway.  I stopped paying as close attention circa 1994.)  However there is a terrific & comprehensive treatment of pallete windows (including the tricky part, making them “float” over other active windows) and extending them into HyperCard-style tear-off menus in MacTutor volume 4, number 4:  “Tear-Off Menus & Floating Palettes” by Don Melton and Mike Ritter of Impulse Technologies (maker of the famed Impulse Audio Digitizer, by the way, one of which I had in the ‘80s).  A quick Google failed to turn off the full text of that article online (but it probably exists somewhere on MacTech’s website—I have a hard copy), but I did find that follow on that might explain how to do it:  http://preserve.mactech.com/articles/mactech/Vol.04/04.12/ToolWindow/index.html

 

Warning—implementing using the Melton-Ritter approach is a fairly major project!

 

It looks like Apple blessed their approach later in a Technical Note:  https://www.fenestrated.net/mac/mirrors/Apple Technotes (As of 2002)/tb/tb_575.html

 

While Googling around on this topic, I stumbled on this which suggests Symantec added some support for these in TCL, but I never used this:  http://preserve.mactech.com/articles/mactech/Vol.09/09.02/TearOffTCL/index.html

 

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...