From 1c6e6e286bbe94a091361853935e10b8fc0a7dfc Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 17 Jan 2014 18:17:10 +0000 Subject: - unused module removed from Scriver; - window data for a chat session is now filled properly git-svn-id: http://svn.miranda-ng.org/main/trunk@7692 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Scriver/src/chat/chat.h | 13 +- plugins/Scriver/src/chat/log.cpp | 51 +- plugins/Scriver/src/chat/manager.cpp | 2 +- plugins/Scriver/src/chat/services.cpp | 39 - plugins/Scriver/src/chat/window.cpp | 89 +- plugins/Scriver/src/msgdialog.cpp | 10 +- plugins/Scriver/src/msgs.h | 60 +- plugins/Scriver/src/msgwindow.cpp | 1887 +++++++++++++++++---------------- plugins/Scriver/src/msgwindow.h | 21 +- 9 files changed, 1047 insertions(+), 1125 deletions(-) delete mode 100644 plugins/Scriver/src/chat/services.cpp (limited to 'plugins/Scriver/src') diff --git a/plugins/Scriver/src/chat/chat.h b/plugins/Scriver/src/chat/chat.h index 323f8cf9ea..00598c44e1 100644 --- a/plugins/Scriver/src/chat/chat.h +++ b/plugins/Scriver/src/chat/chat.h @@ -61,7 +61,6 @@ struct LOGSTREAMDATA : public GCLogStreamDataBase struct SESSION_INFO : public GCSessionInfoBase { - char* pszHeader; TCHAR szSearch[255]; int desiredInputAreaHeight; @@ -81,24 +80,22 @@ typedef struct{ } COLORCHOOSER; -//main.c +// main.c void UpgradeCheck(void); -//colorchooser.c +// colorchooser.c INT_PTR CALLBACK DlgProcColorToolWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -//log.c +// log.c void Log_StreamInEvent(HWND hwndDlg, LOGINFO* lin, SESSION_INFO *si, BOOL bRedraw); void LoadMsgLogBitmaps(void); void FreeMsgLogBitmaps(void); TCHAR* GetChatLogsFilename (HANDLE hContact, time_t tTime); -char* Log_CreateRtfHeader(MODULEINFO * mi, SESSION_INFO *si); -//window.c -INT_PTR CALLBACK RoomWndProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam); +// window.c int GetTextPixelSize( TCHAR* pszText, HFONT hFont, BOOL bWidth); -//options.c +// options.c int OptionsInit(void); // services.c diff --git a/plugins/Scriver/src/chat/log.cpp b/plugins/Scriver/src/chat/log.cpp index 613669777d..f13556a494 100644 --- a/plugins/Scriver/src/chat/log.cpp +++ b/plugins/Scriver/src/chat/log.cpp @@ -127,7 +127,7 @@ void Log_StreamInEvent(HWND hwndDlg, LOGINFO* lin, SESSION_INFO *si, BOOL bRedra sm.rangeToReplace = bRedraw ? NULL : &newsel; sm.flags = 0; sm.disableRedraw = TRUE; - sm.hContact = si->windowData.hContact; + sm.hContact = si->hContact; CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM)&sm); } @@ -152,52 +152,3 @@ void Log_StreamInEvent(HWND hwndDlg, LOGINFO* lin, SESSION_INFO *si, BOOL bRedra InvalidateRect(hwndRich, NULL, TRUE); } } - -char* Log_CreateRtfHeader(MODULEINFO *mi, SESSION_INFO *si) -{ - int bufferAlloced, bufferEnd, i = 0; - int charset = 0; - BOOL forceCharset = FALSE; - - // guesstimate amount of memory for the RTF header - bufferEnd = 0; - bufferAlloced = 4096; - char *buffer = (char*)mir_realloc(si->pszHeader, bufferAlloced); - buffer[0] = '\0'; - - // ### RTF HEADER - - // font table - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "{\\rtf1\\ansi\\deff0{\\fonttbl"); - for (i = 0; i < OPTIONS_FONTCOUNT; i++) - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "{\\f%u\\fnil\\fcharset%u%S;}", i, (!forceCharset) ? pci->aFonts[i].lf.lfCharSet : charset, pci->aFonts[i].lf.lfFaceName); - - // colour table - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}{\\colortbl ;"); - - for (i = 0; i < OPTIONS_FONTCOUNT; i++) - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(pci->aFonts[i].color), GetGValue(pci->aFonts[i].color), GetBValue(pci->aFonts[i].color)); - - for (i = 0; i < mi->nColorCount; i++) - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(mi->crColors[i]), GetGValue(mi->crColors[i]), GetBValue(mi->crColors[i])); - - // new paragraph - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}\\pard"); - - // set tabs and indents - int iIndent = 0; - - if (g_Settings.dwIconFlags) { - iIndent += (14 * 1440) / g_dat.logPixelSX; - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\tx%u", iIndent); - } - if (g_Settings.ShowTime) { - int iSize = (g_Settings.LogTextIndent * 1440) / g_dat.logPixelSX; - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\tx%u", iIndent + iSize); - if (g_Settings.LogIndentEnabled) - iIndent += iSize; - } - AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\fi-%u\\li%u", iIndent, iIndent); - - return buffer; -} diff --git a/plugins/Scriver/src/chat/manager.cpp b/plugins/Scriver/src/chat/manager.cpp index 192906fb40..821a82bde6 100644 --- a/plugins/Scriver/src/chat/manager.cpp +++ b/plugins/Scriver/src/chat/manager.cpp @@ -26,7 +26,7 @@ HWND SM_FindWindowByContact(HANDLE hContact) SESSION_INFO *pTemp = pci->wndList; while (pTemp != NULL) { - if (pTemp->windowData.hContact == hContact) + if (pTemp->hContact == hContact) return pTemp->hWnd; pTemp = pTemp->next; diff --git a/plugins/Scriver/src/chat/services.cpp b/plugins/Scriver/src/chat/services.cpp deleted file mode 100644 index 9945563c48..0000000000 --- a/plugins/Scriver/src/chat/services.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* -Chat module plugin for Miranda IM - -Copyright (C) 2003 Jörgen Persson -Copyright 2003-2009 Miranda ICQ/IM project, - -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. -*/ - -#include "../commonheaders.h" - -void ShowRoom(SESSION_INFO *si, WPARAM wp, BOOL bSetForeground) -{ - if (!si) - return; - - //Do we need to create a window? - if (si->hWnd == NULL) { - HWND hParent = GetParentWindow(si->windowData.hContact, TRUE); - si->hWnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CHANNEL), hParent, RoomWndProc, (LPARAM)si); - } - SendMessage(si->hWnd, DM_UPDATETABCONTROL, -1, (LPARAM)si); - SendMessage(GetParent(si->hWnd), CM_ACTIVATECHILD, 0, (LPARAM)si->hWnd); - SendMessage(GetParent(si->hWnd), CM_POPUPWINDOW, 0, (LPARAM)si->hWnd); - SendMessage(si->hWnd, WM_MOUSEACTIVATE, 0, 0); - SetFocus(GetDlgItem(si->hWnd, IDC_CHAT_MESSAGE)); -} diff --git a/plugins/Scriver/src/chat/window.cpp b/plugins/Scriver/src/chat/window.cpp index 40ae167644..12047a4ab6 100644 --- a/plugins/Scriver/src/chat/window.cpp +++ b/plugins/Scriver/src/chat/window.cpp @@ -458,7 +458,7 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, break; case WM_CONTEXTMENU: - InputAreaContextMenu(hwnd, wParam, lParam, Parentsi->windowData.hContact); + InputAreaContextMenu(hwnd, wParam, lParam, Parentsi->hContact); return TRUE; case WM_KEYUP: @@ -1055,9 +1055,10 @@ static void __cdecl phase2(void *lParam) PostMessage(si->hWnd, GC_REDRAWLOG3, 0, 0); } -INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HMENU hToolbarMenu; + SESSION_INFO *si = (SESSION_INFO *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); if (!si && uMsg != WM_INITDIALOG) return FALSE; @@ -1067,7 +1068,7 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar TranslateDialogDefault(hwndDlg); { SESSION_INFO *psi = (SESSION_INFO*)lParam; - NotifyLocalWinEvent(psi->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_OPENING); + NotifyLocalWinEvent(psi->hContact, hwndDlg, MSG_WINDOW_EVT_OPENING); TranslateDialogDefault(hwndDlg); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)psi); @@ -1110,7 +1111,7 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar IEVIEWEVENT iee = { sizeof(iee) }; iee.iType = IEE_CLEAR_LOG; iee.hwnd = si->windowData.hwndLog; - iee.hContact = si->windowData.hContact; + iee.hContact = si->hContact; iee.codepage = si->windowData.codePage; iee.pszProto = si->pszModule; CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); @@ -1124,9 +1125,9 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar SendMessage(hwndDlg, DM_UPDATESTATUSBAR, 0, 0); SendMessage(hwndDlg, DM_UPDATETITLEBAR, 0, 0); - SendMessage(GetParent(hwndDlg), CM_ADDCHILD, (WPARAM)hwndDlg, (LPARAM)psi->windowData.hContact); + SendMessage(GetParent(hwndDlg), CM_ADDCHILD, (WPARAM)hwndDlg, (LPARAM)psi->hContact); PostMessage(hwndDlg, GC_UPDATENICKLIST, 0, 0); - NotifyLocalWinEvent(psi->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_OPEN); + NotifyLocalWinEvent(psi->hContact, hwndDlg, MSG_WINDOW_EVT_OPEN); } break; @@ -1229,7 +1230,7 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar StatusIconData sid = { sizeof(sid) }; sid.szModule = SRMMMOD; - Srmm_ModifyIcon(si->windowData.hContact, &sid); + Srmm_ModifyIcon(si->hContact, &sid); } break; @@ -1239,7 +1240,6 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar case DM_SETCODEPAGE: si->windowData.codePage = (int)lParam; - si->pszHeader = Log_CreateRtfHeader(pci->MM_FindModule(si->pszModule), si); SendMessage(hwndDlg, GC_REDRAWLOG2, 0, 0); break; @@ -1355,15 +1355,14 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar case DM_ACTIVATE: if (si->wState & STATE_TALK) { si->wState &= ~STATE_TALK; - - db_set_w(si->windowData.hContact, si->pszModule, "ApparentMode", 0); + db_set_w(si->hContact, si->pszModule, "ApparentMode", 0); } if (si->wState & GC_EVENT_HIGHLIGHT) { si->wState &= ~GC_EVENT_HIGHLIGHT; - if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->windowData.hContact, 0)) - CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->windowData.hContact, (LPARAM)"chaticon"); + if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->hContact, 0)) + CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->hContact, (LPARAM)"chaticon"); } SendMessage(hwndDlg, GC_FIXTABICONS, 0, 0); @@ -1406,26 +1405,19 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); if (dis->CtlID == IDC_CHAT_LIST) { - HFONT hFont, hOldFont; - HICON hIcon; - int offset; - int height; int index = dis->itemID; USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, index); if (ui) { int x_offset = 2; - height = dis->rcItem.bottom - dis->rcItem.top; - + int height = dis->rcItem.bottom - dis->rcItem.top; if (height & 1) height++; - if (height == 10) - offset = 0; - else - offset = height / 2 - 5; - hIcon = pci->SM_GetStatusIcon(si, ui); - hFont = (ui->iStatusEx == 0) ? g_Settings.UserListFont : g_Settings.UserListHeadingsFont; - hOldFont = (HFONT)SelectObject(dis->hDC, hFont); + + int offset = (height == 10) ? 0 : height / 2 - 5; + HICON hIcon = pci->SM_GetStatusIcon(si, ui); + HFONT hFont = (ui->iStatusEx == 0) ? g_Settings.UserListFont : g_Settings.UserListHeadingsFont; + HFONT hOldFont = (HFONT)SelectObject(dis->hDC, hFont); SetBkMode(dis->hDC, TRANSPARENT); if (dis->itemAction == ODA_FOCUS && dis->itemState & ODS_SELECTED) @@ -1497,10 +1489,10 @@ INT_PTR CALLBACK RoomWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar return TRUE; case SESSION_TERMINATE: - if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->windowData.hContact, 0)) - CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->windowData.hContact, (LPARAM)"chaticon"); + if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->hContact, 0)) + CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->hContact, (LPARAM)"chaticon"); si->wState &= ~STATE_TALK; - db_set_w(si->windowData.hContact, si->pszModule, "ApparentMode", (LPARAM)0); + db_set_w(si->hContact, si->pszModule, "ApparentMode", (LPARAM)0); SendMessage(hwndDlg, GC_CLOSEWINDOW, 0, 0); return TRUE; @@ -1634,10 +1626,10 @@ LABEL_SHOWWINDOW: pci->SetActiveSession(si->ptszID, si->pszModule); - if (db_get_w(si->windowData.hContact, si->pszModule, "ApparentMode", 0) != 0) - db_set_w(si->windowData.hContact, si->pszModule, "ApparentMode", (LPARAM)0); - if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->windowData.hContact, 0)) - CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->windowData.hContact, (LPARAM)"chaticon"); + if (db_get_w(si->hContact, si->pszModule, "ApparentMode", 0) != 0) + db_set_w(si->hContact, si->pszModule, "ApparentMode", (LPARAM)0); + if (CallService(MS_CLIST_GETEVENT, (WPARAM)si->hContact, 0)) + CallService(MS_CLIST_REMOVEEVENT, (WPARAM)si->hContact, (LPARAM)"chaticon"); break; case WM_NOTIFY: @@ -1706,7 +1698,7 @@ LABEL_SHOWWINDOW: break; case WM_COMMAND: - if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)si->windowData.hContact)) + if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)si->hContact)) break; switch (LOWORD(wParam)) { @@ -1807,7 +1799,7 @@ LABEL_SHOWWINDOW: smaddInfo.Direction = 0; smaddInfo.xPosition = rc.left; smaddInfo.yPosition = rc.bottom; - smaddInfo.hContact = si->windowData.hContact; + smaddInfo.hContact = si->hContact; CallService(MS_SMILEYADD_SHOWSELECTION, 0, (LPARAM)&smaddInfo); } break; @@ -1816,7 +1808,7 @@ LABEL_SHOWWINDOW: if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHAT_HISTORY))) { MODULEINFO *pInfo = pci->MM_FindModule(si->pszModule); if (pInfo) - ShellExecute(hwndDlg, NULL, GetChatLogsFilename(si->windowData.hContact, 0), NULL, NULL, SW_SHOW); + ShellExecute(hwndDlg, NULL, GetChatLogsFilename(si->hContact, 0), NULL, NULL, SW_SHOW); } break; @@ -1994,7 +1986,7 @@ LABEL_SHOWWINDOW: case DM_GETCONTEXTMENU: { - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)si->windowData.hContact, 0); + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)si->hContact, 0); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)hMenu); } return TRUE; @@ -2002,7 +1994,7 @@ LABEL_SHOWWINDOW: case WM_CONTEXTMENU: if (GetParent(hwndDlg) == (HWND)wParam) { POINT pt; - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)si->windowData.hContact, 0); + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)si->hContact, 0); GetCursorPos(&pt); TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hwndDlg, NULL); DestroyMenu(hMenu); @@ -2018,7 +2010,7 @@ LABEL_SHOWWINDOW: break; case WM_DESTROY: - NotifyLocalWinEvent(si->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_CLOSING); + NotifyLocalWinEvent(si->hContact, hwndDlg, MSG_WINDOW_EVT_CLOSING); si->hWnd = NULL; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); SendDlgItemMessage(hwndDlg, IDC_CHAT_MESSAGE, EM_UNSUBCLASSED, 0, 0); @@ -2032,8 +2024,27 @@ LABEL_SHOWWINDOW: CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); } - NotifyLocalWinEvent(si->windowData.hContact, hwndDlg, MSG_WINDOW_EVT_CLOSE); + NotifyLocalWinEvent(si->hContact, hwndDlg, MSG_WINDOW_EVT_CLOSE); break; } return FALSE; } + +void ShowRoom(SESSION_INFO *si, WPARAM wp, BOOL bSetForeground) +{ + if (si == NULL) + return; + + si->windowData.hContact = si->hContact; + + //Do we need to create a window? + if (si->hWnd == NULL) { + HWND hParent = GetParentWindow(si->hContact, TRUE); + si->hWnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CHANNEL), hParent, RoomWndProc, (LPARAM)si); + } + SendMessage(si->hWnd, DM_UPDATETABCONTROL, -1, (LPARAM)si); + SendMessage(GetParent(si->hWnd), CM_ACTIVATECHILD, 0, (LPARAM)si->hWnd); + SendMessage(GetParent(si->hWnd), CM_POPUPWINDOW, 0, (LPARAM)si->hWnd); + SendMessage(si->hWnd, WM_MOUSEACTIVATE, 0, 0); + SetFocus(GetDlgItem(si->hWnd, IDC_CHAT_MESSAGE)); +} diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp index 51bf39deb2..dc7281a159 100644 --- a/plugins/Scriver/src/msgdialog.cpp +++ b/plugins/Scriver/src/msgdialog.cpp @@ -143,16 +143,16 @@ static void saveDraftMessage(HWND hwnd, HANDLE hContact, int codepage) void NotifyLocalWinEvent(HANDLE hContact, HWND hwnd, unsigned int type) { - MessageWindowEventData mwe = { 0 }; - BOOL bChat = FALSE; - if (hContact==NULL || hwnd==NULL) return; - mwe.cbSize = sizeof(mwe); + if (hContact == NULL || hwnd == NULL) + return; + + MessageWindowEventData mwe = { sizeof(mwe) }; mwe.hContact = hContact; mwe.hwndWindow = hwnd; mwe.szModule = SRMMMOD; mwe.uType = type; mwe.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; - bChat = (WindowList_Find(g_dat.hMessageWindowList, hContact) == NULL); + BOOL bChat = (WindowList_Find(g_dat.hMessageWindowList, hContact) == NULL); mwe.hwndInput = GetDlgItem(hwnd, bChat ? IDC_CHAT_MESSAGE : IDC_MESSAGE); mwe.hwndLog = GetDlgItem(hwnd, bChat ? IDC_CHAT_LOG : IDC_LOG); NotifyEventHooks(hHookWinEvt, 0, (LPARAM)&mwe); diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h index 7e593ec9a4..03bacc17be 100644 --- a/plugins/Scriver/src/msgs.h +++ b/plugins/Scriver/src/msgs.h @@ -27,25 +27,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MSGERROR_RETRY 1 #define MSGERROR_DONE 2 -typedef struct ToolbarButtonStruct +struct ToolbarButton { TCHAR *name; UINT controlId; int alignment; int spacing; int width; -}ToolbarButton; +}; -typedef struct ErrorWindowDataStruct +struct ErrorWindowData { TCHAR* szName; TCHAR* szDescription; TCHAR* szText; MessageSendQueueItem* queueItem; HWND hwndParent; -} ErrorWindowData; +}; -typedef struct TabCtrlDataStruct +struct TabCtrlData { int lastClickTime; WPARAM clickWParam; @@ -56,14 +56,12 @@ typedef struct TabCtrlDataStruct int bDragged; int destTab; int srcTab; -} TabCtrlData; +}; -typedef struct ParentWindowDataStruct +struct ParentWindowData { HWND hwnd; HANDLE hContact; - struct ParentWindowDataStruct *prev; - struct ParentWindowDataStruct *next; int childrenCount; HWND hwndActive; HWND hwndStatus; @@ -80,40 +78,40 @@ typedef struct ParentWindowDataStruct int windowWasCascaded; TabCtrlData *tabCtrlDat; BOOL isChat; -}ParentWindowData; + ParentWindowData *prev, *next; +}; -typedef struct MessageWindowTabDataStruct +struct MessageWindowTabData { - HWND hwnd; - HANDLE hContact; - char *szProto; + HWND hwnd; + HANDLE hContact; + char *szProto; ParentWindowData *parent; HICON hIcon; -}MessageWindowTabData; +}; #define NMWLP_INCOMING 1 -typedef struct NewMessageWindowLParamStruct +struct NewMessageWindowLParam { - HANDLE hContact; - BOOL isChat; - int isWchar; - const char *szInitialText; - int flags; -} NewMessageWindowLParam; + HANDLE hContact; + BOOL isChat; + int isWchar; + LPCSTR szInitialText; + int flags; +}; #define CWDF_RTF_INPUT 1 -typedef struct CommonWindowDataStruct { +struct CommonWindowData +{ HANDLE hContact; - TCmdList *cmdList; - TCmdList *cmdListCurrent; - int codePage; - DWORD flags; - HWND hwndLog; - int minLogBoxHeight; - int minEditBoxHeight; -}CommonWindowData; + int codePage; + DWORD flags; + HWND hwndLog; + int minLogBoxHeight, minEditBoxHeight; + TCmdList *cmdList, *cmdListCurrent; +}; struct SrmmWindowData { diff --git a/plugins/Scriver/src/msgwindow.cpp b/plugins/Scriver/src/msgwindow.cpp index 18706d3c9b..1c691acadd 100644 --- a/plugins/Scriver/src/msgwindow.cpp +++ b/plugins/Scriver/src/msgwindow.cpp @@ -30,20 +30,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TIMEOUT_FLASHWND 900 static void DrawTab(ParentWindowData *dat, HWND hwnd, WPARAM wParam, LPARAM lParam); -LRESULT CALLBACK TabCtrlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -extern TCHAR *GetNickname(HANDLE hContact, const char* szProto); - -void SubclassTabCtrl(HWND hwnd) -{ - mir_subclassWindow(hwnd, TabCtrlProc); - SendMessage(hwnd, EM_SUBCLASSED, 0, 0); -} +///////////////////////////////////////////////////////////////////////////////////////// -void UnsubclassTabCtrl(HWND hwnd) -{ - SendMessage(hwnd, EM_UNSUBCLASSED, 0, 0); -} +extern TCHAR *GetNickname(HANDLE hContact, const char* szProto); static const TCHAR *titleTokenNames[] = {_T("%name%"), _T("%status%"), _T("%statusmsg%"), _T("%account%")}; @@ -441,1065 +431,1080 @@ static void SetContainerWindowStyle(ParentWindowData *dat) SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); } -INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - DWORD ws; - ParentWindowData *dat; - dat = (ParentWindowData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if (!dat && msg!=WM_INITDIALOG) return FALSE; - switch (msg) { - case WM_INITDIALOG: - { - HMENU hMenu; - HANDLE hSContact; - int savePerContact = db_get_b(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT); - NewMessageWindowLParam *newData = (NewMessageWindowLParam *) lParam; - dat = (ParentWindowData *) mir_alloc(sizeof(ParentWindowData)); - dat->hContact = newData->hContact; - dat->nFlash = 0; - dat->nFlashMax = db_get_b(NULL, SRMMMOD, SRMSGSET_FLASHCOUNT, SRMSGDEFSET_FLASHCOUNT); - dat->childrenCount = 0; - dat->hwnd = hwndDlg; - dat->mouseLBDown = 0; - dat->windowWasCascaded = 0; - dat->bMinimized = 0; - dat->bVMaximized = 0; - dat->flags2 = g_dat.flags2; - dat->hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL); - dat->isChat = newData->isChat; - SendMessage(dat->hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0); - //SetupStatusBar(dat); - dat->hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); - dat->hwndActive = NULL; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dat); - if (g_dat.hTabIconList != NULL) - TabCtrl_SetImageList(dat->hwndTabs, g_dat.hTabIconList); - - dat->next = NULL; - if (!newData->isChat) { - dat->prev = g_dat.lastParent; - g_dat.lastParent = dat; - } - else { - dat->prev = g_dat.lastChatParent; - g_dat.lastChatParent = dat; - } - if (dat->prev != NULL) - dat->prev->next = dat; - - WindowList_Add(g_dat.hParentWindowList, hwndDlg, hwndDlg); - SubclassTabCtrl(dat->hwndTabs); +///////////////////////////////////////////////////////////////////////////////////////// - SetContainerWindowStyle(dat); +LRESULT CALLBACK TabCtrlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TabCtrlData *dat = (TabCtrlData*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - hSContact = savePerContact ? dat->hContact : NULL; - dat->bTopmost = db_get_b(hSContact, SRMMMOD, SRMSGSET_TOPMOST, SRMSGDEFSET_TOPMOST); - if (ScriverRestoreWindowPosition(hwndDlg, hSContact, SRMMMOD, (newData->isChat && !savePerContact) ? "chat" : "", 0, SW_HIDE)) - SetWindowPos(hwndDlg, 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE | SWP_HIDEWINDOW); + TCHITTESTINFO thinfo; + int tabId; - if (!savePerContact && db_get_b(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE)) - WindowList_Broadcast(g_dat.hParentWindowList, DM_CASCADENEWWINDOW, (WPARAM) hwndDlg, (LPARAM)&dat->windowWasCascaded); + switch (msg) { + case EM_SUBCLASSED: + dat = (TabCtrlData*)mir_alloc(sizeof(TabCtrlData)); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); + dat->bDragging = FALSE; + dat->bDragged = FALSE; + dat->srcTab = -1; + dat->destTab = -1; + return 0; - hMenu = GetSystemMenu( hwndDlg, FALSE ); - InsertMenu( hMenu, 0, MF_BYPOSITION | MF_SEPARATOR, 0, NULL ); - if (dat->bTopmost) { - InsertMenu( hMenu, 0, MF_BYPOSITION | MF_ENABLED | MF_CHECKED | MF_STRING, IDM_TOPMOST, TranslateT("Always On Top")); - SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + case WM_MBUTTONDOWN: + thinfo.pt.x = LOWORD(lParam); + thinfo.pt.y = HIWORD(lParam); + tabId = TabCtrl_HitTest(hwnd, &thinfo); + if (tabId >= 0) { + TCITEM tci; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(hwnd, tabId, &tci); + MessageWindowTabData *mwtd = (MessageWindowTabData *)tci.lParam; + if (mwtd != NULL) { + SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0); + dat->srcTab = -1; } - else InsertMenu( hMenu, 0, MF_BYPOSITION | MF_ENABLED | MF_UNCHECKED | MF_STRING, IDM_TOPMOST, TranslateT("Always On Top")); } - return TRUE; - - case WM_GETMINMAXINFO: - { - MINMAXINFO *mmi = (MINMAXINFO *)lParam; - if (dat->bVMaximized) { - MONITORINFO mi; - HMONITOR hMonitor; - WINDOWPLACEMENT wp; - RECT rcDesktop; - wp.length = sizeof(wp); - GetWindowPlacement(hwndDlg, &wp); - hMonitor = MonitorFromRect(&wp.rcNormalPosition, MONITOR_DEFAULTTONEAREST); - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); - rcDesktop = mi.rcWork; + return 0; - mmi->ptMaxSize.x = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - mmi->ptMaxSize.y = rcDesktop.bottom - rcDesktop.top; - mmi->ptMaxPosition.x = wp.rcNormalPosition.left; - if (IsIconic(hwndDlg)) - mmi->ptMaxPosition.y = rcDesktop.top; - else - mmi->ptMaxPosition.y = 0; - } - SIZE size; - GetMinimunWindowSize(dat, &size); - mmi->ptMinTrackSize.x = size.cx; - mmi->ptMinTrackSize.y = size.cy; + case WM_LBUTTONDBLCLK: + thinfo.pt.x = LOWORD(lParam); + thinfo.pt.y = HIWORD(lParam); + tabId = TabCtrl_HitTest(hwnd, &thinfo); + if (tabId >= 0 && tabId == dat->srcTab) { + SendMessage(GetChildFromTab(hwnd, tabId)->hwnd, WM_CLOSE, 0, 0); + dat->srcTab = -1; } - return FALSE; + dat->destTab = -1; + break; - case WM_SIZE: - if (wParam == SIZE_MINIMIZED) - dat->bMinimized = 1; + case WM_LBUTTONDOWN: + if (!dat->bDragging) { + thinfo.pt.x = LOWORD(lParam); + thinfo.pt.y = HIWORD(lParam); + dat->srcTab = TabCtrl_HitTest(hwnd, &thinfo); - if ( IsIconic(hwndDlg)) - MoveWindow(dat->hwndActive, dat->childRect.left, dat->childRect.top, dat->childRect.right-dat->childRect.left, dat->childRect.bottom - dat->childRect.top, TRUE); - else { - RECT rc, rcStatus, rcChild, rcWindow; - SIZE size; - dat->bMinimized = 0; - GetClientRect(hwndDlg, &rc); - GetWindowRect(hwndDlg, &rcWindow); - rcStatus.top = rcStatus.bottom = 0; - if (dat->flags2 & SMF2_SHOWSTATUSBAR) { - GetWindowRect(dat->hwndStatus, &rcStatus); - SetupStatusBar(dat); - } - MoveWindow(dat->hwndTabs, 0, 2, (rc.right - rc.left), (rc.bottom - rc.top) - (rcStatus.bottom - rcStatus.top) - 2, FALSE); - RedrawWindow(dat->hwndTabs, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); - GetMinimunWindowSize(dat, &size); - if ((rcWindow.bottom-rcWindow.top) < size.cy || (rcWindow.right-rcWindow.left) < size.cx) { - if ((rcWindow.bottom-rcWindow.top) < size.cy) - rcWindow.bottom = rcWindow.top + size.cy; - if ((rcWindow.right-rcWindow.left) < size.cx) - rcWindow.right = rcWindow.left + size.cx; - MoveWindow(hwndDlg, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE); - } - GetChildWindowRect(dat, &rcChild); - memcpy(&dat->childRect, &rcChild, sizeof(RECT)); - MoveWindow(dat->hwndActive, rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, TRUE); - RedrawWindow(GetDlgItem(dat->hwndActive, IDC_LOG), NULL, NULL, RDW_INVALIDATE); - if (dat->flags2 & SMF2_SHOWSTATUSBAR) { - SendMessage(dat->hwndStatus, WM_SIZE, 0, 0); - RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + if (dat->srcTab >= 0) { + dat->bDragging = TRUE; + dat->bDragged = FALSE; + dat->clickLParam = lParam; + dat->clickWParam = wParam; + dat->lastClickTime = ft.dwLowDateTime; + dat->mouseLBDownPos.x = thinfo.pt.x; + dat->mouseLBDownPos.y = thinfo.pt.y; + SetCapture(hwnd); } + return 0; } - return FALSE; + break; - case WM_SETFOCUS: - if (dat->hwndActive != NULL) - SetFocus(dat->hwndActive); - return TRUE; + case WM_CAPTURECHANGED: + case WM_LBUTTONUP: + if (dat->bDragging) { + thinfo.pt.x = LOWORD(lParam); + thinfo.pt.y = HIWORD(lParam); + if (dat->bDragged) { + ImageList_DragLeave(GetDesktopWindow()); + ImageList_EndDrag(); + ImageList_Destroy(dat->hDragImageList); + SetCursor(LoadCursor(NULL, IDC_ARROW)); + dat->destTab = TabCtrl_HitTest(hwnd, &thinfo); + if (thinfo.flags != TCHT_NOWHERE && dat->destTab != dat->srcTab) { + NMHDR nmh; + TCHAR sBuffer[501]; + TCITEM item; + int curSel; + curSel = TabCtrl_GetCurSel(hwnd); + item.mask = TCIF_IMAGE | TCIF_PARAM | TCIF_TEXT; + item.pszText = sBuffer; + item.cchTextMax = SIZEOF(sBuffer); + TabCtrl_GetItem(hwnd, dat->srcTab, &item); + sBuffer[SIZEOF(sBuffer) - 1] = '\0'; - case WM_CLOSE: - if (g_dat.flags2 & SMF2_HIDECONTAINERS && dat->childrenCount > 0) - ShowWindow(hwndDlg, SW_HIDE); - else - DestroyWindow(hwndDlg); - return TRUE; + if (curSel == dat->srcTab) + curSel = dat->destTab; + else if (curSel > dat->srcTab && curSel <= dat->destTab) + curSel--; + else if (curSel < dat->srcTab && curSel >= dat->destTab) + curSel++; - case WM_MEASUREITEM: - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + TabCtrl_DeleteItem(hwnd, dat->srcTab); + TabCtrl_InsertItem(hwnd, dat->destTab, &item); + TabCtrl_SetCurSel(hwnd, curSel); + dat->destTab = -1; + nmh.hwndFrom = hwnd; + nmh.idFrom = GetDlgCtrlID(hwnd); + nmh.code = TCN_SELCHANGE; + SendMessage(GetParent(hwnd), WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh); + UpdateWindow(hwnd); + } + else if (thinfo.flags == TCHT_NOWHERE) { + TCITEM tci; + POINT pt; + NewMessageWindowLParam newData = { 0 }; + dat->destTab = -1; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(hwnd, dat->srcTab, &tci); + MessageWindowTabData *mwtd = (MessageWindowTabData *)tci.lParam; + if (mwtd != NULL) { + HWND hChild = mwtd->hwnd; + HANDLE hContact = mwtd->hContact; + GetCursorPos(&pt); + HWND hParent = WindowFromPoint(pt); + while (GetParent(hParent) != NULL) + hParent = GetParent(hParent); - case WM_DRAWITEM: - { - LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam; - if (dat && dat->hwndActive && dis->hwndItem == dat->hwndStatus) { - MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive); - if (mwtd != NULL) - DrawStatusIcons(mwtd->hContact, dis->hDC, dis->rcItem, 2); - return TRUE; - } - if (dis->hwndItem == dat->hwndTabs) { - DrawTab(dat, dat->hwndTabs, wParam, lParam); - return TRUE; - } - } - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - - case WM_COMMAND: - if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact)) - break; - - if (LOWORD(wParam) == IDCANCEL) - return TRUE; - break; - - case WM_NOTIFY: - { - NMHDR* pNMHDR = (NMHDR*) lParam; - if (pNMHDR->hwndFrom == dat->hwndTabs) { - switch (pNMHDR->code) { - case TCN_SELCHANGE: - { - TCITEM tci = {0}; - int iSel = TabCtrl_GetCurSel(dat->hwndTabs); - tci.mask = TCIF_PARAM; - if (TabCtrl_GetItem(dat->hwndTabs, iSel, &tci)) { - MessageWindowTabData * mwtd = (MessageWindowTabData *) tci.lParam; - ActivateChild(dat, mwtd->hwnd); - SetFocus(dat->hwndActive); - } - } - break; - case NM_RCLICK: - { - TCHITTESTINFO thinfo; - GetCursorPos(&thinfo.pt); - - int x = thinfo.pt.x; - int y = thinfo.pt.y; - ScreenToClient(dat->hwndTabs, &thinfo.pt); - int tabId = TabCtrl_HitTest(dat->hwndTabs, &thinfo); - if (tabId != -1) { - HMENU hMenu, hSubMenu, hUserMenu; - BOOL menuResult; - MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, tabId); - hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - hSubMenu = GetSubMenu(hMenu, 3); - TranslateMenu(hSubMenu); - hUserMenu = (HMENU) SendMessage(mwtd->hwnd, DM_GETCONTEXTMENU, 0, 0); - if (hUserMenu != NULL) { - InsertMenu(hSubMenu, 0, MF_POPUP | MF_BYPOSITION, (UINT_PTR)hUserMenu, TranslateT("User Menu")); - InsertMenu(hSubMenu, 1, MF_SEPARATOR | MF_BYPOSITION, 0, 0); - } - menuResult = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, x, y, 0, hwndDlg, NULL); - switch (menuResult) { - case IDM_CLOSETAB: - SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0); - break; - case IDM_CLOSEOTHERTABS: - CloseOtherChilden(dat, mwtd->hwnd); - break; - default: - CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(menuResult), MPCF_CONTACTMENU), (LPARAM)mwtd->hContact); + hParent = WindowList_Find(g_dat.hParentWindowList, hParent); + if ((hParent != NULL && hParent != GetParent(hwnd)) || (hParent == NULL && mwtd->parent->childrenCount > 1 && (GetKeyState(VK_CONTROL) & 0x8000))) { + if (hParent == NULL) { + RECT rc, rcDesktop; + newData.hContact = hContact; + hParent = (HWND)CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGWIN), NULL, DlgProcParentWindow, (LPARAM)& newData); + GetWindowRect(hParent, &rc); + rc.right = (rc.right - rc.left); + rc.bottom = (rc.bottom - rc.top); + rc.left = pt.x - rc.right / 2; + rc.top = pt.y - rc.bottom / 2; + HMONITOR hMonitor = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST); + MONITORINFO mi; + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + rcDesktop = mi.rcWork; + if (rc.left < rcDesktop.left) + rc.left = rcDesktop.left; + if (rc.top < rcDesktop.top) + rc.top = rcDesktop.top; + MoveWindow(hParent, rc.left, rc.top, rc.right, rc.bottom, FALSE); } - if (hUserMenu != NULL) - DestroyMenu(hUserMenu); - DestroyMenu(hMenu); + NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_CLOSING); + NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_CLOSE); + SetParent(hChild, hParent); + SendMessage(GetParent(hwnd), CM_REMOVECHILD, 0, (LPARAM)hChild); + SendMessage(hChild, DM_SETPARENT, 0, (LPARAM)hParent); + SendMessage(hParent, CM_ADDCHILD, (WPARAM)hChild, (LPARAM)hContact); + SendMessage(hChild, DM_UPDATETABCONTROL, 0, 0); + SendMessage(hParent, CM_ACTIVATECHILD, 0, (LPARAM)hChild); + NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_OPENING); + NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_OPEN); + ShowWindow(hParent, SW_SHOWNA); + EnableWindow(hParent, TRUE); } } - break; + } + else { + dat->destTab = -1; + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } } - else if (pNMHDR->hwndFrom == dat->hwndStatus) { - switch (pNMHDR->code) { - case NM_CLICK: - NMMOUSE *nm = (NMMOUSE*)lParam; - RECT rc; - SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 2, (LPARAM)&rc); - if (nm->pt.x >= rc.left) { - MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive); - if (mwtd != NULL) { - CheckStatusIconClick(mwtd->hContact, dat->hwndStatus, nm->pt, rc, 2, (pNMHDR->code == NM_RCLICK ? MBCF_RIGHTBUTTON : 0)); - } + else if (dat->srcTab >= 0 && g_dat.flags2 & SMF2_TABCLOSEBUTTON) { + IMAGEINFO info; + POINT pt; + RECT rect; + int atTop = (GetWindowLongPtr(hwnd, GWL_STYLE) & TCS_BOTTOM) == 0; + TabCtrl_GetItemRect(hwnd, dat->srcTab, &rect); + pt.x = LOWORD(lParam); + pt.y = HIWORD(lParam); + ImageList_GetImageInfo(g_dat.hButtonIconList, 0, &info); + rect.left = rect.right - (info.rcImage.right - info.rcImage.left) - 6; + if (!atTop) + rect.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top); + + if (pt.x >= rect.left && pt.x < rect.left + (info.rcImage.right - info.rcImage.left) && pt.y >= rect.top && pt.y < rect.top + (info.rcImage.bottom - info.rcImage.top)) { + HBITMAP hOldBitmap, hBmp; + HDC hdc = GetDC(NULL); + HDC hdcMem = CreateCompatibleDC(hdc); + pt.x -= rect.left; + pt.y -= rect.top; + hBmp = CreateCompatibleBitmap(hdc, info.rcImage.right - info.rcImage.left + 1, info.rcImage.bottom - info.rcImage.top + 1); + hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBmp); + SetPixel(hdcMem, pt.x, pt.y, 0x000000); + ImageList_DrawEx(g_dat.hButtonIconList, 0, hdcMem, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); + COLORREF color1 = GetPixel(hdcMem, pt.x, pt.y); + SetPixel(hdcMem, pt.x, pt.y, 0xFFFFFF); + ImageList_DrawEx(g_dat.hButtonIconList, 0, hdcMem, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); + COLORREF color2 = GetPixel(hdcMem, pt.x, pt.y); + SelectObject(hdcMem, hOldBitmap); + DeleteDC(hdcMem); + DeleteObject(hBmp); + ReleaseDC(NULL, hdc); + if (color1 != 0x000000 || color2 != 0xFFFFFF) { + SendMessage(GetChildFromTab(hwnd, dat->srcTab)->hwnd, WM_CLOSE, 0, 0); + dat->srcTab = -1; } - return TRUE; } + else SendMessage(hwnd, WM_LBUTTONDOWN, dat->clickWParam, dat->clickLParam); } - } - break; - - case WM_DROPFILES: - SendMessage(dat->hwndActive, WM_DROPFILES, wParam, lParam); - break; + else SendMessage(hwnd, WM_LBUTTONDOWN, dat->clickWParam, dat->clickLParam); - case WM_TIMER: - if (wParam == TIMERID_FLASHWND) { - if (dat->nFlash < 2 * dat->nFlashMax) { - FlashWindow(hwndDlg, TRUE); - dat->nFlash++; - } - else { - KillTimer(hwndDlg, TIMERID_FLASHWND); - FlashWindow(hwndDlg, FALSE); - } + dat->bDragged = FALSE; + dat->bDragging = FALSE; + dat->destTab = -1; + ReleaseCapture(); } break; - case WM_CONTEXTMENU: - if (dat->hwndStatus && dat->hwndStatus == (HWND)wParam) { - RECT rc; - POINT pt, pt2; - GetCursorPos(&pt); - pt2 = pt; - ScreenToClient(dat->hwndStatus, &pt); + case WM_MOUSEMOVE: + if (wParam & MK_LBUTTON) { + if (dat->bDragging) { + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + thinfo.pt.x = LOWORD(lParam); + thinfo.pt.y = HIWORD(lParam); + if (!dat->bDragged) { + if ((abs(thinfo.pt.x - dat->mouseLBDownPos.x) < 3 && abs(thinfo.pt.y - dat->mouseLBDownPos.y) < 3) + || (ft.dwLowDateTime - dat->lastClickTime) < 10 * 1000 * 150) + break; + } + if (!dat->bDragged) { + POINT pt; + RECT rect; + RECT rect2; + HBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 254)); + GetCursorPos(&pt); + TabCtrl_GetItemRect(hwnd, dat->srcTab, &rect); + rect.right -= rect.left - 1; + rect.bottom -= rect.top - 1; + rect2.left = 0; rect2.right = rect.right; rect2.top = 0; rect2.bottom = rect.bottom; + dat->hDragImageList = ImageList_Create(rect.right, rect.bottom, ILC_COLOR | ILC_MASK, 0, 1); + HDC hDC = GetDC(hwnd); + HDC hMemDC = CreateCompatibleDC(hDC); + HBITMAP hBitmap = CreateCompatibleBitmap(hDC, rect.right, rect.bottom); + HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); + FillRect(hMemDC, &rect2, hBrush); + SetWindowOrgEx(hMemDC, rect.left, rect.top, NULL); + SendMessage(hwnd, WM_PRINTCLIENT, (WPARAM)hMemDC, PRF_CLIENT); + SelectObject(hMemDC, hOldBitmap); + ImageList_AddMasked(dat->hDragImageList, hBitmap, RGB(255, 0, 254)); + DeleteObject(hBitmap); + DeleteObject(hBrush); + ReleaseDC(hwnd, hDC); + DeleteDC(hMemDC); + ImageList_BeginDrag(dat->hDragImageList, 0, dat->mouseLBDownPos.x - rect.left, dat->mouseLBDownPos.y - rect.top); + ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y); + SetCursor(hDragCursor); + dat->mouseLBDownPos.x = thinfo.pt.x; + dat->mouseLBDownPos.y = thinfo.pt.y; + } + else { + POINT pt; + GetCursorPos(&pt); + thinfo.pt = pt; + ScreenToClient(hwnd, &thinfo.pt); + int newDest = TabCtrl_HitTest(hwnd, &thinfo); + if (thinfo.flags == TCHT_NOWHERE) + newDest = -1; - SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 2, (LPARAM)&rc); - if (pt.x >= rc.left) { - MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive); - if (mwtd != NULL) - CheckStatusIconClick(mwtd->hContact, dat->hwndStatus, pt, rc, 2, MBCF_RIGHTBUTTON); - break; + if (newDest != dat->destTab) { + dat->destTab = newDest; + ImageList_DragLeave(GetDesktopWindow()); + RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); + ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y); + } + else ImageList_DragMove(pt.x, pt.y); + } + dat->bDragged = TRUE; + return 0; } - else SendMessage(dat->hwndActive, WM_CONTEXTMENU, (WPARAM)hwndDlg, 0); } break; - case WM_ACTIVATE: - if (LOWORD(wParam) == WA_INACTIVE) { - ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; - ws |= dat->flags2 & SMF2_USETRANSPARENCY ? WS_EX_LAYERED : 0; - SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, ws); - if (dat->flags2 & SMF2_USETRANSPARENCY) - SetLayeredWindowAttributes(hwndDlg, RGB(255, 255, 255), (BYTE)(255 - g_dat.inactiveAlpha), LWA_ALPHA); - break; - } - if (dat->hwndActive != NULL) { - ActivateChild(dat, dat->hwndActive); - g_dat.hFocusWnd = dat->hwndActive; - PostMessage(dat->hwndActive, DM_SETFOCUS, 0, msg); - } - if (KillTimer(hwndDlg, TIMERID_FLASHWND)) { - FlashWindow(hwndDlg, FALSE); - dat->nFlash = 0; - } - ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; - ws |= dat->flags2 & SMF2_USETRANSPARENCY ? WS_EX_LAYERED : 0; - SetWindowLongPtr(hwndDlg , GWL_EXSTYLE , ws); - if (dat->flags2 & SMF2_USETRANSPARENCY) - SetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat.activeAlpha), LWA_ALPHA); - break; + case EM_UNSUBCLASSED: + mir_free(dat); + return 0; + } + return mir_callNextSubclass(hwnd, TabCtrlProc, msg, wParam, lParam); +} - case WM_LBUTTONDOWN: - if (!IsZoomed(hwndDlg)) { - POINT pt; - GetCursorPos(&pt); - return SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); - } - break; +__forceinline void SubclassTabCtrl(HWND hwnd) +{ + mir_subclassWindow(hwnd, TabCtrlProc); + SendMessage(hwnd, EM_SUBCLASSED, 0, 0); +} - case WM_MOVING: - if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) { - int snapPixels = 10; - RECT rcDesktop; - RECT *pRect = (RECT *)lParam; - POINT pt; - MONITORINFO mi; - HMONITOR hMonitor = MonitorFromRect(pRect, MONITOR_DEFAULTTONEAREST); - SIZE szSize = {pRect->right-pRect->left,pRect->bottom-pRect->top}; - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); - GetCursorPos(&pt); +__forceinline void UnsubclassTabCtrl(HWND hwnd) +{ + SendMessage(hwnd, EM_UNSUBCLASSED, 0, 0); +} - rcDesktop = mi.rcWork; - pRect->left = pt.x-dat->mouseLBDownPos.x; - pRect->top = pt.y-dat->mouseLBDownPos.y; - pRect->right = pRect->left+szSize.cx; - pRect->bottom = pRect->top+szSize.cy; - if (pRect->top < rcDesktop.top+snapPixels && pRect->top > rcDesktop.top-snapPixels) { - pRect->top = rcDesktop.top; - pRect->bottom = rcDesktop.top + szSize.cy; - } - if (pRect->left < rcDesktop.left+snapPixels && pRect->left > rcDesktop.left-snapPixels) { - pRect->left = rcDesktop.left; - pRect->right = rcDesktop.left + szSize.cx; - } - if (pRect->right < rcDesktop.right+snapPixels && pRect->right > rcDesktop.right-snapPixels) { - pRect->right = rcDesktop.right; - pRect->left = rcDesktop.right - szSize.cx; - } - if (pRect->bottom < rcDesktop.bottom+snapPixels && pRect->bottom > rcDesktop.bottom-snapPixels) { - pRect->bottom = rcDesktop.bottom; - pRect->top = rcDesktop.bottom - szSize.cy; - } - } - break; +///////////////////////////////////////////////////////////////////////////////////////// - case WM_SYSCOMMAND: - if ((wParam & 0xFFF0) == SC_MAXIMIZE) { - if (GetKeyState(VK_CONTROL) & 0x8000) - dat->bVMaximized = 1; - else - dat->bVMaximized = 0; - } - else if ((wParam & 0xFFF0) == SC_MOVE) { - RECT rc; - GetWindowRect(hwndDlg, &rc); - dat->mouseLBDownPos.x = LOWORD(lParam) - rc.left; - dat->mouseLBDownPos.y = HIWORD(lParam) - rc.top; - } - else if (wParam == IDM_TOPMOST) { - HMENU hMenu = GetSystemMenu(hwndDlg, FALSE); - if (dat->bTopmost) { - CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_UNCHECKED); - SetWindowPos(hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - dat->bTopmost = FALSE; - } - else { - CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_CHECKED); - SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - dat->bTopmost = TRUE; - } - } - break; - case WM_DESTROY: +INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + DWORD ws; + ParentWindowData *dat; + dat = (ParentWindowData *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (!dat && msg!=WM_INITDIALOG) return FALSE; + switch (msg) { + case WM_INITDIALOG: { - char szSettingName[64]; - for (int i = dat->childrenCount; i >= 0; i--) { - TCITEM tci; - tci.mask = TCIF_PARAM | TCIF_IMAGE; - if (TabCtrl_GetItem(dat->hwndTabs, i, &tci)) { - mir_free((MessageWindowTabData *)tci.lParam); - ReleaseIcon(tci.iImage); - TabCtrl_DeleteItem(dat->hwndTabs, i); - } - } - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); - WindowList_Remove(g_dat.hParentWindowList, hwndDlg); - + HMENU hMenu; + HANDLE hSContact; int savePerContact = db_get_b(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT); - HANDLE hContact = (savePerContact) ? dat->hContact : NULL; - - WINDOWPLACEMENT wp = { sizeof(wp) }; - GetWindowPlacement(hwndDlg, &wp); + NewMessageWindowLParam *newData = (NewMessageWindowLParam *) lParam; + dat = (ParentWindowData *) mir_alloc(sizeof(ParentWindowData)); + dat->hContact = newData->hContact; + dat->nFlash = 0; + dat->nFlashMax = db_get_b(NULL, SRMMMOD, SRMSGSET_FLASHCOUNT, SRMSGDEFSET_FLASHCOUNT); + dat->childrenCount = 0; + dat->hwnd = hwndDlg; + dat->mouseLBDown = 0; + dat->windowWasCascaded = 0; + dat->bMinimized = 0; + dat->bVMaximized = 0; + dat->flags2 = g_dat.flags2; + dat->hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL); + dat->isChat = newData->isChat; + SendMessage(dat->hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0); + //SetupStatusBar(dat); + dat->hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); + dat->hwndActive = NULL; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dat); + if (g_dat.hTabIconList != NULL) + TabCtrl_SetImageList(dat->hwndTabs, g_dat.hTabIconList); - char *szNamePrefix = (!savePerContact && dat->isChat) ? "chat" : ""; - if (!dat->windowWasCascaded) { - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sx", szNamePrefix); - db_set_dw(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.left); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sy", szNamePrefix); - db_set_dw(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.top); + dat->next = NULL; + if (!newData->isChat) { + dat->prev = g_dat.lastParent; + g_dat.lastParent = dat; + } + else { + dat->prev = g_dat.lastChatParent; + g_dat.lastChatParent = dat; } - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%swidth", szNamePrefix); - db_set_dw(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.right - wp.rcNormalPosition.left); - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sheight", szNamePrefix); - db_set_dw(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); - db_set_b(hContact, SRMMMOD, SRMSGSET_TOPMOST, (BYTE)dat->bTopmost); - if (g_dat.lastParent == dat) - g_dat.lastParent = dat->prev; - - if (g_dat.lastChatParent == dat) - g_dat.lastChatParent = dat->prev; - if (dat->prev != NULL) - dat->prev->next = dat->next; - - if (dat->next != NULL) - dat->next->prev = dat->prev; + dat->prev->next = dat; - UnsubclassTabCtrl(dat->hwndTabs); - mir_free(dat); - } - break; + WindowList_Add(g_dat.hParentWindowList, hwndDlg, hwndDlg); + SubclassTabCtrl(dat->hwndTabs); - case DM_ERRORDECIDED: - break; + SetContainerWindowStyle(dat); - case CM_STARTFLASHING: - if ((GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg)) {// && !(g_dat.flags2 & SMF2_STAYMINIMIZED)) { - dat->nFlash = 0; - SetTimer(hwndDlg, TIMERID_FLASHWND, TIMEOUT_FLASHWND, NULL); - } - break; + hSContact = savePerContact ? dat->hContact : NULL; + dat->bTopmost = db_get_b(hSContact, SRMMMOD, SRMSGSET_TOPMOST, SRMSGDEFSET_TOPMOST); + if (ScriverRestoreWindowPosition(hwndDlg, hSContact, SRMMMOD, (newData->isChat && !savePerContact) ? "chat" : "", 0, SW_HIDE)) + SetWindowPos(hwndDlg, 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE | SWP_HIDEWINDOW); - case CM_POPUPWINDOW: - EnableWindow(hwndDlg, TRUE); - if (wParam) { /* incoming message */ - if (g_dat.flags & SMF_STAYMINIMIZED) { - if (!IsWindowVisible(hwndDlg)) - ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE); + if (!savePerContact && db_get_b(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE)) + WindowList_Broadcast(g_dat.hParentWindowList, DM_CASCADENEWWINDOW, (WPARAM) hwndDlg, (LPARAM)&dat->windowWasCascaded); - if (dat->childrenCount == 1 || ((g_dat.flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(hwndDlg) || GetForegroundWindow() != hwndDlg))) - SendMessage(hwndDlg, CM_ACTIVATECHILD, 0, (LPARAM)lParam); + hMenu = GetSystemMenu( hwndDlg, FALSE ); + InsertMenu( hMenu, 0, MF_BYPOSITION | MF_SEPARATOR, 0, NULL ); + if (dat->bTopmost) { + InsertMenu( hMenu, 0, MF_BYPOSITION | MF_ENABLED | MF_CHECKED | MF_STRING, IDM_TOPMOST, TranslateT("Always On Top")); + SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } - else { - ShowWindow(hwndDlg, IsIconic(hwndDlg) ? SW_SHOWNORMAL : SW_SHOWNA); + else InsertMenu( hMenu, 0, MF_BYPOSITION | MF_ENABLED | MF_UNCHECKED | MF_STRING, IDM_TOPMOST, TranslateT("Always On Top")); + } + return TRUE; - if (dat->childrenCount == 1 || ((g_dat.flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(hwndDlg) || GetForegroundWindow() != hwndDlg))) - SendMessage(hwndDlg, CM_ACTIVATECHILD, 0, (LPARAM)lParam); + case WM_GETMINMAXINFO: + { + MINMAXINFO *mmi = (MINMAXINFO *)lParam; + if (dat->bVMaximized) { + MONITORINFO mi; + HMONITOR hMonitor; + WINDOWPLACEMENT wp; + RECT rcDesktop; + wp.length = sizeof(wp); + GetWindowPlacement(hwndDlg, &wp); + hMonitor = MonitorFromRect(&wp.rcNormalPosition, MONITOR_DEFAULTTONEAREST); + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + rcDesktop = mi.rcWork; - SetWindowPos(hwndDlg, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + mmi->ptMaxSize.x = wp.rcNormalPosition.right - wp.rcNormalPosition.left; + mmi->ptMaxSize.y = rcDesktop.bottom - rcDesktop.top; + mmi->ptMaxPosition.x = wp.rcNormalPosition.left; + if (IsIconic(hwndDlg)) + mmi->ptMaxPosition.y = rcDesktop.top; + else + mmi->ptMaxPosition.y = 0; } + SIZE size; + GetMinimunWindowSize(dat, &size); + mmi->ptMinTrackSize.x = size.cx; + mmi->ptMinTrackSize.y = size.cy; } - else { /* outgoing message */ - ShowWindow(hwndDlg, IsIconic(hwndDlg) ? SW_SHOWNORMAL : SW_SHOW); - SetForegroundWindow(hwndDlg); - SetFocus((HWND)lParam); - } - break; + return FALSE; - case CM_REMOVECHILD: - RemoveChild(dat, (HWND)lParam); - if (dat->childrenCount != 0) - SetFocus(dat->hwndActive); - else - PostMessage(hwndDlg, WM_CLOSE, 0, 0); - return TRUE; - - case CM_ADDCHILD: - AddChild(dat, (HWND)wParam, (HANDLE)lParam); - return TRUE; - - case CM_ACTIVATECHILD: - ActivateChild(dat, (HWND)lParam); - return TRUE; - - case CM_ACTIVATEPREV: - ActivatePrevChild(dat, (HWND)lParam); - SetFocus(dat->hwndActive); - return TRUE; - - case CM_ACTIVATENEXT: - ActivateNextChild(dat, (HWND)lParam); - SetFocus(dat->hwndActive); - return TRUE; - - case CM_ACTIVATEBYINDEX: - ActivateChildByIndex(dat, (int)lParam); - SetFocus(dat->hwndActive); - return TRUE; + case WM_SIZE: + if (wParam == SIZE_MINIMIZED) + dat->bMinimized = 1; - case CM_GETCHILDCOUNT: - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetChildCount(dat)); - return TRUE; + if ( IsIconic(hwndDlg)) + MoveWindow(dat->hwndActive, dat->childRect.left, dat->childRect.top, dat->childRect.right-dat->childRect.left, dat->childRect.bottom - dat->childRect.top, TRUE); + else { + RECT rc, rcStatus, rcChild, rcWindow; + SIZE size; + dat->bMinimized = 0; + GetClientRect(hwndDlg, &rc); + GetWindowRect(hwndDlg, &rcWindow); + rcStatus.top = rcStatus.bottom = 0; + if (dat->flags2 & SMF2_SHOWSTATUSBAR) { + GetWindowRect(dat->hwndStatus, &rcStatus); + SetupStatusBar(dat); + } + MoveWindow(dat->hwndTabs, 0, 2, (rc.right - rc.left), (rc.bottom - rc.top) - (rcStatus.bottom - rcStatus.top) - 2, FALSE); + RedrawWindow(dat->hwndTabs, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); + GetMinimunWindowSize(dat, &size); + if ((rcWindow.bottom-rcWindow.top) < size.cy || (rcWindow.right-rcWindow.left) < size.cx) { + if ((rcWindow.bottom-rcWindow.top) < size.cy) + rcWindow.bottom = rcWindow.top + size.cy; + if ((rcWindow.right-rcWindow.left) < size.cx) + rcWindow.right = rcWindow.left + size.cx; + MoveWindow(hwndDlg, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE); + } + GetChildWindowRect(dat, &rcChild); + memcpy(&dat->childRect, &rcChild, sizeof(RECT)); + MoveWindow(dat->hwndActive, rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, TRUE); + RedrawWindow(GetDlgItem(dat->hwndActive, IDC_LOG), NULL, NULL, RDW_INVALIDATE); + if (dat->flags2 & SMF2_SHOWSTATUSBAR) { + SendMessage(dat->hwndStatus, WM_SIZE, 0, 0); + RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); + } + } + return FALSE; - case CM_GETACTIVECHILD: - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)dat->hwndActive); + case WM_SETFOCUS: + if (dat->hwndActive != NULL) + SetFocus(dat->hwndActive); return TRUE; - case CM_GETTOOLBARSTATUS: - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)(dat->flags2 & SMF2_SHOWTOOLBAR) != 0); + case WM_CLOSE: + if (g_dat.flags2 & SMF2_HIDECONTAINERS && dat->childrenCount > 0) + ShowWindow(hwndDlg, SW_HIDE); + else + DestroyWindow(hwndDlg); return TRUE; - case DM_SENDMESSAGE: - for (int i = 0; i < dat->childrenCount; i++) { - MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i); - SendMessage(mwtd->hwnd, DM_SENDMESSAGE, wParam, lParam); - } - break; - - case DM_OPTIONSAPPLIED: - dat->flags2 = g_dat.flags2; - SetContainerWindowStyle(dat); - SendMessage(hwndDlg, WM_SIZE, 0, 0); - break; + case WM_MEASUREITEM: + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - case CM_UPDATETITLEBAR: + case WM_DRAWITEM: { - HWND hwnd = (HWND)lParam; - TitleBarData *tbd = (TitleBarData *)wParam; - if (tbd != NULL && dat->hwndActive == hwnd) { - if (tbd->iFlags & TBDF_TEXT) { - TCHAR oldtitle[256]; - GetWindowText(hwndDlg, oldtitle, SIZEOF(oldtitle)); - if (lstrcmp(tbd->pszText, oldtitle)) - SetWindowText(hwndDlg, tbd->pszText); - } - if (tbd->iFlags & TBDF_ICON) { - SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)tbd->hIcon); - if (tbd->hIconBig != NULL) - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)tbd->hIconBig); - if (pTaskbarInterface) - pTaskbarInterface->SetOverlayIcon(hwndDlg, tbd->hIconNot, L""); - } + LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam; + if (dat && dat->hwndActive && dis->hwndItem == dat->hwndStatus) { + MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive); + if (mwtd != NULL) + DrawStatusIcons(mwtd->hContact, dis->hDC, dis->rcItem, 2); + return TRUE; } - } - break; - - case CM_UPDATESTATUSBAR: - { - HWND hwnd = (HWND)lParam; - StatusBarData *sbd = (StatusBarData *)wParam; - if (sbd != NULL) { - if ((sbd->iFlags & SBDF_TEXT) && dat->hwndActive == hwnd) - SendMessage(dat->hwndStatus, SB_SETTEXT, sbd->iItem, (LPARAM)sbd->pszText); - if ((sbd->iFlags & SBDF_ICON) && dat->hwndActive == hwnd) - SendMessage(dat->hwndStatus, SB_SETICON, sbd->iItem, (LPARAM)sbd->hIcon); - RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); + if (dis->hwndItem == dat->hwndTabs) { + DrawTab(dat, dat->hwndTabs, wParam, lParam); + return TRUE; } } - break; + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - case DM_STATUSICONCHANGE: - SendMessage(dat->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_OWNERDRAW) | 2, 0); - SetupStatusBar(dat); - RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); + case WM_COMMAND: + if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact)) + break; + + if (LOWORD(wParam) == IDCANCEL) + return TRUE; break; - case CM_UPDATETABCONTROL: + case WM_NOTIFY: { - TCHAR *ptszTemp = NULL; - TabControlData *tcd = (TabControlData *) wParam; - int tabId = GetTabFromHWND(dat, (HWND) lParam); - if (tabId >= 0 && tcd != NULL) { - TCITEM tci; - tci.mask = 0; - if (tcd->iFlags & TCDF_TEXT) { - tci.mask |= TCIF_TEXT; - tci.pszText = tcd->pszText; - if (g_dat.flags2 & SMF2_LIMITNAMES) { - TCHAR * ltext = limitText(tcd->pszText, g_dat.limitNamesLength); - if (ltext != tcd->pszText) - tci.pszText = ptszTemp = ltext; + NMHDR* pNMHDR = (NMHDR*) lParam; + if (pNMHDR->hwndFrom == dat->hwndTabs) { + switch (pNMHDR->code) { + case TCN_SELCHANGE: + { + TCITEM tci = {0}; + int iSel = TabCtrl_GetCurSel(dat->hwndTabs); + tci.mask = TCIF_PARAM; + if (TabCtrl_GetItem(dat->hwndTabs, iSel, &tci)) { + MessageWindowTabData * mwtd = (MessageWindowTabData *) tci.lParam; + ActivateChild(dat, mwtd->hwnd); + SetFocus(dat->hwndActive); + } } - } - if (tcd->iFlags & TCDF_ICON) { - int iconIdx = -1; - if (tcd->hIcon != NULL) { - TCITEM tci2; - tci2.mask = TCIF_IMAGE; - TabCtrl_GetItem(dat->hwndTabs, tabId, &tci2); - iconIdx = AddOrReplaceIcon(g_dat.hTabIconList, tci2.iImage, tcd->hIcon); + break; + case NM_RCLICK: + { + TCHITTESTINFO thinfo; + GetCursorPos(&thinfo.pt); + + int x = thinfo.pt.x; + int y = thinfo.pt.y; + ScreenToClient(dat->hwndTabs, &thinfo.pt); + int tabId = TabCtrl_HitTest(dat->hwndTabs, &thinfo); + if (tabId != -1) { + HMENU hMenu, hSubMenu, hUserMenu; + BOOL menuResult; + MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, tabId); + hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT)); + hSubMenu = GetSubMenu(hMenu, 3); + TranslateMenu(hSubMenu); + hUserMenu = (HMENU) SendMessage(mwtd->hwnd, DM_GETCONTEXTMENU, 0, 0); + if (hUserMenu != NULL) { + InsertMenu(hSubMenu, 0, MF_POPUP | MF_BYPOSITION, (UINT_PTR)hUserMenu, TranslateT("User Menu")); + InsertMenu(hSubMenu, 1, MF_SEPARATOR | MF_BYPOSITION, 0, 0); + } + menuResult = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, x, y, 0, hwndDlg, NULL); + switch (menuResult) { + case IDM_CLOSETAB: + SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0); + break; + case IDM_CLOSEOTHERTABS: + CloseOtherChilden(dat, mwtd->hwnd); + break; + default: + CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(menuResult), MPCF_CONTACTMENU), (LPARAM)mwtd->hContact); + } + if (hUserMenu != NULL) + DestroyMenu(hUserMenu); + DestroyMenu(hMenu); + } } - tci.mask |= TCIF_IMAGE; - tci.iImage = iconIdx; + break; } - TabCtrl_SetItem(dat->hwndTabs, tabId, &tci); } - mir_free(ptszTemp); - } - break; - - case DM_SWITCHINFOBAR: - dat->flags2 ^= SMF2_SHOWINFOBAR; - { - for (int i=0; i < dat->childrenCount; i++) { - MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i); - SendMessage(mwtd->hwnd, DM_SWITCHINFOBAR, 0, 0); + else if (pNMHDR->hwndFrom == dat->hwndStatus) { + switch (pNMHDR->code) { + case NM_CLICK: + NMMOUSE *nm = (NMMOUSE*)lParam; + RECT rc; + SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 2, (LPARAM)&rc); + if (nm->pt.x >= rc.left) { + MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive); + if (mwtd != NULL) { + CheckStatusIconClick(mwtd->hContact, dat->hwndStatus, nm->pt, rc, 2, (pNMHDR->code == NM_RCLICK ? MBCF_RIGHTBUTTON : 0)); + } + } + return TRUE; + } } - SendMessage(hwndDlg, WM_SIZE, 0, 0); } break; - case DM_SWITCHSTATUSBAR: - dat->flags2 ^= SMF2_SHOWSTATUSBAR; - ShowWindow(dat->hwndStatus, (dat->flags2 & SMF2_SHOWSTATUSBAR) ? SW_SHOW : SW_HIDE); - SendMessage(hwndDlg, WM_SIZE, 0, 0); + case WM_DROPFILES: + SendMessage(dat->hwndActive, WM_DROPFILES, wParam, lParam); break; - case DM_SWITCHTOOLBAR: - dat->flags2 ^= SMF2_SHOWTOOLBAR; - { - for (int i=0; i < dat->childrenCount; i++) { - MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i); - SendMessage(mwtd->hwnd, DM_SWITCHTOOLBAR, 0, 0); + case WM_TIMER: + if (wParam == TIMERID_FLASHWND) { + if (dat->nFlash < 2 * dat->nFlashMax) { + FlashWindow(hwndDlg, TRUE); + dat->nFlash++; + } + else { + KillTimer(hwndDlg, TIMERID_FLASHWND); + FlashWindow(hwndDlg, FALSE); } } - SendMessage(hwndDlg, WM_SIZE, 0, 0); break; - case DM_SWITCHTITLEBAR: - { + case WM_CONTEXTMENU: + if (dat->hwndStatus && dat->hwndStatus == (HWND)wParam) { RECT rc; - dat->flags2 ^= SMF2_SHOWTITLEBAR; - ws = GetWindowLongPtr(hwndDlg, GWL_STYLE) & ~(WS_CAPTION); - if (dat->flags2 & SMF2_SHOWTITLEBAR) - ws |= WS_CAPTION; + POINT pt, pt2; + GetCursorPos(&pt); + pt2 = pt; + ScreenToClient(dat->hwndStatus, &pt); - SetWindowLongPtr(hwndDlg, GWL_STYLE, ws); - GetWindowRect(hwndDlg, &rc); - SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); - RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); + SendMessage(dat->hwndStatus, SB_GETRECT, SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) - 2, (LPARAM)&rc); + if (pt.x >= rc.left) { + MessageWindowTabData *mwtd = GetChildFromHWND(dat, dat->hwndActive); + if (mwtd != NULL) + CheckStatusIconClick(mwtd->hContact, dat->hwndStatus, pt, rc, 2, MBCF_RIGHTBUTTON); + break; + } + else SendMessage(dat->hwndActive, WM_CONTEXTMENU, (WPARAM)hwndDlg, 0); } break; - case DM_CASCADENEWWINDOW: - if ((HWND)wParam != hwndDlg) { - RECT rcThis, rcNew; - GetWindowRect(hwndDlg, &rcThis); - GetWindowRect((HWND) wParam, &rcNew); - if (abs(rcThis.left - rcNew.left) < 3 && abs(rcThis.top - rcNew.top) < 3) { - int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); - SetWindowPos((HWND) wParam, 0, rcNew.left + offset, rcNew.top + offset, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - *(int *) lParam = 1; - } + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_INACTIVE) { + ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; + ws |= dat->flags2 & SMF2_USETRANSPARENCY ? WS_EX_LAYERED : 0; + SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, ws); + if (dat->flags2 & SMF2_USETRANSPARENCY) + SetLayeredWindowAttributes(hwndDlg, RGB(255, 255, 255), (BYTE)(255 - g_dat.inactiveAlpha), LWA_ALPHA); + break; + } + if (dat->hwndActive != NULL) { + ActivateChild(dat, dat->hwndActive); + g_dat.hFocusWnd = dat->hwndActive; + PostMessage(dat->hwndActive, DM_SETFOCUS, 0, msg); + } + if (KillTimer(hwndDlg, TIMERID_FLASHWND)) { + FlashWindow(hwndDlg, FALSE); + dat->nFlash = 0; } + ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED; + ws |= dat->flags2 & SMF2_USETRANSPARENCY ? WS_EX_LAYERED : 0; + SetWindowLongPtr(hwndDlg , GWL_EXSTYLE , ws); + if (dat->flags2 & SMF2_USETRANSPARENCY) + SetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat.activeAlpha), LWA_ALPHA); break; - } - return FALSE; -} -static void DrawTab(ParentWindowData *dat, HWND hwnd, WPARAM wParam, LPARAM lParam) -{ - LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) lParam; - int iTabIndex = lpDIS->itemID; - if (iTabIndex < 0) - return; - - TabCtrlData *tcdat = (TabCtrlData*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - HANDLE hTheme = NULL; - int tstate; - TCHAR szLabel[1024]; - TCITEM tci; - tci.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_STATE; - tci.pszText = szLabel; - tci.cchTextMax = SIZEOF(szLabel); - tci.dwStateMask = TCIS_HIGHLIGHTED; - if (TabCtrl_GetItem(hwnd, iTabIndex, &tci)) { - IMAGEINFO info; - RECT rIcon = lpDIS->rcItem; - RECT rect = lpDIS->rcItem; - RECT rectTab = lpDIS->rcItem; - int bSelected = lpDIS->itemState & ODS_SELECTED; - int atTop = (GetWindowLongPtr(hwnd, GWL_STYLE) & TCS_BOTTOM) == 0; - UINT dwFormat; - if (!IsAppThemed()) { - FillRect(lpDIS->hDC, &rect, GetSysColorBrush(COLOR_BTNFACE)); + case WM_LBUTTONDOWN: + if (!IsZoomed(hwndDlg)) { + POINT pt; + GetCursorPos(&pt); + return SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); } - else { - if (lpDIS->itemState & ODS_SELECTED) - tstate = TTIS_SELECTED; - else if (lpDIS->itemState & ODS_FOCUS) - tstate = TTIS_FOCUSED; - else if (lpDIS->itemState & ODS_HOTLIGHT) - tstate = TTIS_HOT; - else - tstate = TTIS_NORMAL; + break; - if (!bSelected) - InflateRect(&rectTab, 1, 1); + case WM_MOVING: + if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) { + int snapPixels = 10; + RECT rcDesktop; + RECT *pRect = (RECT *)lParam; + POINT pt; + MONITORINFO mi; + HMONITOR hMonitor = MonitorFromRect(pRect, MONITOR_DEFAULTTONEAREST); + SIZE szSize = {pRect->right-pRect->left,pRect->bottom-pRect->top}; + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + GetCursorPos(&pt); - hTheme = OpenThemeData(hwnd, L"TAB"); - if (IsThemeBackgroundPartiallyTransparent(hTheme, TABP_TABITEM, tstate)) - DrawThemeParentBackground(hwnd, lpDIS->hDC, &rectTab); - DrawThemeBackground(hTheme, lpDIS->hDC, TABP_TABITEM, tstate, &rectTab, NULL); - } - if (atTop) { - dwFormat = DT_SINGLELINE | DT_TOP | DT_CENTER | DT_NOPREFIX | DT_NOCLIP; - rIcon.top = rect.top + GetSystemMetrics(SM_CYEDGE); - if (tci.iImage >= 0) { - rIcon.left = rect.left + GetSystemMetrics(SM_CXEDGE) + (bSelected ? 6 : 2); - ImageList_GetImageInfo(g_dat.hTabIconList, tci.iImage, &info); - ImageList_DrawEx(g_dat.hTabIconList, tci.iImage, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); - rect.left = rIcon.left + (info.rcImage.right - info.rcImage.left); + rcDesktop = mi.rcWork; + pRect->left = pt.x-dat->mouseLBDownPos.x; + pRect->top = pt.y-dat->mouseLBDownPos.y; + pRect->right = pRect->left+szSize.cx; + pRect->bottom = pRect->top+szSize.cy; + if (pRect->top < rcDesktop.top+snapPixels && pRect->top > rcDesktop.top-snapPixels) { + pRect->top = rcDesktop.top; + pRect->bottom = rcDesktop.top + szSize.cy; } - if (dat->flags2 & SMF2_TABCLOSEBUTTON) { - ImageList_GetImageInfo(g_dat.hButtonIconList, 0, &info); - rIcon.left = rect.right - GetSystemMetrics(SM_CXEDGE) - (bSelected ? 6 : 2) - (info.rcImage.right - info.rcImage.left); - ImageList_DrawEx(g_dat.hButtonIconList, 0, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); - rect.right = rIcon.left - 1; + if (pRect->left < rcDesktop.left+snapPixels && pRect->left > rcDesktop.left-snapPixels) { + pRect->left = rcDesktop.left; + pRect->right = rcDesktop.left + szSize.cx; } - rect.top += GetSystemMetrics(SM_CYEDGE) + 2; - } - else { - dwFormat = DT_SINGLELINE | DT_BOTTOM | DT_CENTER | DT_NOPREFIX | DT_NOCLIP; - rIcon.left = rect.left + GetSystemMetrics(SM_CXEDGE) + (bSelected ? 6 : 2); - if (tci.iImage >= 0) { - ImageList_GetImageInfo(g_dat.hTabIconList, tci.iImage, &info); - rIcon.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top) - 1; - ImageList_DrawEx(g_dat.hTabIconList, tci.iImage, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); - rect.left = rIcon.left + (info.rcImage.right - info.rcImage.left); + if (pRect->right < rcDesktop.right+snapPixels && pRect->right > rcDesktop.right-snapPixels) { + pRect->right = rcDesktop.right; + pRect->left = rcDesktop.right - szSize.cx; } - if (dat->flags2 & SMF2_TABCLOSEBUTTON) { - ImageList_GetImageInfo(g_dat.hButtonIconList, 0, &info); - rIcon.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top) - 2; - rIcon.left = rect.right - GetSystemMetrics(SM_CXEDGE) - (bSelected ? 6 : 2) - (info.rcImage.right - info.rcImage.left); - ImageList_DrawEx(g_dat.hButtonIconList, 0, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); - rect.right = rIcon.left - 1; + if (pRect->bottom < rcDesktop.bottom+snapPixels && pRect->bottom > rcDesktop.bottom-snapPixels) { + pRect->bottom = rcDesktop.bottom; + pRect->top = rcDesktop.bottom - szSize.cy; } - rect.bottom -= GetSystemMetrics(SM_CYEDGE) + 2; } + break; - if (hTheme) - DrawThemeText(hTheme, lpDIS->hDC, TABP_TABITEM, tstate, szLabel, -1, dwFormat, 0, &rect); - else - DrawText(lpDIS->hDC, szLabel, -1, &rect, dwFormat); - - if (tcdat->bDragged && iTabIndex == tcdat->destTab && iTabIndex != tcdat->srcTab) { - RECT hlRect = lpDIS->rcItem; - if (bSelected) { - hlRect.bottom -= GetSystemMetrics(SM_CYEDGE); - hlRect.top += GetSystemMetrics(SM_CYEDGE); - hlRect.left += GetSystemMetrics(SM_CXEDGE); - hlRect.right -= GetSystemMetrics(SM_CXEDGE); + case WM_SYSCOMMAND: + if ((wParam & 0xFFF0) == SC_MAXIMIZE) { + if (GetKeyState(VK_CONTROL) & 0x8000) + dat->bVMaximized = 1; + else + dat->bVMaximized = 0; + } + else if ((wParam & 0xFFF0) == SC_MOVE) { + RECT rc; + GetWindowRect(hwndDlg, &rc); + dat->mouseLBDownPos.x = LOWORD(lParam) - rc.left; + dat->mouseLBDownPos.y = HIWORD(lParam) - rc.top; + } + else if (wParam == IDM_TOPMOST) { + HMENU hMenu = GetSystemMenu(hwndDlg, FALSE); + if (dat->bTopmost) { + CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_UNCHECKED); + SetWindowPos(hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + dat->bTopmost = FALSE; } else { - if (atTop) { - hlRect.top += GetSystemMetrics(SM_CYEDGE); - hlRect.bottom += GetSystemMetrics(SM_CYEDGE); - } - else { - hlRect.top -= GetSystemMetrics(SM_CYEDGE); - hlRect.bottom -= GetSystemMetrics(SM_CYEDGE); - } + CheckMenuItem(hMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_CHECKED); + SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + dat->bTopmost = TRUE; } - FrameRect(lpDIS->hDC, &hlRect, GetSysColorBrush(COLOR_HIGHLIGHT)); - hlRect.left++; - hlRect.top++; - hlRect.right--; - hlRect.bottom--; - FrameRect(lpDIS->hDC, &hlRect, GetSysColorBrush(COLOR_HIGHLIGHT)); } - if (hTheme) - CloseThemeData(hTheme); - } -} - -LRESULT CALLBACK TabCtrlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TabCtrlData *dat = (TabCtrlData*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - - TCHITTESTINFO thinfo; - int tabId; + break; + case WM_DESTROY: + { + char szSettingName[64]; + for (int i = dat->childrenCount; i >= 0; i--) { + TCITEM tci; + tci.mask = TCIF_PARAM | TCIF_IMAGE; + if (TabCtrl_GetItem(dat->hwndTabs, i, &tci)) { + mir_free((MessageWindowTabData *)tci.lParam); + ReleaseIcon(tci.iImage); + TabCtrl_DeleteItem(dat->hwndTabs, i); + } + } + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); + WindowList_Remove(g_dat.hParentWindowList, hwndDlg); - switch(msg) { - case EM_SUBCLASSED: - dat = (TabCtrlData*)mir_alloc(sizeof(TabCtrlData)); - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); - dat->bDragging = FALSE; - dat->bDragged = FALSE; - dat->srcTab = -1; - dat->destTab = -1; - return 0; + int savePerContact = db_get_b(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT); + HANDLE hContact = (savePerContact) ? dat->hContact : NULL; - case WM_MBUTTONDOWN: - thinfo.pt.x = LOWORD(lParam); - thinfo.pt.y = HIWORD(lParam); - tabId = TabCtrl_HitTest(hwnd, &thinfo); - if (tabId >= 0) { - TCITEM tci; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(hwnd, tabId, &tci); - MessageWindowTabData *mwtd = (MessageWindowTabData *)tci.lParam; - if (mwtd != NULL) { - SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0); - dat->srcTab = -1; + WINDOWPLACEMENT wp = { sizeof(wp) }; + GetWindowPlacement(hwndDlg, &wp); + + char *szNamePrefix = (!savePerContact && dat->isChat) ? "chat" : ""; + if (!dat->windowWasCascaded) { + mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sx", szNamePrefix); + db_set_dw(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.left); + mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sy", szNamePrefix); + db_set_dw(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.top); } - } - return 0; + mir_snprintf(szSettingName, SIZEOF(szSettingName), "%swidth", szNamePrefix); + db_set_dw(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.right - wp.rcNormalPosition.left); + mir_snprintf(szSettingName, SIZEOF(szSettingName), "%sheight", szNamePrefix); + db_set_dw(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); + db_set_b(hContact, SRMMMOD, SRMSGSET_TOPMOST, (BYTE)dat->bTopmost); + if (g_dat.lastParent == dat) + g_dat.lastParent = dat->prev; - case WM_LBUTTONDBLCLK: - thinfo.pt.x = LOWORD(lParam); - thinfo.pt.y = HIWORD(lParam); - tabId = TabCtrl_HitTest(hwnd, &thinfo); - if (tabId >= 0 && tabId == dat->srcTab) { - SendMessage(GetChildFromTab(hwnd, tabId)->hwnd, WM_CLOSE, 0, 0); - dat->srcTab = -1; - } - dat->destTab = -1; - break; + if (g_dat.lastChatParent == dat) + g_dat.lastChatParent = dat->prev; - case WM_LBUTTONDOWN: - if (!dat->bDragging) { - thinfo.pt.x = LOWORD(lParam); - thinfo.pt.y = HIWORD(lParam); - dat->srcTab = TabCtrl_HitTest(hwnd, &thinfo); + if (dat->prev != NULL) + dat->prev->next = dat->next; - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - if (dat->srcTab >= 0) { - dat->bDragging = TRUE; - dat->bDragged = FALSE; - dat->clickLParam = lParam; - dat->clickWParam = wParam; - dat->lastClickTime = ft.dwLowDateTime; - dat->mouseLBDownPos.x = thinfo.pt.x; - dat->mouseLBDownPos.y = thinfo.pt.y; - SetCapture(hwnd); - } - return 0; + if (dat->next != NULL) + dat->next->prev = dat->prev; + + UnsubclassTabCtrl(dat->hwndTabs); + mir_free(dat); } break; - case WM_CAPTURECHANGED: - case WM_LBUTTONUP: - if (dat->bDragging) { - thinfo.pt.x = LOWORD(lParam); - thinfo.pt.y = HIWORD(lParam); - if (dat->bDragged) { - ImageList_DragLeave(GetDesktopWindow()); - ImageList_EndDrag(); - ImageList_Destroy(dat->hDragImageList); - SetCursor(LoadCursor(NULL, IDC_ARROW)); - dat->destTab = TabCtrl_HitTest(hwnd, &thinfo); - if (thinfo.flags != TCHT_NOWHERE && dat->destTab != dat->srcTab) { - NMHDR nmh; - TCHAR sBuffer[501]; - TCITEM item; - int curSel; - curSel = TabCtrl_GetCurSel(hwnd); - item.mask = TCIF_IMAGE | TCIF_PARAM | TCIF_TEXT; - item.pszText = sBuffer; - item.cchTextMax = SIZEOF(sBuffer); - TabCtrl_GetItem(hwnd, dat->srcTab, &item); - sBuffer[SIZEOF(sBuffer) - 1] = '\0'; + case DM_ERRORDECIDED: + break; - if (curSel == dat->srcTab) - curSel = dat->destTab; - else if (curSel > dat->srcTab && curSel <= dat->destTab) - curSel--; - else if (curSel < dat->srcTab && curSel >= dat->destTab) - curSel++; + case CM_STARTFLASHING: + if ((GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg)) {// && !(g_dat.flags2 & SMF2_STAYMINIMIZED)) { + dat->nFlash = 0; + SetTimer(hwndDlg, TIMERID_FLASHWND, TIMEOUT_FLASHWND, NULL); + } + break; - TabCtrl_DeleteItem(hwnd, dat->srcTab); - TabCtrl_InsertItem(hwnd, dat->destTab, &item); - TabCtrl_SetCurSel(hwnd, curSel); - dat->destTab = -1; - nmh.hwndFrom = hwnd; - nmh.idFrom = GetDlgCtrlID(hwnd); - nmh.code = TCN_SELCHANGE; - SendMessage(GetParent(hwnd), WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh); - UpdateWindow(hwnd); - } - else if (thinfo.flags == TCHT_NOWHERE) { - TCITEM tci; - POINT pt; - NewMessageWindowLParam newData = { 0 }; - dat->destTab = -1; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(hwnd, dat->srcTab, &tci); - MessageWindowTabData *mwtd = (MessageWindowTabData *)tci.lParam; - if (mwtd != NULL) { - HWND hChild = mwtd->hwnd; - HANDLE hContact = mwtd->hContact; - GetCursorPos(&pt); - HWND hParent = WindowFromPoint(pt); - while (GetParent(hParent) != NULL) - hParent = GetParent(hParent); + case CM_POPUPWINDOW: + EnableWindow(hwndDlg, TRUE); + if (wParam) { /* incoming message */ + if (g_dat.flags & SMF_STAYMINIMIZED) { + if (!IsWindowVisible(hwndDlg)) + ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE); - hParent = WindowList_Find(g_dat.hParentWindowList, hParent); - if ((hParent != NULL && hParent != GetParent(hwnd)) || (hParent == NULL && mwtd->parent->childrenCount > 1 && (GetKeyState(VK_CONTROL) & 0x8000))) { - if (hParent == NULL) { - RECT rc, rcDesktop; - newData.hContact = hContact; - hParent = (HWND)CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGWIN), NULL, DlgProcParentWindow, (LPARAM)& newData); - GetWindowRect(hParent, &rc); - rc.right = (rc.right - rc.left); - rc.bottom = (rc.bottom - rc.top); - rc.left = pt.x - rc.right / 2; - rc.top = pt.y - rc.bottom / 2; - HMONITOR hMonitor = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST); - MONITORINFO mi; - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); - rcDesktop = mi.rcWork; - if (rc.left < rcDesktop.left) - rc.left = rcDesktop.left; - if (rc.top < rcDesktop.top) - rc.top = rcDesktop.top; - MoveWindow(hParent, rc.left, rc.top, rc.right, rc.bottom, FALSE); - } - NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_CLOSING); - NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_CLOSE); - SetParent(hChild, hParent); - SendMessage(GetParent(hwnd), CM_REMOVECHILD, 0, (LPARAM)hChild); - SendMessage(hChild, DM_SETPARENT, 0, (LPARAM)hParent); - SendMessage(hParent, CM_ADDCHILD, (WPARAM)hChild, (LPARAM)hContact); - SendMessage(hChild, DM_UPDATETABCONTROL, 0, 0); - SendMessage(hParent, CM_ACTIVATECHILD, 0, (LPARAM)hChild); - NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_OPENING); - NotifyLocalWinEvent(hContact, hChild, MSG_WINDOW_EVT_OPEN); - ShowWindow(hParent, SW_SHOWNA); - EnableWindow(hParent, TRUE); - } - } - } - else { - dat->destTab = -1; - RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); - } + if (dat->childrenCount == 1 || ((g_dat.flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(hwndDlg) || GetForegroundWindow() != hwndDlg))) + SendMessage(hwndDlg, CM_ACTIVATECHILD, 0, (LPARAM)lParam); } - else if (dat->srcTab >= 0 && g_dat.flags2 & SMF2_TABCLOSEBUTTON) { - IMAGEINFO info; - POINT pt; - RECT rect; - int atTop = (GetWindowLongPtr(hwnd, GWL_STYLE) & TCS_BOTTOM) == 0; - TabCtrl_GetItemRect(hwnd, dat->srcTab, &rect); - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - ImageList_GetImageInfo(g_dat.hButtonIconList, 0, &info); - rect.left = rect.right - (info.rcImage.right - info.rcImage.left) - 6; - if (!atTop) - rect.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top); + else { + ShowWindow(hwndDlg, IsIconic(hwndDlg) ? SW_SHOWNORMAL : SW_SHOWNA); - if (pt.x >= rect.left && pt.x < rect.left + (info.rcImage.right - info.rcImage.left) && pt.y >= rect.top && pt.y < rect.top + (info.rcImage.bottom - info.rcImage.top)) { - HBITMAP hOldBitmap, hBmp; - HDC hdc = GetDC(NULL); - HDC hdcMem = CreateCompatibleDC(hdc); - pt.x -= rect.left; - pt.y -= rect.top; - hBmp = CreateCompatibleBitmap(hdc, info.rcImage.right - info.rcImage.left + 1, info.rcImage.bottom - info.rcImage.top + 1); - hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBmp); - SetPixel(hdcMem, pt.x, pt.y, 0x000000); - ImageList_DrawEx(g_dat.hButtonIconList, 0, hdcMem, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); - COLORREF color1 = GetPixel(hdcMem, pt.x, pt.y); - SetPixel(hdcMem, pt.x, pt.y, 0xFFFFFF); - ImageList_DrawEx(g_dat.hButtonIconList, 0, hdcMem, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); - COLORREF color2 = GetPixel(hdcMem, pt.x, pt.y); - SelectObject(hdcMem, hOldBitmap); - DeleteDC(hdcMem); - DeleteObject(hBmp); - ReleaseDC(NULL, hdc); - if (color1 != 0x000000 || color2 != 0xFFFFFF) { - SendMessage(GetChildFromTab(hwnd, dat->srcTab)->hwnd, WM_CLOSE, 0, 0); - dat->srcTab = -1; - } - } - else SendMessage(hwnd, WM_LBUTTONDOWN, dat->clickWParam, dat->clickLParam); - } - else SendMessage(hwnd, WM_LBUTTONDOWN, dat->clickWParam, dat->clickLParam); + if (dat->childrenCount == 1 || ((g_dat.flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(hwndDlg) || GetForegroundWindow() != hwndDlg))) + SendMessage(hwndDlg, CM_ACTIVATECHILD, 0, (LPARAM)lParam); - dat->bDragged = FALSE; - dat->bDragging = FALSE; - dat->destTab = -1; - ReleaseCapture(); + SetWindowPos(hwndDlg, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + } + } + else { /* outgoing message */ + ShowWindow(hwndDlg, IsIconic(hwndDlg) ? SW_SHOWNORMAL : SW_SHOW); + SetForegroundWindow(hwndDlg); + SetFocus((HWND)lParam); } break; - case WM_MOUSEMOVE: - if (wParam & MK_LBUTTON) { - if (dat->bDragging) { - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - thinfo.pt.x = LOWORD(lParam); - thinfo.pt.y = HIWORD(lParam); - if (!dat->bDragged) { - if ((abs(thinfo.pt.x - dat->mouseLBDownPos.x) < 3 && abs(thinfo.pt.y - dat->mouseLBDownPos.y) < 3) - || (ft.dwLowDateTime - dat->lastClickTime) < 10 * 1000 * 150) - break; - } - if (!dat->bDragged) { - POINT pt; - RECT rect; - RECT rect2; - HBRUSH hBrush = CreateSolidBrush(RGB(255, 0, 254)); - GetCursorPos(&pt); - TabCtrl_GetItemRect(hwnd, dat->srcTab, &rect); - rect.right -= rect.left - 1; - rect.bottom -= rect.top - 1; - rect2.left = 0; rect2.right = rect.right; rect2.top = 0; rect2.bottom = rect.bottom; - dat->hDragImageList = ImageList_Create(rect.right, rect.bottom, ILC_COLOR | ILC_MASK, 0, 1); - HDC hDC = GetDC(hwnd); - HDC hMemDC = CreateCompatibleDC(hDC); - HBITMAP hBitmap = CreateCompatibleBitmap(hDC, rect.right, rect.bottom); - HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); - FillRect(hMemDC, &rect2, hBrush); - SetWindowOrgEx(hMemDC, rect.left, rect.top, NULL); - SendMessage(hwnd, WM_PRINTCLIENT, (WPARAM)hMemDC, PRF_CLIENT); - SelectObject(hMemDC, hOldBitmap); - ImageList_AddMasked(dat->hDragImageList, hBitmap, RGB(255, 0, 254)); - DeleteObject(hBitmap); - DeleteObject(hBrush); - ReleaseDC(hwnd, hDC); - DeleteDC(hMemDC); - ImageList_BeginDrag(dat->hDragImageList, 0, dat->mouseLBDownPos.x - rect.left, dat->mouseLBDownPos.y - rect.top); - ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y); - SetCursor(hDragCursor); - dat->mouseLBDownPos.x = thinfo.pt.x; - dat->mouseLBDownPos.y = thinfo.pt.y; + case CM_REMOVECHILD: + RemoveChild(dat, (HWND)lParam); + if (dat->childrenCount != 0) + SetFocus(dat->hwndActive); + else + PostMessage(hwndDlg, WM_CLOSE, 0, 0); + return TRUE; + + case CM_ADDCHILD: + AddChild(dat, (HWND)wParam, (HANDLE)lParam); + return TRUE; + + case CM_ACTIVATECHILD: + ActivateChild(dat, (HWND)lParam); + return TRUE; + + case CM_ACTIVATEPREV: + ActivatePrevChild(dat, (HWND)lParam); + SetFocus(dat->hwndActive); + return TRUE; + + case CM_ACTIVATENEXT: + ActivateNextChild(dat, (HWND)lParam); + SetFocus(dat->hwndActive); + return TRUE; + + case CM_ACTIVATEBYINDEX: + ActivateChildByIndex(dat, (int)lParam); + SetFocus(dat->hwndActive); + return TRUE; + + case CM_GETCHILDCOUNT: + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetChildCount(dat)); + return TRUE; + + case CM_GETACTIVECHILD: + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)dat->hwndActive); + return TRUE; + + case CM_GETTOOLBARSTATUS: + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)(dat->flags2 & SMF2_SHOWTOOLBAR) != 0); + return TRUE; + + case DM_SENDMESSAGE: + for (int i = 0; i < dat->childrenCount; i++) { + MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i); + SendMessage(mwtd->hwnd, DM_SENDMESSAGE, wParam, lParam); + } + break; + + case DM_OPTIONSAPPLIED: + dat->flags2 = g_dat.flags2; + SetContainerWindowStyle(dat); + SendMessage(hwndDlg, WM_SIZE, 0, 0); + break; + + case CM_UPDATETITLEBAR: + { + HWND hwnd = (HWND)lParam; + TitleBarData *tbd = (TitleBarData *)wParam; + if (tbd != NULL && dat->hwndActive == hwnd) { + if (tbd->iFlags & TBDF_TEXT) { + TCHAR oldtitle[256]; + GetWindowText(hwndDlg, oldtitle, SIZEOF(oldtitle)); + if (lstrcmp(tbd->pszText, oldtitle)) + SetWindowText(hwndDlg, tbd->pszText); } - else { - POINT pt; - GetCursorPos(&pt); - thinfo.pt = pt; - ScreenToClient(hwnd, &thinfo.pt); - int newDest = TabCtrl_HitTest(hwnd, &thinfo); - if (thinfo.flags == TCHT_NOWHERE) - newDest = -1; + if (tbd->iFlags & TBDF_ICON) { + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)tbd->hIcon); + if (tbd->hIconBig != NULL) + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)tbd->hIconBig); + if (pTaskbarInterface) + pTaskbarInterface->SetOverlayIcon(hwndDlg, tbd->hIconNot, L""); + } + } + } + break; - if (newDest != dat->destTab) { - dat->destTab = newDest; - ImageList_DragLeave(GetDesktopWindow()); - RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); - ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y); + case CM_UPDATESTATUSBAR: + { + HWND hwnd = (HWND)lParam; + StatusBarData *sbd = (StatusBarData *)wParam; + if (sbd != NULL) { + if ((sbd->iFlags & SBDF_TEXT) && dat->hwndActive == hwnd) + SendMessage(dat->hwndStatus, SB_SETTEXT, sbd->iItem, (LPARAM)sbd->pszText); + if ((sbd->iFlags & SBDF_ICON) && dat->hwndActive == hwnd) + SendMessage(dat->hwndStatus, SB_SETICON, sbd->iItem, (LPARAM)sbd->hIcon); + RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); + } + } + break; + + case DM_STATUSICONCHANGE: + SendMessage(dat->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_OWNERDRAW) | 2, 0); + SetupStatusBar(dat); + RedrawWindow(dat->hwndStatus, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); + break; + + case CM_UPDATETABCONTROL: + { + TCHAR *ptszTemp = NULL; + TabControlData *tcd = (TabControlData *) wParam; + int tabId = GetTabFromHWND(dat, (HWND) lParam); + if (tabId >= 0 && tcd != NULL) { + TCITEM tci; + tci.mask = 0; + if (tcd->iFlags & TCDF_TEXT) { + tci.mask |= TCIF_TEXT; + tci.pszText = tcd->pszText; + if (g_dat.flags2 & SMF2_LIMITNAMES) { + TCHAR * ltext = limitText(tcd->pszText, g_dat.limitNamesLength); + if (ltext != tcd->pszText) + tci.pszText = ptszTemp = ltext; } - else ImageList_DragMove(pt.x, pt.y); } - dat->bDragged = TRUE; - return 0; + if (tcd->iFlags & TCDF_ICON) { + int iconIdx = -1; + if (tcd->hIcon != NULL) { + TCITEM tci2; + tci2.mask = TCIF_IMAGE; + TabCtrl_GetItem(dat->hwndTabs, tabId, &tci2); + iconIdx = AddOrReplaceIcon(g_dat.hTabIconList, tci2.iImage, tcd->hIcon); + } + tci.mask |= TCIF_IMAGE; + tci.iImage = iconIdx; + } + TabCtrl_SetItem(dat->hwndTabs, tabId, &tci); } + mir_free(ptszTemp); } break; - case EM_UNSUBCLASSED: - mir_free(dat); - return 0; + case DM_SWITCHINFOBAR: + dat->flags2 ^= SMF2_SHOWINFOBAR; + { + for (int i=0; i < dat->childrenCount; i++) { + MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i); + SendMessage(mwtd->hwnd, DM_SWITCHINFOBAR, 0, 0); + } + SendMessage(hwndDlg, WM_SIZE, 0, 0); + } + break; + + case DM_SWITCHSTATUSBAR: + dat->flags2 ^= SMF2_SHOWSTATUSBAR; + ShowWindow(dat->hwndStatus, (dat->flags2 & SMF2_SHOWSTATUSBAR) ? SW_SHOW : SW_HIDE); + SendMessage(hwndDlg, WM_SIZE, 0, 0); + break; + + case DM_SWITCHTOOLBAR: + dat->flags2 ^= SMF2_SHOWTOOLBAR; + { + for (int i=0; i < dat->childrenCount; i++) { + MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i); + SendMessage(mwtd->hwnd, DM_SWITCHTOOLBAR, 0, 0); + } + } + SendMessage(hwndDlg, WM_SIZE, 0, 0); + break; + + case DM_SWITCHTITLEBAR: + { + RECT rc; + dat->flags2 ^= SMF2_SHOWTITLEBAR; + ws = GetWindowLongPtr(hwndDlg, GWL_STYLE) & ~(WS_CAPTION); + if (dat->flags2 & SMF2_SHOWTITLEBAR) + ws |= WS_CAPTION; + + SetWindowLongPtr(hwndDlg, GWL_STYLE, ws); + GetWindowRect(hwndDlg, &rc); + SetWindowPos(hwndDlg, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING); + RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); + } + break; + + case DM_CASCADENEWWINDOW: + if ((HWND)wParam != hwndDlg) { + RECT rcThis, rcNew; + GetWindowRect(hwndDlg, &rcThis); + GetWindowRect((HWND) wParam, &rcNew); + if (abs(rcThis.left - rcNew.left) < 3 && abs(rcThis.top - rcNew.top) < 3) { + int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); + SetWindowPos((HWND) wParam, 0, rcNew.left + offset, rcNew.top + offset, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + *(int *) lParam = 1; + } + } + break; + } + return FALSE; +} + +static void DrawTab(ParentWindowData *dat, HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) lParam; + int iTabIndex = lpDIS->itemID; + if (iTabIndex < 0) + return; + + TabCtrlData *tcdat = (TabCtrlData*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + HANDLE hTheme = NULL; + int tstate; + TCHAR szLabel[1024]; + TCITEM tci; + tci.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_STATE; + tci.pszText = szLabel; + tci.cchTextMax = SIZEOF(szLabel); + tci.dwStateMask = TCIS_HIGHLIGHTED; + if (TabCtrl_GetItem(hwnd, iTabIndex, &tci)) { + IMAGEINFO info; + RECT rIcon = lpDIS->rcItem; + RECT rect = lpDIS->rcItem; + RECT rectTab = lpDIS->rcItem; + int bSelected = lpDIS->itemState & ODS_SELECTED; + int atTop = (GetWindowLongPtr(hwnd, GWL_STYLE) & TCS_BOTTOM) == 0; + UINT dwFormat; + if (!IsAppThemed()) { + FillRect(lpDIS->hDC, &rect, GetSysColorBrush(COLOR_BTNFACE)); + } + else { + if (lpDIS->itemState & ODS_SELECTED) + tstate = TTIS_SELECTED; + else if (lpDIS->itemState & ODS_FOCUS) + tstate = TTIS_FOCUSED; + else if (lpDIS->itemState & ODS_HOTLIGHT) + tstate = TTIS_HOT; + else + tstate = TTIS_NORMAL; + + if (!bSelected) + InflateRect(&rectTab, 1, 1); + + hTheme = OpenThemeData(hwnd, L"TAB"); + if (IsThemeBackgroundPartiallyTransparent(hTheme, TABP_TABITEM, tstate)) + DrawThemeParentBackground(hwnd, lpDIS->hDC, &rectTab); + DrawThemeBackground(hTheme, lpDIS->hDC, TABP_TABITEM, tstate, &rectTab, NULL); + } + if (atTop) { + dwFormat = DT_SINGLELINE | DT_TOP | DT_CENTER | DT_NOPREFIX | DT_NOCLIP; + rIcon.top = rect.top + GetSystemMetrics(SM_CYEDGE); + if (tci.iImage >= 0) { + rIcon.left = rect.left + GetSystemMetrics(SM_CXEDGE) + (bSelected ? 6 : 2); + ImageList_GetImageInfo(g_dat.hTabIconList, tci.iImage, &info); + ImageList_DrawEx(g_dat.hTabIconList, tci.iImage, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); + rect.left = rIcon.left + (info.rcImage.right - info.rcImage.left); + } + if (dat->flags2 & SMF2_TABCLOSEBUTTON) { + ImageList_GetImageInfo(g_dat.hButtonIconList, 0, &info); + rIcon.left = rect.right - GetSystemMetrics(SM_CXEDGE) - (bSelected ? 6 : 2) - (info.rcImage.right - info.rcImage.left); + ImageList_DrawEx(g_dat.hButtonIconList, 0, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); + rect.right = rIcon.left - 1; + } + rect.top += GetSystemMetrics(SM_CYEDGE) + 2; + } + else { + dwFormat = DT_SINGLELINE | DT_BOTTOM | DT_CENTER | DT_NOPREFIX | DT_NOCLIP; + rIcon.left = rect.left + GetSystemMetrics(SM_CXEDGE) + (bSelected ? 6 : 2); + if (tci.iImage >= 0) { + ImageList_GetImageInfo(g_dat.hTabIconList, tci.iImage, &info); + rIcon.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top) - 1; + ImageList_DrawEx(g_dat.hTabIconList, tci.iImage, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); + rect.left = rIcon.left + (info.rcImage.right - info.rcImage.left); + } + if (dat->flags2 & SMF2_TABCLOSEBUTTON) { + ImageList_GetImageInfo(g_dat.hButtonIconList, 0, &info); + rIcon.top = rect.bottom - (info.rcImage.bottom - info.rcImage.top) - 2; + rIcon.left = rect.right - GetSystemMetrics(SM_CXEDGE) - (bSelected ? 6 : 2) - (info.rcImage.right - info.rcImage.left); + ImageList_DrawEx(g_dat.hButtonIconList, 0, lpDIS->hDC, rIcon.left, rIcon.top, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL); + rect.right = rIcon.left - 1; + } + rect.bottom -= GetSystemMetrics(SM_CYEDGE) + 2; + } + + if (hTheme) + DrawThemeText(hTheme, lpDIS->hDC, TABP_TABITEM, tstate, szLabel, -1, dwFormat, 0, &rect); + else + DrawText(lpDIS->hDC, szLabel, -1, &rect, dwFormat); + + if (tcdat->bDragged && iTabIndex == tcdat->destTab && iTabIndex != tcdat->srcTab) { + RECT hlRect = lpDIS->rcItem; + if (bSelected) { + hlRect.bottom -= GetSystemMetrics(SM_CYEDGE); + hlRect.top += GetSystemMetrics(SM_CYEDGE); + hlRect.left += GetSystemMetrics(SM_CXEDGE); + hlRect.right -= GetSystemMetrics(SM_CXEDGE); + } + else { + if (atTop) { + hlRect.top += GetSystemMetrics(SM_CYEDGE); + hlRect.bottom += GetSystemMetrics(SM_CYEDGE); + } + else { + hlRect.top -= GetSystemMetrics(SM_CYEDGE); + hlRect.bottom -= GetSystemMetrics(SM_CYEDGE); + } + } + FrameRect(lpDIS->hDC, &hlRect, GetSysColorBrush(COLOR_HIGHLIGHT)); + hlRect.left++; + hlRect.top++; + hlRect.right--; + hlRect.bottom--; + FrameRect(lpDIS->hDC, &hlRect, GetSysColorBrush(COLOR_HIGHLIGHT)); + } + if (hTheme) + CloseThemeData(hTheme); } - return mir_callNextSubclass(hwnd, TabCtrlProc, msg, wParam, lParam); } int ScriverRestoreWindowPosition(HWND hwnd, HANDLE hContact, const char *szModule,const char *szNamePrefix, int flags, int showCmd) diff --git a/plugins/Scriver/src/msgwindow.h b/plugins/Scriver/src/msgwindow.h index d0c861bcfc..ea71f2977c 100644 --- a/plugins/Scriver/src/msgwindow.h +++ b/plugins/Scriver/src/msgwindow.h @@ -58,40 +58,39 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define SBDF_TEXT 1 #define SBDF_ICON 2 -typedef struct StatusBarDataStruct +struct StatusBarData { int iItem; int iFlags; TCHAR *pszText; HICON hIcon; -} StatusBarData; +}; #define TBDF_TEXT 1 #define TBDF_ICON 2 -typedef struct TitleBarDataStruct +struct TitleBarData { int iFlags; TCHAR *pszText; HICON hIcon; HICON hIconBig; HICON hIconNot; -} TitleBarData; +}; #define TCDF_TEXT 1 #define TCDF_ICON 2 -typedef struct TabControlDataStruct +struct TabControlData { int iFlags; TCHAR *pszText; -// int iconIdx; HICON hIcon; -} TabControlData; +}; -extern TCHAR* GetWindowTitle(HANDLE *hContact, const char *szProto); -extern TCHAR* GetTabName(HANDLE *hContact); -extern HWND GetParentWindow(HANDLE hContact, BOOL bChat); -extern void NotifyLocalWinEvent(HANDLE hContact, HWND hwnd, unsigned int type); +TCHAR* GetWindowTitle(HANDLE *hContact, const char *szProto); +TCHAR* GetTabName(HANDLE *hContact); +HWND GetParentWindow(HANDLE hContact, BOOL bChat); +void NotifyLocalWinEvent(HANDLE hContact, HWND hwnd, unsigned int type); #endif -- cgit v1.2.3