Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
CalcControlRgn.c
/* |
File: Calc ControlRgn.c |
Contains: This sample shows how to call a CDEF to get the control's Region. |
Written by: Matthew Xavier Mora |
Copyright: Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/19/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
02-28-96 mxm added more comments and error checking |
05-07-96 mxm got it ready for the cd |
*/ |
#include <Resources.h> |
#include <Errors.h> |
#include <Windows.h> |
#include "SAL_Public.h" |
#define kPaintRegionOffset ( 200 ) |
#define kNoOffset ( 0 ) |
#define kNextButtonOffset ( 50 ) |
#define kScrollBarFudge ( 15 ) |
#define kMemorySystemErrMsg "\pMemory Manager error" |
#define kOurWindowTitle "\pCalculate a Control's Region Sample" |
#define kBadThingsMsg "\pBad things happened" |
pascal SInt16 DoButtonHit(ButtonItemRef me, SInt32 modifiers); |
//------------------------------------------------------------------------- |
// This function checks MemError and reports any errors returned |
//------------------------------------------------------------------------- |
static OSErr CheckMemoryError(void) |
//------------------------------------------------------------------------- |
{ |
OSErr err; |
err = MemError(); |
if (err) { |
SAL_ErrorMessage(kMemorySystemErrMsg,err,kSAL_NonFatalError); |
} |
return err; |
} |
//------------------------------------------------------------------------- |
// A utility routine to lock a Handle and report any errors. It returns the |
// the state of the handle before it was locked so you can reset the handle |
// to its original state. |
//------------------------------------------------------------------------- |
static OSErr MyLockHandle(Handle theHandle,SInt8 * state) |
//------------------------------------------------------------------------- |
{ |
OSErr err = noErr; |
SInt8 tempState; |
tempState = HGetState(theHandle); // remember the state |
err = CheckMemoryError(); // alert the user if error |
if (err == noErr) { |
HLock(theHandle); |
err = CheckMemoryError(); |
} |
if (state) { |
*state = tempState; |
} |
return err; |
} |
//------------------------------------------------------------------------- |
// A utility routine to Set a Handle state and report any errors. |
//------------------------------------------------------------------------- |
static OSErr MySetHandleState(Handle theHandle,SInt8 state) |
//------------------------------------------------------------------------- |
{ |
OSErr err = noErr; |
HSetState(theHandle,state); // remember the state |
err = CheckMemoryError(); // report any errors |
return err; // return error |
} |
//------------------------------------------------------------------------- |
// GetControlRgn takes a control handle and an existing Rgn |
// as parameters and will return in the control's rgn |
//------------------------------------------------------------------------- |
pascal OSStatus GetControlRegion(ControlHandle ch,ControlPartCode inPart,RgnHandle theRgn) |
//------------------------------------------------------------------------- |
{ |
#pragma unused(inPart) |
Handle cdefHandle; // Handle to the control Proc |
SInt16 errorState = noErr ; // preset error state |
if ( (ch != nil) && (theRgn != nil) ) { // make sure we have a control and Rgn |
cdefHandle = (**ch).contrlDefProc; // Get the control's Handle |
if (!*cdefHandle) { // lets load it in if its not |
LoadResource(cdefHandle); |
errorState = ResError(); // check for error |
} |
if ((*cdefHandle) != nil && errorState == noErr ) { // all is well |
SInt8 state ; // holding place for handle state |
errorState = MyLockHandle(cdefHandle,&state); |
if (errorState == noErr) { |
UInt32 result; // the result we don't care about |
ControlDefUPP myControlUPP; // Holding place for the CDEF ProcPtr or UPP |
// |
myControlUPP = (ControlDefUPP)(*cdefHandle); |
// What? Casting to a UPP? Are you crazy? |
// The reason you cast in instead of creating a UPP |
// is that it may already be a UPP (ie native CDEF) |
// and dual UPP's would really confuse Mixed Mode. If its not |
// a upp, CallControlDefProc does the right thing by passing a |
// a valid ProcInfo to CallUniversalProc which makes |
// mixed mode a happy camper in any case. |
result = CallControlDefProc(myControlUPP, |
GetControlVariant(ch), |
ch, |
calcCntlRgn, |
(SInt32)theRgn); |
errorState = MySetHandleState(cdefHandle,state); // reset the handle state |
} |
} |
} else { // ControlHandle or theRgn is nil |
errorState = nilHandleErr; // set the error |
} |
return (errorState); // be sure and return any errors |
} |
//------------------------------------------------------------------------- |
// Simple routine to paint the region we get from the Control |
//------------------------------------------------------------------------- |
static OSErr DisplayControlRgn(ControlHandle ch) |
//------------------------------------------------------------------------- |
{ |
RgnHandle theRgn; |
SInt16 err = noErr; |
theRgn = NewRgn(); // Get a region to work with |
if (theRgn) { |
err = GetControlRegion(ch,0,theRgn); // Get the Button's Region |
if (err == noErr){ |
OffsetRgn(theRgn,kPaintRegionOffset,kNoOffset); |
PaintRgn(theRgn); |
DisposeRgn(theRgn); |
} else { |
err = CheckMemoryError(); |
} |
} |
return (err); |
} |
//------------------------------------------------------------------------- |
// This gets called when the Click Me button is clicked. |
// ------------------------------------------------------------------------ |
// Note! |
// There is a problem with global optimization and call back functions. |
// If you want global optimization on for the rest of your code you |
// should turn it off for any call back functions unless MW has released |
// a fix. i.e #pragma optimization_level 1 |
//------------------------------------------------------------------------- |
static pascal short DoButtonHit(const ButtonItemRef me,const long modifiers) |
//------------------------------------------------------------------------- |
{ |
#pragma unused (modifiers) |
ControlHandle cr = nil; |
OSErr err = noErr; |
cr = (ControlHandle) SAL_GetObjectHandle((SInt32) me); |
if (cr) { |
err = DisplayControlRgn(cr); |
if (err != noErr) { |
SAL_ErrorMessage(kBadThingsMsg,err,kSAL_NonFatalError); |
} |
} |
return err; |
} |
//------------------------------------------------------------------------- |
// This gets called when the Clear button is clicked. |
//------------------------------------------------------------------------- |
static pascal SInt16 DoClear(const ButtonItemRef me,const SInt32 modifiers) |
//------------------------------------------------------------------------- |
{ |
#pragma unused (modifiers) |
#pragma unused (me) |
Rect r; |
r = gSAL_CurrentWindow->portRect; // Get the window's portRect |
r.left += kPaintRegionOffset; // offset so it doesn't erase |
r.right -= kScrollBarFudge; // our buttons and scroll bar |
r.bottom -= kScrollBarFudge; // areas |
InvalRect(&r); |
return noErr; |
} |
//------------------------------------------------------------------------- |
// This is the main function. Note how simple it is. It installs |
// two Buttons and then lets SimpleApp handle the rest. |
// |
//------------------------------------------------------------------------- |
void main(void) |
//------------------------------------------------------------------------- |
{ |
Rect r; |
SInt16 gMyWindowID; |
SInt16 err; |
SAL_InitSimpleApp(1,kSAL_UseStandardMenu); // Simple App Sets up the Tool Box For us |
gMyWindowID = SAL_GetDocumentWindow(128,nil); // Get our stored window |
// the global gSAL_CurrentWindow is maintained |
// by SimpleApp and it contains the active |
// document window reference |
SetWTitle(gSAL_CurrentWindow,kOurWindowTitle);// set the window title so we know what we are running |
SetRect(&r,10,30,100,50); // set the control bounds |
err = SAL_InstallPushButton (0, // Reference ID (we don't care) |
gSAL_CurrentWindow, // Owner Window |
"\pClick Me", // Name |
&r, // Bounds |
kSAL_NoCommandKey, // Command Key |
DoButtonHit , // Button Hit |
nil // Button Update Proc |
); |
OffsetRect(&r,kNoOffset,kNextButtonOffset); |
err = SAL_InstallPushButton (0, // Reference ID (we don't care) |
gSAL_CurrentWindow, // Owner Window |
"\pClear", // Name |
&r, // Bounds |
kSAL_NoCommandKey, // Command Key |
DoClear , // Button Hit Proc |
nil // Button Update Proc |
); |
SAL_Run(); // Let SimpleApp handle the rest |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-30