My GUI system isn't really anything special. The highest level element is a window, and all windows are managed by the GUI manager. A window contains several widgets, and input is handled by the GUI managager, which is ticked once per frame.
I'm also going to have the ability to load a window from a schema, which I've semi-decided is going to be an ini-like file (since I have code for that already). So a sample GUI schema would look something like:
X = 0
Y = 0
Alignment = Left
Text = I am a sample test string
X = 0
Y = 20
Width = 30
Text = I R Teh Button
Width and Height will default to the size of the object (Size of the text, for instance). Now I think about this, I might be better off with XML, so I can nest stuff. Hrm...
I'm currently doing text stuff, which is a lot neater than I thought. There's a SOText scene object, which you create and add to the scene as normal. You can set the text string, the font, the colour, etc here. When you change the font, it allocates a new CFont from the font manager. A CFont is really just a wrapper around ID3DXFont, but the D3D device manages a list of them and resets them when the device gets lost. The font manager caches fonts, so two requests for the same font won't allocate two objects. It also keeps hold of an ID3DXSprite for font rendering.
When the scene graph comes to render everything, because it sorts the objects, I can just call ID3DXSprite::Begin() in FirstRender(), using the font manager's sprite, draw the text for all objects, and then call ID3DXSprite::End() in LastRender().
So, the text is set on the scene object, meaning it can be set once and forgotten about, and everything is cached, sorted and rendered nicely. Hooray!
All of that is untested of course (I'll give it a go during my lunch break, it's nearly compilable). So far only text is done (And the GUI manager and window classes).