Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!elroy.jpl.nasa.gov!decwrl!shelby!neon!Kermit.Stanford.EDU!philip From: philip@Kermit.Stanford.EDU (Philip Machanick) Newsgroups: comp.sys.mac.programmer Subject: Re: How to highlight buttons Keywords: button, mac, macintosh, dialog Message-ID: <1990Mar6.195441.6794@Neon.Stanford.EDU> Date: 6 Mar 90 19:54:41 GMT References: <1990Mar6.071221.3962@Neon.Stanford.EDU> <6929@ucdavis.ucdavis.edu> <288@bii.UUCP> Sender: root@Neon.Stanford.EDU (System PRIVILEGED Account) Reply-To: philip@pescadero.stanford.edu Organization: Computer Science Department, Stanford University Lines: 132 I've had a few requests for this, so here is the source code. I've marked places I haven't checked on with comments; you should do a bit of testing before using this (seems ok when I tried it). This is just a quick hack. I've tried to avoid doing anything but drawing the highlight, and to pass anything else to the deafult CDEF. Complication: CDEFs are identified when you ask for a new control by a number which is 16 times the resource ID of the underlying CDEF (see Inside Mac Vol 1). The following was developed in Think Pascal. The project type is Code Resource, with Purgeable turned on, and resource ID=4). The output is a file containing a CDEF. Paste this into a resource file for an application, and create CNTL resources with proc ID 4 (I hope I'm getting this right - my Mac is at home). You can then paste such resources into dialog boxes. Note that you need to make a new CNTL resource for each button you need. Alternatively, you can create the control directly in your program. Examples follow. -----------listing 1--------------------- unit defaultButton; interface function main (varCode: integer; theControl: controlHandle; message: integer; param: longint): longint; implementation function callDefProc (varCode: integer; theControl: controlHandle; message: integer; param: longint; theProc: ptr): longint; inline $205F, { movea.L (A7)+} $4E90; { A0 jsr(A0) } function main (varCode: integer; theControl: controlHandle; message: integer; param: longint): longint; const buttonDefProcID = 0; var itsRect: rect; oldPenState: PenState; defaultProc: handle; begin itsRect := theControl^^.contrlRect; {in all other cases, fool real button into thinking its rect is smaller} if message <> calcCRgns then begin {haven't checked if this is necessary... an exercise for the reader} InsetRect(itsRect, 4, 4); {must do extra step because contrlRect is a component of a packed record} theControl^^.contrlRect := itsRect; end; {if} defaultProc := getResource('CDEF', buttonDefProcID); hLock(handle(defaultProc)); main := callDefProc(varCode, theControl, message, param, ptr(defaultProc^)); hUnlock(handle(defaultProc)); if message <> calcCRgns then begin {revert saved version of rect to actual size} InsetRect(itsRect, -4, -4); theControl^^.contrlRect := itsRect; end; {if} if message = drawCntl then begin {not sure how much of this is necessary, e.g., whether pen is guaranteed to} {be in penNormal state when CDEF is called} getPenState(oldPenState); penMode(patCopy); penSize(3, 3); frameRoundRect(itsRect, 16, 16); setPenState(oldPenState); end; {if} end; {main} end. {defaultButton} -----------end listing 1--------------------- The following example requires a resource file with a DLOG ID=100, with an item no. 1 in it. If that item is one of these special new buttons, it will appear on the DLOG, and behave exactly like a button, except it will be outlined. Missing: because the new control is not a button as far as the dialog manager is concerned, pressing RETURN or ENTER does not select it automatically if it's item 1 (sigh). -----------listing 2--------------------- program tryDefButton; const tryDialogID = 100; highlightItem = 1; CDEFid = 64; {NB: NOT the resource ID; the CDEF resource ID is this number / 16 = 4} var DLOGStorage: DialogRecord; oldPort: GrafPtr; tryDialog: DialogPtr; item: integer; { itsRect: rect; itsType: integer; ignoreHandle: handle; } { theControl : controlHandle; } begin getPort(oldPort); tryDialog := GetNewDialog(tryDialogID, @DLOGStorage, WindowPtr(-1)); {if you want to create the control dynamically, e.g., replace a userItem,} {reinstate the following 3 lines, and declaration of itsRect etc. above} {getDItem(tryDialog, highlightItem, itsType, ignoreHandle, itsRect);} {theControl := newControl(tryDialog, itsRect, 'button', true, 0, 0, 1, CDEFid, 0);} {setDItem(tryDialog, highlightItem, ctrlItem, handle(theControl), itsRect);} showWindow(tryDialog); setPort(tryDialog); repeat ModalDialog(nil, item); { do something } if not eof then readln until eof; {in Think, signalled by ENTER} setPort(oldPort); end. {tryDefButton} -----------end listing 2--------------------- Philip Machanick philip@pescadero.stanford.edu