Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » Changing grid cell colors? Collapse All
Subject Author Date
Dave M May 5, 2005 - 10:51 AM

Hi,

One feature I really need is to be able to easily set the grid cell/row color by invoking a method in CExtGridWnd. For example, maybe there’s a critical error, and I either need to write log messages to the grid control in red-on-white or white-on-red for various rows.

I did find one post here that sounded a little more complicated, since you have to override a method in CExtGridCell. If this is the case, it seems that you’d have to set the color when the cell is created, or if it’s already created, you’d have to destroy the cell and then recreate it.

Maybe it’s easy, and I’m just misunderstanding what needs to be done to implement this. Can you please help me out?

Thanks!
Dave

Technical Support May 6, 2005 - 6:09 AM

Your question deals more with design of the grid control rather than coloring cells. All cell classes are derived from CExtGridCell, which is designed to keep less possible number of properties, which in turn leads to minimizing memory usage. So, you really need to define your cell class and add any required style painting. The cell classes are created on the internal memory manager’s heap which is designed to minimize memory usage and make allocations as faster as possible. This memory manager is based on the IMalloc interface described in COM/OLE documentation but we are using our own blocked/non-blocked implementations of this interface in the CExtGridAlloc class. That is why grid cells may need to be re-created before they become parts of the memory manager. The fastest way of creating cells is provided by the CExtGridWnd::GridCellGet() method where you can specify an MFC’s runtime class of the cell type which should appear inside the memory manager for the specified location. The new cell instance is created by this method only if the specified location does not contain a cell object. After getting a pointer to the required cell type, you can perform its initialization with your custom properties such as the text/background color. You need to override the CExtGridCell::OnQueryTextColor() virtual method to return the required text font. You also have to override CExtGridCell::OnPaintBackground() to change the cell background. Please take a look at the CDemoColoredCell class in the SimpleGrids sample. It seems this is exactly what you need. The instances of this cell class are created in the first column of the grid control under the Colors tab. The second and third columns of this grid control contain cells with check marks and combo boxes which allow you to customize the text/background color of the CDemoColoredCell objects.

Dave M May 6, 2005 - 6:42 AM

Hi,

Thank you for your response. Yesterday, I did figure out what needed to be done by examining the color table code within the SimpleGrids sample.

However, for whatever reason, I can’t get my grid to color the cells -- in fact, my application crashes every time I try to create the colored cell. Here’s what I did:

1. Subclassed CExtGridCellStringDM and implemented the necessary methods. I actually copied-and-pasted your CDemoColoredCell class from SimpleGrids and just changed the name.
2. Added two private members, bgColor and textColor, and initialized them white and gray, respectively.
3. In my load() method that comes after the windows are created, I used the following code:

static LPCTSTR captions[] = { "Header 1", "Header 2", "Header 3" };
list.OuterRowCountTopSet( 1L, false ); // create a header
for( int i=0; i<3; i++) {
list.ColumnAdd( 1, false);
CExtGridCellHeader* pCell = STATIC_DOWNCAST( CExtGridCellHeader, list.GridCellGetOuterAtTop( i, 0L, RUNTIME_CLASS(CExtGridCellHeader)));
pCell->TextSet( captions[i]);
pCell->ExtentSet( 100);
}
for( int i=0; i<10; i++) {
list.RowAdd( 1, false);
LONG row = static_cast<LONG>(i);
// column 1
CExtGridCellStringDMColor* pCell = STATIC_DOWNCAST( CExtGridCellStringDMColor, list.GridCellGet( 0, row, 0, 0, RUNTIME_CLASS( CExtGridCellStringDMColor)));
ostringstream str;
str << "row data" << i;
pCell->TextSet( str.str().c_str());
// column 2
pCell = STATIC_DOWNCAST( CExtGridCellStringDMColor, list.GridCellGet( 1, row, 0, 0, RUNTIME_CLASS( CExtGridCellStringDMColor)));
pCell->TextSet( str.str().c_str());
// column 3
pCell = STATIC_DOWNCAST( CExtGridCellStringDMColor, list.GridCellGet( 2, row, 0, 0, RUNTIME_CLASS( CExtGridCellStringDMColor)));
pCell->TextSet( str.str().c_str());
}

My code always crashes on the first line with STATIC_DOWNCAST. If I step into it, my CExtGridCellStringDMColor (the derived class I mentioned earlier) constructor gets called once and then crashes. If I do the same with your SimpleGrids app, it does the right thing (gets called twice). If I change my variables to be of type CExtGridCellStringDM, the code works fine.

FYI, the variable "list" is the CExtGridWnd member of my dialog. I’ve tried emulating your sample by setting up the grid cells from within a derived CExtGridWnd class, but that doesn’t help.

The only other difference I found was that I call RowAdd( 1, false) in a loop, rather than adding the rows all at once. However, I’ve also tried making that change, and my app still crashes.

If you have any ideas, I would really appreciate it! I’ve spent several hours trying out everything I can think of... If you need me to send you my 7.1 solution, I can do that.

Thank you!
Dave

Technical Support May 8, 2005 - 10:38 AM

We may guess you forgot to use this line in the declaration of the CExtGridCellStringDMColor class:

IMPLEMENT_ExtGridCell_Clone( CExtGridCellStringDMColor,
     CExtGridCellStringDM );
Only this error can make grid control create CExtGridCellStringDM objects instead of CExtGridCellStringDMColor inside its memory manager’s heap.

Dave M May 9, 2005 - 7:58 AM

Thank you for the reply. I sent a code sample to your support team, and someone was able to catch the problem. I had a ridiculous typo in my code where I used the wrong MFC macro.

Dave M May 6, 2005 - 6:48 AM

Maybe I should just send it now so you can see it sooner... but what email address should I send it to?

Technical Support May 6, 2005 - 9:39 AM

The ideal solution would be to send us a test project that demonstrates the problem. In this case we can quickly find the cause of the problem. You can use this e-mail address: support@prof-uis.com.

Dave M May 6, 2005 - 10:02 AM

Thanks, I have just emailed you my sample application.