- Timestamp:
- Feb 14, 2000, 6:31:40 PM (26 years ago)
- Location:
- trunk/src/comctl32
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/comctl32/comctl32.c
r2635 r2782 1 /* $Id: comctl32.c,v 1.1 3 2000-02-04 17:02:06cbratschi Exp $ */1 /* $Id: comctl32.c,v 1.14 2000-02-14 17:31:39 cbratschi Exp $ */ 2 2 /* 3 3 * Win32 common controls implementation … … 12 12 */ 13 13 14 /* WINE 20000130 level (commctrl.c) */ 14 /* 15 - Corel 20000212 level 16 - WINE 20000130 level (commctrl.c) 17 */ 15 18 16 19 #include "comctl32.h" … … 37 40 #include "listview.h" 38 41 39 HANDLE COMCTL32_hHeap = (HANDLE)NULL;42 HANDLE COMCTL32_hHeap = (HANDLE)NULL; 40 43 HMODULE COMCTL32_hModule = 0; 41 LPSTR 44 LPSTR COMCTL32_aSubclass = (LPSTR)NULL; 42 45 43 46 void CDECL RegisterCOMCTL32WindowClasses(unsigned long hinstDLL) … … 633 636 634 637 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0, 635 MAKELPARAM((WORD)d yBitmap, (WORD)dxBitmap));638 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap)); 636 639 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0, 637 MAKELPARAM((WORD)d yButton, (WORD)dxButton));640 MAKELPARAM((WORD)dxButton, (WORD)dyButton)); 638 641 639 642 -
trunk/src/comctl32/propsheet.c
r2126 r2782 1 /* $Id: propsheet.c,v 1.1 7 1999-12-18 20:56:59 achimhaExp $ */1 /* $Id: propsheet.c,v 1.18 2000-02-14 17:31:39 cbratschi Exp $ */ 2 2 /* 3 3 * Property Sheets … … 14 14 15 15 /* WINE 991212 level */ 16 17 /* CB: Odin problems:18 - trap in PROPSHEET_DialogProc (tab control creation)19 */20 16 21 17 #include <string.h> … … 156 152 psInfo->useCallback = dwFlags & PSH_USECALLBACK; 157 153 psInfo->isModeless = dwFlags & PSH_MODELESS; 158 psInfo->ppshheader = lppsh;154 psInfo->ppshheader = (PROPSHEETHEADERA*)lppsh; 159 155 psInfo->ppshheader = COMCTL32_Alloc(sizeof(PROPSHEETHEADERA)); 160 156 *psInfo->ppshheader = *lppsh; … … 168 164 if (dwFlags & PSH_USEPSTARTPAGE) 169 165 { 170 //TRACE(propsheet, "PSH_USEPSTARTPAGE is on");166 //TRACE(propsheet, "PSH_USEPSTARTPAGE is on"); 171 167 psInfo->active_page = 0; 172 168 } … … 297 293 /* Extract the caption */ 298 294 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)); 300 296 p += lstrlenW((LPCWSTR)p) + 1; 301 297 … … 336 332 { 337 333 if (psInfo->hImageList == 0 ) 338 334 psInfo->hImageList = ImageList_Create(icon_cx, icon_cy, ILC_COLOR, 1, 1); 339 335 340 336 ImageList_AddIcon(psInfo->hImageList, hIcon); … … 380 376 EnableWindow( owner, TRUE ); 381 377 } 382 retval = dlgInfo->idResult; 378 retval = dlgInfo->idResult; 383 379 384 380 WIN_ReleaseWndPtr(wndPtr); … … 440 436 if (!(psInfo->ppshheader->dwFlags & PSH_MODELESS)) 441 437 ret = PROPSHEET_DoDialogBox((HWND)ret, psInfo->ppshheader->hwndParent); 442 438 443 439 COMCTL32_Free(temp); 444 440 … … 1024 1020 { 1025 1021 dprintf(("COMCTL32:PROPSHEET_CreatePage: ERROR!!! ppshpage == NULL!!!\n")); 1026 return FALSE; 1022 return FALSE; 1027 1023 } 1028 1024 … … 1130 1126 1131 1127 ppshpage = (LPCPROPSHEETPAGEA)psInfo->proppage[index].hpage; 1132 PROPSHEET_CreatePage(hwndDlg, index, psInfo, ppshpage);1128 PROPSHEET_CreatePage(hwndDlg, index, psInfo, (PROPSHEETPAGEA*)ppshpage); 1133 1129 1134 1130 psn.hdr.hwndFrom = hwndDlg; … … 1142 1138 1143 1139 /* 1144 * TODO: check return value. 1140 * TODO: check return value. 1145 1141 */ 1146 1142 } … … 1181 1177 psn.hdr.idFrom = 0; 1182 1178 psn.lParam = 0; 1183 1179 1184 1180 hwndPage = psInfo->proppage[psInfo->active_page].hwndPage; 1185 1181 … … 1217 1213 psn.hdr.idFrom = 0; 1218 1214 psn.lParam = 0; 1219 1215 1220 1216 hwndPage = psInfo->proppage[psInfo->active_page].hwndPage; 1221 1217 1222 1218 msgResult = SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn); 1223 1219 1224 TRACE("msg result %ld\n", msgResult);1220 //TRACE("msg result %ld\n", msgResult); 1225 1221 1226 1222 if (msgResult == -1) … … 1253 1249 psn.hdr.idFrom = 0; 1254 1250 psn.lParam = 0; 1255 1251 1256 1252 hwndPage = psInfo->proppage[psInfo->active_page].hwndPage; 1257 1253 1258 1254 msgResult = SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn); 1259 1255 1260 TRACE("msg result %ld\n", msgResult);1256 //TRACE("msg result %ld\n", msgResult); 1261 1257 1262 1258 if (msgResult != 0) … … 1289 1285 psn.hdr.idFrom = 0; 1290 1286 psn.lParam = 0; 1291 1287 1292 1288 1293 1289 /* … … 1306 1302 psn.hdr.code = PSN_APPLY; 1307 1303 psn.lParam = lParam; 1308 1304 1309 1305 for (i = 0; i < psInfo->nPages; i++) 1310 1306 { … … 1352 1348 psn.hdr.idFrom = 0; 1353 1349 psn.lParam = 0; 1354 1350 1355 1351 if (SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn)) 1356 1352 return; … … 1358 1354 psn.hdr.code = PSN_RESET; 1359 1355 psn.lParam = lParam; 1360 1356 1361 1357 for (i = 0; i < psInfo->nPages; i++) 1362 1358 { … … 1394 1390 psn.hdr.idFrom = 0; 1395 1391 psn.lParam = 0; 1396 1392 1397 1393 SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &psn); 1398 1394 } … … 1546 1542 if (index < 0 || index >= psInfo->nPages) 1547 1543 { 1548 TRACE("Could not find page to select!\n");1544 //TRACE("Could not find page to select!\n"); 1549 1545 return FALSE; 1550 1546 } … … 1569 1565 1570 1566 /* 1571 * TODO: check return value. 1567 * TODO: check return value. 1572 1568 */ 1573 1569 } … … 1690 1686 { 1691 1687 /* 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); 1693 1689 } 1694 1690 … … 1743 1739 if (index < 0 || index >= psInfo->nPages) 1744 1740 { 1745 TRACE("Could not find page to remove!\n");1741 //TRACE("Could not find page to remove!\n"); 1746 1742 return FALSE; 1747 1743 } 1748 1744 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); 1751 1747 /* 1752 1748 * Check if we're removing the active page. … … 1793 1789 DestroyPropertySheetPage(psInfo->proppage[index].hpage); 1794 1790 } 1795 1791 1796 1792 /* Remove the tab */ 1797 1793 SendMessageA(hwndTabControl, TCM_DELETEITEM, index, 0); … … 1800 1796 psInfo->proppage = COMCTL32_Alloc(sizeof(PropPageInfo) * psInfo->nPages); 1801 1797 1802 if (index > 0) 1798 if (index > 0) 1803 1799 memcpy(&psInfo->proppage[0], &oldPages[0], index * sizeof(PropPageInfo)); 1804 1800 … … 1826 1822 HWND hwndFinish = GetDlgItem(hwndDlg, IDC_FINISH_BUTTON); 1827 1823 1828 TRACE("%ld\n", dwFlags);1824 //TRACE("%ld\n", dwFlags); 1829 1825 1830 1826 EnableWindow(hwndBack, FALSE); … … 1898 1894 PropSheetInfoStr); 1899 1895 1900 TRACE("\n");1896 //TRACE("\n"); 1901 1897 if (HIWORD(psInfo->ppshheader->pszCaption)) 1902 1898 HeapFree(GetProcessHeap(), 0, (LPVOID)psInfo->ppshheader->pszCaption); … … 1988 1984 if ( (ppsp->dwFlags & PSP_USEICONID) && HIWORD( ppsp->u2.pszIcon ) ) 1989 1985 ppsp->u2.pszIcon = HEAP_strdupA( GetProcessHeap(), 0, lpPropSheetPage->u2.pszIcon ); 1990 1986 1991 1987 1992 1988 if ((ppsp->dwFlags & PSP_USETITLE) && HIWORD( ppsp->pszTitle )) … … 2157 2153 ppshpage = (LPCPROPSHEETPAGEA)psInfo->proppage[idx].hpage; 2158 2154 psInfo->active_page = -1; 2159 2155 2160 2156 PROPSHEET_SetCurSel(hwnd, idx, psInfo->proppage[idx].hpage); 2161 2157 … … 2329 2325 if (LoadStringA(COMCTL32_hModule, IDS_CLOSE, buf, sizeof(buf))) 2330 2326 SetWindowTextA(hwndOK, buf); 2331 2327 2332 2328 return FALSE; 2333 2329 } -
trunk/src/comctl32/status.c
r2740 r2782 1 /* $Id: status.c,v 1.1 8 2000-02-10 18:51:19 cbratschi Exp $ */1 /* $Id: status.c,v 1.19 2000-02-14 17:31:39 cbratschi Exp $ */ 2 2 /* 3 3 * Interface code to StatusWindow widget/control … … 900 900 } 901 901 902 hdc = GetDC( 0);902 hdc = GetDC(hwnd); 903 903 if (hdc) { 904 904 TEXTMETRICA tm; … … 907 907 hOldFont = SelectObject (hdc,infoPtr->hDefaultFont); 908 908 GetTextMetricsA(hdc, &tm); 909 infoPtr->textHeight = tm.tmHeight ;909 infoPtr->textHeight = tm.tmHeight+tm.tmExternalLeading; 910 910 SelectObject (hdc, hOldFont); 911 ReleaseDC( 0, hdc);911 ReleaseDC(hwnd, hdc); 912 912 } 913 913 … … 936 936 width = rect.right - rect.left; 937 937 infoPtr->height = infoPtr->textHeight + 4 + VERT_BORDER; 938 //CB: todo: find bug !938 //CB: todo: find bug in font handling! 939 939 infoPtr->height += 4; 940 940 MoveWindow(hwnd,lpCreate->x,lpCreate->y-1,width,infoPtr->height,FALSE); … … 1070 1070 1071 1071 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); 1076 1087 } 1077 1088 -
trunk/src/comctl32/treeview.c
r2769 r2782 1 /* $Id: treeview.c,v 1.2 4 2000-02-12 18:10:40 cbratschi Exp $ */1 /* $Id: treeview.c,v 1.25 2000-02-14 17:31:40 cbratschi Exp $ */ 2 2 /* Treeview control 3 3 * … … 6 6 * Copyright 1999 Sylvain St-Germain 7 7 * Copyright 1999 Achim Hasenmueller 8 * Copyright 1999 Christoph Bratschi8 * Copyright 1999-2000 Christoph Bratschi 9 9 * 10 10 * … … 42 42 */ 43 43 44 /* WINE 991212 level */ 44 /* 45 Most identical with: 46 - Corel 20000212 level 47 - (WINE 991212 level) 48 */ 45 49 46 50 /* CB: todo 47 51 48 - sub parent lines aren't redrawn in expand handler49 - invisible sibling lines aren't drawn in WM_PAINT50 52 - WM_LBUTTONDOWN: bug in highlight code 51 53 - WM_SIZE: redraw doesn't work … … 63 65 /* ffs should be in <string.h>. */ 64 66 67 //#define OS2LINEHACK //CB: too slow, but looks good 68 65 69 /* Defines, since they do not need to return previous state, and nr 66 70 * has no side effects in this file. … … 80 84 static BOOL TREEVIEW_SendCustomDrawNotify (HWND hwnd, DWORD dwDrawStage, HDC hdc, RECT rc); 81 85 static BOOL TREEVIEW_SendCustomDrawItemNotify (HWND hwnd, HDC hdc, TREEVIEW_ITEM *tvItem, UINT uItemDrawState); 86 static LRESULT TREEVIEW_SelectItem (HWND hwnd, WPARAM wParam, LPARAM lParam); 82 87 static LRESULT TREEVIEW_DoSelectItem (HWND hwnd, INT action, HTREEITEM newSelect, INT cause); 83 88 static void TREEVIEW_Refresh(HWND hwnd); … … 88 93 static LRESULT CALLBACK TREEVIEW_Edit_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 89 94 90 LRESULT WINAPI TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam); 95 LRESULT WINAPI TREEVIEW_EndEditLabelNow (HWND hwnd, BOOL bCancel); 96 97 HWND TREEVIEW_EditLabelA(HWND hwnd, HTREEITEM hItem); 91 98 92 99 /* helper functions. Work with the assumption that validity of operands … … 117 124 118 125 /*************************************************************************** 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 */ 130 static 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 /*************************************************************************** 119 159 * This method returns the last expanded child item of a tree node 120 160 */ 121 161 static TREEVIEW_ITEM *TREEVIEW_GetLastListItem( 162 HWND hwnd, 122 163 TREEVIEW_INFO *infoPtr, 123 164 TREEVIEW_ITEM *tvItem) … … 134 175 * If the last sibling has expanded children, restart. 135 176 */ 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, 138 182 infoPtr, 139 183 &(infoPtr->items[(INT)wineItem->firstChild])); 184 } 140 185 141 186 return wineItem; … … 147 192 */ 148 193 static TREEVIEW_ITEM *TREEVIEW_GetPrevListItem( 194 HWND hwnd, 149 195 TREEVIEW_INFO *infoPtr, 150 196 TREEVIEW_ITEM *tvItem) … … 158 204 TREEVIEW_ITEM *upItem = &infoPtr->items[(INT)tvItem->upsibling]; 159 205 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, 162 211 infoPtr, 163 212 &infoPtr->items[(INT)upItem->firstChild]); 213 } 164 214 else 165 215 return upItem; … … 183 233 */ 184 234 static TREEVIEW_ITEM *TREEVIEW_GetNextListItem( 235 HWND hwnd, 185 236 TREEVIEW_INFO *infoPtr, 186 237 TREEVIEW_ITEM *tvItem) … … 191 242 * If this item has children and is expanded, return the first child 192 243 */ 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 } 195 249 196 250 … … 222 276 */ 223 277 static TREEVIEW_ITEM *TREEVIEW_GetListItem( 278 HWND hwnd, 224 279 TREEVIEW_INFO *infoPtr, 225 280 TREEVIEW_ITEM *tvItem, … … 237 292 /* Keep a pointer to the previous in case we ask for more than we got */ 238 293 previousItem = wineItem; 239 wineItem = TREEVIEW_GetNextListItem( infoPtr,wineItem);294 wineItem = TREEVIEW_GetNextListItem(hwnd,infoPtr,wineItem); 240 295 } 241 296 … … 250 305 /* Keep a pointer to the previous in case we ask for more than we got */ 251 306 previousItem = wineItem; 252 wineItem = TREEVIEW_GetPrevListItem( infoPtr,wineItem);307 wineItem = TREEVIEW_GetPrevListItem(hwnd,infoPtr,wineItem); 253 308 } 254 309 … … 270 325 TREEVIEW_ITEM *parentItem) 271 326 { 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; 294 346 } 295 347 … … 316 368 317 369 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; 332 373 } 333 374 … … 342 383 siblingItem->upsibling=wineItem->upsibling; 343 384 } 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 } 344 392 } 345 393 … … 381 429 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 382 430 383 //TRACE (treeview,"\n");384 385 431 if ((INT)wParam == TVSIL_NORMAL) 386 432 return (LRESULT) infoPtr->himlNormal; … … 498 544 infoPtr->insertMarkItem=(HTREEITEM) lParam; 499 545 500 //CB: todo 501 if (!(infoPtr->uInternalStatus & TV_NOREDRAW)) 546 TREEVIEW_Refresh(hwnd); 547 548 return 1; 549 } 550 551 static LRESULT 552 TREEVIEW_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) 502 559 TREEVIEW_Refresh(hwnd); 503 560 504 return 1;505 }506 507 static LRESULT508 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;515 561 return (LRESULT) prevColor; 516 562 } … … 521 567 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 522 568 523 //TRACE("\n");524 569 return (LRESULT) infoPtr->clrBk; 525 570 } … … 531 576 COLORREF prevColor=infoPtr->clrBk; 532 577 533 //TRACE("\n");534 578 infoPtr->clrBk=(COLORREF) lParam; 579 if (infoPtr->clrBk != prevColor) 580 TREEVIEW_Refresh(hwnd); 581 582 535 583 return (LRESULT) prevColor; 536 584 } … … 551 599 #define TREEVIEW_LEFT_MARGIN 8 552 600 601 #ifdef OS2LINEHACK 553 602 //CB: hack for PS_DOT bug in Open32 pen handling 554 603 … … 559 608 { 560 609 if (drawPixel) SetPixel(drawDC,x,y,(COLORREF)lpData); 561 else SetPixel(drawDC,x,y,RGB(255,255,255));562 610 drawPixel = !drawPixel; 563 611 } … … 571 619 for (x = 0;x < cPoints-1;x++) 572 620 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 626 static 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 } 573 666 } 574 667 … … 596 689 if (cditem & CDRF_SKIPDEFAULT) return; 597 690 } 691 692 //CB: what does COMCTL 5.0 with CDRF_NEWFONT? recalc items? 598 693 599 694 /* … … 607 702 * Display the tree hierarchy 608 703 */ 609 if ( (dwStyle & TVS_HASLINES) && (wineItem->hItem != infoPtr->TopRootItem))704 if (dwStyle & TVS_HASLINES) 610 705 { 611 706 /* … … 620 715 { 621 716 TREEVIEW_ITEM *upNode = NULL; 622 BOOL hasParentOrSibling = TRUE;623 717 RECT upRect = {0,0,0,0}; 624 718 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 626 726 /* 627 727 * determine the target location of the line at root, either be linked … … 632 732 else if (wineItem->parent) 633 733 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 640 737 if (wineItem->iLevel == 0) 641 738 { 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; 645 741 points[1].y = points[0].y = center; 646 742 } else 647 743 { 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); 654 745 points[1].y = points[0].y = center; 655 746 points[0].x = points[1].x + 10; … … 659 750 * Get a dotted pen 660 751 */ 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 670 757 DeleteObject(hnewPen); 671 758 SelectObject(hdc, hOldPen); 672 #else673 if (hasParentOrSibling)674 TREEVIEW_Polyline(hdc,points,3,infoPtr->clrLine);675 else676 TREEVIEW_Polyline(hdc,points,2,infoPtr->clrLine);677 #endif678 759 } 679 760 } … … 687 768 if (( dwStyle & TVS_HASBUTTONS) && ( dwStyle & TVS_HASLINES)) 688 769 { 689 if ( (wineItem->cChildren) || 690 (wineItem->cChildren == I_CHILDRENCALLBACK)) 770 if (TREEVIEW_HasChildren(hwnd, wineItem)) 691 771 { 692 772 /* Setup expand box coordinate to facilitate the LMBClick handling */ … … 725 805 himlp=&infoPtr->himlState; 726 806 imageIndex=wineItem->state>>12; 727 imageIndex++; /* yeah, right */728 807 729 808 if ((himlp) && (imageIndex)) … … 768 847 if (himlp) 769 848 { 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); 771 855 ImageList_GetIconSize (*himlp, &cx, &cy); 772 856 wineItem->bitmap.left=xpos-2; … … 778 862 } 779 863 780 781 864 /* 782 865 * Display the text associated with this item 783 866 */ 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)) 800 872 { 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); 876 985 } 877 986 } … … 930 1039 * validate parameters 931 1040 */ 932 if ( lpRect == NULL)1041 if ((infoPtr == NULL) || (lpRect == NULL)) 933 1042 return FALSE; 934 1043 … … 1024 1133 if (tvItem->mask & TVIF_TEXT) { 1025 1134 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); 1030 1141 } else { 1031 1142 if (wineItem->cchTextMax) { … … 1033 1144 wineItem->cchTextMax=0; 1034 1145 } 1035 wineItem->pszText =LPSTR_TEXTCALLBACKA;1146 wineItem->pszText=LPSTR_TEXTCALLBACKA; 1036 1147 } 1037 1148 } 1038 1149 1039 1150 wineItem->mask |= tvItem->mask; … … 1075 1186 //CB: HDC parameter is optional 1076 1187 1188 static 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 1077 1196 static void TREEVIEW_CalcItems(HWND hwnd,HDC hdc,TREEVIEW_INFO *infoPtr) 1078 1197 { 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; 1081 1200 TEXTMETRICA tm; 1082 1201 RECT rect,view; 1083 1202 BOOL ownDC = FALSE; 1203 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE); 1084 1204 1085 1205 GetClientRect(hwnd,&rect); … … 1089 1209 OffsetRect(&view,infoPtr->cx,infoPtr->cy); 1090 1210 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 1091 1225 iItem = (INT)infoPtr->TopRootItem; 1092 1226 infoPtr->firstVisible = 0; 1093 1227 item = NULL; 1094 indent = 0; 1095 x = y = 0; 1228 indent = x = y = 0; 1096 1229 1097 1230 while (iItem) 1098 1231 { 1099 prevItem = item;1100 1232 item = &infoPtr->items[iItem]; 1101 1233 item->iLevel = indent; 1102 1234 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 1103 1243 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); 1129 1247 1130 1248 if ((((y >= view.top) && (y <= view.bottom)) || ((y+height >= view.top) && (y+height <= view.bottom))) && 1131 1249 (x >= view.left) && (x <= view.right)) 1132 1250 { 1133 item->visible 1251 item->visible = TRUE; 1134 1252 if (!infoPtr->firstVisible) 1135 1253 infoPtr->firstVisible = item->hItem; 1136 } else item->visible 1254 } else item->visible = FALSE; 1137 1255 1138 1256 /* look up next item */ … … 1143 1261 indent++; 1144 1262 x += infoPtr->uIndent; 1145 if (x > infoPtr->uTotalWidth) 1146 infoPtr->uTotalWidth=x; 1263 infoPtr->uTotalWidth = MAX(infoPtr->uTotalWidth,itemWidth+x); 1147 1264 } else 1148 1265 { … … 1152 1269 indent--; 1153 1270 x -= infoPtr->uIndent; 1154 prevItem = item; 1155 item =& infoPtr->items[(INT)item->parent]; 1271 item = &infoPtr->items[(INT)item->parent]; 1156 1272 iItem = (INT)item->sibling; 1157 1273 } … … 1162 1278 if (ownDC) ReleaseDC(hwnd,hdc); 1163 1279 1164 /* FIXME: infoPtr->uTotalWidth should also take item label into account */ 1280 infoPtr->uInternalStatus &= ~TV_CALCALL; 1165 1281 1166 1282 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); 1283 infoPtr->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 } 1179 1323 } else 1180 1324 { 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); 1184 1328 } 1185 1329 } … … 1193 1337 TREEVIEW_ITEM *item; 1194 1338 INT iItem,indent; 1195 INT visIndent = -1; 1339 BOOL visFound = FALSE; 1340 HPEN hNewPen,hOldPen; 1196 1341 1197 1342 TREEVIEW_UnqueueRefresh(hwnd,TRUE,FALSE); … … 1212 1357 //draw items 1213 1358 1359 hNewPen = CreatePen(PS_DOT,0,infoPtr->clrLine); 1360 1214 1361 iItem = (INT)infoPtr->TopRootItem; 1215 1362 indent = 0; … … 1218 1365 { 1219 1366 item = &infoPtr->items[iItem]; 1220 /* FIXME: should query item sizes (ie check CDRF_NEWFONT) */1221 1367 if (item->visible) 1222 1368 { 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) 1226 1376 { 1227 1377 //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); 1236 1381 } 1237 1382 if ((item->firstChild) && (item->state & TVIS_EXPANDED)) … … 1251 1396 } 1252 1397 1398 DeleteObject(hNewPen); 1399 1253 1400 if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT) 1254 1401 infoPtr->cdmode = TREEVIEW_SendCustomDrawNotify(hwnd, CDDS_POSTPAINT, hdc, rect); … … 1292 1439 KillTimer (hwnd, TV_EDIT_TIMER); 1293 1440 infoPtr->Timer &= ~TV_EDIT_TIMER_SET; 1441 if (infoPtr->editItem) 1442 TREEVIEW_EditLabelA(hwnd, infoPtr->editItem); 1294 1443 return 0; 1295 1444 default: … … 1348 1497 1349 1498 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); 1353 1500 } 1354 1501 … … 1413 1560 retval=0; 1414 1561 switch (flag) { 1562 case TVGN_CHILD: /* Special case: child of 0 is root */ 1563 if (iItem) break; 1415 1564 case TVGN_ROOT: retval=(INT)infoPtr->TopRootItem; 1416 1565 break; … … 1447 1596 break; 1448 1597 case TVGN_LASTVISIBLE: 1449 returnItem=TREEVIEW_GetLastListItem ( infoPtr,wineItem);1598 returnItem=TREEVIEW_GetLastListItem (hwnd,infoPtr,wineItem); 1450 1599 break; 1451 1600 case TVGN_NEXTVISIBLE: 1452 returnItem=TREEVIEW_GetNextListItem ( infoPtr,wineItem);1601 returnItem=TREEVIEW_GetNextListItem (hwnd,infoPtr,wineItem); 1453 1602 break; 1454 1603 case TVGN_PREVIOUSVISIBLE: 1455 returnItem=TREEVIEW_GetPrevListItem ( infoPtr, wineItem);1604 returnItem=TREEVIEW_GetPrevListItem (hwnd,infoPtr, wineItem); 1456 1605 break; 1457 1606 default: // FIXME (treeview,"Unknown msg %x,item %x\n", flag,iItem); … … 1644 1793 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 1645 1794 TREEVIEW_ITEM *sortMe = NULL; /* Node for which we sort the children */ 1795 INT cChildren; 1796 HTREEITEM hti; 1646 1797 1647 1798 /* Obtain the TVSORTBC struct */ … … 1663 1814 sortMe = &infoPtr->items[ (INT)parent ]; 1664 1815 1816 cChildren = 0; 1817 for(hti = sortMe->firstChild; hti; hti = infoPtr->items[(INT)hti].sibling) 1818 cChildren++; 1819 1665 1820 /* Make sure there is something to sort */ 1666 if ( sortMe->cChildren > 1 )1821 if ( cChildren > 1 ) 1667 1822 { 1668 1823 /* pointer organization */ 1669 HDPA sortList = DPA_Create( sortMe->cChildren);1824 HDPA sortList = DPA_Create(cChildren); 1670 1825 HTREEITEM itemHandle = sortMe->firstChild; 1671 1826 TREEVIEW_ITEM *itemPtr = & infoPtr->items[ (INT)itemHandle ]; … … 1682 1837 DPA_InsertPtr( 1683 1838 sortList, /* the list */ 1684 sortMe->cChildren+1, /* force the insertion to be an append */1839 cChildren+1, /* force the insertion to be an append */ 1685 1840 itemPtr); /* the ptr to store */ 1686 1841 … … 1792 1947 TVITEMEXA *tvItem; 1793 1948 TREEVIEW_ITEM *wineItem, *parentItem, *prevsib, *sibItem; 1794 INT iItem, listItems,i,len;1949 INT iItem,i,len; 1795 1950 1796 1951 /* Item to insert */ … … 1801 1956 if (infoPtr->uNumPtrsAlloced==0) { 1802 1957 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)); 1804 1959 infoPtr->uNumPtrsAlloced=TVITEM_ALLOC; 1805 1960 infoPtr->TopRootItem=(HTREEITEM)1; … … 1815 1970 infoPtr->uNumPtrsAlloced*=2; 1816 1971 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)); 1818 1973 1819 1974 memcpy (&infoPtr->items[0], &oldItems[0], … … 1837 1992 for (i=0; i<infoPtr->uNumPtrsAlloced>>5; i++) { 1838 1993 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 } 1841 1999 tv_clear_bit(iItem,&infoPtr->freeList[i]); 1842 2000 iItem+=i<<5; … … 1846 2004 } 1847 2005 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 1855 2006 /* 1856 2007 * Find the parent item of the new item … … 1863 2014 wineItem->parent = 0; 1864 2015 sibItem = &infoPtr->items [(INT)infoPtr->TopRootItem]; 1865 listItems = infoPtr->uNumItems;1866 2016 } 1867 2017 else { … … 1874 2024 wineItem->parent = ptdi->hParent; 1875 2025 sibItem = &infoPtr->items [(INT)parentItem->firstChild]; 1876 parentItem->cChildren++;1877 listItems = parentItem->cChildren;1878 2026 } 1879 2027 … … 1892 2040 if (tvItem->pszText!=LPSTR_TEXTCALLBACKA) 1893 2041 { 1894 //TRACE (treeview,"(%p,%s)\n", &tvItem->pszText, tvItem->pszText);2042 //TRACE (treeview,"(%p,%s)\n", &tvItem->pszText, tvItem->pszText); 1895 2043 len = lstrlenA (tvItem->pszText)+1; 1896 wineItem->pszText= COMCTL32_Alloc (len +1);2044 wineItem->pszText= COMCTL32_Alloc (len); 1897 2045 lstrcpyA (wineItem->pszText, tvItem->pszText); 1898 2046 wineItem->cchTextMax=len; … … 1900 2048 else 1901 2049 { 1902 //TRACE (treeview,"LPSTR_TEXTCALLBACK\n");2050 //TRACE (treeview,"LPSTR_TEXTCALLBACK\n"); 1903 2051 wineItem->pszText = LPSTR_TEXTCALLBACKA; 1904 2052 wineItem->cchTextMax = 0; … … 1915 2063 wineItem->hItem=(HTREEITEM)iItem; 1916 2064 1917 if ( listItems>1) {2065 if (sibItem != wineItem) { 1918 2066 prevsib=NULL; 1919 2067 1920 2068 switch ((DWORD) ptdi->hInsertAfter) { 1921 2069 case (DWORD) TVI_FIRST: 1922 if (sibItem==wineItem) break;1923 2070 if (wineItem->parent) { 1924 2071 wineItem->sibling=parentItem->firstChild; … … 1931 2078 break; 1932 2079 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: 1941 2081 { 1942 2082 TREEVIEW_ITEM *aChild; … … 2006 2146 2007 2147 case (DWORD) TVI_LAST: 2008 if (sibItem==wineItem) break;2148 TVI_LAST_CASE: 2009 2149 while (sibItem->sibling) { 2010 2150 prevsib=sibItem; … … 2021 2161 } 2022 2162 if (sibItem->hItem!=ptdi->hInsertAfter) { 2023 // ERR (treeview, "tried to insert item after nonexisting handle.\n"); 2024 break; 2163 goto TVI_LAST_CASE; 2025 2164 } 2026 2165 prevsib=sibItem; … … 2037 2176 2038 2177 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 */ 2043 2179 2044 2180 wineItem->mask=tvItem->mask; 2045 2181 wineItem->iIntegral=1; 2046 2182 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 2052 2186 2053 2187 wineItem->expandBox.left = 0; /* Initialize the expandBox */ … … 2055 2189 wineItem->expandBox.right = 0; 2056 2190 wineItem->expandBox.bottom = 0; 2057 wineItem->calculated = FALSE;2058 2191 2059 2192 if (tvItem->mask & TVIF_IMAGE) … … 2070 2203 2071 2204 if (tvItem->mask & TVIF_STATE) { 2072 // TRACE(treeview, "Changing item state from %d to %d\n",2073 // wineItem->state,2074 // tvItem->state);2075 2205 wineItem->state=tvItem->state; 2076 2206 wineItem->stateMask=tvItem->stateMask; 2077 2207 } 2078 2208 2209 wineItem->calculated = FALSE; 2079 2210 TREEVIEW_QueueRefresh(hwnd); 2080 2211 … … 2226 2357 LPARAM lParam) 2227 2358 { 2359 BOOL bCancel = FALSE; 2360 static BOOL bIgnoreKillFocus = FALSE; 2361 2228 2362 switch (uMsg) 2229 2363 { 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; 2238 2380 2239 2381 case WM_GETDLGCODE: 2240 {2241 2382 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 } 2243 2394 2244 2395 default: … … 2254 2405 } 2255 2406 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 2256 2413 return 0; 2257 2414 } 2258 2415 2259 2260 2416 /* should handle edit control messages here */ 2261 2417 … … 2264 2420 2265 2421 { 2266 // TRACE (treeview, "%x %ld\n",wParam, lParam);2267 2268 2422 switch (HIWORD(wParam)) 2269 2423 { 2270 2424 case EN_UPDATE: 2271 2425 { 2272 2426 /* 2273 2427 * Adjust the edit window size 2274 2428 */ 2429 char buffer[1024]; 2275 2430 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 2276 2431 TREEVIEW_ITEM *editItem = TREEVIEW_ValidItem(infoPtr, infoPtr->editItem); 2277 INT iLength = GetWindowTextLengthA(infoPtr->hwndEdit);2278 2432 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) 2282 2442 { 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); 2293 2444 } 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 2294 2468 ReleaseDC(hwnd, hdc); 2295 2296 2469 break; 2297 2470 } 2298 2299 case EN_KILLFOCUS:2300 /* TREEVIEW_EndEditLabelNow(hwnd, (WPARAM)FALSE, 0);2301 */2302 break;2303 2471 2304 2472 default: … … 2377 2545 infoPtr->uNumItems=0; 2378 2546 infoPtr->clrBk = GetSysColor (COLOR_WINDOW); 2379 infoPtr->clrText = GetSysColor (COLOR_WINDOWTEXT);2380 2547 infoPtr->clrLine = GetSysColor (COLOR_WINDOWTEXT); 2381 2548 infoPtr->clrInsertMark = GetSysColor (COLOR_BTNTEXT); … … 2385 2552 infoPtr->himlNormal = NULL; 2386 2553 infoPtr->himlState = NULL; 2387 2554 infoPtr->uItemHeight = -1; 2388 2555 GetTextMetricsA (hdc, &tm); 2389 2556 infoPtr->hFont = GetStockObject (DEFAULT_GUI_FONT); 2390 2391 2557 GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont); 2558 logFont.lfWeight=FW_BOLD; 2392 2559 infoPtr->hBoldFont = CreateFontIndirectA (&logFont); 2393 2560 2394 2561 infoPtr->items = NULL; 2395 infoPtr->selectedItem =0;2562 infoPtr->selectedItem = 0; 2396 2563 infoPtr->clrText=-1; /* use system color */ 2397 2564 infoPtr->dropItem=0; 2398 2399 2565 infoPtr->insertMarkItem=0; 2566 infoPtr->insertBeforeorAfter=0; 2400 2567 infoPtr->pCallBackSort=NULL; 2401 2568 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; 2404 2577 if (!(dwStyle & TVS_NOTOOLTIPS)) { /* Create tooltip control */ 2405 2578 TTTOOLINFOA ti; … … 2434 2607 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti); 2435 2608 } 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);2452 2609 2453 2610 if (dwStyle & TVS_CHECKBOXES) { … … 2478 2635 2479 2636 TREEVIEW_RemoveTree (hwnd); 2480 SetWindowLongA( hwnd, 0, (DWORD)NULL);2481 2637 if (infoPtr->Timer & TV_REFRESH_TIMER_SET) 2482 2638 KillTimer (hwnd, TV_REFRESH_TIMER); … … 2484 2640 DestroyWindow (infoPtr->hwndToolTip); 2485 2641 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); 2486 2647 COMCTL32_Free (infoPtr); 2487 2648 … … 2496 2657 PAINTSTRUCT ps; 2497 2658 2498 // TRACE (treeview,"\n");2499 2659 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam; 2500 2660 TREEVIEW_Draw(hwnd,hdc,&ps.rcPaint); 2501 2661 if(!wParam) 2502 2662 EndPaint (hwnd, &ps); 2503 // TRACE (treeview,"done\n"); 2504 2505 return DefWindowProcA (hwnd, WM_PAINT, wParam, lParam); 2663 2664 return 0; 2506 2665 } 2507 2666 … … 2509 2668 TREEVIEW_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam) 2510 2669 { 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; 2516 2677 } 2517 2678 … … 2519 2680 TREEVIEW_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam) 2520 2681 { 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; 2526 2689 } 2527 2690 … … 2540 2703 } 2541 2704 2542 2543 2544 2545 2546 2547 2705 /* Notifications */ 2548 2549 2550 2551 2552 2706 2553 2707 static BOOL … … 2565 2719 } 2566 2720 2567 2568 2569 2721 static BOOL 2570 2722 TREEVIEW_SendTreeviewNotify (HWND hwnd, UINT code, UINT action, … … 2578 2730 // TRACE (treeview,"code:%x action:%x olditem:%x newitem:%x\n", 2579 2731 // code,action,(INT)oldItem,(INT)newItem); 2732 2733 ZeroMemory(&nmhdr, sizeof(NMTREEVIEWA)); 2734 2580 2735 nmhdr.hdr.hwndFrom = hwnd; 2581 2736 nmhdr.hdr.idFrom = GetWindowLongA( hwnd, GWL_ID); … … 2651 2806 2652 2807 static BOOL 2653 TREEVIEW_SendDispInfoNotify (HWND hwnd, TREEVIEW_ITEM *wineItem, 2654 UINT code, UINT what) 2808 TREEVIEW_SendDispInfoNotify (HWND hwnd, TREEVIEW_ITEM *wineItem, UINT code, UINT what) 2655 2809 { 2656 2810 NMTVDISPINFOA tvdi; … … 2679 2833 (WPARAM)tvdi.hdr.idFrom, 2680 2834 (LPARAM)&tvdi); 2835 2836 /* Ignore posible changes */ 2837 if (code == TVN_BEGINLABELEDIT) 2838 return retval; 2681 2839 2682 2840 if (what & TVIF_TEXT) { … … 2742 2900 TREEVIEW_ITEM *wineItem, UINT uItemDrawState) 2743 2901 { 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, 2780 2941 (WPARAM) GetWindowLongA( hwnd, GWL_ID), (LPARAM)&nmcdhdr); 2781 2942 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; 2785 2947 } 2786 2948 … … 2808 2970 if (!wineItem) 2809 2971 return 0; 2810 if (!wineItem->cChildren) 2972 2973 if (!TREEVIEW_HasChildren(hwnd, wineItem)) 2811 2974 return 0; 2812 2975 … … 2816 2979 // expand, 2817 2980 // wineItem->state); 2818 2819 if (wineItem->cChildren==I_CHILDRENCALLBACK) {2820 //FIXME (treeview,"we don't handle I_CHILDRENCALLBACK yet\n");2821 return 0;2822 }2823 2981 2824 2982 if (flag == TVE_TOGGLE) { /* FIXME: check exact behaviour here */ … … 2919 3077 //CB: todo: optimize! 2920 3078 TREEVIEW_UnqueueRefresh(hwnd,FALSE,FALSE); 3079 //CB: todo: precalc expanded items here 3080 infoPtr->uInternalStatus |= TV_CALCALL; 2921 3081 TREEVIEW_CalcItems(hwnd,0,infoPtr); 2922 3082 TREEVIEW_Refresh(hwnd); … … 2941 3101 2942 3102 while ((wineItem!=NULL) && (pt.y > wineItem->rect.bottom)) 2943 wineItem=TREEVIEW_GetNextListItem ( infoPtr,wineItem);3103 wineItem=TREEVIEW_GetNextListItem (hwnd,infoPtr,wineItem); 2944 3104 2945 3105 if (!wineItem) … … 2948 3108 return wineItem; 2949 3109 } 2950 2951 2952 2953 3110 2954 3111 static LRESULT … … 2960 3117 UINT status,x,y; 2961 3118 3119 lpht->hItem = 0; 2962 3120 GetClientRect (hwnd, &rect); 2963 3121 status=0; … … 3013 3171 } 3014 3172 3173 HWND 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 3015 3254 LRESULT WINAPI 3016 TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam)3255 TREEVIEW_EndEditLabelNow (HWND hwnd, BOOL bCancel) 3017 3256 { 3018 3257 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 3019 3258 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) 3057 3302 { 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 )) 3064 3304 { 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); 3069 3314 } 3070 3315 } 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 */ 3331 static 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 } 3082 3377 3083 3378 static LRESULT 3084 3379 TREEVIEW_LButtonDoubleClick (HWND hwnd, WPARAM wParam, LPARAM lParam) 3085 3380 { 3381 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 3086 3382 TREEVIEW_ITEM *wineItem; 3087 3383 POINT pt; 3088 3384 3089 // TRACE (treeview,"\n");3090 3385 pt.x = (INT)LOWORD(lParam); 3091 3386 pt.y = (INT)HIWORD(lParam); 3092 3387 SetFocus (hwnd); 3093 3388 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 3094 3396 wineItem=TREEVIEW_HitTestPoint (hwnd, pt); 3095 3397 if (!wineItem) return 0; 3096 // TRACE (treeview,"item %d \n",(INT)wineItem->hItem);3097 3398 3098 3399 if (TREEVIEW_SendSimpleNotify (hwnd, NM_DBLCLK)!=TRUE) { /* FIXME!*/ … … 3102 3403 } 3103 3404 3104 3105 3405 static LRESULT 3106 3406 TREEVIEW_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) 3107 3407 { 3108 3408 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); 3109 INT iItem;3110 3409 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 } 3111 3424 3112 3425 ht.pt.x = (INT)LOWORD(lParam); 3113 3426 ht.pt.y = (INT)HIWORD(lParam); 3114 3427 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; 3156 3455 3157 3456 /* … … 3159 3458 * and the click occured on the item label... 3160 3459 */ 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; 3174 3470 } 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 }3198 3471 else if ( ht.flags & (TVHT_ONITEMLABEL | TVHT_ONITEMICON)) 3199 3472 { 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 3209 3484 state=1-(wineItem->state>>12); 3210 3485 //TRACE ("state:%x\n", state); … … 3212 3487 wineItem->state|=state<<12; 3213 3488 //TRACE ("state:%x\n", wineItem->state); 3214 TREEVIEW_Refresh(hwnd); 3215 } 3216 } 3489 //CB: todo: optimize 3490 TREEVIEW_QueueRefresh (hwnd); 3491 } 3492 } 3493 3494 setfocus: 3495 SetFocus (hwnd); 3217 3496 return 0; 3218 3497 } … … 3223 3502 { 3224 3503 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 3263 3531 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 } 3277 3533 3278 3534 static LRESULT … … 3392 3648 wineItem->state |= TVIS_SELECTED; 3393 3649 3394 infoPtr->selectedItem =(HTREEITEM)newSelect;3650 infoPtr->selectedItem = (HTREEITEM)newSelect; 3395 3651 3396 3652 TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE); … … 3471 3727 GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont); 3472 3728 logFont.lfWeight=FW_BOLD; 3729 DeleteObject(infoPtr->hBoldFont); 3473 3730 infoPtr->hBoldFont = CreateFontIndirectA (&logFont); 3474 3731 … … 3496 3753 static LRESULT 3497 3754 TREEVIEW_VScroll (HWND hwnd, WPARAM wParam, LPARAM lParam) 3498 3499 3755 { 3500 3756 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd); … … 3504 3760 // TRACE (treeview,"wp %x, lp %lx\n", wParam, lParam); 3505 3761 if (!infoPtr->uInternalStatus & TV_VSCROLL) return FALSE; 3762 3763 if(infoPtr->hwndEdit) 3764 SetFocus(hwnd); 3506 3765 3507 3766 switch (LOWORD (wParam)) { … … 3516 3775 infoPtr->cy += infoPtr->uRealItemHeight; 3517 3776 if (infoPtr->cy > maxHeight) 3518 3777 infoPtr->cy = maxHeight; 3519 3778 break; 3520 3779 case SB_PAGEUP: … … 3527 3786 if (infoPtr->cy == maxHeight) return FALSE; 3528 3787 infoPtr->cy += infoPtr->uVisibleHeight; 3529 if (infoPtr->cy > maxHeight)3530 infoPtr->cy = maxHeight;3788 if (infoPtr->cy > maxHeight) 3789 infoPtr->cy = maxHeight; 3531 3790 break; 3532 3791 case SB_THUMBTRACK: … … 3536 3795 } 3537 3796 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 } 3540 3802 3541 3803 return TRUE; … … 3552 3814 3553 3815 if (!infoPtr->uInternalStatus & TV_HSCROLL) return FALSE; 3816 3817 if(infoPtr->hwndEdit) 3818 SetFocus(hwnd); 3554 3819 3555 3820 switch (LOWORD (wParam)) { … … 3590 3855 } 3591 3856 3857 static 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 } 3592 3888 3593 3889 static LRESULT … … 3614 3910 switch (wParam) { 3615 3911 case VK_UP: 3616 newItem=TREEVIEW_GetPrevListItem ( infoPtr, prevItem);3912 newItem=TREEVIEW_GetPrevListItem (hwnd,infoPtr, prevItem); 3617 3913 3618 3914 if (!newItem) … … 3627 3923 3628 3924 case VK_DOWN: 3629 newItem=TREEVIEW_GetNextListItem ( infoPtr, prevItem);3925 newItem=TREEVIEW_GetNextListItem (hwnd,infoPtr, prevItem); 3630 3926 3631 3927 if (!newItem) … … 3647 3943 case VK_END: 3648 3944 newItem = &infoPtr->items[(INT)infoPtr->TopRootItem]; 3649 newItem = TREEVIEW_GetLastListItem ( infoPtr, newItem);3945 newItem = TREEVIEW_GetLastListItem (hwnd,infoPtr, newItem); 3650 3946 hNewSelection = newItem->hItem; 3651 3947 … … 3656 3952 3657 3953 case VK_LEFT: 3658 if ( (prevItem->cChildren > 0) && (prevItem->state & TVIS_EXPANDED) ) 3954 if ( (prevItem->state & TVIS_EXPANDED) && 3955 TREEVIEW_HasChildren(hwnd, prevItem)) 3659 3956 { 3660 3957 TREEVIEW_Expand(hwnd, TVE_COLLAPSE, prevSelect ); … … 3673 3970 3674 3971 case VK_RIGHT: 3675 if ( ( prevItem->cChildren > 0) || 3676 ( prevItem->cChildren == I_CHILDRENCALLBACK)) 3972 if ( TREEVIEW_HasChildren(hwnd, prevItem) ) 3677 3973 { 3678 3974 if (! (prevItem->state & TVIS_EXPANDED)) … … 3700 3996 3701 3997 newItem=TREEVIEW_GetListItem( 3998 hwnd, 3702 3999 infoPtr, 3703 4000 prevItem, … … 3715 4012 case VK_NEXT: 3716 4013 newItem=TREEVIEW_GetListItem( 4014 hwnd, 3717 4015 infoPtr, 3718 4016 prevItem, … … 3828 4126 return TREEVIEW_GetImageList (hwnd, wParam, lParam); 3829 4127 3830 4128 case TVM_SETIMAGELIST: 3831 4129 return TREEVIEW_SetImageList (hwnd, wParam, lParam); 3832 4130 … … 3852 4150 3853 4151 case TVM_EDITLABELA: 3854 // FIXME (treeview, "Unimplemented msg TVM_EDITLABELA \n"); 3855 return 0; 4152 return TREEVIEW_EditLabelA(hwnd, (HTREEITEM)lParam); 3856 4153 3857 4154 case TVM_EDITLABELW: … … 3883 4180 3884 4181 case TVM_ENDEDITLABELNOW: 3885 return TREEVIEW_EndEditLabelNow (hwnd, wParam, lParam);4182 return TREEVIEW_EndEditLabelNow (hwnd,(BOOL)wParam); 3886 4183 3887 4184 case TVM_GETISEARCHSTRINGA: … … 3980 4277 return TREEVIEW_LButtonDown (hwnd, wParam, lParam); 3981 4278 3982 case WM_LBUTTONUP:3983 return TREEVIEW_LButtonUp (hwnd, wParam, lParam);3984 3985 4279 case WM_LBUTTONDBLCLK: 3986 4280 return TREEVIEW_LButtonDoubleClick (hwnd, wParam, lParam); … … 3989 4283 return TREEVIEW_RButtonDown (hwnd, wParam, lParam); 3990 4284 3991 case WM_RBUTTONUP:3992 return TREEVIEW_RButtonUp (hwnd, wParam, lParam);3993 3994 case WM_MOUSEMOVE:3995 return TREEVIEW_MouseMove (hwnd, wParam, lParam);3996 3997 4285 case WM_STYLECHANGED: 3998 4286 return TREEVIEW_StyleChanged (hwnd, wParam, lParam); … … 4015 4303 return TREEVIEW_VScroll (hwnd, wParam, lParam); 4016 4304 4305 case WM_MOUSEWHEEL: 4306 return TREEVIEW_MouseWheel (hwnd, wParam, lParam); 4307 4017 4308 case WM_DRAWITEM: 4018 //printf ("drawItem\n");4309 //printf ("drawItem\n"); 4019 4310 return DefWindowProcA (hwnd, uMsg, wParam, lParam); 4020 4311 4021 4312 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); 4025 4316 return DefWindowProcA (hwnd, uMsg, wParam, lParam); 4026 4317 } … … 4029 4320 4030 4321 4031 VOID 4032 TREEVIEW_Register (VOID) 4322 VOID TREEVIEW_Register (VOID) 4033 4323 { 4034 4324 WNDCLASSA wndClass; 4035 4036 // TRACE (treeview,"\n");4037 4038 //SvL: Don't check this now4039 // if (GlobalFindAtomA (WC_TREEVIEWA)) return;4040 4325 4041 4326 ZeroMemory (&wndClass, sizeof(WNDCLASSA)); … … 4052 4337 4053 4338 4054 VOID 4055 TREEVIEW_Unregister (VOID) 4056 { 4057 if (GlobalFindAtomA (WC_TREEVIEWA)) 4058 UnregisterClassA (WC_TREEVIEWA, (HINSTANCE)NULL); 4059 } 4060 4339 VOID TREEVIEW_Unregister (VOID) 4340 { 4341 UnregisterClassA (WC_TREEVIEWA, (HINSTANCE)NULL); 4342 } 4343
Note:
See TracChangeset
for help on using the changeset viewer.