Get TreeView item text related to current item handling WM_NOTIFY / NM_CUSTOMDRAW? - winapi

Subject says it all. Is there a way when handling NM_CUSTOMDRAW for a tree view to get the text of the item currently being drawn?
Thanks.

Related

Report item width of items in TreeView via NM_CUSTOMDRAW?

Is there a WM_MEASUREITEM type item for custom drawing treeview items via NM_CUSTOMDRAW? I'd like to be able to report the width the item will actually be once I paint it in the post paint so a horizontal scrollbar doesn't show up when not needed (because I truncate the text with a ...).
Thanks.
AFAIK, there is no equivalent of WM_MEASUREITEM for a TreeView control.

Treeview control in Win32 API - how to display a single treeview item using different fonts?

I'm faced with a problem where I need to display some characters in a tree-view item (those belonging to the Symbol charset) using Symbol font while others in the default System font (Segoi UI on my Windows 7).
Custom draw allows us to draw different items using different fonts, but I would like to draw the same item string using different fonts as it applies to each character in the string as told above.
So, what I've done with not-so-pleasing results w.r.t. drawing performance upon a horizontal scroll when the number of items is more so far is this:
I disabled horizontal scrolling in my tree-view control using TVS_NOHSCROLL style (since I'm using my own scroll bar control inside the tree-view window to handle all horizontal scrolling)
I sub-classed the treeview control and in the sub-classed winproc, I handle the horizontal scroll notification and mouse notification (where I do my own hittesting and send message like TVM_EXPAND and TVM_SELECT as a result of mosue clicks/double-clicks). Also the scroll bar range is set based on how wide my custom drawn string is (the maximum length amongst all items).
I draw the string for each item upon receiving CDDS_ITEMPOSTPAINT using my own fonts for each character in the item.
The above approach (I left out some details for the sake of brevity) works BUT there are some problems which makes me post this question here and look for an alternare way:
Problems:
The horizontal scroll bar control I create is hosted "inside" the tree-view control at the bottom of the tree-view window. However, when the number of items goes beyond what the tree-view client area can accommodate vertically, the last visible tree-view item gets obscured by the scroll bar control. This can be solved by not making the scroll bar a child of the tree-view and hosting it outside the tree-view window just below it. But I don't want to do this since the scroll bar should typically be a child window of the tree-view.
This is the major one. Since I draw the items myself at each horizontal scroll, the drawing performance upon horizontal scrolling is very slow and also leads to flicker upon scrolling.
Any ideas will be much appreciated as I've been grappling with this for the last one week without success.
I can also post the relevant code here if you want to see the approach I took but I'm sure there shoould be a better approach to this and there must be some other people who would've faced this problem and solved it in the past.
Thanks in advance.
Custom-draw allows you to draw items however you want. You are not limited to a single font per item. When you receive the NM_CUSTOMDRAW notification, draw whatever you want on the provided HDC for the specified item. You can draw pieces of text in one font, pieces of text in a different font, etc. Be sure to return CDRF_SKIPDEFAULT so the TreeView itself will not try to draw anything on the item.
#Anurag S Sharma: I tried to edit this into Remy's answer. It's incomplete as is, but addresses your comment/concerns and answers this particularly vexing/useful question...
The problem is that ff I return CDRF_SKIPDEFAULT, Windows does not even draw the +/- buttons (expanding/collapsing) nor the indent lines in the control which I do want Windows to draw. – Anurag S Sharma
To retain the lines, buttons, and icons you can use ExcludeClipRect to mask only the text region and instead of returning CDRF_SKIPDEFAULT, return 0 as if you didn't draw anything. This itself would not be necessary if the text of the tree item was empty, except that the margins of the text will always be drawn by the default handler (note that Microsoft's controls do not always respect clipping shapes, but in this case they do.)
To replicate the classic TreeView label style in your custom draw procedure you need to do something like the following:
HTREEITEM item = (HTREEITEM)p->dwItemSpec;
TreeView_GetItemRect(p->hdr.hwndFrom,item,&p->rc,1);
RECT cr, rc = p->rc; GetClientRect(p->hdr.hwndFrom,&cr);
DrawTextW(p->hdc,text,-1,&rc,DT_CALCRECT|DT_NOPREFIX|DT_NOCLIP);
rc.right+=4; rc.bottom+=2; IntersectRect(&rc,&cr,&rc);
ExtTextOutW(p->hdc,rc.left+2,rc.top+1,ETO_CLIPPED|ETO_OPAQUE,&rc,text,wcslen(text),0);

position of a tab control tooltip

I created a tab control with TCS_TOOLTIPS style, hence when mouse is over tab items, it displays a tooltip which shows some information.
The tooltip always has the same x-position as the cursor and below the cursor.
I want to make the y-position of the tooltip exact at the bottom of the tab control. In this case, I need to increase the x-position of the tooltip also, in order to avoid the cursor and the tooltip overlap.
But I can not find any information to adjust the position of a tooltip of a tab control.
Is this related to TTM_TRACKPOSITION flag of TOOLINFO? When I created this tab control, I knows only : get hwnd of tooltip by sending TCM_GETTOOLTIPS message ; Treat WM_NOTIFY message and fill TTN_GETDISPINFO structure to display the tooltip. But I didn't find any information about the position.
Sub-class the tooltip control and modify it's position by catching the WM_WINDOWPOSCHANGING message.

Win32: How do I get the listbox for a combobox

I'm writing some code and I need to get the window handle of the listbox associated with a combo box. When looking in spy++, it looks like the parent of the listbox is the desktop, not the combo box. How can I programmatically find the listbox window handle?
Send CB_GETCOMBOBOXINFO to the combo box, and it fills in a COMBOBOXINFO structure, which contains the window handles to the edit control and the list box control.

TreeView with custom drawn TreeNode

I am trying to add a custom icon near the text of a TreeNode, so the items could have a "checked/unchecked" state displayed. I don't want to use a checkbox for that.
Any ideas?
Thanks
Assuming you are using .net and Windows Forms.
You must set DrawMode property of TreeView to TreeViewDrawMode.OwnerDrawAll. Once you do this, treeview's DrawNode event will fire each time a tree node is being drawn. Handle that event and draw your items manually.
You will get DrawTreeNodeEventArgs as the event arguments. State property of it will tell you which state of the tree item you must draw. e.Bounds will help you for determining bounds and you can use e.Graphics for drawing. You can find more detailed information here:
http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.drawnode.aspx
But prepare to invest multiple hours.

Resources