Ignore:
Timestamp:
Mar 30, 2000, 5:39:10 PM (25 years ago)
Author:
cbratschi
Message:

treeview info tip

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/comctl32/treeview.cpp

    r3182 r3280  
    1 /* $Id: treeview.cpp,v 1.4 2000-03-21 17:30:46 cbratschi Exp $ */
     1/* $Id: treeview.cpp,v 1.5 2000-03-30 15:39:10 cbratschi Exp $ */
    22/* Treeview control
    33 *
     
    3333 - bug in SetScrollInfo/ShowScrollBar: WM_SIZE and WM_NCPAINT problems (i.e. RegEdit)
    3434 - VK_LEFT in WinHlp32 displays expanded icon
    35  - tooltips not finished
    3635 - expand not finished
    3736 - TVS_FULLROWSELECT
     
    8483static LRESULT TREEVIEW_EnsureVisible(HWND hwnd,HTREEITEM hItem);
    8584static VOID    TREEVIEW_ISearch(HWND hwnd,CHAR ch);
     85static VOID    TREEVIEW_CheckInfoTip(HWND hwnd);
    8686
    8787static LRESULT CALLBACK TREEVIEW_Edit_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
     
    10301030  INT iItem,len;
    10311031  BOOL mustRefresh = FALSE;
    1032   BOOL mustRepaint = FALSE;
     1032  BOOL mustRepaintItem = FALSE;
     1033  BOOL refreshFullLine = FALSE;
    10331034
    10341035  if (infoPtr->hwndEdit) SetFocus(hwnd);
     
    10491050  {
    10501051    wineItem->iImage = tvItem->iImage;
    1051     mustRepaint = TRUE;
     1052    mustRepaintItem = TRUE;
    10521053  }
    10531054
     
    10641065  {
    10651066    wineItem->iSelectedImage = tvItem->iSelectedImage;
    1066     mustRepaint = TRUE;
     1067    mustRepaintItem = TRUE;
    10671068  }
    10681069
     
    10741075    wineItem->state |= (tvItem->state & tvItem->stateMask);
    10751076    wineItem->stateMask |= tvItem->stateMask;
    1076     mustRepaint = (oldState != wineItem->state) || (oldMask != wineItem->stateMask);
     1077    mustRepaintItem = (oldState != wineItem->state) || (oldMask != wineItem->stateMask);
    10771078  }
    10781079
     
    10851086        len = lstrlenW(tvItem->pszText)+1;
    10861087
     1088        mustRepaintItem = ((wineItem->pszText == LPSTR_TEXTCALLBACKW) || (lstrcmpW(wineItem->pszText,tvItem->pszText) != 0));
    10871089        if (len > wineItem->cchTextMax)
    10881090        {
     
    10941096      } else
    10951097      {
    1096         if (wineItem->cchTextMax)
    1097         {
    1098           if (wineItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free (wineItem->pszText);
    1099           wineItem->cchTextMax = 0;
    1100         }
     1098        if (wineItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(wineItem->pszText);
     1099        wineItem->cchTextMax = 0;
    11011100        wineItem->pszText = LPSTR_TEXTCALLBACKW;
     1101        mustRepaintItem = TRUE;
    11021102      }
    11031103    } else
     
    11051105      if ((LPSTR)tvItem->pszText != LPSTR_TEXTCALLBACKA)
    11061106      {
     1107        mustRepaintItem = ((wineItem->pszText == LPSTR_TEXTCALLBACKW) || (lstrcmpAtoW((CHAR*)tvItem->pszText,wineItem->pszText) != 0));
    11071108        len = lstrlenA((LPSTR)tvItem->pszText)+1;
    11081109        if (len > wineItem->cchTextMax)
     
    11151116      } else
    11161117      {
    1117         if (wineItem->cchTextMax)
    1118         {
    1119           if (wineItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(wineItem->pszText);
    1120           wineItem->cchTextMax = 0;
    1121         }
     1118        if (wineItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(wineItem->pszText);
     1119        wineItem->cchTextMax = 0;
    11221120        wineItem->pszText = LPSTR_TEXTCALLBACKW;
     1121        mustRepaintItem = TRUE;
    11231122      }
    11241123    }
    1125     mustRepaint = TRUE;
     1124    refreshFullLine = TRUE;
    11261125  }
    11271126
     
    11291128  {
    11301129    wineItem->mask |= tvItem->mask;
    1131     mustRepaint = TRUE;
    1132   }
    1133 
    1134   if (mustRepaint || mustRefresh)
     1130    mustRepaintItem = TRUE;
     1131  }
     1132
     1133  if (mustRepaintItem || mustRefresh)
    11351134  {
    11361135    wineItem->calculated = FALSE;
     
    11381137      TREEVIEW_QueueRefresh(hwnd);
    11391138    else
    1140       TREEVIEW_RefreshItem(hwnd,wineItem,FALSE);
     1139      TREEVIEW_RefreshItem(hwnd,wineItem,refreshFullLine);
    11411140  }
    11421141
     
    16861685      KillTimer(hwnd,TV_ISEARCH_TIMER);
    16871686      infoPtr->Timer &= ~TV_ISEARCH_TIMER_SET;
     1687      return 0;
     1688
     1689    case TV_INFOTIP_TIMER:
     1690      TREEVIEW_CheckInfoTip(hwnd);
    16881691      return 0;
    16891692 }
     
    30633066    if (tvdi.item.mask & TVIF_DI_SETITEM)
    30643067    {
    3065       wineItem->pszText = tvdi.item.pszText;
    30663068      if (buf == tvdi.item.pszText)
    30673069      {
     3070        wineItem->pszText = tvdi.item.pszText;
    30683071        wineItem->cchTextMax = 128;
    30693072      } else
    3070       {
    3071         //user-supplied buffer
     3073      { //user-supplied buffer
     3074        INT len = lstrlenW(tvdi.item.pszText);
     3075
    30723076        COMCTL32_Free(buf);
    3073         wineItem->cchTextMax = 0;
     3077        if (len > 0)
     3078        {
     3079          len++;
     3080          wineItem->pszText = (WCHAR*)COMCTL32_Alloc(len*sizeof(WCHAR));
     3081          lstrcpyW(wineItem->pszText,tvdi.item.pszText);
     3082          wineItem->cchTextMax = len;
     3083        } else
     3084        {
     3085          wineItem->pszText = NULL;
     3086          wineItem->cchTextMax = len;
     3087        }
    30743088      }
    30753089      *mustFree = FALSE;
     
    30953109        COMCTL32_Free(buf);
    30963110      } else
    3097       {
    3098         //user-supplied buffer
     3111      { //user-supplied buffer
     3112        INT len = lstrlenA((CHAR*)tvdi.item.pszText);
     3113
    30993114        COMCTL32_Free(buf);
    3100         wineItem->cchTextMax = 0;
     3115        if (len > 0)
     3116        {
     3117          len++;
     3118          wineItem->pszText = (WCHAR*)COMCTL32_Alloc(len*sizeof(WCHAR));
     3119          lstrcpyAtoW(wineItem->pszText,(CHAR*)tvdi.item.pszText);
     3120          wineItem->cchTextMax = len;
     3121        } else
     3122        {
     3123          wineItem->pszText = NULL;
     3124          wineItem->cchTextMax = len;
     3125        }
    31013126      }
    31023127      *mustFree = FALSE;
     
    33543379}
    33553380
    3356 static LRESULT TREEVIEW_HitTest(HWND hwnd,LPTVHITTESTINFO lpht)
     3381static LRESULT TREEVIEW_HitTest(HWND hwnd,LPTVHITTESTINFO lpht,BOOL ignoreClientRect)
    33573382{
    33583383  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     
    33633388
    33643389  if (!lpht) return 0;
    3365   GetClientRect (hwnd, &rect);
     3390
    33663391  status = 0;
    33673392  x = lpht->pt.x;
    33683393  y = lpht->pt.y;
    3369   if (x < rect.left)  status |= TVHT_TOLEFT;
    3370   if (x > rect.right) status |= TVHT_TORIGHT;
    3371   if (y < rect.top )  status |= TVHT_ABOVE;
    3372   if (y > rect.bottom) status |= TVHT_BELOW;
    3373 
    3374   if (status)
    3375   {
    3376     lpht->flags = status;
    3377     lpht->hItem = 0;
    3378 
    3379     return 0;
     3394
     3395  if (!ignoreClientRect)
     3396  {
     3397    GetClientRect (hwnd, &rect);
     3398
     3399    if (x < rect.left)  status |= TVHT_TOLEFT;
     3400    if (x > rect.right) status |= TVHT_TORIGHT;
     3401    if (y < rect.top )  status |= TVHT_ABOVE;
     3402    if (y > rect.bottom) status |= TVHT_BELOW;
     3403
     3404    if (status)
     3405    {
     3406      lpht->flags = status;
     3407      lpht->hItem = 0;
     3408
     3409      return 0;
     3410    }
    33803411  }
    33813412
     
    35973628        {
    35983629          tvdi.item.pszText     = textW;
    3599           tvdi.item.cchTextMax  = lstrlenW(textW);
     3630          tvdi.item.cchTextMax  = lstrlenW(textW)+1;
    36003631        } else
    36013632        {
    36023633          tvdi.item.pszText     = (LPWSTR)textA;
    3603           tvdi.item.cchTextMax  = lstrlenA(textA);
     3634          tvdi.item.cchTextMax  = lstrlenA(textA)+1;
    36043635        }
    36053636
     
    37133744  }
    37143745
    3715   if (!TREEVIEW_HitTest(hwnd,&hitinfo) || !(hitinfo.flags & TVHT_ONITEM)) return FALSE;
     3746  if (!TREEVIEW_HitTest(hwnd,&hitinfo,FALSE) || !(hitinfo.flags & TVHT_ONITEM)) return FALSE;
    37163747  wineItem = &infoPtr->items [(INT)hitinfo.hItem];
    37173748
     
    37233754}
    37243755
     3756VOID TREEVIEW_ShowInfoTip(HWND hwnd,TREEVIEW_INFO *infoPtr,TREEVIEW_ITEM *item)
     3757{
     3758  LPWSTR text;
     3759  BOOL mustFree = FALSE;
     3760  TTTOOLINFOW ti;
     3761  POINT pt;
     3762  DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     3763
     3764  if(dwStyle & TVS_INFOTIP)
     3765  {
     3766    NMTVGETINFOTIPW tvgit;
     3767    WCHAR* buf = (WCHAR*)COMCTL32_Alloc(isUnicodeNotify(&infoPtr->header) ? INFOTIPSIZE*sizeof(WCHAR):INFOTIPSIZE*sizeof(CHAR));
     3768
     3769    tvgit.pszText    = buf;
     3770    tvgit.cchTextMax = INFOTIPSIZE;
     3771    tvgit.hItem      = item->hItem;
     3772    tvgit.lParam     = item->lParam;
     3773
     3774    sendNotify(hwnd,isUnicodeNotify(&infoPtr->header) ? TVN_GETINFOTIPW:TVN_GETINFOTIPA,&tvgit.hdr);
     3775    if (isUnicodeNotify(&infoPtr->header))
     3776    {
     3777      if (buf != tvgit.pszText) COMCTL32_Free(buf); else mustFree = TRUE;
     3778      text = tvgit.pszText;
     3779    } else
     3780    {
     3781      text = (WCHAR*)COMCTL32_Alloc(tvgit.cchTextMax*sizeof(WCHAR));
     3782      lstrcpyAtoW(text,(LPSTR)tvgit.pszText);
     3783      COMCTL32_Free(buf);
     3784    }
     3785  } else
     3786  {
     3787    if (item->pszText == LPSTR_TEXTCALLBACKW)
     3788      text = TREEVIEW_CallbackText(hwnd,item,&mustFree);
     3789    else
     3790      text = item->pszText;
     3791  }
     3792
     3793  infoPtr->tipItem = item->hItem;
     3794  SetTimer(hwnd,TV_INFOTIP_TIMER,TV_INFOTIP_DELAY,0);
     3795  infoPtr->Timer |= TV_INFOTIP_TIMER_SET;
     3796
     3797  ti.cbSize   = sizeof(ti);
     3798  ti.uId      = 0;
     3799  ti.hwnd     = hwnd;
     3800  ti.hinst    = 0;
     3801  ti.lpszText = text;
     3802  pt.x = item->text.left;
     3803  pt.y = item->text.top;
     3804  ClientToScreen(hwnd,&pt);
     3805  SendMessageA(infoPtr->hwndToolTip,TTM_TRACKPOSITION,0,(LPARAM)MAKELPARAM(pt.x,pt.y));
     3806  SendMessageA(infoPtr->hwndToolTip,TTM_UPDATETIPTEXTW,0,(LPARAM)&ti);
     3807  SendMessageA(infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)TRUE,(LPARAM)&ti);
     3808
     3809  if (mustFree) COMCTL32_Free(text);
     3810}
     3811
     3812VOID TREEVIEW_HideInfoTip(HWND hwnd,TREEVIEW_INFO *infoPtr)
     3813{
     3814  if (infoPtr->tipItem)
     3815  {
     3816    TTTOOLINFOA ti;
     3817
     3818    infoPtr->tipItem = 0;
     3819    KillTimer(hwnd,TV_INFOTIP_TIMER);
     3820    infoPtr->Timer &= ~TV_INFOTIP_TIMER_SET;
     3821
     3822    ti.cbSize   = sizeof(TTTOOLINFOA);
     3823    ti.uId      = 0;
     3824    ti.hwnd     = (UINT)hwnd;
     3825
     3826    SendMessageA(infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)FALSE,(LPARAM)&ti);
     3827  }
     3828}
     3829
     3830static VOID TREEVIEW_CheckInfoTip(HWND hwnd)
     3831{
     3832  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     3833  TVHITTESTINFO ht;
     3834
     3835  GetCursorPos(&ht.pt);
     3836  ScreenToClient(hwnd,&ht.pt);
     3837  TREEVIEW_HitTest(hwnd,&ht,TRUE);
     3838
     3839  if ((ht.hItem != infoPtr->tipItem) || !(ht.flags & TVHT_ONITEMLABEL))
     3840    TREEVIEW_HideInfoTip(hwnd,infoPtr);
     3841}
     3842
    37253843static LRESULT TREEVIEW_MouseMove(HWND hwnd,WPARAM wParam,LPARAM lParam)
    37263844{
     
    37323850  ht.pt.y = (INT)HIWORD(lParam);
    37333851
    3734   TREEVIEW_HitTest(hwnd,&ht);
     3852  TREEVIEW_HitTest(hwnd,&ht,FALSE);
    37353853
    37363854  if (ht.hItem)
     
    37403858    item = &infoPtr->items[(INT)ht.hItem];
    37413859
    3742     if (infoPtr->hwndToolTip && ((item->text.left < 0) || (item->text.right > infoPtr->uVisibleWidth)) && (infoPtr->tipItem != item->hItem))
    3743     {
    3744       DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
    3745       LPWSTR text;
    3746       BOOL mustFree = FALSE;
    3747       TTTOOLINFOW ti;
    3748       POINT pt;
    3749 
    3750       if(dwStyle & TVS_INFOTIP)
    3751       {
    3752         NMTVGETINFOTIPW tvgit;
    3753         WCHAR* buf = (WCHAR*)COMCTL32_Alloc(isUnicodeNotify(&infoPtr->header) ? INFOTIPSIZE*sizeof(WCHAR):INFOTIPSIZE*sizeof(CHAR));
    3754 
    3755         tvgit.pszText    = buf;
    3756         tvgit.cchTextMax = INFOTIPSIZE;
    3757         tvgit.hItem      = item->hItem;
    3758         tvgit.lParam     = item->lParam;
    3759 
    3760         sendNotify(hwnd,isUnicodeNotify(&infoPtr->header) ? TVN_GETINFOTIPW:TVN_GETINFOTIPA,&tvgit.hdr);
    3761         if (isUnicodeNotify(&infoPtr->header))
    3762         {
    3763           if (buf != tvgit.pszText) COMCTL32_Free(buf); else mustFree = TRUE;
    3764           text = tvgit.pszText;
    3765         } else
    3766         {
    3767           text = (WCHAR*)COMCTL32_Alloc(tvgit.cchTextMax*sizeof(WCHAR));
    3768           lstrcpyAtoW(text,(LPSTR)tvgit.pszText);
    3769           COMCTL32_Free(buf);
    3770         }
    3771       } else
    3772       {
    3773         if (item->pszText == LPSTR_TEXTCALLBACKW)
    3774           text = TREEVIEW_CallbackText(hwnd,item,&mustFree);
    3775         else
    3776           text = item->pszText;
    3777       }
    3778 #if 0 //CB: not yet
    3779       infoPtr->tipItem = item->hItem;
    3780       ti.cbSize   = sizeof(ti);
    3781       ti.uId      = 0;
    3782       ti.hwnd     = hwnd;
    3783       ti.hinst    = 0;
    3784       ti.lpszText = text;
    3785       pt.x = ti.rect.left;
    3786       pt.y = ti.rect.top;
    3787       ClientToScreen(hwnd,&pt);
    3788       SendMessageA(infoPtr->hwndToolTip,TTM_TRACKPOSITION,0,(LPARAM)MAKELPARAM(pt.x,pt.y));
    3789       SendMessageA(infoPtr->hwndToolTip,TTM_UPDATETIPTEXTW,0,(LPARAM)&ti);
    3790       SendMessageA(infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)TRUE,(LPARAM)&ti);
    3791 #endif
    3792       if (mustFree) COMCTL32_Free(text);
    3793     }
     3860    if (infoPtr->hwndToolTip && (ht.flags & TVHT_ONITEMLABEL) &&
     3861        ((item->text.left < 0) || (item->text.right > infoPtr->uVisibleWidth) || (item->text.top < 0) || (item->text.bottom > infoPtr->uVisibleHeight)) &&
     3862        (infoPtr->tipItem != item->hItem))
     3863      TREEVIEW_ShowInfoTip(hwnd,infoPtr,item);
     3864    else
     3865      TREEVIEW_HideInfoTip(hwnd,infoPtr);
    37943866
    37953867    if (dwStyle & TVS_TRACKSELECT)
     
    38243896  ht.pt.y = (INT)HIWORD(lParam);
    38253897
    3826   TREEVIEW_HitTest (hwnd,&ht);
     3898  TREEVIEW_HitTest (hwnd,&ht,FALSE);
    38273899
    38283900  bTrack = (ht.flags & TVHT_ONITEM) && !(dwStyle & TVS_DISABLEDRAGDROP);
     
    39073979   ht.pt.y = (INT)HIWORD(lParam);
    39083980
    3909    TREEVIEW_HitTest(hwnd,&ht);
     3981   TREEVIEW_HitTest(hwnd,&ht,FALSE);
    39103982
    39113983   if (TREEVIEW_TrackMouse(hwnd, ht.pt))
     
    47314803}
    47324804
     4805static LRESULT TREEVIEW_Notify(HWND hwnd,WPARAM wParam,LPARAM lParam)
     4806{
     4807  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     4808  LPNMHDR hdr = (LPNMHDR)lParam;
     4809
     4810  if (hdr->hwndFrom == infoPtr->hwndToolTip)
     4811  {
     4812    LPARAM lp = (LPARAM)GetMessagePos();
     4813    POINT pt;
     4814
     4815    pt.x = (INT)LOWORD(lp);
     4816    pt.y = (INT)HIWORD(lp);
     4817    ScreenToClient(hwnd,&pt);
     4818    lp = MAKELONG(pt.x,pt.y);
     4819
     4820    if (hdr->code == (UINT)NM_CLICK)
     4821      TREEVIEW_LButtonDown(hwnd,0,lp);
     4822    else if (hdr->code == (UINT)NM_RCLICK)
     4823      TREEVIEW_RButtonDown(hwnd,0,lp);
     4824    else if (hdr->code == (UINT)NM_DBLCLK)
     4825      TREEVIEW_LButtonDoubleClick(hwnd,0,lp);
     4826    else if (hdr->code == (UINT)NM_RDBLCLK)
     4827      TREEVIEW_RButtonDoubleClick(hwnd,0,lp);
     4828  }
     4829
     4830  return 0;
     4831}
     4832
    47334833static LRESULT WINAPI
    47344834TREEVIEW_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     
    48034903
    48044904        case TVM_HITTEST:
    4805           return TREEVIEW_HitTest(hwnd,(LPTVHITTESTINFO)lParam);
     4905          return TREEVIEW_HitTest(hwnd,(LPTVHITTESTINFO)lParam,FALSE);
    48064906
    48074907        case TVM_CREATEDRAGIMAGE:
     
    49245024        case WM_RBUTTONDBLCLK:
    49255025          return TREEVIEW_RButtonDoubleClick(hwnd,wParam,lParam);
     5026
     5027        case WM_NOTIFY:
     5028          return TREEVIEW_Notify(hwnd,wParam,lParam);
    49265029
    49275030        case WM_STYLECHANGED:
Note: See TracChangeset for help on using the changeset viewer.