int SetParentState(PINO_DATABASE *db, NODE *node, unsigned int state) { int status; NCI nci; NODE *lnode; status = TreeNORMAL; for (lnode = node; lnode && (status & 1); lnode = brother_of(lnode)) { status = SetNodeParentState(db, lnode, &nci, state); if ((status & 1) && (!(nci.flags & NciM_STATE)) && (lnode->INFO.TREE_INFO.child)) status = SetParentState(db, child_of(lnode), state); if ((status & 1) && (!(nci.flags & NciM_STATE)) && (lnode->INFO.TREE_INFO.member)) status = SetParentState(db, member_of(lnode), state); } return status; }
int _TreeTurnOn(void *dbid, int nid_in) { PINO_DATABASE *dblist = (PINO_DATABASE *)dbid; NID *nid = (NID *)&nid_in; int status; int node_num; TREE_INFO *info; NCI nci; NODE *node; if (!(IS_OPEN(dblist))) return TreeNOT_OPEN; if (dblist->remote) return TreeTurnOnRemote(dbid,nid_in); nid_to_tree_nidx(dblist, nid, info, node_num); if (!info) return TreeNNF; status = TreeGetNciLw(info, node_num, &nci); if (~status & 1) return status; if (nci.flags & NciM_STATE) { bitassign(0,nci.flags,NciM_STATE); status = TreePutNci(info, node_num, &nci, 0); if (~status & 1) return status; if (!(nci.flags & NciM_PARENT_STATE)) { nid_to_node(dblist, nid, node); if (node->INFO.TREE_INFO.child) status = SetParentState(dblist, child_of(node), 0); if (node->INFO.TREE_INFO.member) status = SetParentState(dblist, member_of(node), 0); } else status = TreePARENT_OFF; } else { status = TreeUnLockNci(info, 0, node_num); if (status & 1) status = TreeALREADY_ON; } return status; }
static void NSISCALL SetParentState(HWND hwTree, HTREEITEM hItem) { TVITEM tvItem; int iState = 0, iItrState, *iFlags; HTREEITEM hParent = TreeView_GetParent(hwTree, hItem); if (!hParent) return; hItem = TreeView_GetChild(hwTree, hParent); tvItem.mask = TVIF_STATE | TVIF_PARAM; tvItem.stateMask = TVIS_STATEIMAGEMASK; while (hItem) { tvItem.hItem = hItem; TreeView_GetItem(hwTree, &tvItem); iItrState = tvItem.state >> 12; iState |= iItrState % 3 ? iItrState % 3 : 3; hItem = TreeView_GetNextSibling(hwTree, hItem); } tvItem.hItem = hParent; TreeView_GetItem(hwTree, &tvItem); iFlags = &(g_sections[tvItem.lParam].flags); *iFlags &= ~(SF_SELECTED|SF_PSELECTED); if (iState == 2) *iFlags |= SF_SELECTED; if (iState == 3) *iFlags |= SF_PSELECTED; tvItem.state = INDEXTOSTATEIMAGEMASK(iState); TreeView_SetItem(hwTree, &tvItem); SetParentState(hwTree, hParent); }
static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HTREEITEM *hTreeItems; static HIMAGELIST hImageList; HWND hwndCombo1 = GetUIItem(IDC_COMBO1); HWND hwndTree1 = GetUIItem(IDC_TREE1); extern HWND g_SectionHack; section *sections=g_sections; if (uMsg == WM_INITDIALOG) { int doLines=0; HTREEITEM Par; HBITMAP hBMcheck1; int x, lastGoodX, i, noCombo=2; g_SectionHack=hwndDlg; if (hTreeItems) GlobalFree(hTreeItems); hTreeItems=(HTREEITEM*)my_GlobalAlloc(sizeof(HTREEITEM)*num_sections); hBMcheck1=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)); oldTreeWndProc=SetWindowLong(hwndTree1,GWL_WNDPROC,(DWORD)newTreeWndProc); if (hImageList) ImageList_Destroy(hImageList); hImageList = ImageList_Create(16,16, ILC_COLOR32|ILC_MASK, 6, 0); ImageList_AddMasked(hImageList,hBMcheck1,RGB(255,0,255)); TreeView_SetImageList(hwndTree1, hImageList, TVSIL_STATE); #ifndef TVM_SETITEMHEIGHT #define TVM_SETITEMHEIGHT (TV_FIRST + 27) #endif #ifndef TVM_GETITEMHEIGHT #define TVM_GETITEMHEIGHT (TV_FIRST + 28) #endif if (SendMessage(hwndTree1, TVM_GETITEMHEIGHT, 0, 0) < 16) SendMessage(hwndTree1, TVM_SETITEMHEIGHT, 16, 0); DeleteObject(hBMcheck1); for (i = 0; i < NSIS_MAX_INST_TYPES+1; i++) { if (g_header->install_types[i]) { int j; if (i != NSIS_MAX_INST_TYPES) noCombo = 0; GetNSISString(g_tmp,g_header->install_types[i]); j=SendMessage(hwndCombo1,CB_ADDSTRING,0,(LPARAM)g_tmp); SendMessage(hwndCombo1,CB_SETITEMDATA,j,i); if (i == g_exec_flags.cur_insttype) SendMessage(hwndCombo1, CB_SETCURSEL, j, 0); } } if (!noCombo) ShowWindow(hwndCombo1,SW_SHOW); SetUITextFromLang(IDC_TEXT1,this_page->parms[1+noCombo]); SetUITextFromLang(IDC_TEXT2,this_page->parms[2+noCombo]); Par=NULL; for (lastGoodX = x = 0; x < num_sections; x ++) { section *sec=sections+x; if (sec->name_ptr) { TVINSERTSTRUCT tv; tv.hParent=Par; tv.hInsertAfter=TVI_LAST; tv.item.mask=TVIF_PARAM|TVIF_TEXT|TVIF_STATE; tv.item.lParam=x; tv.item.pszText=GetNSISStringTT(sec->name_ptr); tv.item.stateMask=TVIS_STATEIMAGEMASK|TVIS_EXPANDED|TVIS_BOLD; { int l=1; // Sf_SELECTED == 1 l += sec->flags & SF_SELECTED; //if (sec->flags & SF_SELECTED) l++; if (sec->flags & SF_RO) l+=3; tv.item.state=INDEXTOSTATEIMAGEMASK(l); } //if (sec->flags&SF_BOLD) { // SF_BOLD << 1 == 16 == TVIS_BOLD tv.item.state|=(sec->flags&SF_BOLD)<<1; } if (sec->flags&SF_SUBSEC) { tv.item.mask|=TVIF_CHILDREN; tv.item.cChildren=1; //if (sec->flags&SF_EXPAND) // TVIS_EXPANDED == SF_EXPAND tv.item.state|=sec->flags&SF_EXPAND; Par = hTreeItems[x] = TreeView_InsertItem(hwndTree1,&tv); doLines=1; } else if (sec->flags&SF_SUBSECEND) { SetParentState(hwndTree1,hTreeItems[lastGoodX]); Par=TreeView_GetParent(hwndTree1,Par); } else { lastGoodX = x; hTreeItems[x] = TreeView_InsertItem(hwndTree1,&tv); } } } if (!doLines) { SetWindowLong(hwndTree1,GWL_STYLE,GetWindowLong(hwndTree1,GWL_STYLE)&~(TVS_LINESATROOT)); } SendMessage(hwndTree1,WM_VSCROLL,SB_TOP,0); uMsg = g_exec_flags.insttype_changed ? WM_NOTIFY_INSTTYPE_CHANGE : WM_IN_UPDATEMSG; } if (uMsg == WM_NOTIFY_SECTEXT) // update text { int x=wParam; int ns=lParam; TVITEM tv; if (tv.hItem=hTreeItems[x]) { tv.mask=TVIF_TEXT; tv.pszText=GetNSISStringTT(ns); TreeView_SetItem(hwndTree1,&tv); } } if (uMsg == WM_NOTIFY_SECFLAGS) // change flags { int flags = sections[wParam].flags; TVITEM tvItem; if (!(tvItem.hItem = hTreeItems[wParam])) return 0; tvItem.mask = TVIF_STATE; tvItem.stateMask = TVIS_BOLD; tvItem.state = 0; //if (flags&SF_BOLD) tvItem.state |= TVIS_BOLD; // SF_BOLD << 1 == 16 == TVIS_BOLD tvItem.state|=(flags&SF_BOLD)<<1; TreeView_SetItem(hwndTree1, &tvItem); TreeView_Expand(hwndTree1, tvItem.hItem, flags & SF_EXPAND ? TVE_EXPAND : TVE_COLLAPSE); if ((flags & (SF_PSELECTED | SF_SELECTED)) != SF_PSELECTED) { CheckTreeItem(hwndTree1, tvItem.hItem, flags & SF_SELECTED); } } if (uMsg == WM_NOTIFY || uMsg == WM_TREEVIEW_KEYHACK) { LPNMHDR lpnmh = (LPNMHDR) lParam; if (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->idFrom == IDC_TREE1) { if (!(g_flags&CH_FLAGS_NO_CUSTOM) && (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->code == NM_CLICK)) { TVITEM tvItem; if (uMsg != WM_TREEVIEW_KEYHACK) tvItem.hItem=TreeHitTest(hwndTree1); else tvItem.hItem=TreeView_GetSelection(hwndTree1); if (tvItem.hItem) { int iState; tvItem.mask = TVIF_STATE|TVIF_PARAM; TreeView_GetItem(hwndTree1, &tvItem); iState = tvItem.state >> 12; if (iState < 4) // not RO { if (iState == 2) // already checked { sections[tvItem.lParam].flags&=~SF_SELECTED; CheckTreeItem(hwndTree1,tvItem.hItem,0); } else { sections[tvItem.lParam].flags|=SF_SELECTED; CheckTreeItem(hwndTree1,tvItem.hItem,1); } lParam = 0; wParam = 1; uMsg = WM_IN_UPDATEMSG; } // not ro } // was valid click } // was click or hack