| 1 | /*
 | 
|---|
| 2 |  *  Header control
 | 
|---|
| 3 |  *
 | 
|---|
| 4 |  *  Copyright 1998 Eric Kohl
 | 
|---|
| 5 |  *  Copyright 2000 Eric Kohl for CodeWeavers
 | 
|---|
| 6 |  *
 | 
|---|
| 7 |  * This library is free software; you can redistribute it and/or
 | 
|---|
| 8 |  * modify it under the terms of the GNU Lesser General Public
 | 
|---|
| 9 |  * License as published by the Free Software Foundation; either
 | 
|---|
| 10 |  * version 2.1 of the License, or (at your option) any later version.
 | 
|---|
| 11 |  *
 | 
|---|
| 12 |  * This library is distributed in the hope that it will be useful,
 | 
|---|
| 13 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 14 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
|---|
| 15 |  * Lesser General Public License for more details.
 | 
|---|
| 16 |  *
 | 
|---|
| 17 |  * You should have received a copy of the GNU Lesser General Public
 | 
|---|
| 18 |  * License along with this library; if not, write to the Free Software
 | 
|---|
| 19 |  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
|---|
| 20 |  *
 | 
|---|
| 21 |  *  TODO:
 | 
|---|
| 22 |  *   - Imagelist support (partially).
 | 
|---|
| 23 |  *   - Callback items (under construction).
 | 
|---|
| 24 |  *   - Hottrack support (partially).
 | 
|---|
| 25 |  *   - Custom draw support (including Notifications).
 | 
|---|
| 26 |  *   - Drag and Drop support (including Notifications).
 | 
|---|
| 27 |  *   - New messages.
 | 
|---|
| 28 |  *   - Use notification format
 | 
|---|
| 29 |  *   - Correct the order maintenance code to preserve valid order
 | 
|---|
| 30 |  *
 | 
|---|
| 31 |  *  FIXME:
 | 
|---|
| 32 |  *   - Little flaw when drawing a bitmap on the right side of the text.
 | 
|---|
| 33 |  */
 | 
|---|
| 34 | 
 | 
|---|
| 35 | #include <string.h>
 | 
|---|
| 36 | 
 | 
|---|
| 37 | #include "winbase.h"
 | 
|---|
| 38 | #include "wine/unicode.h"
 | 
|---|
| 39 | #include "commctrl.h"
 | 
|---|
| 40 | #include "comctl32.h"
 | 
|---|
| 41 | #include "imagelist.h"
 | 
|---|
| 42 | #include "wine/debug.h"
 | 
|---|
| 43 | 
 | 
|---|
| 44 | WINE_DEFAULT_DEBUG_CHANNEL(header);
 | 
|---|
| 45 | 
 | 
|---|
| 46 | typedef struct
 | 
|---|
| 47 | {
 | 
|---|
| 48 |     INT     cxy;
 | 
|---|
| 49 |     HBITMAP hbm;
 | 
|---|
| 50 |     LPWSTR    pszText;
 | 
|---|
| 51 |     INT     fmt;
 | 
|---|
| 52 |     LPARAM    lParam;
 | 
|---|
| 53 |     INT     iImage;
 | 
|---|
| 54 |     INT     iOrder;             /* see documentation of HD_ITEM */
 | 
|---|
| 55 | 
 | 
|---|
| 56 |     BOOL    bDown;              /* is item pressed? (used for drawing) */
 | 
|---|
| 57 |     RECT    rect;               /* bounding rectangle of the item */
 | 
|---|
| 58 | } HEADER_ITEM;
 | 
|---|
| 59 | 
 | 
|---|
| 60 | 
 | 
|---|
| 61 | typedef struct
 | 
|---|
| 62 | {
 | 
|---|
| 63 |     HWND      hwndNotify;       /* Owner window to send notifications to */
 | 
|---|
| 64 |     INT       nNotifyFormat;    /* format used for WM_NOTIFY messages */
 | 
|---|
| 65 |     UINT      uNumItem;         /* number of items (columns) */
 | 
|---|
| 66 |     INT       nHeight;          /* height of the header (pixels) */
 | 
|---|
| 67 |     HFONT     hFont;            /* handle to the current font */
 | 
|---|
| 68 |     HCURSOR   hcurArrow;        /* handle to the arrow cursor */
 | 
|---|
| 69 |     HCURSOR   hcurDivider;      /* handle to a cursor (used over dividers) <-|-> */
 | 
|---|
| 70 |     HCURSOR   hcurDivopen;      /* handle to a cursor (used over dividers) <-||-> */
 | 
|---|
| 71 |     BOOL      bCaptured;        /* Is the mouse captured? */
 | 
|---|
| 72 |     BOOL      bPressed;         /* Is a header item pressed (down)? */
 | 
|---|
| 73 |     BOOL      bTracking;        /* Is in tracking mode? */
 | 
|---|
| 74 |     BOOL      bUnicode;         /* Unicode flag */
 | 
|---|
| 75 |     INT       iMoveItem;        /* index of tracked item. (Tracking mode) */
 | 
|---|
| 76 |     INT       xTrackOffset;     /* distance between the right side of the tracked item and the cursor */
 | 
|---|
| 77 |     INT       xOldTrack;        /* track offset (see above) after the last WM_MOUSEMOVE */
 | 
|---|
| 78 |     INT       nOldWidth;        /* width of a sizing item after the last WM_MOUSEMOVE */
 | 
|---|
| 79 |     INT       iHotItem;         /* index of hot item (cursor is over this item) */
 | 
|---|
| 80 | 
 | 
|---|
| 81 |     HIMAGELIST  himl;           /* handle to a image list (may be 0) */
 | 
|---|
| 82 |     HEADER_ITEM *items;         /* pointer to array of HEADER_ITEM's */
 | 
|---|
| 83 |     BOOL        bRectsValid;    /* validity flag for bounding rectangles */
 | 
|---|
| 84 | } HEADER_INFO;
 | 
|---|
| 85 | 
 | 
|---|
| 86 | 
 | 
|---|
| 87 | #define VERT_BORDER     3
 | 
|---|
| 88 | #define DIVIDER_WIDTH  10
 | 
|---|
| 89 | 
 | 
|---|
| 90 | #define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongA(hwnd,0))
 | 
|---|
| 91 | 
 | 
|---|
| 92 | 
 | 
|---|
| 93 | inline static LRESULT
 | 
|---|
| 94 | HEADER_IndexToOrder (HWND hwnd, INT iItem)
 | 
|---|
| 95 | {
 | 
|---|
| 96 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 97 |     HEADER_ITEM *lpItem = &infoPtr->items[iItem];
 | 
|---|
| 98 |     return lpItem->iOrder;
 | 
|---|
| 99 | }
 | 
|---|
| 100 | 
 | 
|---|
| 101 | 
 | 
|---|
| 102 | static INT
 | 
|---|
| 103 | HEADER_OrderToIndex(HWND hwnd, WPARAM wParam)
 | 
|---|
| 104 | {
 | 
|---|
| 105 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 106 |     INT i,iorder = (INT)wParam;
 | 
|---|
| 107 | 
 | 
|---|
| 108 | 
 | 
|---|
| 109 |     if ((iorder <0) || iorder >infoPtr->uNumItem)
 | 
|---|
| 110 |       return iorder;
 | 
|---|
| 111 |     for (i=0; i<infoPtr->uNumItem; i++)
 | 
|---|
| 112 |       if (HEADER_IndexToOrder(hwnd,i) == iorder)
 | 
|---|
| 113 |         return i;
 | 
|---|
| 114 |     return iorder;
 | 
|---|
| 115 | }
 | 
|---|
| 116 | 
 | 
|---|
| 117 | static void
 | 
|---|
| 118 | HEADER_SetItemBounds (HWND hwnd)
 | 
|---|
| 119 | {
 | 
|---|
| 120 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 121 |     HEADER_ITEM *phdi;
 | 
|---|
| 122 |     RECT rect;
 | 
|---|
| 123 |     int i, x;
 | 
|---|
| 124 | 
 | 
|---|
| 125 |     infoPtr->bRectsValid = TRUE;
 | 
|---|
| 126 | 
 | 
|---|
| 127 |     if (infoPtr->uNumItem == 0)
 | 
|---|
| 128 |         return;
 | 
|---|
| 129 | 
 | 
|---|
| 130 |     GetClientRect (hwnd, &rect);
 | 
|---|
| 131 | 
 | 
|---|
| 132 |     x = rect.left;
 | 
|---|
| 133 |     for (i = 0; i < infoPtr->uNumItem; i++) {
 | 
|---|
| 134 |         phdi = &infoPtr->items[HEADER_OrderToIndex(hwnd,i)];
 | 
|---|
| 135 |         phdi->rect.top = rect.top;
 | 
|---|
| 136 |         phdi->rect.bottom = rect.bottom;
 | 
|---|
| 137 |         phdi->rect.left = x;
 | 
|---|
| 138 |         phdi->rect.right = phdi->rect.left + ((phdi->cxy>0)?phdi->cxy:0);
 | 
|---|
| 139 |         x = phdi->rect.right;
 | 
|---|
| 140 |     }
 | 
|---|
| 141 | }
 | 
|---|
| 142 | 
 | 
|---|
| 143 | static LRESULT
 | 
|---|
| 144 | HEADER_Size (HWND hwnd, WPARAM wParam)
 | 
|---|
| 145 | {
 | 
|---|
| 146 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 147 | 
 | 
|---|
| 148 |     infoPtr->bRectsValid = FALSE;
 | 
|---|
| 149 | 
 | 
|---|
| 150 |     return 0;
 | 
|---|
| 151 | }
 | 
|---|
| 152 | 
 | 
|---|
| 153 | 
 | 
|---|
| 154 | static INT
 | 
|---|
| 155 | HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack)
 | 
|---|
| 156 | {
 | 
|---|
| 157 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 158 |     HEADER_ITEM *phdi = &infoPtr->items[iItem];
 | 
|---|
| 159 |     RECT r;
 | 
|---|
| 160 |     INT  oldBkMode;
 | 
|---|
| 161 | 
 | 
|---|
| 162 |     TRACE("DrawItem(iItem %d bHotTrack %d unicode flag %d)\n", iItem, bHotTrack, infoPtr->bUnicode);
 | 
|---|
| 163 | 
 | 
|---|
| 164 |     if (!infoPtr->bRectsValid)
 | 
|---|
| 165 |         HEADER_SetItemBounds(hwnd);
 | 
|---|
| 166 | 
 | 
|---|
| 167 |     r = phdi->rect;
 | 
|---|
| 168 |     if (r.right - r.left == 0)
 | 
|---|
| 169 |         return phdi->rect.right;
 | 
|---|
| 170 | 
 | 
|---|
| 171 |     if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS) {
 | 
|---|
| 172 |         if (phdi->bDown) {
 | 
|---|
| 173 |             DrawEdge (hdc, &r, BDR_RAISEDOUTER,
 | 
|---|
| 174 |                         BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
 | 
|---|
| 175 |             r.left += 2;
 | 
|---|
| 176 |             r.top  += 2;
 | 
|---|
| 177 |         }
 | 
|---|
| 178 |         else
 | 
|---|
| 179 |             DrawEdge (hdc, &r, EDGE_RAISED,
 | 
|---|
| 180 |                         BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
 | 
|---|
| 181 |     }
 | 
|---|
| 182 |     else
 | 
|---|
| 183 |         DrawEdge (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
 | 
|---|
| 184 | 
 | 
|---|
| 185 |     if (phdi->fmt & HDF_OWNERDRAW) {
 | 
|---|
| 186 |         DRAWITEMSTRUCT dis;
 | 
|---|
| 187 |         dis.CtlType    = ODT_HEADER;
 | 
|---|
| 188 |         dis.CtlID      = GetWindowLongA (hwnd, GWL_ID);
 | 
|---|
| 189 |         dis.itemID     = iItem;
 | 
|---|
| 190 |         dis.itemAction = ODA_DRAWENTIRE;
 | 
|---|
| 191 |         dis.itemState  = phdi->bDown ? ODS_SELECTED : 0;
 | 
|---|
| 192 |         dis.hwndItem   = hwnd;
 | 
|---|
| 193 |         dis.hDC        = hdc;
 | 
|---|
| 194 |         dis.rcItem     = r;
 | 
|---|
| 195 |         dis.itemData   = phdi->lParam;
 | 
|---|
| 196 |         oldBkMode = SetBkMode(hdc, TRANSPARENT);
 | 
|---|
| 197 |         SendMessageA (GetParent (hwnd), WM_DRAWITEM,
 | 
|---|
| 198 |                         (WPARAM)dis.CtlID, (LPARAM)&dis);
 | 
|---|
| 199 |         if (oldBkMode != TRANSPARENT)
 | 
|---|
| 200 |             SetBkMode(hdc, oldBkMode);
 | 
|---|
| 201 |     }
 | 
|---|
| 202 |     else {
 | 
|---|
| 203 |         UINT uTextJustify = DT_LEFT;
 | 
|---|
| 204 | 
 | 
|---|
| 205 |         if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER)
 | 
|---|
| 206 |             uTextJustify = DT_CENTER;
 | 
|---|
| 207 |         else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT)
 | 
|---|
| 208 |             uTextJustify = DT_RIGHT;
 | 
|---|
| 209 | 
 | 
|---|
| 210 |         if ((phdi->fmt & HDF_BITMAP) && !(phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) {
 | 
|---|
| 211 |             BITMAP bmp;
 | 
|---|
| 212 |             HDC    hdcBitmap;
 | 
|---|
| 213 |             INT    yD, yS, cx, cy, rx, ry;
 | 
|---|
| 214 | 
 | 
|---|
| 215 |             GetObjectA (phdi->hbm, sizeof(BITMAP), (LPVOID)&bmp);
 | 
|---|
| 216 | 
 | 
|---|
| 217 |             ry = r.bottom - r.top;
 | 
|---|
| 218 |             rx = r.right - r.left;
 | 
|---|
| 219 | 
 | 
|---|
| 220 |             if (ry >= bmp.bmHeight) {
 | 
|---|
| 221 |                 cy = bmp.bmHeight;
 | 
|---|
| 222 |                 yD = r.top + (ry - bmp.bmHeight) / 2;
 | 
|---|
| 223 |                 yS = 0;
 | 
|---|
| 224 |             }
 | 
|---|
| 225 |             else {
 | 
|---|
| 226 |                 cy = ry;
 | 
|---|
| 227 |                 yD = r.top;
 | 
|---|
| 228 |                 yS = (bmp.bmHeight - ry) / 2;
 | 
|---|
| 229 | 
 | 
|---|
| 230 |             }
 | 
|---|
| 231 | 
 | 
|---|
| 232 |             if (rx >= bmp.bmWidth + 6) {
 | 
|---|
| 233 |                 cx = bmp.bmWidth;
 | 
|---|
| 234 |             }
 | 
|---|
| 235 |             else {
 | 
|---|
| 236 |                 cx = rx - 6;
 | 
|---|
| 237 |             }
 | 
|---|
| 238 | 
 | 
|---|
| 239 |             hdcBitmap = CreateCompatibleDC (hdc);
 | 
|---|
| 240 |             SelectObject (hdcBitmap, phdi->hbm);
 | 
|---|
| 241 |             BitBlt (hdc, r.left + 3, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
 | 
|---|
| 242 |             DeleteDC (hdcBitmap);
 | 
|---|
| 243 | 
 | 
|---|
| 244 |             r.left += (bmp.bmWidth + 3);
 | 
|---|
| 245 |         }
 | 
|---|
| 246 | 
 | 
|---|
| 247 | 
 | 
|---|
| 248 |         if ((phdi->fmt & HDF_BITMAP) && (phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) {
 | 
|---|
| 249 |             BITMAP bmp;
 | 
|---|
| 250 |             HDC    hdcBitmap;
 | 
|---|
| 251 |             INT    xD, yD, yS, cx, cy, rx, ry, tx;
 | 
|---|
| 252 |             RECT   textRect;
 | 
|---|
| 253 | 
 | 
|---|
| 254 |             GetObjectA (phdi->hbm, sizeof(BITMAP), (LPVOID)&bmp);
 | 
|---|
| 255 | 
 | 
|---|
| 256 |             textRect = r;
 | 
|---|
| 257 |             DrawTextW (hdc, phdi->pszText, -1,
 | 
|---|
| 258 |                        &textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
 | 
|---|
| 259 |             tx = textRect.right - textRect.left;
 | 
|---|
| 260 |             ry = r.bottom - r.top;
 | 
|---|
| 261 |             rx = r.right - r.left;
 | 
|---|
| 262 | 
 | 
|---|
| 263 |             if (ry >= bmp.bmHeight) {
 | 
|---|
| 264 |                 cy = bmp.bmHeight;
 | 
|---|
| 265 |                 yD = r.top + (ry - bmp.bmHeight) / 2;
 | 
|---|
| 266 |                 yS = 0;
 | 
|---|
| 267 |             }
 | 
|---|
| 268 |             else {
 | 
|---|
| 269 |                 cy = ry;
 | 
|---|
| 270 |                 yD = r.top;
 | 
|---|
| 271 |                 yS = (bmp.bmHeight - ry) / 2;
 | 
|---|
| 272 | 
 | 
|---|
| 273 |             }
 | 
|---|
| 274 | 
 | 
|---|
| 275 |             if (r.left + tx + bmp.bmWidth + 9 <= r.right) {
 | 
|---|
| 276 |                 cx = bmp.bmWidth;
 | 
|---|
| 277 |                 xD = r.left + tx + 6;
 | 
|---|
| 278 |             }
 | 
|---|
| 279 |             else {
 | 
|---|
| 280 |                 if (rx >= bmp.bmWidth + 6) {
 | 
|---|
| 281 |                     cx = bmp.bmWidth;
 | 
|---|
| 282 |                     xD = r.right - bmp.bmWidth - 3;
 | 
|---|
| 283 |                     r.right = xD - 3;
 | 
|---|
| 284 |                 }
 | 
|---|
| 285 |                 else {
 | 
|---|
| 286 |                     cx = rx - 3;
 | 
|---|
| 287 |                     xD = r.left;
 | 
|---|
| 288 |                     r.right = r.left;
 | 
|---|
| 289 |                 }
 | 
|---|
| 290 |             }
 | 
|---|
| 291 | 
 | 
|---|
| 292 |             hdcBitmap = CreateCompatibleDC (hdc);
 | 
|---|
| 293 |             SelectObject (hdcBitmap, phdi->hbm);
 | 
|---|
| 294 |             BitBlt (hdc, xD, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
 | 
|---|
| 295 |             DeleteDC (hdcBitmap);
 | 
|---|
| 296 |         }
 | 
|---|
| 297 | 
 | 
|---|
| 298 |         if ((phdi->fmt & HDF_IMAGE) && (infoPtr->himl)) {
 | 
|---|
| 299 |           r.left +=3;
 | 
|---|
| 300 |           /* FIXME: (r.bottom- (infoPtr->himl->cy))/2 should horicontal center the image
 | 
|---|
| 301 |              It looks like it doesn't work as expected*/
 | 
|---|
| 302 |           ImageList_Draw (infoPtr->himl, phdi->iImage,hdc,r.left, (r.bottom- (infoPtr->himl->cy))/2,0);
 | 
|---|
| 303 |           r.left += infoPtr->himl->cx;
 | 
|---|
| 304 |         }
 | 
|---|
| 305 | 
 | 
|---|
| 306 |         if (((phdi->fmt & HDF_STRING)
 | 
|---|
| 307 |                 || (!(phdi->fmt & (HDF_OWNERDRAW|HDF_STRING|HDF_BITMAP|
 | 
|---|
| 308 |                                    HDF_BITMAP_ON_RIGHT|HDF_IMAGE)))) /* no explicit format specified? */
 | 
|---|
| 309 |             && (phdi->pszText)) {
 | 
|---|
| 310 |             oldBkMode = SetBkMode(hdc, TRANSPARENT);
 | 
|---|
| 311 |             r.left += 3 ;
 | 
|---|
| 312 |             r.right -= 3;
 | 
|---|
| 313 |             SetTextColor (hdc, (bHotTrack) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
 | 
|---|
| 314 |             DrawTextW (hdc, phdi->pszText, -1,
 | 
|---|
| 315 |                        &r, uTextJustify|DT_END_ELLIPSIS|DT_VCENTER|DT_SINGLELINE);
 | 
|---|
| 316 |             if (oldBkMode != TRANSPARENT)
 | 
|---|
| 317 |                 SetBkMode(hdc, oldBkMode);
 | 
|---|
| 318 |         }
 | 
|---|
| 319 |     }/*Ownerdrawn*/
 | 
|---|
| 320 | 
 | 
|---|
| 321 |     return phdi->rect.right;
 | 
|---|
| 322 | }
 | 
|---|
| 323 | 
 | 
|---|
| 324 | 
 | 
|---|
| 325 | static void
 | 
|---|
| 326 | HEADER_Refresh (HWND hwnd, HDC hdc)
 | 
|---|
| 327 | {
 | 
|---|
| 328 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 329 |     HFONT hFont, hOldFont;
 | 
|---|
| 330 |     RECT rect;
 | 
|---|
| 331 |     HBRUSH hbrBk;
 | 
|---|
| 332 |     INT i, x;
 | 
|---|
| 333 | 
 | 
|---|
| 334 |     /* get rect for the bar, adjusted for the border */
 | 
|---|
| 335 |     GetClientRect (hwnd, &rect);
 | 
|---|
| 336 | 
 | 
|---|
| 337 |     hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
 | 
|---|
| 338 |     hOldFont = SelectObject (hdc, hFont);
 | 
|---|
| 339 | 
 | 
|---|
| 340 |     /* draw Background */
 | 
|---|
| 341 |     hbrBk = GetSysColorBrush(COLOR_3DFACE);
 | 
|---|
| 342 |     FillRect(hdc, &rect, hbrBk);
 | 
|---|
| 343 | 
 | 
|---|
| 344 |     x = rect.left;
 | 
|---|
| 345 |     for (i = 0; i < infoPtr->uNumItem; i++) {
 | 
|---|
| 346 |         x = HEADER_DrawItem (hwnd, hdc, HEADER_OrderToIndex(hwnd,i), FALSE);
 | 
|---|
| 347 |     }
 | 
|---|
| 348 | 
 | 
|---|
| 349 |     if ((x <= rect.right) && (infoPtr->uNumItem > 0)) {
 | 
|---|
| 350 |         rect.left = x;
 | 
|---|
| 351 |         if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS)
 | 
|---|
| 352 |             DrawEdge (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT);
 | 
|---|
| 353 |         else
 | 
|---|
| 354 |             DrawEdge (hdc, &rect, EDGE_ETCHED, BF_BOTTOM);
 | 
|---|
| 355 |     }
 | 
|---|
| 356 | 
 | 
|---|
| 357 |     SelectObject (hdc, hOldFont);
 | 
|---|
| 358 | }
 | 
|---|
| 359 | 
 | 
|---|
| 360 | 
 | 
|---|
| 361 | static void
 | 
|---|
| 362 | HEADER_RefreshItem (HWND hwnd, HDC hdc, INT iItem)
 | 
|---|
| 363 | {
 | 
|---|
| 364 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 365 |     HFONT hFont, hOldFont;
 | 
|---|
| 366 | 
 | 
|---|
| 367 |     hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
 | 
|---|
| 368 |     hOldFont = SelectObject (hdc, hFont);
 | 
|---|
| 369 |     HEADER_DrawItem (hwnd, hdc, iItem, FALSE);
 | 
|---|
| 370 |     SelectObject (hdc, hOldFont);
 | 
|---|
| 371 | }
 | 
|---|
| 372 | 
 | 
|---|
| 373 | 
 | 
|---|
| 374 | static void
 | 
|---|
| 375 | HEADER_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pItem)
 | 
|---|
| 376 | {
 | 
|---|
| 377 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 378 |     RECT rect, rcTest;
 | 
|---|
| 379 |     INT  iCount, width;
 | 
|---|
| 380 |     BOOL bNoWidth;
 | 
|---|
| 381 | 
 | 
|---|
| 382 |     GetClientRect (hwnd, &rect);
 | 
|---|
| 383 | 
 | 
|---|
| 384 |     *pFlags = 0;
 | 
|---|
| 385 |     bNoWidth = FALSE;
 | 
|---|
| 386 |     if (PtInRect (&rect, *lpPt))
 | 
|---|
| 387 |     {
 | 
|---|
| 388 |         if (infoPtr->uNumItem == 0) {
 | 
|---|
| 389 |             *pFlags |= HHT_NOWHERE;
 | 
|---|
| 390 |             *pItem = 1;
 | 
|---|
| 391 |             TRACE("NOWHERE\n");
 | 
|---|
| 392 |             return;
 | 
|---|
| 393 |         }
 | 
|---|
| 394 |         else {
 | 
|---|
| 395 |             /* somewhere inside */
 | 
|---|
| 396 |             for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) {
 | 
|---|
| 397 |                 rect = infoPtr->items[iCount].rect;
 | 
|---|
| 398 |                 width = rect.right - rect.left;
 | 
|---|
| 399 |                 if (width == 0) {
 | 
|---|
| 400 |                     bNoWidth = TRUE;
 | 
|---|
| 401 |                     continue;
 | 
|---|
| 402 |                 }
 | 
|---|
| 403 |                 if (PtInRect (&rect, *lpPt)) {
 | 
|---|
| 404 |                     if (width <= 2 * DIVIDER_WIDTH) {
 | 
|---|
| 405 |                         *pFlags |= HHT_ONHEADER;
 | 
|---|
| 406 |                         *pItem = iCount;
 | 
|---|
| 407 |                         TRACE("ON HEADER %d\n", iCount);
 | 
|---|
| 408 |                         return;
 | 
|---|
| 409 |                     }
 | 
|---|
| 410 |                     if (iCount > 0) {
 | 
|---|
| 411 |                         rcTest = rect;
 | 
|---|
| 412 |                         rcTest.right = rcTest.left + DIVIDER_WIDTH;
 | 
|---|
| 413 |                         if (PtInRect (&rcTest, *lpPt)) {
 | 
|---|
| 414 |                             if (bNoWidth) {
 | 
|---|
| 415 |                                 *pFlags |= HHT_ONDIVOPEN;
 | 
|---|
| 416 |                                 *pItem = iCount - 1;
 | 
|---|
| 417 |                                 TRACE("ON DIVOPEN %d\n", *pItem);
 | 
|---|
| 418 |                                 return;
 | 
|---|
| 419 |                             }
 | 
|---|
| 420 |                             else {
 | 
|---|
| 421 |                                 *pFlags |= HHT_ONDIVIDER;
 | 
|---|
| 422 |                                 *pItem = iCount - 1;
 | 
|---|
| 423 |                                 TRACE("ON DIVIDER %d\n", *pItem);
 | 
|---|
| 424 |                                 return;
 | 
|---|
| 425 |                             }
 | 
|---|
| 426 |                         }
 | 
|---|
| 427 |                     }
 | 
|---|
| 428 |                     rcTest = rect;
 | 
|---|
| 429 |                     rcTest.left = rcTest.right - DIVIDER_WIDTH;
 | 
|---|
| 430 |                     if (PtInRect (&rcTest, *lpPt)) {
 | 
|---|
| 431 |                         *pFlags |= HHT_ONDIVIDER;
 | 
|---|
| 432 |                         *pItem = iCount;
 | 
|---|
| 433 |                         TRACE("ON DIVIDER %d\n", *pItem);
 | 
|---|
| 434 |                         return;
 | 
|---|
| 435 |                     }
 | 
|---|
| 436 | 
 | 
|---|
| 437 |                     *pFlags |= HHT_ONHEADER;
 | 
|---|
| 438 |                     *pItem = iCount;
 | 
|---|
| 439 |                     TRACE("ON HEADER %d\n", iCount);
 | 
|---|
| 440 |                     return;
 | 
|---|
| 441 |                 }
 | 
|---|
| 442 |             }
 | 
|---|
| 443 | 
 | 
|---|
| 444 |             /* check for last divider part (on nowhere) */
 | 
|---|
| 445 |             rect = infoPtr->items[infoPtr->uNumItem-1].rect;
 | 
|---|
| 446 |             rect.left = rect.right;
 | 
|---|
| 447 |             rect.right += DIVIDER_WIDTH;
 | 
|---|
| 448 |             if (PtInRect (&rect, *lpPt)) {
 | 
|---|
| 449 |                 if (bNoWidth) {
 | 
|---|
| 450 |                     *pFlags |= HHT_ONDIVOPEN;
 | 
|---|
| 451 |                     *pItem = infoPtr->uNumItem - 1;
 | 
|---|
| 452 |                     TRACE("ON DIVOPEN %d\n", *pItem);
 | 
|---|
| 453 |                     return;
 | 
|---|
| 454 |                 }
 | 
|---|
| 455 |                 else {
 | 
|---|
| 456 |                     *pFlags |= HHT_ONDIVIDER;
 | 
|---|
| 457 |                     *pItem = infoPtr->uNumItem-1;
 | 
|---|
| 458 |                     TRACE("ON DIVIDER %d\n", *pItem);
 | 
|---|
| 459 |                     return;
 | 
|---|
| 460 |                 }
 | 
|---|
| 461 |             }
 | 
|---|
| 462 | 
 | 
|---|
| 463 |             *pFlags |= HHT_NOWHERE;
 | 
|---|
| 464 |             *pItem = 1;
 | 
|---|
| 465 |             TRACE("NOWHERE\n");
 | 
|---|
| 466 |             return;
 | 
|---|
| 467 |         }
 | 
|---|
| 468 |     }
 | 
|---|
| 469 |     else {
 | 
|---|
| 470 |         if (lpPt->x < rect.left) {
 | 
|---|
| 471 |            TRACE("TO LEFT\n");
 | 
|---|
| 472 |            *pFlags |= HHT_TOLEFT;
 | 
|---|
| 473 |         }
 | 
|---|
| 474 |         else if (lpPt->x > rect.right) {
 | 
|---|
| 475 |             TRACE("TO RIGHT\n");
 | 
|---|
| 476 |             *pFlags |= HHT_TORIGHT;
 | 
|---|
| 477 |         }
 | 
|---|
| 478 | 
 | 
|---|
| 479 |         if (lpPt->y < rect.top) {
 | 
|---|
| 480 |             TRACE("ABOVE\n");
 | 
|---|
| 481 |             *pFlags |= HHT_ABOVE;
 | 
|---|
| 482 |         }
 | 
|---|
| 483 |         else if (lpPt->y > rect.bottom) {
 | 
|---|
| 484 |             TRACE("BELOW\n");
 | 
|---|
| 485 |             *pFlags |= HHT_BELOW;
 | 
|---|
| 486 |         }
 | 
|---|
| 487 |     }
 | 
|---|
| 488 | 
 | 
|---|
| 489 |     *pItem = 1;
 | 
|---|
| 490 |     TRACE("flags=0x%X\n", *pFlags);
 | 
|---|
| 491 |     return;
 | 
|---|
| 492 | }
 | 
|---|
| 493 | 
 | 
|---|
| 494 | 
 | 
|---|
| 495 | static void
 | 
|---|
| 496 | HEADER_DrawTrackLine (HWND hwnd, HDC hdc, INT x)
 | 
|---|
| 497 | {
 | 
|---|
| 498 |     RECT rect;
 | 
|---|
| 499 |     HPEN hOldPen;
 | 
|---|
| 500 |     INT  oldRop;
 | 
|---|
| 501 | 
 | 
|---|
| 502 |     GetClientRect (hwnd, &rect);
 | 
|---|
| 503 | 
 | 
|---|
| 504 |     hOldPen = SelectObject (hdc, GetStockObject (BLACK_PEN));
 | 
|---|
| 505 |     oldRop = SetROP2 (hdc, R2_XORPEN);
 | 
|---|
| 506 |     MoveToEx (hdc, x, rect.top, NULL);
 | 
|---|
| 507 |     LineTo (hdc, x, rect.bottom);
 | 
|---|
| 508 |     SetROP2 (hdc, oldRop);
 | 
|---|
| 509 |     SelectObject (hdc, hOldPen);
 | 
|---|
| 510 | }
 | 
|---|
| 511 | 
 | 
|---|
| 512 | 
 | 
|---|
| 513 | static BOOL
 | 
|---|
| 514 | HEADER_SendSimpleNotify (HWND hwnd, UINT code)
 | 
|---|
| 515 | {
 | 
|---|
| 516 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 517 |     NMHDR nmhdr;
 | 
|---|
| 518 | 
 | 
|---|
| 519 |     nmhdr.hwndFrom = hwnd;
 | 
|---|
| 520 |     nmhdr.idFrom   = GetWindowLongA (hwnd, GWL_ID);
 | 
|---|
| 521 |     nmhdr.code     = code;
 | 
|---|
| 522 | 
 | 
|---|
| 523 |     return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
 | 
|---|
| 524 |                                    (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
 | 
|---|
| 525 | }
 | 
|---|
| 526 | 
 | 
|---|
| 527 | static BOOL
 | 
|---|
| 528 | HEADER_SendHeaderNotify (HWND hwnd, UINT code, INT iItem, INT mask)
 | 
|---|
| 529 | {
 | 
|---|
| 530 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 531 |     NMHEADERA nmhdr;
 | 
|---|
| 532 |     HDITEMA nmitem;
 | 
|---|
| 533 | 
 | 
|---|
| 534 |     nmhdr.hdr.hwndFrom = hwnd;
 | 
|---|
| 535 |     nmhdr.hdr.idFrom   = GetWindowLongA (hwnd, GWL_ID);
 | 
|---|
| 536 |     nmhdr.hdr.code = code;
 | 
|---|
| 537 |     nmhdr.iItem = iItem;
 | 
|---|
| 538 |     nmhdr.iButton = 0;
 | 
|---|
| 539 |     nmhdr.pitem = &nmitem;
 | 
|---|
| 540 |     nmitem.mask = mask;
 | 
|---|
| 541 |     nmitem.cxy = infoPtr->items[iItem].cxy;
 | 
|---|
| 542 |     nmitem.hbm = infoPtr->items[iItem].hbm;
 | 
|---|
| 543 |     nmitem.pszText = NULL;
 | 
|---|
| 544 |     nmitem.cchTextMax = 0;
 | 
|---|
| 545 | /*    nmitem.pszText = infoPtr->items[iItem].pszText; */
 | 
|---|
| 546 | /*    nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax; */
 | 
|---|
| 547 |     nmitem.fmt = infoPtr->items[iItem].fmt;
 | 
|---|
| 548 |     nmitem.lParam = infoPtr->items[iItem].lParam;
 | 
|---|
| 549 |     nmitem.iOrder = infoPtr->items[iItem].iOrder;
 | 
|---|
| 550 |     nmitem.iImage = infoPtr->items[iItem].iImage;
 | 
|---|
| 551 | 
 | 
|---|
| 552 |     return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
 | 
|---|
| 553 |                                (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
 | 
|---|
| 554 | }
 | 
|---|
| 555 | 
 | 
|---|
| 556 | 
 | 
|---|
| 557 | static BOOL
 | 
|---|
| 558 | HEADER_SendClickNotify (HWND hwnd, UINT code, INT iItem)
 | 
|---|
| 559 | {
 | 
|---|
| 560 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 561 |     NMHEADERA nmhdr;
 | 
|---|
| 562 | 
 | 
|---|
| 563 |     nmhdr.hdr.hwndFrom = hwnd;
 | 
|---|
| 564 |     nmhdr.hdr.idFrom   = GetWindowLongA (hwnd, GWL_ID);
 | 
|---|
| 565 |     nmhdr.hdr.code = code;
 | 
|---|
| 566 |     nmhdr.iItem = iItem;
 | 
|---|
| 567 |     nmhdr.iButton = 0;
 | 
|---|
| 568 |     nmhdr.pitem = NULL;
 | 
|---|
| 569 | 
 | 
|---|
| 570 |     return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
 | 
|---|
| 571 |                                (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr);
 | 
|---|
| 572 | }
 | 
|---|
| 573 | 
 | 
|---|
| 574 | 
 | 
|---|
| 575 | static LRESULT
 | 
|---|
| 576 | HEADER_CreateDragImage (HWND hwnd, WPARAM wParam)
 | 
|---|
| 577 | {
 | 
|---|
| 578 |     FIXME("empty stub!\n");
 | 
|---|
| 579 |     return 0;
 | 
|---|
| 580 | }
 | 
|---|
| 581 | 
 | 
|---|
| 582 | 
 | 
|---|
| 583 | static LRESULT
 | 
|---|
| 584 | HEADER_DeleteItem (HWND hwnd, WPARAM wParam)
 | 
|---|
| 585 | {
 | 
|---|
| 586 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
 | 
|---|
| 587 |     INT iItem = (INT)wParam;
 | 
|---|
| 588 | 
 | 
|---|
| 589 |     TRACE("[iItem=%d]\n", iItem);
 | 
|---|
| 590 | 
 | 
|---|
| 591 |     if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
 | 
|---|
| 592 |         return FALSE;
 | 
|---|
| 593 | 
 | 
|---|
| 594 |     if (infoPtr->uNumItem == 1) {
 | 
|---|
| 595 |         TRACE("Simple delete!\n");
 | 
|---|
| 596 |         if (infoPtr->items[0].pszText)
 | 
|---|
| 597 |             COMCTL32_Free (infoPtr->items[0].pszText);
 | 
|---|
| 598 |         COMCTL32_Free (infoPtr->items);
 | 
|---|
| 599 |         infoPtr->items = 0;
 | 
|---|
| 600 |         infoPtr->uNumItem = 0;
 | 
|---|
| 601 |     }
 | 
|---|
| 602 |     else {
 | 
|---|
| 603 |         HEADER_ITEM *oldItems = infoPtr->items;
 | 
|---|
| 604 |         HEADER_ITEM *pItem;
 | 
|---|
| 605 |         INT i;
 | 
|---|
| 606 |         INT iOrder;
 | 
|---|
| 607 |         TRACE("Complex delete! [iItem=%d]\n", iItem);
 | 
|---|
| 608 | 
 | 
|---|
| 609 |         if (infoPtr->items[iItem].pszText)
 | 
|---|
| 610 |             COMCTL32_Free (infoPtr->items[iItem].pszText);
 | 
|---|
| 611 |         iOrder = infoPtr->items[iItem].iOrder;
 | 
|---|
| 612 | 
 | 
|---|
| 613 |         infoPtr->uNumItem--;
 | 
|---|
| 614 |         infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
 | 
|---|
| 615 |         /* pre delete copy */
 | 
|---|
| 616 |         if (iItem > 0) {
 | 
|---|
| 617 |             memcpy (&infoPtr->items[0], &oldItems[0],
 | 
|---|
| 618 |                     iItem * sizeof(HEADER_ITEM));
 | 
|---|
| 619 |         }
 | 
|---|
| 620 | 
 | 
|---|
| 621 |         /* post delete copy */
 | 
|---|
| 622 |         if (iItem < infoPtr->uNumItem) {
 | 
|---|
| 623 |             memcpy (&infoPtr->items[iItem], &oldItems[iItem+1],
 | 
|---|
| 624 |                     (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
 | 
|---|
| 625 |         }
 | 
|---|
| 626 | 
 | 
|---|
| 627 |         /* Correct the orders */
 | 
|---|
| 628 |         for (i=infoPtr->uNumItem, pItem = infoPtr->items; i; i--, pItem++)
 | 
|---|
| 629 |         {
 | 
|---|
| 630 |             if (pItem->iOrder > iOrder)
 | 
|---|
| 631 |             pItem->iOrder--;
 | 
|---|
| 632 |         }
 | 
|---|
| 633 |         COMCTL32_Free (oldItems);
 | 
|---|
| 634 |     }
 | 
|---|
| 635 | 
 | 
|---|
| 636 |     HEADER_SetItemBounds (hwnd);
 | 
|---|
| 637 | 
 | 
|---|
| 638 |     InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 639 | 
 | 
|---|
| 640 |     return TRUE;
 | 
|---|
| 641 | }
 | 
|---|
| 642 | 
 | 
|---|
| 643 | 
 | 
|---|
| 644 | static LRESULT
 | 
|---|
| 645 | HEADER_GetImageList (HWND hwnd)
 | 
|---|
| 646 | {
 | 
|---|
| 647 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 648 | 
 | 
|---|
| 649 |     return (LRESULT)infoPtr->himl;
 | 
|---|
| 650 | }
 | 
|---|
| 651 | 
 | 
|---|
| 652 | 
 | 
|---|
| 653 | static LRESULT
 | 
|---|
| 654 | HEADER_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 655 | {
 | 
|---|
| 656 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 657 |     HDITEMA   *phdi = (HDITEMA*)lParam;
 | 
|---|
| 658 |     INT       nItem = (INT)wParam;
 | 
|---|
| 659 |     HEADER_ITEM *lpItem;
 | 
|---|
| 660 | 
 | 
|---|
| 661 |     if (!phdi)
 | 
|---|
| 662 |         return FALSE;
 | 
|---|
| 663 |     if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
 | 
|---|
| 664 |         return FALSE;
 | 
|---|
| 665 | 
 | 
|---|
| 666 |     TRACE("[nItem=%d]\n", nItem);
 | 
|---|
| 667 | 
 | 
|---|
| 668 |     if (phdi->mask == 0)
 | 
|---|
| 669 |         return TRUE;
 | 
|---|
| 670 | 
 | 
|---|
| 671 |     lpItem = &infoPtr->items[nItem];
 | 
|---|
| 672 |     if (phdi->mask & HDI_BITMAP)
 | 
|---|
| 673 |         phdi->hbm = lpItem->hbm;
 | 
|---|
| 674 | 
 | 
|---|
| 675 |     if (phdi->mask & HDI_FORMAT)
 | 
|---|
| 676 |         phdi->fmt = lpItem->fmt;
 | 
|---|
| 677 | 
 | 
|---|
| 678 |     if (phdi->mask & HDI_WIDTH)
 | 
|---|
| 679 |         phdi->cxy = lpItem->cxy;
 | 
|---|
| 680 | 
 | 
|---|
| 681 |     if (phdi->mask & HDI_LPARAM)
 | 
|---|
| 682 |         phdi->lParam = lpItem->lParam;
 | 
|---|
| 683 | 
 | 
|---|
| 684 |     if (phdi->mask & HDI_TEXT) {
 | 
|---|
| 685 |         if (lpItem->pszText != LPSTR_TEXTCALLBACKW) {
 | 
|---|
| 686 |             if (lpItem->pszText)
 | 
|---|
| 687 |                 WideCharToMultiByte (CP_ACP, 0, lpItem->pszText, -1,
 | 
|---|
| 688 |                                      phdi->pszText, phdi->cchTextMax, NULL, NULL);
 | 
|---|
| 689 |             else
 | 
|---|
| 690 |                 *phdi->pszText = 0;
 | 
|---|
| 691 |         }
 | 
|---|
| 692 |         else
 | 
|---|
| 693 |             phdi->pszText = LPSTR_TEXTCALLBACKA;
 | 
|---|
| 694 |     }
 | 
|---|
| 695 | 
 | 
|---|
| 696 |     if (phdi->mask & HDI_IMAGE)
 | 
|---|
| 697 |         phdi->iImage = lpItem->iImage;
 | 
|---|
| 698 | 
 | 
|---|
| 699 |     if (phdi->mask & HDI_ORDER)
 | 
|---|
| 700 |         phdi->iOrder = lpItem->iOrder;
 | 
|---|
| 701 | 
 | 
|---|
| 702 |     return TRUE;
 | 
|---|
| 703 | }
 | 
|---|
| 704 | 
 | 
|---|
| 705 | 
 | 
|---|
| 706 | static LRESULT
 | 
|---|
| 707 | HEADER_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 708 | {
 | 
|---|
| 709 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 710 |     HDITEMW   *phdi = (HDITEMW*)lParam;
 | 
|---|
| 711 |     INT       nItem = (INT)wParam;
 | 
|---|
| 712 |     HEADER_ITEM *lpItem;
 | 
|---|
| 713 | 
 | 
|---|
| 714 |     if (!phdi)
 | 
|---|
| 715 |         return FALSE;
 | 
|---|
| 716 |     if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
 | 
|---|
| 717 |         return FALSE;
 | 
|---|
| 718 | 
 | 
|---|
| 719 |     TRACE("[nItem=%d]\n", nItem);
 | 
|---|
| 720 | 
 | 
|---|
| 721 |     if (phdi->mask == 0)
 | 
|---|
| 722 |         return TRUE;
 | 
|---|
| 723 | 
 | 
|---|
| 724 |     lpItem = &infoPtr->items[nItem];
 | 
|---|
| 725 |     if (phdi->mask & HDI_BITMAP)
 | 
|---|
| 726 |         phdi->hbm = lpItem->hbm;
 | 
|---|
| 727 | 
 | 
|---|
| 728 |     if (phdi->mask & HDI_FORMAT)
 | 
|---|
| 729 |         phdi->fmt = lpItem->fmt;
 | 
|---|
| 730 | 
 | 
|---|
| 731 |     if (phdi->mask & HDI_WIDTH)
 | 
|---|
| 732 |         phdi->cxy = lpItem->cxy;
 | 
|---|
| 733 | 
 | 
|---|
| 734 |     if (phdi->mask & HDI_LPARAM)
 | 
|---|
| 735 |         phdi->lParam = lpItem->lParam;
 | 
|---|
| 736 | 
 | 
|---|
| 737 |     if (phdi->mask & HDI_TEXT) {
 | 
|---|
| 738 |         if (lpItem->pszText != LPSTR_TEXTCALLBACKW) {
 | 
|---|
| 739 |             if (lpItem->pszText)
 | 
|---|
| 740 |                 lstrcpynW (phdi->pszText, lpItem->pszText, phdi->cchTextMax);
 | 
|---|
| 741 |             else
 | 
|---|
| 742 |                 *phdi->pszText = 0;
 | 
|---|
| 743 |         }
 | 
|---|
| 744 |         else
 | 
|---|
| 745 |             phdi->pszText = LPSTR_TEXTCALLBACKW;
 | 
|---|
| 746 |     }
 | 
|---|
| 747 | 
 | 
|---|
| 748 |     if (phdi->mask & HDI_IMAGE)
 | 
|---|
| 749 |         phdi->iImage = lpItem->iImage;
 | 
|---|
| 750 | 
 | 
|---|
| 751 |     if (phdi->mask & HDI_ORDER)
 | 
|---|
| 752 |         phdi->iOrder = lpItem->iOrder;
 | 
|---|
| 753 | 
 | 
|---|
| 754 |     return TRUE;
 | 
|---|
| 755 | }
 | 
|---|
| 756 | 
 | 
|---|
| 757 | 
 | 
|---|
| 758 | inline static LRESULT
 | 
|---|
| 759 | HEADER_GetItemCount (HWND hwnd)
 | 
|---|
| 760 | {
 | 
|---|
| 761 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 762 |     return infoPtr->uNumItem;
 | 
|---|
| 763 | }
 | 
|---|
| 764 | 
 | 
|---|
| 765 | 
 | 
|---|
| 766 | static LRESULT
 | 
|---|
| 767 | HEADER_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 768 | {
 | 
|---|
| 769 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 770 |     INT iItem = (INT)wParam;
 | 
|---|
| 771 |     LPRECT lpRect = (LPRECT)lParam;
 | 
|---|
| 772 | 
 | 
|---|
| 773 |     if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem))
 | 
|---|
| 774 |         return FALSE;
 | 
|---|
| 775 | 
 | 
|---|
| 776 |     lpRect->left   = infoPtr->items[iItem].rect.left;
 | 
|---|
| 777 |     lpRect->right  = infoPtr->items[iItem].rect.right;
 | 
|---|
| 778 |     lpRect->top    = infoPtr->items[iItem].rect.top;
 | 
|---|
| 779 |     lpRect->bottom = infoPtr->items[iItem].rect.bottom;
 | 
|---|
| 780 | 
 | 
|---|
| 781 |     return TRUE;
 | 
|---|
| 782 | }
 | 
|---|
| 783 | 
 | 
|---|
| 784 | 
 | 
|---|
| 785 | static LRESULT
 | 
|---|
| 786 | HEADER_GetOrderArray(HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 787 | {
 | 
|---|
| 788 |     int i;
 | 
|---|
| 789 |     LPINT order = (LPINT) lParam;
 | 
|---|
| 790 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 791 | 
 | 
|---|
| 792 |     if ((int)wParam <infoPtr->uNumItem)
 | 
|---|
| 793 |       return FALSE;
 | 
|---|
| 794 |     for (i=0; i<(int)wParam; i++)
 | 
|---|
| 795 |       *order++=HEADER_OrderToIndex(hwnd,i);
 | 
|---|
| 796 |     return TRUE;
 | 
|---|
| 797 | }
 | 
|---|
| 798 | 
 | 
|---|
| 799 | static LRESULT
 | 
|---|
| 800 | HEADER_SetOrderArray(HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 801 | {
 | 
|---|
| 802 |     int i;
 | 
|---|
| 803 |     LPINT order = (LPINT) lParam;
 | 
|---|
| 804 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 805 |     HEADER_ITEM *lpItem;
 | 
|---|
| 806 | 
 | 
|---|
| 807 |     if ((int)wParam <infoPtr->uNumItem)
 | 
|---|
| 808 |       return FALSE;
 | 
|---|
| 809 |     for (i=0; i<(int)wParam; i++)
 | 
|---|
| 810 |       {
 | 
|---|
| 811 |         lpItem = &infoPtr->items[*order++];
 | 
|---|
| 812 |         lpItem->iOrder=i;
 | 
|---|
| 813 |       }
 | 
|---|
| 814 |     infoPtr->bRectsValid=0;
 | 
|---|
| 815 |     InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 816 |     return TRUE;
 | 
|---|
| 817 | }
 | 
|---|
| 818 | 
 | 
|---|
| 819 | inline static LRESULT
 | 
|---|
| 820 | HEADER_GetUnicodeFormat (HWND hwnd)
 | 
|---|
| 821 | {
 | 
|---|
| 822 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 823 |     return infoPtr->bUnicode;
 | 
|---|
| 824 | }
 | 
|---|
| 825 | 
 | 
|---|
| 826 | 
 | 
|---|
| 827 | static LRESULT
 | 
|---|
| 828 | HEADER_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 829 | {
 | 
|---|
| 830 |     LPHDHITTESTINFO phti = (LPHDHITTESTINFO)lParam;
 | 
|---|
| 831 | 
 | 
|---|
| 832 |     HEADER_InternalHitTest (hwnd, &phti->pt, &phti->flags, &phti->iItem);
 | 
|---|
| 833 | 
 | 
|---|
| 834 |     if (phti->flags == HHT_ONHEADER)
 | 
|---|
| 835 |         return phti->iItem;
 | 
|---|
| 836 |     else
 | 
|---|
| 837 |         return -1;
 | 
|---|
| 838 | }
 | 
|---|
| 839 | 
 | 
|---|
| 840 | 
 | 
|---|
| 841 | static LRESULT
 | 
|---|
| 842 | HEADER_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 843 | {
 | 
|---|
| 844 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 845 |     HDITEMA   *phdi = (HDITEMA*)lParam;
 | 
|---|
| 846 |     INT       nItem = (INT)wParam;
 | 
|---|
| 847 |     HEADER_ITEM *lpItem;
 | 
|---|
| 848 |     INT       len;
 | 
|---|
| 849 | 
 | 
|---|
| 850 |     if ((phdi == NULL) || (nItem < 0))
 | 
|---|
| 851 |         return -1;
 | 
|---|
| 852 | 
 | 
|---|
| 853 |     if (nItem > infoPtr->uNumItem)
 | 
|---|
| 854 |         nItem = infoPtr->uNumItem;
 | 
|---|
| 855 | 
 | 
|---|
| 856 |     if (infoPtr->uNumItem == 0) {
 | 
|---|
| 857 |         infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM));
 | 
|---|
| 858 |         infoPtr->uNumItem++;
 | 
|---|
| 859 |     }
 | 
|---|
| 860 |     else {
 | 
|---|
| 861 |         HEADER_ITEM *oldItems = infoPtr->items;
 | 
|---|
| 862 | 
 | 
|---|
| 863 |         infoPtr->uNumItem++;
 | 
|---|
| 864 |         infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
 | 
|---|
| 865 |         if (nItem == 0) {
 | 
|---|
| 866 |             memcpy (&infoPtr->items[1], &oldItems[0],
 | 
|---|
| 867 |                     (infoPtr->uNumItem-1) * sizeof(HEADER_ITEM));
 | 
|---|
| 868 |         }
 | 
|---|
| 869 |         else
 | 
|---|
| 870 |         {
 | 
|---|
| 871 |               /* pre insert copy */
 | 
|---|
| 872 |             if (nItem > 0) {
 | 
|---|
| 873 |                  memcpy (&infoPtr->items[0], &oldItems[0],
 | 
|---|
| 874 |                          nItem * sizeof(HEADER_ITEM));
 | 
|---|
| 875 |             }
 | 
|---|
| 876 | 
 | 
|---|
| 877 |             /* post insert copy */
 | 
|---|
| 878 |             if (nItem < infoPtr->uNumItem - 1) {
 | 
|---|
| 879 |                 memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
 | 
|---|
| 880 |                         (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM));
 | 
|---|
| 881 |             }
 | 
|---|
| 882 |         }
 | 
|---|
| 883 | 
 | 
|---|
| 884 |         COMCTL32_Free (oldItems);
 | 
|---|
| 885 |     }
 | 
|---|
| 886 | 
 | 
|---|
| 887 |     lpItem = &infoPtr->items[nItem];
 | 
|---|
| 888 |     lpItem->bDown = FALSE;
 | 
|---|
| 889 | 
 | 
|---|
| 890 |     if (phdi->mask & HDI_WIDTH)
 | 
|---|
| 891 |         lpItem->cxy = phdi->cxy;
 | 
|---|
| 892 | 
 | 
|---|
| 893 |     if (phdi->mask & HDI_TEXT) {
 | 
|---|
| 894 |         if (!phdi->pszText) /* null pointer check */
 | 
|---|
| 895 |             phdi->pszText = "";
 | 
|---|
| 896 |         if (phdi->pszText != LPSTR_TEXTCALLBACKA) {
 | 
|---|
| 897 |             len = MultiByteToWideChar(CP_ACP, 0, phdi->pszText, -1, NULL, 0);
 | 
|---|
| 898 |             lpItem->pszText = COMCTL32_Alloc( len*sizeof(WCHAR) );
 | 
|---|
| 899 |             MultiByteToWideChar(CP_ACP, 0, phdi->pszText, -1, lpItem->pszText, len);
 | 
|---|
| 900 |         }
 | 
|---|
| 901 |         else
 | 
|---|
| 902 |             lpItem->pszText = LPSTR_TEXTCALLBACKW;
 | 
|---|
| 903 |     }
 | 
|---|
| 904 | 
 | 
|---|
| 905 |     if (phdi->mask & HDI_FORMAT)
 | 
|---|
| 906 |         lpItem->fmt = phdi->fmt;
 | 
|---|
| 907 | 
 | 
|---|
| 908 |     if (lpItem->fmt == 0)
 | 
|---|
| 909 |         lpItem->fmt = HDF_LEFT;
 | 
|---|
| 910 | 
 | 
|---|
| 911 |     if (!(lpItem->fmt & HDF_STRING) && (phdi->mask & HDI_TEXT))
 | 
|---|
| 912 |       {
 | 
|---|
| 913 |         lpItem->fmt |= HDF_STRING;
 | 
|---|
| 914 |       }
 | 
|---|
| 915 |     if (phdi->mask & HDI_BITMAP)
 | 
|---|
| 916 |         lpItem->hbm = phdi->hbm;
 | 
|---|
| 917 | 
 | 
|---|
| 918 |     if (phdi->mask & HDI_LPARAM)
 | 
|---|
| 919 |         lpItem->lParam = phdi->lParam;
 | 
|---|
| 920 | 
 | 
|---|
| 921 |     if (phdi->mask & HDI_IMAGE)
 | 
|---|
| 922 |         lpItem->iImage = phdi->iImage;
 | 
|---|
| 923 | 
 | 
|---|
| 924 |     if (phdi->mask & HDI_ORDER)
 | 
|---|
| 925 |       {
 | 
|---|
| 926 |         lpItem->iOrder = phdi->iOrder;
 | 
|---|
| 927 |       }
 | 
|---|
| 928 |     else
 | 
|---|
| 929 |       lpItem->iOrder=nItem;
 | 
|---|
| 930 | 
 | 
|---|
| 931 | 
 | 
|---|
| 932 |     HEADER_SetItemBounds (hwnd);
 | 
|---|
| 933 | 
 | 
|---|
| 934 |     InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 935 | 
 | 
|---|
| 936 |     return nItem;
 | 
|---|
| 937 | }
 | 
|---|
| 938 | 
 | 
|---|
| 939 | 
 | 
|---|
| 940 | static LRESULT
 | 
|---|
| 941 | HEADER_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 942 | {
 | 
|---|
| 943 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 944 |     HDITEMW   *phdi = (HDITEMW*)lParam;
 | 
|---|
| 945 |     INT       nItem = (INT)wParam;
 | 
|---|
| 946 |     HEADER_ITEM *lpItem;
 | 
|---|
| 947 |     INT       len;
 | 
|---|
| 948 | 
 | 
|---|
| 949 |     if ((phdi == NULL) || (nItem < 0))
 | 
|---|
| 950 |         return -1;
 | 
|---|
| 951 | 
 | 
|---|
| 952 |     if (nItem > infoPtr->uNumItem)
 | 
|---|
| 953 |         nItem = infoPtr->uNumItem;
 | 
|---|
| 954 | 
 | 
|---|
| 955 |     if (infoPtr->uNumItem == 0) {
 | 
|---|
| 956 |         infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM));
 | 
|---|
| 957 |         infoPtr->uNumItem++;
 | 
|---|
| 958 |     }
 | 
|---|
| 959 |     else {
 | 
|---|
| 960 |         HEADER_ITEM *oldItems = infoPtr->items;
 | 
|---|
| 961 | 
 | 
|---|
| 962 |         infoPtr->uNumItem++;
 | 
|---|
| 963 |         infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
 | 
|---|
| 964 |         if (nItem == 0) {
 | 
|---|
| 965 |             memcpy (&infoPtr->items[1], &oldItems[0],
 | 
|---|
| 966 |                     (infoPtr->uNumItem-1) * sizeof(HEADER_ITEM));
 | 
|---|
| 967 |         }
 | 
|---|
| 968 |         else
 | 
|---|
| 969 |         {
 | 
|---|
| 970 |               /* pre insert copy */
 | 
|---|
| 971 |             if (nItem > 0) {
 | 
|---|
| 972 |                  memcpy (&infoPtr->items[0], &oldItems[0],
 | 
|---|
| 973 |                          nItem * sizeof(HEADER_ITEM));
 | 
|---|
| 974 |             }
 | 
|---|
| 975 | 
 | 
|---|
| 976 |             /* post insert copy */
 | 
|---|
| 977 |             if (nItem < infoPtr->uNumItem - 1) {
 | 
|---|
| 978 |                 memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
 | 
|---|
| 979 |                         (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM));
 | 
|---|
| 980 |             }
 | 
|---|
| 981 |         }
 | 
|---|
| 982 | 
 | 
|---|
| 983 |         COMCTL32_Free (oldItems);
 | 
|---|
| 984 |     }
 | 
|---|
| 985 | 
 | 
|---|
| 986 |     lpItem = &infoPtr->items[nItem];
 | 
|---|
| 987 |     lpItem->bDown = FALSE;
 | 
|---|
| 988 | 
 | 
|---|
| 989 |     if (phdi->mask & HDI_WIDTH)
 | 
|---|
| 990 |         lpItem->cxy = phdi->cxy;
 | 
|---|
| 991 | 
 | 
|---|
| 992 |     if (phdi->mask & HDI_TEXT) {
 | 
|---|
| 993 |         WCHAR wide_null_char = 0;
 | 
|---|
| 994 |         if (!phdi->pszText) /* null pointer check */
 | 
|---|
| 995 |             phdi->pszText = &wide_null_char;
 | 
|---|
| 996 |         if (phdi->pszText != LPSTR_TEXTCALLBACKW) {
 | 
|---|
| 997 |             len = strlenW (phdi->pszText);
 | 
|---|
| 998 |             lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
 | 
|---|
| 999 |             strcpyW (lpItem->pszText, phdi->pszText);
 | 
|---|
| 1000 |         }
 | 
|---|
| 1001 |         else
 | 
|---|
| 1002 |             lpItem->pszText = LPSTR_TEXTCALLBACKW;
 | 
|---|
| 1003 |     }
 | 
|---|
| 1004 | 
 | 
|---|
| 1005 |     if (phdi->mask & HDI_FORMAT)
 | 
|---|
| 1006 |         lpItem->fmt = phdi->fmt;
 | 
|---|
| 1007 | 
 | 
|---|
| 1008 |     if (lpItem->fmt == 0)
 | 
|---|
| 1009 |         lpItem->fmt = HDF_LEFT;
 | 
|---|
| 1010 | 
 | 
|---|
| 1011 |     if (!(lpItem->fmt &HDF_STRING) && (phdi->mask & HDI_TEXT))
 | 
|---|
| 1012 |       {
 | 
|---|
| 1013 |         lpItem->fmt |= HDF_STRING;
 | 
|---|
| 1014 |       }
 | 
|---|
| 1015 |     if (phdi->mask & HDI_BITMAP)
 | 
|---|
| 1016 |         lpItem->hbm = phdi->hbm;
 | 
|---|
| 1017 | 
 | 
|---|
| 1018 |     if (phdi->mask & HDI_LPARAM)
 | 
|---|
| 1019 |         lpItem->lParam = phdi->lParam;
 | 
|---|
| 1020 | 
 | 
|---|
| 1021 |     if (phdi->mask & HDI_IMAGE)
 | 
|---|
| 1022 |         lpItem->iImage = phdi->iImage;
 | 
|---|
| 1023 | 
 | 
|---|
| 1024 |     if (phdi->mask & HDI_ORDER)
 | 
|---|
| 1025 |       {
 | 
|---|
| 1026 |         lpItem->iOrder = phdi->iOrder;
 | 
|---|
| 1027 |       }
 | 
|---|
| 1028 |     else
 | 
|---|
| 1029 |       lpItem->iOrder = nItem;
 | 
|---|
| 1030 | 
 | 
|---|
| 1031 |     HEADER_SetItemBounds (hwnd);
 | 
|---|
| 1032 | 
 | 
|---|
| 1033 |     InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 1034 | 
 | 
|---|
| 1035 |     return nItem;
 | 
|---|
| 1036 | }
 | 
|---|
| 1037 | 
 | 
|---|
| 1038 | 
 | 
|---|
| 1039 | static LRESULT
 | 
|---|
| 1040 | HEADER_Layout (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1041 | {
 | 
|---|
| 1042 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1043 |     LPHDLAYOUT lpLayout = (LPHDLAYOUT)lParam;
 | 
|---|
| 1044 | 
 | 
|---|
| 1045 |     lpLayout->pwpos->hwnd = hwnd;
 | 
|---|
| 1046 |     lpLayout->pwpos->hwndInsertAfter = 0;
 | 
|---|
| 1047 |     lpLayout->pwpos->x = lpLayout->prc->left;
 | 
|---|
| 1048 |     lpLayout->pwpos->y = lpLayout->prc->top;
 | 
|---|
| 1049 |     lpLayout->pwpos->cx = lpLayout->prc->right - lpLayout->prc->left;
 | 
|---|
| 1050 |     if (GetWindowLongA (hwnd, GWL_STYLE) & HDS_HIDDEN)
 | 
|---|
| 1051 |         lpLayout->pwpos->cy = 0;
 | 
|---|
| 1052 |     else {
 | 
|---|
| 1053 |         lpLayout->pwpos->cy = infoPtr->nHeight;
 | 
|---|
| 1054 |         lpLayout->prc->top += infoPtr->nHeight;
 | 
|---|
| 1055 |     }
 | 
|---|
| 1056 |     lpLayout->pwpos->flags = SWP_NOZORDER;
 | 
|---|
| 1057 | 
 | 
|---|
| 1058 |     TRACE("Layout x=%d y=%d cx=%d cy=%d\n",
 | 
|---|
| 1059 |            lpLayout->pwpos->x, lpLayout->pwpos->y,
 | 
|---|
| 1060 |            lpLayout->pwpos->cx, lpLayout->pwpos->cy);
 | 
|---|
| 1061 | 
 | 
|---|
| 1062 |     infoPtr->bRectsValid = FALSE;
 | 
|---|
| 1063 | 
 | 
|---|
| 1064 |     return TRUE;
 | 
|---|
| 1065 | }
 | 
|---|
| 1066 | 
 | 
|---|
| 1067 | 
 | 
|---|
| 1068 | static LRESULT
 | 
|---|
| 1069 | HEADER_SetImageList (HWND hwnd, HIMAGELIST himl)
 | 
|---|
| 1070 | {
 | 
|---|
| 1071 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1072 |     HIMAGELIST himlOld;
 | 
|---|
| 1073 | 
 | 
|---|
| 1074 |     TRACE("(himl 0x%x)\n", (int)himl);
 | 
|---|
| 1075 |     himlOld = infoPtr->himl;
 | 
|---|
| 1076 |     infoPtr->himl = himl;
 | 
|---|
| 1077 | 
 | 
|---|
| 1078 |     /* FIXME: Refresh needed??? */
 | 
|---|
| 1079 | 
 | 
|---|
| 1080 |     return (LRESULT)himlOld;
 | 
|---|
| 1081 | }
 | 
|---|
| 1082 | 
 | 
|---|
| 1083 | 
 | 
|---|
| 1084 | static LRESULT
 | 
|---|
| 1085 | HEADER_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1086 | {
 | 
|---|
| 1087 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1088 |     HDITEMA *phdi = (HDITEMA*)lParam;
 | 
|---|
| 1089 |     INT nItem = (INT)wParam;
 | 
|---|
| 1090 |     HEADER_ITEM *lpItem;
 | 
|---|
| 1091 | 
 | 
|---|
| 1092 |     if (phdi == NULL)
 | 
|---|
| 1093 |         return FALSE;
 | 
|---|
| 1094 |     if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
 | 
|---|
| 1095 |         return FALSE;
 | 
|---|
| 1096 | 
 | 
|---|
| 1097 |     TRACE("[nItem=%d]\n", nItem);
 | 
|---|
| 1098 | 
 | 
|---|
| 1099 |         if (HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGINGA, nItem, phdi->mask))
 | 
|---|
| 1100 |         return FALSE;
 | 
|---|
| 1101 | 
 | 
|---|
| 1102 |     lpItem = &infoPtr->items[nItem];
 | 
|---|
| 1103 |     if (phdi->mask & HDI_BITMAP)
 | 
|---|
| 1104 |         lpItem->hbm = phdi->hbm;
 | 
|---|
| 1105 | 
 | 
|---|
| 1106 |     if (phdi->mask & HDI_FORMAT)
 | 
|---|
| 1107 |         lpItem->fmt = phdi->fmt;
 | 
|---|
| 1108 | 
 | 
|---|
| 1109 |     if (phdi->mask & HDI_LPARAM)
 | 
|---|
| 1110 |         lpItem->lParam = phdi->lParam;
 | 
|---|
| 1111 | 
 | 
|---|
| 1112 |     if (phdi->mask & HDI_TEXT) {
 | 
|---|
| 1113 |         if (phdi->pszText != LPSTR_TEXTCALLBACKA) {
 | 
|---|
| 1114 |             if (lpItem->pszText) {
 | 
|---|
| 1115 |                 COMCTL32_Free (lpItem->pszText);
 | 
|---|
| 1116 |                 lpItem->pszText = NULL;
 | 
|---|
| 1117 |             }
 | 
|---|
| 1118 |             if (phdi->pszText) {
 | 
|---|
| 1119 |                 INT len = MultiByteToWideChar (CP_ACP,0,phdi->pszText,-1,NULL,0);
 | 
|---|
| 1120 |                 lpItem->pszText = COMCTL32_Alloc( len*sizeof(WCHAR) );
 | 
|---|
| 1121 |                 MultiByteToWideChar (CP_ACP,0,phdi->pszText,-1,lpItem->pszText,len);
 | 
|---|
| 1122 |             }
 | 
|---|
| 1123 |         }
 | 
|---|
| 1124 |         else
 | 
|---|
| 1125 |             lpItem->pszText = LPSTR_TEXTCALLBACKW;
 | 
|---|
| 1126 |     }
 | 
|---|
| 1127 | 
 | 
|---|
| 1128 |     if (phdi->mask & HDI_WIDTH)
 | 
|---|
| 1129 |         lpItem->cxy = phdi->cxy;
 | 
|---|
| 1130 | 
 | 
|---|
| 1131 |     if (phdi->mask & HDI_IMAGE)
 | 
|---|
| 1132 |         lpItem->iImage = phdi->iImage;
 | 
|---|
| 1133 | 
 | 
|---|
| 1134 |     if (phdi->mask & HDI_ORDER)
 | 
|---|
| 1135 |       {
 | 
|---|
| 1136 |         lpItem->iOrder = phdi->iOrder;
 | 
|---|
| 1137 |       }
 | 
|---|
| 1138 |     else
 | 
|---|
| 1139 |       lpItem->iOrder = nItem;
 | 
|---|
| 1140 | 
 | 
|---|
| 1141 |         HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGEDA, nItem, phdi->mask);
 | 
|---|
| 1142 | 
 | 
|---|
| 1143 |     HEADER_SetItemBounds (hwnd);
 | 
|---|
| 1144 | 
 | 
|---|
| 1145 |     InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 1146 | 
 | 
|---|
| 1147 |     return TRUE;
 | 
|---|
| 1148 | }
 | 
|---|
| 1149 | 
 | 
|---|
| 1150 | 
 | 
|---|
| 1151 | static LRESULT
 | 
|---|
| 1152 | HEADER_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1153 | {
 | 
|---|
| 1154 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1155 |     HDITEMW *phdi = (HDITEMW*)lParam;
 | 
|---|
| 1156 |     INT nItem = (INT)wParam;
 | 
|---|
| 1157 |     HEADER_ITEM *lpItem;
 | 
|---|
| 1158 | 
 | 
|---|
| 1159 |     if (phdi == NULL)
 | 
|---|
| 1160 |         return FALSE;
 | 
|---|
| 1161 |     if ((nItem < 0) || (nItem >= (INT)infoPtr->uNumItem))
 | 
|---|
| 1162 |         return FALSE;
 | 
|---|
| 1163 | 
 | 
|---|
| 1164 |     TRACE("[nItem=%d]\n", nItem);
 | 
|---|
| 1165 | 
 | 
|---|
| 1166 |         if (HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGINGW, nItem, phdi->mask))
 | 
|---|
| 1167 |         return FALSE;
 | 
|---|
| 1168 | 
 | 
|---|
| 1169 |     lpItem = &infoPtr->items[nItem];
 | 
|---|
| 1170 |     if (phdi->mask & HDI_BITMAP)
 | 
|---|
| 1171 |         lpItem->hbm = phdi->hbm;
 | 
|---|
| 1172 | 
 | 
|---|
| 1173 |     if (phdi->mask & HDI_FORMAT)
 | 
|---|
| 1174 |         lpItem->fmt = phdi->fmt;
 | 
|---|
| 1175 | 
 | 
|---|
| 1176 |     if (phdi->mask & HDI_LPARAM)
 | 
|---|
| 1177 |         lpItem->lParam = phdi->lParam;
 | 
|---|
| 1178 | 
 | 
|---|
| 1179 |     if (phdi->mask & HDI_TEXT) {
 | 
|---|
| 1180 |         if (phdi->pszText != LPSTR_TEXTCALLBACKW) {
 | 
|---|
| 1181 |             if (lpItem->pszText) {
 | 
|---|
| 1182 |                 COMCTL32_Free (lpItem->pszText);
 | 
|---|
| 1183 |                 lpItem->pszText = NULL;
 | 
|---|
| 1184 |             }
 | 
|---|
| 1185 |             if (phdi->pszText) {
 | 
|---|
| 1186 |                 INT len = strlenW (phdi->pszText);
 | 
|---|
| 1187 |                 lpItem->pszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
 | 
|---|
| 1188 |                 strcpyW (lpItem->pszText, phdi->pszText);
 | 
|---|
| 1189 |             }
 | 
|---|
| 1190 |         }
 | 
|---|
| 1191 |         else
 | 
|---|
| 1192 |             lpItem->pszText = LPSTR_TEXTCALLBACKW;
 | 
|---|
| 1193 |     }
 | 
|---|
| 1194 | 
 | 
|---|
| 1195 |     if (phdi->mask & HDI_WIDTH)
 | 
|---|
| 1196 |         lpItem->cxy = phdi->cxy;
 | 
|---|
| 1197 | 
 | 
|---|
| 1198 |     if (phdi->mask & HDI_IMAGE)
 | 
|---|
| 1199 |         lpItem->iImage = phdi->iImage;
 | 
|---|
| 1200 | 
 | 
|---|
| 1201 |     if (phdi->mask & HDI_ORDER)
 | 
|---|
| 1202 |       {
 | 
|---|
| 1203 |         lpItem->iOrder = phdi->iOrder;
 | 
|---|
| 1204 |       }
 | 
|---|
| 1205 |     else
 | 
|---|
| 1206 |       lpItem->iOrder = nItem;
 | 
|---|
| 1207 | 
 | 
|---|
| 1208 |         HEADER_SendHeaderNotify(hwnd, HDN_ITEMCHANGEDW, nItem, phdi->mask);
 | 
|---|
| 1209 | 
 | 
|---|
| 1210 |     HEADER_SetItemBounds (hwnd);
 | 
|---|
| 1211 | 
 | 
|---|
| 1212 |     InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 1213 | 
 | 
|---|
| 1214 |     return TRUE;
 | 
|---|
| 1215 | }
 | 
|---|
| 1216 | 
 | 
|---|
| 1217 | inline static LRESULT
 | 
|---|
| 1218 | HEADER_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
 | 
|---|
| 1219 | {
 | 
|---|
| 1220 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1221 |     BOOL bTemp = infoPtr->bUnicode;
 | 
|---|
| 1222 | 
 | 
|---|
| 1223 |     infoPtr->bUnicode = (BOOL)wParam;
 | 
|---|
| 1224 | 
 | 
|---|
| 1225 |     return bTemp;
 | 
|---|
| 1226 | }
 | 
|---|
| 1227 | 
 | 
|---|
| 1228 | 
 | 
|---|
| 1229 | static LRESULT
 | 
|---|
| 1230 | HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1231 | {
 | 
|---|
| 1232 |     HEADER_INFO *infoPtr;
 | 
|---|
| 1233 |     TEXTMETRICA tm;
 | 
|---|
| 1234 |     HFONT hOldFont;
 | 
|---|
| 1235 |     HDC   hdc;
 | 
|---|
| 1236 | 
 | 
|---|
| 1237 |     infoPtr = (HEADER_INFO *)COMCTL32_Alloc (sizeof(HEADER_INFO));
 | 
|---|
| 1238 |     SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
 | 
|---|
| 1239 | 
 | 
|---|
| 1240 |     infoPtr->hwndNotify = GetParent(hwnd);
 | 
|---|
| 1241 |     infoPtr->uNumItem = 0;
 | 
|---|
| 1242 |     infoPtr->hFont = 0;
 | 
|---|
| 1243 |     infoPtr->items = 0;
 | 
|---|
| 1244 |     infoPtr->bRectsValid = FALSE;
 | 
|---|
| 1245 |     infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
 | 
|---|
| 1246 |     infoPtr->hcurDivider = LoadCursorA (COMCTL32_hModule, MAKEINTRESOURCEA(IDC_DIVIDER));
 | 
|---|
| 1247 |     infoPtr->hcurDivopen = LoadCursorA (COMCTL32_hModule, MAKEINTRESOURCEA(IDC_DIVIDEROPEN));
 | 
|---|
| 1248 |     infoPtr->bPressed  = FALSE;
 | 
|---|
| 1249 |     infoPtr->bTracking = FALSE;
 | 
|---|
| 1250 |     infoPtr->iMoveItem = 0;
 | 
|---|
| 1251 |     infoPtr->himl = 0;
 | 
|---|
| 1252 |     infoPtr->iHotItem = -1;
 | 
|---|
| 1253 |     infoPtr->bUnicode = IsWindowUnicode (hwnd);
 | 
|---|
| 1254 |     infoPtr->nNotifyFormat =
 | 
|---|
| 1255 |         SendMessageA (infoPtr->hwndNotify, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
 | 
|---|
| 1256 | 
 | 
|---|
| 1257 |     hdc = GetDC (0);
 | 
|---|
| 1258 |     hOldFont = SelectObject (hdc, GetStockObject (SYSTEM_FONT));
 | 
|---|
| 1259 |     GetTextMetricsA (hdc, &tm);
 | 
|---|
| 1260 |     infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
 | 
|---|
| 1261 |     SelectObject (hdc, hOldFont);
 | 
|---|
| 1262 |     ReleaseDC (0, hdc);
 | 
|---|
| 1263 | 
 | 
|---|
| 1264 |     return 0;
 | 
|---|
| 1265 | }
 | 
|---|
| 1266 | 
 | 
|---|
| 1267 | 
 | 
|---|
| 1268 | static LRESULT
 | 
|---|
| 1269 | HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1270 | {
 | 
|---|
| 1271 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1272 |     HEADER_ITEM *lpItem;
 | 
|---|
| 1273 |     INT nItem;
 | 
|---|
| 1274 | 
 | 
|---|
| 1275 |     if (infoPtr->items) {
 | 
|---|
| 1276 |         lpItem = infoPtr->items;
 | 
|---|
| 1277 |         for (nItem = 0; nItem < infoPtr->uNumItem; nItem++, lpItem++) {
 | 
|---|
| 1278 |             if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACKW))
 | 
|---|
| 1279 |                 COMCTL32_Free (lpItem->pszText);
 | 
|---|
| 1280 |         }
 | 
|---|
| 1281 |         COMCTL32_Free (infoPtr->items);
 | 
|---|
| 1282 |     }
 | 
|---|
| 1283 | 
 | 
|---|
| 1284 |     if (infoPtr->himl)
 | 
|---|
| 1285 |         ImageList_Destroy (infoPtr->himl);
 | 
|---|
| 1286 | 
 | 
|---|
| 1287 |     COMCTL32_Free (infoPtr);
 | 
|---|
| 1288 |     SetWindowLongA (hwnd, 0, 0);
 | 
|---|
| 1289 |     return 0;
 | 
|---|
| 1290 | }
 | 
|---|
| 1291 | 
 | 
|---|
| 1292 | 
 | 
|---|
| 1293 | static inline LRESULT
 | 
|---|
| 1294 | HEADER_GetFont (HWND hwnd)
 | 
|---|
| 1295 | {
 | 
|---|
| 1296 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1297 | 
 | 
|---|
| 1298 |     return (LRESULT)infoPtr->hFont;
 | 
|---|
| 1299 | }
 | 
|---|
| 1300 | 
 | 
|---|
| 1301 | 
 | 
|---|
| 1302 | static LRESULT
 | 
|---|
| 1303 | HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1304 | {
 | 
|---|
| 1305 |     POINT pt;
 | 
|---|
| 1306 |     UINT  flags;
 | 
|---|
| 1307 |     INT   nItem;
 | 
|---|
| 1308 | 
 | 
|---|
| 1309 |     pt.x = (INT)LOWORD(lParam);
 | 
|---|
| 1310 |     pt.y = (INT)HIWORD(lParam);
 | 
|---|
| 1311 |     HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
 | 
|---|
| 1312 | 
 | 
|---|
| 1313 |     if ((GetWindowLongA (hwnd, GWL_STYLE) & HDS_BUTTONS) && (flags == HHT_ONHEADER))
 | 
|---|
| 1314 |         HEADER_SendHeaderNotify (hwnd, HDN_ITEMDBLCLICKA, nItem,0);
 | 
|---|
| 1315 |     else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
 | 
|---|
| 1316 |         HEADER_SendHeaderNotify (hwnd, HDN_DIVIDERDBLCLICKA, nItem,0);
 | 
|---|
| 1317 | 
 | 
|---|
| 1318 |     return 0;
 | 
|---|
| 1319 | }
 | 
|---|
| 1320 | 
 | 
|---|
| 1321 | 
 | 
|---|
| 1322 | static LRESULT
 | 
|---|
| 1323 | HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1324 | {
 | 
|---|
| 1325 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1326 |     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
 | 
|---|
| 1327 |     POINT pt;
 | 
|---|
| 1328 |     UINT  flags;
 | 
|---|
| 1329 |     INT   nItem;
 | 
|---|
| 1330 |     HDC   hdc;
 | 
|---|
| 1331 | 
 | 
|---|
| 1332 |     pt.x = (INT)LOWORD(lParam);
 | 
|---|
| 1333 |     pt.y = (INT)HIWORD(lParam);
 | 
|---|
| 1334 |     HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
 | 
|---|
| 1335 | 
 | 
|---|
| 1336 |     if ((dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) {
 | 
|---|
| 1337 |         SetCapture (hwnd);
 | 
|---|
| 1338 |         infoPtr->bCaptured = TRUE;
 | 
|---|
| 1339 |         infoPtr->bPressed  = TRUE;
 | 
|---|
| 1340 |         infoPtr->iMoveItem = nItem;
 | 
|---|
| 1341 | 
 | 
|---|
| 1342 |         infoPtr->items[nItem].bDown = TRUE;
 | 
|---|
| 1343 | 
 | 
|---|
| 1344 |         /* Send WM_CUSTOMDRAW */
 | 
|---|
| 1345 |         hdc = GetDC (hwnd);
 | 
|---|
| 1346 |         HEADER_RefreshItem (hwnd, hdc, nItem);
 | 
|---|
| 1347 |         ReleaseDC (hwnd, hdc);
 | 
|---|
| 1348 | 
 | 
|---|
| 1349 |         TRACE("Pressed item %d!\n", nItem);
 | 
|---|
| 1350 |     }
 | 
|---|
| 1351 |     else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) {
 | 
|---|
| 1352 |         if (!(HEADER_SendHeaderNotify (hwnd, HDN_BEGINTRACKA, nItem,0))) {
 | 
|---|
| 1353 |             SetCapture (hwnd);
 | 
|---|
| 1354 |             infoPtr->bCaptured = TRUE;
 | 
|---|
| 1355 |             infoPtr->bTracking = TRUE;
 | 
|---|
| 1356 |             infoPtr->iMoveItem = nItem;
 | 
|---|
| 1357 |             infoPtr->nOldWidth = infoPtr->items[nItem].cxy;
 | 
|---|
| 1358 |             infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x;
 | 
|---|
| 1359 | 
 | 
|---|
| 1360 |             if (!(dwStyle & HDS_FULLDRAG)) {
 | 
|---|
| 1361 |                 infoPtr->xOldTrack = infoPtr->items[nItem].rect.right;
 | 
|---|
| 1362 |                 hdc = GetDC (hwnd);
 | 
|---|
| 1363 |                 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
 | 
|---|
| 1364 |                 ReleaseDC (hwnd, hdc);
 | 
|---|
| 1365 |             }
 | 
|---|
| 1366 | 
 | 
|---|
| 1367 |             TRACE("Begin tracking item %d!\n", nItem);
 | 
|---|
| 1368 |         }
 | 
|---|
| 1369 |     }
 | 
|---|
| 1370 | 
 | 
|---|
| 1371 |     return 0;
 | 
|---|
| 1372 | }
 | 
|---|
| 1373 | 
 | 
|---|
| 1374 | 
 | 
|---|
| 1375 | static LRESULT
 | 
|---|
| 1376 | HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1377 | {
 | 
|---|
| 1378 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1379 |     /*
 | 
|---|
| 1380 |      *DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
 | 
|---|
| 1381 |      */
 | 
|---|
| 1382 |     POINT pt;
 | 
|---|
| 1383 |     UINT  flags;
 | 
|---|
| 1384 |     INT   nItem, nWidth;
 | 
|---|
| 1385 |     HDC   hdc;
 | 
|---|
| 1386 | 
 | 
|---|
| 1387 |     pt.x = (INT)SLOWORD(lParam);
 | 
|---|
| 1388 |     pt.y = (INT)SHIWORD(lParam);
 | 
|---|
| 1389 |     HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
 | 
|---|
| 1390 | 
 | 
|---|
| 1391 |     if (infoPtr->bPressed) {
 | 
|---|
| 1392 |         if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) {
 | 
|---|
| 1393 |             infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
 | 
|---|
| 1394 |             hdc = GetDC (hwnd);
 | 
|---|
| 1395 |             HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem);
 | 
|---|
| 1396 |             ReleaseDC (hwnd, hdc);
 | 
|---|
| 1397 | 
 | 
|---|
| 1398 |             HEADER_SendClickNotify (hwnd, HDN_ITEMCLICKA, infoPtr->iMoveItem);
 | 
|---|
| 1399 |         }
 | 
|---|
| 1400 |         else if (flags == HHT_ONHEADER)
 | 
|---|
| 1401 |           {
 | 
|---|
| 1402 |             HEADER_ITEM *lpItem;
 | 
|---|
| 1403 |             INT newindex = HEADER_IndexToOrder(hwnd,nItem);
 | 
|---|
| 1404 |             INT oldindex = HEADER_IndexToOrder(hwnd,infoPtr->iMoveItem);
 | 
|---|
| 1405 | 
 | 
|---|
| 1406 |             TRACE("Exchanging [index:order] [%d:%d] [%d:%d]\n",
 | 
|---|
| 1407 |                   infoPtr->iMoveItem,oldindex,nItem,newindex);
 | 
|---|
| 1408 |             lpItem= &infoPtr->items[nItem];
 | 
|---|
| 1409 |             lpItem->iOrder=oldindex;
 | 
|---|
| 1410 | 
 | 
|---|
| 1411 |             lpItem= &infoPtr->items[infoPtr->iMoveItem];
 | 
|---|
| 1412 |             lpItem->iOrder = newindex;
 | 
|---|
| 1413 | 
 | 
|---|
| 1414 |             infoPtr->bRectsValid = FALSE;
 | 
|---|
| 1415 |             InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 1416 |             /* FIXME: Should some WM_NOTIFY be sent */
 | 
|---|
| 1417 |           }
 | 
|---|
| 1418 | 
 | 
|---|
| 1419 |         TRACE("Released item %d!\n", infoPtr->iMoveItem);
 | 
|---|
| 1420 |         infoPtr->bPressed = FALSE;
 | 
|---|
| 1421 |     }
 | 
|---|
| 1422 |     else if (infoPtr->bTracking) {
 | 
|---|
| 1423 |         TRACE("End tracking item %d!\n", infoPtr->iMoveItem);
 | 
|---|
| 1424 |         infoPtr->bTracking = FALSE;
 | 
|---|
| 1425 | 
 | 
|---|
| 1426 |         HEADER_SendHeaderNotify (hwnd, HDN_ENDTRACKA, infoPtr->iMoveItem,HDI_WIDTH);
 | 
|---|
| 1427 | 
 | 
|---|
| 1428 |          /*
 | 
|---|
| 1429 |           * we want to do this even for HDS_FULLDRAG because this is where
 | 
|---|
| 1430 |           * we send the HDN_ITEMCHANGING and HDN_ITEMCHANGED notifications
 | 
|---|
| 1431 |           *
 | 
|---|
| 1432 |           * if (!(dwStyle & HDS_FULLDRAG)) {
 | 
|---|
| 1433 |           */
 | 
|---|
| 1434 | 
 | 
|---|
| 1435 |             hdc = GetDC (hwnd);
 | 
|---|
| 1436 |             HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
 | 
|---|
| 1437 |             ReleaseDC (hwnd, hdc);
 | 
|---|
| 1438 |                         if (HEADER_SendHeaderNotify(hwnd, HDN_ITEMCHANGINGA, infoPtr->iMoveItem, HDI_WIDTH))
 | 
|---|
| 1439 |             {
 | 
|---|
| 1440 |                 infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
 | 
|---|
| 1441 |             }
 | 
|---|
| 1442 |             else {
 | 
|---|
| 1443 |                 nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
 | 
|---|
| 1444 |                 if (nWidth < 0)
 | 
|---|
| 1445 |                     nWidth = 0;
 | 
|---|
| 1446 |                 infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
 | 
|---|
| 1447 |             }
 | 
|---|
| 1448 | 
 | 
|---|
| 1449 |                         HEADER_SendHeaderNotify(hwnd, HDN_ITEMCHANGINGA, infoPtr->iMoveItem, HDI_WIDTH);
 | 
|---|
| 1450 |             HEADER_SetItemBounds (hwnd);
 | 
|---|
| 1451 |             InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 1452 |        /*
 | 
|---|
| 1453 |         * }
 | 
|---|
| 1454 |         */
 | 
|---|
| 1455 |     }
 | 
|---|
| 1456 | 
 | 
|---|
| 1457 |     if (infoPtr->bCaptured) {
 | 
|---|
| 1458 |         infoPtr->bCaptured = FALSE;
 | 
|---|
| 1459 |         ReleaseCapture ();
 | 
|---|
| 1460 |         HEADER_SendSimpleNotify (hwnd, NM_RELEASEDCAPTURE);
 | 
|---|
| 1461 |     }
 | 
|---|
| 1462 | 
 | 
|---|
| 1463 |     return 0;
 | 
|---|
| 1464 | }
 | 
|---|
| 1465 | 
 | 
|---|
| 1466 | 
 | 
|---|
| 1467 | static LRESULT
 | 
|---|
| 1468 | HEADER_NotifyFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1469 | {
 | 
|---|
| 1470 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1471 | 
 | 
|---|
| 1472 |     switch (lParam)
 | 
|---|
| 1473 |     {
 | 
|---|
| 1474 |         case NF_QUERY:
 | 
|---|
| 1475 |             return infoPtr->nNotifyFormat;
 | 
|---|
| 1476 | 
 | 
|---|
| 1477 |         case NF_REQUERY:
 | 
|---|
| 1478 |             infoPtr->nNotifyFormat =
 | 
|---|
| 1479 |                 SendMessageA ((HWND)wParam, WM_NOTIFYFORMAT,
 | 
|---|
| 1480 |                               (WPARAM)hwnd, (LPARAM)NF_QUERY);
 | 
|---|
| 1481 |             return infoPtr->nNotifyFormat;
 | 
|---|
| 1482 |     }
 | 
|---|
| 1483 | 
 | 
|---|
| 1484 |     return 0;
 | 
|---|
| 1485 | }
 | 
|---|
| 1486 | 
 | 
|---|
| 1487 | 
 | 
|---|
| 1488 | static LRESULT
 | 
|---|
| 1489 | HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1490 | {
 | 
|---|
| 1491 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1492 |     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
 | 
|---|
| 1493 |     POINT pt;
 | 
|---|
| 1494 |     UINT  flags;
 | 
|---|
| 1495 |     INT   nItem, nWidth;
 | 
|---|
| 1496 |     HDC   hdc;
 | 
|---|
| 1497 | 
 | 
|---|
| 1498 |     pt.x = (INT)SLOWORD(lParam);
 | 
|---|
| 1499 |     pt.y = (INT)SHIWORD(lParam);
 | 
|---|
| 1500 |     HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
 | 
|---|
| 1501 | 
 | 
|---|
| 1502 |     if ((dwStyle & HDS_BUTTONS) && (dwStyle & HDS_HOTTRACK)) {
 | 
|---|
| 1503 |         if (flags & (HHT_ONHEADER | HHT_ONDIVIDER | HHT_ONDIVOPEN))
 | 
|---|
| 1504 |             infoPtr->iHotItem = nItem;
 | 
|---|
| 1505 |         else
 | 
|---|
| 1506 |             infoPtr->iHotItem = -1;
 | 
|---|
| 1507 |         InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 1508 |     }
 | 
|---|
| 1509 | 
 | 
|---|
| 1510 |     if (infoPtr->bCaptured) {
 | 
|---|
| 1511 |         if (infoPtr->bPressed) {
 | 
|---|
| 1512 |             if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER))
 | 
|---|
| 1513 |                 infoPtr->items[infoPtr->iMoveItem].bDown = TRUE;
 | 
|---|
| 1514 |             else
 | 
|---|
| 1515 |                 infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
 | 
|---|
| 1516 |             hdc = GetDC (hwnd);
 | 
|---|
| 1517 |             HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem);
 | 
|---|
| 1518 |             ReleaseDC (hwnd, hdc);
 | 
|---|
| 1519 | 
 | 
|---|
| 1520 |             TRACE("Moving pressed item %d!\n", infoPtr->iMoveItem);
 | 
|---|
| 1521 |         }
 | 
|---|
| 1522 |         else if (infoPtr->bTracking) {
 | 
|---|
| 1523 |             if (dwStyle & HDS_FULLDRAG) {
 | 
|---|
| 1524 |                 if (HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGINGA, infoPtr->iMoveItem, HDI_WIDTH))
 | 
|---|
| 1525 |                 {
 | 
|---|
| 1526 |                 nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
 | 
|---|
| 1527 |                 if (nWidth < 0)
 | 
|---|
| 1528 |                   nWidth = 0;
 | 
|---|
| 1529 |                 infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
 | 
|---|
| 1530 |                         HEADER_SendHeaderNotify(hwnd, HDN_ITEMCHANGEDA, infoPtr->iMoveItem, HDI_WIDTH);
 | 
|---|
| 1531 |                 }
 | 
|---|
| 1532 |                 HEADER_SetItemBounds (hwnd);
 | 
|---|
| 1533 |                 InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 1534 |             }
 | 
|---|
| 1535 |             else {
 | 
|---|
| 1536 |                 hdc = GetDC (hwnd);
 | 
|---|
| 1537 |                 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
 | 
|---|
| 1538 |                 infoPtr->xOldTrack = pt.x + infoPtr->xTrackOffset;
 | 
|---|
| 1539 |                 if (infoPtr->xOldTrack < infoPtr->items[infoPtr->iMoveItem].rect.left)
 | 
|---|
| 1540 |                     infoPtr->xOldTrack = infoPtr->items[infoPtr->iMoveItem].rect.left;
 | 
|---|
| 1541 |                 infoPtr->items[infoPtr->iMoveItem].cxy =
 | 
|---|
| 1542 |                     infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left;
 | 
|---|
| 1543 |                 HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack);
 | 
|---|
| 1544 |                 ReleaseDC (hwnd, hdc);
 | 
|---|
| 1545 |             HEADER_SendHeaderNotify (hwnd, HDN_TRACKA, infoPtr->iMoveItem, HDI_WIDTH);
 | 
|---|
| 1546 |             }
 | 
|---|
| 1547 | 
 | 
|---|
| 1548 |             TRACE("Tracking item %d!\n", infoPtr->iMoveItem);
 | 
|---|
| 1549 |         }
 | 
|---|
| 1550 |     }
 | 
|---|
| 1551 | 
 | 
|---|
| 1552 |     if ((dwStyle & HDS_BUTTONS) && (dwStyle & HDS_HOTTRACK)) {
 | 
|---|
| 1553 |         FIXME("hot track support!\n");
 | 
|---|
| 1554 |     }
 | 
|---|
| 1555 | 
 | 
|---|
| 1556 |     return 0;
 | 
|---|
| 1557 | }
 | 
|---|
| 1558 | 
 | 
|---|
| 1559 | 
 | 
|---|
| 1560 | static LRESULT
 | 
|---|
| 1561 | HEADER_Paint (HWND hwnd, WPARAM wParam)
 | 
|---|
| 1562 | {
 | 
|---|
| 1563 |     HDC hdc;
 | 
|---|
| 1564 |     PAINTSTRUCT ps;
 | 
|---|
| 1565 | 
 | 
|---|
| 1566 |     hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
 | 
|---|
| 1567 |     HEADER_Refresh (hwnd, hdc);
 | 
|---|
| 1568 |     if(!wParam)
 | 
|---|
| 1569 |         EndPaint (hwnd, &ps);
 | 
|---|
| 1570 |     return 0;
 | 
|---|
| 1571 | }
 | 
|---|
| 1572 | 
 | 
|---|
| 1573 | 
 | 
|---|
| 1574 | static LRESULT
 | 
|---|
| 1575 | HEADER_RButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1576 | {
 | 
|---|
| 1577 |     BOOL bRet;
 | 
|---|
| 1578 |     POINT pt;
 | 
|---|
| 1579 | 
 | 
|---|
| 1580 |     pt.x = LOWORD(lParam);
 | 
|---|
| 1581 |     pt.y = HIWORD(lParam);
 | 
|---|
| 1582 | 
 | 
|---|
| 1583 |     /* Send a Notify message */
 | 
|---|
| 1584 |     bRet = HEADER_SendSimpleNotify (hwnd, NM_RCLICK);
 | 
|---|
| 1585 | 
 | 
|---|
| 1586 |     /* Change to screen coordinate for WM_CONTEXTMENU */
 | 
|---|
| 1587 |     ClientToScreen(hwnd, &pt);
 | 
|---|
| 1588 | 
 | 
|---|
| 1589 |     /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */
 | 
|---|
| 1590 |     SendMessageA( hwnd, WM_CONTEXTMENU, (WPARAM) hwnd, MAKELPARAM(pt.x, pt.y));
 | 
|---|
| 1591 | 
 | 
|---|
| 1592 |     return bRet;
 | 
|---|
| 1593 | }
 | 
|---|
| 1594 | 
 | 
|---|
| 1595 | 
 | 
|---|
| 1596 | static LRESULT
 | 
|---|
| 1597 | HEADER_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1598 | {
 | 
|---|
| 1599 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1600 |     POINT pt;
 | 
|---|
| 1601 |     UINT  flags;
 | 
|---|
| 1602 |     INT   nItem;
 | 
|---|
| 1603 | 
 | 
|---|
| 1604 |     TRACE("code=0x%X  id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
 | 
|---|
| 1605 | 
 | 
|---|
| 1606 |     GetCursorPos (&pt);
 | 
|---|
| 1607 |     ScreenToClient (hwnd, &pt);
 | 
|---|
| 1608 | 
 | 
|---|
| 1609 |     HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem);
 | 
|---|
| 1610 | 
 | 
|---|
| 1611 |     if (flags == HHT_ONDIVIDER)
 | 
|---|
| 1612 |         SetCursor (infoPtr->hcurDivider);
 | 
|---|
| 1613 |     else if (flags == HHT_ONDIVOPEN)
 | 
|---|
| 1614 |         SetCursor (infoPtr->hcurDivopen);
 | 
|---|
| 1615 |     else
 | 
|---|
| 1616 |         SetCursor (infoPtr->hcurArrow);
 | 
|---|
| 1617 | 
 | 
|---|
| 1618 |     return 0;
 | 
|---|
| 1619 | }
 | 
|---|
| 1620 | 
 | 
|---|
| 1621 | 
 | 
|---|
| 1622 | static LRESULT
 | 
|---|
| 1623 | HEADER_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1624 | {
 | 
|---|
| 1625 |     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
 | 
|---|
| 1626 |     TEXTMETRICA tm;
 | 
|---|
| 1627 |     HFONT hFont, hOldFont;
 | 
|---|
| 1628 |     HDC hdc;
 | 
|---|
| 1629 | 
 | 
|---|
| 1630 |     infoPtr->hFont = (HFONT)wParam;
 | 
|---|
| 1631 | 
 | 
|---|
| 1632 |     hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
 | 
|---|
| 1633 | 
 | 
|---|
| 1634 |     hdc = GetDC (0);
 | 
|---|
| 1635 |     hOldFont = SelectObject (hdc, hFont);
 | 
|---|
| 1636 |     GetTextMetricsA (hdc, &tm);
 | 
|---|
| 1637 |     infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
 | 
|---|
| 1638 |     SelectObject (hdc, hOldFont);
 | 
|---|
| 1639 |     ReleaseDC (0, hdc);
 | 
|---|
| 1640 | 
 | 
|---|
| 1641 |     infoPtr->bRectsValid = FALSE;
 | 
|---|
| 1642 | 
 | 
|---|
| 1643 |     if (lParam) {
 | 
|---|
| 1644 |         InvalidateRect(hwnd, NULL, FALSE);
 | 
|---|
| 1645 |     }
 | 
|---|
| 1646 | 
 | 
|---|
| 1647 |     return 0;
 | 
|---|
| 1648 | }
 | 
|---|
| 1649 | 
 | 
|---|
| 1650 | 
 | 
|---|
| 1651 | static LRESULT WINAPI
 | 
|---|
| 1652 | HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 1653 | {
 | 
|---|
| 1654 |     TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx\n", hwnd, msg, wParam, lParam);
 | 
|---|
| 1655 |     if (!HEADER_GetInfoPtr (hwnd) && (msg != WM_CREATE))
 | 
|---|
| 1656 |         return DefWindowProcA (hwnd, msg, wParam, lParam);
 | 
|---|
| 1657 |     switch (msg) {
 | 
|---|
| 1658 | /*      case HDM_CLEARFILTER: */
 | 
|---|
| 1659 | 
 | 
|---|
| 1660 |         case HDM_CREATEDRAGIMAGE:
 | 
|---|
| 1661 |             return HEADER_CreateDragImage (hwnd, wParam);
 | 
|---|
| 1662 | 
 | 
|---|
| 1663 |         case HDM_DELETEITEM:
 | 
|---|
| 1664 |             return HEADER_DeleteItem (hwnd, wParam);
 | 
|---|
| 1665 | 
 | 
|---|
| 1666 | /*      case HDM_EDITFILTER: */
 | 
|---|
| 1667 | 
 | 
|---|
| 1668 | /*      case HDM_GETBITMAPMARGIN: */
 | 
|---|
| 1669 | 
 | 
|---|
| 1670 |         case HDM_GETIMAGELIST:
 | 
|---|
| 1671 |             return HEADER_GetImageList (hwnd);
 | 
|---|
| 1672 | 
 | 
|---|
| 1673 |         case HDM_GETITEMA:
 | 
|---|
| 1674 |             return HEADER_GetItemA (hwnd, wParam, lParam);
 | 
|---|
| 1675 | 
 | 
|---|
| 1676 |         case HDM_GETITEMW:
 | 
|---|
| 1677 |             return HEADER_GetItemW (hwnd, wParam, lParam);
 | 
|---|
| 1678 | 
 | 
|---|
| 1679 |         case HDM_GETITEMCOUNT:
 | 
|---|
| 1680 |             return HEADER_GetItemCount (hwnd);
 | 
|---|
| 1681 | 
 | 
|---|
| 1682 |         case HDM_GETITEMRECT:
 | 
|---|
| 1683 |             return HEADER_GetItemRect (hwnd, wParam, lParam);
 | 
|---|
| 1684 | 
 | 
|---|
| 1685 |         case HDM_GETORDERARRAY:
 | 
|---|
| 1686 |             return HEADER_GetOrderArray(hwnd, wParam, lParam);
 | 
|---|
| 1687 | 
 | 
|---|
| 1688 |         case HDM_GETUNICODEFORMAT:
 | 
|---|
| 1689 |             return HEADER_GetUnicodeFormat (hwnd);
 | 
|---|
| 1690 | 
 | 
|---|
| 1691 |         case HDM_HITTEST:
 | 
|---|
| 1692 |             return HEADER_HitTest (hwnd, wParam, lParam);
 | 
|---|
| 1693 | 
 | 
|---|
| 1694 |         case HDM_INSERTITEMA:
 | 
|---|
| 1695 |             return HEADER_InsertItemA (hwnd, wParam, lParam);
 | 
|---|
| 1696 | 
 | 
|---|
| 1697 |         case HDM_INSERTITEMW:
 | 
|---|
| 1698 |             return HEADER_InsertItemW (hwnd, wParam, lParam);
 | 
|---|
| 1699 | 
 | 
|---|
| 1700 |         case HDM_LAYOUT:
 | 
|---|
| 1701 |             return HEADER_Layout (hwnd, wParam, lParam);
 | 
|---|
| 1702 | 
 | 
|---|
| 1703 |         case HDM_ORDERTOINDEX:
 | 
|---|
| 1704 |             return HEADER_OrderToIndex(hwnd, wParam);
 | 
|---|
| 1705 | 
 | 
|---|
| 1706 | /*      case HDM_SETBITMAPMARGIN: */
 | 
|---|
| 1707 | 
 | 
|---|
| 1708 | /*      case HDM_SETFILTERCHANGETIMEOUT: */
 | 
|---|
| 1709 | 
 | 
|---|
| 1710 | /*      case HDM_SETHOTDIVIDER: */
 | 
|---|
| 1711 | 
 | 
|---|
| 1712 |         case HDM_SETIMAGELIST:
 | 
|---|
| 1713 |             return HEADER_SetImageList (hwnd, (HIMAGELIST)lParam);
 | 
|---|
| 1714 | 
 | 
|---|
| 1715 |         case HDM_SETITEMA:
 | 
|---|
| 1716 |             return HEADER_SetItemA (hwnd, wParam, lParam);
 | 
|---|
| 1717 | 
 | 
|---|
| 1718 |         case HDM_SETITEMW:
 | 
|---|
| 1719 |             return HEADER_SetItemW (hwnd, wParam, lParam);
 | 
|---|
| 1720 | 
 | 
|---|
| 1721 |         case HDM_SETORDERARRAY:
 | 
|---|
| 1722 |             return HEADER_SetOrderArray(hwnd, wParam, lParam);
 | 
|---|
| 1723 | 
 | 
|---|
| 1724 |         case HDM_SETUNICODEFORMAT:
 | 
|---|
| 1725 |             return HEADER_SetUnicodeFormat (hwnd, wParam);
 | 
|---|
| 1726 | 
 | 
|---|
| 1727 |         case WM_CREATE:
 | 
|---|
| 1728 |             return HEADER_Create (hwnd, wParam, lParam);
 | 
|---|
| 1729 | 
 | 
|---|
| 1730 |         case WM_DESTROY:
 | 
|---|
| 1731 |             return HEADER_Destroy (hwnd, wParam, lParam);
 | 
|---|
| 1732 | 
 | 
|---|
| 1733 |         case WM_ERASEBKGND:
 | 
|---|
| 1734 |             return 1;
 | 
|---|
| 1735 | 
 | 
|---|
| 1736 |         case WM_GETDLGCODE:
 | 
|---|
| 1737 |             return DLGC_WANTTAB | DLGC_WANTARROWS;
 | 
|---|
| 1738 | 
 | 
|---|
| 1739 |         case WM_GETFONT:
 | 
|---|
| 1740 |             return HEADER_GetFont (hwnd);
 | 
|---|
| 1741 | 
 | 
|---|
| 1742 |         case WM_LBUTTONDBLCLK:
 | 
|---|
| 1743 |             return HEADER_LButtonDblClk (hwnd, wParam, lParam);
 | 
|---|
| 1744 | 
 | 
|---|
| 1745 |         case WM_LBUTTONDOWN:
 | 
|---|
| 1746 |             return HEADER_LButtonDown (hwnd, wParam, lParam);
 | 
|---|
| 1747 | 
 | 
|---|
| 1748 |         case WM_LBUTTONUP:
 | 
|---|
| 1749 |             return HEADER_LButtonUp (hwnd, wParam, lParam);
 | 
|---|
| 1750 | 
 | 
|---|
| 1751 |         case WM_MOUSEMOVE:
 | 
|---|
| 1752 |             return HEADER_MouseMove (hwnd, wParam, lParam);
 | 
|---|
| 1753 | 
 | 
|---|
| 1754 |         case WM_NOTIFYFORMAT:
 | 
|---|
| 1755 |             return HEADER_NotifyFormat (hwnd, wParam, lParam);
 | 
|---|
| 1756 | 
 | 
|---|
| 1757 |         case WM_SIZE:
 | 
|---|
| 1758 |             return HEADER_Size (hwnd, wParam);
 | 
|---|
| 1759 | 
 | 
|---|
| 1760 |         case WM_PAINT:
 | 
|---|
| 1761 |             return HEADER_Paint (hwnd, wParam);
 | 
|---|
| 1762 | 
 | 
|---|
| 1763 |         case WM_RBUTTONUP:
 | 
|---|
| 1764 |             return HEADER_RButtonUp (hwnd, wParam, lParam);
 | 
|---|
| 1765 | 
 | 
|---|
| 1766 |         case WM_SETCURSOR:
 | 
|---|
| 1767 |             return HEADER_SetCursor (hwnd, wParam, lParam);
 | 
|---|
| 1768 | 
 | 
|---|
| 1769 |         case WM_SETFONT:
 | 
|---|
| 1770 |             return HEADER_SetFont (hwnd, wParam, lParam);
 | 
|---|
| 1771 | 
 | 
|---|
| 1772 |         default:
 | 
|---|
| 1773 |             if ((msg >= WM_USER) && (msg < WM_APP))
 | 
|---|
| 1774 |                 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
 | 
|---|
| 1775 |                      msg, wParam, lParam );
 | 
|---|
| 1776 |             return DefWindowProcA (hwnd, msg, wParam, lParam);
 | 
|---|
| 1777 |     }
 | 
|---|
| 1778 |     return 0;
 | 
|---|
| 1779 | }
 | 
|---|
| 1780 | 
 | 
|---|
| 1781 | 
 | 
|---|
| 1782 | VOID
 | 
|---|
| 1783 | HEADER_Register (void)
 | 
|---|
| 1784 | {
 | 
|---|
| 1785 |     WNDCLASSA wndClass;
 | 
|---|
| 1786 | 
 | 
|---|
| 1787 |     ZeroMemory (&wndClass, sizeof(WNDCLASSA));
 | 
|---|
| 1788 |     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
 | 
|---|
| 1789 |     wndClass.lpfnWndProc   = (WNDPROC)HEADER_WindowProc;
 | 
|---|
| 1790 |     wndClass.cbClsExtra    = 0;
 | 
|---|
| 1791 |     wndClass.cbWndExtra    = sizeof(HEADER_INFO *);
 | 
|---|
| 1792 |     wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
 | 
|---|
| 1793 |     wndClass.lpszClassName = WC_HEADERA;
 | 
|---|
| 1794 | 
 | 
|---|
| 1795 |     RegisterClassA (&wndClass);
 | 
|---|
| 1796 | }
 | 
|---|
| 1797 | 
 | 
|---|
| 1798 | 
 | 
|---|
| 1799 | VOID
 | 
|---|
| 1800 | HEADER_Unregister (void)
 | 
|---|
| 1801 | {
 | 
|---|
| 1802 |     UnregisterClassA (WC_HEADERA, NULL);
 | 
|---|
| 1803 | }
 | 
|---|