diff options
Diffstat (limited to 'plugins/w7ui/clistproxywindow.cpp')
-rw-r--r-- | plugins/w7ui/clistproxywindow.cpp | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/plugins/w7ui/clistproxywindow.cpp b/plugins/w7ui/clistproxywindow.cpp new file mode 100644 index 0000000000..12e5b476ed --- /dev/null +++ b/plugins/w7ui/clistproxywindow.cpp @@ -0,0 +1,292 @@ +#include "headers.h"
+
+CClistProxyWindow *g_clistProxyWnd = 0;
+extern ITaskbarList3 *g_pTaskbarList;
+
+CClistProxyWindow::CClistProxyWindow() : m_overlayEvents(5)
+{
+ g_clistProxyWnd = this;
+
+ m_activeOverlay = 0;
+ m_overlayIcon = 0;
+ m_overlayText = 0;
+
+ SetWindowText(hwnd(), _T("Miranda IM"));
+ SendMessage(hwnd(), WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
+ SendMessage(hwnd(), WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
+
+ SetEventHook(ME_CLIST_STATUSMODECHANGE, &CClistProxyWindow::OnStatusModeChanged);
+ SetEventHook(ME_AV_MYAVATARCHANGED, &CClistProxyWindow::OnAvatarChanged);
+ SetEventHook(ME_SYSTEM_MODULESLOADED, &CClistProxyWindow::OnModulesLoaded);
+ SetEventHook(ME_PROTO_ACCLISTCHANGED, &CClistProxyWindow::OnAccListChanged);
+
+ SetTimer(1, 500);
+}
+
+CClistProxyWindow::~CClistProxyWindow()
+{
+ KillObjectEventHooks(this);
+}
+
+int __cdecl CClistProxyWindow::OnStatusModeChanged(WPARAM wParam, LPARAM lParam)
+{
+ Update();
+ return 0;
+}
+int __cdecl CClistProxyWindow::OnAvatarChanged(WPARAM wParam, LPARAM lParam)
+{
+ Update();
+ return 0;
+}
+int __cdecl CClistProxyWindow::OnModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ Update();
+ return 0;
+}
+int __cdecl CClistProxyWindow::OnAccListChanged(WPARAM wParam, LPARAM lParam)
+{
+ Update();
+ return 0;
+}
+
+HANDLE CClistProxyWindow::SetEventHook(char *evt, int (__cdecl CClistProxyWindow::*fn)(WPARAM, LPARAM))
+{
+ return HookEventObj(evt, *(MIRANDAHOOKOBJ *)&fn, this);
+}
+
+void CClistProxyWindow::Flash()
+{
+ FlashWindow(hwnd(), TRUE);
+}
+
+void CClistProxyWindow::SetOverlayIcon(HICON hIcon)
+{
+ m_overlayIcon = hIcon;
+ m_overlayIconHandle = 0;
+}
+
+void CClistProxyWindow::SetOverlayIconHandle(HANDLE hIcolibIcon)
+{
+ m_overlayIcon = 0;
+ m_overlayIconHandle = hIcolibIcon;
+}
+
+void CClistProxyWindow::AddOverlayEvent(int idx)
+{
+ m_overlayEvents[idx].Push();
+}
+
+void CClistProxyWindow::RemoveOverlayEvent(int idx)
+{
+ m_overlayEvents[idx].Pop();
+}
+
+int CClistProxyWindow::AllocateOverlayEvent(HANDLE hIcolibIcon)
+{
+ m_overlayEvents.insert(new COverlayEventSlot(hIcolibIcon, _T("")), m_overlayEvents.getCount());
+ return m_overlayEvents.getCount() - 1;
+}
+
+void CClistProxyWindow::Update()
+{
+ AddButton(LoadSkinnedIcon(SKINICON_OTHER_MIRANDA), TranslateT("Menu"), -1);
+
+ int nAccounts = 0;
+ PROTOACCOUNT **accounts;
+ ProtoEnumAccounts(&nAccounts, &accounts);
+ for (int i = 0; i < nAccounts; ++i)
+ {
+ if (!accounts[i]->bIsEnabled || !accounts[i]->bIsVisible || !accounts[i]->ppro || !(accounts[i]->ppro->GetCaps(PFLAGNUM_1) & PF1_IM))
+ continue;
+
+ HICON hIcon = LoadSkinnedProtoIcon(accounts[i]->szModuleName, CallProtoService(accounts[i]->szModuleName, PS_GETSTATUS, 0, 0));
+ AddButton(hIcon, accounts[i]->tszAccountName, (INT_PTR)accounts[i]->tszAccountName);
+ }
+ UpdateButtons(g_pTaskbarList);
+
+ InvalidateThumbnail();
+}
+
+void CClistProxyWindow::OnActivate(HWND hwndFrom)
+{
+ CallService(MS_CLIST_SHOWHIDE, 0, 0);
+
+ HWND hwndClui = (HWND)CallService(MS_CLUI_GETHWND, 0, 0);
+ if (hwndFrom != hwndClui && !IsIconic(hwndClui) && IsWindowVisible(hwndClui))
+ SetForegroundWindow(hwndClui);
+ else
+ SetForegroundWindow(NULL);
+}
+
+void CClistProxyWindow::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:
+ {
+ hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDMAIN, 0, 0);
+ break;
+ }
+
+ default:
+ {
+ hMenu = (HMENU)CallService(MS_CLIST_MENUGETSTATUS, 0, 0);
+ int nItems = GetMenuItemCount(hMenu);
+ for (int i = 0; i < nItems; ++i)
+ {
+ TCHAR buf[128];
+ MENUITEMINFO mii = {0};
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STRING|MIIM_SUBMENU;
+ mii.dwTypeData = buf;
+ mii.cch = SIZEOF(buf);
+ GetMenuItemInfo(hMenu, i, TRUE, &mii);
+
+ if (mii.hSubMenu && !lstrcmp(mii.dwTypeData, (TCHAR*)data))
+ {
+ hMenu = mii.hSubMenu;
+ break;
+ }
+ }
+ }
+ }
+
+ SetForegroundWindow(hwndClui);
+ TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hwndClui, NULL);
+}
+
+void CClistProxyWindow::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_GETMYAVATAR, 0, (LPARAM)"");
+ 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 = NULL;
+ 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 | AVDRQ_OWNPIC;
+ avdr.szProto = "";
+
+ avdr.alpha = 255;
+ CallService(MS_AV_DRAWAVATAR, 0, (LPARAM)&avdr);
+
+ rc.left += avatarWidth + 5;
+ }
+ }
+
+ int nAccounts = 0;
+ PROTOACCOUNT **accounts;
+ ProtoEnumAccounts(&nAccounts, &accounts);
+ for (int i = 0; i < nAccounts; ++i)
+ {
+ if (!accounts[i]->bIsEnabled /*|| !accounts[i]->ppro || !(accounts[i]->ppro->GetCaps(PFLAGNUM_1) & PF1_IM)*/)
+ continue;
+
+ char *proto = accounts[i]->szModuleName;
+
+ if (true)
+ {
+ TCHAR name[128]; name[0] = 0;
+
+ CONTACTINFO ci = {0};
+ ci.cbSize = sizeof(ci);
+ ci.hContact = NULL;
+ ci.szProto = proto;
+ ci.dwFlag = CNF_UNIQUEID | CNF_TCHAR;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci))
+ {
+ switch (ci.type)
+ {
+ case CNFT_ASCIIZ:
+ mir_sntprintf(name, SIZEOF(name), _T("%s - %s"), accounts[i]->tszAccountName, ci.pszVal);
+ mir_free((void *)ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ mir_sntprintf(name, SIZEOF(name), _T("%s - %u"), accounts[i]->tszAccountName, ci.dVal);
+ break;
+ }
+
+ } else
+ {
+ lstrcpyn(name, accounts[i]->tszAccountName, SIZEOF(name));
+ }
+
+ RECT rcText = rc;
+ rcText.left += 20;
+ DrawText(hdc, name, -1, &rcText, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK|DT_TOP|DT_SINGLELINE);
+ GetTextExtentPoint32(hdc, name, lstrlen(name), &sz);
+ }
+
+ if (true)
+ {
+ HICON hIcon = LoadSkinnedProtoIcon(proto, CallProtoService(proto, PS_GETSTATUS, 0, 0));
+ DrawIconEx(hdc, rc.left, rc.top + (sz.cy - 16) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+ }
+
+ rc.top += sz.cy + 5;
+ }
+
+ SelectObject(hdc, hfntSave);
+
+ DeleteDC(hdc);
+ MakeBitmapOpaque(hbmp);
+ SetThumbnail(hbmp);
+ DeleteObject(hbmp);
+}
+
+void CClistProxyWindow::OnClose()
+{
+ CallService("CloseAction", NULL, NULL);
+}
+
+void CClistProxyWindow::OnTimer(int id)
+{
+ HANDLE hIcolibItem = m_overlayIconHandle;
+ for (m_activeOverlay = (m_activeOverlay + 1) % (m_overlayEvents.getCount() + 1); m_activeOverlay < m_overlayEvents.getCount(); ++m_activeOverlay)
+ if (m_overlayEvents[m_activeOverlay])
+ {
+ hIcolibItem = m_overlayEvents[m_activeOverlay].GetIcon();
+ break;
+ }
+
+ HICON hIcon = hIcolibItem ? (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)hIcolibItem) : m_overlayIcon;
+ if (hIcon) g_pTaskbarList->SetOverlayIcon(hwnd(), hIcon, L"");
+}
|