Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Advanced Color Imaging on the Mac OS /
Chapter 2 - Color Picker Manager / Writing Your Own Color Pickers


Initializing Your Color Picker

The Color Picker Manager sends the kInitPicker request code after your color picker has set up all of its external data. (If the Color Picker Manager opens a color picker only to obtain a list of color pickers for the More Choices list in a dialog box, your color picker will not receive this message unless the user actually chooses the color picker.)

Your color picker code should use the CallComponentFunctionWithStorage function, which invokes a specified function of your color picker with the parameters originally provided by the Color Picker Manager. Your color picker passes these parameters by specifying the same component parameters structure that was received by your color picker's main entry point. The CallComponentFunctionWithStorage function also provides a handle to the memory associated with the current connection. Your color picker uses this memory to store private data that it initializes in response to the kInitPicker request code.

To access resources that are stored in your color picker, you can use the Component Manager functions OpenComponentResFile and CloseComponentResFile. Listing 2-17 illustrates how a color picker uses these functions to gain access to its private data, which it initializes in response to the kInitPicker request code.

Listing 2-17 Initializing private data for a color picker

pascal ComponentResult MyInitPicker(PickerStorageHndl storage,
                           PickerInitData *data)
{
   GrafPtr     thePort;
   OSErr       error = noErr;
   PMColorPtr  theColor;
   RGBColor    rgb;
   short       resFile;

   /* open resource file */
   resFile = OpenComponentResFile((Component) (*storage)->myself);
   GetPort(&thePort);
   (*storage)->port = thePort;
   (*storage)->flags = data->flags;
   (*storage)->realPicker = true;
   /* always open an invisible picker */
   (*storage)->visible = false;
   (*storage)->active = true;
   /* initalize internal colors */
   theColor = &(*storage)->color;
   theColor->profile = 0;
   theColor->color.rgb.red = 0;
   theColor->color.rgb.green = 0;
   theColor->color.rgb.blue = 0;
   (*storage)->origColor = (*storage)->color;
   (*storage)->lastRGB = (*storage)->color.color.rgb;
   MyInitNumerics(storage);
   /* allocate patterns for the color rectangles */
   (*storage)->newColorPat = NewPixPat();
   (*storage)->origColorPat = NewPixPat();
   /* initialize rectangles to the correct colors */
   rgb = (*storage)->color.color.rgb;
   MakeRGBPat((*storage)->newColorPat,&rgb);
   rgb = (*storage)->origColor.color.rgb;
   MakeRGBPat((*storage)->origColorPat,&rgb);
   (*storage)->profile = 0L;
   finish:
   CloseComponentResFile(resFile);
   return error;
}
WARNING
Do not leave any resource files open when your color picker is closed. Their maps will be left in the subheap when the subheap is freed, causing the Resource Manager to crash.
Before handling the kInitPicker request code, your color picker must be able to handle the kTestGraphicsWorld, kGetDialog, and kGetItemList request codes.

In response to the kTestGraphicsWorld request code, you should test whether your color picker can operate under existing conditions and return noErr if it can, as illustrated in Listing 2-18.

Listing 2-18 Testing whether an environment can support your color picker

pascal ComponentResult MyTestGraphicsWorld(PickerStorageHndl storage,
                                 PickerInitData *data)
{
   #pragma unused(storage,data)
   OSErr err = noErr;
   long gLong;
   /* color picker requires Color QuickDraw */
   Gestalt(gestaltQuickdrawVersion,&gLong);
   return gLong >= gestalt8BitQD ? noErr : pickerCantLive;
}
If your color picker uses its own dialog box, it should return a pointer to this dialog box in response to the kGetDialog request code. If your color picker uses the default dialog box, it should return nil, as illustrated here.

   pascal ComponentResult MyGetDialog(PickerStorageHndl storage)
   {
      #pragma unused (storage)
      return 0L;
   }
In response to the kGetItemList request code, your color picker should return its dialog box items, as illustrated in Listing 2-19. The Color Picker Manager adds these items to the color picker dialog box.

Listing 2-19 Returning the dialog box items for a color picker

pascal long MyGetItemList(PickerStorageHndl storage)
{
   #pragma unused (storage)
   Handle theItems;
   short resFile;

   /* open resource file to get DITL */
   resFile = OpenComponentResFile((Component) (*storage)->myself);
   /* get the DITL and detach it so it won't go away after 
      closing the file */
   theItems = GetResource ('DITL', kPickerDITL);
   if(theItems)
      DetachResource(theItems);
   CloseComponentResFile(resFile);  /* close the file */
   return (long) theItems;
}
A color picker must respond to the kSetVisibility request code by making itself either visible or invisible, as requested by the Color Picker Manager.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
13 NOV 1996