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.
DrawCode.c
/* |
File: DrawCode.c |
Contains: DragWindowGrid- a big nasty function to Drag a window along grid lines. |
Note the elegant error handling. You should change it to make your users happy. |
You can change the size of the 'grid rects' by changing the value of kIncrement. |
Written by: |
Copyright: Copyright © 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): |
8/5/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include <Windows.h> |
#include <QuickDraw.h> |
#include <TextUtils.h> |
#include <Fonts.h> |
#include <Memory.h> |
void DragWindowGrid(WindowPtr win, Point pt); |
void DrawIt(WindowPtr win); |
pascal void DrawWindowContent(short pixelDepth, short dFlags, GDHandle theDevice, long theWin); |
void MyCreateNewWindow(void); |
void PreEventLoop(void); |
void DoUpdate(WindowPtr thisWindow); |
void PostEventLoop(void); |
void DragWindowGrid(WindowPtr win, Point pt) |
{ |
RgnHandle dragRgn, lastDragRgn, insetGray; |
GrafPtr oldPort, tmpPort; |
Point currPt, firstMulPoint, lastMulPoint, currMulPoint; |
Boolean frameHidden; |
enum {kIncrement = 16, kBorderInset = 4}; |
// Set up our regions - init our variables. |
dragRgn = NewRgn(); |
lastDragRgn = NewRgn(); |
insetGray = NewRgn(); |
if ((dragRgn == NULL) || (lastDragRgn == NULL) || (insetGray == NULL)) { |
DebugStr("\pnot enough memory- bye!"); |
return; |
} |
CopyRgn(GetGrayRgn(), insetGray); |
if (MemError() != noErr) { |
DebugStr("\pnot enough memory- bye!"); |
return; |
} |
InsetRgn(insetGray, kBorderInset, kBorderInset); |
frameHidden = false; |
// Set up a port to draw into, and save off the old |
tmpPort = (GrafPtr)NewPtr(sizeof(GrafPort)); |
if (tmpPort == NULL) { |
DebugStr("\pnot enough memory- bye!"); |
return; |
} |
GetPort(&oldPort); |
OpenPort(tmpPort); |
CopyRgn(GetGrayRgn(), tmpPort->visRgn); |
if (MemError() != noErr) { |
DebugStr("\pnot enough memory- bye!"); |
return; |
} |
tmpPort->portRect = (*GetGrayRgn())->rgnBBox; |
SetPort(tmpPort); |
PenMode(patXor); |
PenPat(&qd.gray); |
// Set the incoming point to be on a multiple of kIncrement, |
// to make later calculations easier. |
currMulPoint.h = pt.h + (kIncrement/2); |
currMulPoint.h /= kIncrement; currMulPoint.h *= kIncrement; |
currMulPoint.v = pt.v + (kIncrement/2); |
currMulPoint.v /= kIncrement; currMulPoint.v *= kIncrement; |
firstMulPoint = lastMulPoint = currMulPoint; |
CopyRgn(((WindowPeek)win)->strucRgn, dragRgn); |
if (MemError() != noErr) { |
DebugStr("\pnot enough memory- bye!"); |
return; |
} |
CopyRgn(((WindowPeek)win)->strucRgn, lastDragRgn); |
if (MemError() != noErr) { |
DebugStr("\pnot enough memory- bye!"); |
return; |
} |
// Draw the first framed region, which will follow the mouse |
// on the screen |
FrameRgn(lastDragRgn); |
while (WaitMouseUp() == true) { |
// Now track the mouse, and when it moves enough make the framed |
// region move as well. |
GetMouse(&currPt); |
// Set the new point to be on a multiple of kIncrement |
currMulPoint.h = currPt.h + (kIncrement/2); |
currMulPoint.h /= kIncrement; currMulPoint.h *= kIncrement; |
currMulPoint.v = currPt.v + (kIncrement/2); |
currMulPoint.v /= kIncrement; currMulPoint.v *= kIncrement; |
// Should we be showing the frame region ?? |
if (PtInRgn(currPt, insetGray) == false) { |
// It's somewhere near the edges, so hide the frame |
if (frameHidden == false) |
// if it's not hidden already, hide it now |
FrameRgn(lastDragRgn); |
frameHidden = true; |
} |
else { |
// else, the frame should be shown if it's hidden |
if (frameHidden == true) { |
FrameRgn(lastDragRgn); |
frameHidden = false; |
} |
} |
// Has the mouse moved ? |
if (&currMulPoint != &lastMulPoint) { |
// The mouse coordinates have changed enough to adjust the window, |
// so move the frame accordingly |
OffsetRgn(dragRgn, currMulPoint.h - lastMulPoint.h, currMulPoint.v - lastMulPoint.v); |
if (frameHidden == false) { |
// Only show the frame if we're allowed to. |
FrameRgn(dragRgn); |
FrameRgn(lastDragRgn); |
} |
lastMulPoint = currMulPoint; |
CopyRgn(dragRgn, lastDragRgn); |
if (MemError() != noErr) { |
DebugStr("\pnot enough memory- bye!"); |
return; |
} |
} |
} |
if (frameHidden == false) |
// If frameHidden is true, there's no need to erase the final |
// frame. |
FrameRgn(lastDragRgn); |
if ((&lastMulPoint != &firstMulPoint) && (frameHidden == false)) { |
// The mouse has moved from its original position and is |
// somewhere on the screen, so move the window accordingly. |
Point globalPt, diffPt, contPt = {0, 0}; |
// Calculate the difference between the strucRgn's 0, 0 and |
// the window's content region 0, 0. Remember that MoveWindow |
// moves the window's *content* to the coordinate specified, and |
// we want to move the window's structure to fit in the lastDragRgn |
SetPort(win); |
// LocalToGlobal works much better when the port is set up... |
LocalToGlobal(&contPt); |
SetPort(tmpPort); |
diffPt.h = contPt.h - (*((WindowPeek)win)->strucRgn)->rgnBBox.left; |
diffPt.v = contPt.v - (*((WindowPeek)win)->strucRgn)->rgnBBox.top; |
globalPt.h = (*lastDragRgn)->rgnBBox.left; |
globalPt.v = (*lastDragRgn)->rgnBBox.top; |
LocalToGlobal(&globalPt); |
globalPt.h += diffPt.h; |
globalPt.v += diffPt.v; |
MoveWindow(win, globalPt.h, globalPt.v, true); |
} |
// Close the port and tear everything down |
ClosePort(tmpPort); |
SetPort(oldPort); |
DisposeRgn(dragRgn); |
DisposeRgn(insetGray); |
DisposeRgn(lastDragRgn); |
} |
/*-------------------------------------------------------------------------------------*/ |
void DrawIt(WindowPtr win) |
{ |
short origFont, origSize; |
origFont = win->txFont; |
origSize = win->txSize; |
TextFont(kFontIDCourier); |
TextSize(12); |
ForeColor(redColor); |
PaintRect(&(*win).portRect); |
ForeColor(blackColor); |
MoveTo(20, 20); |
DrawString("\pDrag this window."); |
TextFont(origFont); |
TextSize(origSize); |
} |
/*-------------------------------------------------------------------------------------*/ |
pascal void DrawWindowContent(short pixelDepth, short dFlags, GDHandle theDevice, long theWin) |
{ |
#pragma unused (pixelDepth, dFlags, theDevice) |
GrafPtr savePort; |
GetPort(&savePort); |
SetPort((GrafPtr)theWin); |
DrawIt((WindowPtr)theWin); |
SetPort(savePort); |
} |
/*-------------------------------------------------------------------------------------*/ |
void MyCreateNewWindow(void) |
{ |
Rect winDimension; |
SetRect(&winDimension, 60, 60, 460, 260); |
(void)NewCWindow(0L, &winDimension, "\pSample", true, noGrowDocProc, |
(WindowPtr)-1L, true, 0L); |
} |
/*-------------------------------------------------------------------------------------*/ |
void PreEventLoop(void) |
{ |
MyCreateNewWindow(); |
} |
/*-------------------------------------------------------------------------------------*/ |
void DoUpdate(WindowPtr thisWindow) |
{ |
static DeviceLoopDrawingUPP procForDeviceLoop = nil; |
SetPort(thisWindow); |
if ( procForDeviceLoop == nil ) |
procForDeviceLoop = NewDeviceLoopDrawingProc(DrawWindowContent); |
BeginUpdate(thisWindow); |
DeviceLoop(thisWindow->visRgn, procForDeviceLoop, (long)thisWindow, singleDevices); |
EndUpdate(thisWindow); |
} |
/*-------------------------------------------------------------------------------------*/ |
void PostEventLoop(void) |
{ |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-30