>>By using HGETSTATE and HSETSTATE, you always restore to >>the previous state, and so cannot unlock a handle by error. > >Ok, I've not heard of this one; so then how _do_ you use >HGETSTATE/HSETSTATE in this situation? These commands act like GETPORT/SETPORT when working with GrafPorts. When you are working on a window, instead or working thru every conceivable grafport that your app may have, getting it's pointer, saving it and restoring it after you do the following: FN windowStuff oldPort& = FN GETPORT CALL SETPORT( myWndPtr&) ... 'here you do your stuff ' clean up before leaving CALL SETPORT( myWndPtr&) END FN Well HGETSTATE and HSETSTATE work in exactly the same manner LOCAL FN goTJ( myHndl&) oldState% = FN HGETSTATE ' the state, locked, pugeable, etc is now in oldState% CALL HLOCK( myHndl&) ' now you are _sure_ the handle is locked, it may have ' been before, or not, but now you are sure. ... dereference handle ... do lots of wicked things on dereferenced handle ... particularly things that force the memory manager ... to make the memory blocks tango CALL HSETSTATE( myHndl&, oldState%) ' now you have reset the handle to what it was ' before, so you're not interfering with a what ' another FN may have done to the Handle END FN >Truthfully I find handles to be more trouble when I start a project, so I >usually use pointers first and then convert to handles afterwards. In this case I'll give you another tip: I always create and kill my handles in the same place (anyone for home-raised handles ?) That is: I have a FN wher the handle is created and where it is killed LOCAL FN doWindow( cmd%, adrPtr&) ' adrPtr& would be the address of a record that I attach to ' a window. I then keep a bunch of info in that record that ' applies to the window SELECT cmd% CASE _mymakeWindow ' here i set up the window, fill the record, and of course ' create the handle adrPtr&.wrHndl& = FN HEWHANDLE CASE _myKillWindow ' here i erase the window, and empty the record DEF DISPOSEH( adrPtr&.wrHndl&) END SELECT This is great in debugging, as it becomes very difficult to knowingly kill a handle, then try and use it elsewhere, and when you do so, you can easily follow the code, and see that you've done so. In the example the handle is tied to a window, but it doesn't have to be. It's just the principal of creating and killing in the same FN, rather than just anywhere in your code, that helps you track down when you try to re-use a handle that you've killed. The other technique is that when you kill a handle, instead of setting it back to zero, set it to &DEADBEEF (an easy mnemonic). If you try to use it again as a valid handle you will crash into macsBug with the distinctive &DEADBEEF address appearing, and know that you've tried to use a handle that you have already killed. (&DEADBEEF is an address that is guaranteed to crash, on 68K Macs It was somewhere in the NuBus controllers, on PowerMacs... I don't know where (PCI bus controllers?) but believe me - it crashes! >(That is if afterwards ever comes...) Afterwards always comes. The important thing is being thre to see it (or not - depending on which afterwards you mean :-) ------------------------------------------------------------- ! "format utile" studio de graphisme/graphic design studio ! ! 32 bd de Menilmontant, 75020 Paris, France ! ! phone +33 1 43 49 02 04 +++ fax +33 1 43 49 16 51 ! ------------------------------------------------------------- *** coming soon to a browser near you *** <http://www.cybercities.com/formatutile> -------------------------------------------------------------