/* 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. */ #ifndef __popup_wnd2_h__ #define __popup_wnd2_h__ #define UM_CALLMETHOD (WM_USER+2048) class PopupAvatar; #define POPUP_OBJECT_SIGNARURE 0x0B1A11BE class PopupWnd2 : public MZeroedObject { public: typedef LRESULT(PopupWnd2::*MethodPtr)(LPARAM lParam); enum TextType { TT_NONE, TT_UNICODE, TT_MTEXT }; struct ActionInfo { POPUPACTION actionA; RECT rc; bool hover; ActionInfo() : hover(false) {} }; DWORD m_signature; private: // style COLORREF m_clBack, m_clText, m_clTitle, m_clClock; int m_iTimeout; // content TextType m_textType; wchar_t *m_lptzTitle, *m_lptzText; HANDLE m_mtTitle, m_mtText; bool m_bTextEmpty, m_bIcoLib; HFONT m_hfnTitle, m_hfnText; HICON m_hIcon; HBITMAP m_hbmAvatar; wchar_t m_time[2 + 1 + 2 + 1]; ActionInfo* m_actions; int m_actionCount; HANDLE m_hNotification; // other data Formula::Args m_args; MCONTACT m_hContact, m_hContactPassed; WNDPROC m_PluginWindowProc; void *m_PluginData; // the window LPTSTR m_lpzSkin; bool m_customPopup; HWND m_hwnd, m_hwndToolTip; bool m_bPositioned; POINT m_pos; SIZE m_sz; MyBitmap *m_bmpBase, *m_bmp, *m_bmpAnimate; PopupAvatar*m_avatar; int m_avatarFrameDelay; bool m_bReshapeWindow; bool m_bIsPinned; // show & hide bool m_bFade; BYTE m_btAlpha0, m_btAlpha1; bool m_bSlide; POINT m_ptPosition0, m_ptPosition1; bool m_bDestroy; bool m_bIsHovered; // prevent unwanted clicks POINT m_ptPrevCursor; // system POPUPOPTIONS *m_options; DWORD m_lockCount; PopupSkin::RenderInfo m_renderInfo; void fixDefaults(); void fixAvatar(); int fixActions(POPUPACTION *theActions, int count); int fixActions(POPUPACTION *theActions, int count, int additional); public: PopupWnd2(POPUPDATA2 *ppd, POPUPOPTIONS *theCustomOptions = NULL, bool renderOnly = false); ~PopupWnd2(); void startThread(); void create(); void updateLayered(BYTE opacity); SIZE measure(); void update(); void animate(); void show(); void hide(); void idle(); DWORD lock() { return ++m_lockCount; } DWORD unlock() { return m_lockCount = m_lockCount ? m_lockCount - 1 : 0; } bool isLocked() { return m_lockCount != 0; } void setIcon(HICON); void updateData(POPUPDATAW_V2 *ppd); void updateData(POPUPDATA2 *ppd); void buildMText(); void updateText(wchar_t *text); void updateTitle(wchar_t *title); void updateTimer(); MyBitmap *getContent() { return m_bmp; } COLORREF getTextColor() { return m_clText; } COLORREF getTitleColor() { return m_clTitle; } COLORREF getClockColor() { return m_clClock; } COLORREF getBackColor() { return m_clBack; } bool isTextEmpty() { return m_bTextEmpty; } bool isIcolib() { return m_bIcoLib; } TextType getTextType() { return m_textType; } wchar_t *getText() { return m_lptzText; } HANDLE getTextM() { return m_mtText; } wchar_t *getTitle() { return m_lptzTitle; } HANDLE getTitleM() { return m_mtTitle; } int getActionCount() { return m_actionCount; } ActionInfo *getActions() { return m_actions; } wchar_t *getTime() { return m_time; } HICON getIcon() { return m_hIcon; } MCONTACT getContact() { return m_hContact; } MCONTACT getContactPassed() { return m_hContactPassed; } int getTimeout() { return m_iTimeout; } HWND getHwnd() { return m_hwnd; } void *getData() { return m_PluginData; } PopupAvatar *getAvatar() { return m_avatar; } Formula::Args *getArgs() { return &m_args; } PopupSkin::RenderInfo *getRenderInfo() { return &m_renderInfo; } SIZE getSize() { return m_sz; } void setSize(SIZE sz) { this->m_sz = sz; if (m_hwnd) { SetWindowPos(m_hwnd, 0, 0, 0, sz.cx, sz.cy, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_DEFERERASE | SWP_NOSENDCHANGING); if (!m_customPopup) PopupThreadUpdateWindow(this); } } bool isPositioned() { return m_bPositioned; } POINT getPosition() { return m_pos; } POINT getRealPosition() { return POINT(); } void setPosition(POINT pt) { m_bPositioned = true; m_pos = pt; if (m_bSlide) m_ptPosition1 = pt; else SetWindowPos(m_hwnd, 0, pt.x, pt.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE | SWP_DEFERERASE | SWP_NOSENDCHANGING); } // Thread-related methods void callMethodAsync(MethodPtr method, LPARAM lParam) { // we can't pass MethodPtr via WPARAM because it's size can differ! well, it's still 4 bytes on msvc but // on gcc we will get 8 bytes... MethodPtr *method_copy = new MethodPtr; *method_copy = method; PostMessage(m_hwnd, UM_CALLMETHOD, (WPARAM)method_copy, (LPARAM)lParam); } void callMethodSync(MethodPtr method, LPARAM lParam) { // we can't pass MethodPtr via WPARAM because it's size can differ! well, it's still 4 bytes on msvc but // on gcc we will get 8 bytes... MethodPtr *method_copy = new MethodPtr; *method_copy = method; SendMessage(m_hwnd, UM_CALLMETHOD, (WPARAM)method_copy, (LPARAM)lParam); } LRESULT m_updateData_POPUPDATAW_V2(LPARAM arg) { updateData((POPUPDATAW_V2 *)arg); update(); return 0; } LRESULT m_updateData_POPUPDATA2(LPARAM arg) { updateData((POPUPDATA2 *)arg); update(); return 0; } LRESULT m_updateText(LPARAM arg) { updateText((wchar_t *)arg); update(); return 0; } LRESULT m_updateTitle(LPARAM arg) { updateTitle((wchar_t *)arg); update(); return 0; } LRESULT m_show(LPARAM) { show(); return 0; } LRESULT m_hide(LPARAM) { hide(); return 0; } // window related stuff LRESULT CALLBACK WindowProc(UINT, WPARAM, LPARAM); static LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); // window creation flag volatile bool m_bWindowCreated; }; bool LoadPopupWnd2(); void UnloadPopupWnd2(); static inline bool IsValidPopupObject(PopupWnd2 *wnd) { bool res = false; __try { if (wnd->m_signature == POPUP_OBJECT_SIGNARURE) res = true; } __except (EXCEPTION_EXECUTE_HANDLER) { res = false; } return res; } #endif // __popup_wnd2_h__