What does the TRACE message "Warning - more than one redraw ...." in the output window mean?
If you have overridden GetStyleRowCol you must not call RedrawRowCol, SetRowCount, or other operations that call UpdateWindow. If UpdateWindow was called the named TRACE message will be printed.
GetStyleRowCol is called from within OnDrawTopLeftBottomRight to load the cell data. So, if you call at that time RedrawRowCol with flags set to GX_UPDATENOW a new WM_PAINT message will be sent to OG which results in a recursive call to OnDrawTopLeftBottomRight.
OG can't deal with that recursion because it holds all drawing information in attributes of the grid. Therefore the recursive call would override the data initialized by the first OnDrawTopLeftBottomRight call.
Functions that should not force a redraw with GX_UPDATENOW flag are functions like GetStyleRowCol, ComposeStyleRowCol, GetCoveredCellsRowCol and all the other Get.... callback functions that are only called to determine information in the grid.
Of course, it is no problem to force a problem with GX_INVALIDATE so that the paint message will be sent after the actual WM_PAINT message has been processed.
The OnInitCurrentCell and OnMovedCurrentCell methods are exceptions. They might occasionally be called from within OnDrawTopLeftBottomRight to keep the current cell data in sync with the grid. Therefore these methods should also not force redrawing with GX_UPDATENOW but only with GX_INVALIDATE.
All other methods should be fine and able to redraw the grid. But, whenever you see that TRACE message displayed "Warning - more than one redraw ...." you should check which method forced this recursive redraw.
BTW - Invalidate() invalidates an area. The window manager will post a WM_PAINT message for all invalid areas in the message pump. That means if you call Invalidate the redrawing of the specified area will be delayed until the actually processed messages returns back to the message loop and the message loop dispatches the WM_PAINT message.
If you call UpdateWindow the window and all its child window will receive a WM_PAINT message immediately. A call to UpdateWindow() is like a SendMessage(WM_PAINT, ...) to the parent and all child windows and the message will be processed immediately.