summaryrefslogtreecommitdiff
path: root/!Deprecated/NewAwaySysMod/ContactList.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-28 19:25:08 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-28 19:25:08 +0000
commit66526765714b08969548a414d3fa87dbe333242d (patch)
treed3fc2027140f97edfdfc5023e70ff8b4db920c11 /!Deprecated/NewAwaySysMod/ContactList.cpp
parent3ccd712341ed9e76252bd595c5a797d6c8ea8992 (diff)
"!Deprecated" folders moved from root directory to plugins
git-svn-id: http://svn.miranda-ng.org/main/trunk@1230 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to '!Deprecated/NewAwaySysMod/ContactList.cpp')
-rw-r--r--!Deprecated/NewAwaySysMod/ContactList.cpp905
1 files changed, 0 insertions, 905 deletions
diff --git a/!Deprecated/NewAwaySysMod/ContactList.cpp b/!Deprecated/NewAwaySysMod/ContactList.cpp
deleted file mode 100644
index 70b26d1d57..0000000000
--- a/!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);
- }
-}