How can I wrap the item text in treeview control in WTL - c++

I am maintaining a ATL/WTL project in which it contains a tree view. The class used for the tree view is CTreeViewCtrl. Now the client has asked to wrap the tree item text when it goes out of view though we can re-size the pane or scroll left of right anytime to see the content. It also shows the full string, when hidden, as a tool tip when mouse pointer is hovered on a tree item.
Is there any way I can set in the tree item or the tree view to wrap the text content.
Thanks

There's a way: do custom drawing of treeview's items while processing NM_CUSTOMDRAW message from treeview control, specifically the CDDS_ITEMPOSTPAINT drawing stage.
On custom drawing you draw multi-line text using ::DrawText() with DT_WORDBREAK flag.
In order to have enough space available for text to fit in use TVITEMEX structure's iIntegral field. You'll have to specify number of lines for each node by sending TVM_SETITEM message to treeview window with pointer to TVITEMEX as LPARAM. You'll have to recalculate number of lines for each of tree's nodes every time treeview's width changes (WM_SIZE).

Related

Win32 (C++) :- How to make a list item collapsible

I have a listbox in which multiple list items are there. I want to implement something like if we click on the list item, it will collapse and show the summary of the clicked item:
I have been searching this on the web for quite sometime but haven't got any good solution. I am very new to Win32. Any suggestions on how to approach this like which control should I use. Any help will be appreciated.
Standard ListBox and ListView controls do not natively support expanding/collapsing items, however it is possible to implement it in a ListBox with some extra work.
Give the ListBox the LBS_OWNERDRAWVARIABLE list box style to allow the list to contain items of different heights. When a new item is added to the list, the ListBox will send a WM_MEASUREITEM message to its parent window asking for the item's initial height. Return an appropriate height based on whether the item should be displayed as collapsed or expanded.
Once an item has been added to the list, you can send the ListBox a LB_SETITEMHEIGHT message to assign a new height for that item based on whether it should now be displayed collapsed or expanded. Then invalidate the ListBox to trigger a repaint of the items.
The LBS_OWNERDRAW... styles require you to manually draw each list item whenever the ListBox sends a WM_DRAWITEM message to its parent window. You can draw the requested item on the provided HDC however you want, such as with the DrawText() function, configuring its parameters based on whether the item's text is currently being displayed as collapsed or expanded. Also use the state information provided by the message itself to configure the HDC's font and background/foreground colors as desired (particularly important when rendering items in the selected and focused states).
With that in place, all you have left to do is make your click handler determine the index of the item being clicked on (via GetMessagePos(), ScreenToClient(), and LB_ITEMFROMPOINT), and then assign it a new height based on its new expanded/collapsed state, and let the resulting repaint draw the new text accordingly.

Highlighting items in TreeView C++ BUILDER

How can i change text color of some specifec item in TreeView?
TreeView is filled in program.
I mean i want to highlight some Treeview item by changing it text color.
You need to owner-draw the TreeView. It has OnCustomDrawItem and OnAdvancedCustomDrawItem events for that purpose. On a per-item basis, you can set the TreeView's Canvas->Font->Color property to whatever you want. Since you have access to the Canvas, you can draw whatever you want, not just customize the text.

How to display dynamic tooltip?

In a customized wxScrolledWindow, there are many nodes and edges which are displayed.
When mouse rolls over some kinds of the nodes, I can calculate which node is covered by the mouse and want to show a tooltip about the information of the nodes.
How to do it?
wxWidgets has a wxTipWindow class that you can use for this. Define an EVT_ENTER_WINDOW mouse event handler. The handler will get called when the mouse cursor is inside one of your nodes. Inside of the handling function you can create a new wxTipWindow to show extra info for your nodes.

Get relative X/Y of a mouse-click on a MFC CListBox item

I have a CListBox with custom drawing being used, and need to detect mouse-clicks within each item to perform actions.
I can listen for mouse-clicks on the main control and mess about translating coords into the local space of the RECT for the item under the mouse. But is it possible to register message handlers for clicks on individual list items... are there messages for that?
You can use the LVM_HITTEST message to find out which item was clicked.
Well you could just listen for the LBN_SELCHANGE notification. This will fire every time the user clicks a new item. It won't activate if the already selected item is selected though. This may, or may not, be a problem.
Beyond that I'm pretty sure you'll need to intercept WM_LBUTTONUP messages and transform them to the list box's client space ...
OR You could just use a single columned CListCtrl (ListView) class with headers turned off (LVS_NOCOLUMNHEADER). You can then trap the NM_CLICK message. Personally, I massively prefer CListCtrl to CListBox. It IS a little more complex but way more powerful :)
Edit: Or you could try using http://msdn.microsoft.com/en-us/library/bb761323(VS.85).aspx
I'm not certain I understand why you need to have the XY coordinate inside each item of a Clistbox ?
anyway,
AFAIK, Individual items are not CWnd derived objects.
You could get the mouse position inside the control with OnLButtonDown (or up), it returns a CPoint.
After that, use CListBox::GetItemRect to get the rect of the currently selected item, do a bit of pixel computation and you should be able to get the XY inside the rect of the selected item.
Max.
Use the DPtoLP function to convert device coordinates into logical coordinates.
http://msdn.microsoft.com/en-us/library/dd162474(v=vs.85).aspx

How to edit columns in-place with CListCtrl?

I want to have CListCtrl.EditLabel() for any column of the list. How can I implement such a feature?
This is doable but it does require a fair bit of stuffing around with mouse clicks and focus events.
In a nutshell you trap the left mouse button down message and convert it into a cell hit details (i.e a row and column index).
With these cell details you can not determine the size and location of the list view cell and also the text value that it contains.
Now create a CEdit control directly over this cell by using size and location details from the previous step and give it the text value of the cell.
The final step is to handle the focus and keyboard enter events for the CEdit so that the text details of the CEdit can be put back into the list view cell.
It does take a fair amount of coding but when done right it does work well as an alternative to a grid control.
Don't attempt with CListCtrl.
Use the MFC Grid Control. We deploy it in an off-the-shelf app with success. It offers in-place edit, checkbox, spin, etc for all cells, as well as column and row headers, auto-size, auto-expand, colors, drag-drop.