home *** CD-ROM | disk | FTP | other *** search
- /*
- File: CustomWindow.c
-
- Contains: A sample on how to create a fully functional custom window for Carbon
-
- Written by: Karl Groethe
-
- Copyright: Copyright © 2000 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):
- 6/28/00 created
-
-
- */
- #include "CustomWindow.h"
- #include <Carbon/Carbon.h>
-
- #define kPictureID 128
- #define kMaskPictureID 129
-
- SInt32 myWindowDef(short varCode,WindowRef window, SInt16 message, SInt32 param)
- {
- /*------------------------------------------------------
- This is the main entry point for the Custom Window.
- --------------------------------------------------------*/
- switch(message){
- case kWindowMsgDraw:
- return myWindowDraw(window,param);
- case kWindowMsgHitTest:
- return myWindowHitTest(window,param);
- case kWindowMsgInitialize:
- return myWindowInitialize(window,param);
- case kWindowMsgCleanUp:
- return myWindowCleanUp(window,param);
- case kWindowMsgDrawGrowOutline:
- return myWindowDrawGrowOutline(window,param);
- //8.0 forward
- case kWindowMsgGetFeatures:
- return myWindowGetFeatures(window,param);
- case kWindowMsgGetRegion:
- return myWindowGetRegion(window,param);
- //8.5 forward
- case kWindowMsgDragHilite:
- return myWindowDragHilite(window,param);
- case kWindowMsgModified:
- return myWindowModified(window,param);
- case kWindowMsgDrawInCurrentPort:
- return myWindowDrawInCurrentPort(window,param);
- case kWindowMsgStateChanged:
- return myWindowStateChanged(window,param);
- //carbon only
- case kWindowMsgGetGrowImageRegion:
- return myWindowGetGrowImageRegion(window,param);
- default:
- return 0;
- }
- }
- SInt32 myWindowGetFeatures(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- Define which options your custom window supports.
- --------------------------------------------------------*/
- //just enable everything for our demo
- *(OptionBits*)param=kWindowCanGrow|
- kWindowCanZoom|
- kWindowCanCollapse|
- kWindowCanGetWindowRegion|
- kWindowHasTitleBar|
- kWindowSupportsDragHilite|
- kWindowCanDrawInCurrentPort|
- kWindowCanMeasureTitle|
- kWindowWantsDisposeAtProcessDeath|
- kWindowSupportsSetGrowImageRegion|
- kWindowDefSupportsColorGrafPort;
- return 1;
- }
- SInt32 myWindowDraw(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- Use this method to draw the window based on the value
- of param.
- wNoHit: draw the frame and attributes
- wInGoAway: hilite or unhilite GoAway box
- wInZoomIn: hilite or unhilite ZoomIn Box
- wInZoomOut: hilite or unhilite ZoomOut Box
- wInCollapseBox: hilite or unhilite Collapse Box
- --------------------------------------------------------*/
- static Boolean hilite=FALSE;
- WindowAttributes attributes;
-
- if(IsWindowVisible(window))
- {
- switch(param){
- case wNoHit:
- hilite=FALSE;//redrawn so no box hiliteing
-
- drawWindowFrame(window);
-
- GetWindowAttributes(window,&attributes);
- if(attributes & kWindowCloseBoxAttribute)//is there a close box?
- drawWindowCloseBox(window,hilite);
- if(attributes & kWindowFullZoomAttribute)//is there a zoom box?
- drawWindowZoomBox(window,hilite);
- if(attributes & kWindowCollapseBoxAttribute)//is there a collapse box?
- drawWindowCollapseBox(window,hilite);
-
- break;
- case wInGoAway:
- hilite=drawWindowCloseBox(window,!hilite);
- break;
- case wInZoomIn:
- case wInZoomOut:
- hilite=drawWindowZoomBox(window,!hilite);
- break;
- case wInCollapseBox:
- hilite=drawWindowCollapseBox(window,!hilite);
- break;
- }
- }
- return 0;
- }
-
- RgnHandle getWindowCloseBoxRegion(WindowRef window,RgnHandle closeBoxRegion)
- {
- /*------------------------------------------------------
- Define the region for the close box
- --------------------------------------------------------*/
- SetEmptyRgn(closeBoxRegion);
- return closeBoxRegion;
- }
- RgnHandle getWindowZoomBoxRegion(WindowRef window,RgnHandle zoomBoxRegion)
- {
- /*------------------------------------------------------
- Define the region for the zoom box
- --------------------------------------------------------*/
- SetEmptyRgn(zoomBoxRegion);
- return zoomBoxRegion;
-
- }
- RgnHandle getWindowCollapseBoxRegion(WindowRef window,RgnHandle collapseBoxRegion)
- {
- /*------------------------------------------------------
- Define the region for the collapse box
- --------------------------------------------------------*/
- SetEmptyRgn(collapseBoxRegion);
- return collapseBoxRegion;
- }
- RgnHandle getWindowGrowBoxRegion(WindowRef window,RgnHandle growBoxRegion)
- {
- /*------------------------------------------------------
- Define the region for the Grow Box
- --------------------------------------------------------*/
- SetEmptyRgn(growBoxRegion);
- return growBoxRegion;
- }
- RgnHandle getWindowTitleBarRegion(WindowRef window,RgnHandle titleBarRegion)
- {
- /*------------------------------------------------------
- Define the region for the title bar
- --------------------------------------------------------*/
- SetEmptyRgn(titleBarRegion);
- return titleBarRegion;
- }
- RgnHandle getWindowTitleTextRegion(WindowRef window,RgnHandle titleTextRegion)
- {
- /*------------------------------------------------------
- Define the region for the text in the title bar
- --------------------------------------------------------*/
- SetEmptyRgn(titleTextRegion);
- return titleTextRegion;
- }
- RgnHandle getWindowContentRegion(WindowRef window,RgnHandle contentRegion)
- {
- /*------------------------------------------------------
- Define the content region of our window.
- --------------------------------------------------------*/
- SetEmptyRgn(contentRegion);
- if(!IsWindowCollapsed(window)){
- //only define the content region when the window is
- //not collapsed
- }
-
- return contentRegion;
- }
- RgnHandle getWindowStructureRegion(WindowRef window, RgnHandle structureRegion)
- {
- /*------------------------------------------------------
- Define the structural region of our window.
- --------------------------------------------------------*/
- static RgnHandle pictureRgn=NULL;
- static Rect pictureRect;
- Rect windowRect;
-
- SetEmptyRgn(structureRegion);
-
- if(!pictureRgn){//haven't Cached our region yet
- PicHandle myPicture=GetPicture(kMaskPictureID);
- GrafPtr origPort;
- GDHandle origDev;
- GWorldPtr pictMask;
- PixMapHandle maskBitMap;
- GetGWorld(&origPort,&origDev);
- pictureRgn=NewRgn();
- pictureRect=(*myPicture)->picFrame;
- NewGWorld(&pictMask,1,&pictureRect,NULL,NULL,0);
- maskBitMap=GetPortPixMap(pictMask);
- LockPixels(maskBitMap);
- SetGWorld(pictMask,NULL);
- EraseRect(&pictureRect);
- DrawPicture(myPicture,&pictureRect);
- BitMapToRegion(pictureRgn,(BitMap*)*maskBitMap);//use the mask to create a region
- InsetRgn(pictureRgn,1,1);
- SetGWorld(origPort,origDev);
- UnlockPixels(maskBitMap);
- DisposeGWorld(pictMask);
- ReleaseResource((Handle)myPicture);
- }
- getCurrentPortBounds(&windowRect);//how big is the window
- CopyRgn(pictureRgn,structureRegion);//make a copy of our cached region
- MapRgn(structureRegion,&pictureRect,&windowRect);//scale it to our actual window size
- return structureRegion;
- }
-
- RgnHandle getWindowDragRegion(WindowRef window, RgnHandle dragRegion)
- {
- /*------------------------------------------------------
- Define the drag region of our window.
- --------------------------------------------------------*/
- RgnHandle structureRegion=NewRgn();
- RgnHandle contentRegion=NewRgn();
-
- SetEmptyRgn(dragRegion);
-
- getWindowStructureRegion(window,structureRegion);
- getWindowContentRegion(window,contentRegion);
- //our drag region is the difference between the structural and content regions
- DiffRgn(structureRegion,contentRegion,dragRegion);
-
- DisposeRgn(structureRegion);
- DisposeRgn(contentRegion);
-
- return dragRegion;
- }
- void drawWindowFrame(WindowRef window)
- {
- /*------------------------------------------------------
- Draw the frame of our window.
-
- This function needs to draw the title bar,
- the grow box, the title string and the
- structural aspects of the window.
- --------------------------------------------------------*/
- static GWorldPtr framePict=NULL;
- static Rect pictureRect;
- GrafPtr thePort;
- Rect frame;
-
- if(!framePict){//haven't cached our picture
- PicHandle myPicture=GetPicture(kPictureID);
- GrafPtr origPort;
- GDHandle origDev;
- GetGWorld(&origPort,&origDev);
- pictureRect=(*myPicture)->picFrame;
- NewGWorld(&framePict,0,&pictureRect,NULL,NULL,0);
- SetGWorld(framePict,NULL);
- DrawPicture(myPicture,&pictureRect);
- SetGWorld(origPort,origDev);
- ReleaseResource((Handle)myPicture);
- }
-
- getCurrentPortBounds(&frame);
- GetPort(&thePort);
- CopyBits(GetPortBitMapForCopyBits(framePict),
- GetPortBitMapForCopyBits(thePort),
- &pictureRect,&frame,srcCopy,NULL);//draw our picture
- myWindowDrawGrowBox(window,0);//draw grow box as part of frame
-
- if(IsWindowHilited(window))
- {
- //do any hilighting
- }
-
- }
- Boolean drawWindowCloseBox(WindowRef window, Boolean hilite)
- {
- /*------------------------------------------------------
- This function draws the close box.
- If hilite is true it draws the hiliting as well.
- --------------------------------------------------------*/
- RgnHandle closeBoxRegion=NewRgn();
- getWindowCloseBoxRegion(window,closeBoxRegion);
- EraseRgn(closeBoxRegion);//clear away old
- //draw close box
- if(hilite)
- {
- //do hilighting
- }
- DisposeRgn(closeBoxRegion);
- return hilite;
- }
- Boolean drawWindowZoomBox(WindowRef window, Boolean hilite)
- {
- /*------------------------------------------------------
- This function draws the zoom box.
- If hilite is true it draws the hiliting as well.
- --------------------------------------------------------*/
- RgnHandle zoomBoxRegion=NewRgn();
- getWindowZoomBoxRegion(window,zoomBoxRegion);
- EraseRgn(zoomBoxRegion);//clear away old
- //draw zoom Box
- if(hilite)
- {
- //do hilighting
- }
- DisposeRgn(zoomBoxRegion);
- return hilite;
- }
-
- Boolean drawWindowCollapseBox(WindowRef window, Boolean hilite)
- {
- /*------------------------------------------------------
- This function draws the collapse box.
- If hilite is true it draws the hiliting as well.
- --------------------------------------------------------*/
- RgnHandle collapseBoxRegion=NewRgn();
- getWindowCollapseBoxRegion(window,collapseBoxRegion);
- EraseRgn(collapseBoxRegion);//clear away old stuff
- if(hilite){
- //do hilighting
- }
- DisposeRgn(collapseBoxRegion);
- return hilite;
- }
- RgnHandle getWindowUpdateRegion(WindowRef window, RgnHandle updateRegion)
- {
- return updateRegion;
- }
- SInt32 myWindowHitTest(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- Determine the region of the window which was hit
- --------------------------------------------------------*/
- Point hitPoint;
- static RgnHandle tempRgn=nil;
- if(!tempRgn) tempRgn=NewRgn();
-
- SetPt(&hitPoint,LoWord(param),HiWord(param));//get the point clicked
-
- if(IsWindowHilited(window)){ //make sure the window is in front for these
-
- if(PtInRgn(hitPoint,getWindowGrowBoxRegion(window,tempRgn)))//in GrowBox?
- return wInGrow;
- if(PtInRgn(hitPoint,getWindowCloseBoxRegion(window,tempRgn)))//in the Close Box?
- return wInGoAway;
- if(PtInRgn(hitPoint,getWindowZoomBoxRegion(window,tempRgn)))//in the Zoom Box?
- return wInZoomOut;
-
- //Mac OS 8.0 or later
- if(PtInRgn(hitPoint,getWindowCollapseBoxRegion(window,tempRgn)))//in the Collapse Box?
- return wInCollapseBox;
- }
- //Mac OS 8.5 or later
- if(PtInRgn(hitPoint,getWindowContentRegion(window,tempRgn))) //in window content region?
- return wInContent;
- if(PtInRgn(hitPoint,getWindowDragRegion(window,tempRgn)))//in window drag region?
- return wInDrag;
-
- return wNoHit;//no significant area was hit.
- }
- SInt32 myWindowInitialize(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- perform any initialization for your window here
- --------------------------------------------------------*/
- return 0;
- }
- SInt32 myWindowCleanUp(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- dispose of anything allocated in Initialization
- --------------------------------------------------------*/
- return 0;
- }
- SInt32 myWindowDrawGrowBox(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- This function draws the grow box of the window
- --------------------------------------------------------*/
- RgnHandle growBoxRegion=NewRgn();
- getWindowGrowBoxRegion(window,growBoxRegion);
- //draw grow box here
- return 0;
- }
-
- SInt32 myWindowGetRegion(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- Define each of the window's regions
- --------------------------------------------------------*/
- GetWindowRegionPtr rgnRec=(GetWindowRegionPtr)param;
-
- switch(rgnRec->regionCode){
- case kWindowTitleBarRgn:
- getWindowTitleBarRegion(window,rgnRec->winRgn);
- break;
- case kWindowTitleTextRgn:
- getWindowTitleTextRegion(window,rgnRec->winRgn);
- break;
- case kWindowCloseBoxRgn:
- getWindowCloseBoxRegion(window,rgnRec->winRgn);
- break;
- case kWindowZoomBoxRgn:
- getWindowZoomBoxRegion(window,rgnRec->winRgn);
- break;
- case kWindowDragRgn:
- getWindowDragRegion(window,rgnRec->winRgn);
- break;
- case kWindowGrowRgn:
- getWindowGrowBoxRegion(window,rgnRec->winRgn);
- break;
- case kWindowCollapseBoxRgn:
- getWindowCollapseBoxRegion(window,rgnRec->winRgn);
- break;
- case kWindowStructureRgn:
- getWindowStructureRegion(window,rgnRec->winRgn);
- break;
- case kWindowContentRgn:
- getWindowContentRegion(window,rgnRec->winRgn);
- break;
- //Carbon Forward
- case kWindowUpdateRgn:
- getWindowUpdateRegion(window,rgnRec->winRgn);
- break;
- default:
- return errWindowRegionCodeInvalid;
- }
- return noErr;
- }
- SInt32 myWindowDragHilite(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- Hilight the window to show support for
- drag-and-drop.
- --------------------------------------------------------*/
- if(param){
- //hilite window
- }else{
- //unhilight window
- }
- return 0;
- }
- SInt32 myWindowModified(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- Called when a document's "modified" bit is changed
- --------------------------------------------------------*/
- if(param){
- //document has been modified
- }else{
- //document has been saved
- }
- return 0;
- }
- SInt32 myWindowDrawInCurrentPort(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- same as myWindowDraw but must draw in current port.
- myWindowDraw is defined to draw in the current port
- so just call it directly.
- --------------------------------------------------------*/
- myWindowDraw(window,param);
- return 0;
- }
- SInt32 myWindowStateChanged(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- use this method if you need notification of a state
- change after the internal data has been altered but
- before the window is updated on the screen
- --------------------------------------------------------*/
- if(param & kWindowStateTitleChanged){
- //the Title Has changed
- }
- if(param & kWindowStateSizeChanged){
- //the window size has changed
- }
- if(param & kWindowStatePositionChanged){
- //the window position has changed
- }
- if(param & kWindowStateZOrderChanged){
- //the widow has changed Z order
- }
- if(param & kWindowStateVisibilityChanged){
- //the window has been shown or hidden
- }
- if(param & kWindowStateHiliteChanged){
- //the window has been selected or deselected
- }
- if(param & kWindowStateCollapseChanged){
- //the window has been collapsed or expanded
- }
- return 0;
- }
- SInt32 myWindowDrawGrowOutline(WindowRef window,SInt32 Param)
- {
- /*------------------------------------------------------
- Draw the window's grow outline
- --------------------------------------------------------*/
- return 0;
- }
- SInt32 myWindowGetGrowImageRegion(WindowRef window,SInt32 param)
- {
- /*------------------------------------------------------
- Get region to xor during grow/resize.
- --------------------------------------------------------*/
- GetGrowImageRegionRec* rgnRec=(GetGrowImageRegionRec*)param;
- #pragma unused(rgnRec)
-
- return noErr;
- }
-
- void getCurrentPortBounds(Rect* inRect)
- {
- /*------------------------------------------------------
- Simple utility function to get the bounds of the
- current port.
- --------------------------------------------------------*/
- CGrafPtr thePort;
- GetPort(&thePort);
- GetPortBounds(thePort,inRect);
- }