*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
*
* Note that TREEVIEW_INFO * and HTREEITEM are the same thing.
*
- * Note2: All items always! have valid (allocated) pszText field.
- * If item's text == LPSTR_TEXTCALLBACKA we allocate buffer
+ * Note2: If item's text == LPSTR_TEXTCALLBACKA we allocate buffer
* of size TEXT_CALLBACK_SIZE in DoSetItem.
* We use callbackMask to keep track of fields to be updated.
*
* TODO:
- * missing notifications: NM_SETCURSOR, TVN_GETINFOTIP, TVN_KEYDOWN,
+ * missing notifications: TVN_GETINFOTIP, TVN_KEYDOWN,
* TVN_SETDISPINFO, TVN_SINGLEEXPAND
*
* missing styles: TVS_FULLROWSELECT, TVS_INFOTIP, TVS_RTLREADING,
#include "wine/unicode.h"
#include "wine/debug.h"
+WINE_DEFAULT_DEBUG_CHANNEL(treeview);
+
/* internal structures */
typedef struct _TREEITEM /* HTREEITEM is a _TREEINFO *. */
HTREEITEM selectedItem; /* handle to selected item or 0 if none */
HTREEITEM hotItem; /* handle currently under cursor, 0 if none */
HTREEITEM focusedItem; /* item that was under the cursor when WM_LBUTTONDOWN was received */
+ HTREEITEM editItem; /* item being edited with builtin edit box */
HTREEITEM firstVisible; /* handle to first visible item */
LONG maxVisibleOrder;
int stateImageWidth;
HDPA items;
- DWORD lastKeyPressTimestamp; /* Added */
- WPARAM charCode; /* Added */
- INT nSearchParamLength; /* Added */
- WCHAR szSearchParam[ MAX_PATH ]; /* Added */
+ DWORD lastKeyPressTimestamp;
+ WPARAM charCode;
+ INT nSearchParamLength;
+ WCHAR szSearchParam[ MAX_PATH ];
} TREEVIEW_INFO;
#define TV_VSCROLL 0x02 /* (horizontal/vertical) */
#define TV_LDRAG 0x04 /* Lbutton pushed to start drag */
#define TV_LDRAGGING 0x08 /* Lbutton pushed, mouse moved. */
-#define TV_RDRAG 0x10 /* dito Rbutton */
+#define TV_RDRAG 0x10 /* ditto Rbutton */
#define TV_RDRAGGING 0x20
/* bitflags for infoPtr->timer */
#define TV_EDIT_TIMER 2
#define TV_EDIT_TIMER_SET 2
-
-VOID TREEVIEW_Register (VOID);
-VOID TREEVIEW_Unregister (VOID);
-
-
-WINE_DEFAULT_DEBUG_CHANNEL(treeview);
-
-
#define TEXT_CALLBACK_SIZE 260
#define TREEVIEW_LEFT_MARGIN 8
#define OVERLAYIMAGEINDEX(x) (((x) >> 8) & 0x0f)
#define ISVISIBLE(x) ((x)->visibleOrder >= 0)
+#define GETLINECOLOR(x) ((x) == CLR_DEFAULT ? comctl32_color.clrGrayText : (x))
+#define GETBKCOLOR(x) ((x) == CLR_NONE ? comctl32_color.clrWindow : (x))
+#define GETTXTCOLOR(x) ((x) == CLR_NONE ? comctl32_color.clrWindowText : (x))
+#define GETINSCOLOR(x) ((x) == CLR_DEFAULT ? comctl32_color.clrBtnText : (x))
static const WCHAR themeClass[] = { 'T','r','e','e','v','i','e','w',0 };
typedef VOID (*TREEVIEW_ItemEnumFunc)(TREEVIEW_INFO *, TREEVIEW_ITEM *,LPVOID);
-static VOID TREEVIEW_Invalidate(TREEVIEW_INFO *, TREEVIEW_ITEM *);
+static VOID TREEVIEW_Invalidate(const TREEVIEW_INFO *, const TREEVIEW_ITEM *);
static LRESULT TREEVIEW_DoSelectItem(TREEVIEW_INFO *, INT, HTREEITEM, INT);
static VOID TREEVIEW_SetFirstVisible(TREEVIEW_INFO *, TREEVIEW_ITEM *, BOOL);
static LRESULT TREEVIEW_EnsureVisible(TREEVIEW_INFO *, HTREEITEM, BOOL);
-static LRESULT TREEVIEW_RButtonUp(TREEVIEW_INFO *, LPPOINT);
+static LRESULT TREEVIEW_RButtonUp(const TREEVIEW_INFO *, const POINT *);
static LRESULT TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel);
static VOID TREEVIEW_UpdateScrollBars(TREEVIEW_INFO *infoPtr);
static LRESULT TREEVIEW_HScroll(TREEVIEW_INFO *, WPARAM);
-static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND wParam, UINT lParam);
-
/* Random Utilities *****************************************************/
/* Don't call this. Nothing wants an item index. */
static inline int
-TREEVIEW_GetItemIndex(TREEVIEW_INFO *infoPtr, HTREEITEM handle)
+TREEVIEW_GetItemIndex(const TREEVIEW_INFO *infoPtr, HTREEITEM handle)
{
- assert(infoPtr != NULL);
-
return DPA_GetPtrIndex(infoPtr->items, handle);
}
/* Checks if item has changed and needs to be redrawn */
-static inline BOOL item_changed (TREEVIEW_ITEM *tiOld, TREEVIEW_ITEM *tiNew, LPTVITEMEXW tvChange)
+static inline BOOL item_changed (const TREEVIEW_ITEM *tiOld, const TREEVIEW_ITEM *tiNew,
+ const TVITEMEXW *tvChange)
{
/* Number of children has changed */
if ((tvChange->mask & TVIF_CHILDREN) && (tiOld->cChildren != tiNew->cChildren))
* This method checks that handle is an item for this tree.
*/
static BOOL
-TREEVIEW_ValidItem(TREEVIEW_INFO *infoPtr, HTREEITEM handle)
+TREEVIEW_ValidItem(const TREEVIEW_INFO *infoPtr, HTREEITEM handle)
{
if (TREEVIEW_GetItemIndex(infoPtr, handle) == -1)
{
}
static inline HFONT
-TREEVIEW_FontForItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
+TREEVIEW_FontForItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
{
if ((infoPtr->dwStyle & TVS_TRACKSELECT) && (item == infoPtr->hotItem))
return infoPtr->hUnderlineFont;
/* for trace/debugging purposes only */
static const char *
-TREEVIEW_ItemName(TREEVIEW_ITEM *item)
+TREEVIEW_ItemName(const TREEVIEW_ITEM *item)
{
if (item == NULL) return "<null item>";
if (item->pszText == LPSTR_TEXTCALLBACKW) return "<callback>";
/* An item is not a child of itself. */
static BOOL
-TREEVIEW_IsChildOf(TREEVIEW_ITEM *parent, TREEVIEW_ITEM *child)
+TREEVIEW_IsChildOf(const TREEVIEW_ITEM *parent, const TREEVIEW_ITEM *child)
{
do
{
* of a tree node
*/
static TREEVIEW_ITEM *
-TREEVIEW_GetLastListItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem)
+TREEVIEW_GetLastListItem(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem)
{
if (!wineItem)
return NULL;
* considering the tree hierarchy.
*/
static TREEVIEW_ITEM *
-TREEVIEW_GetPrevListItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *tvItem)
+TREEVIEW_GetPrevListItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *tvItem)
{
if (tvItem->prevSibling)
{
* considering the tree hierarchy.
*/
static TREEVIEW_ITEM *
-TREEVIEW_GetNextListItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *tvItem)
+TREEVIEW_GetNextListItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *tvItem)
{
- assert(tvItem != NULL);
-
/*
* If this item has children and is expanded, return the first child
*/
* forward if count is >0.
*/
static TREEVIEW_ITEM *
-TREEVIEW_GetListItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
+TREEVIEW_GetListItem(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
LONG count)
{
- TREEVIEW_ITEM *(*next_item)(TREEVIEW_INFO *, TREEVIEW_ITEM *);
+ TREEVIEW_ITEM *(*next_item)(const TREEVIEW_INFO *, const TREEVIEW_ITEM *);
TREEVIEW_ITEM *previousItem;
assert(wineItem != NULL);
/* Notifications ************************************************************/
-static INT get_notifycode(TREEVIEW_INFO *infoPtr, INT code)
+static INT get_notifycode(const TREEVIEW_INFO *infoPtr, INT code)
{
if (!infoPtr->bNtfUnicode) {
switch (code) {
}
static LRESULT
-TREEVIEW_SendRealNotify(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+TREEVIEW_SendRealNotify(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
- TRACE("wParam=%d, lParam=%ld\n", wParam, lParam);
+ TRACE("wParam=%ld, lParam=%ld\n", wParam, lParam);
return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
}
static BOOL
-TREEVIEW_SendSimpleNotify(TREEVIEW_INFO *infoPtr, UINT code)
+TREEVIEW_SendSimpleNotify(const TREEVIEW_INFO *infoPtr, UINT code)
{
NMHDR nmhdr;
HWND hwnd = infoPtr->hwnd;
nmhdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
nmhdr.code = get_notifycode(infoPtr, code);
- return (BOOL)TREEVIEW_SendRealNotify(infoPtr,
- (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
+ return (BOOL)TREEVIEW_SendRealNotify(infoPtr, nmhdr.idFrom, (LPARAM)&nmhdr);
}
static VOID
-TREEVIEW_TVItemFromItem(TREEVIEW_INFO *infoPtr, UINT mask, TVITEMW *tvItem, TREEVIEW_ITEM *item)
+TREEVIEW_TVItemFromItem(const TREEVIEW_INFO *infoPtr, UINT mask, TVITEMW *tvItem, TREEVIEW_ITEM *item)
{
tvItem->mask = mask;
tvItem->hItem = item;
}
static BOOL
-TREEVIEW_SendTreeviewNotify(TREEVIEW_INFO *infoPtr, UINT code, UINT action,
+TREEVIEW_SendTreeviewNotify(const TREEVIEW_INFO *infoPtr, UINT code, UINT action,
UINT mask, HTREEITEM oldItem, HTREEITEM newItem)
{
HWND hwnd = infoPtr->hwnd;
nmhdr.ptDrag.x = 0;
nmhdr.ptDrag.y = 0;
- ret = (BOOL)TREEVIEW_SendRealNotify(infoPtr,
- (WPARAM)nmhdr.hdr.idFrom,
- (LPARAM)&nmhdr);
+ ret = (BOOL)TREEVIEW_SendRealNotify(infoPtr, nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
if (!infoPtr->bNtfUnicode)
{
Free(nmhdr.itemOld.pszText);
}
static BOOL
-TREEVIEW_SendTreeviewDnDNotify(TREEVIEW_INFO *infoPtr, UINT code,
+TREEVIEW_SendTreeviewDnDNotify(const TREEVIEW_INFO *infoPtr, UINT code,
HTREEITEM dragItem, POINT pt)
{
HWND hwnd = infoPtr->hwnd;
nmhdr.ptDrag.x = pt.x;
nmhdr.ptDrag.y = pt.y;
- return (BOOL)TREEVIEW_SendRealNotify(infoPtr,
- (WPARAM)nmhdr.hdr.idFrom,
- (LPARAM)&nmhdr);
+ return (BOOL)TREEVIEW_SendRealNotify(infoPtr, nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
}
static BOOL
-TREEVIEW_SendCustomDrawNotify(TREEVIEW_INFO *infoPtr, DWORD dwDrawStage,
+TREEVIEW_SendCustomDrawNotify(const TREEVIEW_INFO *infoPtr, DWORD dwDrawStage,
HDC hdc, RECT rc)
{
HWND hwnd = infoPtr->hwnd;
NMTVCUSTOMDRAW nmcdhdr;
LPNMCUSTOMDRAW nmcd;
- TRACE("drawstage:%lx hdc:%p\n", dwDrawStage, hdc);
+ TRACE("drawstage:%x hdc:%p\n", dwDrawStage, hdc);
nmcd = &nmcdhdr.nmcd;
nmcd->hdr.hwndFrom = hwnd;
nmcdhdr.clrTextBk = infoPtr->clrBk;
nmcdhdr.iLevel = 0;
- return (BOOL)TREEVIEW_SendRealNotify(infoPtr,
- (WPARAM)nmcd->hdr.idFrom,
- (LPARAM)&nmcdhdr);
+ return (BOOL)TREEVIEW_SendRealNotify(infoPtr, nmcd->hdr.idFrom, (LPARAM)&nmcdhdr);
}
/* FIXME: need to find out when the flags in uItemState need to be set */
static BOOL
-TREEVIEW_SendCustomDrawItemNotify(TREEVIEW_INFO *infoPtr, HDC hdc,
+TREEVIEW_SendCustomDrawItemNotify(const TREEVIEW_INFO *infoPtr, HDC hdc,
TREEVIEW_ITEM *wineItem, UINT uItemDrawState,
NMTVCUSTOMDRAW *nmcdhdr)
{
nmcd->lItemlParam = wineItem->lParam;
nmcdhdr->iLevel = wineItem->iLevel;
- TRACE("drawstage:%lx hdc:%p item:%lx, itemstate:%x, lItemlParam:%lx\n",
+ TRACE("drawstage:%x hdc:%p item:%lx, itemstate:%x, lItemlParam:%lx\n",
nmcd->dwDrawStage, nmcd->hdc, nmcd->dwItemSpec,
nmcd->uItemState, nmcd->lItemlParam);
- retval = TREEVIEW_SendRealNotify(infoPtr,
- (WPARAM)nmcd->hdr.idFrom,
- (LPARAM)nmcdhdr);
+ retval = TREEVIEW_SendRealNotify(infoPtr, nmcd->hdr.idFrom, (LPARAM)nmcdhdr);
- return (BOOL)retval;
+ return retval;
}
static BOOL
-TREEVIEW_BeginLabelEditNotify(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *editItem)
+TREEVIEW_BeginLabelEditNotify(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *editItem)
{
HWND hwnd = infoPtr->hwnd;
NMTVDISPINFOW tvdi;
}
static void
-TREEVIEW_UpdateDispInfo(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
+TREEVIEW_UpdateDispInfo(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
UINT mask)
{
- NMTVDISPINFOW callback;
+ NMTVDISPINFOEXW callback;
HWND hwnd = infoPtr->hwnd;
TRACE("mask %x callbackMask %x\n", mask, wineItem->callbackMask);
if (mask & TVIF_TEXT)
wineItem->textWidth = 0;
- TREEVIEW_SendRealNotify(infoPtr,
- (WPARAM)callback.hdr.idFrom, (LPARAM)&callback);
+ TREEVIEW_SendRealNotify(infoPtr, callback.hdr.idFrom, (LPARAM)&callback);
/* It may have changed due to a call to SetItem. */
mask &= wineItem->callbackMask;
(LPSTR)callback.item.pszText, -1,
NULL, 0);
buflen = max((len)*sizeof(WCHAR), TEXT_CALLBACK_SIZE);
- newText = (LPWSTR)ReAlloc(wineItem->pszText, buflen);
+ newText = ReAlloc(wineItem->pszText, buflen);
TRACE("returned str %s, len=%d, buflen=%d\n",
debugstr_a((LPSTR)callback.item.pszText), len, buflen);
(LPSTR)callback.item.pszText, -1,
NULL, 0);
buflen = max((len)*sizeof(WCHAR), TEXT_CALLBACK_SIZE);
- newText = (LPWSTR)Alloc(buflen);
+ newText = Alloc(buflen);
TRACE("same buffer str %s, len=%d, buflen=%d\n",
debugstr_a((LPSTR)callback.item.pszText), len, buflen);
(LPSTR)callback.item.pszText, -1,
wineItem->pszText, buflen/sizeof(WCHAR));
wineItem->cchTextMax = buflen/sizeof(WCHAR);
- if (oldText)
- Free(oldText);
+ Free(oldText);
}
}
}
* Just use wineItem->firstChild to check for physical children.
*/
static BOOL
-TREEVIEW_HasChildren(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem)
+TREEVIEW_HasChildren(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem)
{
TREEVIEW_UpdateDispInfo(infoPtr, wineItem, TVIF_CHILDREN);
return wineItem->cChildren > 0;
}
+static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand)
+{
+ INT format;
+
+ TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand);
+
+ if (nCommand != NF_REQUERY) return 0;
+
+ format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY);
+ TRACE("format=%d\n", format);
+
+ if (format != NFR_ANSI && format != NFR_UNICODE) return 0;
+
+ infoPtr->bNtfUnicode = (format == NFR_UNICODE);
+
+ return format;
+}
/* Item Position ********************************************************/
/* Compute linesOffset, stateOffset, imageOffset, textOffset of an item. */
static VOID
-TREEVIEW_ComputeItemInternalMetrics(TREEVIEW_INFO *infoPtr,
- TREEVIEW_ITEM *item)
+TREEVIEW_ComputeItemInternalMetrics(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
{
/* Same effect, different optimisation. */
#if 0
> TVS_LINESATROOT);
#endif
- item->linesOffset = infoPtr->uIndent * (item->iLevel + lar - 1)
+ item->linesOffset = infoPtr->uIndent * (lar ? item->iLevel : item->iLevel - 1)
- infoPtr->scrollX;
item->stateOffset = item->linesOffset + infoPtr->uIndent;
item->imageOffset = item->stateOffset
}
static VOID
-TREEVIEW_ComputeTextWidth(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, HDC hDC)
+TREEVIEW_ComputeTextWidth(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, HDC hDC)
{
HDC hdc;
HFONT hOldFont=0;
}
static VOID
-TREEVIEW_ComputeItemRect(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
+TREEVIEW_ComputeItemRect(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
{
item->rect.top = infoPtr->uItemHeight *
(item->visibleOrder - infoPtr->firstVisible->visibleOrder);
for (item = start; item != NULL;
item = TREEVIEW_GetNextListItem(infoPtr, item))
{
+ if (!ISVISIBLE(item) && order > 0)
+ TREEVIEW_ComputeItemInternalMetrics(infoPtr, item);
item->visibleOrder = order;
order += item->iIntegral;
}
* root must be expanded
*/
static VOID
-TREEVIEW_UpdateSubTree(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *root)
+TREEVIEW_UpdateSubTree(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *root)
{
TREEVIEW_ITEM *sibling;
HDC hdc;
/* Item Allocation **********************************************************/
static TREEVIEW_ITEM *
-TREEVIEW_AllocateItem(TREEVIEW_INFO *infoPtr)
+TREEVIEW_AllocateItem(const TREEVIEW_INFO *infoPtr)
{
TREEVIEW_ITEM *newItem = Alloc(sizeof(TREEVIEW_ITEM));
if (!newItem)
return NULL;
- newItem->iImage = -1;
- newItem->iSelectedImage = -1;
+ /* I_IMAGENONE would make more sense but this is neither what is
+ * documented (MSDN doesn't specify) nor what Windows actually does
+ * (it sets it to zero)... and I can so imagine an application using
+ * inc/dec to toggle the images. */
+ newItem->iImage = 0;
+ newItem->iSelectedImage = 0;
if (DPA_InsertPtr(infoPtr->items, INT_MAX, newItem) == -1)
{
TREEVIEW_FreeItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
{
DPA_DeletePtr(infoPtr->items, DPA_GetPtrIndex(infoPtr->items, item));
- Free(item);
if (infoPtr->selectedItem == item)
infoPtr->selectedItem = NULL;
if (infoPtr->hotItem == item)
infoPtr->dropItem = NULL;
if (infoPtr->insertMarkItem == item)
infoPtr->insertMarkItem = NULL;
+ Free(item);
}
TREEVIEW_InsertBefore(TREEVIEW_ITEM *newItem, TREEVIEW_ITEM *sibling,
TREEVIEW_ITEM *parent)
{
- assert(newItem != NULL);
assert(parent != NULL);
if (sibling != NULL)
TREEVIEW_InsertAfter(TREEVIEW_ITEM *newItem, TREEVIEW_ITEM *sibling,
TREEVIEW_ITEM *parent)
{
- assert(newItem != NULL);
assert(parent != NULL);
if (sibling != NULL)
}
static BOOL
-TREEVIEW_DoSetItemT(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
+TREEVIEW_DoSetItemT(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
const TVITEMEXW *tvItem, BOOL isW)
{
UINT callbackClear = 0;
if (tvItem->mask & TVIF_TEXT)
{
wineItem->textWidth = 0; /* force width recalculation */
- if (tvItem->pszText != LPSTR_TEXTCALLBACKW) /* covers != TEXTCALLBACKA too */
+ if (tvItem->pszText != LPSTR_TEXTCALLBACKW && tvItem->pszText != NULL) /* covers != TEXTCALLBACKA too, and undocumented: pszText of NULL also means TEXTCALLBACK */
{
int len;
LPWSTR newText;
if (!TREEVIEW_ValidItem(infoPtr, parentItem))
{
WARN("invalid parent %p\n", parentItem);
- return (LRESULT)(HTREEITEM)NULL;
+ return 0;
}
}
newItem = TREEVIEW_AllocateItem(infoPtr);
if (newItem == NULL)
- return (LRESULT)(HTREEITEM)NULL;
+ return 0;
newItem->parent = parentItem;
newItem->iIntegral = 1;
+ newItem->visibleOrder = -1;
if (!TREEVIEW_DoSetItemT(infoPtr, newItem, tvItem, isW))
- return (LRESULT)(HTREEITEM)NULL;
+ return 0;
/* After this point, nothing can fail. (Except for TVI_SORT.) */
{
TREEVIEW_ITEM *aChild;
TREEVIEW_ITEM *previousChild = NULL;
+ TREEVIEW_ITEM *originalFirst = parentItem->firstChild;
BOOL bItemInserted = FALSE;
aChild = parentItem->firstChild;
if (comp < 0) /* we are smaller than the current one */
{
TREEVIEW_InsertBefore(newItem, aChild, parentItem);
+ if (infoPtr->firstVisible == originalFirst &&
+ aChild == originalFirst)
+ TREEVIEW_SetFirstVisible(infoPtr, newItem, TRUE);
bItemInserted = TRUE;
break;
}
TREEVIEW_VerifyTree(infoPtr);
+ if (!infoPtr->bRedraw) return (LRESULT)newItem;
+
if (parentItem == infoPtr->root ||
(ISVISIBLE(parentItem) && parentItem->state & TVIS_EXPANDED))
{
}
else
{
- newItem->visibleOrder = -1;
-
/* refresh treeview if newItem is the first item inserted under parentItem */
if (ISVISIBLE(parentItem) && newItem->prevSibling == newItem->nextSibling)
{
TREEVIEW_RemoveItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem);
static void
-TREEVIEW_RemoveAllChildren(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *parentItem)
+TREEVIEW_RemoveAllChildren(TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *parentItem)
{
TREEVIEW_ITEM *kill = parentItem->firstChild;
}
static void
-TREEVIEW_UnlinkItem(TREEVIEW_ITEM *item)
+TREEVIEW_UnlinkItem(const TREEVIEW_ITEM *item)
{
TREEVIEW_ITEM *parentItem = item->parent;
infoPtr->uNumItems--;
- if (wineItem->pszText && wineItem->pszText != LPSTR_TEXTCALLBACKW)
+ if (wineItem->pszText != LPSTR_TEXTCALLBACKW)
Free(wineItem->pszText);
TREEVIEW_FreeItem(infoPtr, wineItem);
TREEVIEW_VerifyTree(infoPtr);
+ if (!infoPtr->bRedraw) return TRUE;
if (visible)
{
/* Get/Set Messages *********************************************************/
static LRESULT
-TREEVIEW_SetRedraw(TREEVIEW_INFO* infoPtr, WPARAM wParam, LPARAM lParam)
+TREEVIEW_SetRedraw(TREEVIEW_INFO* infoPtr, WPARAM wParam)
{
- if(wParam)
- infoPtr->bRedraw = TRUE;
- else
- infoPtr->bRedraw = FALSE;
+ infoPtr->bRedraw = wParam ? TRUE : FALSE;
- return 0;
+ if (infoPtr->bRedraw)
+ {
+ TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
+ TREEVIEW_RecalculateVisibleOrder(infoPtr, NULL);
+ TREEVIEW_UpdateScrollBars(infoPtr);
+ TREEVIEW_Invalidate(infoPtr, NULL);
+ }
+ return 0;
}
static LRESULT
-TREEVIEW_GetIndent(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetIndent(const TREEVIEW_INFO *infoPtr)
{
TRACE("\n");
return infoPtr->uIndent;
static LRESULT
-TREEVIEW_GetToolTips(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetToolTips(const TREEVIEW_INFO *infoPtr)
{
TRACE("\n");
return (LRESULT)infoPtr->hwndToolTip;
}
static LRESULT
-TREEVIEW_GetUnicodeFormat(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetUnicodeFormat(const TREEVIEW_INFO *infoPtr)
{
return infoPtr->bNtfUnicode;
}
static LRESULT
-TREEVIEW_GetScrollTime(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetScrollTime(const TREEVIEW_INFO *infoPtr)
{
return infoPtr->uScrollTime;
}
static LRESULT
-TREEVIEW_GetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam)
+TREEVIEW_GetImageList(const TREEVIEW_INFO *infoPtr, WPARAM wParam)
{
TRACE("\n");
switch (wParam)
{
- case (WPARAM)TVSIL_NORMAL:
+ case TVSIL_NORMAL:
return (LRESULT)infoPtr->himlNormal;
- case (WPARAM)TVSIL_STATE:
+ case TVSIL_STATE:
return (LRESULT)infoPtr->himlState;
default:
/* Compute the natural height for items. */
static UINT
-TREEVIEW_NaturalHeight(TREEVIEW_INFO *infoPtr)
+TREEVIEW_NaturalHeight(const TREEVIEW_INFO *infoPtr)
{
TEXTMETRICW tm;
HDC hdc = GetDC(0);
height = tm.tmHeight + tm.tmExternalLeading + TVHEIGHT_FONT_ADJUST;
if (height < infoPtr->normalImageHeight)
height = infoPtr->normalImageHeight;
+
+ /* Round down, unless we support odd ("non even") heights. */
+ if (!(infoPtr->dwStyle & TVS_NONEVENHEIGHT))
+ height &= ~1;
+
return height;
}
int oldHeight = infoPtr->normalImageHeight;
- TRACE("%x,%p\n", wParam, himlNew);
+ TRACE("%lx,%p\n", wParam, himlNew);
switch (wParam)
{
- case (WPARAM)TVSIL_NORMAL:
+ case TVSIL_NORMAL:
himlOld = infoPtr->himlNormal;
infoPtr->himlNormal = himlNew;
break;
- case (WPARAM)TVSIL_STATE:
+ case TVSIL_STATE:
himlOld = infoPtr->himlState;
infoPtr->himlState = himlNew;
}
/* Round down, unless we support odd ("non even") heights. */
- if (!(infoPtr->dwStyle) & TVS_NONEVENHEIGHT)
+ if (!(infoPtr->dwStyle & TVS_NONEVENHEIGHT))
infoPtr->uItemHeight &= ~1;
if (infoPtr->uItemHeight != prevHeight)
}
static LRESULT
-TREEVIEW_GetItemHeight(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetItemHeight(const TREEVIEW_INFO *infoPtr)
{
TRACE("\n");
return infoPtr->uItemHeight;
static LRESULT
-TREEVIEW_GetFont(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetFont(const TREEVIEW_INFO *infoPtr)
{
TRACE("%p\n", infoPtr->hFont);
return (LRESULT)infoPtr->hFont;
infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont;
DeleteObject(infoPtr->hBoldFont);
+ DeleteObject(infoPtr->hUnderlineFont);
infoPtr->hBoldFont = TREEVIEW_CreateBoldFont(infoPtr->hFont);
infoPtr->hUnderlineFont = TREEVIEW_CreateUnderlineFont(infoPtr->hFont);
static LRESULT
-TREEVIEW_GetLineColor(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetLineColor(const TREEVIEW_INFO *infoPtr)
{
TRACE("\n");
return (LRESULT)infoPtr->clrLine;
static LRESULT
-TREEVIEW_GetTextColor(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetTextColor(const TREEVIEW_INFO *infoPtr)
{
TRACE("\n");
return (LRESULT)infoPtr->clrText;
static LRESULT
-TREEVIEW_GetBkColor(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetBkColor(const TREEVIEW_INFO *infoPtr)
{
TRACE("\n");
return (LRESULT)infoPtr->clrBk;
static LRESULT
-TREEVIEW_GetInsertMarkColor(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetInsertMarkColor(const TREEVIEW_INFO *infoPtr)
{
TRACE("\n");
return (LRESULT)infoPtr->clrInsertMark;
{
COLORREF prevColor = infoPtr->clrInsertMark;
- TRACE("%lx\n", color);
+ TRACE("%x\n", color);
infoPtr->clrInsertMark = color;
return (LRESULT)prevColor;
* input HTREEITEM and the output RECT.
*/
static LRESULT
-TREEVIEW_GetItemRect(TREEVIEW_INFO *infoPtr, BOOL fTextRect, LPRECT lpRect)
+TREEVIEW_GetItemRect(const TREEVIEW_INFO *infoPtr, BOOL fTextRect, LPRECT lpRect)
{
TREEVIEW_ITEM *wineItem;
const HTREEITEM *pItem = (HTREEITEM *)lpRect;
lpRect->bottom = wineItem->rect.bottom;
lpRect->left = wineItem->textOffset;
- lpRect->right = wineItem->textOffset + wineItem->textWidth;
+ if (!wineItem->textWidth)
+ TREEVIEW_ComputeTextWidth(infoPtr, wineItem, 0);
+
+ lpRect->right = wineItem->textOffset + wineItem->textWidth + 4;
}
else
{
*lpRect = wineItem->rect;
}
- TRACE("%s [L:%ld R:%ld T:%ld B:%ld]\n", fTextRect ? "text" : "item",
- lpRect->left, lpRect->right, lpRect->top, lpRect->bottom);
+ TRACE("%s [%s]\n", fTextRect ? "text" : "item", wine_dbgstr_rect(lpRect));
return TRUE;
}
static inline LRESULT
-TREEVIEW_GetVisibleCount(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetVisibleCount(const TREEVIEW_INFO *infoPtr)
{
- /* Suprise! This does not take integral height into account. */
+ /* Surprise! This does not take integral height into account. */
return infoPtr->clientHeight / infoPtr->uItemHeight;
}
static LRESULT
-TREEVIEW_GetItemT(TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
+TREEVIEW_GetItemT(const TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
{
TREEVIEW_ITEM *wineItem;
if (tvItem->mask & TVIF_TEXT)
{
- if (isW)
+ if (wineItem->pszText == NULL)
+ {
+ if (tvItem->cchTextMax > 0)
+ tvItem->pszText[0] = '\0';
+ }
+ else if (isW)
{
if (wineItem->pszText == LPSTR_TEXTCALLBACKW)
{
/* Beware MSDN Library Visual Studio 6.0. It says -1 on failure, 0 on success,
* which is wrong. */
static LRESULT
-TREEVIEW_SetItemT(TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
+TREEVIEW_SetItemT(TREEVIEW_INFO *infoPtr, const TVITEMEXW *tvItem, BOOL isW)
{
TREEVIEW_ITEM *wineItem;
TREEVIEW_ITEM originalItem;
if (!TREEVIEW_ValidItem(infoPtr, wineItem))
return FALSE;
- /* store the orignal item values */
+ /* store the original item values */
originalItem = *wineItem;
if (!TREEVIEW_DoSetItemT(infoPtr, wineItem, tvItem, isW))
}
static LRESULT
-TREEVIEW_GetItemState(TREEVIEW_INFO *infoPtr, HTREEITEM wineItem, UINT mask)
+TREEVIEW_GetItemState(const TREEVIEW_INFO *infoPtr, HTREEITEM wineItem, UINT mask)
{
TRACE("\n");
}
static LRESULT
-TREEVIEW_GetNextItem(TREEVIEW_INFO *infoPtr, UINT which, HTREEITEM wineItem)
+TREEVIEW_GetNextItem(const TREEVIEW_INFO *infoPtr, UINT which, HTREEITEM wineItem)
{
TREEVIEW_ITEM *retval;
static LRESULT
-TREEVIEW_GetCount(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetCount(const TREEVIEW_INFO *infoPtr)
{
TRACE(" %d\n", infoPtr->uNumItems);
return (LRESULT)infoPtr->uNumItems;
}
static VOID
-TREEVIEW_ToggleItemState(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
+TREEVIEW_ToggleItemState(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
{
if (infoPtr->dwStyle & TVS_CHECKBOXES)
{
/* Draw the lines and expand button for an item. Also draws one section
* of the line from item's parent to item's parent's next sibling. */
static void
-TREEVIEW_DrawItemLines(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item)
+TREEVIEW_DrawItemLines(const TREEVIEW_INFO *infoPtr, HDC hdc, const TREEVIEW_ITEM *item)
{
LONG centerx, centery;
BOOL lar = ((infoPtr->dwStyle
& (TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS))
> TVS_LINESATROOT);
HBRUSH hbr, hbrOld;
+ COLORREF clrBk = GETBKCOLOR(infoPtr->clrBk);
if (!lar && item->iLevel == 0)
return;
- hbr = CreateSolidBrush(infoPtr->clrBk);
+ hbr = CreateSolidBrush(clrBk);
hbrOld = SelectObject(hdc, hbr);
-
+
centerx = (item->linesOffset + item->stateOffset) / 2;
centery = (item->rect.top + item->rect.bottom) / 2;
HTREEITEM parent;
LOGBRUSH lb;
- /*
- * Get a dotted grey pen
- */
+ /* Get a dotted grey pen */
lb.lbStyle = BS_SOLID;
- lb.lbColor = infoPtr->clrLine;
+ lb.lbColor = GETLINECOLOR(infoPtr->clrLine);
hNewPen = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, NULL);
hOldPen = SelectObject(hdc, hNewPen);
+ /* Make sure the center is on a dot (using +2 instead
+ * of +1 gives us pixel-by-pixel compat with native) */
+ centery = (centery + 2) & ~1;
+
MoveToEx(hdc, item->stateOffset, centery, NULL);
LineTo(hdc, centerx - 1, centery);
LONG rectsize = min(height, width) / 4;
/* plussize = ceil(rectsize * 3/4) */
LONG plussize = (rectsize + 1) * 3 / 4;
-
- HPEN hNewPen = CreatePen(PS_SOLID, 0, infoPtr->clrLine);
- HPEN hOldPen = SelectObject(hdc, hNewPen);
-
+
+ HPEN new_pen = CreatePen(PS_SOLID, 0, GETLINECOLOR(infoPtr->clrLine));
+ HPEN old_pen = SelectObject(hdc, new_pen);
+
Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1,
centerx + rectsize + 2, centery + rectsize + 2);
-
- SelectObject(hdc, hOldPen);
- DeleteObject(hNewPen);
-
+
+ SelectObject(hdc, old_pen);
+ DeleteObject(new_pen);
+
+ /* draw +/- signs with current text color */
+ new_pen = CreatePen(PS_SOLID, 0, GETTXTCOLOR(infoPtr->clrText));
+ old_pen = SelectObject(hdc, new_pen);
+
if (height < 18 || width < 18)
{
MoveToEx(hdc, centerx - plussize + 1, centery, NULL);
{
Rectangle(hdc, centerx - 1, centery - plussize + 1,
centerx + 2, centery + plussize);
- SetPixel(hdc, centerx - 1, centery, infoPtr->clrBk);
- SetPixel(hdc, centerx + 1, centery, infoPtr->clrBk);
+ SetPixel(hdc, centerx - 1, centery, clrBk);
+ SetPixel(hdc, centerx + 1, centery, clrBk);
}
}
+
+ SelectObject(hdc, old_pen);
+ DeleteObject(new_pen);
}
}
}
}
static void
-TREEVIEW_DrawItem(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem)
+TREEVIEW_DrawItem(const TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem)
{
INT cditem;
HFONT hOldFont;
{
if ((wineItem->state & TVIS_DROPHILITED) || inFocus)
{
- nmcdhdr.clrTextBk = GetSysColor(COLOR_HIGHLIGHT);
- nmcdhdr.clrText = GetSysColor(COLOR_HIGHLIGHTTEXT);
+ nmcdhdr.clrTextBk = comctl32_color.clrHighlight;
+ nmcdhdr.clrText = comctl32_color.clrHighlightText;
}
else
{
- nmcdhdr.clrTextBk = GetSysColor(COLOR_BTNFACE);
- if (infoPtr->clrText == -1)
- nmcdhdr.clrText = GetSysColor(COLOR_WINDOWTEXT);
- else
- nmcdhdr.clrText = infoPtr->clrText;
+ nmcdhdr.clrTextBk = comctl32_color.clrBtnFace;
+ nmcdhdr.clrText = GETTXTCOLOR(infoPtr->clrText);
}
}
else
{
- nmcdhdr.clrTextBk = infoPtr->clrBk;
+ nmcdhdr.clrTextBk = GETBKCOLOR(infoPtr->clrBk);
if ((infoPtr->dwStyle & TVS_TRACKSELECT) && (wineItem == infoPtr->hotItem))
nmcdhdr.clrText = comctl32_color.clrHighlight;
- else if (infoPtr->clrText == -1)
- nmcdhdr.clrText = GetSysColor(COLOR_WINDOWTEXT);
else
- nmcdhdr.clrText = infoPtr->clrText;
+ nmcdhdr.clrText = GETTXTCOLOR(infoPtr->clrText);
}
hOldFont = SelectObject(hdc, TREEVIEW_FontForItem(infoPtr, wineItem));
rcText.left = wineItem->textOffset;
rcText.right = rcText.left + wineItem->textWidth + 4;
- TRACE("drawing text %s at (%ld,%ld)-(%ld,%ld)\n",
- debugstr_w(wineItem->pszText),
- rcText.left, rcText.top, rcText.right, rcText.bottom);
+ TRACE("drawing text %s at (%s)\n",
+ debugstr_w(wineItem->pszText), wine_dbgstr_rect(&rcText));
/* Draw it */
ExtTextOutW(hdc, rcText.left + 2, rcText.top + 1,
int offset;
int left, right;
- hNewPen = CreatePen(PS_SOLID, 2, infoPtr->clrInsertMark);
+ hNewPen = CreatePen(PS_SOLID, 2, GETINSCOLOR(infoPtr->clrInsertMark));
hOldPen = SelectObject(hdc, hNewPen);
if (infoPtr->insertBeforeorAfter)
> infoPtr->clientWidth - GetSystemMetrics(SM_CXVSCROLL))
horz = TRUE;
}
- else if (infoPtr->treeWidth > infoPtr->clientWidth)
+ else if (infoPtr->treeWidth > infoPtr->clientWidth || infoPtr->scrollX > 0)
horz = TRUE;
if (!vert && horz && infoPtr->treeHeight
infoPtr->uInternalStatus |= TV_HSCROLL;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
+ TREEVIEW_HScroll(infoPtr,
+ MAKEWPARAM(SB_THUMBPOSITION, scrollX));
}
else
{
infoPtr->uInternalStatus &= ~TV_HSCROLL;
scrollX = 0;
- }
-
- if (infoPtr->scrollX != scrollX)
- {
- TREEVIEW_HScroll(infoPtr,
- MAKEWPARAM(SB_THUMBPOSITION, scrollX));
+ if (infoPtr->scrollX != 0)
+ {
+ TREEVIEW_HScroll(infoPtr,
+ MAKEWPARAM(SB_THUMBPOSITION, scrollX));
+ }
}
if (!horz)
infoPtr->uInternalStatus &= ~TV_HSCROLL;
}
+static void
+TREEVIEW_FillBkgnd(const TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
+{
+ HBRUSH hBrush;
+ COLORREF clrBk = GETBKCOLOR(infoPtr->clrBk);
+
+ hBrush = CreateSolidBrush(clrBk);
+ FillRect(hdc, rc, hBrush);
+ DeleteObject(hBrush);
+}
+
/* CtrlSpy doesn't mention this, but CorelDRAW's object manager needs it. */
static LRESULT
-TREEVIEW_EraseBackground(TREEVIEW_INFO *infoPtr, HDC hDC)
+TREEVIEW_EraseBackground(const TREEVIEW_INFO *infoPtr, HDC hdc)
{
- HBRUSH hBrush = CreateSolidBrush(infoPtr->clrBk);
RECT rect;
+ TRACE("%p\n", infoPtr);
+
GetClientRect(infoPtr->hwnd, &rect);
- FillRect(hDC, &rect, hBrush);
- DeleteObject(hBrush);
+ TREEVIEW_FillBkgnd(infoPtr, hdc, &rect);
return 1;
}
static void
-TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr, HDC hdc, RECT *rc)
+TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
{
HWND hwnd = infoPtr->hwnd;
RECT rect = *rc;
}
}
- TREEVIEW_UpdateScrollBars(infoPtr);
+ //
+ // This is correct, but is causes and infinite loop of WM_PAINT messages, resulting
+ // in continuous painting of the scroll bar in reactos. Comment out until the real
+ // bug is found
+ //
+ //TREEVIEW_UpdateScrollBars(infoPtr);
if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT)
infoPtr->cdmode =
TREEVIEW_SendCustomDrawNotify(infoPtr, CDDS_POSTPAINT, hdc, rect);
}
+static inline void
+TREEVIEW_InvalidateItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
+{
+ if (item) InvalidateRect(infoPtr->hwnd, &item->rect, TRUE);
+}
+
static void
-TREEVIEW_Invalidate(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
+TREEVIEW_Invalidate(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
{
- if (item != NULL)
+ if (item)
InvalidateRect(infoPtr->hwnd, &item->rect, TRUE);
else
InvalidateRect(infoPtr->hwnd, NULL, TRUE);
}
static LRESULT
-TREEVIEW_Paint(TREEVIEW_INFO *infoPtr, WPARAM wParam)
+TREEVIEW_Paint(TREEVIEW_INFO *infoPtr, HDC hdc_ref)
{
HDC hdc;
PAINTSTRUCT ps;
TRACE("\n");
- if (wParam)
+ if (hdc_ref)
{
- hdc = (HDC)wParam;
- GetClientRect(infoPtr->hwnd, &rc);
- TREEVIEW_EraseBackground(infoPtr, hdc);
+ hdc = hdc_ref;
+ GetClientRect(infoPtr->hwnd, &rc);
}
else
{
hdc = BeginPaint(infoPtr->hwnd, &ps);
- rc = ps.rcPaint;
+ rc = ps.rcPaint;
+ if(ps.fErase)
+ TREEVIEW_FillBkgnd(infoPtr, hdc, &rc);
}
if(infoPtr->bRedraw) /* WM_SETREDRAW sets bRedraw */
TREEVIEW_Refresh(infoPtr, hdc, &rc);
- if (!wParam)
+ if (!hdc_ref)
EndPaint(infoPtr->hwnd, &ps);
return 0;
}
+static LRESULT
+TREEVIEW_PrintClient(TREEVIEW_INFO *infoPtr, HDC hdc, DWORD options)
+{
+ FIXME("Partial Stub: (hdc=%p options=0x%08x)\n", hdc, options);
+
+ if ((options & PRF_CHECKVISIBLE) && !IsWindowVisible(infoPtr->hwnd))
+ return 0;
+
+ if (options & PRF_ERASEBKGND)
+ TREEVIEW_EraseBackground(infoPtr, hdc);
+
+ if (options & PRF_CLIENT)
+ {
+ RECT rc;
+ GetClientRect(infoPtr->hwnd, &rc);
+ TREEVIEW_Refresh(infoPtr, hdc, &rc);
+ }
+
+ return 0;
+}
/* Sorting **************************************************************/
* Forward the DPA local callback to the treeview owner callback
*/
static INT WINAPI
-TREEVIEW_CallBackCompare(TREEVIEW_ITEM *first, TREEVIEW_ITEM *second, LPTVSORTCB pCallBackSort)
+TREEVIEW_CallBackCompare(const TREEVIEW_ITEM *first, const TREEVIEW_ITEM *second,
+ const TVSORTCB *pCallBackSort)
{
/* Forward the call to the client-defined callback */
return pCallBackSort->lpfnCompare(first->lParam,
*/
static INT WINAPI
TREEVIEW_SortOnName(TREEVIEW_ITEM *first, TREEVIEW_ITEM *second,
- TREEVIEW_INFO *infoPtr)
+ const TREEVIEW_INFO *infoPtr)
{
TREEVIEW_UpdateDispInfo(infoPtr, first, TVIF_TEXT);
TREEVIEW_UpdateDispInfo(infoPtr, second, TVIF_TEXT);
/* Returns the number of physical children belonging to item. */
static INT
-TREEVIEW_CountChildren(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
+TREEVIEW_CountChildren(const TREEVIEW_ITEM *item)
{
INT cChildren = 0;
HTREEITEM hti;
/* Returns a DPA containing a pointer to each physical child of item in
* sibling order. If item has no children, an empty DPA is returned. */
static HDPA
-TREEVIEW_BuildChildDPA(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
+TREEVIEW_BuildChildDPA(const TREEVIEW_ITEM *item)
{
HTREEITEM child = item->firstChild;
*/
static LRESULT
-TREEVIEW_Sort(TREEVIEW_INFO *infoPtr, BOOL fRecurse, HTREEITEM parent,
+TREEVIEW_Sort(TREEVIEW_INFO *infoPtr, HTREEITEM parent,
LPTVSORTCB pSort)
{
INT cChildren;
lpCompare = (LPARAM)infoPtr;
}
- cChildren = TREEVIEW_CountChildren(infoPtr, parent);
+ cChildren = TREEVIEW_CountChildren(parent);
/* Make sure there is something to sort */
if (cChildren > 1)
HTREEITEM nextItem = 0;
HTREEITEM prevItem = 0;
- HDPA sortList = TREEVIEW_BuildChildDPA(infoPtr, parent);
+ HDPA sortList = TREEVIEW_BuildChildDPA(parent);
if (sortList == NULL)
return FALSE;
/* The order of DPA entries has been changed, so fixup the
* nextSibling and prevSibling pointers. */
- item = (HTREEITEM)DPA_GetPtr(sortList, count++);
- while ((nextItem = (HTREEITEM)DPA_GetPtr(sortList, count++)) != NULL)
+ item = DPA_GetPtr(sortList, count++);
+ while ((nextItem = DPA_GetPtr(sortList, count++)) != NULL)
{
- /* link the two current item toghether */
+ /* link the two current item together */
item->nextSibling = nextItem;
nextItem->prevSibling = item;
* and sort the children of the TV item specified in lParam
*/
static LRESULT
-TREEVIEW_SortChildrenCB(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPTVSORTCB pSort)
+TREEVIEW_SortChildrenCB(TREEVIEW_INFO *infoPtr, LPTVSORTCB pSort)
{
- return TREEVIEW_Sort(infoPtr, wParam, pSort->hParent, pSort);
+ return TREEVIEW_Sort(infoPtr, pSort->hParent, pSort);
}
* Sort the children of the TV item specified in lParam.
*/
static LRESULT
-TREEVIEW_SortChildren(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+TREEVIEW_SortChildren(TREEVIEW_INFO *infoPtr, LPARAM lParam)
{
- return TREEVIEW_Sort(infoPtr, (BOOL)wParam, (HTREEITEM)lParam, NULL);
+ return TREEVIEW_Sort(infoPtr, (HTREEITEM)lParam, NULL);
}
/* Expansion/Collapse ***************************************************/
static BOOL
-TREEVIEW_SendExpanding(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
+TREEVIEW_SendExpanding(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
UINT action)
{
return !TREEVIEW_SendTreeviewNotify(infoPtr, TVN_ITEMEXPANDINGW, action,
}
static VOID
-TREEVIEW_SendExpanded(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
+TREEVIEW_SendExpanded(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
UINT action)
{
TREEVIEW_SendTreeviewNotify(infoPtr, TVN_ITEMEXPANDEDW, action,
{
scrollRect.top = nextItem->rect.top;
- ScrollWindowEx (infoPtr->hwnd, 0, scrollDist, &scrollRect, NULL,
+ ScrollWindowEx (infoPtr->hwnd, 0, scrollDist, &scrollRect, &scrollRect,
NULL, NULL, SW_ERASE | SW_INVALIDATE);
TREEVIEW_Invalidate(infoPtr, wineItem);
} else {
if (bExpandPartial)
FIXME("TVE_EXPANDPARTIAL not implemented\n");
- TREEVIEW_RecalculateVisibleOrder(infoPtr, wineItem);
- TREEVIEW_UpdateSubTree(infoPtr, wineItem);
- TREEVIEW_UpdateScrollBars(infoPtr);
-
- scrollRect.left = 0;
- scrollRect.bottom = infoPtr->treeHeight;
- scrollRect.right = infoPtr->clientWidth;
- if (nextItem)
+ if (ISVISIBLE(wineItem))
{
- scrollDist = nextItem->rect.top - orgNextTop;
- scrollRect.top = orgNextTop;
+ TREEVIEW_RecalculateVisibleOrder(infoPtr, wineItem);
+ TREEVIEW_UpdateSubTree(infoPtr, wineItem);
+ TREEVIEW_UpdateScrollBars(infoPtr);
- ScrollWindowEx (infoPtr->hwnd, 0, scrollDist, &scrollRect, NULL,
- NULL, NULL, SW_ERASE | SW_INVALIDATE);
- TREEVIEW_Invalidate (infoPtr, wineItem);
- } else {
- scrollRect.top = wineItem->rect.top;
- InvalidateRect(infoPtr->hwnd, &scrollRect, FALSE);
- }
+ scrollRect.left = 0;
+ scrollRect.bottom = infoPtr->treeHeight;
+ scrollRect.right = infoPtr->clientWidth;
+ if (nextItem)
+ {
+ scrollDist = nextItem->rect.top - orgNextTop;
+ scrollRect.top = orgNextTop;
+
+ ScrollWindowEx (infoPtr->hwnd, 0, scrollDist, &scrollRect, NULL,
+ NULL, NULL, SW_ERASE | SW_INVALIDATE);
+ TREEVIEW_Invalidate (infoPtr, wineItem);
+ } else {
+ scrollRect.top = wineItem->rect.top;
+ InvalidateRect(infoPtr->hwnd, &scrollRect, FALSE);
+ }
- /* Scroll up so that as many children as possible are visible.
- * This fails when expanding causes an HScroll bar to appear, but we
- * don't know that yet, so the last item is obscured. */
- if (wineItem->firstChild != NULL)
- {
- int nChildren = wineItem->lastChild->visibleOrder
- - wineItem->firstChild->visibleOrder + 1;
+ /* Scroll up so that as many children as possible are visible.
+ * This fails when expanding causes an HScroll bar to appear, but we
+ * don't know that yet, so the last item is obscured. */
+ if (wineItem->firstChild != NULL)
+ {
+ int nChildren = wineItem->lastChild->visibleOrder
+ - wineItem->firstChild->visibleOrder + 1;
- int visible_pos = wineItem->visibleOrder
- - infoPtr->firstVisible->visibleOrder;
+ int visible_pos = wineItem->visibleOrder
+ - infoPtr->firstVisible->visibleOrder;
- int rows_below = TREEVIEW_GetVisibleCount(infoPtr) - visible_pos - 1;
+ int rows_below = TREEVIEW_GetVisibleCount(infoPtr) - visible_pos - 1;
- if (visible_pos > 0 && nChildren > rows_below)
- {
- int scroll = nChildren - rows_below;
+ if (visible_pos > 0 && nChildren > rows_below)
+ {
+ int scroll = nChildren - rows_below;
- if (scroll > visible_pos)
- scroll = visible_pos;
+ if (scroll > visible_pos)
+ scroll = visible_pos;
- if (scroll > 0)
- {
- TREEVIEW_ITEM *newFirstVisible
- = TREEVIEW_GetListItem(infoPtr, infoPtr->firstVisible,
- scroll);
+ if (scroll > 0)
+ {
+ TREEVIEW_ITEM *newFirstVisible
+ = TREEVIEW_GetListItem(infoPtr, infoPtr->firstVisible,
+ scroll);
- TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE);
- }
- }
+ TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE);
+ }
+ }
+ }
}
return TRUE;
/* Hit-Testing **********************************************************/
static TREEVIEW_ITEM *
-TREEVIEW_HitTestPoint(TREEVIEW_INFO *infoPtr, POINT pt)
+TREEVIEW_HitTestPoint(const TREEVIEW_INFO *infoPtr, POINT pt)
{
TREEVIEW_ITEM *wineItem;
LONG row;
}
static LRESULT
-TREEVIEW_HitTest(TREEVIEW_INFO *infoPtr, LPTVHITTESTINFO lpht)
+TREEVIEW_HitTest(const TREEVIEW_INFO *infoPtr, LPTVHITTESTINFO lpht)
{
TREEVIEW_ITEM *wineItem;
RECT rect;
if (status)
{
lpht->flags = status;
- return (LRESULT)(HTREEITEM)NULL;
+ return 0;
}
wineItem = TREEVIEW_HitTestPoint(infoPtr, lpht->pt);
if (!wineItem)
{
lpht->flags = TVHT_NOWHERE;
- return (LRESULT)(HTREEITEM)NULL;
+ return 0;
}
if (x >= wineItem->textOffset + wineItem->textWidth)
}
lpht->hItem = wineItem;
- TRACE("(%ld,%ld):result %x\n", lpht->pt.x, lpht->pt.y, lpht->flags);
+ TRACE("(%d,%d):result %x\n", lpht->pt.x, lpht->pt.y, lpht->flags);
return (LRESULT)wineItem;
}
/* Item Label Editing ***************************************************/
static LRESULT
-TREEVIEW_GetEditControl(TREEVIEW_INFO *infoPtr)
+TREEVIEW_GetEditControl(const TREEVIEW_INFO *infoPtr)
{
return (LRESULT)infoPtr->hwndEdit;
}
return TRUE;
break;
+ case WM_DESTROY:
+ {
+ WNDPROC editProc = infoPtr->wpEditOrig;
+ infoPtr->wpEditOrig = 0;
+ SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (DWORD_PTR)editProc);
+ return CallWindowProcW(editProc, hwnd, uMsg, wParam, lParam);
+ }
+
case WM_GETDLGCODE:
return DLGC_WANTARROWS | DLGC_WANTALLKEYS;
case WM_KEYDOWN:
- if (wParam == (WPARAM)VK_ESCAPE)
+ if (wParam == VK_ESCAPE)
{
bCancel = TRUE;
break;
}
- else if (wParam == (WPARAM)VK_RETURN)
+ else if (wParam == VK_RETURN)
{
break;
}
static LRESULT
TREEVIEW_Command(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
- TRACE("%x %ld\n", wParam, lParam);
+ TRACE("code=%x, id=%x, handle=%lx\n", HIWORD(wParam), LOWORD(wParam), lParam);
switch (HIWORD(wParam))
{
* Adjust the edit window size
*/
WCHAR buffer[1024];
- TREEVIEW_ITEM *editItem = infoPtr->selectedItem;
+ TREEVIEW_ITEM *editItem = infoPtr->editItem;
HDC hdc = GetDC(infoPtr->hwndEdit);
SIZE sz;
- int len;
HFONT hFont, hOldFont = 0;
+ TRACE("edit=%p\n", infoPtr->hwndEdit);
+
+ if (!IsWindow(infoPtr->hwndEdit) || !hdc) return FALSE;
+
infoPtr->bLabelChanged = TRUE;
- len = GetWindowTextW(infoPtr->hwndEdit, buffer, sizeof(buffer));
+ GetWindowTextW(infoPtr->hwndEdit, buffer, sizeof(buffer)/sizeof(buffer[0]));
/* Select font to get the right dimension of the string */
hFont = (HFONT)SendMessageW(infoPtr->hwndEdit, WM_GETFONT, 0, 0);
ReleaseDC(infoPtr->hwnd, hdc);
break;
}
+ case EN_KILLFOCUS:
+ /* apparently we should respect passed handle value */
+ if (infoPtr->hwndEdit != (HWND)lParam) return FALSE;
+
+ TREEVIEW_EndEditLabelNow(infoPtr, FALSE);
+ break;
default:
return SendMessageW(infoPtr->hwndNotify, WM_COMMAND, wParam, lParam);
HWND hwnd = infoPtr->hwnd;
HWND hwndEdit;
SIZE sz;
- TREEVIEW_ITEM *editItem = hItem;
HINSTANCE hinst = (HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE);
HDC hdc;
HFONT hOldFont=0;
TEXTMETRICW textMetric;
- static const WCHAR EditW[] = {'E','d','i','t',0};
TRACE("%p %p\n", hwnd, hItem);
- if (!TREEVIEW_ValidItem(infoPtr, editItem))
+ if (!TREEVIEW_ValidItem(infoPtr, hItem))
return NULL;
if (infoPtr->hwndEdit)
infoPtr->bLabelChanged = FALSE;
- /* Make sure that edit item is selected */
- TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, hItem, TVC_UNKNOWN);
+ /* make edit item visible */
TREEVIEW_EnsureVisible(infoPtr, hItem, TRUE);
- TREEVIEW_UpdateDispInfo(infoPtr, editItem, TVIF_TEXT);
+ TREEVIEW_UpdateDispInfo(infoPtr, hItem, TVIF_TEXT);
hdc = GetDC(hwnd);
/* Select the font to get appropriate metric dimensions */
}
/* Get string length in pixels */
- GetTextExtentPoint32W(hdc, editItem->pszText, strlenW(editItem->pszText),
- &sz);
+ if (hItem->pszText)
+ GetTextExtentPoint32W(hdc, hItem->pszText, strlenW(hItem->pszText),
+ &sz);
+ else
+ GetTextExtentPoint32A(hdc, "", 0, &sz);
/* Add Extra spacing for the next character */
GetTextMetricsW(hdc, &textMetric);
sz.cx += (textMetric.tmMaxCharWidth * 2);
sz.cx = max(sz.cx, textMetric.tmMaxCharWidth * 3);
- sz.cx = min(sz.cx, infoPtr->clientWidth - editItem->textOffset + 2);
+ sz.cx = min(sz.cx, infoPtr->clientWidth - hItem->textOffset + 2);
if (infoPtr->hFont != 0)
{
}
ReleaseDC(hwnd, hdc);
+
+ infoPtr->editItem = hItem;
+
hwndEdit = CreateWindowExW(WS_EX_LEFT,
- EditW,
+ WC_EDITW,
0,
WS_CHILD | WS_BORDER | ES_AUTOHSCROLL |
WS_CLIPSIBLINGS | ES_WANTRETURN |
- ES_LEFT, editItem->textOffset - 2,
- editItem->rect.top - 1, sz.cx + 3,
- editItem->rect.bottom -
- editItem->rect.top + 3, hwnd, 0, hinst, 0);
+ ES_LEFT, hItem->textOffset - 2,
+ hItem->rect.top - 1, sz.cx + 3,
+ hItem->rect.bottom -
+ hItem->rect.top + 3, hwnd, 0, hinst, 0);
/* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0); */
infoPtr->hwndEdit = hwndEdit;
GetWindowLongW(hwndEdit, GWL_STYLE) | WS_BORDER);
SendMessageW(hwndEdit, WM_SETFONT,
- (WPARAM)TREEVIEW_FontForItem(infoPtr, editItem), FALSE);
+ (WPARAM)TREEVIEW_FontForItem(infoPtr, hItem), FALSE);
infoPtr->wpEditOrig = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC,
(DWORD_PTR)
TREEVIEW_Edit_SubclassProc);
- if (TREEVIEW_BeginLabelEditNotify(infoPtr, editItem))
+ if (TREEVIEW_BeginLabelEditNotify(infoPtr, hItem))
{
DestroyWindow(hwndEdit);
infoPtr->hwndEdit = 0;
+ infoPtr->editItem = NULL;
return NULL;
}
- infoPtr->selectedItem = hItem;
- SetWindowTextW(hwndEdit, editItem->pszText);
+ if (hItem->pszText)
+ SetWindowTextW(hwndEdit, hItem->pszText);
+
SetFocus(hwndEdit);
SendMessageW(hwndEdit, EM_SETSEL, 0, -1);
ShowWindow(hwndEdit, SW_SHOW);
TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
{
HWND hwnd = infoPtr->hwnd;
- TREEVIEW_ITEM *editedItem = infoPtr->selectedItem;
+ TREEVIEW_ITEM *editedItem = infoPtr->editItem;
NMTVDISPINFOW tvdi;
BOOL bCommit;
WCHAR tmpText[1024] = { '\0' };
WCHAR *newText = tmpText;
int iLength = 0;
- if (!infoPtr->hwndEdit)
- return FALSE;
+ if (!IsWindow(infoPtr->hwndEdit)) return FALSE;
tvdi.hdr.hwndFrom = hwnd;
tvdi.hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
tvdi.item.cchTextMax = 0;
}
- bCommit = (BOOL)TREEVIEW_SendRealNotify(infoPtr,
- (WPARAM)tvdi.hdr.idFrom, (LPARAM)&tvdi);
+ bCommit = (BOOL)TREEVIEW_SendRealNotify(infoPtr, tvdi.hdr.idFrom, (LPARAM)&tvdi);
if (!bCancel && bCommit) /* Apply the changes */
{
if (strcmpW(newText, editedItem->pszText) != 0)
{
- if (NULL == ReAlloc(editedItem->pszText, iLength + 1))
+ WCHAR *ptr = ReAlloc(editedItem->pszText, sizeof(WCHAR)*(iLength + 1));
+ if (ptr == NULL)
{
ERR("OutOfMemory, cannot allocate space for label\n");
+ if(newText != tmpText) Free(newText);
DestroyWindow(infoPtr->hwndEdit);
infoPtr->hwndEdit = 0;
+ infoPtr->editItem = NULL;
return FALSE;
}
else
{
+ editedItem->pszText = ptr;
editedItem->cchTextMax = iLength + 1;
strcpyW(editedItem->pszText, newText);
+ TREEVIEW_ComputeTextWidth(infoPtr, editedItem, 0);
}
}
if(newText != tmpText) Free(newText);
ShowWindow(infoPtr->hwndEdit, SW_HIDE);
DestroyWindow(infoPtr->hwndEdit);
infoPtr->hwndEdit = 0;
+ infoPtr->editItem = NULL;
return TRUE;
}
* Windows.
*/
static LRESULT
-TREEVIEW_TrackMouse(TREEVIEW_INFO *infoPtr, POINT pt)
+TREEVIEW_TrackMouse(const TREEVIEW_INFO *infoPtr, POINT pt)
{
INT cxDrag = GetSystemMetrics(SM_CXDRAG);
INT cyDrag = GetSystemMetrics(SM_CYDRAG);
HWND hwnd = infoPtr->hwnd;
TVHITTESTINFO ht;
BOOL bTrack, bDoLabelEdit;
- HTREEITEM tempItem;
/* If Edit control is active - kill it and return.
* The best way to do it is to set focus to itself.
if(ht.hItem && (ht.flags & TVHT_ONITEM))
{
infoPtr->focusedItem = ht.hItem;
- InvalidateRect(hwnd, &(((HTREEITEM)(ht.hItem))->rect), TRUE);
-
- if(infoPtr->selectedItem)
- InvalidateRect(hwnd, &(infoPtr->selectedItem->rect), TRUE);
+ TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
+ TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem);
}
bTrack = (ht.flags & TVHT_ONITEM)
if(infoPtr->focusedItem)
{
/* refresh the item that was focused */
- tempItem = infoPtr->focusedItem;
- infoPtr->focusedItem = 0;
- InvalidateRect(infoPtr->hwnd, &tempItem->rect, TRUE);
+ TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
+ infoPtr->focusedItem = NULL;
/* refresh the selected item to return the filled background */
- InvalidateRect(infoPtr->hwnd, &(infoPtr->selectedItem->rect), TRUE);
+ TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem);
}
return 0;
}
static LRESULT
-TREEVIEW_RButtonUp(TREEVIEW_INFO *infoPtr, LPPOINT pPt)
+TREEVIEW_RButtonUp(const TREEVIEW_INFO *infoPtr, const POINT *pPt)
{
+ TVHITTESTINFO ht;
+
+ ht.pt = *pPt;
+
+ TREEVIEW_HitTest(infoPtr, &ht);
+
+ if (ht.hItem)
+ {
+ /* Change to screen coordinate for WM_CONTEXTMENU */
+ ClientToScreen(infoPtr->hwnd, &ht.pt);
+
+ /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */
+ SendMessageW(infoPtr->hwnd, WM_CONTEXTMENU,
+ (WPARAM)infoPtr->hwnd, MAKELPARAM(ht.pt.x, ht.pt.y));
+ }
return 0;
}
static LRESULT
-TREEVIEW_CreateDragImage(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+TREEVIEW_CreateDragImage(TREEVIEW_INFO *infoPtr, LPARAM lParam)
{
TREEVIEW_ITEM *dragItem = (HTREEITEM)lParam;
INT cx, cy;
hdc = CreateCompatibleDC(htopdc);
hOldFont = SelectObject(hdc, infoPtr->hFont);
- GetTextExtentPoint32W(hdc, dragItem->pszText, strlenW(dragItem->pszText),
+
+ if (dragItem->pszText)
+ GetTextExtentPoint32W(hdc, dragItem->pszText, strlenW(dragItem->pszText),
&size);
- TRACE("%ld %ld %s %d\n", size.cx, size.cy, debugstr_w(dragItem->pszText),
- strlenW(dragItem->pszText));
+ else
+ GetTextExtentPoint32A(hdc, "", 0, &size);
+
+ TRACE("%d %d %s\n", size.cx, size.cy, debugstr_w(dragItem->pszText));
hbmp = CreateCompatibleBitmap(htopdc, size.cx, size.cy);
hOldbmp = SelectObject(hdc, hbmp);
/* draw item text */
SetRect(&rc, cx, 0, size.cx, size.cy);
- DrawTextW(hdc, dragItem->pszText, strlenW(dragItem->pszText), &rc,
- DT_LEFT);
+
+ if (dragItem->pszText)
+ DrawTextW(hdc, dragItem->pszText, strlenW(dragItem->pszText), &rc,
+ DT_LEFT);
+
SelectObject(hdc, hOldFont);
SelectObject(hdc, hOldbmp);
INT cause)
{
TREEVIEW_ITEM *prevSelect;
- RECT rcFocused;
assert(newSelect == NULL || TREEVIEW_ValidItem(infoPtr, newSelect));
/* reset and redraw focusedItem if focusedItem was set so we don't */
/* have to worry about the previously focused item when we set a new one */
- if(infoPtr->focusedItem)
- {
- rcFocused = (infoPtr->focusedItem)->rect;
- infoPtr->focusedItem = 0;
- InvalidateRect(infoPtr->hwnd, &rcFocused, TRUE);
- }
+ TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
+ infoPtr->focusedItem = NULL;
switch (action)
{
if (TREEVIEW_SendTreeviewNotify(infoPtr,
TVN_SELCHANGINGW,
cause,
- TVIF_HANDLE | TVIF_STATE | TVIF_PARAM,
+ TVIF_TEXT | TVIF_HANDLE | TVIF_STATE | TVIF_PARAM,
prevSelect,
newSelect))
return FALSE;
TREEVIEW_EnsureVisible(infoPtr, infoPtr->selectedItem, FALSE);
- if (prevSelect)
- TREEVIEW_Invalidate(infoPtr, prevSelect);
- if (newSelect)
- TREEVIEW_Invalidate(infoPtr, newSelect);
+ TREEVIEW_InvalidateItem(infoPtr, prevSelect);
+ TREEVIEW_InvalidateItem(infoPtr, newSelect);
TREEVIEW_SendTreeviewNotify(infoPtr,
TVN_SELCHANGEDW,
cause,
- TVIF_HANDLE | TVIF_STATE | TVIF_PARAM,
+ TVIF_TEXT | TVIF_HANDLE | TVIF_STATE | TVIF_PARAM,
prevSelect,
newSelect);
break;
* BUGS
*
* - The current implementation has a list of characters it will
- * accept and it ignores averything else. In particular it will
+ * accept and it ignores everything else. In particular it will
* ignore accentuated characters which seems to match what
* Windows does. But I'm not sure it makes sense to follow
* Windows there.
*
* TREEVIEW_ProcessLetterKeys
*/
-static INT TREEVIEW_ProcessLetterKeys(
- HWND hwnd, /* handle to the window */
- WPARAM charCode, /* the character code, the actual character */
- LPARAM keyData /* key data */
- )
+static INT TREEVIEW_ProcessLetterKeys(TREEVIEW_INFO *infoPtr, WPARAM charCode, LPARAM keyData)
{
- TREEVIEW_INFO *infoPtr;
HTREEITEM nItem;
HTREEITEM endidx,idx;
TVITEMEXW item;
DWORD timestamp,elapsed;
/* simple parameter checking */
- if (!hwnd || !charCode || !keyData)
- return 0;
-
- infoPtr=(TREEVIEW_INFO*)GetWindowLongPtrW(hwnd, 0);
- if (!infoPtr)
- return 0;
+ if (!charCode || !keyData) return 0;
/* only allow the valid WM_CHARs through */
if (!isalnum(charCode) &&
/* Expand parents as necessary. */
HTREEITEM parent;
- /* see if we are trying to ensure that root is vislble */
+ /* see if we are trying to ensure that root is visible */
if((item != infoPtr->root) && TREEVIEW_ValidItem(infoPtr, item))
parent = item->parent;
else
viscount = TREEVIEW_GetVisibleCount(infoPtr);
- TRACE("%p (%s) %ld - %ld viscount(%d)\n", item, TREEVIEW_ItemName(item), item->visibleOrder,
+ TRACE("%p (%s) %d - %d viscount(%d)\n", item, TREEVIEW_ItemName(item), item->visibleOrder,
hasFirstVisible ? infoPtr->firstVisible->visibleOrder : -1, viscount);
if (hasFirstVisible)
int nScrollCode = LOWORD(wParam);
- TRACE("wp %x\n", wParam);
+ TRACE("wp %lx\n", wParam);
if (!(infoPtr->uInternalStatus & TV_VSCROLL))
return 0;
- if (infoPtr->hwndEdit)
- SetFocus(infoPtr->hwnd);
-
if (!oldFirstVisible)
{
assert(infoPtr->root->firstChild == NULL);
int scrollX = infoPtr->scrollX;
int nScrollCode = LOWORD(wParam);
- TRACE("wp %x\n", wParam);
+ TRACE("wp %lx\n", wParam);
if (!(infoPtr->uInternalStatus & TV_HSCROLL))
return FALSE;
- if (infoPtr->hwndEdit)
- SetFocus(infoPtr->hwnd);
-
maxWidth = infoPtr->treeWidth - infoPtr->clientWidth;
/* shall never occur */
if (maxWidth <= 0)
}
static LRESULT
-TREEVIEW_MouseWheel(TREEVIEW_INFO *infoPtr, WPARAM wParam)
+TREEVIEW_MouseWheel(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
short gcWheelDelta;
UINT pulScrollLines = 3;
+ if (wParam & (MK_SHIFT | MK_CONTROL))
+ return DefWindowProcW(infoPtr->hwnd, WM_MOUSEWHEEL, wParam, lParam);
+
if (infoPtr->firstVisible == NULL)
return TRUE;
/* Create/Destroy *******************************************************/
+static void
+initialize_checkboxes(TREEVIEW_INFO *infoPtr)
+{
+ RECT rc;
+ HBITMAP hbm, hbmOld;
+ HDC hdc, hdcScreen;
+ int nIndex;
+
+ infoPtr->himlState = ImageList_Create(16, 16, ILC_COLOR | ILC_MASK, 3, 0);
+
+ hdcScreen = GetDC(0);
+
+ hdc = CreateCompatibleDC(hdcScreen);
+ hbm = CreateCompatibleBitmap(hdcScreen, 48, 16);
+ hbmOld = SelectObject(hdc, hbm);
+
+ SetRect(&rc, 0, 0, 48, 16);
+ FillRect(hdc, &rc, (HBRUSH)(COLOR_WINDOW+1));
+
+ SetRect(&rc, 18, 2, 30, 14);
+ DrawFrameControl(hdc, &rc, DFC_BUTTON,
+ DFCS_BUTTONCHECK|DFCS_FLAT);
+
+ SetRect(&rc, 34, 2, 46, 14);
+ DrawFrameControl(hdc, &rc, DFC_BUTTON,
+ DFCS_BUTTONCHECK|DFCS_FLAT|DFCS_CHECKED);
+
+ SelectObject(hdc, hbmOld);
+ nIndex = ImageList_AddMasked(infoPtr->himlState, hbm,
+ comctl32_color.clrWindow);
+ TRACE("checkbox index %d\n", nIndex);
+
+ DeleteObject(hbm);
+ DeleteDC(hdc);
+ ReleaseDC(0, hdcScreen);
+
+ infoPtr->stateImageWidth = 16;
+ infoPtr->stateImageHeight = 16;
+}
+
static LRESULT
TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
{
- static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' };
RECT rcClient;
TREEVIEW_INFO *infoPtr;
LOGFONTW lf;
- TRACE("wnd %p, style %lx\n", hwnd, GetWindowLongW(hwnd, GWL_STYLE));
+ TRACE("wnd %p, style %x\n", hwnd, GetWindowLongW(hwnd, GWL_STYLE));
- infoPtr = (TREEVIEW_INFO *)Alloc(sizeof(TREEVIEW_INFO));
+ infoPtr = Alloc(sizeof(TREEVIEW_INFO));
if (infoPtr == NULL)
{
infoPtr->treeHeight = 0;
infoPtr->uIndent = MINIMUM_INDENT;
- infoPtr->selectedItem = 0;
- infoPtr->focusedItem = 0;
- infoPtr->hotItem = 0;
- infoPtr->firstVisible = 0;
+ infoPtr->selectedItem = NULL;
+ infoPtr->focusedItem = NULL;
+ infoPtr->hotItem = NULL;
+ infoPtr->editItem = NULL;
+ infoPtr->firstVisible = NULL;
infoPtr->maxVisibleOrder = 0;
- infoPtr->dropItem = 0;
- infoPtr->insertMarkItem = 0;
+ infoPtr->dropItem = NULL;
+ infoPtr->insertMarkItem = NULL;
infoPtr->insertBeforeorAfter = 0;
/* dragList */
infoPtr->scrollX = 0;
- infoPtr->clrBk = GetSysColor(COLOR_WINDOW);
- infoPtr->clrText = -1; /* use system color */
- infoPtr->clrLine = RGB(128, 128, 128);
- infoPtr->clrInsertMark = GetSysColor(COLOR_BTNTEXT);
+ infoPtr->clrBk = CLR_NONE; /* use system color */
+ infoPtr->clrText = CLR_NONE; /* use system color */
+ infoPtr->clrLine = CLR_DEFAULT;
+ infoPtr->clrInsertMark = CLR_DEFAULT;
/* hwndToolTip */
- infoPtr->hwndEdit = 0;
+ infoPtr->hwndEdit = NULL;
infoPtr->wpEditOrig = NULL;
infoPtr->bIgnoreEditKillFocus = FALSE;
infoPtr->bLabelChanged = FALSE;
TREEVIEW_NotifyFormat(infoPtr, infoPtr->hwndNotify, NF_REQUERY);
if (!(infoPtr->dwStyle & TVS_NOTOOLTIPS))
- infoPtr->hwndToolTip = COMCTL32_CreateToolTip(hwnd);
+ infoPtr->hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, WS_POPUP,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ hwnd, 0, 0, 0);
if (infoPtr->dwStyle & TVS_CHECKBOXES)
- {
- RECT rc;
- HBITMAP hbm, hbmOld;
- HDC hdc,hdcScreen;
- int nIndex;
-
- infoPtr->himlState =
- ImageList_Create(16, 16, ILC_COLOR | ILC_MASK, 3, 0);
-
- hdcScreen = CreateDCW(szDisplayW, NULL, NULL, NULL);
-
- /* Create a coloured bitmap compatible with the screen depth
- because checkboxes are not black&white */
- hdc = CreateCompatibleDC(hdcScreen);
- hbm = CreateCompatibleBitmap(hdcScreen, 48, 16);
- hbmOld = SelectObject(hdc, hbm);
-
- rc.left = 0; rc.top = 0;
- rc.right = 48; rc.bottom = 16;
- FillRect(hdc, &rc, (HBRUSH)(COLOR_WINDOW+1));
-
- rc.left = 18; rc.top = 2;
- rc.right = 30; rc.bottom = 14;
- DrawFrameControl(hdc, &rc, DFC_BUTTON,
- DFCS_BUTTONCHECK|DFCS_FLAT);
-
- rc.left = 34; rc.right = 46;
- DrawFrameControl(hdc, &rc, DFC_BUTTON,
- DFCS_BUTTONCHECK|DFCS_FLAT|DFCS_CHECKED);
-
- SelectObject(hdc, hbmOld);
- nIndex = ImageList_AddMasked(infoPtr->himlState, hbm,
- GetSysColor(COLOR_WINDOW));
- TRACE("checkbox index %d\n", nIndex);
-
- DeleteObject(hbm);
- DeleteDC(hdc);
- DeleteDC(hdcScreen);
-
- infoPtr->stateImageWidth = 16;
- infoPtr->stateImageHeight = 16;
- }
+ initialize_checkboxes(infoPtr);
/* Make sure actual scrollbar state is consistent with uInternalStatus */
ShowScrollBar(hwnd, SB_VERT, FALSE);
{
TRACE("\n");
+ /* free item data */
TREEVIEW_RemoveTree(infoPtr);
+ /* root isn't freed with other items */
+ TREEVIEW_FreeItem(infoPtr, infoPtr->root);
+ DPA_Destroy(infoPtr->items);
/* tool tip is automatically destroyed: we are its owner */
CloseThemeData (GetWindowTheme (infoPtr->hwnd));
/* Deassociate treeview from the window before doing anything drastic. */
- SetWindowLongPtrW(infoPtr->hwnd, 0, (DWORD_PTR)NULL);
+ SetWindowLongPtrW(infoPtr->hwnd, 0, 0);
DeleteObject(infoPtr->hDefaultFont);
TREEVIEW_ITEM *prevItem = infoPtr->selectedItem;
- TRACE("%x\n", wParam);
+ TRACE("%lx\n", wParam);
if (prevItem == NULL)
return FALSE;
static LRESULT
TREEVIEW_MouseLeave (TREEVIEW_INFO * infoPtr)
{
- if (infoPtr->hotItem)
- {
- /* remove hot effect from item */
- InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
- infoPtr->hotItem = NULL;
- }
+ /* remove hot effect from item */
+ TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
+ infoPtr->hotItem = NULL;
+
return 0;
}
static LRESULT
-TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, WPARAM wParam, LPARAM lParam)
+TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, LPARAM lParam)
{
POINT pt;
TRACKMOUSEEVENT trackinfo;
TREEVIEW_ITEM * item;
+ if (!(infoPtr->dwStyle & TVS_TRACKSELECT)) return 0;
+
/* fill in the TRACKMOUSEEVENT struct */
trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
trackinfo.dwFlags = TME_QUERY;
trackinfo.hwndTrack = infoPtr->hwnd;
- trackinfo.dwHoverTime = HOVER_DEFAULT;
/* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
_TrackMouseEvent(&trackinfo);
if(!(trackinfo.dwFlags & TME_LEAVE))
{
trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
+ trackinfo.hwndTrack = infoPtr->hwnd;
+ /* do it as fast as possible, minimal systimer latency will be used */
+ trackinfo.dwHoverTime = 1;
/* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
/* and can properly deactivate the hot item */
_TrackMouseEvent(&trackinfo);
}
- pt.x = (INT)LOWORD(lParam);
- pt.y = (INT)HIWORD(lParam);
+ pt.x = (short)LOWORD(lParam);
+ pt.y = (short)HIWORD(lParam);
item = TREEVIEW_HitTestPoint(infoPtr, pt);
if (item != infoPtr->hotItem)
{
/* redraw old hot item */
- if (infoPtr->hotItem)
- InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
+ TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
infoPtr->hotItem = item;
/* redraw new hot item */
- if (infoPtr->hotItem)
- InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
+ TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
}
return 0;
}
/* Draw themed border */
-static BOOL nc_paint (TREEVIEW_INFO *infoPtr, HRGN region)
+static BOOL TREEVIEW_NCPaint (const TREEVIEW_INFO *infoPtr, HRGN region, LPARAM lParam)
{
HTHEME theme = GetWindowTheme (infoPtr->hwnd);
HDC dc;
int cxEdge = GetSystemMetrics (SM_CXEDGE),
cyEdge = GetSystemMetrics (SM_CYEDGE);
- if (!theme) return FALSE;
+ if (!theme)
+ return DefWindowProcW (infoPtr->hwnd, WM_NCPAINT, (WPARAM)region, lParam);
GetWindowRect(infoPtr->hwnd, &r);
}
static LRESULT
-TREEVIEW_Notify(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+TREEVIEW_Notify(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
LPNMHDR lpnmh = (LPNMHDR)lParam;
if (lppgc->dwFlag == PGF_CALCWIDTH) {
lppgc->iWidth = infoPtr->treeWidth;
- TRACE("got PGN_CALCSIZE, returning horz size = %ld, client=%ld\n",
+ TRACE("got PGN_CALCSIZE, returning horz size = %d, client=%d\n",
infoPtr->treeWidth, infoPtr->clientWidth);
}
else {
lppgc->iHeight = infoPtr->treeHeight;
- TRACE("got PGN_CALCSIZE, returning vert size = %ld, client=%ld\n",
+ TRACE("got PGN_CALCSIZE, returning vert size = %d, client=%d\n",
infoPtr->treeHeight, infoPtr->clientHeight);
}
return 0;
return DefWindowProcW(infoPtr->hwnd, WM_NOTIFY, wParam, lParam);
}
-static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand)
-{
- INT format;
-
- TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand);
-
- if (nCommand != NF_REQUERY) return 0;
-
- format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY);
- TRACE("format=%d\n", format);
-
- if (format != NFR_ANSI && format != NFR_UNICODE) return 0;
-
- infoPtr->bNtfUnicode = (format == NFR_UNICODE);
-
- return format;
-}
-
static LRESULT
TREEVIEW_Size(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
}
else
{
- FIXME("WM_SIZE flag %x %lx not handled\n", wParam, lParam);
+ FIXME("WM_SIZE flag %lx %lx not handled\n", wParam, lParam);
}
TREEVIEW_Invalidate(infoPtr, NULL);
static LRESULT
TREEVIEW_StyleChanged(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
- TRACE("(%x %lx)\n", wParam, lParam);
+ TRACE("(%lx %lx)\n", wParam, lParam);
if (wParam == GWL_STYLE)
{
- DWORD dwNewStyle = ((LPSTYLESTRUCT)lParam)->styleNew;
+ DWORD dwNewStyle = ((LPSTYLESTRUCT)lParam)->styleNew;
- /* we have to take special care about tooltips */
- if ((infoPtr->dwStyle ^ dwNewStyle) & TVS_NOTOOLTIPS)
- {
- if (infoPtr->dwStyle & TVS_NOTOOLTIPS)
- {
- infoPtr->hwndToolTip = COMCTL32_CreateToolTip(infoPtr->hwnd);
- TRACE("\n");
- }
- else
- {
- DestroyWindow(infoPtr->hwndToolTip);
- infoPtr->hwndToolTip = 0;
- }
- }
+ if ((infoPtr->dwStyle ^ dwNewStyle) & TVS_CHECKBOXES)
+ {
+ if (dwNewStyle & TVS_CHECKBOXES)
+ {
+ initialize_checkboxes(infoPtr);
+ TRACE("checkboxes enabled\n");
+ }
+ else
+ {
+ FIXME("tried to disable checkboxes\n");
+ }
+ }
+
+ if ((infoPtr->dwStyle ^ dwNewStyle) & TVS_NOTOOLTIPS)
+ {
+ if (infoPtr->dwStyle & TVS_NOTOOLTIPS)
+ {
+ infoPtr->hwndToolTip = COMCTL32_CreateToolTip(infoPtr->hwnd);
+ TRACE("tooltips enabled\n");
+ }
+ else
+ {
+ DestroyWindow(infoPtr->hwndToolTip);
+ infoPtr->hwndToolTip = 0;
+ TRACE("tooltips disabled\n");
+ }
+ }
- infoPtr->dwStyle = dwNewStyle;
+ infoPtr->dwStyle = dwNewStyle;
}
TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
}
static LRESULT
-TREEVIEW_SetCursor(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+TREEVIEW_SetCursor(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
POINT pt;
TREEVIEW_ITEM * item;
+ NMMOUSE nmmouse;
GetCursorPos(&pt);
ScreenToClient(infoPtr->hwnd, &pt);
item = TREEVIEW_HitTestPoint(infoPtr, pt);
- /* FIXME: send NM_SETCURSOR */
+ memset(&nmmouse, 0, sizeof(nmmouse));
+ nmmouse.hdr.hwndFrom = infoPtr->hwnd;
+ nmmouse.hdr.idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);
+ nmmouse.hdr.code = NM_SETCURSOR;
+ if (item)
+ {
+ nmmouse.dwItemSpec = (DWORD_PTR)item;
+ nmmouse.dwItemData = item->lParam;
+ }
+ nmmouse.pt.x = 0;
+ nmmouse.pt.y = 0;
+ nmmouse.dwHitInfo = lParam;
+ if (TREEVIEW_SendRealNotify(infoPtr, nmmouse.hdr.idFrom, (LPARAM)&nmmouse))
+ return 0;
if (item && (infoPtr->dwStyle & TVS_TRACKSELECT))
{
}
static LRESULT
-TREEVIEW_KillFocus(TREEVIEW_INFO *infoPtr)
+TREEVIEW_KillFocus(const TREEVIEW_INFO *infoPtr)
{
TRACE("\n");
}
/* update theme after a WM_THEMECHANGED message */
-static LRESULT theme_changed (TREEVIEW_INFO* infoPtr)
+static LRESULT TREEVIEW_ThemeChanged(const TREEVIEW_INFO *infoPtr)
{
HTHEME theme = GetWindowTheme (infoPtr->hwnd);
CloseThemeData (theme);
{
TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
- TRACE("hwnd %p msg %04x wp=%08x lp=%08lx\n", hwnd, uMsg, wParam, lParam);
+ TRACE("hwnd %p msg %04x wp=%08lx lp=%08lx\n", hwnd, uMsg, wParam, lParam);
if (infoPtr) TREEVIEW_VerifyTree(infoPtr);
else
switch (uMsg)
{
case TVM_CREATEDRAGIMAGE:
- return TREEVIEW_CreateDragImage(infoPtr, wParam, lParam);
+ return TREEVIEW_CreateDragImage(infoPtr, lParam);
case TVM_DELETEITEM:
return TREEVIEW_DeleteItem(infoPtr, (HTREEITEM)lParam);
case TVM_EDITLABELA:
- return (LRESULT)TREEVIEW_EditLabel(infoPtr, (HTREEITEM)lParam);
-
case TVM_EDITLABELW:
return (LRESULT)TREEVIEW_EditLabel(infoPtr, (HTREEITEM)lParam);
return 0;
case TVM_GETITEMA:
- return TREEVIEW_GetItemT(infoPtr, (LPTVITEMEXW)lParam, FALSE);
-
case TVM_GETITEMW:
- return TREEVIEW_GetItemT(infoPtr, (LPTVITEMEXW)lParam, TRUE);
-
+ return TREEVIEW_GetItemT(infoPtr, (LPTVITEMEXW)lParam,
+ uMsg == TVM_GETITEMW);
case TVM_GETITEMHEIGHT:
return TREEVIEW_GetItemHeight(infoPtr);
return TREEVIEW_HitTest(infoPtr, (LPTVHITTESTINFO)lParam);
case TVM_INSERTITEMA:
- return TREEVIEW_InsertItemT(infoPtr, (LPTVINSERTSTRUCTW)lParam, FALSE);
-
case TVM_INSERTITEMW:
- return TREEVIEW_InsertItemT(infoPtr, (LPTVINSERTSTRUCTW)lParam, TRUE);
-
+ return TREEVIEW_InsertItemT(infoPtr, (LPTVINSERTSTRUCTW)lParam,
+ uMsg == TVM_INSERTITEMW);
case TVM_SELECTITEM:
return TREEVIEW_SelectItem(infoPtr, (INT)wParam, (HTREEITEM)lParam);
return TREEVIEW_SetInsertMarkColor(infoPtr, (COLORREF)lParam);
case TVM_SETITEMA:
- return TREEVIEW_SetItemT(infoPtr, (LPTVITEMEXW)lParam, FALSE);
-
case TVM_SETITEMW:
- return TREEVIEW_SetItemT(infoPtr, (LPTVITEMEXW)lParam, TRUE);
-
+ return TREEVIEW_SetItemT(infoPtr, (LPTVITEMEXW)lParam,
+ uMsg == TVM_SETITEMW);
case TVM_SETLINECOLOR:
return TREEVIEW_SetLineColor(infoPtr, (COLORREF)lParam);
return TREEVIEW_SetUnicodeFormat(infoPtr, (BOOL)wParam);
case TVM_SORTCHILDREN:
- return TREEVIEW_SortChildren(infoPtr, wParam, lParam);
+ return TREEVIEW_SortChildren(infoPtr, lParam);
case TVM_SORTCHILDRENCB:
- return TREEVIEW_SortChildrenCB(infoPtr, wParam, (LPTVSORTCB)lParam);
+ return TREEVIEW_SortChildrenCB(infoPtr, (LPTVSORTCB)lParam);
case WM_CHAR:
- return TREEVIEW_ProcessLetterKeys( hwnd, wParam, lParam );
+ return TREEVIEW_ProcessLetterKeys(infoPtr, wParam, lParam);
case WM_COMMAND:
return TREEVIEW_Command(infoPtr, wParam, lParam);
return TREEVIEW_MouseLeave(infoPtr);
case WM_MOUSEMOVE:
- if (infoPtr->dwStyle & TVS_TRACKSELECT)
- return TREEVIEW_MouseMove(infoPtr, wParam, lParam);
- else
- return 0;
+ return TREEVIEW_MouseMove(infoPtr, lParam);
- case WM_NCPAINT:
- if (nc_paint (infoPtr, (HRGN)wParam))
- return 0;
+ case WM_NCLBUTTONDOWN:
+ if (infoPtr->hwndEdit)
+ SetFocus(infoPtr->hwnd);
goto def;
+ case WM_NCPAINT:
+ return TREEVIEW_NCPaint (infoPtr, (HRGN)wParam, lParam);
+
case WM_NOTIFY:
return TREEVIEW_Notify(infoPtr, wParam, lParam);
return TREEVIEW_NotifyFormat(infoPtr, (HWND)wParam, (UINT)lParam);
case WM_PRINTCLIENT:
+ return TREEVIEW_PrintClient(infoPtr, (HDC)wParam, lParam);
+
case WM_PAINT:
- return TREEVIEW_Paint(infoPtr, wParam);
+ return TREEVIEW_Paint(infoPtr, (HDC)wParam);
case WM_RBUTTONDOWN:
return TREEVIEW_RButtonDown(infoPtr, lParam);
return TREEVIEW_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam);
case WM_SETREDRAW:
- return TREEVIEW_SetRedraw(infoPtr, wParam, lParam);
+ return TREEVIEW_SetRedraw(infoPtr, wParam);
case WM_SIZE:
return TREEVIEW_Size(infoPtr, wParam, lParam);
case WM_STYLECHANGED:
return TREEVIEW_StyleChanged(infoPtr, wParam, lParam);
- /* WM_SYSCOLORCHANGE */
+ case WM_SYSCOLORCHANGE:
+ COMCTL32_RefreshSysColors();
+ return 0;
/* WM_SYSKEYDOWN */
return TREEVIEW_HandleTimer(infoPtr, wParam);
case WM_THEMECHANGED:
- return theme_changed (infoPtr);
+ return TREEVIEW_ThemeChanged (infoPtr);
case WM_VSCROLL:
return TREEVIEW_VScroll(infoPtr, wParam);
/* WM_WININICHANGE */
case WM_MOUSEWHEEL:
- if (wParam & (MK_SHIFT | MK_CONTROL))
- goto def;
- return TREEVIEW_MouseWheel(infoPtr, wParam);
+ return TREEVIEW_MouseWheel(infoPtr, wParam, lParam);
case WM_DRAWITEM:
TRACE("drawItem\n");
default:
/* This mostly catches MFC and Delphi messages. :( */
- if ((uMsg >= WM_USER) && (uMsg < WM_APP))
- TRACE("Unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam);
+ if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg))
+ TRACE("Unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam);
def:
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}