FB II Compiler

PG PRO

Debugging

Memory

System

Mathematics

Resources

Disk I/O

Windows

Controls

Menus

Mouse

Keyboard

Text

Fonts

Drawing

Sound

Clipboard

Printing

Communication

ASM

Made with FB

TEXT

Use HGETSTATE and HSETSTATE


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(oldPort&)
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

I always create and kill my handles in the same place
That is:
I have a FN where 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!

Jonathan