home *** CD-ROM | disk | FTP | other *** search
- /*******************************************
-
- WDEF Patcher
- Steve Falkenburg MacDTS
- ⌐1991 Apple Computer
-
- This snippet shows how you can add a simple extra part to a WDEF without
- writing an entire WDEF. It also shows how to access the new part via
- FindWindow().
-
- Roberto Avanzi (independent programmer), June 18, 1992
- Added support for tracking the extra part, in a way similar to the one used
- by the system.
- given back to Apple as an enhanced snippet (mmmh, sounds quite absurd)
-
- *******************************************/
-
- #include <Windows.h>
-
- /* add 2 to this when checking with FindWindow() ! */
-
- #define kOurHit 32
-
- Boolean gInBackground;
- Boolean gDone;
-
- void InitStuff(void);
- void EventLoop(WindowPtr window);
- void DoDrag(WindowPtr window,Point globMouse);
- void HandleMouseDowns(EventRecord *ev);
- void HandleContent(WindowPtr theWindow,EventRecord *ev);
- void HandleUpdates(WindowPtr wind);
- void DoDeActivate(WindowPtr window,Boolean chFlag);
- void DoActivate(WindowPtr window,Boolean chFlag);
- void HandleActivates(EventRecord *ev);
- void HandleSREvt(long message);
- void DoGrow(WindowPtr window,Point globMouse);
- void PatchWindowWDEF(WindowPtr window);
- pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param);
- void HandleOurPart(WindowPtr window);
- /* roberto avanzi, june 18, 1992 */
- Boolean TrackMyPart(WindowPtr window);
-
-
- /* this struct allows us to insert a WDEF patch safely. It contains a jump instruction
- and stores the old handle to the WDEF
- */
-
- typedef struct {
- short jmpInst;
- ProcPtr patchAddr;
- Handle oldAddr;
- Boolean partState; /* roberto avanzi jun 18 1992 */
- } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
-
-
- void main(void)
- {
- WindowPtr mainWindow;
- Rect bounds = {100,100,150,300};
-
- gInBackground = false;
- gDone = false;
-
- InitStuff();
- mainWindow = NewWindow(nil,&bounds,"\pWDEF Patcher",false,zoomDocProc,(WindowPtr)-1,true,0);
- PatchWindowWDEF(mainWindow);
- ShowWindow(mainWindow);
- EventLoop(mainWindow);
- }
-
-
- void InitStuff(void)
- {
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- FlushEvents(everyEvent,0);
- }
-
-
- void EventLoop(WindowPtr window)
- {
- EventRecord ev;
-
- do {
- if (WaitNextEvent(everyEvent,&ev,10,nil)) {
- switch (ev.what) {
- case mouseDown:
- HandleMouseDowns(&ev);
- break;
- case updateEvt:
- HandleUpdates((WindowPtr)ev.message);
- break;
- case activateEvt:
- HandleActivates(&ev);
- break;
- case app4Evt:
- HandleSREvt(ev.message);
- break;
- }
- }
- } while (!gDone);
- }
-
-
- void HandleMouseDowns(EventRecord *ev)
- {
- WindowPtr theWindow;
- short part;
-
- part = FindWindow(ev->where,&theWindow);
-
- switch (part) {
- case inMenuBar:
- break;
- case inSysWindow:
- SystemClick(ev,theWindow);
- break;
- case inDrag:
- DoDrag(theWindow,ev->where);
- break;
- case inGoAway:
- if (TrackGoAway(theWindow,ev->where)) {
- gDone = true;
- }
- break;
- case inContent:
- HandleContent(theWindow,ev);
- break;
- case inGrow:
- DoGrow(theWindow,ev->where);
- break;
- case kOurHit+2: // remember, we're adding 2 so the FindWindow/WDEF
- HandleOurPart(theWindow); // codes match
- break;
- case inZoomIn:
- case inZoomOut:
- SetPort(theWindow); // important
- if (TrackBox(theWindow,ev->where, part))
- ZoomWindow(theWindow, part, true);
- break;
- }
- }
-
-
-
- /* handles a mouse down in our added window part */
- /* here you should do something more intelligent than beep, if you really want */
-
- void HandleOurPart(WindowPtr window)
- {
- // then track the Part (Roberto Avanzi 18-06-1992)
-
- if (TrackMyPart(window))
- SysBeep(10);
-
- }
-
- /* Roberto Avanzi , june 18, 1992
- here i decide to track the control and mimic the system's behavior.
- I can as well decide to make a popup appear near the box.
- This is more consistent with the rest of the User Interface
- */
-
- Boolean TrackMyPart(WindowPtr window)
- {
- long r;
- Point pt;
- WindowPtr wind;
- pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param);
-
- #define pstate (**(WDEFPatchHndl) ((WindowPeek)window)->windowDefProc).partState
-
- /* hilite control */
- pstate = true; (void) MyWDEFPatch(zoomDocProc ,window,wDraw,kOurHit);
-
- while (Button())
- {
- GetMouse(&pt);
- LocalToGlobal(&pt);
- r = FindWindow(pt,&wind);
- if ( ( (wind == window) && ( r == kOurHit+2) ) != pstate )
- {
- pstate = ! pstate; (void) MyWDEFPatch(zoomDocProc ,window,wDraw,kOurHit);
- }
- }
-
- if (! pstate ) return false; /* yawn, changed idea */
- /* un-hilite control */
- pstate = false; (void) MyWDEFPatch(zoomDocProc,window,wDraw,kOurHit);
- return true; /* OK, we HIT !!! */
-
- #undef pstate
- }
-
- /* DoDrag: Handles drag window events */
-
- void DoDrag(WindowPtr window,Point globMouse)
- {
- Rect dragRect;
-
- SetRect(&dragRect,-32000,-32000,32000,32000);
-
- DragWindow(window,globMouse,&dragRect);
- SetPort(window);
- }
-
-
- /* DoGrow: Handles grow window events */
-
- void DoGrow(WindowPtr window,Point globMouse)
- {
- long newSize;
- Rect windLimits;
- GrafPtr tempPort;
-
- SetRect(&windLimits,64,64,32000,32000);
-
- if ((newSize = GrowWindow(window,globMouse,&windLimits)) != 0) {
- GetPort(&tempPort);
- SetPort(window);
- SizeWindow(window,LoWord(newSize),HiWord(newSize),true);
- InvalRect(&window->portRect);
- SetPort(tempPort);
- }
- }
-
-
- void HandleContent(WindowPtr theWindow,EventRecord *ev)
- {
- GrafPtr savePort;
- Point where;
-
- where = ev->where;
- SetPort(theWindow);
-
- if (theWindow != FrontWindow()) {
- SelectWindow(theWindow);
- return;
- }
- }
-
-
- void HandleUpdates(WindowPtr wind)
- {
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(wind);
- BeginUpdate(wind);
- EraseRect(&wind->portRect);
- DrawGrowIcon(wind);
- EndUpdate(wind);
- SetPort(savePort);
- }
-
-
- void HandleActivates(EventRecord *ev)
- {
- if ((ev->modifiers & activeFlag) != 0) {
- DoActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
- }
- else {
- DoDeActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
- }
- }
-
-
- /* DoActivate: Performs activate tasks */
-
- void DoActivate(WindowPtr window,Boolean chFlag)
- {
- DrawGrowIcon(window);
- }
-
-
- /* DoDeActivate: Performs deactivate tasks */
-
- void DoDeActivate(WindowPtr window,Boolean chFlag)
- {
- DrawGrowIcon(window);
- }
-
-
- void HandleSREvt(long message)
- {
- if ((message >> 24) == 1)
- if ((message & 1) != 0) {
- gInBackground = false;
- SetCursor(&arrow);
- if (FrontWindow()) {
- HiliteWindow(FrontWindow(),true);
- DoActivate(FrontWindow(),true);
- }
- }
- else if (FrontWindow()) {
- gInBackground = true;
- HiliteWindow(FrontWindow(),false);
- DoDeActivate(FrontWindow(),true);
- }
- }
-
-
-
-
- /* this installs the WDEF patch into a window */
-
- void PatchWindowWDEF(WindowPtr window)
- {
- WDEFPatchHndl wdefHndl;
- WDEFPatchPtr wdefPatch;
-
- wdefHndl = (WDEFPatchHndl)NewHandle(sizeof(WDEFPatch));
- HLock(wdefHndl);
- wdefPatch = *wdefHndl;
- wdefPatch->oldAddr = ((WindowPeek)window)->windowDefProc;
- wdefPatch->jmpInst = 0x4ef9; /*JMP*/
- wdefPatch->patchAddr = MyWDEFPatch;
-
- HUnlock(wdefHndl);
- ((WindowPeek)window)->windowDefProc = (Handle)wdefHndl;
- }
-
-
- pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param)
- {
- long thisA5;
- WDEFPatchHndl wdPatch;
- pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
- Handle oldWDEF;
- long result;
- Rect ourRect,ourElementRect;
- Point *hitPt;
- Point mouse;
- Point pt;
- GrafPtr savePort;
- GrafPtr aPort;
- RgnHandle aRgn;
- Rect aRect;
-
- ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
- SetRect(&ourElementRect,ourRect.right-38,ourRect.top+4,ourRect.right-26,ourRect.top+15);
-
- wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
-
- oldWDEF = (**wdPatch).oldAddr;
- HLock(oldWDEF);
- wdefProc = (void *)*oldWDEF;
- wdefProc = (void *)StripAddress(wdefProc);
-
- /* now, folks, WHY do I check it, u'll ask me ? Heh, it's a funny quirk in
- the sys WDEF (at least, sys 7's, dunno whattabout older ones) .
- Suppose You click once in the grow icon and DO NOT resize the window.
- (remember, just click and do not move the mouse in the meantime).
- Then you click on the added part. That part is tracked in the right way,
- * BUT *
- ALSO the zoom box gets hilited. Dunno why should happen, but It's a lot
- of FUN. Sadly, cannot find its place in any useful app. Therefore we
- do this check.
- APPLE says: if you write your own WDEF and receive unknown messages, do not
- do anything. pass along and do NOTHING.
- APPLE does: we get something new ? therefore we process it anyway, just to
- keep developers writing workarounds and keep their minds afresh.
- What else can we say ? Thanks !!!!! (Roberto Avanzi june 19, 1992)
- */
- if ( (message == wDraw) ? (((short)param) != kOurHit ) : true )
- result = (wdefProc)(varCode,window,message,param);
-
- if (((WindowPeek)window)->visible)
- if (((WindowPeek)window)->hilited)
- {
- switch (message) {
- case wDraw:
- GetPort(&savePort);
- GetWMgrPort(&aPort);
- SetPort(aPort);
- aRgn = NewRgn();
- GetClip(aRgn);
- SetRect(&aRect,-32000,-32000,32000,32000);
- ClipRect(&aRect);
- switch ( (short) param ) { // Roberto Avanzi 18-06-1992: support for
- // tracking of the new part
- case 0:
- (**wdPatch).partState = false;
- case kOurHit:
- PenNormal(); // draw our part
- if ( (**wdPatch).partState )
- {
- InsetRect(&ourElementRect,-1,0);
- EraseRect(&ourElementRect);
- InsetRect(&ourElementRect,1,0);
- FrameRect(&ourElementRect);
- MoveTo(ourElementRect.left+2,ourElementRect.top+2);
- Line(2,2); Move(-2,0); Line(2,-2);
- Move(3,0); Line(2,2); Move(-2,0); Line(2,-2);
- Move(0,4); Line(-2,2); Line(-3,0); Line(-2,-2);
- }
- else
- {
- InsetRect(&ourElementRect,-1,0);
- EraseRect(&ourElementRect);
- InsetRect(&ourElementRect,1,0);
- FrameRect(&ourElementRect);
- InsetRect(&ourElementRect,2,2);
- FrameRect(&ourElementRect);
- }
- break;
- default:
- break;
- }
- SetClip(aRgn);
- DisposeRgn(aRgn);
- SetPort(savePort);
- break;
- case wHit:
- hitPt = (Point *)¶m; // hit test our part
- if (PtInRect(*hitPt,&ourElementRect))
- {
- result = kOurHit;
- }
- break;
- default:
- break;
- } // switch
- } // if hilited (otherwise we dont see the new box, addition by Roberto Avanzi)
- HUnlock(oldWDEF);
-
- return result;
- }
-
-