Changeset 2782 for trunk/src


Ignore:
Timestamp:
Feb 14, 2000, 6:31:40 PM (26 years ago)
Author:
cbratschi
Message:

merged comctl32.c and treeview with corel 20000212 + my newest code

Location:
trunk/src/comctl32
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/comctl32/comctl32.c

    r2635 r2782  
    1 /* $Id: comctl32.c,v 1.13 2000-02-04 17:02:06 cbratschi Exp $ */
     1/* $Id: comctl32.c,v 1.14 2000-02-14 17:31:39 cbratschi Exp $ */
    22/*
    33 * Win32 common controls implementation
     
    1212 */
    1313
    14 /* WINE 20000130 level (commctrl.c) */
     14/*
     15 - Corel 20000212 level
     16 - WINE 20000130 level (commctrl.c)
     17*/
    1518
    1619#include "comctl32.h"
     
    3740#include "listview.h"
    3841
    39 HANDLE COMCTL32_hHeap = (HANDLE)NULL;
     42HANDLE  COMCTL32_hHeap = (HANDLE)NULL;
    4043HMODULE COMCTL32_hModule = 0;
    41 LPSTR    COMCTL32_aSubclass = (LPSTR)NULL;
     44LPSTR   COMCTL32_aSubclass = (LPSTR)NULL;
    4245
    4346void CDECL RegisterCOMCTL32WindowClasses(unsigned long hinstDLL)
     
    633636
    634637            SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
    635                             MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
     638                            MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
    636639            SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
    637                             MAKELPARAM((WORD)dyButton, (WORD)dxButton));
     640                            MAKELPARAM((WORD)dxButton, (WORD)dyButton));
    638641
    639642
  • trunk/src/comctl32/propsheet.c

    r2126 r2782  
    1 /* $Id: propsheet.c,v 1.17 1999-12-18 20:56:59 achimha Exp $ */
     1/* $Id: propsheet.c,v 1.18 2000-02-14 17:31:39 cbratschi Exp $ */
    22/*
    33 * Property Sheets
     
    1414
    1515/* WINE 991212 level */
    16 
    17 /* CB: Odin problems:
    18  - trap in PROPSHEET_DialogProc (tab control creation)
    19 */
    2016
    2117#include <string.h>
     
    156152  psInfo->useCallback = dwFlags & PSH_USECALLBACK;
    157153  psInfo->isModeless = dwFlags & PSH_MODELESS;
    158   psInfo->ppshheader = lppsh;
     154  psInfo->ppshheader = (PROPSHEETHEADERA*)lppsh;
    159155  psInfo->ppshheader = COMCTL32_Alloc(sizeof(PROPSHEETHEADERA));
    160156  *psInfo->ppshheader = *lppsh;
     
    168164  if (dwFlags & PSH_USEPSTARTPAGE)
    169165  {
    170 //    TRACE(propsheet, "PSH_USEPSTARTPAGE is on");
     166    //TRACE(propsheet, "PSH_USEPSTARTPAGE is on");
    171167    psInfo->active_page = 0;
    172168  }
     
    297293  /* Extract the caption */
    298294  psInfo->proppage[index].pszText = (LPCWSTR)p;
    299 //  TRACE("Tab %d %s\n",index,debugstr_w((LPCWSTR)p));
     295  //TRACE("Tab %d %s\n",index,debugstr_w((LPCWSTR)p));
    300296  p += lstrlenW((LPCWSTR)p) + 1;
    301297
     
    336332    {
    337333      if (psInfo->hImageList == 0 )
    338         psInfo->hImageList = ImageList_Create(icon_cx, icon_cy, ILC_COLOR, 1, 1);
     334        psInfo->hImageList = ImageList_Create(icon_cx, icon_cy, ILC_COLOR, 1, 1);
    339335
    340336      ImageList_AddIcon(psInfo->hImageList, hIcon);
     
    380376       EnableWindow( owner, TRUE );
    381377   }
    382    retval = dlgInfo->idResult; 
     378   retval = dlgInfo->idResult;
    383379
    384380   WIN_ReleaseWndPtr(wndPtr);
     
    440436  if (!(psInfo->ppshheader->dwFlags & PSH_MODELESS))
    441437     ret = PROPSHEET_DoDialogBox((HWND)ret, psInfo->ppshheader->hwndParent);
    442  
     438
    443439  COMCTL32_Free(temp);
    444440
     
    10241020  {
    10251021    dprintf(("COMCTL32:PROPSHEET_CreatePage: ERROR!!! ppshpage == NULL!!!\n"));
    1026     return FALSE; 
     1022    return FALSE;
    10271023  }
    10281024
     
    11301126
    11311127     ppshpage = (LPCPROPSHEETPAGEA)psInfo->proppage[index].hpage;
    1132      PROPSHEET_CreatePage(hwndDlg, index, psInfo, ppshpage);
     1128     PROPSHEET_CreatePage(hwndDlg, index, psInfo, (PROPSHEETPAGEA*)ppshpage);
    11331129
    11341130     psn.hdr.hwndFrom = hwndDlg;
     
    11421138
    11431139     /*
    1144       * TODO: check return value. 
     1140      * TODO: check return value.
    11451141      */
    11461142  }
     
    11811177  psn.hdr.idFrom   = 0;
    11821178  psn.lParam       = 0;
    1183  
     1179
    11841180  hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
    11851181
     
    12171213  psn.hdr.idFrom   = 0;
    12181214  psn.lParam       = 0;
    1219  
     1215
    12201216  hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
    12211217
    12221218  msgResult = SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn);
    12231219
    1224   TRACE("msg result %ld\n", msgResult);
     1220  //TRACE("msg result %ld\n", msgResult);
    12251221
    12261222  if (msgResult == -1)
     
    12531249  psn.hdr.idFrom   = 0;
    12541250  psn.lParam       = 0;
    1255  
     1251
    12561252  hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
    12571253
    12581254  msgResult = SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn);
    12591255
    1260   TRACE("msg result %ld\n", msgResult);
     1256  //TRACE("msg result %ld\n", msgResult);
    12611257
    12621258  if (msgResult != 0)
     
    12891285  psn.hdr.idFrom   = 0;
    12901286  psn.lParam       = 0;
    1291  
     1287
    12921288
    12931289  /*
     
    13061302  psn.hdr.code = PSN_APPLY;
    13071303  psn.lParam   = lParam;
    1308  
     1304
    13091305  for (i = 0; i < psInfo->nPages; i++)
    13101306  {
     
    13521348  psn.hdr.idFrom   = 0;
    13531349  psn.lParam       = 0;
    1354  
     1350
    13551351  if (SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn))
    13561352    return;
     
    13581354  psn.hdr.code = PSN_RESET;
    13591355  psn.lParam   = lParam;
    1360  
     1356
    13611357  for (i = 0; i < psInfo->nPages; i++)
    13621358  {
     
    13941390  psn.hdr.idFrom   = 0;
    13951391  psn.lParam       = 0;
    1396  
     1392
    13971393  SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn);
    13981394}
     
    15461542  if (index < 0 || index >= psInfo->nPages)
    15471543  {
    1548     TRACE("Could not find page to select!\n");
     1544    //TRACE("Could not find page to select!\n");
    15491545    return FALSE;
    15501546  }
     
    15691565
    15701566    /*
    1571      * TODO: check return value. 
     1567     * TODO: check return value.
    15721568     */
    15731569  }
     
    16901686  {
    16911687     /* Create the page but don't show it */
    1692      PROPSHEET_CreatePage(hwndDlg, psInfo->nPages, psInfo, ppsp);
     1688     PROPSHEET_CreatePage(hwndDlg, psInfo->nPages, psInfo, (PROPSHEETPAGEA*)ppsp);
    16931689  }
    16941690
     
    17431739  if (index < 0 || index >= psInfo->nPages)
    17441740  {
    1745       TRACE("Could not find page to remove!\n");
     1741      //TRACE("Could not find page to remove!\n");
    17461742      return FALSE;
    17471743  }
    17481744
    1749   TRACE("total pages %d removing page %d active page %d\n",
    1750         psInfo->nPages, index, psInfo->active_page);
     1745  //TRACE("total pages %d removing page %d active page %d\n",
     1746  //      psInfo->nPages, index, psInfo->active_page);
    17511747  /*
    17521748   * Check if we're removing the active page.
     
    17931789     DestroyPropertySheetPage(psInfo->proppage[index].hpage);
    17941790  }
    1795  
     1791
    17961792  /* Remove the tab */
    17971793  SendMessageA(hwndTabControl, TCM_DELETEITEM, index, 0);
     
    18001796  psInfo->proppage = COMCTL32_Alloc(sizeof(PropPageInfo) * psInfo->nPages);
    18011797
    1802   if (index > 0) 
     1798  if (index > 0)
    18031799    memcpy(&psInfo->proppage[0], &oldPages[0], index * sizeof(PropPageInfo));
    18041800
     
    18261822  HWND hwndFinish = GetDlgItem(hwndDlg, IDC_FINISH_BUTTON);
    18271823
    1828   TRACE("%ld\n", dwFlags);
     1824  //TRACE("%ld\n", dwFlags);
    18291825
    18301826  EnableWindow(hwndBack, FALSE);
     
    18981894                                                       PropSheetInfoStr);
    18991895
    1900   TRACE("\n");
     1896  //TRACE("\n");
    19011897  if (HIWORD(psInfo->ppshheader->pszCaption))
    19021898      HeapFree(GetProcessHeap(), 0, (LPVOID)psInfo->ppshheader->pszCaption);
     
    19881984  if ( (ppsp->dwFlags & PSP_USEICONID) && HIWORD( ppsp->u2.pszIcon ) )
    19891985      ppsp->u2.pszIcon = HEAP_strdupA( GetProcessHeap(), 0, lpPropSheetPage->u2.pszIcon );
    1990        
     1986
    19911987
    19921988  if ((ppsp->dwFlags & PSP_USETITLE) && HIWORD( ppsp->pszTitle ))
     
    21572153      ppshpage = (LPCPROPSHEETPAGEA)psInfo->proppage[idx].hpage;
    21582154      psInfo->active_page = -1;
    2159  
     2155
    21602156      PROPSHEET_SetCurSel(hwnd, idx, psInfo->proppage[idx].hpage);
    21612157
     
    23292325      if (LoadStringA(COMCTL32_hModule, IDS_CLOSE, buf, sizeof(buf)))
    23302326         SetWindowTextA(hwndOK, buf);
    2331  
     2327
    23322328      return FALSE;
    23332329    }
  • trunk/src/comctl32/status.c

    r2740 r2782  
    1 /* $Id: status.c,v 1.18 2000-02-10 18:51:19 cbratschi Exp $ */
     1/* $Id: status.c,v 1.19 2000-02-14 17:31:39 cbratschi Exp $ */
    22/*
    33 * Interface code to StatusWindow widget/control
     
    900900    }
    901901
    902     hdc = GetDC(0);
     902    hdc = GetDC(hwnd);
    903903    if (hdc) {
    904904        TEXTMETRICA tm;
     
    907907        hOldFont = SelectObject (hdc,infoPtr->hDefaultFont);
    908908        GetTextMetricsA(hdc, &tm);
    909         infoPtr->textHeight = tm.tmHeight;
     909        infoPtr->textHeight = tm.tmHeight+tm.tmExternalLeading;
    910910        SelectObject (hdc, hOldFont);
    911         ReleaseDC(0, hdc);
     911        ReleaseDC(hwnd, hdc);
    912912    }
    913913
     
    936936    width = rect.right - rect.left;
    937937    infoPtr->height = infoPtr->textHeight + 4 + VERT_BORDER;
    938 //CB: todo: find bug!
     938//CB: todo: find bug in font handling!
    939939infoPtr->height += 4;
    940940    MoveWindow(hwnd,lpCreate->x,lpCreate->y-1,width,infoPtr->height,FALSE);
     
    10701070
    10711071    infoPtr->hFont = (HFONT)wParam;
    1072     if (LOWORD(lParam) == TRUE) {
    1073         HDC hdc = GetDC (hwnd);
    1074         STATUSBAR_Refresh (hwnd, hdc);
    1075         ReleaseDC (hwnd, hdc);
     1072    if (LOWORD(lParam) == TRUE)
     1073    {
     1074      HDC hdc = GetDC (hwnd);
     1075      TEXTMETRICA tm;
     1076      HFONT hOldFont;
     1077
     1078      hOldFont = SelectObject(hdc,infoPtr->hFont);
     1079      GetTextMetricsA(hdc,&tm);
     1080      infoPtr->textHeight = tm.tmHeight+tm.tmExternalLeading;
     1081      SelectObject(hdc,hOldFont);
     1082
     1083      //CB: todo: move window
     1084
     1085      STATUSBAR_Refresh (hwnd, hdc);
     1086      ReleaseDC (hwnd, hdc);
    10761087    }
    10771088
  • trunk/src/comctl32/treeview.c

    r2769 r2782  
    1 /* $Id: treeview.c,v 1.24 2000-02-12 18:10:40 cbratschi Exp $ */
     1/* $Id: treeview.c,v 1.25 2000-02-14 17:31:40 cbratschi Exp $ */
    22/* Treeview control
    33 *
     
    66 * Copyright 1999 Sylvain St-Germain
    77 * Copyright 1999 Achim Hasenmueller
    8  * Copyright 1999 Christoph Bratschi
     8 * Copyright 1999-2000 Christoph Bratschi
    99 *
    1010 *
     
    4242 */
    4343
    44 /* WINE 991212 level */
     44/*
     45 Most identical with:
     46 - Corel 20000212 level
     47 - (WINE 991212 level)
     48*/
    4549
    4650/* CB: todo
    4751
    48  - sub parent lines aren't redrawn in expand handler
    49  - invisible sibling lines aren't drawn in WM_PAINT
    5052 - WM_LBUTTONDOWN: bug in highlight code
    5153 - WM_SIZE: redraw doesn't work
     
    6365/* ffs should be in <string.h>. */
    6466
     67//#define OS2LINEHACK //CB: too slow, but looks good
     68
    6569/* Defines, since they do not need to return previous state, and nr
    6670 * has no side effects in this file.
     
    8084static BOOL    TREEVIEW_SendCustomDrawNotify (HWND hwnd, DWORD dwDrawStage, HDC hdc, RECT rc);
    8185static BOOL    TREEVIEW_SendCustomDrawItemNotify (HWND hwnd, HDC hdc, TREEVIEW_ITEM *tvItem, UINT uItemDrawState);
     86static LRESULT TREEVIEW_SelectItem (HWND hwnd, WPARAM wParam, LPARAM lParam);
    8287static LRESULT TREEVIEW_DoSelectItem (HWND hwnd, INT action, HTREEITEM newSelect, INT cause);
    8388static void    TREEVIEW_Refresh(HWND hwnd);
     
    8893static LRESULT CALLBACK TREEVIEW_Edit_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    8994
    90 LRESULT WINAPI TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam);
     95LRESULT WINAPI TREEVIEW_EndEditLabelNow (HWND hwnd, BOOL bCancel);
     96
     97HWND TREEVIEW_EditLabelA(HWND hwnd, HTREEITEM hItem);
    9198
    9299/* helper functions. Work with the assumption that validity of operands
     
    117124
    118125/***************************************************************************
     126 * This function uses cChildren field to decide whether item has children
     127 * or not.
     128 * Note: return value doesn't reflect physical presence of children.
     129 */
     130static INT TREEVIEW_HasChildren(
     131  HWND hwnd,
     132  TREEVIEW_ITEM *wineItem)
     133{
     134   INT cChildren = 0;
     135
     136   if ( wineItem->mask & TVIF_CHILDREN )
     137   {
     138      if (wineItem->cChildren == I_CHILDRENCALLBACK)
     139      {
     140         TREEVIEW_ITEM tempItem;
     141
     142         tempItem.hItem  = wineItem->hItem;
     143         tempItem.state  = wineItem->state;
     144         tempItem.lParam = wineItem->lParam;
     145
     146         TREEVIEW_SendDispInfoNotify(hwnd, &tempItem, TVN_GETDISPINFO, TVIF_CHILDREN);
     147         cChildren = tempItem.cChildren;
     148      }
     149      else
     150         cChildren = wineItem->cChildren;
     151   }
     152   else if ( wineItem->firstChild )
     153      cChildren = 1;
     154
     155   return cChildren;
     156}
     157
     158/***************************************************************************
    119159 * This method returns the last expanded child item of a tree node
    120160 */
    121161static TREEVIEW_ITEM *TREEVIEW_GetLastListItem(
     162  HWND hwnd,
    122163  TREEVIEW_INFO *infoPtr,
    123164  TREEVIEW_ITEM *tvItem)
     
    134175   * If the last sibling has expanded children, restart.
    135176   */
    136   if ( ( wineItem->cChildren > 0 ) && ( wineItem->state & TVIS_EXPANDED) )
    137     return TREEVIEW_GetLastListItem(
     177  if ((wineItem->state & TVIS_EXPANDED) &&
     178       TREEVIEW_HasChildren(hwnd, wineItem))
     179  {
     180       return TREEVIEW_GetLastListItem(
     181             hwnd,
    138182             infoPtr,
    139183             &(infoPtr->items[(INT)wineItem->firstChild]));
     184  }
    140185
    141186  return wineItem;
     
    147192 */
    148193static TREEVIEW_ITEM *TREEVIEW_GetPrevListItem(
     194  HWND hwnd,
    149195  TREEVIEW_INFO *infoPtr,
    150196  TREEVIEW_ITEM *tvItem)
     
    158204    TREEVIEW_ITEM *upItem = &infoPtr->items[(INT)tvItem->upsibling];
    159205
    160     if ( ( upItem->cChildren > 0 ) && ( upItem->state & TVIS_EXPANDED) )
    161       return TREEVIEW_GetLastListItem(
     206    if ( (upItem->state & TVIS_EXPANDED) &&
     207          TREEVIEW_HasChildren(hwnd, upItem) )
     208    {
     209       return TREEVIEW_GetLastListItem(
     210               hwnd,
    162211               infoPtr,
    163212               &infoPtr->items[(INT)upItem->firstChild]);
     213    }
    164214    else
    165215      return upItem;
     
    183233 */
    184234static TREEVIEW_ITEM *TREEVIEW_GetNextListItem(
     235  HWND hwnd,
    185236  TREEVIEW_INFO *infoPtr,
    186237  TREEVIEW_ITEM *tvItem)
     
    191242   * If this item has children and is expanded, return the first child
    192243   */
    193   if ((tvItem->firstChild) && (tvItem->state & TVIS_EXPANDED))
    194                 return (& infoPtr->items[(INT)tvItem->firstChild]);
     244  if ( (tvItem->state & TVIS_EXPANDED) &&
     245        TREEVIEW_HasChildren(hwnd, tvItem) )
     246  {
     247     return (& infoPtr->items[(INT)tvItem->firstChild]);
     248  }
    195249
    196250
     
    222276 */
    223277static TREEVIEW_ITEM *TREEVIEW_GetListItem(
     278  HWND hwnd,
    224279  TREEVIEW_INFO *infoPtr,
    225280  TREEVIEW_ITEM *tvItem,
     
    237292      /* Keep a pointer to the previous in case we ask for more than we got */
    238293      previousItem = wineItem;
    239       wineItem     = TREEVIEW_GetNextListItem(infoPtr, wineItem);
     294      wineItem     = TREEVIEW_GetNextListItem(hwnd,infoPtr,wineItem);
    240295    }
    241296
     
    250305      /* Keep a pointer to the previous in case we ask for more than we got */
    251306      previousItem = wineItem;
    252       wineItem = TREEVIEW_GetPrevListItem(infoPtr, wineItem);
     307      wineItem = TREEVIEW_GetPrevListItem(hwnd,infoPtr,wineItem);
    253308    }
    254309
     
    270325  TREEVIEW_ITEM *parentItem)
    271326{
    272  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    273  TREEVIEW_ITEM *killItem;
    274  INT    kill;
    275 
    276  kill=(INT)parentItem->firstChild;
    277  while (kill) {
    278         tv_set_bit ( kill, infoPtr->freeList);
    279         killItem=& infoPtr->items[kill];
    280         if (killItem->pszText!=LPSTR_TEXTCALLBACKA)
    281                 COMCTL32_Free (killItem->pszText);
    282         TREEVIEW_SendTreeviewNotify (hwnd, TVN_DELETEITEM, 0, (HTREEITEM)kill, 0);
    283         if (killItem->firstChild)
    284                         TREEVIEW_RemoveAllChildren (hwnd, killItem);
    285         kill=(INT)killItem->sibling;
    286  }
    287 
    288  if (parentItem->cChildren>0) {
    289         infoPtr->uNumItems -= parentItem->cChildren;
    290         parentItem->firstChild = 0;
    291         parentItem->cChildren  = 0;
    292  }
    293 
     327  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     328  TREEVIEW_ITEM *killItem;
     329  INT    kill;
     330
     331  kill=(INT)parentItem->firstChild;
     332  while (kill)
     333  {
     334    tv_set_bit ( kill, infoPtr->freeList);
     335    infoPtr->uNumItems--;
     336    killItem=& infoPtr->items[kill];
     337    if (killItem->pszText!=LPSTR_TEXTCALLBACKA)
     338      COMCTL32_Free (killItem->pszText);
     339    TREEVIEW_SendTreeviewNotify (hwnd, TVN_DELETEITEM, 0, (HTREEITEM)kill, 0);
     340    if (killItem->firstChild)
     341      TREEVIEW_RemoveAllChildren (hwnd, killItem);
     342    kill=(INT)killItem->sibling;
     343  }
     344
     345  parentItem->firstChild = 0;
    294346}
    295347
     
    316368
    317369 if (wineItem->parent) {
    318         parentItem=& infoPtr->items [(INT)wineItem->parent];
    319         switch (parentItem->cChildren) {
    320                 case I_CHILDRENCALLBACK:
    321 //                              FIXME (treeview,"we don't handle I_CHILDRENCALLBACK yet\n");
    322                                 break;
    323                 case 1:
    324                         parentItem->cChildren=0;
    325                         parentItem->firstChild=0;
    326                         return;
    327                 default:
    328                         parentItem->cChildren--;
    329                         if ((INT)parentItem->firstChild==iItem)
    330                                 parentItem->firstChild=wineItem->sibling;
    331                 }
     370   parentItem=& infoPtr->items [(INT)wineItem->parent];
     371   if ((INT)parentItem->firstChild==iItem)
     372     parentItem->firstChild=wineItem->sibling;
    332373 }
    333374
     
    342383        siblingItem->upsibling=wineItem->upsibling;
    343384 }
     385
     386 if (iItem==(INT)infoPtr->selectedItem) {
     387   if (!wineItem->upsibling)
     388     infoPtr->selectedItem = 0;
     389   else
     390     TREEVIEW_DoSelectItem(hwnd, TVGN_CARET, wineItem->upsibling, TVC_UNKNOWN);
     391 }
    344392}
    345393
     
    381429  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    382430
    383   //TRACE (treeview,"\n");
    384 
    385431  if ((INT)wParam == TVSIL_NORMAL)
    386432        return (LRESULT) infoPtr->himlNormal;
     
    498544  infoPtr->insertMarkItem=(HTREEITEM) lParam;
    499545
    500   //CB: todo
    501   if (!(infoPtr->uInternalStatus & TV_NOREDRAW))
     546  TREEVIEW_Refresh(hwnd);
     547
     548  return 1;
     549}
     550
     551static LRESULT
     552TREEVIEW_SetTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
     553{
     554  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     555  COLORREF prevColor=infoPtr->clrText;
     556
     557  infoPtr->clrText=(COLORREF) lParam;
     558  if (infoPtr->clrText != prevColor)
    502559    TREEVIEW_Refresh(hwnd);
    503560
    504   return 1;
    505 }
    506 
    507 static LRESULT
    508 TREEVIEW_SetTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
    509 {
    510   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    511   COLORREF prevColor=infoPtr->clrText;
    512 
    513 //  TRACE (treeview,"\n");
    514   infoPtr->clrText=(COLORREF) lParam;
    515561  return (LRESULT) prevColor;
    516562}
     
    521567  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    522568
    523   //TRACE("\n");
    524569  return (LRESULT) infoPtr->clrBk;
    525570}
     
    531576  COLORREF prevColor=infoPtr->clrBk;
    532577
    533   //TRACE("\n");
    534578  infoPtr->clrBk=(COLORREF) lParam;
     579  if (infoPtr->clrBk != prevColor)
     580    TREEVIEW_Refresh(hwnd);
     581
     582
    535583  return (LRESULT) prevColor;
    536584}
     
    551599#define TREEVIEW_LEFT_MARGIN 8
    552600
     601#ifdef OS2LINEHACK
    553602//CB: hack for PS_DOT bug in Open32 pen handling
    554603
     
    559608{
    560609  if (drawPixel) SetPixel(drawDC,x,y,(COLORREF)lpData);
    561   else SetPixel(drawDC,x,y,RGB(255,255,255));
    562610  drawPixel = !drawPixel;
    563611}
     
    571619  for (x = 0;x < cPoints-1;x++)
    572620    LineDDA(lppt[x].x,lppt[x].y,lppt[x+1].x,lppt[x+1].y,TREEVIEW_DDAProc,color);
     621}
     622#endif
     623
     624//CB: pen must be selected!
     625
     626static void TREEVIEW_DrawVLines(HDC hdc,TREEVIEW_INFO *infoPtr,TREEVIEW_ITEM *wineItem)
     627{
     628  POINT points[2];
     629  INT center;
     630
     631  center = (wineItem->rect.top+wineItem->rect.bottom)/2;
     632//INT cChildren = TREEVIEW_HasChildren(hwnd,wineItem);
     633  if ((wineItem->iLevel == 0) && !wineItem->upsibling && wineItem->sibling)
     634  {
     635    TREEVIEW_ITEM *lastItem = &infoPtr->items[(INT)wineItem->sibling];
     636
     637    while (lastItem->sibling) lastItem = &infoPtr->items[(INT)lastItem->sibling];
     638
     639    points[0].y = center;
     640    points[1].x = points[0].x = 8;
     641    points[1].y = (lastItem->rect.top+lastItem->rect.bottom)/2;
     642#ifdef OS2LINEHACK
     643    TREEVIEW_Polyline(hdc,points,2,infoPtr->clrLine);
     644#else
     645    Polyline(hdc,points,2);
     646#endif
     647  }
     648
     649  if (wineItem->firstChild && (wineItem->state & TVIS_EXPANDED))
     650  {
     651    TREEVIEW_ITEM *lastItem = &infoPtr->items[(INT)wineItem->firstChild];
     652
     653    while (lastItem->sibling) lastItem = &infoPtr->items[(INT)lastItem->sibling];
     654
     655    points[0].y = (lastItem->upsibling != NULL) ?
     656                   wineItem->rect.bottom-3:  /* is linked to an icon       */
     657                   wineItem->rect.bottom+1;  /* is linked to a +/- box     */
     658    points[1].x = points[0].x = 28 + (20*wineItem->iLevel);
     659    points[1].y = (lastItem->rect.top+lastItem->rect.bottom)/2;  /* is linked to a +/- box     */
     660#ifdef OS2LINEHACK
     661    TREEVIEW_Polyline(hdc,points,2,infoPtr->clrLine);
     662#else
     663    Polyline(hdc,points,2);
     664#endif
     665  }
    573666}
    574667
     
    596689    if (cditem & CDRF_SKIPDEFAULT) return;
    597690  }
     691
     692  //CB: what does COMCTL 5.0 with CDRF_NEWFONT? recalc items?
    598693
    599694  /*
     
    607702   * Display the tree hierarchy
    608703   */
    609   if ((dwStyle & TVS_HASLINES) && (wineItem->hItem != infoPtr->TopRootItem))
     704  if (dwStyle & TVS_HASLINES)
    610705  {
    611706    /*
     
    620715    {
    621716      TREEVIEW_ITEM *upNode    = NULL;
    622       BOOL  hasParentOrSibling = TRUE;
    623717      RECT  upRect             = {0,0,0,0};
    624718      HPEN  hOldPen, hnewPen;
    625       POINT points[3];
     719      POINT points[2];
     720
     721      hnewPen = CreatePen(PS_DOT, 0, infoPtr->clrLine);
     722      hOldPen = SelectObject(hdc,hnewPen);
     723
     724      TREEVIEW_DrawVLines(hdc,infoPtr,wineItem);
     725
    626726      /*
    627727       * determine the target location of the line at root, either be linked
     
    632732      else if (wineItem->parent)
    633733        upNode  = TREEVIEW_ValidItem (infoPtr, wineItem->parent);
    634       else
    635         hasParentOrSibling = FALSE;
    636 
    637       if (upNode)
    638         upRect = upNode->rect;
    639 //CB: todo: draw full lines to avoid problems with PS_DOT and scrolling
     734
     735      if (upNode) upRect = upNode->rect;
     736
    640737      if (wineItem->iLevel == 0)
    641738      {
    642         points[2].x = points[1].x = upRect.left+8;
    643         points[0].x = points[2].x + 10;
    644         points[2].y = upRect.bottom-3;
     739        points[1].x = upRect.left+8;
     740        points[0].x = points[1].x + 10;
    645741        points[1].y = points[0].y = center;
    646742      } else
    647743      {
    648         points[2].x = points[1].x = 8 + (20*wineItem->iLevel);
    649         points[2].y = (upNode->cChildren == 0) ?
    650                         upRect.top :        /* is linked to the "L" above */
    651                         ( wineItem->upsibling != NULL) ?
    652                           upRect.bottom-3:  /* is linked to an icon       */
    653                           upRect.bottom+1;  /* is linked to a +/- box     */
     744        points[1].x = 8 + (20*wineItem->iLevel);
    654745        points[1].y = points[0].y = center;
    655746        points[0].x = points[1].x + 10;
     
    659750       * Get a dotted pen
    660751       */
    661 #if 0 //CB: workaround for Open32 PS_DOT bug
    662       hnewPen = CreatePen(PS_DOT, 0, infoPtr->clrLine);
    663       hOldPen = SelectObject( hdc, hnewPen );
    664 
    665       if (hasParentOrSibling)
    666         Polyline(hdc,points,3);
    667       else
    668         Polyline(hdc,points,2);
    669 
     752#ifdef OS2LINEHACK //CB: workaround for Open32 PS_DOT bug
     753      TREEVIEW_Polyline(hdc,points,2,infoPtr->clrLine);
     754#else
     755      Polyline(hdc,points,2);
     756#endif
    670757      DeleteObject(hnewPen);
    671758      SelectObject(hdc, hOldPen);
    672 #else
    673       if (hasParentOrSibling)
    674         TREEVIEW_Polyline(hdc,points,3,infoPtr->clrLine);
    675       else
    676         TREEVIEW_Polyline(hdc,points,2,infoPtr->clrLine);
    677 #endif
    678759    }
    679760  }
     
    687768  if (( dwStyle & TVS_HASBUTTONS) && ( dwStyle & TVS_HASLINES))
    688769  {
    689     if ( (wineItem->cChildren) ||
    690          (wineItem->cChildren == I_CHILDRENCALLBACK))
     770    if (TREEVIEW_HasChildren(hwnd, wineItem))
    691771    {
    692772      /* Setup expand box coordinate to facilitate the LMBClick handling */
     
    725805      himlp=&infoPtr->himlState;
    726806    imageIndex=wineItem->state>>12;
    727     imageIndex++;          /* yeah, right */
    728807
    729808    if ((himlp) && (imageIndex))
     
    768847    if (himlp)
    769848    {
    770       ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL);
     849      int ovlIdx = 0;
     850
     851      if(wineItem->stateMask & TVIS_OVERLAYMASK)
     852      ovlIdx = wineItem->state & TVIS_OVERLAYMASK;
     853
     854      ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL|ovlIdx);
    771855      ImageList_GetIconSize (*himlp, &cx, &cy);
    772856      wineItem->bitmap.left=xpos-2;
     
    778862  }
    779863
    780 
    781864  /*
    782865   * Display the text associated with this item
    783866   */
    784   r.left=xpos;
    785   if ((wineItem->mask & TVIF_TEXT) && (wineItem->pszText))
    786   {
    787     COLORREF oldBkColor = 0;
    788     COLORREF oldTextColor = 0;
    789     INT      oldBkMode;
    790 
    791     r.left += 3;
    792     r.right -= 3;
    793 
    794     wineItem->text.left  = r.left;
    795     wineItem->text.right = r.right;
    796     wineItem->text.top   = r.top;
    797     wineItem->text.bottom= r.bottom;
    798 
    799     if (wineItem->pszText== LPSTR_TEXTCALLBACKA)
     867  /* Don't paint item's text if it's being edited */
     868  if (!infoPtr->hwndEdit || (infoPtr->editItem != wineItem->hItem))
     869  {
     870    r.left=xpos;
     871    if ((wineItem->mask & TVIF_TEXT) && (wineItem->pszText))
    800872    {
    801       //TRACE("LPSTR_TEXTCALLBACK\n");
    802       TREEVIEW_SendDispInfoNotify (hwnd, wineItem, TVN_GETDISPINFO, TVIF_TEXT);
    803     }
    804 
    805 /* Yep, there are some things that need to be straightened out here.
    806    Removing the comments around the setTextColor does not give the right
    807    results. Dito FillRect.
    808 */
    809 
    810 
    811 /*    GetTextExtentPoint32A (hdc, wineItem->pszText,
    812                                         strlen (wineItem->pszText), &size); */
    813 
    814 /*    FillRect ( hdc, &wineItem->text, GetSysColorBrush (infoPtr->clrBk));
    815  */
    816 
    817 
    818     if (!(cditem & CDRF_NOTIFYPOSTPAINT) &&
    819         (wineItem->state & (TVIS_SELECTED | TVIS_DROPHILITED)) )
    820     {
    821       oldBkMode    = SetBkMode  (hdc, OPAQUE);
    822       oldBkColor   = SetBkColor  (hdc, GetSysColor( COLOR_HIGHLIGHT));
    823       oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT));
    824     } else
    825     {
    826       oldBkMode    = SetBkMode  (hdc, TRANSPARENT);
    827       oldBkColor   = SetBkColor (hdc, infoPtr->clrBk);
    828  /*         oldTextColor = SetTextColor(hdc, infoPtr->clrText);  */
    829     }
    830 
    831 
    832 
    833     /* Draw it */
    834     DrawTextA ( hdc,
    835       wineItem->pszText,
    836       lstrlenA(wineItem->pszText),
    837       &wineItem->text,
    838       uTextJustify | DT_VCENTER | DT_SINGLELINE );
    839 
    840     /* Obtain the text coordinate */
    841     DrawTextA (
    842       hdc,
    843       wineItem->pszText,
    844       lstrlenA(wineItem->pszText),
    845       &wineItem->text,
    846       uTextJustify | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT);
    847 
    848     /* Restore the hdc state */
    849     SetTextColor( hdc, oldTextColor);
    850 
    851     if (oldBkMode != TRANSPARENT)
    852       SetBkMode(hdc, oldBkMode);
    853     if (wineItem->state & (TVIS_SELECTED | TVIS_DROPHILITED))
    854       SetBkColor (hdc, oldBkColor);
    855 
    856     /* Draw the box arround the selected item */
    857     if (wineItem->state & TVIS_SELECTED )
    858     {
    859       HPEN  hNewPen     = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT) );
    860       HPEN  hOldPen     = SelectObject( hdc, hNewPen );
    861       POINT points[4];
    862 
    863       points[0].x = wineItem->text.left-1;
    864       points[0].y = wineItem->text.top+1;
    865       points[1].x = wineItem->text.right;
    866       points[1].y = wineItem->text.top+1;
    867       points[2].x = wineItem->text.right;
    868       points[2].y = wineItem->text.bottom;
    869       points[3].x = wineItem->text.left-1;
    870       points[3].y = wineItem->text.bottom;
    871 
    872       Polyline (hdc,points,4);
    873 
    874       DeleteObject(hNewPen);
    875       SelectObject(hdc, hOldPen);
     873      COLORREF oldTextColor = 0;
     874      INT      oldBkMode;
     875      HBRUSH   hbrBk = 0;
     876      BOOL     inFocus = GetFocus() == hwnd;
     877
     878      r.left += 3;
     879      r.right -= 3;
     880
     881      wineItem->text.left  = r.left;
     882      wineItem->text.right = r.right;
     883      wineItem->text.top   = r.top;
     884      wineItem->text.bottom= r.bottom;
     885
     886      oldBkMode = SetBkMode(hdc, TRANSPARENT);
     887
     888      /* - If item is drop target or it is selected and window is in focus -
     889       * use blue background (COLOR_HIGHLIGHT).
     890       * - If item is selected, window is not in focus, but it has style
     891       * TVS_SHOWSELALWAYS - use grey background (COLOR_BTNFACE)
     892       * - Otherwise - don't fill background
     893       */
     894       if ((wineItem->state & TVIS_DROPHILITED) ||
     895           ((wineItem->state & TVIS_SELECTED) &&
     896            (inFocus || (GetWindowLongA( hwnd, GWL_STYLE) & TVS_SHOWSELALWAYS))))
     897       {
     898           if ((wineItem->state & TVIS_DROPHILITED) || inFocus)
     899           {
     900               hbrBk = CreateSolidBrush(GetSysColor( COLOR_HIGHLIGHT));
     901               oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT));
     902           }
     903           else
     904           {
     905               hbrBk = CreateSolidBrush(GetSysColor( COLOR_BTNFACE));
     906
     907               if (infoPtr->clrText == -1)
     908                   oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
     909               else
     910                   oldTextColor = SetTextColor(hdc, infoPtr->clrText);
     911           }
     912      }
     913      else
     914      {
     915          if (infoPtr->clrText == -1)
     916              oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
     917          else
     918              oldTextColor = SetTextColor(hdc, infoPtr->clrText);
     919      }
     920
     921      if (wineItem->pszText== LPSTR_TEXTCALLBACKA) {
     922        //TRACE("LPSTR_TEXTCALLBACK\n");
     923        TREEVIEW_SendDispInfoNotify (hwnd, wineItem, TVN_GETDISPINFO, TVIF_TEXT);
     924      }
     925
     926      /* Obtain the text coordinate */
     927     DrawTextA (
     928            hdc,
     929            wineItem->pszText,
     930            lstrlenA(wineItem->pszText),
     931            &wineItem->text,
     932            uTextJustify | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT | DT_NOPREFIX);
     933
     934      /* We need to reset it to items height */
     935      wineItem->text.top = r.top;
     936      wineItem->text.bottom = r.bottom;
     937      wineItem->text.right += 4; /* This is extra for focus rectangle */
     938
     939      if (hbrBk)
     940      {
     941          FillRect(hdc, &wineItem->text, hbrBk);
     942          DeleteObject(hbrBk);
     943      }
     944
     945      wineItem->text.left += 2;
     946
     947      /* Draw it */
     948      DrawTextA ( hdc,
     949        wineItem->pszText,
     950        lstrlenA(wineItem->pszText),
     951        &wineItem->text,
     952        uTextJustify | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS);
     953
     954       wineItem->text.left -=2;
     955
     956      /* Restore the hdc state */
     957      SetTextColor( hdc, oldTextColor);
     958
     959      /* Draw the box arround the selected item */
     960      if (wineItem->state & TVIS_SELECTED)
     961      {
     962        HPEN  hNewPen     = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT) );
     963        HPEN  hOldPen     = SelectObject( hdc, hNewPen );
     964        INT   rop         = SetROP2(hdc, R2_XORPEN);
     965        POINT points[5];
     966
     967        points[4].x = points[0].x = wineItem->text.left;
     968        points[4].y = points[0].y = wineItem->text.top;
     969        points[1].x = wineItem->text.right-1 ;
     970        points[1].y = wineItem->text.top;
     971        points[2].x = wineItem->text.right-1;
     972        points[2].y = wineItem->text.bottom-1;
     973        points[3].x = wineItem->text.left;
     974        points[3].y = wineItem->text.bottom-1;
     975
     976        Polyline (hdc,points,5);
     977
     978        SetROP2(hdc, rop);
     979        DeleteObject(hNewPen);
     980        SelectObject(hdc, hOldPen);
     981      }
     982
     983      if (oldBkMode != TRANSPARENT)
     984          SetBkMode(hdc, oldBkMode);
    876985    }
    877986  }
     
    9301039   * validate parameters
    9311040   */
    932   if (lpRect == NULL)
     1041  if ((infoPtr == NULL) || (lpRect == NULL))
    9331042    return FALSE;
    9341043
     
    10241133  if (tvItem->mask & TVIF_TEXT) {
    10251134                if (tvItem->pszText!=LPSTR_TEXTCALLBACKA) {
    1026         len = lstrlenA (tvItem->pszText);
    1027         if (len > wineItem->cchTextMax)
    1028                         wineItem->pszText = COMCTL32_ReAlloc (wineItem->pszText, len+1);
    1029         lstrcpynA (wineItem->pszText, tvItem->pszText,len+1);
     1135        len=lstrlenA (tvItem->pszText) + 1;
     1136        if (len>wineItem->cchTextMax) {
     1137           wineItem->pszText= COMCTL32_ReAlloc (wineItem->pszText, len);
     1138           wineItem->cchTextMax = len;
     1139        }
     1140        lstrcpynA (wineItem->pszText, tvItem->pszText,len);
    10301141                } else {
    10311142                        if (wineItem->cchTextMax) {
     
    10331144                                wineItem->cchTextMax=0;
    10341145                        }
    1035                 wineItem->pszText = LPSTR_TEXTCALLBACKA;
     1146                wineItem->pszText=LPSTR_TEXTCALLBACKA;
    10361147                }
    1037    }
     1148  }
    10381149
    10391150  wineItem->mask |= tvItem->mask;
     
    10751186//CB: HDC parameter is optional
    10761187
     1188static void TREEVIEW_CalcItem(HWND hwnd,HDC hdc,TREEVIEW_ITEM *item)
     1189{
     1190  item->calculated = TRUE;
     1191  //CB: todo: move calc code from TREEVIEW_DrawItem
     1192}
     1193
     1194//CB: HDC parameter is optional
     1195
    10771196static void TREEVIEW_CalcItems(HWND hwnd,HDC hdc,TREEVIEW_INFO *infoPtr)
    10781197{
    1079   TREEVIEW_ITEM *item,*prevItem;
    1080   INT iItem, indent, x, y, cx, height, itemHeight;
     1198  TREEVIEW_ITEM *item;
     1199  INT iItem, indent,x,y,height,itemHeight,itemWidth;
    10811200  TEXTMETRICA tm;
    10821201  RECT rect,view;
    10831202  BOOL ownDC = FALSE;
     1203  DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
    10841204
    10851205  GetClientRect(hwnd,&rect);
     
    10891209  OffsetRect(&view,infoPtr->cx,infoPtr->cy);
    10901210
     1211  itemHeight = 0;
     1212  ImageList_GetIconSize (infoPtr->himlNormal, &x, &itemHeight);
     1213  itemHeight = MAX(infoPtr->uItemHeight,itemHeight);
     1214
     1215  if (!hdc)
     1216  {
     1217    ownDC = TRUE;
     1218    hdc = GetDC(hwnd);
     1219  }
     1220
     1221  GetTextMetricsA (hdc, &tm);
     1222  itemHeight = MAX(tm.tmHeight+tm.tmExternalLeading,itemHeight);
     1223  infoPtr->uRealItemHeight = itemHeight;
     1224
    10911225  iItem = (INT)infoPtr->TopRootItem;
    10921226  infoPtr->firstVisible = 0;
    10931227  item = NULL;
    1094   indent = 0;
    1095   x = y = 0;
     1228  indent = x = y = 0;
    10961229
    10971230  while (iItem)
    10981231  {
    1099     prevItem = item;
    11001232    item = &infoPtr->items[iItem];
    11011233    item->iLevel = indent;
    11021234
     1235    height = itemHeight * item->iIntegral +1;
     1236
     1237    item->rect.top    = y-infoPtr->cy;
     1238    item->rect.bottom = item->rect.top+height;
     1239    item->rect.left   = x-infoPtr->cx;
     1240    item->rect.right  = rect.right;
     1241
     1242    //calculate size and fill rects
    11031243    if ((infoPtr->uInternalStatus & TV_CALCALL) || !item->calculated)
    1104     {
    1105       ImageList_GetIconSize(infoPtr->himlNormal,&cx,&itemHeight);
    1106       if (infoPtr->uItemHeight > itemHeight)
    1107         itemHeight = infoPtr->uItemHeight;
    1108 
    1109       if (!hdc)
    1110       {
    1111         ownDC = TRUE;
    1112         hdc = GetDC(hwnd);
    1113       }
    1114 
    1115       GetTextMetricsA(hdc,&tm);
    1116       if ((tm.tmHeight + tm.tmExternalLeading) > itemHeight)
    1117         itemHeight = tm.tmHeight + tm.tmExternalLeading;
    1118 
    1119       infoPtr->uRealItemHeight = itemHeight;
    1120 
    1121       height = itemHeight * item->iIntegral +1;
    1122       item->calculated = TRUE;
    1123     } else height = infoPtr->uRealItemHeight*item->iIntegral+1;
    1124 
    1125     item->rect.top    = y - infoPtr->cy + rect.top;
    1126     item->rect.bottom = item->rect.top + height ;
    1127     item->rect.left   = x - infoPtr->cx + rect.left;
    1128     item->rect.right  = rect.right;
     1244      TREEVIEW_CalcItem(hwnd,hdc,item);
     1245
     1246    itemWidth = MAX(itemWidth,item->rect.right-item->rect.left);
    11291247
    11301248    if ((((y >= view.top) && (y <= view.bottom)) || ((y+height >= view.top) && (y+height <= view.bottom))) &&
    11311249        (x >= view.left) && (x <= view.right))
    11321250    {
    1133       item->visible     = TRUE;
     1251      item->visible = TRUE;
    11341252      if (!infoPtr->firstVisible)
    11351253        infoPtr->firstVisible = item->hItem;
    1136     } else item->visible    = FALSE;
     1254    } else item->visible = FALSE;
    11371255
    11381256    /* look up next item */
     
    11431261      indent++;
    11441262      x += infoPtr->uIndent;
    1145       if (x > infoPtr->uTotalWidth)
    1146         infoPtr->uTotalWidth=x;
     1263      infoPtr->uTotalWidth = MAX(infoPtr->uTotalWidth,itemWidth+x);
    11471264    } else
    11481265    {
     
    11521269        indent--;
    11531270        x -= infoPtr->uIndent;
    1154         prevItem = item;
    1155         item =& infoPtr->items[(INT)item->parent];
     1271        item = &infoPtr->items[(INT)item->parent];
    11561272        iItem = (INT)item->sibling;
    11571273      }
     
    11621278  if (ownDC) ReleaseDC(hwnd,hdc);
    11631279
    1164 /* FIXME: infoPtr->uTotalWidth should also take item label into account */
     1280  infoPtr->uInternalStatus &= ~TV_CALCALL;
    11651281
    11661282  infoPtr->uTotalHeight = y;
    1167 
    1168   infoPtr->uInternalStatus &= ~TV_CALCALL;
    1169 
    1170 //CB: todo: use SetScrollInfo, HSCROLL
    1171 
    1172   if (infoPtr->uTotalHeight >= infoPtr->uVisibleHeight)
    1173   {
    1174     if (!(infoPtr->uInternalStatus & TV_VSCROLL))
    1175       ShowScrollBar (hwnd, SB_VERT, TRUE);
    1176     infoPtr->uInternalStatus |= TV_VSCROLL;
    1177     SetScrollRange (hwnd, SB_VERT, 0, infoPtr->uTotalHeight - infoPtr->uVisibleHeight, FALSE);
    1178     SetScrollPos (hwnd, SB_VERT, infoPtr->cy, TRUE);
     1283infoPtr->uTotalWidth = 0; //CB: not yet ready
     1284
     1285  if (!(dwStyle & TVS_NOSCROLL))
     1286  {
     1287    if (infoPtr->uTotalHeight >= infoPtr->uVisibleHeight)
     1288    {
     1289      SCROLLINFO info;
     1290
     1291      info.cbSize = sizeof(info);
     1292      info.nMin   = 0;
     1293      info.nMax   = infoPtr->uTotalHeight-1;
     1294      info.nPos   = infoPtr->cy;
     1295      info.nPage  = MAX(infoPtr->uVisibleHeight,1);
     1296      info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
     1297      infoPtr->uInternalStatus |= TV_VSCROLL;
     1298      SetScrollInfo(hwnd,SB_VERT,&info,TRUE);
     1299    } else
     1300    {
     1301      if (infoPtr->uInternalStatus & TV_VSCROLL)
     1302        ShowScrollBar(hwnd,SB_VERT,FALSE);
     1303      infoPtr->uInternalStatus &= ~TV_VSCROLL;
     1304    }
     1305    if (!(dwStyle & TVS_NOHSCROLL) && (infoPtr->uTotalWidth >= infoPtr->uVisibleWidth))
     1306    {
     1307      SCROLLINFO info;
     1308
     1309      info.cbSize = sizeof(info);
     1310      info.nMin   = 0;
     1311      info.nMax   = infoPtr->uTotalWidth-1;
     1312      info.nPos   = infoPtr->cx;
     1313      info.nPage  = MAX(infoPtr->uVisibleWidth,1);
     1314      info.fMask  = SIF_RANGE | SIF_POS | SIF_PAGE;
     1315      infoPtr->uInternalStatus |= TV_HSCROLL;
     1316      SetScrollInfo(hwnd,SB_HORZ,&info,TRUE);
     1317    } else
     1318    {
     1319      if (infoPtr->uInternalStatus & TV_HSCROLL)
     1320        ShowScrollBar(hwnd,SB_HORZ,FALSE);
     1321      infoPtr->uInternalStatus &= ~TV_HSCROLL;
     1322    }
    11791323  } else
    11801324  {
    1181     if (infoPtr->uInternalStatus & TV_VSCROLL)
    1182       ShowScrollBar (hwnd, SB_VERT, FALSE);
    1183     infoPtr->uInternalStatus &= ~TV_VSCROLL;
     1325    if (infoPtr->uInternalStatus & (TV_VSCROLL | TV_HSCROLL))
     1326      ShowScrollBar(hwnd,SB_BOTH,FALSE);
     1327    infoPtr->uInternalStatus &= ~(TV_VSCROLL | TV_HSCROLL);
    11841328  }
    11851329}
     
    11931337    TREEVIEW_ITEM *item;
    11941338    INT iItem,indent;
    1195     INT visIndent = -1;
     1339    BOOL visFound = FALSE;
     1340    HPEN hNewPen,hOldPen;
    11961341
    11971342    TREEVIEW_UnqueueRefresh(hwnd,TRUE,FALSE);
     
    12121357    //draw items
    12131358
     1359    hNewPen = CreatePen(PS_DOT,0,infoPtr->clrLine);
     1360
    12141361    iItem = (INT)infoPtr->TopRootItem;
    12151362    indent = 0;
     
    12181365    {
    12191366      item = &infoPtr->items[iItem];
    1220       /* FIXME: should query item sizes (ie check CDRF_NEWFONT) */
    12211367      if (item->visible)
    12221368      {
    1223         if (updateRect && IntersectRect(NULL,&item->rect,updateRect)) TREEVIEW_DrawItem(hwnd,hdc,item);
    1224         visIndent = indent;
    1225       } else if (visIndent != -1)
     1369        if (updateRect && IntersectRect(NULL,&item->rect,updateRect))
     1370        {
     1371          TREEVIEW_DrawItem(hwnd,hdc,item);
     1372          visFound = TRUE;
     1373        }
     1374      } else if (visFound) break;
     1375      if (!visFound)
    12261376      {
    12271377        //draw vertical connections
    1228 
    1229         if (visIndent == 0) break;
    1230 
    1231         if (indent < visIndent)
    1232         {
    1233 //CB: todo
    1234           visIndent = indent;
    1235         }
     1378        hOldPen = SelectObject(hdc,hNewPen);
     1379        TREEVIEW_DrawVLines(hdc,infoPtr,item);
     1380        SelectObject(hdc,hOldPen);
    12361381      }
    12371382      if ((item->firstChild) && (item->state & TVIS_EXPANDED))
     
    12511396    }
    12521397
     1398    DeleteObject(hNewPen);
     1399
    12531400    if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT)
    12541401      infoPtr->cdmode = TREEVIEW_SendCustomDrawNotify(hwnd, CDDS_POSTPAINT, hdc, rect);
     
    12921439                KillTimer (hwnd, TV_EDIT_TIMER);
    12931440                infoPtr->Timer &= ~TV_EDIT_TIMER_SET;
     1441                if (infoPtr->editItem)
     1442                   TREEVIEW_EditLabelA(hwnd, infoPtr->editItem);
    12941443                return 0;
    12951444        default:
     
    13481497
    13491498   if (tvItem->mask & TVIF_CHILDREN) {
    1350 //              if (TVIF_CHILDREN==I_CHILDRENCALLBACK)
    1351 //                      FIXME (treeview,"I_CHILDRENCALLBACK not supported\n");
    1352         tvItem->cChildren=wineItem->cChildren;
     1499      tvItem->cChildren = TREEVIEW_HasChildren(hwnd, wineItem);
    13531500   }
    13541501
     
    14131560  retval=0;
    14141561  switch (flag) {
     1562        case TVGN_CHILD: /* Special case: child of 0 is root */
     1563            if (iItem) break;
    14151564        case TVGN_ROOT: retval=(INT)infoPtr->TopRootItem;
    14161565                                        break;
     
    14471596                                        break;
    14481597        case TVGN_LASTVISIBLE:
    1449                                         returnItem=TREEVIEW_GetLastListItem (infoPtr,wineItem);
     1598                                        returnItem=TREEVIEW_GetLastListItem (hwnd,infoPtr,wineItem);
    14501599                                        break;
    14511600        case TVGN_NEXTVISIBLE:
    1452                                         returnItem=TREEVIEW_GetNextListItem (infoPtr,wineItem);
     1601                                        returnItem=TREEVIEW_GetNextListItem (hwnd,infoPtr,wineItem);
    14531602                                        break;
    14541603        case TVGN_PREVIOUSVISIBLE:
    1455                                         returnItem=TREEVIEW_GetPrevListItem (infoPtr, wineItem);
     1604                                        returnItem=TREEVIEW_GetPrevListItem (hwnd,infoPtr, wineItem);
    14561605                                        break;
    14571606        default:        //      FIXME (treeview,"Unknown msg %x,item %x\n", flag,iItem);
     
    16441793  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    16451794  TREEVIEW_ITEM *sortMe  = NULL; /* Node for which we sort the children */
     1795  INT            cChildren;
     1796  HTREEITEM      hti;
    16461797
    16471798  /* Obtain the TVSORTBC struct */
     
    16631814  sortMe = &infoPtr->items[ (INT)parent ];
    16641815
     1816  cChildren = 0;
     1817  for(hti = sortMe->firstChild; hti; hti = infoPtr->items[(INT)hti].sibling)
     1818      cChildren++;
     1819
    16651820  /* Make sure there is something to sort */
    1666   if ( sortMe->cChildren > 1 )
     1821  if ( cChildren > 1 )
    16671822  {
    16681823    /* pointer organization */
    1669     HDPA          sortList   = DPA_Create(sortMe->cChildren);
     1824    HDPA          sortList   = DPA_Create(cChildren);
    16701825    HTREEITEM     itemHandle = sortMe->firstChild;
    16711826    TREEVIEW_ITEM *itemPtr   = & infoPtr->items[ (INT)itemHandle ];
     
    16821837      DPA_InsertPtr(
    16831838        sortList,              /* the list */
    1684         sortMe->cChildren+1,   /* force the insertion to be an append */
     1839        cChildren+1,   /* force the insertion to be an append */
    16851840        itemPtr);              /* the ptr to store */
    16861841
     
    17921947  TVITEMEXA     *tvItem;
    17931948  TREEVIEW_ITEM *wineItem, *parentItem, *prevsib, *sibItem;
    1794   INT           iItem,listItems,i,len;
     1949  INT           iItem,i,len;
    17951950
    17961951  /* Item to insert */
     
    18011956  if (infoPtr->uNumPtrsAlloced==0) {
    18021957        infoPtr->items = COMCTL32_Alloc (TVITEM_ALLOC*sizeof (TREEVIEW_ITEM));
    1803         infoPtr->freeList= COMCTL32_Alloc ((1+(TVITEM_ALLOC>>5)) * sizeof (INT));
     1958        infoPtr->freeList= COMCTL32_Alloc (((TVITEM_ALLOC>>5)) * sizeof (INT));
    18041959        infoPtr->uNumPtrsAlloced=TVITEM_ALLOC;
    18051960        infoPtr->TopRootItem=(HTREEITEM)1;
     
    18151970        infoPtr->uNumPtrsAlloced*=2;
    18161971    infoPtr->items = COMCTL32_Alloc (infoPtr->uNumPtrsAlloced*sizeof (TREEVIEW_ITEM));
    1817     infoPtr->freeList= COMCTL32_Alloc ((1+(infoPtr->uNumPtrsAlloced>>5))*sizeof (INT));
     1972    infoPtr->freeList= COMCTL32_Alloc (((infoPtr->uNumPtrsAlloced>>5))*sizeof (INT));
    18181973
    18191974    memcpy (&infoPtr->items[0], &oldItems[0],
     
    18371992        for (i=0; i<infoPtr->uNumPtrsAlloced>>5; i++) {
    18381993                if (infoPtr->freeList[i]) {
    1839                         iItem=ffs (infoPtr->freeList[i])-1;
    1840 
     1994                        for(iItem = 0; iItem < 32; iItem++)
     1995                        {
     1996                           if(tv_test_bit(iItem, &infoPtr->freeList[i]))
     1997                              break;
     1998                        }
    18411999                        tv_clear_bit(iItem,&infoPtr->freeList[i]);
    18422000                        iItem+=i<<5;
     
    18462004  }
    18472005
    1848 //  if (TRACE_ON(treeview)) {
    1849 //    for (i=0; i<infoPtr->uNumPtrsAlloced>>5; i++)
    1850 //          TRACE (treeview,"%8x\n",infoPtr->freeList[i]);
    1851 //  }
    1852 
    1853 //  if (!iItem) ERR (treeview, "Argh -- can't find free item.\n");
    1854 
    18552006  /*
    18562007   * Find the parent item of the new item
     
    18632014    wineItem->parent = 0;
    18642015    sibItem          = &infoPtr->items [(INT)infoPtr->TopRootItem];
    1865     listItems        = infoPtr->uNumItems;
    18662016  }
    18672017  else  {
     
    18742024        wineItem->parent = ptdi->hParent;
    18752025        sibItem          = &infoPtr->items [(INT)parentItem->firstChild];
    1876         parentItem->cChildren++;
    1877         listItems        = parentItem->cChildren;
    18782026  }
    18792027
     
    18922040    if (tvItem->pszText!=LPSTR_TEXTCALLBACKA)
    18932041    {
    1894 //      TRACE (treeview,"(%p,%s)\n", &tvItem->pszText, tvItem->pszText);
     2042      //TRACE (treeview,"(%p,%s)\n", &tvItem->pszText, tvItem->pszText);
    18952043      len = lstrlenA (tvItem->pszText)+1;
    1896       wineItem->pszText= COMCTL32_Alloc (len+1);
     2044      wineItem->pszText= COMCTL32_Alloc (len);
    18972045      lstrcpyA (wineItem->pszText, tvItem->pszText);
    18982046      wineItem->cchTextMax=len;
     
    19002048    else
    19012049    {
    1902 //      TRACE (treeview,"LPSTR_TEXTCALLBACK\n");
     2050      //TRACE (treeview,"LPSTR_TEXTCALLBACK\n");
    19032051      wineItem->pszText = LPSTR_TEXTCALLBACKA;
    19042052      wineItem->cchTextMax = 0;
     
    19152063  wineItem->hItem=(HTREEITEM)iItem;
    19162064
    1917   if (listItems>1) {
     2065  if (sibItem != wineItem) {
    19182066     prevsib=NULL;
    19192067
    19202068     switch ((DWORD) ptdi->hInsertAfter) {
    19212069                case (DWORD) TVI_FIRST:
    1922                         if (sibItem==wineItem) break;
    19232070                        if (wineItem->parent) {
    19242071                                wineItem->sibling=parentItem->firstChild;
     
    19312078                        break;
    19322079
    1933                 case (DWORD) TVI_SORT:
    1934           if (sibItem==wineItem)
    1935         /*
    1936          * This item is the first child of the level and it
    1937          * has already been inserted
    1938          */
    1939         break;
    1940       else
     2080      case (DWORD) TVI_SORT:
    19412081      {
    19422082        TREEVIEW_ITEM *aChild;
     
    20062146
    20072147                case (DWORD) TVI_LAST:
    2008                         if (sibItem==wineItem) break;
     2148            TVI_LAST_CASE:
    20092149                        while (sibItem->sibling) {
    20102150                                prevsib=sibItem;
     
    20212161              }
    20222162                        if (sibItem->hItem!=ptdi->hInsertAfter) {
    2023 //                       ERR (treeview, "tried to insert item after nonexisting handle.\n");
    2024                          break;
     2163                          goto TVI_LAST_CASE;
    20252164                        }
    20262165                        prevsib=sibItem;
     
    20372176
    20382177
    2039 /* Fill in info structure */
    2040 
    2041 //   TRACE (treeview,"new item %d; parent %d, mask %x\n", iItem,
    2042 //                      (INT)wineItem->parent,tvItem->mask);
     2178   /* Fill in info structure */
    20432179
    20442180   wineItem->mask=tvItem->mask;
    20452181   wineItem->iIntegral=1;
    20462182
    2047    if (tvItem->mask & TVIF_CHILDREN) {
    2048          wineItem->cChildren=tvItem->cChildren;
    2049 //       if (tvItem->cChildren==I_CHILDRENCALLBACK)
    2050 //                      FIXME (treeview," I_CHILDRENCALLBACK not supported\n");
    2051         }
     2183   if (tvItem->mask & TVIF_CHILDREN)
     2184     wineItem->cChildren=tvItem->cChildren;
     2185
    20522186
    20532187  wineItem->expandBox.left   = 0; /* Initialize the expandBox */
     
    20552189  wineItem->expandBox.right  = 0;
    20562190  wineItem->expandBox.bottom = 0;
    2057   wineItem->calculated = FALSE;
    20582191
    20592192   if (tvItem->mask & TVIF_IMAGE)
     
    20702203
    20712204   if (tvItem->mask & TVIF_STATE) {
    2072 //     TRACE(treeview, "Changing item state from %d to %d\n",
    2073 //       wineItem->state,
    2074 //       tvItem->state);
    20752205        wineItem->state=tvItem->state;
    20762206        wineItem->stateMask=tvItem->stateMask;
    20772207   }
    20782208
     2209   wineItem->calculated = FALSE;
    20792210   TREEVIEW_QueueRefresh(hwnd);
    20802211
     
    22262357                                                        LPARAM lParam)
    22272358{
     2359  BOOL bCancel = FALSE;
     2360  static BOOL bIgnoreKillFocus = FALSE;
     2361
    22282362  switch (uMsg)
    22292363  {
    2230     case WM_ERASEBKGND:
    2231     {
    2232       RECT rc;
    2233       HDC  hdc = (HDC) wParam;
    2234       GetClientRect (hwnd, &rc);
    2235       Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
    2236       return -1;
    2237     }
     2364    case WM_PAINT:
     2365        {
     2366          LRESULT rc;
     2367          TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(GetParent(hwnd));
     2368          TRACE("WM_PAINT start\n");
     2369          rc = CallWindowProcA( infoPtr->wpEditOrig, hwnd, uMsg, wParam, lParam);
     2370          TRACE("WM_PAINT done\n");
     2371          return rc;
     2372        }
     2373
     2374    case WM_KILLFOCUS:
     2375        if(bIgnoreKillFocus)
     2376        {
     2377            return TRUE;
     2378        }
     2379        break;
    22382380
    22392381    case WM_GETDLGCODE:
    2240     {
    22412382      return DLGC_WANTARROWS | DLGC_WANTALLKEYS;
    2242     }
     2383
     2384    case WM_KEYDOWN:
     2385        if (VK_ESCAPE == (INT)wParam)
     2386        {
     2387            bCancel = TRUE;
     2388            break;
     2389        }
     2390        else if (VK_RETURN == (INT)wParam)
     2391        {
     2392            break;
     2393        }
    22432394
    22442395    default:
     
    22542405  }
    22552406
     2407  /* Processing LVN_ENDLABELEDIT message could kill the focus       */
     2408  /* eg. Using a messagebox                                         */
     2409  bIgnoreKillFocus = TRUE;
     2410  TREEVIEW_EndEditLabelNow(GetParent(hwnd), bCancel);
     2411  bIgnoreKillFocus = FALSE;
     2412
    22562413  return 0;
    22572414}
    22582415
    2259 
    22602416/* should handle edit control messages here */
    22612417
     
    22642420
    22652421{
    2266 //  TRACE (treeview, "%x %ld\n",wParam, lParam);
    2267 
    22682422  switch (HIWORD(wParam))
    22692423  {
    2270                 case EN_UPDATE:
     2424    case EN_UPDATE:
    22712425    {
    22722426      /*
    22732427       * Adjust the edit window size
    22742428       */
     2429      char buffer[1024];
    22752430      TREEVIEW_INFO *infoPtr  = TREEVIEW_GetInfoPtr(hwnd);
    22762431      TREEVIEW_ITEM *editItem = TREEVIEW_ValidItem(infoPtr, infoPtr->editItem);
    2277       INT           iLength   = GetWindowTextLengthA(infoPtr->hwndEdit);
    22782432      HDC           hdc       = GetDC(infoPtr->hwndEdit);
    2279       TEXTMETRICA   tm;
    2280 
    2281       if ( GetTextMetricsA(hdc, &tm) )
     2433      SIZE          sz;
     2434      int           len;
     2435      HFONT         hFont, hOldFont=0;
     2436
     2437      len = GetWindowTextA(infoPtr->hwndEdit, buffer, 1024);
     2438
     2439      /* Select font to get the right dimension of the string */
     2440      hFont = SendMessageA(infoPtr->hwndEdit, WM_GETFONT, 0, 0);
     2441      if(hFont != 0)
    22822442      {
    2283         LONG newWidth = (iLength * tm.tmAveCharWidth) + 15;
    2284 
    2285                 SetWindowPos (
    2286           infoPtr->hwndEdit,
    2287           HWND_TOP,
    2288           editItem->text.left - 2,
    2289           editItem->text.top  - 1,
    2290           newWidth,
    2291           editItem->text.bottom - editItem->text.top  + 3,
    2292           SWP_DRAWFRAME );
     2443          hOldFont = SelectObject(hdc, hFont);
    22932444      }
     2445
     2446      if (GetTextExtentPoint32A(hdc, buffer, strlen(buffer), &sz))
     2447      {
     2448          TEXTMETRICA textMetric;
     2449          /* Add Extra spacing for the next character */
     2450          GetTextMetricsA(hdc, &textMetric);
     2451          sz.cx += (textMetric.tmMaxCharWidth * 2);
     2452
     2453          SetWindowPos (
     2454            infoPtr->hwndEdit,
     2455            HWND_TOP,
     2456            0,
     2457            0,
     2458            sz.cx,
     2459            editItem->text.bottom - editItem->text.top + 3,
     2460            SWP_NOMOVE|SWP_DRAWFRAME);
     2461      }
     2462
     2463      if(hFont != 0)
     2464      {
     2465          SelectObject(hdc, hOldFont);
     2466      }
     2467
    22942468      ReleaseDC(hwnd, hdc);
    2295 
    22962469      break;
    22972470    }
    2298 
    2299     case EN_KILLFOCUS:
    2300 /*      TREEVIEW_EndEditLabelNow(hwnd, (WPARAM)FALSE, 0);
    2301 */
    2302       break;
    23032471
    23042472    default:
     
    23772545    infoPtr->uNumItems=0;
    23782546    infoPtr->clrBk   = GetSysColor (COLOR_WINDOW);
    2379     infoPtr->clrText = GetSysColor (COLOR_WINDOWTEXT);
    23802547    infoPtr->clrLine = GetSysColor (COLOR_WINDOWTEXT);
    23812548    infoPtr->clrInsertMark = GetSysColor (COLOR_BTNTEXT);
     
    23852552    infoPtr->himlNormal = NULL;
    23862553    infoPtr->himlState = NULL;
    2387         infoPtr->uItemHeight = -1;
     2554    infoPtr->uItemHeight = -1;
    23882555    GetTextMetricsA (hdc, &tm);
    23892556    infoPtr->hFont = GetStockObject (DEFAULT_GUI_FONT);
    2390         GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
    2391         logFont.lfWeight=FW_BOLD;
     2557    GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
     2558    logFont.lfWeight=FW_BOLD;
    23922559    infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
    23932560
    23942561    infoPtr->items = NULL;
    2395     infoPtr->selectedItem=0;
     2562    infoPtr->selectedItem = 0;
    23962563    infoPtr->clrText=-1;        /* use system color */
    23972564    infoPtr->dropItem=0;
    2398         infoPtr->insertMarkItem=0;
    2399         infoPtr->insertBeforeorAfter=0;
     2565    infoPtr->insertMarkItem=0;
     2566    infoPtr->insertBeforeorAfter=0;
    24002567    infoPtr->pCallBackSort=NULL;
    24012568    infoPtr->uScrollTime = 300;  /* milliseconds */
    2402         infoPtr->wpEditOrig = NULL; /* we haven't subclassed anything yet */
    2403         infoPtr->hwndToolTip=0;
     2569    infoPtr->hwndEdit = 0;
     2570
     2571/*
     2572    infoPtr->hwndNotify = GetParent32 (hwnd);
     2573    infoPtr->bTransparent = ( GetWindowLongA( hwnd, GWL_STYLE) & TBSTYLE_FLAT);
     2574*/
     2575
     2576    infoPtr->hwndToolTip=0;
    24042577    if (!(dwStyle & TVS_NOTOOLTIPS)) {   /* Create tooltip control */
    24052578                TTTOOLINFOA ti;
     
    24342607        SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
    24352608    }
    2436 
    2437         infoPtr->hwndEdit = CreateWindowExA (
    2438                           WS_EX_LEFT,
    2439                           "EDIT",
    2440                           0,
    2441                           WS_CHILD | WS_BORDER | ES_AUTOHSCROLL |
    2442                           ES_WANTRETURN | ES_LEFT,
    2443                           0, 0, 0, 0,
    2444                           hwnd,
    2445                           0,0,0); /* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0);*/
    2446 
    2447   SendMessageA ( infoPtr->hwndEdit, WM_SETFONT, infoPtr->hFont, FALSE);
    2448         infoPtr->wpEditOrig = (WNDPROC)SetWindowLongA (
    2449                                     infoPtr->hwndEdit,
    2450                                     GWL_WNDPROC,
    2451                                                                 (LONG) TREEVIEW_Edit_SubclassProc);
    24522609
    24532610  if (dwStyle & TVS_CHECKBOXES) {
     
    24782635
    24792636   TREEVIEW_RemoveTree (hwnd);
    2480    SetWindowLongA( hwnd, 0, (DWORD)NULL);
    24812637   if (infoPtr->Timer & TV_REFRESH_TIMER_SET)
    24822638     KillTimer (hwnd, TV_REFRESH_TIMER);
     
    24842640     DestroyWindow (infoPtr->hwndToolTip);
    24852641
     2642   /* Restore original windproc so that we can free infoPtr */
     2643   if (infoPtr->hwndEdit)
     2644   SetWindowLongA (infoPtr->hwndEdit, GWL_WNDPROC, (DWORD)infoPtr->wpEditOrig);
     2645
     2646   DeleteObject(infoPtr->hBoldFont);
    24862647   COMCTL32_Free (infoPtr);
    24872648
     
    24962657    PAINTSTRUCT ps;
    24972658
    2498 //    TRACE (treeview,"\n");
    24992659    hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
    25002660    TREEVIEW_Draw(hwnd,hdc,&ps.rcPaint);
    25012661    if(!wParam)
    25022662        EndPaint (hwnd, &ps);
    2503 //    TRACE (treeview,"done\n");
    2504 
    2505     return DefWindowProcA (hwnd, WM_PAINT, wParam, lParam);
     2663
     2664    return 0;
    25062665}
    25072666
     
    25092668TREEVIEW_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
    25102669{
    2511    TREEVIEW_SendSimpleNotify (hwnd, NM_SETFOCUS);
    2512 
    2513    //CB: todo: focus item
    2514 
    2515    return 0;
     2670  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     2671
     2672  TREEVIEW_SendSimpleNotify (hwnd, NM_SETFOCUS);
     2673
     2674  if (infoPtr->selectedItem) TREEVIEW_RefreshItem(hwnd,TREEVIEW_ValidItem(infoPtr,infoPtr->selectedItem));
     2675
     2676  return 0;
    25162677}
    25172678
     
    25192680TREEVIEW_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
    25202681{
    2521    TREEVIEW_SendSimpleNotify (hwnd, NM_KILLFOCUS);
    2522 
    2523    //CB: todo: focus item
    2524 
    2525    return 0;
     2682  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     2683
     2684  TREEVIEW_SendSimpleNotify (hwnd, NM_KILLFOCUS);
     2685
     2686  if (infoPtr->selectedItem) TREEVIEW_RefreshItem(hwnd,TREEVIEW_ValidItem(infoPtr,infoPtr->selectedItem));
     2687
     2688  return 0;
    25262689}
    25272690
     
    25402703}
    25412704
    2542 
    2543 
    2544 
    2545 
    2546 
    25472705/* Notifications */
    2548 
    2549 
    2550 
    2551 
    25522706
    25532707static BOOL
     
    25652719}
    25662720
    2567 
    2568 
    25692721static BOOL
    25702722TREEVIEW_SendTreeviewNotify (HWND hwnd, UINT code, UINT action,
     
    25782730//  TRACE (treeview,"code:%x action:%x olditem:%x newitem:%x\n",
    25792731//                code,action,(INT)oldItem,(INT)newItem);
     2732
     2733  ZeroMemory(&nmhdr, sizeof(NMTREEVIEWA));
     2734
    25802735  nmhdr.hdr.hwndFrom = hwnd;
    25812736  nmhdr.hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
     
    26512806
    26522807static BOOL
    2653 TREEVIEW_SendDispInfoNotify (HWND hwnd, TREEVIEW_ITEM *wineItem,
    2654                                                                 UINT code, UINT what)
     2808TREEVIEW_SendDispInfoNotify (HWND hwnd, TREEVIEW_ITEM *wineItem, UINT code, UINT what)
    26552809{
    26562810  NMTVDISPINFOA tvdi;
     
    26792833                  (WPARAM)tvdi.hdr.idFrom,
    26802834                  (LPARAM)&tvdi);
     2835
     2836  /* Ignore posible changes */
     2837  if (code == TVN_BEGINLABELEDIT)
     2838      return retval;
    26812839
    26822840  if (what & TVIF_TEXT) {
     
    27422900                        TREEVIEW_ITEM *wineItem, UINT uItemDrawState)
    27432901{
    2744  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    2745  NMTVCUSTOMDRAW nmcdhdr;
    2746  LPNMCUSTOMDRAW nmcd;
    2747  DWORD dwDrawStage,dwItemSpec;
    2748  UINT uItemState;
    2749  INT retval;
    2750 
    2751  dwDrawStage=CDDS_ITEM | uItemDrawState;
    2752  dwItemSpec=(DWORD)wineItem->hItem;
    2753  uItemState=0;
    2754  if (wineItem->hItem==infoPtr->selectedItem) uItemState|=CDIS_SELECTED;
    2755  if (wineItem->hItem==infoPtr->focusItem)        uItemState|=CDIS_FOCUS;
    2756  if (wineItem->hItem==infoPtr->hotItem)      uItemState|=CDIS_HOT;
    2757 
    2758  nmcd= & nmcdhdr.nmcd;
    2759  nmcd->hdr.hwndFrom = hwnd;
    2760  nmcd->hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
    2761  nmcd->hdr.code   = NM_CUSTOMDRAW;
    2762  nmcd->dwDrawStage= dwDrawStage;
    2763  nmcd->hdc                = hdc;
    2764  nmcd->rc.left    = wineItem->rect.left;
    2765  nmcd->rc.right   = wineItem->rect.right;
    2766  nmcd->rc.bottom  = wineItem->rect.bottom;
    2767  nmcd->rc.top     = wineItem->rect.top;
    2768  nmcd->dwItemSpec = dwItemSpec;
    2769  nmcd->uItemState = uItemState;
    2770  nmcd->lItemlParam= wineItem->lParam;
    2771 
    2772  nmcdhdr.clrText  = infoPtr->clrText;
    2773  nmcdhdr.clrTextBk= infoPtr->clrBk;
    2774  nmcdhdr.iLevel   = wineItem->iLevel;
    2775 
    2776 // TRACE (treeview,"drawstage:%lx hdc:%x item:%lx, itemstate:%x\n",
    2777 //                dwDrawStage, hdc, dwItemSpec, uItemState);
    2778 
    2779  retval=SendMessageA (GetParent (hwnd), WM_NOTIFY,
     2902  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     2903  NMTVCUSTOMDRAW nmcdhdr;
     2904  LPNMCUSTOMDRAW nmcd;
     2905  DWORD dwDrawStage,dwItemSpec;
     2906  UINT uItemState;
     2907  INT retval;
     2908
     2909  dwDrawStage=CDDS_ITEM | uItemDrawState;
     2910  dwItemSpec=(DWORD)wineItem->hItem;
     2911  uItemState=0;
     2912  if (wineItem->hItem == infoPtr->selectedItem)
     2913  {
     2914    uItemState|=CDIS_SELECTED;
     2915    if (GetFocus() == hwnd) uItemState |= CDIS_FOCUS;
     2916  }
     2917  if (wineItem->hItem==infoPtr->hotItem)      uItemState|=CDIS_HOT;
     2918
     2919  nmcd= & nmcdhdr.nmcd;
     2920  nmcd->hdr.hwndFrom = hwnd;
     2921  nmcd->hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
     2922  nmcd->hdr.code   = NM_CUSTOMDRAW;
     2923  nmcd->dwDrawStage= dwDrawStage;
     2924  nmcd->hdc                = hdc;
     2925  nmcd->rc.left    = wineItem->rect.left;
     2926  nmcd->rc.right   = wineItem->rect.right;
     2927  nmcd->rc.bottom  = wineItem->rect.bottom;
     2928  nmcd->rc.top     = wineItem->rect.top;
     2929  nmcd->dwItemSpec = dwItemSpec;
     2930  nmcd->uItemState = uItemState;
     2931  nmcd->lItemlParam= wineItem->lParam;
     2932
     2933  nmcdhdr.clrText  = infoPtr->clrText;
     2934  nmcdhdr.clrTextBk= infoPtr->clrBk;
     2935  nmcdhdr.iLevel   = wineItem->iLevel;
     2936
     2937  //TRACE (treeview,"drawstage:%lx hdc:%x item:%lx, itemstate:%x\n",
     2938  //               dwDrawStage, hdc, dwItemSpec, uItemState);
     2939
     2940  retval=SendMessageA (GetParent (hwnd), WM_NOTIFY,
    27802941                 (WPARAM) GetWindowLongA( hwnd, GWL_ID), (LPARAM)&nmcdhdr);
    27812942
    2782  infoPtr->clrText=nmcdhdr.clrText;
    2783  infoPtr->clrBk  =nmcdhdr.clrTextBk;
    2784  return (BOOL) retval;
     2943  infoPtr->clrText=nmcdhdr.clrText;
     2944  infoPtr->clrBk  =nmcdhdr.clrTextBk;
     2945
     2946  return (BOOL) retval;
    27852947}
    27862948
     
    28082970  if (!wineItem)
    28092971    return 0;
    2810   if (!wineItem->cChildren)
     2972
     2973  if (!TREEVIEW_HasChildren(hwnd, wineItem))
    28112974    return 0;
    28122975
     
    28162979//    expand,
    28172980//    wineItem->state);
    2818 
    2819   if (wineItem->cChildren==I_CHILDRENCALLBACK) {
    2820     //FIXME (treeview,"we don't handle I_CHILDRENCALLBACK yet\n");
    2821     return 0;
    2822   }
    28232981
    28242982  if (flag == TVE_TOGGLE) {    /* FIXME: check exact behaviour here */
     
    29193077  //CB: todo: optimize!
    29203078  TREEVIEW_UnqueueRefresh(hwnd,FALSE,FALSE);
     3079  //CB: todo: precalc expanded items here
     3080  infoPtr->uInternalStatus |= TV_CALCALL;
    29213081  TREEVIEW_CalcItems(hwnd,0,infoPtr);
    29223082  TREEVIEW_Refresh(hwnd);
     
    29413101
    29423102 while ((wineItem!=NULL) && (pt.y > wineItem->rect.bottom))
    2943        wineItem=TREEVIEW_GetNextListItem (infoPtr,wineItem);
     3103       wineItem=TREEVIEW_GetNextListItem (hwnd,infoPtr,wineItem);
    29443104
    29453105 if (!wineItem)
     
    29483108 return wineItem;
    29493109}
    2950 
    2951 
    2952 
    29533110
    29543111static LRESULT
     
    29603117  UINT status,x,y;
    29613118
     3119  lpht->hItem = 0;
    29623120  GetClientRect (hwnd, &rect);
    29633121  status=0;
     
    30133171}
    30143172
     3173HWND TREEVIEW_EditLabelA(HWND hwnd, HTREEITEM hItem)
     3174{
     3175  SIZE sz;
     3176  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     3177  TREEVIEW_ITEM *editItem = TREEVIEW_ValidItem(infoPtr, (HTREEITEM)hItem);
     3178  HINSTANCE hinst = GetWindowLongA(hwnd, GWL_HINSTANCE);
     3179
     3180  HDC hdc;
     3181  HFONT hOldFont=0;
     3182  TEXTMETRICA textMetric;
     3183
     3184  //TRACE("%d %d\n",(INT)hwnd, (INT)hItem);
     3185        if (!editItem)
     3186                return FALSE;
     3187
     3188  if(infoPtr->hwndEdit)
     3189    return infoPtr->hwndEdit;
     3190
     3191        /* Make shure that edit item is selected */
     3192  TREEVIEW_DoSelectItem ( hwnd, TVGN_CARET, hItem, TVC_UNKNOWN);
     3193  //CB: todo: necessary?
     3194  TREEVIEW_Refresh(hwnd);
     3195
     3196  if (editItem->pszText== LPSTR_TEXTCALLBACKA)
     3197                TREEVIEW_SendDispInfoNotify (hwnd, editItem, TVN_GETDISPINFO, TVIF_TEXT);
     3198
     3199  hdc = GetDC(hwnd);
     3200    /* Select the font to get appropriate metric dimensions */
     3201  if(infoPtr->hFont != 0)
     3202  {
     3203      hOldFont = SelectObject(hdc, infoPtr->hFont);
     3204  }
     3205
     3206  /*Get String Lenght in pixels */
     3207  GetTextExtentPoint32A(hdc, editItem->pszText, strlen(editItem->pszText), &sz);
     3208
     3209  /*Add Extra spacing for the next character */
     3210  GetTextMetricsA(hdc, &textMetric);
     3211  sz.cx += (textMetric.tmMaxCharWidth * 2);
     3212
     3213  if(infoPtr->hFont != 0)
     3214  {
     3215      SelectObject(hdc, hOldFont);
     3216  }
     3217
     3218  ReleaseDC(hwnd, hdc);
     3219  infoPtr->hwndEdit = CreateWindowExA (
     3220                         WS_EX_LEFT,
     3221                         "EDIT",
     3222                          0,
     3223                         WS_CHILD | WS_BORDER | ES_AUTOHSCROLL | WS_CLIPSIBLINGS |
     3224                         ES_WANTRETURN | ES_LEFT,
     3225                         editItem->text.left - 2, editItem->text.top  - 1,
     3226                         sz.cx+3, editItem->text.bottom - editItem->text.top  + 3,
     3227                         hwnd,
     3228                         0,hinst,0); /* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0);*/
     3229
     3230  SendMessageA ( infoPtr->hwndEdit, WM_SETFONT, infoPtr->hFont, FALSE);
     3231  infoPtr->wpEditOrig = (WNDPROC)SetWindowLongA (
     3232                                   infoPtr->hwndEdit,
     3233                                   GWL_WNDPROC,
     3234                  (DWORD) TREEVIEW_Edit_SubclassProc);
     3235
     3236  if (TREEVIEW_SendDispInfoNotify (hwnd, editItem, TVN_BEGINLABELEDIT,
     3237           editItem->mask & (TVIF_HANDLE|TVIF_TEXT|TVIF_STATE|TVIF_PARAM)))
     3238  {
     3239     DestroyWindow(infoPtr->hwndEdit);
     3240     infoPtr->hwndEdit = 0;
     3241     return (HWND)0;
     3242  }
     3243
     3244  infoPtr->editItem = hItem;
     3245  SetWindowTextA(infoPtr->hwndEdit, editItem->pszText);
     3246  SetFocus(infoPtr->hwndEdit);
     3247  SendMessageA(infoPtr->hwndEdit, EM_SETSEL, 0, -1);
     3248  ShowWindow(infoPtr->hwndEdit, SW_SHOW);
     3249
     3250  return infoPtr->hwndEdit;
     3251}
     3252
     3253
    30153254LRESULT WINAPI
    3016 TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam)
     3255TREEVIEW_EndEditLabelNow (HWND hwnd, BOOL bCancel)
    30173256{
    30183257  TREEVIEW_INFO *infoPtr    = TREEVIEW_GetInfoPtr(hwnd);
    30193258  TREEVIEW_ITEM *editedItem = TREEVIEW_ValidItem (infoPtr, infoPtr->editItem);
    3020   BOOL          bRevert     = (BOOL)wParam;
    3021   BOOL          bReturn     = ! bRevert;
    3022 
    3023   if ( ! (BOOL)wParam ) /* wParam is set to true to cancel the edition */
    3024   {
    3025                 if ( TREEVIEW_SendDispInfoNotify(  /* return true to cancel edition */
    3026            hwnd,
    3027            editedItem,
    3028            TVN_ENDLABELEDIT,
    3029            0))
    3030     {
    3031       bRevert = TRUE;
    3032       bReturn = FALSE;
    3033     }
    3034   }
    3035 
    3036   if (bRevert == FALSE) /* Apply the changes */
    3037   {
    3038     char tmpText[1024];
    3039     int  iLength = GetWindowTextA(infoPtr->hwndEdit, tmpText, 1023);
    3040     bReturn      = FALSE;
    3041 
    3042     if (iLength == 0)
    3043     {
    3044 //      ERR( treeview, "Problem retreiving new item label.");
    3045     }
    3046     else if (iLength >= 1023)
    3047     {
    3048 //      ERR( treeview,
    3049 //        "Insuficient space to retrieve new item label, new label ignored.");
    3050     }
    3051     else
    3052     {
    3053       if (strcmp( tmpText, editedItem->pszText ) == 0)
    3054         /* Do nothing if the label has not changed */
    3055         bReturn = TRUE;
    3056       else
     3259  NMTVDISPINFOA tvdi;
     3260  BOOL bCommit;
     3261  char tmpText[1024] = { '\0' };
     3262  int  iLength = 0;
     3263
     3264  if (!infoPtr->hwndEdit)
     3265     return FALSE;
     3266
     3267  tvdi.hdr.hwndFrom     = hwnd;
     3268  tvdi.hdr.idFrom       = GetWindowLongA(hwnd, GWL_ID);
     3269  tvdi.hdr.code         = TVN_ENDLABELEDIT;
     3270  tvdi.item.mask        = 0;
     3271  tvdi.item.hItem       = editedItem->hItem;
     3272  tvdi.item.state       = editedItem->state;
     3273  tvdi.item.lParam      = editedItem->lParam;
     3274
     3275  if (!bCancel)
     3276  {
     3277    iLength = GetWindowTextA(infoPtr->hwndEdit, tmpText, 1023);
     3278
     3279    //if (iLength >= 1023)
     3280    //{
     3281    //  ERR("Insuficient space to retrieve new item label.");
     3282    //}
     3283
     3284    tvdi.item.pszText = tmpText;
     3285    tvdi.item.cchTextMax  = iLength + 1;
     3286  }
     3287  else
     3288  {
     3289      tvdi.item.pszText = NULL;
     3290      tvdi.item.cchTextMax  = 0;
     3291  }
     3292
     3293  bCommit=(BOOL)SendMessageA (
     3294                  GetParent(hwnd),
     3295                  WM_NOTIFY,
     3296                  (WPARAM)tvdi.hdr.idFrom,
     3297                  (LPARAM)&tvdi);
     3298
     3299  if (!bCancel && bCommit) /* Apply the changes */
     3300  {
     3301      if (strcmp( tmpText, editedItem->pszText ) != 0)
    30573302      {
    3058         LPSTR tmpLabel = COMCTL32_Alloc( iLength+1 );
    3059 
    3060 //        if ( tmpLabel == NULL )
    3061 //          ERR( treeview,
    3062 //            "OutOfMemory, cannot allocate space for label");
    3063 //        else
     3303        if(NULL == COMCTL32_ReAlloc(editedItem->pszText, iLength+1 ))
    30643304        {
    3065           COMCTL32_Free(editedItem->pszText);
    3066           editedItem->pszText = tmpLabel;
    3067           lstrcpyA( editedItem->pszText, tmpText);
    3068           bReturn = TRUE;
     3305          //ERR("OutOfMemory, cannot allocate space for label");
     3306          DestroyWindow(infoPtr->hwndEdit);
     3307          infoPtr->hwndEdit = 0;
     3308          return FALSE;
     3309        }
     3310        else
     3311        {
     3312           editedItem->cchTextMax = iLength + 1;
     3313           lstrcpyA( editedItem->pszText, tmpText);
    30693314        }
    30703315      }
    3071     }
    3072 
    3073                 ShowWindow(infoPtr->hwndEdit, SW_HIDE);
    3074                 EnableWindow(infoPtr->hwndEdit, FALSE);
    3075     infoPtr->editItem = 0;
    3076   }
    3077 
    3078   return bReturn;
    3079 }
    3080 
    3081 
     3316  }
     3317
     3318  ShowWindow(infoPtr->hwndEdit, SW_HIDE);
     3319  DestroyWindow(infoPtr->hwndEdit);
     3320  infoPtr->hwndEdit = 0;
     3321  infoPtr->editItem = 0;
     3322
     3323  return TRUE;
     3324}
     3325
     3326
     3327/***************************************************************************
     3328 * This is quite unusual piece of code, but that's how it's implemented in
     3329 * Windows.
     3330 */
     3331static LRESULT TREEVIEW_TrackMouse(HWND hwnd, POINT pt)
     3332{
     3333   INT cxDrag = GetSystemMetrics(SM_CXDRAG);
     3334   INT cyDrag = GetSystemMetrics(SM_CYDRAG);
     3335   RECT r;
     3336   MSG msg;
     3337
     3338   r.top    = pt.y - cyDrag;
     3339   r.left   = pt.x - cxDrag;
     3340   r.bottom = pt.y + cyDrag;
     3341   r.right  = pt.x + cxDrag;
     3342
     3343   SetCapture(hwnd);
     3344
     3345   while(1)
     3346   {
     3347      if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD))
     3348      {
     3349         if (msg.message == WM_MOUSEMOVE)
     3350         {
     3351            pt.x = (INT)LOWORD(msg.lParam);
     3352            pt.y = (INT)HIWORD(msg.lParam);
     3353            if (PtInRect(&r, pt))
     3354               continue;
     3355            else
     3356            {
     3357               ReleaseCapture();
     3358               return 1;
     3359            }
     3360         }
     3361         else if (msg.message >= WM_LBUTTONDOWN &&
     3362                  msg.message <= WM_RBUTTONDBLCLK)
     3363         {
     3364            break;
     3365         }
     3366
     3367         DispatchMessageA( &msg );
     3368      }
     3369
     3370      if (GetCapture() != hwnd)
     3371         return 0;
     3372   }
     3373
     3374   ReleaseCapture();
     3375   return 0;
     3376}
    30823377
    30833378static LRESULT
    30843379TREEVIEW_LButtonDoubleClick (HWND hwnd, WPARAM wParam, LPARAM lParam)
    30853380{
     3381  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    30863382  TREEVIEW_ITEM *wineItem;
    30873383  POINT pt;
    30883384
    3089 //  TRACE (treeview,"\n");
    30903385  pt.x = (INT)LOWORD(lParam);
    30913386  pt.y = (INT)HIWORD(lParam);
    30923387  SetFocus (hwnd);
    30933388
     3389  if (infoPtr->Timer & TV_EDIT_TIMER_SET)
     3390  {
     3391     /* If there is pending 'edit label' event - kill it now */
     3392     infoPtr->editItem = 0;
     3393     KillTimer (hwnd, TV_EDIT_TIMER);
     3394  }
     3395
    30943396  wineItem=TREEVIEW_HitTestPoint (hwnd, pt);
    30953397  if (!wineItem) return 0;
    3096 //  TRACE (treeview,"item %d \n",(INT)wineItem->hItem);
    30973398
    30983399  if (TREEVIEW_SendSimpleNotify (hwnd, NM_DBLCLK)!=TRUE) {     /* FIXME!*/
     
    31023403}
    31033404
    3104 
    31053405static LRESULT
    31063406TREEVIEW_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
    31073407{
    31083408  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    3109   INT iItem;
    31103409  TVHITTESTINFO ht;
     3410  BOOL bTrack;
     3411  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
     3412
     3413
     3414  /* If Edit control is active - kill it and return.
     3415   * The best way to do it is to set focus to itself.
     3416   * Edit control subclassed procedure will automatically call
     3417   * EndEditLabelNow.
     3418   */
     3419  if (infoPtr->hwndEdit)
     3420  {
     3421     SetFocus (hwnd);
     3422     return 0;
     3423  }
    31113424
    31123425  ht.pt.x = (INT)LOWORD(lParam);
    31133426  ht.pt.y = (INT)HIWORD(lParam);
    31143427
    3115   SetFocus (hwnd);
    3116   iItem=TREEVIEW_HitTest (hwnd, (LPARAM) &ht);
    3117 //  TRACE (treeview,"item %d \n",iItem);
    3118 
    3119   if (ht.flags & TVHT_ONITEMBUTTON) {
    3120     TREEVIEW_Expand (hwnd, (WPARAM) TVE_TOGGLE, (LPARAM) iItem);
    3121   }
    3122   else
    3123   {
    3124     infoPtr->uInternalStatus|=TV_LDRAG;
    3125   }
    3126 
    3127   return 0;
    3128 }
    3129 
    3130 static LRESULT
    3131 TREEVIEW_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
    3132 {
    3133   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    3134   INT           iItem;
    3135   TREEVIEW_ITEM *wineItem;
    3136   TVHITTESTINFO ht;
    3137 
    3138   ht.pt.x = (INT)LOWORD(lParam);
    3139   ht.pt.y = (INT)HIWORD(lParam);
    3140 
    3141   //TRACE("\n");
    3142 
    3143   /* Return true to cancel default behaviour */
    3144   if ( TREEVIEW_SendSimpleNotify (hwnd, NM_CLICK) )
    3145     return 0;
    3146 
    3147   /* Get the item */
    3148   iItem = TREEVIEW_HitTest (hwnd, (LPARAM) &ht);
    3149   //TRACE ("%d\n",iItem);
    3150   if (!iItem)
    3151     return 0;
    3152 
    3153   wineItem = TREEVIEW_ValidItem(infoPtr, (HTREEITEM)iItem);
    3154 
    3155   infoPtr->uInternalStatus &= ~(TV_LDRAG | TV_LDRAGGING);
     3428  TREEVIEW_HitTest (hwnd, (LPARAM) &ht);
     3429  //TRACE("item %d \n", (INT)ht.hItem);
     3430
     3431  bTrack = (ht.flags & TVHT_ONITEM) && !(dwStyle & TVS_DISABLEDRAGDROP);
     3432
     3433  /* Send NM_CLICK right away */
     3434  if (!bTrack)
     3435     if ( TREEVIEW_SendSimpleNotify (hwnd, NM_CLICK) )
     3436        goto setfocus;
     3437
     3438  if (ht.flags & TVHT_ONITEMBUTTON)
     3439  {
     3440     TREEVIEW_Expand (hwnd, (WPARAM) TVE_TOGGLE, (LPARAM) ht.hItem);
     3441     goto setfocus;
     3442  }
     3443  else if (bTrack)
     3444  {
     3445     if (TREEVIEW_TrackMouse(hwnd, ht.pt))
     3446     {
     3447        TREEVIEW_SendTreeviewDnDNotify (hwnd, TVN_BEGINDRAG, ht.hItem, ht.pt);
     3448        infoPtr->dropItem = ht.hItem;
     3449        return 0;
     3450     }
     3451  }
     3452
     3453  if(TREEVIEW_SendSimpleNotify (hwnd, NM_CLICK))
     3454     goto setfocus;
    31563455
    31573456  /*
     
    31593458   * and the click occured on the item label...
    31603459   */
    3161   if ( ( GetWindowLongA( hwnd, GWL_STYLE) & TVS_EDITLABELS ) &&
    3162        ( wineItem->state & TVIS_SELECTED ) &&
    3163        ( ht.flags & TVHT_ONITEMLABEL ))
    3164   {
    3165     if ( infoPtr->editItem == 0 ) /* If we are not curently editing */
    3166     {
    3167                 if ( TREEVIEW_SendDispInfoNotify(  /* Return true to cancel edition */
    3168               hwnd,
    3169               wineItem,
    3170               TVN_BEGINLABELEDIT,
    3171               0))
    3172       {
    3173         return 0;
     3460  if ( ( dwStyle & TVS_EDITLABELS ) &&
     3461       ( ht.flags & TVHT_ONITEMLABEL ) &&
     3462       ( infoPtr->selectedItem == ht.hItem ) )
     3463  {
     3464       if (infoPtr->Timer & TV_EDIT_TIMER_SET)
     3465          KillTimer (hwnd, TV_EDIT_TIMER);
     3466
     3467       infoPtr->editItem = ht.hItem;
     3468       SetTimer (hwnd, TV_EDIT_TIMER, GetDoubleClickTime(), 0);
     3469       infoPtr->Timer|=TV_EDIT_TIMER_SET;
    31743470      }
    3175 
    3176                 //TRACE("Edit started for %s.\n", wineItem->pszText);
    3177                 infoPtr->editItem = wineItem->hItem;
    3178 
    3179                 SetWindowPos (
    3180         infoPtr->hwndEdit,
    3181         HWND_TOP,
    3182         wineItem->text.left - 2,
    3183         wineItem->text.top  - 1,
    3184         wineItem->text.right  - wineItem->text.left + 20 ,
    3185         wineItem->text.bottom - wineItem->text.top  + 3,
    3186         SWP_DRAWFRAME );
    3187 
    3188                 SetWindowTextA( infoPtr->hwndEdit, wineItem->pszText );
    3189       SendMessageA  ( infoPtr->hwndEdit, EM_SETSEL, 0, -1 );
    3190                 SetFocus      ( infoPtr->hwndEdit);
    3191       ShowWindow    ( infoPtr->hwndEdit, SW_SHOW);
    3192     }
    3193   }
    3194   else if ( infoPtr->editItem != 0 ) /* If we are curently editing */
    3195   {
    3196     TREEVIEW_EndEditLabelNow(hwnd, (WPARAM)FALSE, 0);
    3197   }
    31983471  else if ( ht.flags & (TVHT_ONITEMLABEL | TVHT_ONITEMICON))
    31993472  {
    3200     TREEVIEW_DoSelectItem ( hwnd, TVGN_CARET, (HTREEITEM)iItem, TVC_BYMOUSE);
    3201   }
    3202 
    3203   if (ht.flags & TVHT_ONITEMSTATEICON) {
    3204         DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    3205 
    3206 
    3207         if (dwStyle & TVS_CHECKBOXES) {      /* TVS_CHECKBOXES requires _us_ */
    3208                         int state;                                       /* to toggle the current state */
     3473     TREEVIEW_DoSelectItem ( hwnd, TVGN_CARET, ht.hItem, TVC_BYMOUSE);
     3474  }
     3475  else if (ht.flags & TVHT_ONITEMSTATEICON)
     3476  {
     3477     if (dwStyle & TVS_CHECKBOXES)  /* TVS_CHECKBOXES requires _us_ */
     3478     {                              /* to toggle the current state  */
     3479        int state;
     3480        TREEVIEW_ITEM *wineItem;
     3481
     3482        wineItem = TREEVIEW_ValidItem(infoPtr, ht.hItem);
     3483
    32093484                        state=1-(wineItem->state>>12);
    32103485                        //TRACE ("state:%x\n", state);
     
    32123487                        wineItem->state|=state<<12;
    32133488                        //TRACE ("state:%x\n", wineItem->state);
    3214                         TREEVIEW_Refresh(hwnd);
    3215                 }
    3216   }
     3489                        //CB: todo: optimize
     3490                        TREEVIEW_QueueRefresh (hwnd);
     3491          }
     3492  }
     3493
     3494setfocus:
     3495  SetFocus (hwnd);
    32173496  return 0;
    32183497}
     
    32233502{
    32243503 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    3225 
    3226 // TRACE (treeview,"\n");
    3227  infoPtr->uInternalStatus|=TV_RDRAG;
    3228  return 0;
    3229 }
    3230 
    3231 static LRESULT
    3232 TREEVIEW_RButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
    3233 {
    3234  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    3235 
    3236 // TRACE (treeview,"\n");
    3237  if (TREEVIEW_SendSimpleNotify (hwnd, NM_RCLICK)) return 0;
    3238  infoPtr->uInternalStatus&= ~(TV_RDRAG | TV_RDRAGGING);
    3239  return 0;
    3240 }
    3241 
    3242 
    3243 static LRESULT
    3244 TREEVIEW_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
    3245 {
    3246  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    3247  TREEVIEW_ITEM *hotItem;
    3248  POINT pt;
    3249 
    3250  pt.x=(INT) LOWORD (lParam);
    3251  pt.y=(INT) HIWORD (lParam);
    3252  hotItem=TREEVIEW_HitTestPoint (hwnd, pt);
    3253  if (!hotItem) return 0;
    3254  infoPtr->focusItem=hotItem->hItem;
    3255 
    3256  if ( GetWindowLongA( hwnd, GWL_STYLE) & TVS_DISABLEDRAGDROP) return 0;
    3257 
    3258  if (infoPtr->uInternalStatus & TV_LDRAG) {
    3259         TREEVIEW_SendTreeviewDnDNotify (hwnd, TVN_BEGINDRAG, hotItem->hItem, pt);
    3260         infoPtr->uInternalStatus &= ~TV_LDRAG;
    3261         infoPtr->uInternalStatus |= TV_LDRAGGING;
    3262         infoPtr->dropItem=hotItem->hItem;
     3504   TVHITTESTINFO ht;
     3505
     3506   if (infoPtr->hwndEdit)
     3507   {
     3508      SetFocus(hwnd);
     3509      return 0;
     3510   }
     3511
     3512   ht.pt.x = (INT)LOWORD(lParam);
     3513   ht.pt.y = (INT)HIWORD(lParam);
     3514
     3515   TREEVIEW_HitTest (hwnd, (LPARAM) &ht);
     3516
     3517   if (TREEVIEW_TrackMouse(hwnd, ht.pt))
     3518   {
     3519      if (ht.hItem)
     3520      {
     3521         TREEVIEW_SendTreeviewDnDNotify (hwnd, TVN_BEGINRDRAG, ht.hItem, ht.pt);
     3522         infoPtr->dropItem = ht.hItem;
     3523      }
     3524   }
     3525   else
     3526   {
     3527      SetFocus(hwnd);
     3528      TREEVIEW_SendSimpleNotify (hwnd, NM_RCLICK);
     3529   }
     3530
    32633531        return 0;
    3264  }
    3265 
    3266  if (infoPtr->uInternalStatus & TV_RDRAG) {
    3267         TREEVIEW_SendTreeviewDnDNotify (hwnd, TVN_BEGINRDRAG, hotItem->hItem, pt);
    3268         infoPtr->uInternalStatus &= ~TV_RDRAG;
    3269         infoPtr->uInternalStatus |= TV_RDRAGGING;
    3270         infoPtr->dropItem=hotItem->hItem;
    3271         return 0;
    3272  }
    3273 
    3274  return 0;
    3275 }
    3276 
     3532}
    32773533
    32783534static LRESULT
     
    33923648        wineItem->state |=  TVIS_SELECTED;
    33933649
    3394       infoPtr->selectedItem=(HTREEITEM)newSelect;
     3650      infoPtr->selectedItem = (HTREEITEM)newSelect;
    33953651
    33963652      TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE);
     
    34713727  GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
    34723728  logFont.lfWeight=FW_BOLD;
     3729  DeleteObject(infoPtr->hBoldFont);
    34733730  infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
    34743731
     
    34963753static LRESULT
    34973754TREEVIEW_VScroll (HWND hwnd, WPARAM wParam, LPARAM lParam)
    3498 
    34993755{
    35003756  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     
    35043760//  TRACE (treeview,"wp %x, lp %lx\n", wParam, lParam);
    35053761  if (!infoPtr->uInternalStatus & TV_VSCROLL) return FALSE;
     3762
     3763  if(infoPtr->hwndEdit)
     3764    SetFocus(hwnd);
    35063765
    35073766  switch (LOWORD (wParam)) {
     
    35163775                        infoPtr->cy += infoPtr->uRealItemHeight;
    35173776                        if (infoPtr->cy > maxHeight)
    3518                                 infoPtr->cy = maxHeight;
     3777                          infoPtr->cy = maxHeight;
    35193778                        break;
    35203779        case SB_PAGEUP:
     
    35273786                        if (infoPtr->cy == maxHeight) return FALSE;
    35283787                        infoPtr->cy += infoPtr->uVisibleHeight;
    3529             if (infoPtr->cy > maxHeight)
    3530                 infoPtr->cy = maxHeight;
     3788                        if (infoPtr->cy > maxHeight)
     3789                          infoPtr->cy = maxHeight;
    35313790                        break;
    35323791        case SB_THUMBTRACK:
     
    35363795  }
    35373796
    3538   TREEVIEW_CalcItems(hwnd,0,infoPtr);
    3539   ScrollWindowEx(hwnd,0,lastPos-infoPtr->cy,NULL,NULL,0,NULL,SW_INVALIDATE);
     3797  if (lastPos != infoPtr->cy)
     3798  {
     3799    TREEVIEW_CalcItems(hwnd,0,infoPtr);
     3800    ScrollWindowEx(hwnd,0,lastPos-infoPtr->cy,NULL,NULL,0,NULL,SW_INVALIDATE);
     3801  }
    35403802
    35413803  return TRUE;
     
    35523814
    35533815  if (!infoPtr->uInternalStatus & TV_HSCROLL) return FALSE;
     3816
     3817  if(infoPtr->hwndEdit)
     3818    SetFocus(hwnd);
    35543819
    35553820  switch (LOWORD (wParam)) {
     
    35903855}
    35913856
     3857static LRESULT TREEVIEW_MouseWheel (HWND hwnd, WPARAM wParam, LPARAM lParam)
     3858{
     3859
     3860    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     3861    short gcWheelDelta = 0;
     3862    UINT pulScrollLines = 3;
     3863
     3864    if (wParam & (MK_SHIFT | MK_CONTROL))
     3865      return DefWindowProcA( hwnd, WM_MOUSEWHEEL, wParam, lParam );
     3866
     3867
     3868    SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
     3869
     3870    gcWheelDelta -= (short) HIWORD(wParam);
     3871    pulScrollLines *= (gcWheelDelta / WHEEL_DELTA);
     3872
     3873    if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines)
     3874    {
     3875        int wheelDy = pulScrollLines * infoPtr->uRealItemHeight;
     3876        int newDy = infoPtr->cy + wheelDy;
     3877        int maxDy = infoPtr->uTotalHeight - infoPtr->uVisibleHeight;
     3878
     3879        if (newDy > maxDy) newDy = maxDy;
     3880        if (newDy < 0) newDy = 0;
     3881
     3882        if (newDy == infoPtr->cy) return TRUE;
     3883
     3884        TREEVIEW_VScroll(hwnd, MAKEWPARAM(SB_THUMBTRACK,newDy),0);
     3885    }
     3886  return TRUE;
     3887}
    35923888
    35933889static LRESULT
     
    36143910 switch (wParam) {
    36153911        case VK_UP:
    3616                 newItem=TREEVIEW_GetPrevListItem (infoPtr, prevItem);
     3912                newItem=TREEVIEW_GetPrevListItem (hwnd,infoPtr, prevItem);
    36173913
    36183914                if (!newItem)
     
    36273923
    36283924        case VK_DOWN:
    3629                 newItem=TREEVIEW_GetNextListItem (infoPtr, prevItem);
     3925                newItem=TREEVIEW_GetNextListItem (hwnd,infoPtr, prevItem);
    36303926
    36313927                if (!newItem)
     
    36473943        case VK_END:
    36483944                newItem       = &infoPtr->items[(INT)infoPtr->TopRootItem];
    3649                 newItem       = TREEVIEW_GetLastListItem (infoPtr, newItem);
     3945                newItem       = TREEVIEW_GetLastListItem (hwnd,infoPtr, newItem);
    36503946    hNewSelection = newItem->hItem;
    36513947
     
    36563952
    36573953        case VK_LEFT:
    3658     if ( (prevItem->cChildren > 0) && (prevItem->state & TVIS_EXPANDED) )
     3954    if ( (prevItem->state & TVIS_EXPANDED) &&
     3955         TREEVIEW_HasChildren(hwnd, prevItem))
    36593956    {
    36603957      TREEVIEW_Expand(hwnd, TVE_COLLAPSE, prevSelect );
     
    36733970
    36743971        case VK_RIGHT:
    3675     if ( ( prevItem->cChildren > 0)  ||
    3676          ( prevItem->cChildren == I_CHILDRENCALLBACK))
     3972    if ( TREEVIEW_HasChildren(hwnd, prevItem) )
    36773973    {
    36783974      if (! (prevItem->state & TVIS_EXPANDED))
     
    37003996
    37013997                newItem=TREEVIEW_GetListItem(
     3998              hwnd,
    37023999              infoPtr,
    37034000              prevItem,
     
    37154012  case VK_NEXT:
    37164013                newItem=TREEVIEW_GetListItem(
     4014              hwnd,
    37174015              infoPtr,
    37184016              prevItem,
     
    38284126                return TREEVIEW_GetImageList (hwnd, wParam, lParam);
    38294127
    3830                 case TVM_SETIMAGELIST:
     4128        case TVM_SETIMAGELIST:
    38314129                return TREEVIEW_SetImageList (hwnd, wParam, lParam);
    38324130
     
    38524150
    38534151        case TVM_EDITLABELA:
    3854 //                      FIXME (treeview, "Unimplemented msg TVM_EDITLABELA \n");
    3855                 return 0;
     4152                return TREEVIEW_EditLabelA(hwnd, (HTREEITEM)lParam);
    38564153
    38574154        case TVM_EDITLABELW:
     
    38834180
    38844181        case TVM_ENDEDITLABELNOW:
    3885                 return TREEVIEW_EndEditLabelNow (hwnd, wParam, lParam);
     4182                return TREEVIEW_EndEditLabelNow (hwnd,(BOOL)wParam);
    38864183
    38874184        case TVM_GETISEARCHSTRINGA:
     
    39804277                return TREEVIEW_LButtonDown (hwnd, wParam, lParam);
    39814278
    3982         case WM_LBUTTONUP:
    3983                 return TREEVIEW_LButtonUp (hwnd, wParam, lParam);
    3984 
    39854279        case WM_LBUTTONDBLCLK:
    39864280                return TREEVIEW_LButtonDoubleClick (hwnd, wParam, lParam);
     
    39894283                return TREEVIEW_RButtonDown (hwnd, wParam, lParam);
    39904284
    3991         case WM_RBUTTONUP:
    3992                 return TREEVIEW_RButtonUp (hwnd, wParam, lParam);
    3993 
    3994         case WM_MOUSEMOVE:
    3995                 return TREEVIEW_MouseMove (hwnd, wParam, lParam);
    3996 
    39974285        case WM_STYLECHANGED:
    39984286                return TREEVIEW_StyleChanged (hwnd, wParam, lParam);
     
    40154303                return TREEVIEW_VScroll (hwnd, wParam, lParam);
    40164304
     4305        case WM_MOUSEWHEEL:
     4306                return TREEVIEW_MouseWheel (hwnd, wParam, lParam);
     4307
    40174308        case WM_DRAWITEM:
    4018 //              printf ("drawItem\n");
     4309                //printf ("drawItem\n");
    40194310                return DefWindowProcA (hwnd, uMsg, wParam, lParam);
    40204311
    40214312        default:
    4022 //              if (uMsg >= WM_USER)
    4023 //                FIXME (treeview, "Unknown msg %04x wp=%08x lp=%08lx\n",
    4024 //                   uMsg, wParam, lParam);
     4313              //if (uMsg >= WM_USER)
     4314              //  FIXME (treeview, "Unknown msg %04x wp=%08x lp=%08lx\n",
     4315              //     uMsg, wParam, lParam);
    40254316            return DefWindowProcA (hwnd, uMsg, wParam, lParam);
    40264317      }
     
    40294320
    40304321
    4031 VOID
    4032 TREEVIEW_Register (VOID)
     4322VOID TREEVIEW_Register (VOID)
    40334323{
    40344324    WNDCLASSA wndClass;
    4035 
    4036 //    TRACE (treeview,"\n");
    4037 
    4038 //SvL: Don't check this now
    4039 //    if (GlobalFindAtomA (WC_TREEVIEWA)) return;
    40404325
    40414326    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
     
    40524337
    40534338
    4054 VOID
    4055 TREEVIEW_Unregister (VOID)
    4056 {
    4057     if (GlobalFindAtomA (WC_TREEVIEWA))
    4058         UnregisterClassA (WC_TREEVIEWA, (HINSTANCE)NULL);
    4059 }
    4060 
     4339VOID TREEVIEW_Unregister (VOID)
     4340{
     4341    UnregisterClassA (WC_TREEVIEWA, (HINSTANCE)NULL);
     4342}
     4343
Note: See TracChangeset for help on using the changeset viewer.