First off, I want a replacement for the RichEdit, so I'm writing my own custom control (I think I mentioned that I started doing that ages ago). This is a complete restart though.
I'm only dealing with fixed-width fonts, which makes a bit easier, but I want to be able to insert images and things to the control, like a RichEdit (With some limitations). I have a rough idea of how I want to handle all this. The control (I'm calling it a DruinkEdit) will have a std::vector of lines of content. Each line can contain text and/or an image. I'll be double buffering my stuff probably, for performance reasons, although I'd like to do some fancy stuff like rendering some D3D crap in the background. And I don't think that'll work too well with double buffering. We'll see anyway.
So, after 10 or 15 mins, I've got a working control, as a child window of my test app:
I'm intending to make it unicode and 64-bit compatible, but VC2005 still bitches about 64-bit conversion warnings with SetWindowLongPtr() and GetWindowLongPtr(), is that normal?
Also, I'm not to sure how to store all my state information. I'd like to do it however the standard Windows controls do it, since that's obviously the most tidy. At the moment, once the DruinkEdit window class is registered (It'll be done automatically in a .lib or .dll form, but I'm doing it manually for now), you can use CreateWindow() to create a DruinkEdit.
The control allocates sizeof(CDruinkEdit*) bytes after each window (using the cbWndExtra parameter of the WNDCLASSEX structure), and allocates a CDruinkEdit there in WM_NCCREATE, and destroys it in WM_NCDESTROY. Between then, everything just gets thrown at my non-static window proc.
Here's my static window proc for your amusement:
//C4244: 'argument' : conversion from 'LONG_PTR' to 'LONG', possible loss of data
//C4312: 'type cast' : conversion from 'LONG' to 'CDruinkEdit *' of greater size
LRESULT CALLBACK CDruinkEdit::StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// Get pointer to control
if(uMsg == WM_NCCREATE)
pEdit = new CDruinkEdit(true);
if(!pEdit) return -1;
pEdit = (CDruinkEdit*)GetWindowLongPtr(hWnd,0);
if(!pEdit) return DefWindowProc(hWnd,uMsg,wParam,lParam);
pEdit->m_hWnd = hWnd;
Anyway, I expect this to be a nice little side project, and not so vast that I'll get fed up with it, particularly now I'm working fulltime...