I want to set image only in particular rows of listctrl.
If I use CListCtrl's SetImageList, it is setting image in first column of each row.
Is it possible to set image only in whichever row I want.
I think it's a little bit messy but it works for me.
If your CListCtrl has LVS_OWNERDRAWFIXED style, than you can decide which column which image will have.
For this purpose you need to set extended style LVS_EX_SUBITEMIMAGES for your list after it will be created. Than you add CImageList
field to your CListCtrl-derived class, for example it will have m_imgList name. This field has to be initialized with default values
and with image resource that will be using. After that you have to call SetImageList and pass it m_imgList. As long as your list will
have LVS_OWNERDRAWFIXED style you need to implement DrawItem function in which you will call something like this for image drawing:
LVITEM lvItem = {0};
lvItem.mask = LVIF_IMAGE;
lvItem.iSubItem = nCol; // column index
lvItem.iItem = nItem; // item index
GetItem(&lvItem);
POINT p; // init it like you want
pDC // pointer on device context
m_imgList.Draw(pDC, lvItem.iImage, p, ILD_MASK);
And before that, when you will fill the list with values, you have to fill in LVITEM structure for needed column:
LVITEM lvItem = {0};
lvItem.iItem = nItem; // item index
lvItem.iSubItem = i; // column index
lvItem.iImage = nImg; // image index from imageList
lvItem.mask = LVIF_IMAGE;
And after that you have to call InsertItem or SetItem with this lvItem parameter.
A simple way to achieve it is adding a transparent image in your CImageList and set it on the list item you don't want the image to appear.
Related
I've looked here:
https://www.amcharts.com/docs/v4/reference/xycursor/
and tried this
chart.cursor.fontSize = "14";
chart.cursor.fill = am4core.color("#ff0000");
chart.cursor.fontFamily = "verdana";
To style the (default white on black) element when the xycursor touches the X/Y axis (don't know what the correct name for this element is, hope you know which one I mean)
I would like to set the font size and family. Tried to set the color to red to see if it has to be set via the fill property, but also that doesn't work.
Created the cursor like this:
chart.cursor = new am4charts.XYCursor();
chart.cursor.xAxis = axis;
You have to set the tooltip properties inside the axis objects directly, as mentioned in the documentation. For example, to change the font, size and color in the category axis tooltip, modify the tooltip's label object:
categoryAxis.tooltip.getFillFromObject = false;
categoryAxis.tooltip.label.fill = "#ff0000"
categoryAxis.tooltip.label.fontFamily = "Courier New"
categoryAxis.tooltip.label.fontSize = 15;
Demo
I have a CListCtrl that shows my data in rows. It has two column. Now i need to add another column that will be actually showing a icon.
// set look and feel
listCtrl.SetExtendedStyle(listCtrl.GetExtendedStyle() | columnStyles);
Adding row items as below :
for (const auto dataValue : dataTable)
{
int rowIndex = listCtrl.GetItemCount();
listCtrl.InsertItem(rowIndex, dataValue.at(0).c_str());
for (int colIndex = 1; colIndex < listCtrl.GetHeaderCtrl()->GetItemCount(); ++colIndex)
{
listCtrl.SetItemText(rowIndex, colIndex, dataValue.at(colIndex).c_str());
}
}
I added a new column that will contain the icons for the rows.
I can not getting proper idea how to add icon in the cells of the added column. Consider it's added in first column.
Please suggest.
You don't need a new column, as the image is displayed in the left of the first column (Given your text I assume you are using the LVS_REPORT style).
You need to have a member image list with same count of images as items of your list. So on your list's derived class, add a member:
CImageList m_ImageList;
Then on your list's OnCreate function:
m_ImageList.Create(32, 32, ILC_COLOR24, numberOfEnableParts, 1);
m_ImageList.SetImageCount(n);
for (int i = 0; i< n; i++)
{
if(InsertItem(n, sText) != -1)
{
//set text of columns with SetItemText
//...
// don't know if you use a icon or a bitmap; next line I did it for the second case
m_ImageList->Replace(n, CBitmap::FromHandle(hBmp), (CBitmap*)NULL);
//then, associate the item with its own image of the image list
LVITEM lvi;
lvi.iItem= i;
lvi.iSubItem= 0;
lvi.mask = LVIF_IMAGE;
lvi.iImage= i;
SetItem(&lvi);
}
}
SetImageList(m_ImageList, LVSIL_SMALL);
I have a bitmap stored as a BGRA array of bytes. This is the code I've been using to paint the bitmap:
CDC *dispDC = new CDC();
dispDC->CreateCompatibleDC(pDC);
CBitmap *dispBMP = new CBitmap();
dispBMP->CreateCompatibleBitmap(pDC, sourceImage->GetWidth(), sourceImage->GetHeight());
dispDC->SelectObject(this->dispBMP);
The actual copying of the pixels in the translatedImage array happens with this:
dispBMP->SetBitmapBits(sourceImage->GetArea() * 4, translatedImage);
Then after some more processing I call pDC->StretchBlt with dispDC as the source CDC. This works fine when logged in locally because the display is also set to 32bpp.
Once I log in with Remote Desktop, the display goes to 16bpp and the image is mangled. The culprit is SetBitmapBits; i.e. for it to work, I have to properly fill translatedImage with the 16bpp version of what I want to show. Rather than do this myself, I searched the documentation and found SetDIBits which sounds like it does what I want:
The SetDIBits function sets the pixels in a compatible bitmap (DDB) using the color data found in the specified DIB.
In my case, the DIB is the 32bpp RGBA array, and the DDB is dispBMP which I create with CreateCompatibleBitmap.
So instead of my call to SetBitmapBits, this is what I did:
BITMAPINFO info;
ZeroMemory(&info, sizeof(BITMAPINFO));
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biCompression = BI_RGB;
info.bmiHeader.biSizeImage = sourceImage->GetArea()*4;
info.bmiHeader.biWidth = sourceImage->GetWidth();
info.bmiHeader.biHeight = sourceImage->GetHeight();
info.bmiHeader.biClrUsed = 0;
int r = SetDIBits(pDC->GetSafeHdc(), (HBITMAP)dispBMP,
0, sourceImage->GetHeight(), translatedImage,
&info, DIB_PAL_COLORS);
However, r is always zero and, naturally, I get nothing but black in my window. What is wrong with the code?
According to the documentation for SetDIBits:
The bitmap identified by the hbmp parameter must not be selected into a
device context when the application calls this function.
In your example code you select it into device context after creating it, so presumably that's why SetDIBits is failing.
Ross Ridge was correct in pointing out the code order mistake. However, this didn't solve the problem.
The problem was in the parameters I was passing. I am new to C++ and MFC and often forget all the "operators" which can act on types to automatically convert them.
Previously I had this:
int r = SetDIBits(pDC->GetSafeHdc(), (HBITMAP)dispBMP,
0, sourceImage->GetHeight(), translatedImage,
&info, DIB_PAL_COLORS);
The correct call is this:
int r = SetDIBits(*pDC, *dispBMP,
0, sourceImage->GetHeight(), translatedImage,
&info, DIB_PAL_COLORS);
(Note I pass dereferenced pointers in the first two parameters.) Everything else was correct, including the counter-intuitive DIB_PAL_COLORS flag for a bitmap which has not palette.
After obviously missing some key points in the documentation I reread it and then found this which has sample code showing that I was simply passing the parameters incorrectly.
I have a treeview with checkboxes and it has imagelist set with TreeView_SetImageList().
I am trying to remove image from nodes that do not have children. I was successful in removing checkboxes from parent nodes, so I thought to try the similar approach:
// add an item
TVINSERTSTRUCT tvis = {0};
tvis.item.mask = TVIF_TEXT // | TVIF_IMAGE;
// tvis.item.iImage = -1; // I thought this will work
// tvis.item.iSelectedImage = -1; // but it does not work at all
tvis.item.pszText = L"Some text";
tvis.hInsertAfter = TVI_LAST;
tvis.hParent = TVI_ROOT;
htItem = reinterpret_cast<HTREEITEM>( SendMessage( hwndTV,
TVM_INSERTITEM, 0, reinterpret_cast<LPARAM>( &tvis ) ) );
// remove image
TVITEM tvi;
tvi.hItem = htItem;
tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvi.iImage = -1;
tvi.iSelectedImage = -1;
TreeView_SetItem( hwndTV, &tvi );
It does not work as expected. At first the image is not shown, but the item text is not next to the checkbox:
If I select another item the image suddenly reappears:
If I click on the problematic node again I get the same result, as shown in the first picture.
My question is simple:
How do I remove an image from a node?
Thank you.
Best regards.
You cannot remove images from individual nodes. Once you have an image list assigned, the TreeView reserves space for the list's images on all nodes equally, even if individual nodes do not display images from the list.
To do what you are asking, do not assign the image list at all, and then custom-drawn the nodes to make them appear however you want.
I'm attempting to color disabled rows in a gtk tree view widget a light gray color. From what I've read, I'm supposed to set the background-gdk property of the corresponding cellrenderer and bind it to a model column. This sort of works.
Gtk::CellRendererText* textRenderer = manage(new Gtk::CellRendererText());
textRenderer->property_editable() = false;
Gtk::TreeViewColumn *col = manage(new Gtk::TreeViewColumn("Column1", *textRenderer));
col->add_attribute(*textRenderer, "background-gdk", m_treeview_columns.m_back_color);
my_treeview.append_column(*col);
Gtk::TreeModel::Row row;
for (int i = 0; i < NUMBER_OF_ROWS; iLane++){
row = *(treeview_liststore->append());
row[m_workListColumns.m_back_color] = Gdk::Color("#CCCCCC");
}
In the end though, I get only the cells colored properly. BUT I also get an ugly white-space in between the cells. Does anyone know of a way to fix this or a better way to achieve the effect I'm after?
Could you set the background of the row to match the cell background or set the bakground of the tree view all together ? Or maybe the cell with cell-background-gdk ?