summaryrefslogtreecommitdiff
path: root/plugins/Scriver/msgwindow.cpp
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-06-23 21:05:39 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-06-23 21:05:39 +0000
commit449553a9543c7ecc601f74c4abccc07d13521b15 (patch)
tree3c0d0e1a1f173a16f95bbd37f798ea20943459bd /plugins/Scriver/msgwindow.cpp
parentfe59b607ba13cd60375174b0d901b860bfa52e07 (diff)
Scriver:
renamed to .cpp git-svn-id: http://svn.miranda-ng.org/main/trunk@590 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Scriver/msgwindow.cpp')
-rw-r--r--plugins/Scriver/msgwindow.cpp1661
1 files changed, 1661 insertions, 0 deletions
diff --git a/plugins/Scriver/msgwindow.cpp b/plugins/Scriver/msgwindow.cpp
new file mode 100644
index 0000000000..1bda12f9db
--- /dev/null
+++ b/plugins/Scriver/msgwindow.cpp
@@ -0,0 +1,1661 @@
+/*
+Scriver
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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"
+#include "statusicon.h"
+#include "chat/chat.h"
+
+#ifndef __MINGW32__
+#if (_MSC_VER < 1300)
+#include "multimon.h"
+#endif
+#endif
+
+extern HINSTANCE g_hInst;
+extern HCURSOR hDragCursor;
+extern ITaskbarList3 * pTaskbarInterface;
+
+#define SB_CHAR_WIDTH 40
+#define SB_SENDING_WIDTH 25
+#define SB_UNICODE_WIDTH 18
+
+#define TIMERID_FLASHWND 1
+#define TIMEOUT_FLASHWND 900
+
+static WNDPROC OldTabCtrlProc;
+static void DrawTab(ParentWindowData *dat, HWND hwnd, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK TabCtrlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+extern TCHAR *GetNickname(HANDLE hContact, const char* szProto);
+
+void SubclassTabCtrl(HWND hwnd) {
+ OldTabCtrlProc = (WNDPROC) SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) TabCtrlProc);
+ SendMessage(hwnd, EM_SUBCLASSED, 0, 0);
+}
+
+void UnsubclassTabCtrl(HWND hwnd) {
+ SendMessage(hwnd, EM_UNSUBCLASSED, 0, 0);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) OldTabCtrlProc);
+}
+
+static const TCHAR *titleTokenNames[] = {_T("%name%"), _T("%status%"), _T("%statusmsg%"), _T("%account%")};
+
+TCHAR* GetWindowTitle(HANDLE *hContact, const char *szProto)
+{
+ int isTemplate;
+ int i, j, len;
+ TCHAR* tokens[4] = {0};
+ int tokenLen[4] = {0};
+ TCHAR *p, *tmplt, *title;
+ char *accModule;
+ TCHAR *pszNewTitleEnd = mir_tstrdup(TranslateT("Message Session"));
+ isTemplate = 0;
+ if (hContact && szProto) {
+ tokens[0] = GetNickname(hContact, szProto);
+ tokenLen[0] = lstrlen(tokens[0]);
+ tokens[1] = mir_tstrdup((TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, szProto ?
+ DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE) : ID_STATUS_OFFLINE, GSMDF_TCHAR));
+ tokenLen[1] = lstrlen(tokens[1]);
+ tokens[2] = DBGetStringT(hContact, "CList", "StatusMsg");
+ if (tokens[2] != NULL) {
+ tokenLen[2] = (int)lstrlen(tokens[2]);
+ for (i = j = 0; i < tokenLen[2]; i++) {
+ if (tokens[2][i] == '\r') {
+ continue;
+ } else if (tokens[2][i] == '\n') {
+ tokens[2][j++] = ' ';
+ } else {
+ tokens[2][j++] = tokens[2][i];
+ }
+ }
+ tokens[2][j] = '\0';
+ tokenLen[2] = j;
+ }
+
+ accModule = (char *) CallService(MS_PROTO_GETCONTACTBASEACCOUNT, (WPARAM) hContact, 0);
+ if (accModule != NULL) {
+ PROTOACCOUNT* proto = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)accModule);
+ if (proto != NULL) {
+ tokens[3] = mir_tstrdup(proto->tszAccountName);
+ tokenLen[3] = lstrlen(tokens[3]);
+ }
+ }
+ tmplt = DBGetStringT(NULL, SRMMMOD, SRMSGSET_WINDOWTITLE);
+ if (tmplt != NULL) {
+ isTemplate = 1;
+ } else {
+ if (g_dat->flags & SMF_STATUSICON) {
+ tmplt = _T("%name% - ");
+ } else {
+ tmplt = _T("%name% (%status%) : ");
+ }
+ }
+ } else {
+ tmplt = _T("");
+ }
+ for (len = 0, p = tmplt; *p; p++, len++) {
+ if (*p == '%') {
+ for (i = 0; i < SIZEOF(titleTokenNames); i ++) {
+ int tnlen = (int)_tcslen(titleTokenNames[i]);
+ if (!_tcsncmp(p, titleTokenNames[i], tnlen)) {
+ len += tokenLen[i] - 1;
+ p += tnlen - 1;
+ break;
+ }
+ }
+ }
+ }
+ if (!isTemplate) {
+ len += lstrlen(pszNewTitleEnd);
+ }
+ title = (TCHAR *)mir_alloc(sizeof(TCHAR) * (len + 1));
+ for (len = 0, p = tmplt; *p; p++) {
+ if (*p == '%') {
+ for (i = 0; i < SIZEOF(titleTokenNames); i ++) {
+ int tnlen = lstrlen(titleTokenNames[i]);
+ if (!_tcsncmp(p, titleTokenNames[i], tnlen)) {
+ if (tokens[i] != NULL) {
+ memcpy(title+len, tokens[i], sizeof(TCHAR) * tokenLen[i]);
+ len += tokenLen[i];
+ }
+ p += tnlen - 1;
+ break;
+ }
+ }
+ if (i < SIZEOF(titleTokenNames)) continue;
+ }
+ title[len++] = *p;
+ }
+ if (!isTemplate) {
+ memcpy(title+len, pszNewTitleEnd, sizeof(TCHAR) * lstrlen(pszNewTitleEnd));
+ len += lstrlen(pszNewTitleEnd);
+ }
+ title[len] = '\0';
+ if (isTemplate) {
+ mir_free(tmplt);
+ }
+ for (i = 0; i < SIZEOF(titleTokenNames); i ++) {
+ mir_free(tokens[i]);
+ }
+ mir_free(pszNewTitleEnd);
+ return title;
+}
+
+TCHAR* GetTabName(HANDLE *hContact)
+{
+ if (hContact) {
+ return GetNickname(hContact, NULL);
+ }
+ return NULL;
+}
+
+static int GetChildCount(ParentWindowData *dat) {
+ return TabCtrl_GetItemCount(dat->hwndTabs);
+}
+
+static void GetChildWindowRect(ParentWindowData *dat, RECT *rcChild)
+{
+ RECT rc, rcStatus, rcTabs;
+ GetClientRect(dat->hwnd, &rc);
+ GetClientRect(dat->hwndTabs, &rcTabs);
+ TabCtrl_AdjustRect(dat->hwndTabs, FALSE, &rcTabs);
+ rcStatus.top = rcStatus.bottom = 0;
+ if (dat->flags2 & SMF2_SHOWSTATUSBAR) {
+ GetWindowRect(dat->hwndStatus, &rcStatus);
+ }
+ rcChild->left = 0;
+ rcChild->right = rc.right;
+ if (dat->flags2 & SMF2_TABSATBOTTOM) {
+ rcChild->top = 2;
+ if ((dat->flags2 & SMF2_USETABS && !(dat->flags2 & SMF2_HIDEONETAB)) || (dat->childrenCount > 1)) {
+ rcChild->bottom = rcTabs.bottom + 4;
+ } else {
+ rcChild->bottom = rc.bottom - rc.top - (rcStatus.bottom - rcStatus.top);
+ }
+ } else {
+ if ((dat->flags2 & SMF2_USETABS && !(dat->flags2 & SMF2_HIDEONETAB)) || (dat->childrenCount > 1)) {
+ rcChild->top = rcTabs.top;
+ } else {
+ rcChild->top = 2;//rcTabs.top - 2;
+ }
+ rcChild->bottom = rc.bottom - rc.top - (rcStatus.bottom - rcStatus.top);
+ }
+}
+
+static int GetTabFromHWND(ParentWindowData *dat, HWND child)
+{
+ MessageWindowTabData * mwtd;
+ TCITEM tci;
+ int l, i;
+ l = TabCtrl_GetItemCount(dat->hwndTabs);
+ for (i = 0; i < l; i++) {
+ ZeroMemory(&tci, sizeof(TCITEM));
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(dat->hwndTabs, i, &tci);
+ mwtd = (MessageWindowTabData *) tci.lParam;
+ if (mwtd->hwnd == child) {
+ return i;
+ }
+ }
+ return -1;
+
+}
+
+static MessageWindowTabData * GetChildFromTab(HWND hwndTabs, int tabId)
+{
+ TCITEM tci;
+ ZeroMemory(&tci, sizeof(TCITEM));
+ tci.mask = TCIF_PARAM;
+ if (TabCtrl_GetItem(hwndTabs, tabId, &tci)) {
+ return (MessageWindowTabData *) tci.lParam;
+ }
+ return NULL;
+}
+
+static MessageWindowTabData * GetChildFromHWND(ParentWindowData *dat, HWND hwnd)
+{
+ MessageWindowTabData * mwtd;
+ TCITEM tci;
+ int l, i;
+ l = TabCtrl_GetItemCount(dat->hwndTabs);
+ for (i = 0; i < l; i++) {
+ ZeroMemory(&tci, sizeof(TCITEM));
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(dat->hwndTabs, i, &tci);
+ mwtd = (MessageWindowTabData *) tci.lParam;
+ if (mwtd->hwnd == hwnd) {
+ return mwtd;
+ }
+ }
+ return NULL;
+}
+
+static void GetMinimunWindowSize(ParentWindowData *dat, SIZE *size)
+{
+ MINMAXINFO mmi;
+ RECT rc, rcWindow;
+ int i, minW = 216, minH = 80;
+ GetWindowRect(dat->hwnd, &rcWindow);
+ GetChildWindowRect(dat, &rc);
+ for (i=0;i<dat->childrenCount;i++) {
+ MessageWindowTabData * mwtd = GetChildFromTab(dat->hwndTabs, i);
+ SendMessage(mwtd->hwnd, WM_GETMINMAXINFO, 0, (LPARAM) &mmi);
+ if (i==0 || mmi.ptMinTrackSize.x > minW) minW = mmi.ptMinTrackSize.x;
+ if (i==0 || mmi.ptMinTrackSize.y > minH) minH = mmi.ptMinTrackSize.y;
+ }
+ if (dat->bMinimized) {
+ size->cx = minW;
+ size->cy = minH;
+ } else {
+ size->cx = minW + (rcWindow.right - rcWindow.left) - (rc.right - rc.left);
+ size->cy = minH + (rcWindow.bottom - rcWindow.top) - (rc.bottom - rc.top);
+ }
+}
+
+static void SetupStatusBar(ParentWindowData *dat)
+{
+ int statusIconNum = GetStatusIconsCount(dat->hContact);
+ int statwidths[4];
+ RECT rc;
+ GetClientRect(dat->hwnd, &rc);
+ statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH - SB_UNICODE_WIDTH - 2 * (statusIconNum > 0) - statusIconNum * (GetSystemMetrics(SM_CXSMICON) + 2);
+ statwidths[1] = rc.right - rc.left - SB_UNICODE_WIDTH - 2 * (statusIconNum > 0) - statusIconNum * (GetSystemMetrics(SM_CXSMICON) + 2);
+ statwidths[2] = rc.right - rc.left - SB_UNICODE_WIDTH;
+ statwidths[3] = -1;
+ SendMessage(dat->hwndStatus, SB_SETPARTS, 4, (LPARAM) statwidths);
+ SendMessage(dat->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_OWNERDRAW) | 2, (LPARAM)0);
+ SendMessage(dat->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_NOBORDERS) | 3, (LPARAM)0);
+}
+
+static int AddOrReplaceIcon(HIMAGELIST hList, int prevIndex, HICON hIcon) {
+ int usageIdx = -1;
+ int i;
+ for (i = 0; i < g_dat->tabIconListUsageSize; i++) {
+ if (!g_dat->tabIconListUsage[i].used && usageIdx == -1) {
+ usageIdx = i;
+ }
+ if (g_dat->tabIconListUsage[i].index == prevIndex) {
+ usageIdx = i;
+ break;
+ }
+ }
+ if (usageIdx == -1) {
+ usageIdx = g_dat->tabIconListUsageSize;
+ g_dat->tabIconListUsage = (ImageListUsageEntry*) mir_realloc(g_dat->tabIconListUsage, sizeof(ImageListUsageEntry) * (g_dat->tabIconListUsageSize + 1));
+ g_dat->tabIconListUsageSize++;
+ } else {
+ prevIndex = g_dat->tabIconListUsage[usageIdx].index;
+ }
+ g_dat->tabIconListUsage[usageIdx].used = 1;
+ g_dat->tabIconListUsage[usageIdx].index = (int) ImageList_ReplaceIcon(hList, prevIndex, hIcon);
+ return g_dat->tabIconListUsage[usageIdx].index;
+}
+
+static void ReleaseIcon(int index) {
+ int i;
+ for (i = 0; i < g_dat->tabIconListUsageSize; i++) {
+ if (g_dat->tabIconListUsage[i].index == index) {
+ g_dat->tabIconListUsage[i].used = 0;
+ }
+ }
+}
+
+static void ActivateChild(ParentWindowData *dat, HWND child) {
+ int i;
+ RECT rcChild;
+ GetChildWindowRect(dat, &rcChild);
+ SetWindowPos(child, HWND_TOP, rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, SWP_NOSIZE);
+
+ i = GetTabFromHWND(dat, child);
+ if ( i == -1 )
+ return;
+ else {
+ MessageWindowTabData *mwtd;
+ if (( mwtd = GetChildFromTab(dat->hwndTabs, i)) == NULL )
+ return;
+
+ dat->hContact = mwtd->hContact;
+ if(child != dat->hwndActive) {
+ HWND prev = dat->hwndActive;
+ dat->hwndActive = child;
+ SetupStatusBar(dat);
+ SendMessage(dat->hwndActive, DM_UPDATESTATUSBAR, 0, 0);
+ SendMessage(dat->hwndActive, DM_UPDATETITLEBAR, 0, 0);
+ SendMessage(dat->hwnd, WM_SIZE, 0, 0);
+ ShowWindow(dat->hwndActive, SW_SHOWNOACTIVATE);
+ SendMessage(dat->hwndActive, DM_SCROLLLOGTOBOTTOM, 0, 0);
+ if (prev!=NULL) ShowWindow(prev, SW_HIDE);
+ } else {
+ SendMessage(dat->hwnd, WM_SIZE, 0, 0);
+ }
+ TabCtrl_SetCurSel(dat->hwndTabs, i);
+ SendMessage(dat->hwndActive, DM_ACTIVATE, WA_ACTIVE, 0);
+ }
+}
+
+static void UpdateTabsPadding(ParentWindowData *dat)
+{
+ if (dat->childrenCount > 1) {
+// ws |= 0x2000; //TCS_OWNERDRAWFIXED
+ TabCtrl_SetPadding(dat->hwndTabs, GetSystemMetrics(SM_CXEDGE) + 12, GetSystemMetrics(SM_CYEDGE) + 1);
+ } else {
+ TabCtrl_SetPadding(dat->hwndTabs, GetSystemMetrics(SM_CXEDGE) + 4, GetSystemMetrics(SM_CYEDGE) + 1);
+ }
+}
+
+static void AddChild(ParentWindowData *dat, HWND hwnd, HANDLE hContact)
+{
+ TCITEM tci;
+ int tabId;
+ MessageWindowTabData *mwtd = (MessageWindowTabData *) mir_alloc(sizeof(MessageWindowTabData));
+ mwtd->hwnd = hwnd;
+ mwtd->hContact = hContact;
+ mwtd->szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ mwtd->parent = dat;
+ dat->childrenCount++;
+ tci.mask = TCIF_PARAM | TCIF_IMAGE | TCIF_TEXT;
+ tci.lParam = (LPARAM) mwtd;
+ tci.iImage = -1;
+ tci.pszText = _T("");
+ tabId = TabCtrl_InsertItem(dat->hwndTabs, dat->childrenCount-1, &tci);
+// ActivateChild(dat, mdat->hwnd);
+ UpdateTabsPadding(dat);
+ SetWindowPos(mwtd->hwnd, HWND_TOP, dat->childRect.left, dat->childRect.top, dat->childRect.right-dat->childRect.left, dat->childRect.bottom - dat->childRect.top, SWP_HIDEWINDOW);
+ SendMessage(dat->hwnd, WM_SIZE, 0, 0);
+
+ if (MyEnableThemeDialogTexture)
+ MyEnableThemeDialogTexture(hwnd, ETDT_ENABLETAB);
+}
+
+static void RemoveChild(ParentWindowData *dat, HWND child)
+{
+ int tab = GetTabFromHWND(dat, child);
+ if (tab >= 0) {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM | TCIF_IMAGE;
+ TabCtrl_GetItem(dat->hwndTabs, tab, &tci);
+ TabCtrl_DeleteItem(dat->hwndTabs, tab);
+ mir_free((MessageWindowTabData *) tci.lParam);
+ dat->childrenCount--;
+ if (child == dat->hwndActive) {
+ if (tab == TabCtrl_GetItemCount(dat->hwndTabs)) tab--;
+ if (tab >=0 ) {
+ ActivateChild(dat, GetChildFromTab(dat->hwndTabs, tab)->hwnd);
+ }
+ else
+ dat->hwndActive = NULL;
+ }
+ UpdateTabsPadding(dat);
+ ReleaseIcon(tci.iImage);
+ }
+}
+
+static void CloseOtherChilden(ParentWindowData *dat, HWND child)
+{
+ int i;
+ ActivateChild(dat, child);
+ for (i=dat->childrenCount-1;i>=0;i--) {
+ MessageWindowTabData *mwtd = GetChildFromTab(dat->hwndTabs, i);
+ if (mwtd != NULL && mwtd->hwnd != child) {
+ SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0);
+ }
+ }
+ UpdateTabsPadding(dat);
+ ActivateChild(dat, child);
+}
+
+static void ActivateNextChild(ParentWindowData *dat, HWND child)
+{
+ int i = GetTabFromHWND(dat, child);
+ int l = TabCtrl_GetItemCount(dat->hwndTabs);
+ i = (i+1) % l;
+ ActivateChild(dat, GetChildFromTab(dat->hwndTabs, i)->hwnd);
+}
+
+static void ActivatePrevChild(ParentWindowData *dat, HWND child)
+{
+ int i = GetTabFromHWND(dat, child);
+ int l = TabCtrl_GetItemCount(dat->hwndTabs);
+ i = (i+l-1) % l;
+ ActivateChild(dat, GetChildFromTab(dat->hwndTabs, i)->hwnd);
+}
+
+static void ActivateChildByIndex(ParentWindowData *dat, int index)
+{
+ int l = TabCtrl_GetItemCount(dat->hwndTabs);
+ if (index < l) {
+ MessageWindowTabData *mwtd = GetChildFromTab(dat->hwndTabs, index);
+ if (mwtd != NULL) {
+ ActivateChild(dat, mwtd->hwnd);
+ }
+ }
+}
+
+static void SetContainerWindowStyle(ParentWindowData *dat)
+{
+ DWORD ws;
+ RECT rc;
+ if (!(dat->flags2 & SMF2_SHOWSTATUSBAR)) {
+ ShowWindow(dat->hwndStatus, SW_HIDE);
+ } else {
+ ShowWindow(dat->hwndStatus, SW_SHOW);
+ }
+ ws = GetWindowLongPtr(dat->hwnd, GWL_STYLE) & ~(WS_CAPTION);
+ if (dat->flags2 & SMF2_SHOWTITLEBAR) {
+ ws |= WS_CAPTION;
+ }
+ SetWindowLongPtr(dat->hwnd, GWL_STYLE, ws);
+
+ ws = GetWindowLongPtr(dat->hwnd, GWL_EXSTYLE)& ~WS_EX_LAYERED;
+ ws |= dat->flags2 & SMF2_USETRANSPARENCY ? WS_EX_LAYERED : 0;
+ SetWindowLongPtr(dat->hwnd , GWL_EXSTYLE , ws);
+ if (dat->flags2 & SMF2_USETRANSPARENCY) {
+ pSetLayeredWindowAttributes(dat->hwnd, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA);
+ }
+
+ ws = GetWindowLongPtr(dat->hwndTabs, GWL_STYLE) & ~(TCS_BOTTOM | 0x2000);
+ if (dat->flags2 & SMF2_TABSATBOTTOM) {
+ ws |= TCS_BOTTOM;
+ }
+ ws |= 0x2000; //TCS_OWNERDRAWFIXED
+ if (dat->childrenCount > 1) {
+// ws |= 0x2000; //TCS_OWNERDRAWFIXED
+ TabCtrl_SetPadding(dat->hwndTabs, GetSystemMetrics(SM_CXEDGE) + 12, GetSystemMetrics(SM_CYEDGE) + 1);
+ } else {
+ TabCtrl_SetPadding(dat->hwndTabs, GetSystemMetrics(SM_CXEDGE) + 4, GetSystemMetrics(SM_CYEDGE) + 1);
+ }
+ SetWindowLongPtr(dat->hwndTabs, GWL_STYLE, ws);
+ GetWindowRect(dat->hwnd, &rc);
+ SetWindowPos(dat->hwnd, 0, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
+ 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 = DBGetContactSettingByte(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 = DBGetContactSettingByte(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);
+
+// hSContact = !(dat->flags2 & SMF2_USETABS) && savePerContact ? dat->hContact : NULL;
+ hSContact = savePerContact ? dat->hContact : NULL;
+ dat->bTopmost = DBGetContactSettingByte(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);
+ }
+// if (!(dat->flags2 & SMF2_USETABS)) {
+ if (!savePerContact && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE))
+ WindowList_Broadcast(g_dat->hParentWindowList, DM_CASCADENEWWINDOW, (WPARAM) hwndDlg, (LPARAM) &dat->windowWasCascaded);
+ // }
+ 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 {
+ 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;
+ SIZE size;
+ 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;
+ 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;
+ }
+ }
+ GetMinimunWindowSize(dat, &size);
+ mmi->ptMinTrackSize.x = size.cx;
+ mmi->ptMinTrackSize.y = size.cy;
+ return FALSE;
+ }
+
+ case WM_SIZE:
+ if (wParam == SIZE_MINIMIZED) {
+ dat->bMinimized = 1;
+ }
+ 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 {
+// }
+// if (!IsIconic(hwndDlg)) {
+ 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 WM_SETFOCUS:
+ if (dat->hwndActive != NULL) {
+ SetFocus(dat->hwndActive);
+ }
+ return TRUE;
+ case WM_CLOSE:
+ if (g_dat->flags2 & SMF2_HIDECONTAINERS && dat->childrenCount > 0) {
+ ShowWindow(hwndDlg, SW_HIDE);
+ } else {
+ DestroyWindow(hwndDlg);
+ }
+ return TRUE;
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ 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;
+ } else 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;
+ }
+ switch (LOWORD(wParam)) {
+ case IDCANCEL:
+ //DestroyWindow(hwndDlg);
+ 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;
+ int tabId, x, y;
+ GetCursorPos(&thinfo.pt);
+ x = thinfo.pt.x;
+ y = thinfo.pt.y;
+ ScreenToClient(dat->hwndTabs, &thinfo.pt);
+ 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);
+ }
+ }
+ break;
+ }
+ } else if (pNMHDR->hwndFrom == dat->hwndStatus) {
+ switch (pNMHDR->code) {
+ case NM_CLICK:
+// case NM_RCLICK:
+ {
+ 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;
+ }
+ }
+ }
+ }
+ break;
+ case WM_DROPFILES:
+ SendMessage(dat->hwndActive, WM_DROPFILES, wParam, lParam);
+ break;
+ case WM_TIMER:
+ if (wParam == TIMERID_FLASHWND) {
+ if (dat->nFlash < 2 * dat->nFlashMax) {
+ FlashWindow(hwndDlg, TRUE);
+ dat->nFlash++;
+ } else {// || ((GetActiveWindow() == hwndDlg) && (GetForegroundWindow() == hwndDlg))) {
+ KillTimer(hwndDlg, TIMERID_FLASHWND);
+ FlashWindow(hwndDlg, FALSE);
+ }
+ }
+ break;
+ case WM_CONTEXTMENU:
+ if (dat->hwndStatus && dat->hwndStatus == (HWND) wParam) {
+ RECT rc;
+ POINT pt, pt2;
+ GetCursorPos(&pt);
+ pt2.x = pt.x;
+ pt2.y = pt.y;
+ ScreenToClient(dat->hwndStatus, &pt);
+
+ 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 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) {
+ pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->inactiveAlpha), LWA_ALPHA);
+// RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+ }
+ 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) {
+ pSetLayeredWindowAttributes(hwndDlg, RGB(255,255,255), (BYTE)(255-g_dat->activeAlpha), LWA_ALPHA);
+// RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ if (!IsZoomed(hwndDlg)) {
+ POINT pt;
+ GetCursorPos(&pt);
+ // dat->mouseLBDown = 1;
+ // GetCursorPos(&dat->mouseLBDownPos);
+ return SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y));
+ // SetCapture(hwndDlg);
+
+ }
+ break;
+ 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);
+// SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 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:
+ {
+ WINDOWPLACEMENT wp = { 0 };
+ HANDLE hContact;
+ int i;
+ char szSettingName[64];
+ char *szNamePrefix;
+ int savePerContact = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT);
+ for (i=dat->childrenCount;--i>=0;) {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM | TCIF_IMAGE;
+ TabCtrl_GetItem(dat->hwndTabs, i, &tci);
+ TabCtrl_DeleteItem(dat->hwndTabs, i);
+ mir_free((MessageWindowTabData *) tci.lParam);
+ ReleaseIcon(tci.iImage);
+ }
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
+ WindowList_Remove(g_dat->hParentWindowList, hwndDlg);
+ if (savePerContact)
+// if (!(dat->flags2 & SMF2_USETABS) && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT))
+ hContact = dat->hContact;
+ else
+ hContact = NULL;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(hwndDlg, &wp);
+ szNamePrefix = (!savePerContact && dat->isChat) ? "chat" : "";
+ if (!dat->windowWasCascaded) {
+ wsprintfA(szSettingName,"%sx",szNamePrefix);
+ DBWriteContactSettingDword(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.left);
+ wsprintfA(szSettingName,"%sy",szNamePrefix);
+ DBWriteContactSettingDword(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.top);
+ }
+ wsprintfA(szSettingName,"%swidth",szNamePrefix);
+ DBWriteContactSettingDword(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.right - wp.rcNormalPosition.left);
+ wsprintfA(szSettingName,"%sheight",szNamePrefix);
+ DBWriteContactSettingDword(hContact, SRMMMOD, szSettingName, wp.rcNormalPosition.bottom - wp.rcNormalPosition.top);
+ DBWriteContactSettingByte(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;
+ }
+ UnsubclassTabCtrl(dat->hwndTabs);
+ mir_free(dat);
+ }
+ break;
+ case DM_ERRORDECIDED:
+ break;
+ case CM_STARTFLASHING:
+ if ((GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg)) {// && !(g_dat->flags2 & SMF2_STAYMINIMIZED)) {
+ dat->nFlash = 0;
+ SetTimer(hwndDlg, TIMERID_FLASHWND, TIMEOUT_FLASHWND, NULL);
+ }
+ break;
+ case CM_POPUPWINDOW:
+ EnableWindow(hwndDlg, TRUE);
+ if (wParam) { /* incoming message */
+ if (g_dat->flags & SMF_STAYMINIMIZED) {
+ if (!IsWindowVisible(hwndDlg)) {
+ ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE);
+ }
+ if (dat->childrenCount == 1 ||
+ ((g_dat->flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(hwndDlg) || GetForegroundWindow() != hwndDlg))) {
+ SendMessage(hwndDlg, CM_ACTIVATECHILD, 0, (LPARAM) lParam);
+ }
+ } else {
+ if (IsIconic(hwndDlg)) {
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ } else {
+ ShowWindow(hwndDlg, SW_SHOWNA);
+ }
+ if (dat->childrenCount == 1 ||
+ ((g_dat->flags2 & SMF2_SWITCHTOACTIVE) && (IsIconic(hwndDlg) || GetForegroundWindow() != hwndDlg))) {
+ SendMessage(hwndDlg, CM_ACTIVATECHILD, 0, (LPARAM)lParam);
+ }
+ SetWindowPos(hwndDlg, HWND_TOP, 0,0,0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
+ //SetForegroundWindow(hwndDlg);
+ }
+ } else { /* outgoing message */
+ if (IsIconic(hwndDlg)) {
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ } else {
+ ShowWindow(hwndDlg, SW_SHOW);
+ }
+ SetForegroundWindow(hwndDlg);
+ SetFocus((HWND) lParam);
+ }
+ break;
+ 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:
+// if ((HWND) lParam != dat->hwndActive) {
+ 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:
+ {
+ int i;
+ for (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);
+ //RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+ 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)) { //swt() flickers even if the title hasn't actually changed
+ SetWindowText(hwndDlg, tbd->pszText);
+ //SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ }
+ }
+ 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->lpVtbl->SetOverlayIcon(pTaskbarInterface, hwndDlg, tbd->hIconNot, L"");
+ }
+ }
+ 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);
+ }
+ break;
+ }
+ case DM_STATUSICONCHANGE:
+ SendMessage(dat->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_OWNERDRAW) | 2, (LPARAM)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;
+ }
+ }
+ }
+ 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 DM_SWITCHINFOBAR:
+ {
+ int i;
+ dat->flags2 ^= SMF2_SHOWINFOBAR;
+ for (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;
+ if (!(dat->flags2 & SMF2_SHOWSTATUSBAR)) {
+ ShowWindow(dat->hwndStatus, SW_HIDE);
+ } else {
+ ShowWindow(dat->hwndStatus, SW_SHOW);
+ }
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ break;
+ case DM_SWITCHTOOLBAR:
+ {
+ int i;
+ dat->flags2 ^= SMF2_SHOWTOOLBAR;
+ for (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);
+// SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ RedrawWindow(hwndDlg, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ break;
+ case DM_CASCADENEWWINDOW:
+ if ((HWND) wParam == hwndDlg)
+ break;
+ {
+ 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;
+ //case DM_MESSAGESENDING:
+ // dat->messagesInProgress += wParam ? -1 : 1;
+ // if (dat->messagesInProgress < 0) dat->messagesInProgress = 0;
+ // break;
+ }
+ return FALSE;
+}
+
+static void DrawTab(ParentWindowData *dat, HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+ TabCtrlData *tcdat;
+ TCITEM tci;
+ LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) lParam;
+ int iTabIndex = lpDIS->itemID;
+ tcdat = (TabCtrlData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ if (iTabIndex >= 0) {
+ HANDLE hTheme = NULL;
+ int tstate;
+ TCHAR szLabel[1024];
+ 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 (!MyIsAppThemed || !MyIsAppThemed()) {
+ 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 = MyOpenThemeData(hwnd, L"TAB");
+ if(MyIsThemeBackgroundPartiallyTransparent(hTheme, TABP_TABITEM, tstate))
+ MyDrawThemeParentBackground(hwnd, lpDIS->hDC, &rectTab);
+ MyDrawThemeBackground(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->childrenCount > 1) {
+ 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->childrenCount > 1) {
+ 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) {
+
+ MyDrawThemeText(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) MyCloseThemeData(hTheme);
+ }
+ }
+}
+
+BOOL CALLBACK TabCtrlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TabCtrlData *dat;
+ dat = (TabCtrlData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ 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;
+ case WM_MBUTTONDOWN:
+ {
+ TCITEM tci;
+ int tabId;
+ MessageWindowTabData *mwtd;
+ TCHITTESTINFO thinfo;
+ thinfo.pt.x = LOWORD(lParam);
+ thinfo.pt.y = HIWORD(lParam);
+ tabId = TabCtrl_HitTest(hwnd, &thinfo);
+ if (tabId >= 0) {
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(hwnd, tabId, &tci);
+ mwtd = (MessageWindowTabData *) tci.lParam;
+ if (mwtd != NULL) {
+ SendMessage(mwtd->hwnd, WM_CLOSE, 0, 0);
+ dat->srcTab = -1;
+ }
+ }
+ return 0;
+ }
+ case WM_LBUTTONDBLCLK:
+ {
+ TCHITTESTINFO thinfo;
+ int tabId;
+ 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;
+ case WM_LBUTTONDOWN:
+ if (!dat->bDragging) {
+ TCHITTESTINFO thinfo;
+ FILETIME ft;
+ thinfo.pt.x = LOWORD(lParam);
+ thinfo.pt.y = HIWORD(lParam);
+ dat->srcTab = TabCtrl_HitTest(hwnd, &thinfo);
+ 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;
+ }
+ break;
+ case WM_CAPTURECHANGED:
+ case WM_LBUTTONUP:
+ if (dat->bDragging) {
+ TCHITTESTINFO thinfo;
+ 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';
+ 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++;
+ }
+ }
+ 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) {
+ MessageWindowTabData *mwtd;
+ TCITEM tci;
+ POINT pt;
+ NewMessageWindowLParam newData = { 0 };
+ dat->destTab = -1;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(hwnd, dat->srcTab, &tci);
+ mwtd = (MessageWindowTabData *) tci.lParam;
+ if (mwtd != NULL) {
+ HWND hChild = mwtd->hwnd;
+ HANDLE hContact = mwtd->hContact;
+ HWND hParent;
+ GetCursorPos(&pt);
+ hParent = WindowFromPoint(pt);
+ while (GetParent(hParent) != NULL) {
+ hParent = GetParent(hParent);
+ }
+ 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) {
+ MONITORINFO mi;
+ HMONITOR hMonitor;
+ 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 = MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
+ 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);
+ }
+ } else if (dat->srcTab >= 0 && TabCtrl_GetItemCount(hwnd) > 1) {
+ 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;
+ COLORREF color1, color2;
+ 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 = 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);
+ 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);
+ 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);
+ }
+ dat->bDragged = FALSE;
+ dat->bDragging = FALSE;
+ dat->destTab = -1;
+ ReleaseCapture();
+ }
+ break;
+ case WM_MOUSEMOVE:
+ if (wParam & MK_LBUTTON) {
+ if (dat->bDragging) {
+ FILETIME ft;
+ TCHITTESTINFO thinfo;
+ 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;
+ HDC hDC, hMemDC;
+ HBITMAP hBitmap, hOldBitmap;
+ 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 = GetDC(hwnd);
+ hMemDC = CreateCompatibleDC(hDC);
+ hBitmap = CreateCompatibleBitmap(hDC, rect.right, rect.bottom);
+ hOldBitmap = 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 {
+ TCHITTESTINFO thinfo;
+ POINT pt;
+ int newDest;
+ GetCursorPos(&pt);
+ thinfo.pt = pt;
+ ScreenToClient(hwnd, &thinfo.pt);
+ newDest = TabCtrl_HitTest(hwnd, &thinfo);
+ if (thinfo.flags == TCHT_NOWHERE) {
+ newDest = -1;
+ }
+ 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;
+ }
+ }
+ break;
+ case EM_UNSUBCLASSED:
+ mir_free(dat);
+ return 0;
+ }
+ return CallWindowProc(OldTabCtrlProc, hwnd, msg, wParam, lParam);
+}
+
+
+int ScriverRestoreWindowPosition(HWND hwnd,HANDLE hContact,const char *szModule,const char *szNamePrefix, int flags, int showCmd)
+{
+ RECT rcDesktop;
+ WINDOWPLACEMENT wp;
+ char szSettingName[64];
+ int x,y;
+ MONITORINFO mi;
+ HMONITOR hMonitor;
+// SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 0);
+ wp.length=sizeof(wp);
+ GetWindowPlacement(hwnd,&wp);
+ wsprintfA(szSettingName,"%sx",szNamePrefix);
+ x=DBGetContactSettingDword(hContact,szModule,szSettingName,-1);
+ wsprintfA(szSettingName,"%sy",szNamePrefix);
+ y=(int)DBGetContactSettingDword(hContact,szModule,szSettingName,-1);
+ if(x==-1) return 1;
+ if(flags&RWPF_NOSIZE) {
+ OffsetRect(&wp.rcNormalPosition,x-wp.rcNormalPosition.left,y-wp.rcNormalPosition.top);
+ } else {
+ wp.rcNormalPosition.left=x;
+ wp.rcNormalPosition.top=y;
+ wsprintfA(szSettingName,"%swidth",szNamePrefix);
+ wp.rcNormalPosition.right=wp.rcNormalPosition.left+DBGetContactSettingDword(hContact,szModule,szSettingName,-1);
+ wsprintfA(szSettingName,"%sheight",szNamePrefix);
+ wp.rcNormalPosition.bottom=wp.rcNormalPosition.top+DBGetContactSettingDword(hContact,szModule,szSettingName,-1);
+ }
+ wp.flags=0;
+ wp.showCmd = showCmd;
+
+ hMonitor = MonitorFromRect(&wp.rcNormalPosition, MONITOR_DEFAULTTONEAREST);
+ mi.cbSize = sizeof(mi);
+ GetMonitorInfo(hMonitor, &mi);
+ rcDesktop = mi.rcWork;
+ if (wp.rcNormalPosition.left > rcDesktop.right || wp.rcNormalPosition.top > rcDesktop.bottom
+ || wp.rcNormalPosition.right < rcDesktop.left || wp.rcNormalPosition.bottom < rcDesktop.top) return 1;
+ SetWindowPlacement(hwnd,&wp);
+ return 0;
+}
+
+HWND GetParentWindow(HANDLE hContact, BOOL bChat) {
+ NewMessageWindowLParam newData = { 0 };
+ newData.hContact = hContact;
+ newData.isChat = bChat;
+ if (g_dat->flags2 & SMF2_USETABS) {
+ if (!bChat || !(g_dat->flags2 & SMF2_SEPARATECHATSCONTAINERS)) {
+ if (g_dat->lastParent != NULL) {
+ int tabsNum = (int) SendMessage(g_dat->lastParent->hwnd, CM_GETCHILDCOUNT, 0, 0);
+ if (!(g_dat->flags2 & SMF2_LIMITTABS) || tabsNum < g_dat->limitTabsNum) {
+ return g_dat->lastParent->hwnd;
+ }
+ }
+ } else {
+ if (g_dat->lastChatParent != NULL) {
+ int tabsNum = (int) SendMessage(g_dat->lastChatParent->hwnd, CM_GETCHILDCOUNT, 0, 0);
+ if (!(g_dat->flags2 & SMF2_LIMITCHATSTABS) || tabsNum < g_dat->limitChatsTabsNum) {
+ return g_dat->lastChatParent->hwnd;
+ }
+ }
+ }
+ }
+ if (!(g_dat->flags2 & SMF2_SEPARATECHATSCONTAINERS)) {
+ newData.isChat =FALSE;
+ }
+ return CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGWIN), NULL, DlgProcParentWindow, (LPARAM) & newData);
+}