Draw text and icons, implement ordering functions, allow reordering
with mouse and fix the WM_NOTIFY target.
diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c
index b4555ef..b12af41 100644
--- a/dlls/comctl32/header.c
+++ b/dlls/comctl32/header.c
@@ -6,7 +6,6 @@
* TODO:
* - Imagelist support (partially).
* - Callback items (under construction).
- * - Order list support.
* - Control specific cursors (over dividers).
* - Hottrack support (partially).
* - Custom draw support (including Notifications).
@@ -15,7 +14,7 @@
*
* FIXME:
* - Replace DrawText32A by DrawTextEx32A(...|DT_ENDELLIPSIS) in
- * HEADER_DrawItem.
+ * HEADER_DrawItem.(Is still needed? UB 001018)
* - Little flaw when drawing a bitmap on the right side of the text.
*/
@@ -25,6 +24,7 @@
#include "wine/unicode.h"
#include "wine/winestring.h"
#include "commctrl.h"
+#include "imagelist.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(header);
@@ -46,6 +46,7 @@
typedef struct
{
+ HWND hwndNotify; /* Owner window to send notifications to */
UINT uNumItem; /* number of items (columns) */
INT nHeight; /* height of the header (pixels) */
HFONT hFont; /* handle to the current font */
@@ -65,7 +66,7 @@
HIMAGELIST himl; /* handle to a image list (may be 0) */
HEADER_ITEM *items; /* pointer to array of HEADER_ITEM's */
BOOL bRectsValid; /* validity flag for bounding rectangles */
- LPINT pOrder; /* pointer to order array */
+ /*LPINT pOrder; pointer to order array */
} HEADER_INFO;
@@ -75,6 +76,30 @@
#define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongA(hwnd,0))
+inline static LRESULT
+HEADER_IndexToOrder (HWND hwnd, INT iItem)
+{
+ HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
+ HEADER_ITEM *lpItem = (HEADER_ITEM*)&infoPtr->items[iItem];
+ return lpItem->iOrder;
+}
+
+
+static INT
+HEADER_OrderToIndex(HWND hwnd, WPARAM wParam)
+{
+ HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
+ INT i,iorder = (INT)wParam;
+
+
+ if ((iorder <0) || iorder >infoPtr->uNumItem)
+ return iorder;
+ for (i=0; i<infoPtr->uNumItem; i++)
+ if (HEADER_IndexToOrder(hwnd,i) == iorder)
+ return i;
+ return iorder;
+}
+
static void
HEADER_SetItemBounds (HWND hwnd)
{
@@ -92,7 +117,7 @@
x = rect.left;
for (i = 0; i < infoPtr->uNumItem; i++) {
- phdi = &infoPtr->items[i];
+ phdi = &infoPtr->items[HEADER_OrderToIndex(hwnd,i)];
phdi->rect.top = rect.top;
phdi->rect.bottom = rect.bottom;
phdi->rect.left = x;
@@ -252,9 +277,11 @@
}
if (phdi->fmt & HDF_IMAGE) {
-
-
-/* ImageList_Draw (infoPtr->himl, phdi->iImage,...); */
+ r.left +=3;
+ /* FIXME: (r.bottom- (infoPtr->himl->cy))/2 should horicontal center the image
+ It looks like it doesn't work as expected*/
+ ImageList_Draw (infoPtr->himl, phdi->iImage,hdc,r.left, (r.bottom- (infoPtr->himl->cy))/2,NULL);
+ r.left += infoPtr->himl->cx;
}
if (((phdi->fmt & HDF_STRING)
@@ -262,15 +289,15 @@
HDF_BITMAP_ON_RIGHT|HDF_IMAGE)))) /* no explicit format specified? */
&& (phdi->pszText)) {
oldBkMode = SetBkMode(hdc, TRANSPARENT);
- r.left += 3;
+ r.left += 3 ;
r.right -= 3;
- SetTextColor (hdc, bHotTrack ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
+ SetTextColor (hdc, (bHotTrack) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
DrawTextW (hdc, phdi->pszText, -1,
- &r, uTextJustify|DT_VCENTER|DT_SINGLELINE);
+ &r, uTextJustify|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE);
if (oldBkMode != TRANSPARENT)
SetBkMode(hdc, oldBkMode);
}
- }
+ }/*Ownerdrawn*/
return phdi->rect.right;
}
@@ -297,7 +324,7 @@
x = rect.left;
for (i = 0; i < infoPtr->uNumItem; i++) {
- x = HEADER_DrawItem (hwnd, hdc, i, FALSE);
+ x = HEADER_DrawItem (hwnd, hdc, HEADER_OrderToIndex(hwnd,i), FALSE);
}
if ((x <= rect.right) && (infoPtr->uNumItem > 0)) {
@@ -467,13 +494,14 @@
static BOOL
HEADER_SendSimpleNotify (HWND hwnd, UINT code)
{
+ HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
NMHDR nmhdr;
nmhdr.hwndFrom = hwnd;
nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
nmhdr.code = code;
- return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
+ return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}
@@ -500,7 +528,7 @@
nmitem.iOrder = infoPtr->items[iItem].iOrder;
nmitem.iImage = infoPtr->items[iItem].iImage;
- return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
+ return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
}
@@ -529,7 +557,7 @@
nmitem.iOrder = infoPtr->items[iItem].iOrder;
nmitem.iImage = infoPtr->items[iItem].iImage;
- return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
+ return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
}
@@ -537,6 +565,7 @@
static BOOL
HEADER_SendClickNotify (HWND hwnd, UINT code, INT iItem)
{
+ HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
NMHEADERA nmhdr;
nmhdr.hdr.hwndFrom = hwnd;
@@ -546,7 +575,7 @@
nmhdr.iButton = 0;
nmhdr.pitem = NULL;
- return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
+ return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
}
@@ -750,8 +779,39 @@
}
-/* << HEADER_GetOrderArray >> */
+static LRESULT
+HEADER_GetOrderArray(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ LPINT order = (LPINT) lParam;
+ HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
+ if ((int)wParam <infoPtr->uNumItem)
+ return FALSE;
+ for (i=0; i<(int)wParam; i++)
+ *order++=HEADER_OrderToIndex(hwnd,i);
+ return TRUE;
+}
+
+static LRESULT
+HEADER_SetOrderArray(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ LPINT order = (LPINT) lParam;
+ HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
+ HEADER_ITEM *lpItem;
+
+ if ((int)wParam <infoPtr->uNumItem)
+ return FALSE;
+ for (i=0; i<(int)wParam; i++)
+ {
+ lpItem = (HEADER_ITEM*)&infoPtr->items[*order++];
+ lpItem->iOrder=i;
+ }
+ infoPtr->bRectsValid=0;
+ InvalidateRect(hwnd, NULL, FALSE);
+ return TRUE;
+}
inline static LRESULT
HEADER_GetUnicodeFormat (HWND hwnd)
@@ -845,6 +905,10 @@
if (lpItem->fmt == 0)
lpItem->fmt = HDF_LEFT;
+ if (!(lpItem->fmt &HDF_STRING) && (phdi->mask & HDI_TEXT))
+ {
+ lpItem->fmt |= HDF_STRING;
+ }
if (phdi->mask & HDI_BITMAP)
lpItem->hbm = phdi->hbm;
@@ -855,7 +919,12 @@
lpItem->iImage = phdi->iImage;
if (phdi->mask & HDI_ORDER)
+ {
lpItem->iOrder = phdi->iOrder;
+ }
+ else
+ lpItem->iOrder=nItem;
+
HEADER_SetItemBounds (hwnd);
@@ -939,7 +1008,11 @@
lpItem->iImage = phdi->iImage;
if (phdi->mask & HDI_ORDER)
+ {
lpItem->iOrder = phdi->iOrder;
+ }
+ else
+ lpItem->iOrder = nItem;
HEADER_SetItemBounds (hwnd);
@@ -1044,7 +1117,11 @@
lpItem->iImage = phdi->iImage;
if (phdi->mask & HDI_ORDER)
+ {
lpItem->iOrder = phdi->iOrder;
+ }
+ else
+ lpItem->iOrder = nItem;
HEADER_SendItemChange(hwnd,nItem,phdi->mask,HDN_ITEMCHANGEDA);
@@ -1107,7 +1184,11 @@
lpItem->iImage = phdi->iImage;
if (phdi->mask & HDI_ORDER)
+ {
lpItem->iOrder = phdi->iOrder;
+ }
+ else
+ lpItem->iOrder = nItem;
HEADER_SendItemChange(hwnd, nItem, phdi->mask,HDN_ITEMCHANGEDW);
@@ -1118,10 +1199,6 @@
return TRUE;
}
-
-/* << HEADER_SetOrderArray >> */
-
-
inline static LRESULT
HEADER_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
{
@@ -1145,6 +1222,7 @@
infoPtr = (HEADER_INFO *)COMCTL32_Alloc (sizeof(HEADER_INFO));
SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
+ infoPtr->hwndNotify = GetParent(hwnd);
infoPtr->uNumItem = 0;
infoPtr->nHeight = 20;
infoPtr->hFont = 0;
@@ -1303,6 +1381,25 @@
HEADER_SendClickNotify (hwnd, HDN_ITEMCLICKA, infoPtr->iMoveItem);
}
+ else if (flags == HHT_ONHEADER)
+ {
+ HEADER_ITEM *lpItem;
+ INT newindex = HEADER_IndexToOrder(hwnd,nItem);
+ INT oldindex = HEADER_IndexToOrder(hwnd,infoPtr->iMoveItem);
+
+ TRACE("Exchanging [index:order] [%d:%d] [%d:%d]\n",
+ infoPtr->iMoveItem,oldindex,nItem,newindex);
+ lpItem= (HEADER_ITEM*)&infoPtr->items[nItem];
+ lpItem->iOrder=oldindex;
+
+ lpItem= (HEADER_ITEM*)&infoPtr->items[infoPtr->iMoveItem];
+ lpItem->iOrder = newindex;
+
+ infoPtr->bRectsValid = FALSE;
+ InvalidateRect(hwnd, NULL, FALSE);
+ /* FIXME: Should some WM_NOTIFY be sent */
+ }
+
TRACE("Released item %d!\n", infoPtr->iMoveItem);
infoPtr->bPressed = FALSE;
}
@@ -1555,7 +1652,14 @@
case HDM_GETITEMRECT:
return HEADER_GetItemRect (hwnd, wParam, lParam);
-/* case HDM_GETORDERARRAY: */
+ case HDM_GETORDERARRAY:
+ return HEADER_GetOrderArray(hwnd, wParam, lParam);
+
+ case HDM_SETORDERARRAY:
+ return HEADER_SetOrderArray(hwnd, wParam, lParam);
+
+ case HDM_ORDERTOINDEX:
+ return HEADER_OrderToIndex(hwnd, wParam);
case HDM_GETUNICODEFORMAT:
return HEADER_GetUnicodeFormat (hwnd);
@@ -1581,8 +1685,6 @@
case HDM_SETITEMW:
return HEADER_SetItemW (hwnd, wParam, lParam);
-/* case HDM_SETORDERARRAY: */
-
case HDM_SETUNICODEFORMAT:
return HEADER_SetUnicodeFormat (hwnd, wParam);