diff options
Diffstat (limited to 'plugins/NewStory/src/history_control.cpp')
-rw-r--r-- | plugins/NewStory/src/history_control.cpp | 810 |
1 files changed, 405 insertions, 405 deletions
diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp index d7fb75cc37..da8dcecd5b 100644 --- a/plugins/NewStory/src/history_control.cpp +++ b/plugins/NewStory/src/history_control.cpp @@ -1,23 +1,7 @@ #include "stdafx.h" -LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - HANDLE htuLog = 0; -void InitNewstoryControl() -{ - htuLog = MTextRegister("Newstory", MTEXT_FANCY_DEFAULT | MTEXT_SYSTEM_HICONS); - - WNDCLASS wndclass = {}; - wndclass.style = /*CS_HREDRAW | CS_VREDRAW | */CS_DBLCLKS | CS_GLOBALCLASS; - wndclass.lpfnWndProc = NewstoryListWndProc; - wndclass.cbWndExtra = sizeof(void *); - wndclass.hInstance = g_plugin.getInst(); - wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndclass.lpszClassName = _T(NEWSTORYLIST_CLASS); - RegisterClass(&wndclass); -} - ///////////////////////////////////////////////////////////////////////// // Control utilities, types and constants @@ -25,11 +9,11 @@ struct NewstoryListData : public MZeroedObject { HistoryArray items; - DWORD scrollTopItem; // topmost item + int scrollTopItem; // topmost item int scrollTopPixel; // y coord of topmost item, this should be negative or zero - DWORD caret; + int caret; int cachedWindowHeight; - DWORD cachedMaxTopItem; // the largest ID of top item to avoid empty space + int cachedMaxTopItem; // the largest ID of top item to avoid empty space int cachedMaxTopPixel; RECT rcLastPaint; @@ -40,13 +24,6 @@ struct NewstoryListData : public MZeroedObject #define AVERAGE_ITEM_HEIGHT 100 -//static HFONT CopyFont(HFONT hfnt) -//{ -// LOGFONT lf; -// GetObject(hfnt, sizeof(lf), &lf); -// return CreateFontIndirect(&lf); -//} - static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels); static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item); static void FixScrollPosition(HWND hwnd, NewstoryListData *data); @@ -56,7 +33,6 @@ static void EndEditItem(HWND hwnd, NewstoryListData *data); static int LayoutItem(HWND hwnd, HistoryArray *items, int index); static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width); - // Edit box static WNDPROC OldEditWndProc; static LRESULT CALLBACK HistoryEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -94,7 +70,378 @@ static LRESULT CALLBACK HistoryEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, L } ///////////////////////////////////////////////////////////////////////// +// Utilities + +static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels) +{ + if (scrollItems) { + data->scrollTopItem += scrollItems; + data->scrollTopPixel = 0; + } + else if (scrollPixels) { + data->scrollTopPixel += scrollPixels; + if (data->scrollTopPixel > 0) { + while ((data->scrollTopPixel > 0) && data->scrollTopItem) { + data->scrollTopItem--; + int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem); + data->scrollTopPixel -= itemHeight; + } + + if (data->scrollTopPixel > 0) { + data->scrollTopPixel = 0; + } + } + else if (data->scrollTopPixel < 0) { + int maxItem = data->items.getCount(); + int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem); + while ((-data->scrollTopPixel > itemHeight) && (data->scrollTopItem < maxItem)) { + data->scrollTopPixel += itemHeight; + data->scrollTopItem++; + itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem); + } + } + } + + FixScrollPosition(hwnd, data); +} + +static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item) +{ + if (data->scrollTopItem >= item) { + data->scrollTopItem = item; + data->scrollTopPixel = 0; + } + else { + RECT rc; GetClientRect(hwnd, &rc); + int height = rc.bottom - rc.top; + int top = data->scrollTopPixel; + int idx = data->scrollTopItem; + int itemHeight = LayoutItem(hwnd, &data->items, idx); + bool found = false; + while (top < height) { + if (idx == item) { + itemHeight = LayoutItem(hwnd, &data->items, idx); + if (top + itemHeight > height) + ScrollListBy(hwnd, data, 0, height - top - itemHeight); + found = true; + break; + } + top += itemHeight; + idx++; + itemHeight = LayoutItem(hwnd, &data->items, idx); + } + if (!found) { + data->scrollTopItem = item; + data->scrollTopPixel = 0; + } + } + FixScrollPosition(hwnd, data); +} + +static void FixScrollPosition(HWND hwnd, NewstoryListData *data) +{ + EndEditItem(hwnd, data); + + RECT rc; + GetWindowRect(hwnd, &rc); + int windowHeight = rc.bottom - rc.top; + + if (windowHeight != data->cachedWindowHeight) { + int maxTopItem = 0; + int tmp = 0; + for (maxTopItem = data->items.getCount(); (maxTopItem > 0) && (tmp < windowHeight); maxTopItem--) + tmp += LayoutItem(hwnd, &data->items, maxTopItem - 1); + data->cachedMaxTopItem = maxTopItem; + data->cachedWindowHeight = windowHeight; + data->cachedMaxTopPixel = (windowHeight < tmp) ? windowHeight - tmp : 0; + } + + if (data->scrollTopItem < 0) { + data->scrollTopItem = 0; + } + + if ((data->scrollTopItem > data->cachedMaxTopItem) || + ((data->scrollTopItem == data->cachedMaxTopItem) && (data->scrollTopPixel < data->cachedMaxTopPixel))) { + data->scrollTopItem = data->cachedMaxTopItem; + data->scrollTopPixel = data->cachedMaxTopPixel; + } + RecalcScrollBar(hwnd, data); +} + +static void RecalcScrollBar(HWND hwnd, NewstoryListData *data) +{ + SCROLLINFO si = { 0 }; + RECT clRect; + GetClientRect(hwnd, &clRect); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + si.nMin = 0; + si.nMax = data->items.getCount() * AVERAGE_ITEM_HEIGHT; + si.nPage = clRect.bottom; + si.nPos = data->scrollTopItem * AVERAGE_ITEM_HEIGHT; + SetScrollInfo(hwnd, SB_VERT, &si, TRUE); +} + +static void BeginEditItem(HWND hwnd, NewstoryListData *data, int index) +{ + if (data->hwndEditBox) + EndEditItem(hwnd, data); + + if (data->scrollTopItem > index) + return; + + RECT rc; GetClientRect(hwnd, &rc); + int height = rc.bottom - rc.top; + + int top = data->scrollTopPixel; + int idx = data->scrollTopItem; + int itemHeight = LayoutItem(hwnd, &data->items, idx); + while (top < height) { + if (idx == index) { + HistoryArray::ItemData *item = data->items.get(index, ELM_DATA); + + int tpl; + int fontid; + int colorid; + switch (item->dbe.eventType) { + case EVENTTYPE_MESSAGE: + tpl = TPL_COPY_MESSAGE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG; + colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG; + break; + + case EVENTTYPE_FILE: + tpl = TPL_COPY_FILE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE; + colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE; + break; + + case EVENTTYPE_STATUSCHANGE: + tpl = TPL_COPY_SIGN; + fontid = FONT_STATUS; + colorid = COLOR_STATUS; + break; + + case EVENTTYPE_AUTHREQUEST: + tpl = TPL_COPY_AUTH; + fontid = FONT_INOTHER; + colorid = COLOR_INOTHER; + break; + + case EVENTTYPE_ADDED: + tpl = TPL_COPY_ADDED; + fontid = FONT_INOTHER; + colorid = COLOR_INOTHER; + break; + + case EVENTTYPE_JABBER_PRESENCE: + tpl = TPL_COPY_PRESENCE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; + colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER; + break; + + default: + tpl = TPL_COPY_OTHER; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; + colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER; + break; + } + + ptrW text(TplFormatString(tpl, item->hContact, item)); + data->hwndEditBox = CreateWindow(L"EDIT", text, WS_CHILD | WS_BORDER | ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL, 0, top, rc.right - rc.left, itemHeight, hwnd, NULL, g_plugin.getInst(), NULL); + OldEditWndProc = (WNDPROC)SetWindowLongPtr(data->hwndEditBox, GWLP_WNDPROC, (LONG_PTR)HistoryEditWndProc); + SendMessage(data->hwndEditBox, WM_SETFONT, (WPARAM)fonts[fontid].hfnt, 0); + SendMessage(data->hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100); + SendMessage(data->hwndEditBox, EM_SETSEL, 0, (LPARAM)(-1)); + ShowWindow(data->hwndEditBox, SW_SHOW); + SetFocus(data->hwndEditBox); + break; + } + top += itemHeight; + idx++; + itemHeight = LayoutItem(hwnd, &data->items, idx); + } +} + +static void EndEditItem(HWND, NewstoryListData *data) +{ + DestroyWindow(data->hwndEditBox); + data->hwndEditBox = 0; +} + +static int LayoutItem(HWND hwnd, HistoryArray *items, int index) +{ + HDC hdc = GetDC(hwnd); + RECT rc; GetClientRect(hwnd, &rc); + int width = rc.right - rc.left; + + HistoryArray::ItemData *item = items->get(index, ELM_DATA); + if (!item) return 0; + + int tpl; + int fontid; + switch (item->dbe.eventType) { + case EVENTTYPE_MESSAGE: + tpl = TPL_MESSAGE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG; + break; + + case EVENTTYPE_FILE: + tpl = TPL_FILE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE; + break; + + case EVENTTYPE_STATUSCHANGE: + tpl = TPL_SIGN; + fontid = FONT_STATUS; + break; + + case EVENTTYPE_AUTHREQUEST: + tpl = TPL_AUTH; + fontid = FONT_INOTHER; + break; + + case EVENTTYPE_ADDED: + tpl = TPL_ADDED; + fontid = FONT_INOTHER; + break; + + case EVENTTYPE_JABBER_PRESENCE: + tpl = TPL_PRESENCE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; + break; + + default: + tpl = TPL_OTHER; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; + break; + } + + HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt); + if (!item->data) + item->data = MTextCreateW(htuLog, ptrW(TplFormatString(tpl, item->hContact, item))); + + SIZE sz; + sz.cx = width - 6; + MTextMeasure(hdc, &sz, (HANDLE)item->data); + + SelectObject(hdc, hfnt); + + ReleaseDC(hwnd, hdc); + return sz.cy + 5; +} + +static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width) +{ + if (!items) return 0; + HistoryArray::ItemData *item = items->get(index, ELM_DATA); + + // LOGFONT lfText; + COLORREF clText, clBack, clLine; + int tpl; + int fontid; + int colorid; + switch (item->dbe.eventType) { + case EVENTTYPE_MESSAGE: + tpl = TPL_MESSAGE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG; + colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG; + break; + + case EVENTTYPE_FILE: + tpl = TPL_FILE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE; + colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE; + break; + + case EVENTTYPE_STATUSCHANGE: + tpl = TPL_SIGN; + fontid = FONT_STATUS; + colorid = COLOR_STATUS; + break; + + case EVENTTYPE_AUTHREQUEST: + tpl = TPL_AUTH; + fontid = FONT_INOTHER; + colorid = COLOR_INOTHER; + break; + + case EVENTTYPE_ADDED: + tpl = TPL_ADDED; + fontid = FONT_INOTHER; + colorid = COLOR_INOTHER; + break; + + case EVENTTYPE_JABBER_PRESENCE: + tpl = TPL_PRESENCE; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; + colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER; + break; + + default: + tpl = TPL_OTHER; + fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; + colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER; + break; + } + clText = fonts[fontid].cl; + if (item->flags & HIF_SELECTED) { + MTextSendMessage(0, item->data, EM_SETSEL, 0, -1); + clText = colors[COLOR_SELTEXT].cl; + clLine = GetSysColor(COLOR_HIGHLIGHTTEXT); + clBack = GetSysColor(COLOR_HIGHLIGHT); + } + else { + MTextSendMessage(0, item->data, EM_SETSEL, 0, 0); + clLine = colors[COLOR_SELECTED].cl; + clBack = colors[colorid].cl; + } + + if (!item->data) { + wchar_t *buf = TplFormatString(tpl, item->hContact, item); + item->data = MTextCreateW(htuLog, buf); + mir_free(buf); + if (!item->data) + return 0; + } + + SIZE sz; + sz.cx = width - 6; + HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt); + MTextMeasure(hdc, &sz, (HANDLE)item->data); + SelectObject(hdc, hfnt); + int height = sz.cy + 5; + + RECT rc; + SetRect(&rc, 0, top, width, top + height); + + HBRUSH hbr; + hbr = CreateSolidBrush(clBack); + FillRect(hdc, &rc, hbr); + + SetTextColor(hdc, clText); + SetBkMode(hdc, TRANSPARENT); + + POINT pos; + pos.x = 3; + pos.y = top + 2; + hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt); + MTextDisplay(hdc, pos, sz, (HANDLE)item->data); + SelectObject(hdc, hfnt); + + DeleteObject(hbr); + + HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 1, clLine)); + MoveToEx(hdc, rc.left, rc.bottom - 1, 0); + LineTo(hdc, rc.right, rc.bottom - 1); + DeleteObject(SelectObject(hdc, hpn)); + + return height; +} + +///////////////////////////////////////////////////////////////////////// // WndProc + LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { NewstoryListData *data = (NewstoryListData *)GetWindowLongPtr(hwnd, 0); @@ -114,7 +461,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM InvalidateRect(hwnd, 0, FALSE); break; - // History list control messages + // History list control messages case NSM_GETCOUNT: return data->items.getCount(); @@ -216,19 +563,14 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM } case NSM_SETCARET: - { - if ((wParam >= 0) && (wParam < data->items.getCount())) { - data->caret = wParam; - if (lParam) { - SendMessage(hwnd, NSM_ENSUREVISIBLE, data->caret, 0); - } - } + if ((wParam >= 0) && (wParam < data->items.getCount())) { + data->caret = wParam; + if (lParam) + SendMessage(hwnd, NSM_ENSUREVISIBLE, data->caret, 0); } case NSM_GETCARET: - { - return data->caret; - } + return data->caret; case NSM_FINDNEXT: { @@ -250,6 +592,19 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM return id; } + case NSM_SEEKTIME: + { + int eventCount = data->items.getCount(); + for (int i = 0; i < eventCount; i++) { + auto *item = data->items.get(i, ELM_NOTHING); + if (item->dbe.timestamp >= wParam) { + SendMessage(hwnd, NSM_SETCARET, i, TRUE); + break; + } + } + } + return TRUE; + case NSM_COPY: { CMStringW res; @@ -462,7 +817,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM case WM_MOUSEWHEEL: { - DWORD s_scrollTopItem = data->scrollTopItem; + int s_scrollTopItem = data->scrollTopItem; int s_scrollTopPixel = data->scrollTopPixel; UINT scrollLines; @@ -477,7 +832,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM case WM_VSCROLL: { - DWORD s_scrollTopItem = data->scrollTopItem; + int s_scrollTopItem = data->scrollTopItem; int s_scrollTopPixel = data->scrollTopPixel; switch (LOWORD(wParam)) { @@ -540,371 +895,16 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM return DefWindowProc(hwnd, msg, wParam, lParam); } -///////////////////////////////////////////////////////////////////////// -// Utilities -static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels) -{ - if (scrollItems) { - data->scrollTopItem += scrollItems; - data->scrollTopPixel = 0; - } - else if (scrollPixels) { - data->scrollTopPixel += scrollPixels; - if (data->scrollTopPixel > 0) { - while ((data->scrollTopPixel > 0) && data->scrollTopItem) { - data->scrollTopItem--; - int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem); - data->scrollTopPixel -= itemHeight; - } - - if (data->scrollTopPixel > 0) { - data->scrollTopPixel = 0; - } - } - else if (data->scrollTopPixel < 0) { - int maxItem = data->items.getCount(); - int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem); - while ((-data->scrollTopPixel > itemHeight) && (data->scrollTopItem < maxItem)) { - data->scrollTopPixel += itemHeight; - data->scrollTopItem++; - itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem); - } - } - } - - FixScrollPosition(hwnd, data); -} - -static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item) -{ - if (data->scrollTopItem >= item) { - data->scrollTopItem = item; - data->scrollTopPixel = 0; - } - else { - RECT rc; GetClientRect(hwnd, &rc); - int height = rc.bottom - rc.top; - int top = data->scrollTopPixel; - int idx = data->scrollTopItem; - int itemHeight = LayoutItem(hwnd, &data->items, idx); - bool found = false; - while (top < height) { - if (idx == item) { - itemHeight = LayoutItem(hwnd, &data->items, idx); - if (top + itemHeight > height) - ScrollListBy(hwnd, data, 0, height - top - itemHeight); - found = true; - break; - } - top += itemHeight; - idx++; - itemHeight = LayoutItem(hwnd, &data->items, idx); - } - if (!found) { - data->scrollTopItem = item; - data->scrollTopPixel = 0; - } - } - FixScrollPosition(hwnd, data); -} - -static void FixScrollPosition(HWND hwnd, NewstoryListData *data) -{ - EndEditItem(hwnd, data); - - RECT rc; - GetWindowRect(hwnd, &rc); - int windowHeight = rc.bottom - rc.top; - - if (windowHeight != data->cachedWindowHeight) { - int maxTopItem = 0; - int tmp = 0; - for (maxTopItem = data->items.getCount(); (maxTopItem > 0) && (tmp < windowHeight); maxTopItem--) - tmp += LayoutItem(hwnd, &data->items, maxTopItem - 1); - data->cachedMaxTopItem = maxTopItem; - data->cachedWindowHeight = windowHeight; - data->cachedMaxTopPixel = (windowHeight < tmp) ? windowHeight - tmp : 0; - } - - if (data->scrollTopItem < 0) { - data->scrollTopItem = 0; - } - - if ((data->scrollTopItem > data->cachedMaxTopItem) || - ((data->scrollTopItem == data->cachedMaxTopItem) && (data->scrollTopPixel < data->cachedMaxTopPixel))) { - data->scrollTopItem = data->cachedMaxTopItem; - data->scrollTopPixel = data->cachedMaxTopPixel; - } - RecalcScrollBar(hwnd, data); -} - -static void RecalcScrollBar(HWND hwnd, NewstoryListData *data) -{ - SCROLLINFO si = { 0 }; - RECT clRect; - GetClientRect(hwnd, &clRect); - si.cbSize = sizeof(si); - si.fMask = SIF_ALL; - si.nMin = 0; - si.nMax = data->items.getCount() * AVERAGE_ITEM_HEIGHT; - si.nPage = clRect.bottom; - si.nPos = data->scrollTopItem * AVERAGE_ITEM_HEIGHT; - SetScrollInfo(hwnd, SB_VERT, &si, TRUE); -} - -static void BeginEditItem(HWND hwnd, NewstoryListData *data, int index) -{ - if (data->hwndEditBox) - EndEditItem(hwnd, data); - - if (data->scrollTopItem > index) - return; - - RECT rc; GetClientRect(hwnd, &rc); - int height = rc.bottom - rc.top; - - int top = data->scrollTopPixel; - int idx = data->scrollTopItem; - int itemHeight = LayoutItem(hwnd, &data->items, idx); - while (top < height) { - if (idx == index) { - HistoryArray::ItemData *item = data->items.get(index, ELM_DATA); - - int tpl; - int fontid; - int colorid; - switch (item->dbe.eventType) { - case EVENTTYPE_MESSAGE: - tpl = TPL_COPY_MESSAGE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG; - colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG; - break; - - case EVENTTYPE_FILE: - tpl = TPL_COPY_FILE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE; - colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE; - break; - - case EVENTTYPE_STATUSCHANGE: - tpl = TPL_COPY_SIGN; - fontid = FONT_STATUS; - colorid = COLOR_STATUS; - break; - - case EVENTTYPE_AUTHREQUEST: - tpl = TPL_COPY_AUTH; - fontid = FONT_INOTHER; - colorid = COLOR_INOTHER; - break; - - case EVENTTYPE_ADDED: - tpl = TPL_COPY_ADDED; - fontid = FONT_INOTHER; - colorid = COLOR_INOTHER; - break; - - case EVENTTYPE_JABBER_PRESENCE: - tpl = TPL_COPY_PRESENCE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; - colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER; - break; - - default: - tpl = TPL_COPY_OTHER; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; - colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER; - break; - } - - ptrW text(TplFormatString(tpl, item->hContact, item)); - data->hwndEditBox = CreateWindow(L"EDIT", text, WS_CHILD | WS_BORDER | ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL, 0, top, rc.right - rc.left, itemHeight, hwnd, NULL, g_plugin.getInst(), NULL); - OldEditWndProc = (WNDPROC)SetWindowLongPtr(data->hwndEditBox, GWLP_WNDPROC, (LONG_PTR)HistoryEditWndProc); - SendMessage(data->hwndEditBox, WM_SETFONT, (WPARAM)fonts[fontid].hfnt, 0); - SendMessage(data->hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100); - SendMessage(data->hwndEditBox, EM_SETSEL, 0, (LPARAM)(-1)); - ShowWindow(data->hwndEditBox, SW_SHOW); - SetFocus(data->hwndEditBox); - break; - } - top += itemHeight; - idx++; - itemHeight = LayoutItem(hwnd, &data->items, idx); - } -} - -static void EndEditItem(HWND, NewstoryListData *data) -{ - DestroyWindow(data->hwndEditBox); - data->hwndEditBox = 0; -} - -static int LayoutItem(HWND hwnd, HistoryArray *items, int index) -{ - HDC hdc = GetDC(hwnd); - RECT rc; GetClientRect(hwnd, &rc); - int width = rc.right - rc.left; - - HistoryArray::ItemData *item = items->get(index, ELM_DATA); - if (!item) return 0; - - int tpl; - int fontid; - switch (item->dbe.eventType) { - case EVENTTYPE_MESSAGE: - tpl = TPL_MESSAGE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG; - break; - - case EVENTTYPE_FILE: - tpl = TPL_FILE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE; - break; - - case EVENTTYPE_STATUSCHANGE: - tpl = TPL_SIGN; - fontid = FONT_STATUS; - break; - - case EVENTTYPE_AUTHREQUEST: - tpl = TPL_AUTH; - fontid = FONT_INOTHER; - break; - - case EVENTTYPE_ADDED: - tpl = TPL_ADDED; - fontid = FONT_INOTHER; - break; - - case EVENTTYPE_JABBER_PRESENCE: - tpl = TPL_PRESENCE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; - break; - - default: - tpl = TPL_OTHER; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; - break; - } - - HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt); - if (!item->data) - item->data = MTextCreateW(htuLog, ptrW(TplFormatString(tpl, item->hContact, item))); - - SIZE sz; - sz.cx = width - 6; - MTextMeasure(hdc, &sz, (HANDLE)item->data); - - SelectObject(hdc, hfnt); - - ReleaseDC(hwnd, hdc); - return sz.cy + 5; -} - -static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width) +void InitNewstoryControl() { - if (!items) return 0; - HistoryArray::ItemData *item = items->get(index, ELM_DATA); - - // LOGFONT lfText; - COLORREF clText, clBack, clLine; - int tpl; - int fontid; - int colorid; - switch (item->dbe.eventType) { - case EVENTTYPE_MESSAGE: - tpl = TPL_MESSAGE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG; - colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG; - break; - - case EVENTTYPE_FILE: - tpl = TPL_FILE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE; - colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE; - break; - - case EVENTTYPE_STATUSCHANGE: - tpl = TPL_SIGN; - fontid = FONT_STATUS; - colorid = COLOR_STATUS; - break; - - case EVENTTYPE_AUTHREQUEST: - tpl = TPL_AUTH; - fontid = FONT_INOTHER; - colorid = COLOR_INOTHER; - break; - - case EVENTTYPE_ADDED: - tpl = TPL_ADDED; - fontid = FONT_INOTHER; - colorid = COLOR_INOTHER; - break; - - case EVENTTYPE_JABBER_PRESENCE: - tpl = TPL_PRESENCE; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; - colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER; - break; - - default: - tpl = TPL_OTHER; - fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER; - colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER; - break; - } - clText = fonts[fontid].cl; - if (item->flags & HIF_SELECTED) { - MTextSendMessage(0, item->data, EM_SETSEL, 0, -1); - // clText = colors[COLOR_SELTEXT].cl; - clLine = GetSysColor(COLOR_HIGHLIGHTTEXT); - clBack = GetSysColor(COLOR_HIGHLIGHT); //colors[COLOR_SELECTED].cl; - } - else { - MTextSendMessage(0, item->data, EM_SETSEL, 0, 0); - clLine = colors[COLOR_SELECTED].cl; - clBack = colors[colorid].cl; - } - - if (!item->data) { - wchar_t *buf = TplFormatString(tpl, item->hContact, item); - item->data = MTextCreateW(htuLog, buf); - mir_free(buf); - if (!item->data) - return 0; - } - - SIZE sz; - sz.cx = width - 6; - HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt); - MTextMeasure(hdc, &sz, (HANDLE)item->data); - SelectObject(hdc, hfnt); - int height = sz.cy + 5; - - RECT rc; - SetRect(&rc, 0, top, width, top + height); - - HBRUSH hbr; - hbr = CreateSolidBrush(clBack); - FillRect(hdc, &rc, hbr); - - SetTextColor(hdc, clText); - SetBkMode(hdc, TRANSPARENT); - - POINT pos; - pos.x = 3; - pos.y = top + 2; - hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt); - MTextDisplay(hdc, pos, sz, (HANDLE)item->data); - SelectObject(hdc, hfnt); - - DeleteObject(hbr); - - HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 1, clLine)); - MoveToEx(hdc, rc.left, rc.bottom - 1, 0); - LineTo(hdc, rc.right, rc.bottom - 1); - DeleteObject(SelectObject(hdc, hpn)); + htuLog = MTextRegister("Newstory", MTEXT_FANCY_DEFAULT | MTEXT_SYSTEM_HICONS); - return height; + WNDCLASS wndclass = {}; + wndclass.style = /*CS_HREDRAW | CS_VREDRAW | */CS_DBLCLKS | CS_GLOBALCLASS; + wndclass.lpfnWndProc = NewstoryListWndProc; + wndclass.cbWndExtra = sizeof(void *); + wndclass.hInstance = g_plugin.getInst(); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.lpszClassName = _T(NEWSTORYLIST_CLASS); + RegisterClass(&wndclass); } |