From b26198b243f682cfd66aa5d06acbb62d6d35206c Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 20 Feb 2014 18:43:33 +0000 Subject: attempt to revive NAS git-svn-id: http://svn.miranda-ng.org/main/trunk@8194 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/!Deprecated/NewAwaySysMod/ContactList.cpp | 905 ---------------------- 1 file changed, 905 deletions(-) delete mode 100644 plugins/!Deprecated/NewAwaySysMod/ContactList.cpp (limited to 'plugins/!Deprecated/NewAwaySysMod/ContactList.cpp') diff --git a/plugins/!Deprecated/NewAwaySysMod/ContactList.cpp b/plugins/!Deprecated/NewAwaySysMod/ContactList.cpp deleted file mode 100644 index 70b26d1d57..0000000000 --- a/plugins/!Deprecated/NewAwaySysMod/ContactList.cpp +++ /dev/null @@ -1,905 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "ContactList.h" -#include "Properties.h" - -#define INTM_CONTACTDELETED (WM_USER + 1) -#define INTM_ICONCHANGED (WM_USER + 2) -#define INTM_INVALIDATE (WM_USER + 3) - -#define HCONTACT_ISGROUP 0x80000000 -#define HCONTACT_ISINFO 0xFFFF0000 -#define IsHContactInfo(h) (((unsigned)(h) & HCONTACT_ISINFO) == HCONTACT_ISINFO) -#define IsHContactGroup(h) (!IsHContactInfo(h) && ((unsigned)(h) & HCONTACT_ISGROUP)) -#define IsHContactContact(h) (((unsigned)(h) & HCONTACT_ISGROUP) == 0) - -#define EXTRAICON_XSTEP (GetSystemMetrics(SM_CXSMICON) + 1) - -static HANDLE hCLWindowList; - - -static int CLContactDeleted(WPARAM wParam, LPARAM lParam) -{ - WindowList_Broadcast(hCLWindowList, INTM_CONTACTDELETED, wParam, lParam); - return 0; -} - -static int CLContactIconChanged(WPARAM wParam, LPARAM lParam) -{ - WindowList_Broadcast(hCLWindowList, INTM_ICONCHANGED, wParam, lParam); - return 0; -} - -static int CLIconsChanged(WPARAM wParam, LPARAM lParam) -{ - WindowList_Broadcast(hCLWindowList, INTM_INVALIDATE, 0, 0); - return 0; -} - -void LoadCListModule() -{ - hCLWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); - HookEvent(ME_DB_CONTACT_DELETED, CLContactDeleted); - HookEvent(ME_CLIST_CONTACTICONCHANGED, CLContactIconChanged); - HookEvent(ME_SKIN_ICONSCHANGED, CLIconsChanged); -} - - -static LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - CCList *dat = CWndUserData(hWnd).GetCList(); - switch (Msg) - { - case WM_NOTIFY: - { - LPNMHDR pnmh = (LPNMHDR)lParam; - if (pnmh->hwndFrom == dat->hTreeView) - { - switch (pnmh->code) - { - case TVN_ITEMEXPANDED: // just set an appropriate group image - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; - TVITEM tvItem; - tvItem.hItem = pnmtv->itemNew.hItem; - tvItem.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvItem.iImage = tvItem.iSelectedImage = (pnmtv->itemNew.state & TVIS_EXPANDED) ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT; - TreeView_SetItem(dat->hTreeView, &tvItem); - } break; - case TVN_SELCHANGED: - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; - TREEITEMARRAY OldSelection = dat->SelectedItems; - int I; - for (I = 0; I < dat->SelectedItems.GetSize(); I++) - { - if (dat->SelectedItems[I] != pnmtv->itemNew.hItem) - { - TreeView_SetItemState(dat->hTreeView, dat->SelectedItems[I], 0, TVIS_SELECTED); - } - } - dat->SelectedItems.RemoveAll(); - if (pnmtv->itemNew.hItem) - { - dat->SelectedItems.AddElem(pnmtv->itemNew.hItem); - dat->SelectGroups(pnmtv->itemNew.hItem, true); - } - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = dat->hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); - nm.OldSelection = &OldSelection; - nm.NewSelection = &dat->SelectedItems; - SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); - } break; - case TVN_DELETEITEM: - { - if (dat->Items.GetSize()) // if Items size = 0, then this TVN_DELETEITEM came after WM_DESTROY, so there is no need to do anything - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; - TREEITEMARRAY OldSelection = dat->SelectedItems; - int Index = dat->SelectedItems.Find(pnmtv->itemOld.hItem); - if (Index != -1) - { - dat->SelectedItems.RemoveElem(Index); - } - // find an item to pass to SelectGroups() - HTREEITEM hItem = TreeView_GetNextSibling(dat->hTreeView, pnmtv->itemOld.hItem); - if (!hItem) - { - hItem = TreeView_GetPrevSibling(dat->hTreeView, pnmtv->itemOld.hItem); - if (!hItem) - { - hItem = TreeView_GetParent(dat->hTreeView, pnmtv->itemOld.hItem); - } - } - if (hItem) // if it wasn't one of the root items - { - dat->SelectGroups(hItem, dat->SelectedItems.Find(hItem) != -1); - } - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = dat->hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); - nm.OldSelection = &OldSelection; - nm.NewSelection = &dat->SelectedItems; - SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); - dat->Items[pnmtv->itemOld.lParam].hContact = INVALID_HANDLE_VALUE; - } - } break; - case NM_CUSTOMDRAW: - { - LPNMTVCUSTOMDRAW lpNMCD = (LPNMTVCUSTOMDRAW)lParam; - switch (lpNMCD->nmcd.dwDrawStage) - { - case CDDS_PREPAINT: // the control is about to start painting - { - return CDRF_NOTIFYITEMDRAW; // instruct the control to return information when it draws items - } break; - case CDDS_ITEMPREPAINT: - { - return CDRF_NOTIFYPOSTPAINT; - } break; - case CDDS_ITEMPOSTPAINT: - { - RECT rc; - if (TreeView_GetItemRect(dat->hTreeView, (HTREEITEM)lpNMCD->nmcd.dwItemSpec, &rc, false)) - { - int I; - for (I = 0; I < MAXEXTRAICONS; I++) - { - BYTE nIndex = dat->Items[lpNMCD->nmcd.lItemlParam].ExtraIcons[I]; - if (nIndex != CLC_EXTRAICON_EMPTY) - { - ImageList_DrawEx(dat->ExtraImageList, nIndex, lpNMCD->nmcd.hdc, rc.right - EXTRAICON_XSTEP * (I + 1), rc.top, 0, 0, /*GetSysColor(COLOR_WINDOW)*/CLR_NONE, CLR_NONE, ILD_NORMAL); - } - } - } - } break; - } - } break; - } - } - } - } - return CallWindowProc(dat->OrigParentProc, hWnd, Msg, wParam, lParam); -} - - -static LRESULT CALLBACK ContactListSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - CCList *dat = CWndUserData(GetParent(hWnd)).GetCList(); - switch (Msg) - { - case INTM_CONTACTDELETED: // wParam = (HANDLE)hContact - { - HTREEITEM hItem = dat->FindContact((HANDLE)wParam); - if (hItem) - { - TreeView_DeleteItem(hWnd, hItem); - } - } break; - case INTM_ICONCHANGED: // wParam = (HANDLE)hContact, lParam = IconID - { - TVITEM tvi; - tvi.hItem = dat->FindContact((HANDLE)wParam); - if (tvi.hItem) - { - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvi.iImage = tvi.iSelectedImage = lParam; - TreeView_SetItem(hWnd, &tvi); - dat->SortContacts(); - InvalidateRect(hWnd, NULL, false); - } - } break; - case INTM_INVALIDATE: - { - InvalidateRect(hWnd, NULL, true); - } break; - case WM_RBUTTONDOWN: - { - SetFocus(hWnd); - TVHITTESTINFO hitTest; - hitTest.pt.x = (short)LOWORD(lParam); - hitTest.pt.y = (short)HIWORD(lParam); - TreeView_HitTest(hWnd, &hitTest); - if (hitTest.hItem && hitTest.flags & TVHT_ONITEM) - { - TreeView_SelectItem(hWnd, hitTest.hItem); - } - return DefWindowProc(hWnd, Msg, wParam, lParam); - } break; - case WM_LBUTTONDOWN: - { - POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; - DWORD hitFlags; - HTREEITEM hItem = dat->HitTest(&pt, &hitFlags); - if (!hItem) - { - break; - } - if (hitFlags & MCLCHT_ONITEMICON) - { - if (TreeView_GetChild(hWnd, hItem)) // if it's a group, then toggle its state - { - NMTREEVIEW nmtv; - nmtv.hdr.hwndFrom = hWnd; - nmtv.hdr.idFrom = GetDlgCtrlID(hWnd); - nmtv.hdr.code = TVN_ITEMEXPANDING; - nmtv.action = TVE_TOGGLE; - nmtv.itemNew.hItem = hItem; - nmtv.itemNew.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM; - TreeView_GetItem(hWnd, &nmtv.itemNew); - nmtv.ptDrag = pt; - if (SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmtv)) - { - return 0; - } - HTREEITEM hOldSelItem = TreeView_GetSelection(hWnd); - TreeView_Expand(hWnd, hItem, TVE_TOGGLE); - HTREEITEM hNewSelItem = TreeView_GetSelection(hWnd); - if (hNewSelItem != hOldSelItem) - { - TreeView_SetItemState(hWnd, hOldSelItem, (dat->SelectedItems.Find(hOldSelItem) == -1) ? 0 : TVIS_SELECTED, TVIS_SELECTED); - TreeView_SetItemState(hWnd, hNewSelItem, (dat->SelectedItems.Find(hNewSelItem) == -1) ? 0 : TVIS_SELECTED, TVIS_SELECTED); - } - nmtv.hdr.code = TVN_ITEMEXPANDED; - TreeView_GetItem(hWnd, &nmtv.itemNew); - SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmtv); - return 0; - } - } - if (hitFlags & MCLCHT_ONITEM) - { - if (wParam & MK_CONTROL) - { - SetFocus(hWnd); - TREEITEMARRAY OldSelection = dat->SelectedItems; - int nIndex = dat->SelectedItems.Find(hItem); - if (nIndex == -1) - { - TreeView_SetItemState(hWnd, hItem, TVIS_SELECTED, TVIS_SELECTED); - dat->SelectedItems.AddElem(hItem); - } else - { - TreeView_SetItemState(hWnd, hItem, 0, TVIS_SELECTED); - dat->SelectedItems.RemoveElem(nIndex); - } - dat->SelectGroups(hItem, nIndex == -1); - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = hWnd; - nm.hdr.idFrom = GetDlgCtrlID(hWnd); - nm.OldSelection = &OldSelection; - nm.NewSelection = &dat->SelectedItems; - SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm); - return 0; - } else - { - if (hItem == TreeView_GetSelection(hWnd) && (dat->SelectedItems.GetSize() != 1 || (dat->SelectedItems.GetSize() == 1 && dat->SelectedItems[0] != hItem))) // if it was a click on the selected item and there's need to do something in this case, then send SELCHANGED notification by ourselves, as the tree control doesn't do anything - { - TreeView_SetItemState(hWnd, hItem, TVIS_SELECTED, TVIS_SELECTED); - NMTREEVIEW nm = {0}; - nm.hdr.code = TVN_SELCHANGED; - nm.hdr.hwndFrom = hWnd; - nm.hdr.idFrom = GetDlgCtrlID(hWnd); - nm.itemOld.hItem = TreeView_GetSelection(hWnd); - nm.itemOld.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM; - TreeView_GetItem(hWnd, &nm.itemOld); - nm.itemNew = nm.itemOld; - SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm); - } - } - } - } break; - case WM_SETFOCUS: - case WM_KILLFOCUS: - { - int I; - for (I = 0; I < dat->SelectedItems.GetSize(); I++) - { - RECT rc; - if (TreeView_GetItemRect(hWnd, dat->SelectedItems[I], &rc, false)) - { - InvalidateRect(hWnd, &rc, false); - } - } - } break; - case WM_SIZE: - case WM_HSCROLL: - { - InvalidateRect(hWnd, NULL, false); - } break; - case WM_MEASUREITEM: - { - if (!wParam) // if the message was sent by a menu - { - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - } - } break; - case WM_DRAWITEM: - { - if (!wParam) // if the message was sent by a menu - { - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - } - } break; - case WM_CONTEXTMENU: - { - POINT pt; - pt.x = (short)LOWORD(lParam); - pt.y = (short)HIWORD(lParam); - HTREEITEM hItem = NULL; - if (pt.x == -1 && pt.y == -1) - { - if (dat->SelectedItems.GetSize() == 1) - { - hItem = dat->SelectedItems[0]; - TreeView_EnsureVisible(hWnd, hItem); - RECT rc; - TreeView_GetItemRect(hWnd, hItem, &rc, true); - pt.x = rc.left; - pt.y = rc.bottom; - } - } else - { - DWORD hitFlags; - ScreenToClient(hWnd, &pt); - hItem = dat->HitTest(&pt, &hitFlags); - if (!(hitFlags & MCLCHT_ONITEM)) - { - hItem = NULL; - } - } - if (hItem) - { - HANDLE hContact = dat->GetItemData(hItem).hContact; - if (IsHContactContact(hContact)) - { - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)hContact, 0); - if (hMenu) - { - ClientToScreen(hWnd, &pt); - CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, NULL), MPCF_CONTACTMENU), (LPARAM)hContact); - DestroyMenu(hMenu); - return 0; - } - } - } - } break; - case WM_DESTROY: - { - if (dat->ExtraImageList) - { - ImageList_Destroy(dat->ExtraImageList); - } - dat->SelectedItems.RemoveAll(); - dat->Items.RemoveAll(); - } break; - } - return CallWindowProc(dat->OrigTreeViewProc, hWnd, Msg, wParam, lParam); -} - - -CCList::CCList(HWND hTreeView): hTreeView(hTreeView), ExtraImageList(NULL) -{ - CWndUserData(GetParent(hTreeView)).SetCList(this); - OrigTreeViewProc = (WNDPROC)SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (LONG_PTR)ContactListSubclassProc); - OrigParentProc = (WNDPROC)SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)ParentSubclassProc); - TreeView_SetImageList(hTreeView, CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), TVSIL_NORMAL); - WindowList_Add(hCLWindowList, hTreeView, NULL); - TreeView_SetIndent(hTreeView, 5); // doesn't set it less than the initial value on my system, and I guess it's because of icons... but who knows - maybe it will work somewhere -} - - -CCList::~CCList() -{ - WindowList_Remove(hCLWindowList, hTreeView); - _ASSERT(GetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC) == (LONG_PTR)ParentSubclassProc); // we won't allow anyone to change our WNDPROC. otherwise we're not sure that we're setting the right WNDPROC back - SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (LONG_PTR)OrigTreeViewProc); - SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)OrigParentProc); - CWndUserData(GetParent(hTreeView)).SetCList(NULL); -} - - -HTREEITEM CCList::AddContact(HANDLE hContact) -// adds a new contact if it doesn't exist yet; returns its hItem -{ - _ASSERT(IsHContactContact(hContact)); - HTREEITEM hContactItem = FindContact(hContact); - if (hContactItem) - { - return hContactItem; - } - TVINSERTSTRUCT tvIns; - ZeroMemory(&tvIns, sizeof(tvIns)); - tvIns.hParent = AddGroup(DBGetContactSettingString(hContact, "CList", "Group", _T(""))); -/* if (!tvIns.hParent) - { - return NULL; - }*/ // <- place hidden contacts in the root anyway, as otherwise we won't see icq contacts that are hidden beneath metacontacts; TODO: show metacontacts as groups?? - tvIns.item.pszText = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); - tvIns.hInsertAfter = TVI_ROOT; - tvIns.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; - tvIns.item.iImage = tvIns.item.iSelectedImage = CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0); - tvIns.item.lParam = Items.AddElem(CCLItemData(hContact)); - return TreeView_InsertItem(hTreeView, &tvIns); -} - - -typedef struct -{ - HANDLE hGroup; - TCString GroupName; -} sGroupEnumData; - -int GroupEnum(const char *szSetting, LPARAM lParam) -{ - sGroupEnumData *GroupEnumData = (sGroupEnumData*)lParam; - TCString GroupName = DBGetContactSettingString(NULL, "CListGroups", szSetting, _T(" ")); - if (!lstrcmp(GroupEnumData->GroupName, &GroupName[1])) - { - GroupEnumData->hGroup = (HANDLE)(atol(szSetting) | HCONTACT_ISGROUP); - } - return 0; -} - -HTREEITEM CCList::AddGroup(TCString GroupName) -// adds a new group if it doesn't exist yet; returns its hItem -{ - if (GroupName == _T("")) - { - return TVI_ROOT; - } - sGroupEnumData GroupEnumData; - GroupEnumData.GroupName = GroupName; - GroupEnumData.hGroup = NULL; - DBCONTACTENUMSETTINGS dbEnum; - ZeroMemory(&dbEnum, sizeof(dbEnum)); - dbEnum.lParam = (LPARAM)&GroupEnumData; - dbEnum.pfnEnumProc = GroupEnum; - dbEnum.szModule = "CListGroups"; - CallService(MS_DB_CONTACT_ENUMSETTINGS, NULL, (LPARAM)&dbEnum); - if (!GroupEnumData.hGroup) // means there is no such group in the groups list - { - return NULL; - } - HTREEITEM hGroupItem = FindContact(GroupEnumData.hGroup); - if (hGroupItem) - { - return hGroupItem; // exists already, just return its handle - } - TVINSERTSTRUCT tvIns = {0}; - tvIns.hParent = TVI_ROOT; - tvIns.item.pszText = _tcsrchr(GroupName, '\\'); - if (tvIns.item.pszText) - { - TCString ParentGroupName(_T("")); - tvIns.hParent = AddGroup(ParentGroupName.DiffCat(GroupName, tvIns.item.pszText)); - tvIns.item.pszText++; - } else - { - tvIns.item.pszText = GroupName; - } - tvIns.hInsertAfter = TVI_ROOT; - tvIns.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; - tvIns.item.state = tvIns.item.stateMask = TVIS_BOLD | TVIS_EXPANDED; - tvIns.item.iImage = tvIns.item.iSelectedImage = IMAGE_GROUPOPEN; - tvIns.item.lParam = Items.AddElem(CCLItemData(GroupEnumData.hGroup)); - return TreeView_InsertItem(hTreeView, &tvIns); -} - - -HTREEITEM CCList::AddInfo(TCString Title, HTREEITEM hParent, HTREEITEM hInsertAfter, LPARAM lParam, HICON hIcon) -{ - TVINSERTSTRUCT tvi = {0}; - tvi.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; - tvi.item.pszText = Title; - tvi.hParent = hParent; - tvi.hInsertAfter = hInsertAfter; - tvi.item.lParam = Items.AddElem(CCLItemData()); - Items[tvi.item.lParam].lParam = lParam; - tvi.item.state = tvi.item.stateMask = TVIS_BOLD | TVIS_EXPANDED; - if (hIcon) - { - HIMAGELIST iml = TreeView_GetImageList(hTreeView, TVSIL_NORMAL); - tvi.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvi.item.iImage = tvi.item.iSelectedImage = ImageList_AddIcon(iml, hIcon); // we don't check for duplicate icons, but I think that's ok, judging that the check will require some pretty significant amount of additional coding - TreeView_SetImageList(hTreeView, iml, TVSIL_NORMAL); - } - return TreeView_InsertItem(hTreeView, &tvi); -} - - -void CCList::SetInfoIcon(HTREEITEM hItem, HICON hIcon) -{ - _ASSERT(hItem && hIcon && GetItemType(hItem) == MCLCIT_INFO); - TVITEM tvi = {0}; - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvi.hItem = hItem; - HIMAGELIST iml = TreeView_GetImageList(hTreeView, TVSIL_NORMAL); - tvi.iImage = tvi.iSelectedImage = ImageList_AddIcon(iml, hIcon); // again, we don't check for duplicate icons - TreeView_SetImageList(hTreeView, iml, TVSIL_NORMAL); - TreeView_SetItem(hTreeView, &tvi); -} - - -static int CALLBACK CompareItemsCallback(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) -{ - CCList *dat = (CCList*)lParamSort; - if (IsHContactInfo(dat->Items[lParam1].hContact)) // Info items precede all other items - { - return (IsHContactInfo(dat->Items[lParam2].hContact)) ? 0 : -1; - } else if (IsHContactInfo(dat->Items[lParam2].hContact)) - { - return 1; - } - if (IsHContactGroup(dat->Items[lParam1].hContact)) // groups precede contacts - { - if (IsHContactGroup(dat->Items[lParam2].hContact)) - { - return (unsigned)dat->Items[lParam1].hContact - (unsigned)dat->Items[lParam2].hContact; - } else - { - return -1; - } - } else if (IsHContactGroup(dat->Items[lParam2].hContact)) - { - return 1; - } - return CallService(MS_CLIST_CONTACTSCOMPARE, (WPARAM)dat->Items[lParam1].hContact, (LPARAM)dat->Items[lParam2].hContact); -} - -void CCList::SortContacts() -{ - TVSORTCB tvSort; - ZeroMemory(&tvSort, sizeof(tvSort)); - tvSort.lpfnCompare = CompareItemsCallback; - tvSort.hParent = TVI_ROOT; - tvSort.lParam = (LPARAM)this; - while (tvSort.hParent) - { - TreeView_SortChildrenCB(hTreeView, &tvSort, 0); - tvSort.hParent = GetNextItem(MCLGN_NEXT | MCLGN_GROUP | MCLGN_MULTILEVEL, tvSort.hParent); - } -} - - -int CCList::GetExtraImage(HTREEITEM hItem, int iColumn) // returns iImage, or CLC_EXTRAICON_EMPTY -{ - _ASSERT(iColumn < MAXEXTRAICONS); - return GetItemData(hItem).ExtraIcons[iColumn]; -} - - -void CCList::SetExtraImage(HTREEITEM hItem, int iColumn, int iImage) // set iImage to CLC_EXTRAICON_EMPTY to reset image -{ - _ASSERT(iColumn < MAXEXTRAICONS); - GetItemData(hItem).ExtraIcons[iColumn] = iImage; - RECT rc; - if (TreeView_GetItemRect(hTreeView, hItem, &rc, false)) - { - InvalidateRect(hTreeView, &rc, true); - } -} - - -void CCList::SetExtraImageList(HIMAGELIST hImgList) -{ - ExtraImageList = hImgList; - InvalidateRect(hTreeView, NULL, false); -} - - -int CCList::GetItemType(HTREEITEM hItem) // returns a MCLCIT_ (see below) -{ - HANDLE hContact = GetItemData(hItem).hContact; - return (IsHContactInfo(hContact)) ? MCLCIT_INFO : ((IsHContactGroup(hContact)) ? MCLCIT_GROUP : MCLCIT_CONTACT); -} - - -DWORD CCList::GetItemTypeAsCLGNFlag(HTREEITEM hItem) -{ - HANDLE hContact = GetItemData(hItem).hContact; - return (IsHContactInfo(hContact)) ? MCLGN_INFO : ((IsHContactGroup(hContact)) ? MCLGN_GROUP : MCLGN_CONTACT); -} - - -HTREEITEM CCList::GetNextItem(DWORD Flags, HTREEITEM hItem) -{ - switch (Flags & ~(MCLGN_MULTILEVEL | MCLGN_NOTCHILD | MCLGN_ANY)) - { - case MCLGN_ROOT: - { - return TreeView_GetRoot(hTreeView); - } break; - case MCLGN_LAST: - { - HTREEITEM hNextItem = TVI_ROOT; - do - { - hItem = hNextItem; - hNextItem = TreeView_GetLastChild(hTreeView, hNextItem); - } while (hNextItem); - return (hItem == TVI_ROOT) ? NULL : hItem; - } break; - case MCLGN_CHILD: - { - return TreeView_GetChild(hTreeView, hItem); - } break; - case MCLGN_LASTCHILD: - { - return TreeView_GetLastChild(hTreeView, hItem); - } break; - case MCLGN_PARENT: - { - return TreeView_GetParent(hTreeView, hItem); - } break; - case MCLGN_NEXT: - { - do - { - if (Flags & MCLGN_MULTILEVEL) - { - HTREEITEM hNextItem = NULL; - if ((Flags & MCLGN_NOTCHILD) != MCLGN_NOTCHILD) - { - hNextItem = TreeView_GetChild(hTreeView, hItem); - } - if (!hNextItem) - { - hNextItem = TreeView_GetNextSibling(hTreeView, hItem); - while (!hNextItem) // move back until we find next sibling of the item or one of its parents - { - hItem = TreeView_GetParent(hTreeView, hItem); - if (!hItem) // means it was the root, there are no items left. - { - break; // returns NULL as the next item - } - hNextItem = TreeView_GetNextSibling(hTreeView, hItem); - } - } - hItem = hNextItem; - } else - { - hItem = TreeView_GetNextSibling(hTreeView, hItem); - } - Flags &= ~(MCLGN_NOTCHILD & ~MCLGN_MULTILEVEL); // clear MCLGN_NOTCHILD flag - } while (hItem && !(Flags & GetItemTypeAsCLGNFlag(hItem))); - return hItem; - } break; - case MCLGN_PREV: - { - do - { - if (Flags & MCLGN_MULTILEVEL) - { - HTREEITEM hNextItem = TreeView_GetPrevSibling(hTreeView, hItem); - if (hNextItem) - { - if ((Flags & MCLGN_NOTCHILD) != MCLGN_NOTCHILD) - { - while (hNextItem) - { - hItem = hNextItem; - hNextItem = TreeView_GetLastChild(hTreeView, hItem); - } - } else - { - hItem = hNextItem; - } - } else - { - hItem = TreeView_GetParent(hTreeView, hItem); - } - } else - { - hItem = TreeView_GetPrevSibling(hTreeView, hItem); - } - Flags &= ~(MCLGN_NOTCHILD & ~MCLGN_MULTILEVEL); // clear MCLGN_NOTCHILD flag - } while (hItem && !(Flags & GetItemTypeAsCLGNFlag(hItem))); - return hItem; - } break; - default: - { - _ASSERT(0); - } break; - } - return NULL; -} - - -HANDLE CCList::GethContact(HTREEITEM hItem) // returns hContact, hGroup or hInfo -{ - HANDLE hContact = GetItemData(hItem).hContact; - if (IsHContactContact(hContact)) - { - return hContact; - } else if (IsHContactGroup(hContact)) - { - return (HANDLE)((int)hContact & ~HCONTACT_ISGROUP); - } else - { - return (HANDLE)((int)hContact & ~HCONTACT_ISINFO); - } -} - - -HTREEITEM CCList::HitTest(LPPOINT pt, PDWORD hitFlags) // pt is relative to control; returns hItem or NULL -{ - TVHITTESTINFO hti; - hti.pt = *pt; - TreeView_HitTest(hTreeView, &hti); - *hitFlags = 0; - if (hti.flags & TVHT_ABOVE) - { - *hitFlags |= MCLCHT_ABOVE; - } - if (hti.flags & TVHT_BELOW) - { - *hitFlags |= MCLCHT_BELOW; - } - if (hti.flags & TVHT_TOLEFT) - { - *hitFlags |= MCLCHT_TOLEFT; - } - if (hti.flags & TVHT_TORIGHT) - { - *hitFlags |= MCLCHT_TORIGHT; - } - if (hti.flags & TVHT_NOWHERE) - { - *hitFlags |= MCLCHT_NOWHERE; - } - if (hti.flags & TVHT_ONITEMINDENT) - { - *hitFlags |= MCLCHT_ONITEMINDENT; - } - if (hti.flags & (TVHT_ONITEMICON | TVHT_ONITEMSTATEICON)) - { - *hitFlags |= MCLCHT_ONITEMICON; - } - if (hti.flags & TVHT_ONITEMLABEL) - { - *hitFlags |= MCLCHT_ONITEMLABEL; - } - if (hti.flags & TVHT_ONITEMRIGHT) - { - *hitFlags |= MCLCHT_ONITEMRIGHT; - } - if (hti.flags & (TVHT_ONITEMINDENT | TVHT_ONITEM | TVHT_ONITEMRIGHT)) - { - // extraicon tests - RECT rc; - if (TreeView_GetItemRect(hTreeView, hti.hItem, &rc, false)) - { - int nIndex = (rc.right - pt->x - 1) / EXTRAICON_XSTEP; - if (nIndex >= 0 && nIndex < MAXEXTRAICONS && GetItemData(hti.hItem).ExtraIcons[nIndex] != CLC_EXTRAICON_EMPTY) - { - *hitFlags |= MCLCHT_ONITEMEXTRA | (nIndex << 24); - } - } - } - return hti.hItem; -} - - -int CCList::Array_SetItemState(HTREEITEM hItem, bool bSelected) -{ - _ASSERT(hItem); - int nIndex = SelectedItems.Find(hItem); - if (nIndex == -1 && bSelected) - { - return SelectedItems.AddElem(hItem); - } else if (nIndex != -1 && !bSelected) - { - SelectedItems.RemoveElem(nIndex); - return -1; - } - return nIndex; -} - - -CCLItemData& CCList::GetItemData(HTREEITEM hItem) -{ - _ASSERT(hItem && hItem != INVALID_HANDLE_VALUE); - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = hItem; - int Res = TreeView_GetItem(hTreeView, &tvi); - _ASSERT(Res); - return Items[tvi.lParam]; -} - - -HTREEITEM CCList::TreeView_GetLastChild(HWND hTreeView, HTREEITEM hItem) -{ - HTREEITEM hPrevItem = TreeView_GetChild(hTreeView, hItem); - hItem = hPrevItem; - while (hItem) // find last sibling - { - hPrevItem = hItem; - hItem = TreeView_GetNextSibling(hTreeView, hPrevItem); - } - return hPrevItem; -} - - -HTREEITEM CCList::FindContact(HANDLE hContact) -{ - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = TreeView_GetRoot(hTreeView); - while (tvi.hItem) - { - TreeView_GetItem(hTreeView, &tvi); - if (Items[tvi.lParam].hContact == hContact) - { - return tvi.hItem; - } - tvi.hItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_MULTILEVEL, tvi.hItem); - } - return NULL; -} - - -void CCList::SelectGroups(HTREEITEM hCurItem, bool bSelected) -{ -// select/deselect all child items - HTREEITEM hItem = TreeView_GetChild(hTreeView, hCurItem); - HTREEITEM hLimitItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_NOTCHILD, hCurItem); - while (hItem && hItem != hLimitItem) - { - TreeView_SetItemState(hTreeView, hItem, bSelected ? TVIS_SELECTED : 0, TVIS_SELECTED); - Array_SetItemState(hItem, bSelected); - hItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_MULTILEVEL, hItem); - } -// select/deselect all parent groups - hCurItem = TreeView_GetParent(hTreeView, hCurItem); - if (bSelected) - { - while (hCurItem) // select until we'll find an unselected item or until we'll reach the root - { - hItem = TreeView_GetChild(hTreeView, hCurItem); - while (hItem) // walk through all siblings - { - if (!(TreeView_GetItemState(hTreeView, hItem, TVIS_SELECTED) & TVIS_SELECTED)) - { - break; - } - hItem = TreeView_GetNextSibling(hTreeView, hItem); - } - if (hItem) // means there was at least one unselected item - { - break; - } - TreeView_SetItemState(hTreeView, hCurItem, TVIS_SELECTED, TVIS_SELECTED); - Array_SetItemState(hCurItem, true); - hCurItem = TreeView_GetParent(hTreeView, hCurItem); - } - } - while (hCurItem) // and deselect all remaining parent groups - { - TreeView_SetItemState(hTreeView, hCurItem, 0, TVIS_SELECTED); - Array_SetItemState(hCurItem, false); - hCurItem = TreeView_GetParent(hTreeView, hCurItem); - } -} -- cgit v1.2.3