/* Popup Plus plugin for Miranda IM Copyright © 2002 Luca Santarelli, © 2004-2007 Victor Pavlychko © 2010 MPK © 2010 Merlin_de 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. =============================================================================== File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/history.cpp $ Revision : $Revision: 1631 $ Last change on : $Date: 2010-07-08 08:22:12 +0300 (Чт, 08 июл 2010) $ Last change by : $Author: MPK $ =============================================================================== */ #include "headers.h" static POPUPDATA2 *popupHistory; static int popupHistoryStart = 0; static int popupHistorySize = 0; static int popupHistoryBuffer = 100; #define UM_RESIZELIST (WM_USER+100) #define UM_SELECTLAST (WM_USER+101) #define UM_ADDITEM (WM_USER+102) static HWND hwndHistory = NULL; static inline int getHistoryIndex(int idx) { return (popupHistoryStart + idx) % popupHistoryBuffer; } static inline POPUPDATA2 *getHistoryItem(int idx) { return popupHistory + (popupHistoryStart + idx) % popupHistoryBuffer; } static INT_PTR CALLBACK HistoryDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void PopupHistoryLoad() { popupHistoryBuffer = DBGetContactSettingWord(NULL, MODULNAME, "HistorySize", SETTING_HISTORYSIZE_DEFAULT); popupHistory = new POPUPDATA2[popupHistoryBuffer]; } void PopupHistoryResize() { int i; int toDelete = 0; int toCopy = popupHistorySize; if (popupHistoryBuffer == PopUpOptions.HistorySize) return; if (hwndHistory) PostMessage(hwndHistory, WM_CLOSE, 0, 0); POPUPDATA2 *oldPopupHistory = popupHistory; int oldStart = popupHistoryStart; int oldBuffer = popupHistoryBuffer; popupHistory = new POPUPDATA2[PopUpOptions.HistorySize]; popupHistoryStart = 0; popupHistoryBuffer = PopUpOptions.HistorySize; if(PopUpOptions.HistorySize < popupHistorySize){ //if old history bigger new one toDelete = popupHistorySize - PopUpOptions.HistorySize; toCopy = PopUpOptions.HistorySize; popupHistorySize = PopUpOptions.HistorySize; } for(i = 0; i < toCopy; ++i){ //copy needed popupHistory[i] = oldPopupHistory[(oldStart + toDelete + i)%oldBuffer]; } for(i = 0; i < toDelete; ++i){//free too old ones POPUPDATA2 *ppd = &oldPopupHistory[(oldStart + i)%oldBuffer]; if (ppd->flags & PU2_UNICODE) { mir_free(ppd->lpwzTitle); mir_free(ppd->lpwzText); } else { mir_free(ppd->lpzTitle); mir_free(ppd->lpzText); } if (ppd->lpzSkin) mir_free(ppd->lpzSkin); } delete [] oldPopupHistory; } void PopupHistoryUnload() { for (int i = 0; i < popupHistorySize; ++i) { POPUPDATA2 *ppd = &popupHistory[getHistoryIndex(i)]; if (ppd->flags & PU2_UNICODE) { mir_free(ppd->lpwzTitle); mir_free(ppd->lpwzText); } else { mir_free(ppd->lpzTitle); mir_free(ppd->lpzText); } if (ppd->lpzSkin) mir_free(ppd->lpzSkin); } delete [] popupHistory; popupHistory = NULL; } void PopupHistoryAdd(POPUPDATA2 *ppdNew) { if (!PopUpOptions.EnableHistory) return; POPUPDATA2 *ppd; if (popupHistorySize < popupHistoryBuffer) { ++popupHistorySize; ppd = &popupHistory[getHistoryIndex(popupHistorySize-1)]; } else { popupHistoryStart = (popupHistoryStart+1)%popupHistoryBuffer; ppd = &popupHistory[getHistoryIndex(popupHistorySize-1)]; if (ppd->flags & PU2_UNICODE) { mir_free(ppd->lpwzTitle); mir_free(ppd->lpwzText); } else { mir_free(ppd->lpzTitle); mir_free(ppd->lpzText); } if (ppd->lpzSkin) mir_free(ppd->lpzSkin); } *ppd = *ppdNew; if (ppd->flags&PU2_UNICODE) { ppd->lpwzTitle = mir_wstrdup(ppd->lpwzTitle); ppd->lpwzText = mir_wstrdup(ppd->lpwzText); } else { ppd->lpzTitle = mir_strdup(ppd->lpzTitle); ppd->lpzText = mir_strdup(ppd->lpzText); } if (ppd->lpzSkin) { ppd->lpzSkin = mir_strdup(ppd->lpzSkin); } else { ppd->lpzSkin = NULL; } ppd->dwTimestamp = time(NULL); // GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL,"HH':'mm", ppd->lpzTime, sizeof(ppd->lpzTime)); if (hwndHistory) PostMessage(hwndHistory, UM_ADDITEM, 0, (LPARAM)ppd); } void PopupHistoryShow() { if (!PopUpOptions.EnableHistory){ MessageBox(NULL, TranslateT("Popup History is disabled"), TranslateT("Popup History message"), MB_OK); return; } if (hwndHistory) { ShowWindow(hwndHistory, SW_SHOW); SetForegroundWindow(hwndHistory); SetFocus(hwndHistory); SetActiveWindow(hwndHistory); } else { hwndHistory = CreateDialog(hInst, MAKEINTRESOURCE(IDD_HISTORY), NULL, HistoryDlgProc); SetWindowText(hwndHistory, TranslateT("Popup History")); //ShowWindow(hwndHistory, SW_SHOW); } } static INT_PTR CALLBACK HistoryDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static int oldWidth = 0; static int loadItem = -1; static enum { LOG_NONE, LOG_DEFAULT, LOG_HPP } logType = LOG_NONE; static HWND hwndLog = NULL; switch (msg) { case WM_INITDIALOG: { oldWidth = 0; HWND hwndList = GetDlgItem(hwnd, IDC_POPUP_LIST); for (int i = 0; i < popupHistorySize; ++i) ListBox_SetItemData(hwndList, ListBox_AddString(hwndList, _T("")), 0); SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)IcoLib_GetIcon(ICO_HISTORY,0)); SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)IcoLib_GetIcon(ICO_HISTORY,1)); if (gbHppInstalled && PopUpOptions.UseHppHistoryLog) { logType = LOG_HPP; ShowWindow(GetDlgItem(hwnd, IDC_POPUP_LIST), SW_HIDE); IEVIEWWINDOW ieWindow; ieWindow.cbSize = sizeof(IEVIEWWINDOW); ieWindow.iType = IEW_CREATE; ieWindow.dwFlags = 0; ieWindow.dwMode = IEWM_MUCC; // ieWindow.dwMode = IEWM_CHAT; ieWindow.parent = hwnd; ieWindow.x = 0; ieWindow.y = 0; ieWindow.cx = 100; ieWindow.cy = 100; CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow); hwndLog = ieWindow.hwnd; ShowWindow(hwndLog, SW_SHOW); RECT rcLst; GetWindowRect(hwndList, &rcLst); POINT pt; pt.x = rcLst.left; pt.y = rcLst.top; ScreenToClient(hwnd, &pt); ieWindow.cbSize = sizeof(IEVIEWWINDOW); ieWindow.iType = IEW_SETPOS; ieWindow.parent = hwnd; ieWindow.hwnd = hwndLog; ieWindow.x = pt.x; ieWindow.y = pt.y; ieWindow.cx = rcLst.right-rcLst.left; ieWindow.cy = rcLst.bottom-rcLst.top; CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow); IEVIEWEVENTDATA ieData; IEVIEWEVENT ieEvent; ieEvent.cbSize = sizeof(ieEvent); ieEvent.iType = IEE_LOG_MEM_EVENTS; ieEvent.dwFlags = 0; ieEvent.hwnd = hwndLog; ieEvent.eventData = &ieData; ieEvent.count = 1; ieEvent.codepage = 0; ieEvent.pszProto = NULL; for (int i = 0; i < popupHistorySize; ++i) { ieData.cbSize = sizeof(ieData); ieData.iType = IEED_EVENT_SYSTEM; ieData.dwFlags = 0; ieData.color = getHistoryItem(i)->colorText; if (getHistoryItem(i)->flags & PU2_UNICODE) { ieData.dwFlags |= IEEDF_UNICODE_TEXT|IEEDF_UNICODE_NICK; ieData.pszNickW = getHistoryItem(i)->lpwzTitle; ieData.pszTextW = getHistoryItem(i)->lpwzText; ieData.pszText2W = NULL; } else { ieData.dwFlags |= 0; ieData.pszNick = getHistoryItem(i)->lpzTitle; ieData.pszText = getHistoryItem(i)->lpzText; ieData.pszText2 = NULL; } ieData.bIsMe = FALSE; ieData.time = getHistoryItem(i)->dwTimestamp; ieData.dwData = 0; ieData.next = NULL; CallService(MS_HPP_EG_EVENT, 0, (WPARAM)&ieEvent); } } else { logType = LOG_DEFAULT; hwndLog = hwndList; ShowWindow(hwndLog, SW_SHOW); } Utils_RestoreWindowPosition(hwnd, NULL, MODULNAME, "popupHistory_"); if (logType == LOG_DEFAULT) { SendMessage(hwnd, UM_RESIZELIST, 0, 0); ListBox_SetTopIndex(hwndLog, popupHistorySize-1); } return TRUE; } case WM_MEASUREITEM: { if (logType != LOG_DEFAULT) return TRUE; LPMEASUREITEMSTRUCT lpmis; lpmis = (LPMEASUREITEMSTRUCT) lParam; if (lpmis->itemID == -1) return FALSE; lpmis->itemHeight = 50; return TRUE; } case WM_DRAWITEM: { if (logType != LOG_DEFAULT) return TRUE; LPDRAWITEMSTRUCT lpdis; lpdis = (LPDRAWITEMSTRUCT) lParam; if (lpdis->itemID == -1) return FALSE; HWND hwndList = GetDlgItem(hwnd, lpdis->CtlID); PopupWnd2 *wndPreview = (PopupWnd2 *)ListBox_GetItemData(hwndList, lpdis->itemID); if (!wndPreview) { RECT rc; GetWindowRect(hwndLog, &rc); if (rc.right-rc.left <= 30) return FALSE; POPUPOPTIONS customOptions = PopUpOptions; customOptions.DynamicResize = FALSE; customOptions.MinimumWidth = customOptions.MaximumWidth = rc.right-rc.left-30; POPUPDATA2 *ppd = &popupHistory[getHistoryIndex(lpdis->itemID)]; wndPreview = new PopupWnd2(ppd, &customOptions, true); wndPreview->buildMText(); wndPreview->update(); ListBox_SetItemData(hwndLog, lpdis->itemID, wndPreview); ListBox_SetItemHeight(hwndLog, lpdis->itemID, wndPreview->getSize().cy+6); } if (wndPreview) { if (lpdis->itemState & ODS_SELECTED) { HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); FillRect(lpdis->hDC, &lpdis->rcItem, hbr); DeleteObject(hbr); } else { HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); FillRect(lpdis->hDC, &lpdis->rcItem, hbr); DeleteObject(hbr); } int width = wndPreview->getContent()->getWidth(); int height = wndPreview->getContent()->getHeight(); #if defined(_UNICODE) { BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 255; bf.AlphaFormat = AC_SRC_ALPHA; AlphaBlend(lpdis->hDC, lpdis->rcItem.left+5, lpdis->rcItem.top+3, width, height, wndPreview->getContent()->getDC(), 0, 0, width, height, bf); } #else if (MyAlphaBlend) { BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 255; bf.AlphaFormat = AC_SRC_ALPHA; MyAlphaBlend(lpdis->hDC, lpdis->rcItem.left+5, lpdis->rcItem.top+3, width, height, wndPreview->getContent()->getDC(), 0, 0, width, height, bf); } else { BitBlt(lpdis->hDC, lpdis->rcItem.left+5, lpdis->rcItem.top+5, lpdis->rcItem.left+5+width, lpdis->rcItem.top+3+height, wndPreview->getContent()->getDC(), 0, 0, SRCCOPY); } #endif } return TRUE; } case WM_DELETEITEM: { if (logType != LOG_DEFAULT) return TRUE; DELETEITEMSTRUCT *lpdis = (DELETEITEMSTRUCT *)lParam; PopupWnd2 *wnd = (PopupWnd2 *)ListBox_GetItemData(lpdis->hwndItem, lpdis->itemID); if (wnd) delete wnd; return TRUE; } case WM_SIZE: { RECT rcLst; GetClientRect(hwnd, &rcLst); rcLst.left += 10; rcLst.top += 10; rcLst.right -= 10; rcLst.bottom -= 10; if (logType == LOG_HPP) { // POINT pt; // pt.x = rcLst.left; // pt.y = rcLst.top; // ScreenToClient(hwnd, &pt); SetWindowPos(hwndLog, NULL, rcLst.left, rcLst.top, rcLst.right-rcLst.left, rcLst.bottom-rcLst.top, SWP_NOZORDER|SWP_DEFERERASE|SWP_SHOWWINDOW); IEVIEWWINDOW ieWindow; ieWindow.cbSize = sizeof(IEVIEWWINDOW); ieWindow.iType = IEW_SETPOS; ieWindow.parent = hwnd; ieWindow.hwnd = hwndLog; ieWindow.x = rcLst.left; ieWindow.y = rcLst.top; ieWindow.cx = rcLst.right-rcLst.left; ieWindow.cy = rcLst.bottom-rcLst.top; CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow); } else if (logType == LOG_DEFAULT) { SetWindowPos(hwndLog, NULL, rcLst.left, rcLst.top, rcLst.right-rcLst.left, rcLst.bottom-rcLst.top, SWP_NOZORDER|SWP_DEFERERASE|SWP_SHOWWINDOW); if (rcLst.right-rcLst.left != oldWidth) { oldWidth = rcLst.right-rcLst.left; PostMessage(hwnd, UM_RESIZELIST, 0, 0); } } return TRUE; } case UM_RESIZELIST: { if (logType != LOG_DEFAULT) return TRUE; RECT rc; GetWindowRect(GetDlgItem(hwnd, IDC_POPUP_LIST), &rc); if (rc.right-rc.left <= 30) return FALSE; for (int i = 0; i < popupHistorySize; ++i) { PopupWnd2 *wndPreview = (PopupWnd2 *)ListBox_GetItemData(hwndLog, i); if (wndPreview) delete wndPreview; ListBox_SetItemData(hwndLog, i, 0); ListBox_SetItemHeight(hwndLog, i, 50); } ScrollWindow(hwndLog, 0, 100000, NULL, NULL); InvalidateRect(hwndLog, NULL, TRUE); return TRUE; } case UM_ADDITEM: { if (logType == LOG_HPP) { POPUPDATA2 *ppd = (POPUPDATA2 *)lParam; IEVIEWEVENTDATA ieData; IEVIEWEVENT ieEvent; ieEvent.cbSize = sizeof(ieEvent); ieEvent.iType = IEE_LOG_MEM_EVENTS; ieEvent.dwFlags = 0; ieEvent.hwnd = hwndLog; ieEvent.eventData = &ieData; ieEvent.count = 1; ieEvent.codepage = 0; ieEvent.pszProto = NULL; ieData.cbSize = sizeof(ieData); ieData.dwFlags = 0; ieData.iType = IEED_EVENT_SYSTEM; ieData.color = ppd->colorText; if (ppd->flags & PU2_UNICODE) { ieData.dwFlags |= IEEDF_UNICODE_TEXT|IEEDF_UNICODE_NICK; ieData.pszNickW = ppd->lpwzTitle; ieData.pszTextW = ppd->lpwzText; ieData.pszText2W = NULL; } else { ieData.dwFlags |= 0; ieData.pszNick = ppd->lpzTitle; ieData.pszText = ppd->lpzText; ieData.pszText2 = NULL; } ieData.bIsMe = FALSE; ieData.time = ppd->dwTimestamp; ieData.dwData = 0; ieData.next = NULL; CallService(MS_HPP_EG_EVENT, 0, (WPARAM)&ieEvent); } else if(logType == LOG_DEFAULT) { if (popupHistorySize <= ListBox_GetCount(hwndLog)) { loadItem = 0; PostMessage(hwnd, UM_RESIZELIST, 0, 0); return TRUE; } ListBox_SetItemData(hwndLog, ListBox_AddString(hwndLog, _T("")), 0); /* if (loadItem < 0) { loadItem = ListBox_GetCount(hwndList)-1; SendMessage(hwnd, UM_RESIZEITEM, 0, 0); }*/ } return TRUE; } case WM_CLOSE: { Utils_SaveWindowPosition(hwnd, NULL, MODULNAME, "popupHistory_"); DestroyWindow(hwnd); hwndHistory = NULL; return TRUE; } case WM_DESTROY: { if (logType == LOG_HPP) { IEVIEWWINDOW ieWindow; ieWindow.cbSize = sizeof(IEVIEWWINDOW); ieWindow.iType = IEW_DESTROY; ieWindow.dwFlags = 0; ieWindow.dwMode = IEWM_TABSRMM; ieWindow.parent = hwnd; ieWindow.hwnd = hwndLog; CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow); } } } return FALSE; //DefWindowProc(hwnd, msg, wParam, lParam); }