From cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 14:14:52 +0000 Subject: svn.miranda.im is moving to a new home! git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- w7ui/srmmproxywindow.cpp | 374 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 w7ui/srmmproxywindow.cpp (limited to 'w7ui/srmmproxywindow.cpp') diff --git a/w7ui/srmmproxywindow.cpp b/w7ui/srmmproxywindow.cpp new file mode 100644 index 0000000..a70ca1b --- /dev/null +++ b/w7ui/srmmproxywindow.cpp @@ -0,0 +1,374 @@ +#include "headers.h" + +extern int g_eventSlotMessage; +extern ITaskbarList3 *g_pTaskbarList; + +/////////////////////////////////////////////////////////////////////////////// +// srmm processing + +CSrmmProxyWindow::CSrmmProxyWindow(HANDLE hContact, HWND hwndWindow, HWND hwndParent) +{ + m_hContact = hContact; + m_hwndWindow = hwndWindow; + m_hwndParent = hwndParent; + + m_hbmpPreview = NULL; + m_refreshPreview = true; + + m_bActive = false; + m_bUnread = false; + m_bTyping = false; + + UpdateIcon(); + SetWindowText(hwnd(), (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)m_hContact, GCDNF_TCHAR)); + SetTimer(1, 1000); + + SetEventHook(ME_DB_EVENT_ADDED, &CSrmmProxyWindow::OnDbEventAdded); + SetEventHook(ME_DB_CONTACT_SETTINGCHANGED, &CSrmmProxyWindow::OnDbSettingChanged); + SetEventHook(ME_AV_AVATARCHANGED, &CSrmmProxyWindow::OnAvatarChanged); + SetEventHook(ME_PROTO_CONTACTISTYPING, &CSrmmProxyWindow::OnContactTyping); + + AddButton(LoadSkinnedIcon(SKINICON_OTHER_USERDETAILS), TranslateT("User Details"), 1, THBF_DISMISSONCLICK); + AddButton(LoadSkinnedIcon(SKINICON_OTHER_HISTORY), TranslateT("History"), 2, THBF_DISMISSONCLICK); + AddButton(LoadSkinnedIcon(SKINICON_EVENT_FILE), TranslateT("File"), 3, THBF_DISMISSONCLICK); + UpdateButtons(g_pTaskbarList); +} + +CSrmmProxyWindow::~CSrmmProxyWindow() +{ + DeleteObject(m_hbmpPreview); + KillObjectEventHooks(this); +} + + +void CSrmmProxyWindow::Refresh() +{ + InvalidateThumbnail(); + m_refreshPreview = true; +} + +int __cdecl CSrmmProxyWindow::OnDbEventAdded(WPARAM wParam, LPARAM lParam) +{ + if ((HANDLE)wParam == m_hContact) + { + Refresh(); + + if (!m_bUnread && !IsActive()) + { + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(dbei); + if (!CallService(MS_DB_EVENT_GET, (WPARAM)lParam, (LPARAM)&dbei)) + if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & (DBEF_READ|DBEF_SENT))) + { + g_clistProxyWnd->Flash(); + g_clistProxyWnd->AddOverlayEvent(g_eventSlotMessage); + m_bUnread = true; + UpdateIcon(); + } + } + } + return 0; +} + +int __cdecl CSrmmProxyWindow::OnDbSettingChanged(WPARAM wParam, LPARAM lParam) +{ + if ((HANDLE)wParam == m_hContact) + { + UpdateIcon(); + Refresh(); + } + return 0; +} + +int __cdecl CSrmmProxyWindow::OnAvatarChanged(WPARAM wParam, LPARAM lParam) +{ + if ((HANDLE)wParam == m_hContact) + Refresh(); + return 0; +} + +int __cdecl CSrmmProxyWindow::OnContactTyping(WPARAM wParam, LPARAM lParam) +{ + if ((HANDLE)wParam == m_hContact) + { + m_bTyping = lParam ? true : false; + UpdateIcon(); + } + return 0; +} + +HANDLE CSrmmProxyWindow::SetEventHook(char *evt, int (__cdecl CSrmmProxyWindow::*fn)(WPARAM, LPARAM)) +{ + return HookEventObj(evt, *(MIRANDAHOOKOBJ *)&fn, this); +} + +void CSrmmProxyWindow::OnTabActive() +{ + m_bActive = true; + if (m_bUnread) + { + g_clistProxyWnd->RemoveOverlayEvent(g_eventSlotMessage); + m_bUnread = false; + UpdateIcon(); + } +} + +void CSrmmProxyWindow::OnTabInactive() +{ + m_bActive = false; +} + +bool CSrmmProxyWindow::IsActive() +{ + for (HWND hwnd = GetFocus(); hwnd; hwnd = GetParent(hwnd)) + if (hwnd == m_hwndWindow) + return m_bActive = true; + return m_bActive = false; +} + +void CSrmmProxyWindow::UpdateIcon() +{ + HICON hIcon; + if (m_bTyping) + { + hIcon = LoadSkinnedIcon(SKINICON_OTHER_TYPING); + } else + if (m_bUnread) + { + hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); + } else + { + char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)m_hContact, 0); + if (!szProto) return; + int iStatus = DBGetContactSettingWord(m_hContact, szProto, "Status", ID_STATUS_OFFLINE); + hIcon = (HICON)LoadSkinnedProtoIcon(szProto, iStatus); + } + + SendMessage(hwnd(), WM_SETICON, ICON_BIG, (LPARAM)hIcon); + SendMessage(hwnd(), WM_SETICON, ICON_SMALL, (LPARAM)hIcon); +} + +void CSrmmProxyWindow::OnActivate(HWND hwndFrom) +{ + CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)m_hContact, 0); +} + +void CSrmmProxyWindow::OnToolbar(int id, INT_PTR data) +{ + POINT pt; GetCursorPos(&pt); + HMENU hMenu = NULL; + HWND hwndClui = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); + + switch (data) + { + case 1: + CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)m_hContact, 0); + break; + + case 2: + CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)m_hContact, 0); + break; + + case 3: + CallService(MS_FILE_SENDFILE, (WPARAM)m_hContact, 0); + break; + } +} + +void CSrmmProxyWindow::OnRenderThumbnail(int width, int height) +{ + HBITMAP hbmp = CreateDwmBitmap(width, height); + HDC hdc = CreateCompatibleDC(0); + SelectObject(hdc, hbmp); + + RGBQUAD rgb0, rgb1; + rgb0.rgbRed = 0; rgb0.rgbGreen = 0; rgb0.rgbBlue = 0; + rgb1.rgbRed = 19; rgb1.rgbGreen = 58; rgb1.rgbBlue = 89; + DrawGradient(hdc, 0, 0, width, height, &rgb0, &rgb1); + + HFONT hfntSave = (HFONT)SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); + SetTextColor(hdc, RGB(255, 255, 255)); + SetBkMode(hdc, TRANSPARENT); + + RECT rc; + SIZE sz; + SetRect(&rc, 5, 5, width-10, height-10); + + int avatarWidth = 0; + int avatarHeight = 0; + if (true) + { + AVATARCACHEENTRY *ace = (AVATARCACHEENTRY *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)m_hContact, 0); + if (ace && (ace != (AVATARCACHEENTRY *)CALLSERVICE_NOTFOUND)) + { + if (ace->bmWidth < width / 4) + { + avatarWidth = ace->bmWidth; + avatarHeight = ace->bmHeight; + } else + { + avatarWidth = width / 4; + avatarHeight = avatarWidth * ace->bmHeight / ace->bmWidth; + } + + AVATARDRAWREQUEST avdr = {0}; + avdr.cbSize = sizeof(avdr); + avdr.hContact = m_hContact; + avdr.hTargetDC = hdc; + avdr.rcDraw = rc; + avdr.rcDraw.bottom = avdr.rcDraw.top + avatarHeight; + avdr.rcDraw.right = avdr.rcDraw.left + avatarWidth; + avdr.dwFlags = AVDRQ_FALLBACKPROTO | AVDRQ_FORCEALPHA; + + avdr.alpha = 255; + CallService(MS_AV_DRAWAVATAR, 0, (LPARAM)&avdr); + + rc.left += avatarWidth + 5; + } + } + + char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)m_hContact, 0); + + if (true) + { + CONTACTINFO ci = {0}; + ci.cbSize = sizeof(ci); + ci.hContact = m_hContact; + ci.szProto = proto; + ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR; + if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) + { + TCHAR name[128]; name[0] = 0; + switch (ci.type) + { + case CNFT_ASCIIZ: + mir_sntprintf(name, SIZEOF(name), _T("%s"), ci.pszVal); + mir_free((void *)ci.pszVal); + break; + case CNFT_DWORD: + mir_sntprintf(name, SIZEOF(name), _T("%u"), ci.dVal); + break; + } + + TextOut(hdc, rc.left + 20, rc.top, name, lstrlen(name)); + GetTextExtentPoint32(hdc, name, lstrlen(name), &sz); + } + } + + if (true) + { + HIMAGELIST hIml = (HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0); + int iIcon = CallService(MS_CLIST_GETCONTACTICON, (WPARAM)m_hContact, 0); + ImageList_Draw(hIml, iIcon, hdc, rc.left, rc.top + (sz.cy - 16) / 2, ILD_TRANSPARENT); + } + + rc.top += sz.cy + 5; + + rc.left += 10; + + struct + { + TCHAR *text; + bool out; + } msgs[10] = {0}; + + if (true) + { + int hMsgs = 0; + int n = 0; + HANDLE hEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)m_hContact, 0); + while (hEvent) + { + BYTE buf[1024]; + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(dbei); + dbei.cbBlob = sizeof(buf); + dbei.pBlob = buf; + if (!CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&dbei)) + { + if (dbei.eventType == EVENTTYPE_MESSAGE) + { + msgs[n].text = DbGetEventTextT(&dbei, CP_ACP); + msgs[n].out = dbei.flags & DBEF_SENT ? true : false; + + RECT rcCopy = rc; + hMsgs += DrawText(hdc, msgs[n].text, -1, &rcCopy, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK|DT_TOP|DT_CALCRECT); + if (n && hMsgs > rc.bottom - rc.top) + { + mir_free(msgs[n].text); + msgs[n].text = 0; + break; + } + + hMsgs += 3; + + if (++n >= SIZEOF(msgs)) break; + } + } + hEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEvent, 0); + } + } + + if (true) + { + for (int i = SIZEOF(msgs); i--; ) + { + if (!msgs[i].text) continue; + + TCHAR szDir[] = { (msgs[i].out ? (WCHAR)0xbb : (WCHAR)0xab), 0 }; + rc.left -= 10; + DrawText(hdc, szDir, -1, &rc, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK|DT_TOP); + rc.left += 10; + + rc.top += 3 + DrawText(hdc, msgs[i].text, -1, &rc, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK|DT_TOP); + mir_free(msgs[i].text); + } + } + + SelectObject(hdc, hfntSave); + + DeleteDC(hdc); + MakeBitmapOpaque(hbmp); + SetThumbnail(hbmp); + DeleteObject(hbmp); +} + +void CSrmmProxyWindow::OnRenderPreview() +{ + if (!m_hbmpPreview) return; + + RECT rc; + GetWindowRect(m_hwndWindow, &rc); + MapWindowPoints(NULL, m_hwndParent, (POINT *)&rc, 2); + SetPreview(m_hbmpPreview, rc.left, rc.top); +} + +void CSrmmProxyWindow::OnTimer(int) +{ + g_pTaskbarList->UnregisterTab(m_hwndParent); + + if (!m_refreshPreview) return; + if (!IsWindowVisible(m_hwndWindow) || !IsWindowVisible(m_hwndParent) || IsIconic(m_hwndParent)) return; + if (m_hbmpPreview) DeleteObject(m_hbmpPreview); + + m_refreshPreview = false; + + RECT rc; + GetWindowRect(m_hwndWindow, &rc); + + m_hbmpPreview = CreateDwmBitmap(rc.right - rc.left, rc.bottom - rc.top); + HDC hdc = CreateCompatibleDC(0); + HBITMAP hbmpSave = (HBITMAP)SelectObject(hdc, m_hbmpPreview); + PrintWindow(m_hwndWindow, hdc, PW_CLIENTONLY); + SelectObject(hdc, hbmpSave); + DeleteDC(hdc); + + MakeBitmapOpaque(m_hbmpPreview); + + InvalidateThumbnail(); +} + +void CSrmmProxyWindow::OnClose() +{ + SendMessage(m_hwndWindow, WM_CLOSE, 1, 0); +} \ No newline at end of file -- cgit v1.2.3