Ok, I've coded 3 implementations, compared them, and thought through the implications of each, and right now I'm going to go with either the existing ID system, or dumb handles (the only difference is in who allocates the 'ID', you or the system).
For intelligent handles, there are the two methods of Diggsey/Ben, and mine.
I found no benefit to using the Diggsey/Ben method over using standard ID's - existence-checks are replaced by 'is the handle valid' checks, there's a constant overhead for adding/removing handles from internal resource lists (they get copied and destroyed whenever you pass one into a function), and there's a memory overhead on a per-handle basis, and then you still need to manually delete the resource when you are done.
Although there were benefits to the scoped handle method I suggested, there was one great big problem with it - global variables, by definition, never go out of scope, so if a handle is stored in a variable at that scope, the resource is never deleted automatically, and can only be deleted by assigning a 'null' handle to the variable, and then you need to provide a function to check if the handle is valid. At this point, you're in a worse position than other methods, because sometimes you leave it to the system, and sometimes you don't and a beginner will make mistakes with that. In addition, it's kind-of counter-intuitive in a beginners language to use variables and not commands for controlling resource lifetimes.
Basically, all the new suggestions are pants, and we should stick with ID's.
Code is available for all three via email on request (it's quick-n-dirty code just to check things out, so don't expect too much).