summaryrefslogtreecommitdiff
path: root/plugins/YAPP/src/yapp_history_dlg.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-24 12:45:18 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-24 12:45:18 +0000
commit0cda0baab21d4d4bf40c9459f6f5a7e49aa92492 (patch)
treec1244d2f42e6d1728a81a18bd0fbd091904bf20c /plugins/YAPP/src/yapp_history_dlg.cpp
parent171e81205e357e0d54283a63997ed58ff97d54a9 (diff)
VersionInfo, W7UI, WhoUsesMyFiles, YAPP, ZeroNotification: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@1161 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/YAPP/src/yapp_history_dlg.cpp')
-rw-r--r--plugins/YAPP/src/yapp_history_dlg.cpp743
1 files changed, 743 insertions, 0 deletions
diff --git a/plugins/YAPP/src/yapp_history_dlg.cpp b/plugins/YAPP/src/yapp_history_dlg.cpp
new file mode 100644
index 0000000000..534af1fe0c
--- /dev/null
+++ b/plugins/YAPP/src/yapp_history_dlg.cpp
@@ -0,0 +1,743 @@
+#include "common.h"
+#include "resource.h"
+#include "yapp_history.h"
+
+//************ Some helper resize stuff ******************
+
+#define MIN_HISTORY_WIDTH 540
+#define MIN_HISTORY_HEIGHT 300
+
+#define GAP_SIZE 2
+
+#define ANCHOR_LEFT 0x000001
+#define ANCHOR_RIGHT 0x000002
+#define ANCHOR_TOP 0x000004
+#define ANCHOR_BOTTOM 0x000008
+#define ANCHOR_ALL ANCHOR_LEFT | ANCHOR_RIGHT | ANCHOR_TOP | ANCHOR_BOTTOM
+
+WNDPROC oldPopupsListProc = NULL;
+
+HWND hHistoryWindow = 0; //the history window
+HICON hiPopupHistory; //popup history icon
+PopupHistoryList lstPopupHistory; //defined in main.cpp
+
+const TCHAR *szHistoryColumns[] = {_T("Title"), _T("Message"), _T("Timestamp")}; //need to make sure that the string and size vectors have the same number of elements
+const int cxHistoryColumns[] = {100, 450, 115};
+const int cHistoryColumns = sizeof(szHistoryColumns) / sizeof(szHistoryColumns[0]);
+
+struct PopupHistoryWindowData{
+ HWND hIEView;
+};
+
+void ScreenToClient(HWND hWnd, LPRECT rect)
+{
+ POINT pt;
+ int cx = rect->right - rect->left;
+ int cy = rect->bottom - rect->top;
+ pt.x = rect->left;
+ pt.y = rect->top;
+ ScreenToClient(hWnd, &pt);
+ rect->left = pt.x;
+ rect->top = pt.y;
+ rect->right = pt.x + cx;
+ rect->bottom = pt.y + cy;
+}
+
+RECT AnchorCalcPos(HWND window, const RECT *rParent, const WINDOWPOS *parentPos, int anchors)
+{
+ RECT rChild;
+ RECT rTmp;
+
+ GetWindowRect(window, &rChild);
+ ScreenToClient(parentPos->hwnd, &rChild);
+
+ int cx = rParent->right - rParent->left;
+ int cy = rParent->bottom - rParent->top;
+ if ((cx == parentPos->cx) && (cy == parentPos->cy))
+ {
+ return rChild;
+ }
+ if (parentPos->flags & SWP_NOSIZE)
+ {
+ return rChild;
+ }
+
+ rTmp.left = parentPos->x - rParent->left;
+ rTmp.right = (parentPos->x + parentPos->cx) - rParent->right;
+ rTmp.bottom = (parentPos->y + parentPos->cy) - rParent->bottom;
+ rTmp.top = parentPos->y - rParent->top;
+
+ cx = (rTmp.left) ? -rTmp.left : rTmp.right;
+ cy = (rTmp.top) ? -rTmp.top : rTmp.bottom;
+
+ rChild.right += cx;
+ rChild.bottom += cy;
+ //expanded the window accordingly, now we need to enforce the anchors
+ if ((anchors & ANCHOR_LEFT) && (!(anchors & ANCHOR_RIGHT)))
+ {
+ rChild.right -= cx;
+ }
+ if ((anchors & ANCHOR_TOP) && (!(anchors & ANCHOR_BOTTOM)))
+ {
+ rChild.bottom -= cy;
+ }
+ if ((anchors & ANCHOR_RIGHT) && (!(anchors & ANCHOR_LEFT)))
+ {
+ rChild.left += cx;
+ }
+ if ((anchors & ANCHOR_BOTTOM) && (!(anchors & ANCHOR_TOP)))
+ {
+ rChild.top += cy;
+ }
+ return rChild;
+}
+
+void AnchorMoveWindow(HWND window, const WINDOWPOS *parentPos, int anchors)
+{
+ RECT rParent;
+ RECT rChild;
+
+ if (parentPos->flags & SWP_NOSIZE)
+ {
+ return;
+ }
+ GetWindowRect(parentPos->hwnd, &rParent);
+ rChild = AnchorCalcPos(window, &rParent, parentPos, anchors);
+ MoveWindow(window, rChild.left, rChild.top, rChild.right - rChild.left, rChild.bottom - rChild.top, FALSE);
+}
+
+void AddAnchorWindowToDeferList(HDWP &hdWnds, HWND window, RECT *rParent, WINDOWPOS *wndPos, int anchors)
+{
+ RECT rChild = AnchorCalcPos(window, rParent, wndPos, anchors);
+ hdWnds = DeferWindowPos(hdWnds, window, HWND_NOTOPMOST, rChild.left, rChild.top, rChild.right - rChild.left, rChild.bottom - rChild.top, SWP_NOZORDER);
+}
+//************************************************************
+
+//Stucture passed to list sort function
+struct SortParams{
+ HWND hList;
+ int column;
+};
+
+static int lastColumn = -1; //last sort column
+
+int MatchesFilterCS(const TCHAR *filter, const PopupHistoryData *popupItem) //case sensitive
+{
+ if (_tcslen(filter) <= 0) { return 1; } //if no filter is set then the popup item matches the filter
+ int match = 0;
+
+ match = (_tcsstr(popupItem->messageT, filter)) ? 1 : match; //check message part
+
+ if (!match) //check title part of no match has been found
+ {
+ match = (_tcsstr(popupItem->titleT, filter)) ? 1 : match;
+ }
+
+ if (!match) //if no match has been found yet try to match the timestamp
+ {
+ TCHAR buffer[1024];
+ struct tm *myTime = localtime(&popupItem->timestamp);
+ _tcsftime(buffer, 1024, _T("%c"), myTime);
+ match = (_tcsstr(buffer, filter)) ? 1 : match;
+ }
+
+ return match;
+}
+
+__inline void ConvertCase(TCHAR *dest, const TCHAR *source, size_t size)
+{
+ _tcsncpy(dest, source, size);
+ _tcslwr(dest);
+}
+
+int MatchesFilterCI(const TCHAR *filterS, const PopupHistoryData *popupItem)
+{
+ if (_tcslen(filterS) <= 0) { return 1; } //if no filter is set then the popup item matches the filter
+ int match = 0;
+ const int BUFFER_SIZE = 1024;
+ TCHAR buffer[BUFFER_SIZE];
+ TCHAR filterI[BUFFER_SIZE];
+
+ ConvertCase(filterI, filterS, BUFFER_SIZE);
+
+ ConvertCase(buffer, popupItem->messageT, BUFFER_SIZE); //check message part
+ match = (_tcsstr(buffer, filterI)) ? 1 : match;
+
+ if (!match) // check title part of no match has been found
+ {
+ ConvertCase(buffer, popupItem->titleT, BUFFER_SIZE);
+ match = (_tcsstr(buffer, filterI)) ? 1 : match;
+ }
+
+ if (!match) //if no match has been found yet try to match the timestamp
+ {
+ struct tm *myTime = localtime(&popupItem->timestamp);
+ _tcsftime(buffer, 1024, _T("%c"), myTime);
+ match = (_tcsstr(buffer, filterI)) ? 1 : match;
+ }
+
+ return match;
+}
+
+int CALLBACK PopupsCompare(LPARAM lParam1, LPARAM lParam2, LPARAM myParam)
+{
+ SortParams params = *(SortParams *) myParam;
+ const int MAX_SIZE = 512;
+ TCHAR text1[MAX_SIZE];
+ TCHAR text2[MAX_SIZE];
+ int res;
+
+ ListView_GetItemText(params.hList, (int) lParam1, params.column, text1, MAX_SIZE);
+ ListView_GetItemText(params.hList, (int) lParam2, params.column, text2, MAX_SIZE);
+
+ res = _tcsicmp(text1, text2);
+
+ res = (params.column == lastColumn) ? -res : res; //do reverse search on second click on same column
+
+ return res;
+}
+
+
+
+int CalcCustomControlPos(IEVIEWWINDOW *ieWnd, HWND hMainWindow)
+{
+ RECT rect;
+ GetWindowRect(GetDlgItem(hMainWindow, IDC_LST_HISTORY), &rect);
+ ScreenToClient(hMainWindow, &rect);
+ //GetClientRect(hMainWindow, &rect);
+
+ ieWnd->x = rect.left + GAP_SIZE;
+ ieWnd->y = rect.top + GAP_SIZE;
+ ieWnd->cx = rect.right - rect.left - (2 * GAP_SIZE);
+ ieWnd->cy = rect.bottom - rect.top - (2 * GAP_SIZE);
+ return 0;
+}
+
+void MoveCustomControl(HWND hWnd, int renderer)
+{
+ switch (renderer)
+ {
+ case RENDER_HISTORYPP:
+ case RENDER_IEVIEW:
+ {
+ PopupHistoryWindowData *data = (PopupHistoryWindowData *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ if (data)
+ {
+ IEVIEWWINDOW ieWnd = {0};
+ ieWnd.cbSize = sizeof(ieWnd);
+ ieWnd.parent = hWnd;
+ ieWnd.hwnd = data->hIEView;
+ ieWnd.iType = IEW_SETPOS;
+ CalcCustomControlPos(&ieWnd, hWnd);
+
+ CallService((renderer == RENDER_HISTORYPP) ? MS_HPP_EG_WINDOW : MS_IEVIEW_WINDOW, 0, (LPARAM) &ieWnd);
+ }
+
+ break;
+ }
+ }
+}
+
+void LoadRenderer(HWND hWnd, int renderer)
+{
+ switch (renderer)
+ {
+ case RENDER_HISTORYPP:
+ case RENDER_IEVIEW:
+ {
+ IEVIEWWINDOW ieWnd = {0};
+
+ ieWnd.cbSize = sizeof(ieWnd);
+ ieWnd.iType = IEW_CREATE;
+ ieWnd.dwMode = IEWM_HISTORY;
+ ieWnd.dwFlags = 0;
+ ieWnd.parent = hWnd;
+ CalcCustomControlPos(&ieWnd, hWnd);
+
+ CallService((renderer == RENDER_HISTORYPP) ? MS_HPP_EG_WINDOW : MS_IEVIEW_WINDOW, 0, (LPARAM) &ieWnd); //create the IeView or H++ control.
+
+ PopupHistoryWindowData *data = (PopupHistoryWindowData *) mir_alloc(sizeof(PopupHistoryWindowData)); //create custom control data
+ data->hIEView = ieWnd.hwnd;
+ ShowWindow(data->hIEView, SW_SHOW);
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data); //set it as the window's user data
+ ShowWindow(GetDlgItem(hWnd, IDC_LST_HISTORY), SW_HIDE);
+ //SetWindowPos(GetDlgItem(hWnd, IDC_LST_HISTORY), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ break;
+ }
+ }
+}
+
+void UnloadRenderer(HWND hWnd, int renderer)
+{
+ switch (renderer)
+ {
+ case RENDER_HISTORYPP:
+ case RENDER_IEVIEW:
+ {
+ PopupHistoryWindowData *data = (PopupHistoryWindowData *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+ if (data)
+ {
+ IEVIEWWINDOW ieWnd = {0};
+ ieWnd.cbSize = sizeof(ieWnd);
+ ieWnd.parent = hWnd;
+ ieWnd.hwnd = data->hIEView;
+ ieWnd.iType = IEW_DESTROY;
+ CallService((renderer == RENDER_HISTORYPP) ? MS_HPP_EG_WINDOW : MS_IEVIEW_WINDOW, 0, (LPARAM) &ieWnd);
+
+ mir_free(data);
+ }
+
+ break;
+ }
+ }
+}
+
+void DeleteOldEvents(HWND hWnd, int renderer)
+{
+ switch (renderer)
+ {
+ case RENDER_HISTORYPP:
+ case RENDER_IEVIEW:
+ {
+ PopupHistoryWindowData *data = (PopupHistoryWindowData *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ if (data)
+ {
+ IEVIEWEVENT ieEvent = {0};
+ ieEvent.cbSize = sizeof(IEVIEWEVENT);
+ ieEvent.hwnd = data->hIEView;
+ ieEvent.iType = IEE_CLEAR_LOG;
+
+ CallService((renderer == RENDER_HISTORYPP) ? MS_HPP_EG_EVENT : MS_IEVIEW_EVENT, 0, (LPARAM) &ieEvent);
+ }
+
+ break;
+ }
+
+ case RENDER_DEFAULT:
+ default:
+ {
+ ListView_DeleteAllItems(GetDlgItem(hWnd, IDC_LST_HISTORY));
+
+ break;
+ }
+
+ }
+}
+
+typedef int (*SIG_MATCHESFILTER)(const TCHAR *filter, const PopupHistoryData *popupItem);
+typedef void (*SIG_ADDEVENTS)(HWND hWnd, int renderer, TCHAR *filter, SIG_MATCHESFILTER MatchesFilter);
+
+IEVIEWEVENTDATA *CreateAndFillEventData(PopupHistoryData *popupItem)
+{
+ IEVIEWEVENTDATA *eventData = (IEVIEWEVENTDATA *) mir_calloc(sizeof(IEVIEWEVENTDATA));
+ if (eventData)
+ {
+ eventData->cbSize = sizeof(IEVIEWEVENTDATA);
+ eventData->iType = IEED_EVENT_MESSAGE;
+
+ eventData->dwFlags = IEEDF_UNICODE_NICK | IEEDF_UNICODE_TEXT | IEEDF_UNICODE_TEXT2;
+ eventData->pszNickW = popupItem->titleT;
+ eventData->pszTextW = popupItem->messageT;
+
+ eventData->time = (DWORD) popupItem->timestamp;
+ eventData->next = NULL;
+ }
+
+ return eventData;
+}
+
+void AddEventsCustomControl(HWND hWnd, int renderer, TCHAR *filter, SIG_MATCHESFILTER MatchesFilter)
+{
+ PopupHistoryWindowData *pwData = (PopupHistoryWindowData *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ if (pwData)
+ {
+ IEVIEWEVENT ieEvent = {0};
+ ieEvent.cbSize = sizeof(IEVIEWEVENT);
+ ieEvent.hwnd = pwData->hIEView;
+ ieEvent.codepage = CP_ACP;
+ ieEvent.iType = IEE_LOG_MEM_EVENTS;
+ ieEvent.hContact = NULL;//(HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); IEVIEW needs a contact handle !!
+
+ IEVIEWEVENTDATA *eventData = NULL;
+ IEVIEWEVENTDATA *cED = NULL;
+ IEVIEWEVENTDATA *prevED = NULL;
+
+ int i;
+ int count = 0;
+ int size = lstPopupHistory.Count();
+ PopupHistoryData *popupItem;
+
+ for (i = 0; i < size; i++)
+ {
+ popupItem = lstPopupHistory.Get(i);
+ if (MatchesFilter(filter, popupItem))
+ {
+ cED = CreateAndFillEventData(popupItem);
+ if (cED)
+ {
+ count++;
+ if (!eventData)
+ {
+ eventData = cED;
+ }
+ else{
+ prevED->next = cED;
+ }
+
+ prevED = cED;
+ }
+ }
+ }
+ ieEvent.count = count;
+ ieEvent.eventData = eventData;
+
+ CallService((renderer == RENDER_HISTORYPP) ? MS_HPP_EG_EVENT : MS_IEVIEW_EVENT, 0, (LPARAM) &ieEvent);
+
+ while (eventData)
+ {
+ cED = eventData;
+ eventData = eventData->next;
+ mir_free(cED);
+ }
+ }
+}
+
+void AddEventsDefault(HWND hWnd, int renderer, TCHAR *filter, SIG_MATCHESFILTER MatchesFilter)
+{
+ HWND hHistoryList = GetDlgItem(hWnd, IDC_LST_HISTORY);
+ TCHAR buffer[1024];
+ struct tm *myTime;
+
+ LVITEM item = {0};
+ item.mask = LVIF_TEXT;
+
+ int i, lIndex;
+ lIndex = 0;
+ PopupHistoryData *popupItem;
+ for (i = 0; i < lstPopupHistory.Count(); i++)
+ {
+ item.iItem = lIndex;
+ popupItem = lstPopupHistory.Get(i);
+ if (MatchesFilter(filter, popupItem))
+ {
+ item.pszText = popupItem->titleT;
+ ListView_InsertItem(hHistoryList, &item);
+ ListView_SetItemText(hHistoryList, lIndex, 1, popupItem->messageT);
+ myTime = localtime(&popupItem->timestamp);
+ _tcsftime(buffer, 1024, _T("%c"), myTime);
+ ListView_SetItemText(hHistoryList, lIndex++, 2, buffer);
+ }
+ }
+}
+
+void RefreshPopupHistory(HWND hWnd, int renderer)
+{
+ if (!hWnd) { return; }
+ const int MAX_FILTER_SIZE = 1024;
+ SIG_MATCHESFILTER MatchesFilter = (IsDlgButtonChecked(hWnd, IDC_HISTORY_FILTER_CASESENSITIVE)) ? MatchesFilterCS : MatchesFilterCI; //case sensitive compare or not ?
+
+ SIG_ADDEVENTS AddEvents = (renderer == RENDER_DEFAULT) ? AddEventsDefault : AddEventsCustomControl;
+
+ TCHAR filter[MAX_FILTER_SIZE];
+ DeleteOldEvents(hWnd, renderer); //delete events
+
+ GetWindowText(GetDlgItem(hWnd, IDC_HISTORY_FILTER), filter, MAX_FILTER_SIZE); //get filter text
+
+ AddEvents(hWnd, renderer, filter, MatchesFilter);
+
+ if (renderer == RENDER_DEFAULT)
+ {
+ HWND hHistoryList = GetDlgItem(hWnd, IDC_LST_HISTORY);
+ SortParams params = {0};
+ params.hList = hHistoryList;
+ params.column = lastColumn;
+
+ ListView_SortItemsEx(hHistoryList, PopupsCompare, &params);
+ }
+}
+
+void CopyPopupDataToClipboard(HWND hList, int selection)
+{
+ if (!selection)
+ {
+ return;
+ }
+
+ if (!GetOpenClipboardWindow())
+ {
+ if (OpenClipboard(hList))
+ {
+ TCHAR buffer[2048];
+ buffer[0] = _T('\0');
+ TCHAR *clipboard;
+ int i;
+ int found = 0;
+ int count = ListView_GetItemCount(hList);
+ int textType;
+
+ textType = CF_UNICODETEXT;
+
+
+ for (i = 0; i < count; i++)
+ {
+ if (ListView_GetItemState(hList, i, LVIS_SELECTED))
+ {
+ ListView_GetItemText(hList, i, selection - 100, buffer, 2048);
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ {
+ EmptyClipboard();
+ int len = (int)_tcslen(buffer);
+
+ HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, (len + 2) * sizeof(TCHAR));
+ clipboard = (TCHAR *) GlobalLock(hData);
+ _tcsncpy(clipboard, buffer, len);
+ clipboard[len] = _T('\0');
+ GlobalUnlock(hData);
+ if (!SetClipboardData(textType, hData))
+ {
+ PUShowMessage("Could not set clipboard data", SM_WARNING);
+ }
+ }
+ CloseClipboard();
+ }
+ else{
+ PUShowMessage("Could not open clipboard", SM_WARNING);
+ }
+ }
+ else{
+ PUShowMessage("The clipboard is not available", SM_WARNING);
+ }
+}
+
+//subclass proc for the list view
+BOOL CALLBACK PopupsListSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_CONTEXTMENU:
+ {
+ int x = LOWORD(lParam);
+ int y = HIWORD(lParam);
+ int selection;
+
+ HMENU hMenu = CreatePopupMenu();
+ AppendMenu(hMenu, MF_STRING, POPUPMENU_TITLE, TranslateT("Copy title to clipboard"));
+ AppendMenu(hMenu, MF_STRING, POPUPMENU_MESSAGE, TranslateT("Copy message to clipboard"));
+ AppendMenu(hMenu, MF_STRING, POPUPMENU_TIMESTAMP, TranslateT("Copy timestamp to clipboard"));
+ selection = TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, x, y, 0, hWnd, NULL);
+ DestroyMenu(hMenu);
+ if (selection)
+ {
+ CopyPopupDataToClipboard(hWnd, selection);
+ }
+
+ break;
+ }
+
+ case WM_KEYUP:
+ {
+ switch (wParam)
+ {
+ case 'C':
+ {
+ if (GetKeyState(VK_CONTROL))
+ {
+ CopyPopupDataToClipboard(hWnd, POPUPMENU_MESSAGE);
+ }
+
+ break;
+ }
+
+ case VK_ESCAPE:
+ {
+ SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0);
+
+ break;
+ }
+
+ }
+
+ break;
+ }
+
+ case WM_SYSKEYDOWN:
+ {
+ if (wParam == 'X')
+ {
+ SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0);
+ }
+
+ break;
+ }
+ }
+
+ return CallWindowProc(oldPopupsListProc, hWnd, msg, wParam, lParam);
+}
+
+//load the columns
+void LoadHistoryColumns(HWND hHistoryList)
+{
+ LVCOLUMN col;
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ int i;
+
+ for (i = 0; i < cHistoryColumns; i++)
+ {
+ col.pszText = TranslateTS(szHistoryColumns[i]);
+ col.cx = cxHistoryColumns[i];
+ ListView_InsertColumn(hHistoryList, i, &col);
+ }
+}
+
+//this is the history list window handler
+INT_PTR CALLBACK DlgProcHistLst(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int bInitializing;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ bInitializing = 1;
+ int renderer = lstPopupHistory.GetRenderer();
+
+ SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hiPopupHistory);
+
+ LoadRenderer(hWnd, renderer);
+
+ TranslateDialogDefault(hWnd);
+ HWND hHistoryList = GetDlgItem(hWnd, IDC_LST_HISTORY);
+
+ ListView_SetExtendedListViewStyleEx(hHistoryList, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
+
+ oldPopupsListProc = (WNDPROC) SetWindowLongPtr(hHistoryList, GWLP_WNDPROC, (LONG_PTR) PopupsListSubclassProc);
+
+ LoadHistoryColumns(hHistoryList);
+
+ RefreshPopupHistory(hWnd, renderer);
+
+ bInitializing = 0;
+
+ return TRUE;
+ }
+
+ case WM_DESTROY:
+ {
+ UnloadRenderer(hWnd, lstPopupHistory.GetRenderer());
+ hHistoryWindow = NULL;
+
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ //Utils_SaveWindowPosition(hWnd, 0, MODULE, "history_dlg");
+ DestroyWindow(hWnd);
+
+ break;
+ }
+
+ case WM_WINDOWPOSCHANGING:
+ {
+ WINDOWPOS *wndPos = (WINDOWPOS *) lParam;
+
+ if (wndPos->cx < MIN_HISTORY_WIDTH)
+ {
+ wndPos->cx = MIN_HISTORY_WIDTH;
+ }
+ if (wndPos->cy < MIN_HISTORY_HEIGHT)
+ {
+ wndPos->cy = MIN_HISTORY_HEIGHT;
+ }
+
+ RECT rParent;
+ GetWindowRect(hWnd, &rParent);
+ HDWP hdWnds = BeginDeferWindowPos(4);
+
+ AddAnchorWindowToDeferList(hdWnds, GetDlgItem(hWnd, IDC_CLOSE), &rParent, wndPos, ANCHOR_RIGHT | ANCHOR_BOTTOM);
+ AddAnchorWindowToDeferList(hdWnds, GetDlgItem(hWnd, IDC_HISTORY_FILTER), &rParent, wndPos, ANCHOR_LEFT | ANCHOR_BOTTOM);
+ AddAnchorWindowToDeferList(hdWnds, GetDlgItem(hWnd, IDC_HISTORY_FILTER_CASESENSITIVE), &rParent, wndPos, ANCHOR_LEFT | ANCHOR_RIGHT | ANCHOR_BOTTOM);
+ AddAnchorWindowToDeferList(hdWnds, GetDlgItem(hWnd, IDC_LST_HISTORY), &rParent, wndPos, ANCHOR_ALL);
+
+ EndDeferWindowPos(hdWnds);
+ MoveCustomControl(hWnd, lstPopupHistory.GetRenderer()); //move the custom control too, if any
+ break;
+ }
+
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_CLOSE:
+ {
+ SendMessage(hWnd, WM_CLOSE, 0, 0);
+
+ break;
+ }
+
+ case IDC_HISTORY_FILTER_CASESENSITIVE:
+ {
+ if (HIWORD(wParam) == BN_CLICKED)
+ {
+ RefreshPopupHistory(hWnd, lstPopupHistory.GetRenderer());
+ }
+ }
+
+ case IDC_HISTORY_FILTER:
+ {
+ if (HIWORD(wParam) == EN_CHANGE)
+ {
+ if (!bInitializing)
+ {
+ RefreshPopupHistory(hWnd, lstPopupHistory.GetRenderer());
+ }
+ }
+
+ break;
+ }
+
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case IDC_LST_HISTORY:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case LVN_COLUMNCLICK:
+ {
+ LPNMLISTVIEW lv = (LPNMLISTVIEW) lParam;
+ int column = lv->iSubItem;
+ SortParams params = {0};
+ params.hList = GetDlgItem(hWnd, IDC_LST_HISTORY);
+ params.column = column;
+
+ ListView_SortItemsEx(params.hList, PopupsCompare, (LPARAM) &params);
+ lastColumn = (params.column == lastColumn) ? -1 : params.column;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return 0;
+}