diff options
Diffstat (limited to 'plugins/Console/src')
| -rw-r--r-- | plugins/Console/src/Console.cpp | 1430 | ||||
| -rw-r--r-- | plugins/Console/src/commonheaders.cpp | 24 | ||||
| -rw-r--r-- | plugins/Console/src/commonheaders.h | 68 | ||||
| -rw-r--r-- | plugins/Console/src/init.cpp | 74 | ||||
| -rw-r--r-- | plugins/Console/src/resource.h | 58 | ||||
| -rw-r--r-- | plugins/Console/src/version.h | 41 | 
6 files changed, 1695 insertions, 0 deletions
diff --git a/plugins/Console/src/Console.cpp b/plugins/Console/src/Console.cpp new file mode 100644 index 0000000000..b04be4dc39 --- /dev/null +++ b/plugins/Console/src/Console.cpp @@ -0,0 +1,1430 @@ +/*
 +
 +Miranda IM: the free IM client for Microsoft* Windows*
 +
 +Copyright 2000-2008 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"
 +
 +#define MS_CONSOLE_SHOW_HIDE "Console/Show/Hide"
 +
 +#define DEFAULT_WRAPLEN 90
 +#define MIN_WRAPLEN     25
 +#define MAX_WRAPLEN     255
 +
 +#define MIN_LIMIT       1000
 +#define MAX_LIMIT       1000000
 +
 +#define IMG_EMPTY       0
 +#define IMG_ARROW       1
 +#define IMG_IN          2
 +#define IMG_OUT         3
 +#define IMG_INFO        4
 +
 +#define LOGICONX_SIZE  10
 +#define LOGICONY_SIZE  10
 +
 +#define ICON_FIRST     3
 +
 +#define ICON_NOSCROLL  1
 +#define ICON_PAUSED    2
 +#define ICON_SCROLL    3
 +#define ICON_STARTED   4
 +
 +#define HM_DUMP        (WM_USER+10)
 +#define HM_ADD         (WM_USER+11)
 +#define HM_REMOVE      (WM_USER+12)
 +#define HM_SETFONT     (WM_USER+13)
 +#define HM_SETCOLOR    (WM_USER+14)
 +#define HM_PAUSEALL    (WM_USER+15)
 +#define HM_RESTART     (WM_USER+16)
 +
 +
 +typedef struct {
 +	const char* pszHead;
 +	const char* pszMsg;
 +} LOGMSG;
 +
 +
 +typedef struct {
 +	char szModule[128];
 +	TCHAR szMsg[1];
 +} DUMPMSG;
 +
 +
 +typedef struct {
 +	HWND hwnd;
 +	HWND hList;
 +	char *Module;
 +	int Scroll;
 +	int Paused;
 +	int newline;
 +} LOGWIN;
 +
 +
 +
 +static SortedList lModules = {0};
 +
 +static LOGWIN *pActive = NULL;
 +static int tabCount = 0;
 +static RECT rcTabs = {0};
 +static HWND hTabs = NULL;
 +static HWND hwndConsole = NULL;
 +
 +static HIMAGELIST gImg = NULL;
 +static HFONT hfLogFont = NULL;
 +
 +static int gIcons = 0;
 +static int gVisible = 0;
 +static int gSingleMode = 0;
 +static int gLimit = 0;
 +static int gSeparator = 0;
 +
 +static DWORD gWrapLen = DEFAULT_WRAPLEN;
 +
 +static DWORD OutMsgs = 0;
 +static DWORD InMsgs = 0;
 +
 +static HICON hIcons[15] = {0};
 +static HANDLE hMenu = NULL;
 +
 +static void LoadSettings();
 +static void ShowConsole(int show);
 +static INT_PTR ShowHideConsole(WPARAM wParam, LPARAM lParam);
 +static int Openfile(TCHAR *outputFile, int selection);
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +static HANDLE hTTBButt = 0;
 +
 +static INT_PTR HideConsoleButt(WPARAM wParam,LPARAM lParam)
 +{
 +	ShowConsole(0);
 +	return 0;
 +}
 +
 +static INT_PTR ShowConsoleButt(WPARAM wParam,LPARAM lParam)
 +{
 +	ShowConsole(1);
 +	return 0;
 +}
 +
 +static int OnTTBLoaded(WPARAM wParam,LPARAM lParam)
 +{
 +	if ( !IsWindow(hwndConsole))
 +		return 0;
 +
 +	int state = IsWindowVisible(hwndConsole);
 +
 +	CreateServiceFunction("Console/Hide", HideConsoleButt);
 +	CreateServiceFunction("Console/Show", ShowConsoleButt);
 +
 +	TTBButton ttbb = {0};
 +	ttbb.cbSize = sizeof(ttbb);
 +
 +	TCHAR szModuleFileName[MAX_PATH]={0};
 +	GetModuleFileName(hInst, szModuleFileName, SIZEOF(szModuleFileName));
 +
 +	SKINICONDESC sid={0};
 +	sid.cbSize = sizeof(sid);
 +	sid.pszSection = "Console";
 +	sid.ptszDefaultFile = szModuleFileName;
 +	sid.flags = SIDF_PATH_TCHAR;
 +	sid.pszDescription = "Show";
 +	sid.pszName = "Console_Up";
 +	sid.iDefaultIndex = -IDI_BTN_UP;
 +	ttbb.hIconHandleUp = Skin_AddIcon(&sid);
 +
 +	sid.pszDescription = "Hide";
 +	sid.pszName = "Console_Down";
 +	sid.iDefaultIndex = -IDI_BTN_DN;
 +	ttbb.hIconHandleDn = Skin_AddIcon(&sid);
 +
 +	ttbb.dwFlags = (state ? TTBBF_PUSHED : 0) | TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP;
 +	ttbb.pszService = "Console/Hide";
 +	ttbb.name = LPGEN("Show/Hide Console");
 +	ttbb.pszTooltipDn = LPGEN("Hide Console");
 +	ttbb.pszTooltipUp = LPGEN("Show Console");
 +	hTTBButt = TopToolbar_AddButton(&ttbb);
 +	if (hTTBButt)
 +		CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)hTTBButt, (LPARAM)(state?TTBST_PUSHED:TTBST_RELEASED));
 +
 +	return 0;
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +void ScrollDown(LOGWIN * dat) {
 +	if (dat->Scroll)
 +		ListView_EnsureVisible(dat->hList, ListView_GetItemCount(dat->hList) - 1, FALSE);
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +static void ShowConsole(int show)
 +{
 +	HWND hwnd = NULL;
 +
 +	if (!hwndConsole || !pActive) return;
 +
 +	gVisible = show;
 +
 +	if (show) {
 +		hwnd = GetForegroundWindow();
 +		if ( InMsgs == OutMsgs )
 +			ScrollDown( pActive );
 +	}
 +	ShowWindow(hwndConsole, (show)?SW_SHOW:SW_HIDE);
 +	DBWriteContactSettingByte(NULL,"Console","Show",(BYTE)((show)?1:0));
 +
 +	if (hwnd)
 +		SetForegroundWindow(hwnd);
 +
 +	if (show)
 +		RedrawWindow(pActive->hList, NULL, NULL, RDW_INVALIDATE | RDW_FRAME |RDW_UPDATENOW | RDW_ERASE);
 +
 +	if (hMenu)
 +	{
 +		CLISTMENUITEM mi = {0};
 +
 +		mi.cbSize = sizeof(mi);
 +		mi.ptszName=(show)?TranslateT("Hide Console"):TranslateT("Show Console");
 +		mi.flags = CMIM_NAME | CMIF_TCHAR;
 +		CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenu, (LPARAM)&mi);
 +	}
 +
 +	if (hTTBButt)
 +		CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)hTTBButt, (show)?TTBST_PUSHED:TTBST_RELEASED);
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +static INT_PTR ShowHideConsole(WPARAM wParam, LPARAM lParam)
 +{
 +	if (hwndConsole)
 +		ShowConsole(!IsWindowVisible(hwndConsole));
 +
 +	return 0;
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +int LogResize(HWND hwnd,LPARAM lParam,UTILRESIZECONTROL *urc)
 +{
 +	switch(urc->wId) {
 +	case IDC_LIST:
 +		ListView_SetColumnWidth(GetDlgItem(hwnd, IDC_LIST), 0, urc->dlgNewSize.cx - 25);
 +		return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT;
 +	case IDC_STARTALL:
 +	case IDC_PAUSEALL:
 +	case IDC_CLOSE:
 +		return RD_ANCHORX_RIGHT|RD_ANCHORY_TOP;
 +	default:
 +		return RD_ANCHORX_LEFT|RD_ANCHORY_TOP;
 +	}
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +typedef struct
 +{
 +	UINT control;
 +	UINT icon;
 +	int  type;
 +	TCHAR *tooltip;
 +} controlinfo;
 +
 +
 +static controlinfo ctrls[] =
 +{
 +	// IDC_SCROLL & IDC_PAUSE must be first
 +	{IDC_SCROLL, IDI_SCROLL, BUTTONSETASFLATBTN, _T("Scrolling (Ctrl+Q)")},
 +	{IDC_PAUSE, IDI_STARTED, BUTTONSETASFLATBTN, _T("Pause logging(Ctrl+P)")},
 +	{IDC_SAVE, IDI_SAVE, BUTTONSETASFLATBTN, _T("Save log to file (Ctrl+S)")},
 +	{IDC_COPY, IDI_COPY, BUTTONSETASFLATBTN, _T("Copy selected log (Ctrl+C)")},
 +	{IDC_DELETE, IDI_DELETE, BUTTONSETASFLATBTN, _T("Delete selected (Del)")},
 +	{IDC_OPTIONS, IDI_OPTIONS, BUTTONSETASFLATBTN, _T("Log options (Ctrl+O)")},
 +	{IDC_STARTALL, IDI_START, BUTTONSETASFLATBTN, _T("Start logging in all tabs")},
 +	{IDC_PAUSEALL, IDI_PAUSE, BUTTONSETASFLATBTN, _T("Pause logging in all tabs")},
 +	{IDC_CLOSE, IDI_CLOSE, BUTTONSETASFLATBTN, _T("Close tab (Ctrl+W)")},
 +};
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +static LRESULT CALLBACK SubclassProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
 +{
 +	int ctrl = GetKeyState(VK_CONTROL)&0x8000;
 +
 +	switch (msg) {
 +
 +		case WM_KEYDOWN:
 +			if ( wParam == VK_DELETE && !ctrl) {
 +				SendMessage(GetParent(hwnd), WM_COMMAND, IDC_DELETE, 0);
 +				break;
 +			}
 +
 +			if (wParam == VK_LEFT && ctrl)
 +			{
 +			    NMHDR nmhdr = {0};
 +   				int tab = TabCtrl_GetCurSel(hTabs);
 +
 +				if (tab == 0)
 +					tab = TabCtrl_GetItemCount(hTabs)-1;
 +				else
 +					tab--;
 +
 +				TabCtrl_SetCurSel(hTabs, tab);
 +			    nmhdr.code = TCN_SELCHANGE;
 +			    SendMessage(hwndConsole, WM_NOTIFY, IDC_TABS, (LPARAM)&nmhdr);
 +				break;
 +			}
 +
 +			if (wParam == VK_RIGHT && ctrl)
 +			{
 +				NMHDR nmhdr = {0};
 +				int tab = TabCtrl_GetCurSel(hTabs);
 +				int count =  TabCtrl_GetItemCount(hTabs);
 +				tab = (tab + 1) % count;
 +
 +				TabCtrl_SetCurSel(hTabs, tab);
 +				nmhdr.code = TCN_SELCHANGE;
 +				SendMessage(hwndConsole, WM_NOTIFY, IDC_TABS, (LPARAM)&nmhdr);
 +				break;
 +			}
 +
 +			break;
 +
 +		case WM_CHAR:
 +/*
 +			{
 +				char t[32];
 +				sprintf(t,"%u\n",wParam);
 +				OutputDebugStringA(t);
 +			}
 +*/
 +			// CTRL
 +			if ( !(GetKeyState(VK_CONTROL)&0x8000))
 +				break;
 +
 +			switch(wParam) {
 +
 +				case 1:	// Ctrl+A
 +	   				if ( ListView_GetSelectedCount(hwnd) != (UINT)ListView_GetItemCount(hwnd))
 +						ListView_SetItemState(hwnd, -1, LVIS_SELECTED, LVIS_SELECTED);
 +					return 0;
 +
 +				case 3: // Ctrl+D
 +					SendMessage(GetParent(hwnd), WM_COMMAND, IDC_COPY, 0);
 +					return 0;
 +
 +				case 15: // Ctrl+O
 +					SendMessage(GetParent(hwnd), WM_COMMAND, IDC_OPTIONS, 0);
 +					return 0;
 +
 +				case 16: // Ctrl+P
 +					SendMessage(GetParent(hwnd), WM_COMMAND, IDC_PAUSE, 0);
 +					return 0;
 +
 +				case 17: // Ctrl+Q
 +					SendMessage(GetParent(hwnd), WM_COMMAND, IDC_SCROLL, 0);
 +					return 0;
 +
 +				case 19: // Ctrl+S
 +					SendMessage(GetParent(hwnd), WM_COMMAND, IDC_SAVE, 0);
 +					return 0;
 +
 +				case 23: // Ctrl+W
 +					SendMessage(GetParent(hwnd), WM_COMMAND, IDC_CLOSE, 0);
 +					return 0;
 +			}
 +			break;
 +   	}       
 +	return CallWindowProc((WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA),hwnd,msg,wParam,lParam);
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +static INT_PTR CALLBACK LogDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
 +{
 +
 +	LOGWIN *dat = (LOGWIN*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
 +
 +	switch(message) {
 +	case WM_INITDIALOG:
 +	{
 +		dat = (LOGWIN*)lParam;
 +
 +		dat->hwnd = hwndDlg;
 +		dat->Scroll = 1;
 +		dat->Paused = 0;
 +		dat->hList = GetDlgItem(hwndDlg, IDC_LIST);
 +
 +		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG)dat);
 +		SetWindowLongPtr(dat->hList, GWLP_USERDATA, SetWindowLongPtr(dat->hList, GWLP_WNDPROC, (LONG)SubclassProc));
 +
 +		// init buttons
 +		{
 +			int i;
 +			HWND hwnd;
 +			for(i = 0; i < SIZEOF(ctrls); i++) {
 +				hwnd = GetDlgItem(hwndDlg,ctrls[i].control);
 +				SendMessage(hwnd, ctrls[i].type, 0, 0);
 +				SendMessage(hwnd, BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[i+ICON_FIRST]);
 +				SendMessage(hwnd, BUTTONADDTOOLTIP,(WPARAM)TranslateTS(ctrls[i].tooltip), BATF_TCHAR);
 +			}
 +		}
 +
 +		CheckDlgButton(hwndDlg,IDC_SCROLL,dat->Scroll?BST_CHECKED:BST_UNCHECKED);
 +		SendDlgItemMessage(hwndDlg,IDC_SCROLL,BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[(dat->Scroll?ICON_SCROLL:ICON_NOSCROLL)]);
 +
 +		if (gSingleMode)
 +		{
 +			ShowWindow(GetDlgItem(hwndDlg, IDC_PAUSEALL), SW_HIDE);
 +			ShowWindow(GetDlgItem(hwndDlg, IDC_STARTALL), SW_HIDE);
 +			ShowWindow(GetDlgItem(hwndDlg, IDC_CLOSE), SW_HIDE);
 +		}
 +
 +		// init listview
 +		{
 +			LVITEM lvi = {0};
 +			LVCOLUMN sLC;
 +			//ListView_SetUnicodeFormat(dat->hList, TRUE);
 +			ListView_SetImageList(dat->hList, gImg, LVSIL_SMALL);
 +			sLC.mask = LVCF_FMT | LVCF_WIDTH;
 +			sLC.fmt = LVCFMT_LEFT;
 +			sLC.cx = 630;
 +			ListView_InsertColumn(dat->hList, 0, &sLC);
 +			ListView_SetExtendedListViewStyle(dat->hList, LVS_EX_FULLROWSELECT);
 +
 +			lvi.mask = LVIF_TEXT;
 +			if (gIcons)
 +			{
 +				lvi.mask |= LVIF_IMAGE;
 +				lvi.iImage = IMG_INFO;
 +			}
 +
 +			lvi.pszText = TranslateT("*** Console started ***");
 +			ListView_InsertItem(dat->hList, &lvi);
 +		}
 +
 +		SendMessage(hwndDlg, WM_SIZE, 0, 0);
 +		break;
 +	}
 +	case HM_DUMP:
 +	{
 +		// lParam = DUMPMSG
 +		if (!lParam) break;
 +		if (dat && !dat->Paused)
 +		{
 +			LVITEM lvi = {0};
 +			int last = 0x7fffffff;
 +			TCHAR szBreak;
 +			DWORD len, tmplen;
 +			DWORD wraplen = gWrapLen;
 +			TCHAR *str = ((DUMPMSG*)lParam)->szMsg;
 +
 +			lvi.iItem = 0x7fffffff;
 +
 +			str = _tcstok(str, _T("\n"));
 +
 +			if (gIcons && str != NULL)
 +			{
 +				lvi.mask = LVIF_TEXT | LVIF_IMAGE;
 +
 +				if (_tcsstr(str, _T("Data received")))
 +				{
 +					if (gSeparator) ListView_InsertItem(dat->hList, &lvi);
 +					lvi.iImage = IMG_IN;
 +				}
 +				else
 +				if (_tcsstr(str, _T("Data sent")))
 +				{
 +					if (gSeparator) ListView_InsertItem(dat->hList, &lvi);
 +					lvi.iImage = IMG_OUT;
 +				}
 +				else
 +				{
 +					if (gSeparator && dat->newline)
 +					{
 +						ListView_InsertItem(dat->hList, &lvi);
 +						dat->newline = 0;
 +					}
 +					lvi.iImage = IMG_INFO;
 +				}
 +			} else
 +				lvi.mask = LVIF_TEXT;
 +
 +			while (str != NULL)
 +			{
 +				lvi.pszText = &str[0];
 +				tmplen = len = (DWORD)_tcslen(lvi.pszText);
 +
 +				while(len > wraplen)
 +				{
 +					szBreak = lvi.pszText[wraplen];
 +					lvi.pszText[wraplen] = 0;
 +					last = ListView_InsertItem(dat->hList, &lvi);
 +					lvi.pszText[wraplen] = szBreak;
 +					len -= wraplen;
 +					lvi.pszText = &str[0] + tmplen - len;
 +
 +					dat->newline = 1;
 +					lvi.iImage = IMG_EMPTY;
 +				}
 +
 +				if (len && lvi.pszText[len-1] == '\r')
 +					lvi.pszText[len-1] = 0;
 +
 +				last = ListView_InsertItem(dat->hList, &lvi);
 +
 +				str = _tcstok(NULL, _T("\n"));
 +
 +				if (str) dat->newline = 1;
 +				lvi.iImage = IMG_EMPTY;
 +			}
 +
 +
 +			if ( gVisible && dat == pActive && dat->Scroll == 1 )
 +				ListView_EnsureVisible(dat->hList, last, FALSE);
 +
 +			if (last > gLimit)
 +			{
 +				int idx = last - gLimit + gLimit/4; // leave only 75% of LIMIT
 +
 +				while (idx >= 0)
 +				{
 +					ListView_DeleteItem(dat->hList, idx);
 +					idx--;
 +				}
 +			}
 +		}
 +
 +		mir_free((DUMPMSG*)lParam);
 +		return TRUE;
 +	}
 +	case WM_SIZE:
 +	{
 +		UTILRESIZEDIALOG urd={0};
 +		urd.cbSize=sizeof(urd);
 +		urd.hInstance=hInst;
 +		urd.hwndDlg=hwndDlg;
 +		urd.lpTemplate=MAKEINTRESOURCEA(IDD_LOG);
 +		urd.pfnResizer=LogResize;
 +		SetWindowPos(hwndDlg, HWND_TOP, rcTabs.left, rcTabs.top, rcTabs.right - rcTabs.left, rcTabs.bottom - rcTabs.top, SWP_SHOWWINDOW);
 +		CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd);
 +		break;
 +	}
 +	case WM_COMMAND:
 +	{
 +		switch(LOWORD(wParam))
 +		{
 +			if (!dat) break;
 +
 +			case IDC_PAUSE:
 +			{
 +				LVITEM lvi = {0};
 +				dat->Paused = !(dat->Paused);
 +				lvi.mask = LVIF_TEXT | LVIF_IMAGE;
 +				lvi.iImage = IMG_INFO;
 +				lvi.iItem = 0x7FFFFFFF;
 +				lvi.pszText = (dat->Paused) ? TranslateT("*** Console paused ***") : TranslateT("*** Console resumed ***");
 +				ListView_InsertItem(dat->hList, &lvi);
 +				CheckDlgButton(hwndDlg,IDC_PAUSE,(dat->Paused)?BST_CHECKED:BST_UNCHECKED);
 +				SendDlgItemMessage(hwndDlg,IDC_PAUSE,BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[((dat->Paused)?ICON_PAUSED:ICON_STARTED)]);
 +				break;
 +			}
 +			case IDC_SCROLL:
 +			{
 +				dat->Scroll = !(dat->Scroll);
 +				CheckDlgButton(hwndDlg,IDC_SCROLL,(dat->Scroll)?BST_CHECKED:BST_UNCHECKED);
 +				SendDlgItemMessage(hwndDlg,IDC_SCROLL,BM_SETIMAGE,IMAGE_ICON,(LPARAM)hIcons[((dat->Scroll)?ICON_SCROLL:ICON_NOSCROLL)]);
 +				break;
 +			}
 +			case IDC_COPY:
 +			{
 +				int idx = 0;
 +				TCHAR szText[128];
 +				TCHAR *src, *dst, *buf;
 +				int flags = LVNI_BELOW;
 +				int count = ListView_GetSelectedCount(dat->hList);
 +
 +				if (count)
 +					flags |= LVNI_SELECTED;
 +				else
 +					count = ListView_GetItemCount(dat->hList);
 +
 +				dst = buf = (TCHAR*)malloc((count*(sizeof(szText)+1)+1)*sizeof(TCHAR));
 +				if (!buf) break;
 +
 +				while ((idx = ListView_GetNextItem(dat->hList, idx, flags)) > 0)
 +				{
 +					ListView_GetItemText(dat->hList, idx, 0, szText, sizeof(szText)-1);
 +					src = szText;
 +					while (*dst++ = *src++);
 +					dst--;
 +					*dst++ = '\r';
 +					*dst++ = '\n';
 +					*dst = 0;
 +				}
 +
 +				if (dst - buf > 0 && OpenClipboard(hwndDlg)) {
 +					HGLOBAL hClipboardData;
 +					TCHAR* pchData;
 +					EmptyClipboard();
 +					if (hClipboardData = GlobalAlloc(GMEM_DDESHARE, (dst-buf+1)*sizeof(TCHAR))) {
 +						pchData = (TCHAR*)GlobalLock(hClipboardData);
 +						_tcscpy(pchData, buf);
 +						GlobalUnlock(hClipboardData);
 +						SetClipboardData(CF_UNICODETEXT,hClipboardData);
 +					}
 +					CloseClipboard();
 +				}
 +				free(buf);
 +				break;
 +			}
 +			case IDC_DELETE:
 +			{
 +				int idx = 0;
 +				int count = ListView_GetSelectedCount(dat->hList);
 +
 +				if ( !count ) break;
 +
 +				if ( count == ListView_GetItemCount(dat->hList)) {
 +					LVITEM lvi = {0};
 +					ListView_DeleteAllItems(dat->hList);
 +					lvi.mask = LVIF_TEXT | LVIF_IMAGE;
 +					lvi.iImage = IMG_INFO;
 +					lvi.pszText = TranslateT("*** Console cleared ***");
 +					ListView_InsertItem(dat->hList, &lvi);
 +					dat->newline = 0;
 +					break;
 +				}
 +
 +				while ((idx = ListView_GetNextItem(dat->hList, idx, LVNI_BELOW|LVNI_SELECTED)) > 0)
 +				{
 +					ListView_DeleteItem(dat->hList, idx);
 +					idx--;
 +				}
 +				break;
 +			}
 +			case IDC_SAVE:
 +			{
 +				FILE *fp;
 +				TCHAR szFile[MAX_PATH];
 +
 +				if (!Openfile(szFile, ListView_GetSelectedCount(dat->hList))) break;
 +
 +				fp = _tfopen(szFile, _T("wt"));
 +				if (fp) {
 +					int idx = 0;
 +					TCHAR szText[128];
 +					int flags = LVNI_BELOW;
 +					if (ListView_GetSelectedCount(dat->hList))
 +						flags |= LVNI_SELECTED;
 +
 +					while ((idx = ListView_GetNextItem(dat->hList, idx, flags)) > 0)
 +					{
 +						ListView_GetItemText(dat->hList, idx, 0, szText, SIZEOF(szText)-1);
 +						_ftprintf(fp, _T("%s\n"), szText);
 +					}
 +   					fclose(fp);
 +				}
 +				break;
 +			}
 +			case IDC_OPTIONS:
 +				CallServiceSync(MS_NETLIB_LOGWIN,0,0);
 +				break;
 +			case IDC_STARTALL:
 +				SendMessage(hwndConsole, HM_PAUSEALL, 0, 0);
 +				break;
 +			case IDC_PAUSEALL:
 +				SendMessage(hwndConsole, HM_PAUSEALL, 0, 1);
 +				break;
 +			case IDC_CLOSE:
 +				if (tabCount > 1)
 +					SendMessage(hwndDlg, WM_CLOSE, 0, 0);
 +				break;
 +			default:
 +				break;
 +		}
 +		break;
 +	}
 +	case WM_CLOSE:
 +		DestroyWindow(hwndDlg);
 +		break;
 +	case WM_DESTROY:
 +		SetWindowLongPtr(dat->hList, GWLP_WNDPROC, GetWindowLongPtr(dat->hList, GWLP_USERDATA));
 +		SendMessage(hwndConsole, HM_REMOVE, 0, (LPARAM)dat);
 +		break;
 +	}
 +
 +	return FALSE;
 +}
 +
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +int ConsoleResize(HWND hwnd,LPARAM lParam,UTILRESIZECONTROL *urc)
 +{
 +	switch(urc->wId) {
 +	case IDC_TABS:
 +		return RD_ANCHORX_WIDTH|RD_ANCHORY_HEIGHT;
 +	default:
 +		return RD_ANCHORX_LEFT|RD_ANCHORY_TOP;
 +	}
 +}
 +
 +
 +static INT_PTR CALLBACK ConsoleDlgProc(HWND hwndDlg,UINT message,WPARAM wParam,LPARAM lParam)
 +{
 +	switch(message) {
 +	case WM_INITDIALOG:
 +	{
 +		TCHAR title[MAX_PATH];
 +		TCHAR name[MAX_PATH] = {0};
 +		TCHAR path[MAX_PATH] = {0};
 +		
 +		hTabs = GetDlgItem(hwndDlg, IDC_TABS);
 +
 +		//TabCtrl_SetMinTabWidth(hTabs, 100);
 +
 +		// restore position
 +		{
 +			SAVEWINDOWPOS swp;
 +			swp.hwnd=hwndDlg; swp.hContact=NULL; swp.szModule="Console"; swp.szNamePrefix="Console";
 +			CallService(MS_UTILS_RESTOREWINDOWPOSITION, RWPF_HIDDEN, (LPARAM)&swp);
 +		}
 +
 +		CallService(MS_DB_GETPROFILENAMET,(WPARAM)MAX_PATH,(LPARAM)name);
 +
 +		CallService(MS_DB_GETPROFILEPATHT,(WPARAM)MAX_PATH,(LPARAM)path);
 +
 +		mir_sntprintf(title, MAX_PATH, _T("%s - %s\\%s"), TranslateT("Miranda Console"), path, name);
 +
 +		SetWindowText(hwndDlg, title);
 +		SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(LPARAM)hIcons[0]);
 +
 +		hwndConsole = hwndDlg;
 +		SendMessage(hwndDlg, HM_ADD, 0, 0);
 +		PostMessage(hwndDlg, WM_SIZE, 0, 0);
 +		break;
 +	}
 +	case HM_DUMP:
 +	{
 +		// lParam = DUMPMSG
 +		int idx;
 +		LOGWIN *lw;
 +		LOGWIN lw2;
 +		DUMPMSG *dumpMsg = (DUMPMSG*)lParam;
 +
 +		if (!pActive) {
 +			mir_free(dumpMsg);
 +			break;
 +		}
 +
 +		if (!gSingleMode)
 +		{
 +			lw2.Module = dumpMsg->szModule;
 +			if (!List_GetIndex(&lModules, &lw2, &idx))
 +				SendMessage(hwndDlg, HM_ADD, (WPARAM)idx, (LPARAM)dumpMsg->szModule);
 +
 +			lw = (LOGWIN*)lModules.items[idx];
 +		}
 +		else
 +			lw = pActive;
 +
 +		if (lw->hwnd)
 +			SendMessage(lw->hwnd, HM_DUMP, wParam, lParam);
 +		else
 +			PostMessage(hwndDlg, HM_DUMP, wParam, lParam); // loop msg until window will be ready
 +
 +		return TRUE;
 +	}
 +	case HM_ADD:
 +	{
 +		// wParam = index, lParam = module name
 +		LOGWIN *lw;
 +		COLORREF col;
 +		TCITEM tci = {0};
 +		int idx = (int)wParam;
 +		char *str = (char*)lParam;
 +
 +		if (!str) str = ""; // startup window
 +
 +		lw = (LOGWIN*)mir_calloc( sizeof(LOGWIN));
 +		lw->Module = (char*)mir_strdup(str);
 +		List_Insert(&lModules, lw, idx);
 +
 +		if (!gSingleMode && lParam)
 +		{
 +			tci.mask = TCIF_PARAM | TCIF_TEXT;
 +			tci.lParam = (LPARAM)lw;
 +
 +			tci.pszText = mir_a2u(lw->Module);
 +			idx = TabCtrl_InsertItem(hTabs, tabCount, &tci);
 +			mir_free(tci.pszText);
 +
 +			tabCount++;
 +		}
 +
 +		GetClientRect(hTabs, &rcTabs);
 +		TabCtrl_AdjustRect(hTabs, FALSE, &rcTabs);
 +
 +		CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_LOG), hwndDlg, LogDlgProc, (LPARAM)lw);
 +		ShowWindow(lw->hwnd, (tabCount > 1)?SW_HIDE:SW_SHOWNOACTIVATE);
 +
 +		if (pActive)
 +		{
 +			col = ListView_GetBkColor(pActive->hList);
 +			ListView_SetBkColor(lw->hList, col);
 +			ListView_SetTextBkColor(lw->hList, col);
 +
 +			col = ListView_GetTextColor(pActive->hList);
 +			ListView_SetTextColor(lw->hList, col);
 +
 +			if (hfLogFont)
 +				SendMessage(lw->hList, WM_SETFONT, (WPARAM)hfLogFont, (LPARAM)TRUE);
 +		}
 +
 +		// hide startup window
 +		if (tabCount == 1)
 +		{
 +			ShowWindow(pActive->hwnd, SW_HIDE);
 +			PostMessage(pActive->hwnd, WM_CLOSE, 0, 0);
 +			pActive = lw;
 +		}
 +
 +		if (!pActive)
 +			pActive = lw;
 +
 +		return TRUE;
 +	}
 +	case HM_REMOVE:
 +	{
 +		// lParam = LOGWIN
 +		LOGWIN *lw = (LOGWIN*)lParam;
 +
 +		if (!lw) break;
 +
 +		if (lw == pActive)
 +		{
 +			int tab = TabCtrl_GetCurSel(hTabs);
 +			if (tab >= 0)
 +			{
 +				TCITEM tci={0};
 +
 +				TabCtrl_DeleteItem(hTabs, tab);
 +				tabCount--;
 +				if (tabCount)
 +				{
 +					tab--;
 +					if (tab < 0 ) tab = 0;
 +					TabCtrl_SetCurSel(hTabs, tab);
 +
 +					tci.mask = TCIF_PARAM;
 +					TabCtrl_GetItem(hTabs, tab, &tci);
 +					pActive = (LOGWIN*)tci.lParam;
 +					SendMessage(pActive->hwnd, WM_SIZE, 0, 0);
 +					ScrollDown(pActive);
 +					ShowWindow(pActive->hwnd, SW_SHOWNOACTIVATE);
 +					SetFocus(pActive->hList);
 +				}
 +				else
 +					pActive = NULL;
 +			}
 +		}
 +
 +		List_RemovePtr(&lModules, lw);
 +		mir_free(lw->Module);
 +		mir_free(lw);
 +		return TRUE;
 +	}
 +	case HM_SETFONT:
 +	{
 +		// wParam = font, lParam = font color
 +		int i;
 +		LOGWIN *lw;
 +		for ( i = 0; i < lModules.realCount; i++ )
 +		{
 +			lw = (LOGWIN*)lModules.items[i];
 +			ListView_SetTextColor(lw->hList, (COLORREF)lParam);
 +			if (wParam)
 +				SendMessage(lw->hList, WM_SETFONT, wParam, (LPARAM)TRUE);
 +		}
 +		return TRUE;
 +	}
 +	case HM_SETCOLOR:
 +	{
 +		// wParam = font, lParam = background color
 +		int i;
 +		LOGWIN *lw;
 +		for ( i = 0; i < lModules.realCount; i++ )
 +		{
 +			lw = (LOGWIN*)lModules.items[i];
 +			ListView_SetBkColor(lw->hList, (COLORREF)lParam);
 +			ListView_SetTextBkColor(lw->hList, (COLORREF)lParam);
 +			if (wParam)
 +				SendMessage(lw->hList, WM_SETFONT, wParam, (LPARAM)TRUE);
 +		}
 +		return TRUE;
 +	}
 +	case HM_PAUSEALL:
 +	{
 +		// lParam = 1 to pause, 0 to start
 +		int i;
 +		LOGWIN *lw;
 +		for ( i = 0; i < lModules.realCount; i++ )
 +		{
 +			lw = (LOGWIN*)lModules.items[i];
 +			if (lw->Paused != (int)lParam)
 +				SendMessage(lw->hwnd, WM_COMMAND, IDC_PAUSE, 0);
 +		}
 +		return TRUE;
 +	}
 +	case HM_RESTART:
 +	{
 +		if (pActive)
 +		{
 +			pActive = NULL;
 +			PostMessage(hwndDlg, HM_RESTART, 0, 0);
 +			return TRUE;
 +		}
 +		// close all tabs
 +		if (!lParam)
 +		{
 +			LOGWIN *lw;
 +			TabCtrl_DeleteAllItems(hTabs);
 +			while ( lModules.realCount )
 +			{
 +				lw = (LOGWIN*)lModules.items[0];
 +				SendMessage(lw->hwnd, WM_CLOSE, 0, 0);
 +			}
 +			tabCount = 0;
 +			PostMessage(hwndDlg, HM_RESTART, 0, 1);
 +			return TRUE;
 +		}
 +
 +		LoadSettings();
 +		SendMessage(hwndDlg, HM_ADD, 0, 0);
 +		PostMessage(hwndDlg, WM_SIZE, 0, 0);
 +		return TRUE;
 +	}
 + 	case WM_SETFOCUS:
 +		if (pActive) {
 +			SetFocus(pActive->hList);
 +		}
 +		return TRUE;
 +	case WM_NOTIFY:
 +		switch(wParam) {
 +		case IDC_TABS:
 +			{
 +				LPNMHDR lpnmhdr = (LPNMHDR)lParam;
 +				if (lpnmhdr->code == TCN_SELCHANGE)
 +				{
 +					int newTab = TabCtrl_GetCurSel(hTabs);
 +					if (newTab >= 0 )
 +					{
 +						TCITEM tci={0};
 +						HWND hOld = pActive->hwnd;
 +
 +						tci.mask = TCIF_PARAM;
 +
 +						if (!TabCtrl_GetItem(hTabs, newTab, &tci)) break;
 +
 +						pActive = (LOGWIN*)tci.lParam;
 +
 +						SendMessage(pActive->hwnd, WM_SIZE, 0, 0);
 +						ScrollDown(pActive);
 +						ShowWindow(hOld, SW_HIDE);
 +						ShowWindow(pActive->hwnd, SW_SHOWNOACTIVATE);
 +						SetFocus(pActive->hList);
 +					} else
 +						SendMessage(pActive->hwnd, WM_SIZE, 0, 0);
 +				}
 +				break;
 +			}
 +		}
 +		break;
 +	case WM_SIZE:
 +	{
 +		UTILRESIZEDIALOG urd={0};
 +		urd.cbSize=sizeof(urd);
 +		urd.hInstance=hInst;
 +		urd.hwndDlg=hwndDlg;
 +		urd.lpTemplate=MAKEINTRESOURCEA(IDD_CONSOLE);
 +		urd.pfnResizer=ConsoleResize;
 +		CallService(MS_UTILS_RESIZEDIALOG,0,(LPARAM)&urd);
 +
 +		GetClientRect(hTabs, &rcTabs);
 +		TabCtrl_AdjustRect(hTabs, FALSE, &rcTabs);
 +
 +		if ( pActive )
 +			SendMessage(pActive->hwnd, WM_SIZE, 0, 0);
 +		break;
 +	}
 +	case WM_GETMINMAXINFO:
 +	{
 +		MINMAXINFO *mmi=(MINMAXINFO*)lParam;
 +		mmi->ptMinTrackSize.x=400;
 +		mmi->ptMinTrackSize.y=200;
 +		break;
 +	}
 +	case WM_CLOSE:
 +		if ( lParam != 1 ) {
 +			Utils_SaveWindowPosition(hwndDlg,NULL,"Console","Console");
 +			ShowConsole(0);
 +			return TRUE;
 +		} else
 +			DestroyWindow(hwndDlg);
 +		break;
 +	case WM_DESTROY:
 +		pActive = NULL;
 +		if (hfLogFont) DeleteObject(hfLogFont);
 +		PostQuitMessage(0);
 +		break;
 +	}
 +
 +	return FALSE;
 +}
 +
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +
 +void __cdecl ConsoleThread(void* arg)
 +{
 +	MSG msg;
 +	HWND hwnd;
 +
 +	hwnd = CreateDialog(hInst,MAKEINTRESOURCE(IDD_CONSOLE),NULL,ConsoleDlgProc);
 +
 +	if (!hwnd) return;
 +
 +	while( GetMessage(&msg, NULL, 0, 0) > 0 )
 +	{
 +		switch(msg.message) {
 +		case HM_DUMP:
 +			OutMsgs++;
 +			break;
 +		}
 +
 +		if ( IsDialogMessage(hwnd, &msg))
 +			continue;
 +
 +		TranslateMessage(&msg);
 +		DispatchMessage(&msg);
 +	}
 +
 +	hwndConsole = NULL;
 +}
 +
 +///////////////////////////////////////////////////////////////////////////////
 +
 +static int OnFastDump(WPARAM wParam,LPARAM lParam)
 +{
 +	if ( pActive )
 +	{
 +		LOGMSG *logMsg = (LOGMSG*)lParam;
 +		DWORD headlen = (DWORD)strlen(logMsg->pszHead);
 +		DWORD msglen = (DWORD)strlen(logMsg->pszMsg);
 +		DWORD len = (headlen + msglen + 1) * sizeof(TCHAR) + sizeof(DUMPMSG);
 +		DUMPMSG *dumpMsg = (DUMPMSG*)mir_alloc( len );
 +		TCHAR *str = dumpMsg->szMsg;
 +
 +		strncpy(dumpMsg->szModule, ((NETLIBUSER*)wParam)->szDescriptiveName, sizeof(dumpMsg->szModule))[ sizeof(dumpMsg->szModule)-1 ] = 0;
 +
 +		{
 +			wchar_t *ucs2;
 +
 +			ucs2 = mir_a2u( logMsg->pszHead );
 +			wcscpy(str, ucs2);
 +			mir_free(ucs2);
 +
 +			// try to detect utf8
 +			ucs2 = mir_utf8decodeW( logMsg->pszMsg );
 +			if ( !ucs2 )
 +				ucs2 = mir_a2u( logMsg->pszMsg );
 +
 +			wcscat( str, ucs2 );
 +			mir_free( ucs2 );
 +		}
 +
 +		InMsgs++;
 +		PostMessage(hwndConsole, HM_DUMP, 0, (LPARAM)dumpMsg);
 +	}
 +	return 0;
 +}
 +
 +///////////////////////////////////////////////////////////////////////////////
 +
 +static void LoadSettings()
 +{
 +	gIcons = DBGetContactSettingByte(NULL, "Console", "ShowIcons", 1);
 +	gSeparator = DBGetContactSettingByte(NULL, "Console", "Separator", 1);
 +	gSingleMode = DBGetContactSettingByte(NULL, "Console", "SingleMode", 0);
 +
 +	gWrapLen = DBGetContactSettingByte(NULL, "Console", "Wrap", DEFAULT_WRAPLEN);
 +	if ( gWrapLen < MIN_WRAPLEN ) gWrapLen = DEFAULT_WRAPLEN;
 +
 +	gLimit = DBGetContactSettingDword(NULL, "Console", "Limit", MAX_LIMIT);
 +	if (gLimit > MAX_LIMIT) gLimit = MAX_LIMIT;
 +	if (gLimit < MIN_LIMIT) gLimit = MIN_LIMIT;
 +}
 +
 +
 +static void SaveSettings(HWND hwndDlg)
 +{
 +	int len = GetDlgItemInt(hwndDlg, IDC_WRAP, NULL, FALSE);
 +	if (len < MIN_WRAPLEN )
 +		len = MIN_WRAPLEN;
 +	else
 +	if (len > MAX_WRAPLEN)
 +		len = MAX_WRAPLEN;
 +
 +	gWrapLen = len;
 +	SetDlgItemInt(hwndDlg, IDC_WRAP, gWrapLen, FALSE);
 +	DBWriteContactSettingByte(NULL, "Console", "Wrap", (BYTE)len);
 +
 +	len = GetDlgItemInt(hwndDlg, IDC_LIMIT, NULL, FALSE);
 +	if (len < MIN_LIMIT )
 +		len = MIN_LIMIT;
 +	else
 +	if (len > MAX_LIMIT)
 +		len = MAX_LIMIT;
 +
 +	gLimit = len;
 +	SetDlgItemInt(hwndDlg, IDC_LIMIT, gLimit, FALSE);
 +	DBWriteContactSettingDword(NULL, "Console", "Limit", len);
 +
 +	DBWriteContactSettingByte(NULL, "Console", "SingleMode", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SINGLE));
 +	DBWriteContactSettingByte(NULL, "Console", "Separator", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SEPARATOR));
 +	DBWriteContactSettingByte(NULL, "Console", "ShowIcons", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SHOWICONS));
 +
 +	DBWriteContactSettingByte(NULL, "Console", "ShowAtStart", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_START));
 +}
 +
 +
 +static INT_PTR CALLBACK OptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	switch(msg) {
 +		case WM_INITDIALOG:
 +			TranslateDialogDefault(hwndDlg);
 +			CheckDlgButton(hwndDlg, IDC_START, DBGetContactSettingByte(NULL, "Console", "ShowAtStart", 0));
 +			CheckDlgButton(hwndDlg, IDC_SINGLE, gSingleMode);
 +			CheckDlgButton(hwndDlg, IDC_SHOWICONS, gIcons);
 +			CheckDlgButton(hwndDlg, IDC_SEPARATOR, gSeparator);
 +			SetDlgItemInt(hwndDlg, IDC_WRAP, gWrapLen, FALSE);
 +			SetDlgItemInt(hwndDlg, IDC_LIMIT, gLimit, FALSE);
 +			break;
 +		case WM_COMMAND:
 +			switch (LOWORD(wParam)) {
 +				case IDC_RESTART:
 +				{
 +					if (!pActive) break;
 +					SaveSettings(hwndDlg);
 +					PostMessage(hwndConsole, HM_RESTART, 0, 0);
 +					break;
 +				}
 +				case IDC_LIMIT:
 +				case IDC_WRAP:
 +					if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
 +						return FALSE;
 +					SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
 +					break;
 +				case IDC_START:
 +				case IDC_SEPARATOR:
 +				case IDC_SHOWICONS:
 +				case IDC_SINGLE:
 +					SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
 +					break;
 +			}
 +			break;
 +		case WM_NOTIFY:
 +			switch(((LPNMHDR)lParam)->idFrom)
 +			{
 +				case 0:
 +					switch (((LPNMHDR)lParam)->code)
 +					{
 +						case PSN_APPLY:
 +						{
 +							SaveSettings(hwndDlg);
 +							break;
 +						}
 +					}
 +				break;
 +			}
 +			break;
 +	}
 +	return FALSE;
 +}
 +
 +
 +static int OptInit(WPARAM wParam,LPARAM lParam)
 +{
 +	OPTIONSDIALOGPAGE odp={0};
 +	odp.cbSize = sizeof(odp);
 +	odp.hInstance = hInst;
 +	odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
 +	odp.pszGroup = LPGEN("Network");
 +	odp.pszTitle = LPGEN("Console");
 +	odp.pfnDlgProc = OptDlgProc;
 +	odp.flags = ODPF_BOLDGROUPS;
 +	odp.expertOnlyControls = NULL;
 +	Options_AddPage(wParam, &odp);
 +	return 0;
 +}
 +
 +///////////////////////////////////////////////////////////////////////////////
 +
 +static int OnColourChange(WPARAM wParam,LPARAM lParam)
 +{
 +	if (hwndConsole)
 +	{
 +	   	ColourID cid = {0};
 +	   	COLORREF col;
 +
 +	   	cid.cbSize=sizeof(cid);
 +		strcpy(cid.group,"Console");
 +		strcpy(cid.name,"Background");
 +		strcpy(cid.dbSettingsGroup,"Console");
 +		strcpy(cid.setting,"BgColor");
 +
 +		col = (COLORREF)CallService(MS_COLOUR_GET,(WPARAM)&cid,0);
 +		if (col != -1)
 +			SendMessage(hwndConsole, HM_SETCOLOR, (WPARAM)hfLogFont, (LPARAM)col);
 +	}
 +	return 0;
 +}
 +
 +
 +static int OnFontChange(WPARAM wParam,LPARAM lParam)
 +{
 +	if (hwndConsole)
 +	{
 +	   	COLORREF col;
 +		HFONT hf = NULL;
 +		LOGFONT LogFont={0};
 +		FontIDT fid={0};
 +		fid.cbSize=sizeof(fid);
 +
 +		_tcscpy(fid.group,_T("Console"));
 +		_tcscpy(fid.name,TranslateT("Text"));
 +
 +		col = (COLORREF)CallService(MS_FONT_GETT,(WPARAM)&fid,(LPARAM)&LogFont);
 +
 +		if (LogFont.lfHeight != 0)
 +		{
 +			hf=CreateFontIndirect(&LogFont);
 +
 +			SendMessage(hwndConsole, HM_SETFONT, (WPARAM)hf, (LPARAM)col);
 +
 +			if (hfLogFont)
 +				DeleteObject(hfLogFont);
 +			hfLogFont = hf;
 +		}
 +	}
 +	return 0;
 +}
 +
 +static int OnSystemModulesLoaded(WPARAM wParam,LPARAM lParam)
 +{
 +	HookEvent( ME_NETLIB_FASTDUMP, OnFastDump );
 +
 +	CreateServiceFunction(MS_CONSOLE_SHOW_HIDE, ShowHideConsole);
 +
 +	FontIDT fid = {0};
 +	fid.cbSize = sizeof(fid);
 +	_tcscpy(fid.group,_T("Console"));
 +	_tcscpy(fid.name,TranslateT("Text"));
 +	strcpy(fid.dbSettingsGroup,"Console");
 +	strcpy(fid.prefix,"ConsoleFont");
 +	_tcscpy(fid.backgroundGroup,_T("Console"));
 +	_tcscpy(fid.backgroundName,_T("Background"));
 +	fid.flags = FIDF_DEFAULTVALID;
 +	fid.deffontsettings.charset = DEFAULT_CHARSET;
 +	fid.deffontsettings.colour = RGB(0, 0, 0);
 +	fid.deffontsettings.size = 10;
 +	fid.deffontsettings.style = 0;
 +	_tcsncpy(fid.deffontsettings.szFace, _T("Courier"), LF_FACESIZE);
 +	FontRegisterT(&fid);
 +
 +	HookEvent(ME_FONT_RELOAD,OnFontChange);
 +
 +	ColourIDT cid = {0};
 +	cid.cbSize=sizeof(cid);
 +	_tcscpy(cid.group,_T("Console"));
 +	_tcscpy(cid.name,_T("Background"));
 +	strcpy(cid.dbSettingsGroup,"Console");
 +	strcpy(cid.setting,"BgColor");
 +	cid.defcolour = RGB(255,255,255);
 +	ColourRegisterT(&cid);
 +
 +	HookEvent(ME_COLOUR_RELOAD, OnColourChange);
 +
 +	HOTKEYDESC hkd = {0};
 +	hkd.cbSize = sizeof(hkd);
 +	hkd.pszName = "Console_Show_Hide";
 +	hkd.pszDescription = LPGEN("Show/Hide Console");
 +	hkd.pszSection = "Main";
 +	hkd.pszService = MS_CONSOLE_SHOW_HIDE;
 +	hkd.DefHotKey = HOTKEYCODE(HOTKEYF_EXT, 'C');
 +	Hotkey_Register(&hkd);
 +
 +	if (hwndConsole && IsWindow(hwndConsole))
 +	{
 +		CLISTMENUITEM mi={0};
 +		HookEvent(ME_TTB_MODULELOADED, OnTTBLoaded);
 +		mi.cbSize=sizeof(mi);
 +		mi.flags=CMIF_TCHAR;
 +		mi.hIcon=hIcons[0];
 +		mi.ptszPopupName=TranslateT("&Help");
 +		mi.popupPosition=2000090000;
 +		mi.position=1000000000;
 +		mi.ptszName=(IsWindowVisible(hwndConsole))?TranslateT("Hide Console"):TranslateT("Show Console");
 +		mi.pszService=MS_CONSOLE_SHOW_HIDE;
 +		hMenu = Menu_AddMainMenuItem(&mi);
 +
 +		OnFontChange(0,0);
 +		OnColourChange(0,0);
 +
 +		if (DBGetContactSettingByte(NULL,"Console","ShowAtStart",0) || DBGetContactSettingByte(NULL,"Console","Show",1))
 +			ShowConsole(1);
 +		else
 +			ShowConsole(0);
 +	}
 +
 +	return 0;
 +}
 +
 +static int PreshutdownConsole(WPARAM wParam,LPARAM lParam)
 +{
 +	if (hwndConsole)
 +		PostMessage(hwndConsole, WM_CLOSE, 0, 1 );
 +
 +	return 0;
 +}
 +
 +///////////////////////////////////////////////////////////////////////////////
 +
 +static int stringCompare( LOGWIN *lw1, LOGWIN *lw2 )
 +{
 +	return strcmp( lw1->Module, lw2->Module );
 +}
 +
 +///////////////////////////////////////////////////////////////////////////////
 +
 +static UINT logicons[] = {IDI_EMPTY, IDI_ARROW, IDI_IN, IDI_OUT, IDI_INFO};
 +
 +
 +void InitConsole()
 +{
 +	int i;
 +	HICON hi;
 +
 +	lModules.sortFunc = (FSortFunc)stringCompare;
 +	lModules.increment = 5;
 +
 +	hIcons[0] = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONSOLE));
 +	hIcons[1] = (HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_NOSCROLL),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
 +	hIcons[2] = (HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_PAUSED),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
 +
 +	for(i = 0; i < SIZEOF(ctrls); i++) {
 +		hIcons[i+ICON_FIRST] = (HICON)LoadImage(hInst,MAKEINTRESOURCE(ctrls[i].icon),IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0);
 +	}
 +
 +   	gImg = ImageList_Create(LOGICONX_SIZE, LOGICONY_SIZE, ILC_COLOR24 | ILC_MASK, SIZEOF(logicons), 0);
 +
 +    for(i = 0; i < SIZEOF(logicons); i++)
 +    {
 +       	hi = (HICON)LoadImage(hInst,MAKEINTRESOURCE(logicons[i]),IMAGE_ICON,LOGICONX_SIZE,LOGICONY_SIZE,0);
 +		if (hi)
 +		{
 +			ImageList_AddIcon(gImg, hi);
 +			DestroyIcon(hi);
 +		}
 +	}
 +
 +	LoadSettings();
 +
 +	mir_forkthread(ConsoleThread, 0);
 +
 +	HookEvent(ME_SYSTEM_PRESHUTDOWN, PreshutdownConsole);
 +	HookEvent(ME_SYSTEM_MODULESLOADED, OnSystemModulesLoaded);
 +	HookEvent(ME_OPT_INITIALISE, OptInit);
 +	HookEvent(ME_NETLIB_FASTDUMP, OnFastDump);
 +}
 +
 +void ShutdownConsole(void)
 +{
 +	int i;
 +
 +	List_Destroy(&lModules);
 +
 +	if (gImg) ImageList_Destroy(gImg);
 +
 +	for(i = 0; i < SIZEOF(hIcons); i++) {
 +		if (hIcons[i]) DestroyIcon(hIcons[i]);
 +	}
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 +
 +TCHAR *addstring(TCHAR *str, TCHAR *add) {
 +	_tcscpy(str,add);
 +	return str + _tcslen(add) + 1;
 +}
 +
 +
 +static int Openfile(TCHAR *outputFile, int selection)
 +{
 +	OPENFILENAME ofn = {0};
 +	TCHAR filename[MAX_PATH+2] = _T("");
 +	TCHAR *title;
 +
 +	TCHAR *filter, *tmp, *tmp1, *tmp2;
 +	tmp1 = TranslateT("Text Files (*.txt)");
 +	tmp2 = TranslateT("All Files");
 +	filter = tmp = (TCHAR*)_alloca((_tcslen(tmp1)+_tcslen(tmp2)+11)*sizeof(TCHAR));
 +	tmp = addstring(tmp, tmp1);
 +	tmp = addstring(tmp, _T("*.TXT"));
 +	tmp = addstring(tmp, tmp2);
 +	tmp = addstring(tmp, _T("*"));
 +	*tmp = 0;
 +
 +	if (selection)
 +		title = TranslateT("Save selection to file");
 +	else
 +		title = TranslateT("Save log to file");
 +
 +	ofn.lStructSize = sizeof(ofn);
 +	ofn.lpstrFile = filename;
 +	ofn.lpstrFilter = filter;
 +	ofn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
 +	ofn.lpstrTitle = title;
 +	ofn.nMaxFile = MAX_PATH;
 +	ofn.lpstrDefExt = _T("txt");
 +
 +	if (!GetSaveFileName(&ofn))
 +		return 0;
 +	_tcscpy(outputFile, filename);
 +	return 1;
 +}
 +
 +////////////////////////////////////////////////////////////////////////////////
 diff --git a/plugins/Console/src/commonheaders.cpp b/plugins/Console/src/commonheaders.cpp new file mode 100644 index 0000000000..cbfb79d624 --- /dev/null +++ b/plugins/Console/src/commonheaders.cpp @@ -0,0 +1,24 @@ +/*
 +
 +Miranda IM: the free IM client for Microsoft* Windows*
 +
 +Copyright 2000-2008 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"
\ No newline at end of file diff --git a/plugins/Console/src/commonheaders.h b/plugins/Console/src/commonheaders.h new file mode 100644 index 0000000000..7689c7dce2 --- /dev/null +++ b/plugins/Console/src/commonheaders.h @@ -0,0 +1,68 @@ +/*
 +
 +Miranda IM: the free IM client for Microsoft* Windows*
 +
 +Copyright 2000-2008 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.
 +*/
 +
 +#define _CRT_SECURE_NO_WARNINGS
 +#define _WIN32_WINNT 0x0501
 +
 +#pragma comment( lib, "comctl32.lib")
 +
 +#include <windows.h>
 +#include <stdio.h>
 +#include <time.h>
 +#include <stddef.h>
 +#include <process.h>
 +#include <commctrl.h>
 +#include <Richedit.h>
 +#include <malloc.h>
 +#include <tchar.h>
 +#include <io.h>
 +#include <fcntl.h>
 +
 +#define MIRANDA_VER 0x0A00
 +
 +#include <newpluginapi.h>
 +#include <win2k.h>
 +#include <m_system.h>
 +#include <m_utils.h>
 +#include <m_netlib.h>
 +#include <m_database.h>
 +#include <m_options.h>
 +#include <m_langpack.h>
 +#include <m_clui.h>
 +#include <m_clist.h>
 +#include <m_langpack.h>
 +#include <m_button.h>
 +#include <m_fontservice.h>
 +#include <m_hotkeys.h>
 +#include <m_icolib.h>
 +#include <m_toptoolbar.h>
 +#include "resource.h"
 +
 +#include "version.h"
 +
 +extern HINSTANCE hInst;
 +
 +void InitConsole();
 +void ShutdownConsole();
 +
 +#define MS_NETLIB_LOGWIN "Netlib/Log/Win"
 diff --git a/plugins/Console/src/init.cpp b/plugins/Console/src/init.cpp new file mode 100644 index 0000000000..58943d2c6a --- /dev/null +++ b/plugins/Console/src/init.cpp @@ -0,0 +1,74 @@ +/*
 +
 +Miranda IM: the free IM client for Microsoft* Windows*
 +
 +Copyright 2000-2008 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"
 +
 +DWORD mirandaVer;
 +int hLangpack;
 +HINSTANCE hInst;
 +
 +PLUGININFOEX pluginInfoEx={
 +	sizeof(PLUGININFOEX),
 +	__PLUGIN_NAME,
 +	__VERSION_DWORD,
 +	__PLUGIN_LONGDESC,
 +	__PLUGIN_AUTHOR,
 +	__PLUGIN_EMAIL,
 +	__PLUGIN_RIGHTS,
 +	__PLUGIN_URL,
 +	UNICODE_AWARE,
 +	MIID_CONSOLE
 +};
 +
 +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
 +{
 +	hInst = hinstDLL;
 +	return TRUE;
 +}
 +
 +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
 +{
 +	return &pluginInfoEx;
 +}
 +
 +// we implement service mode interface
 +static const MUUID interfaces[] = {MIID_LOGWINDOW, MIID_LAST};
 +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
 +{
 +	return interfaces;
 +}
 +
 +extern "C" __declspec(dllexport) int Load(void)
 +{
 +	mir_getLP(&pluginInfoEx);
 +
 +	InitCommonControls();
 +	InitConsole();
 +	return 0;
 +}
 +
 +extern "C" __declspec(dllexport) int Unload(void)
 +{
 +    ShutdownConsole();
 +	return 0;
 +}
\ No newline at end of file diff --git a/plugins/Console/src/resource.h b/plugins/Console/src/resource.h new file mode 100644 index 0000000000..a8947819a4 --- /dev/null +++ b/plugins/Console/src/resource.h @@ -0,0 +1,58 @@ +//{{NO_DEPENDENCIES}}
 +// Microsoft Visual C++ generated include file.
 +// Used by resource.rc
 +//
 +#define IDI_CONSOLE_UP                  100
 +#define IDI_CONSOLE_DOWN                101
 +#define IDD_MSG                         111
 +#define IDD_CONSOLE                     112
 +#define IDD_LOG                         113
 +#define IDD_OPTIONS                     114
 +#define IDI_COPY                        402
 +#define IDI_NOSCROLL                    403
 +#define IDI_SCROLL                      404
 +#define IDI_SAVE                        405
 +#define IDI_DELETE                      406
 +#define IDI_OPTIONS                     407
 +#define IDI_PAUSED                      408
 +#define IDI_STARTED                     409
 +#define IDI_BTN_UP                      410
 +#define IDI_BTN_DN                      411
 +#define IDI_CLOSE                       412
 +#define IDI_START                       413
 +#define IDI_PAUSE                       414
 +#define IDI_IN                          415
 +#define IDI_OUT                         416
 +#define IDI_ARROW                       417
 +#define IDI_INFO                        418
 +#define IDI_EMPTY                       419
 +#define IDC_TABS                        1000
 +#define IDC_LIST                        1001
 +#define IDC_SAVE                        1002
 +#define IDC_PAUSE                       1003
 +#define IDC_SCROLL                      1004
 +#define IDC_COPY                        1005
 +#define IDC_DELETE                      1006
 +#define IDC_OPTIONS                     1007
 +#define IDI_CONSOLE                     1008
 +#define IDC_CLOSE                       1009
 +#define IDC_PAUSEALL                    1010
 +#define IDC_STARTALL                    1011
 +#define IDC_SINGLE                      1012
 +#define IDC_WRAP                        1013
 +#define IDC_SHOWICONS                   1014
 +#define IDC_SEPARATOR                   1015
 +#define IDC_LIMIT                       1016
 +#define IDC_START                       1017
 +#define IDC_RESTART                     1018
 +
 +// Next default values for new objects
 +//
 +#ifdef APSTUDIO_INVOKED
 +#ifndef APSTUDIO_READONLY_SYMBOLS
 +#define _APS_NEXT_RESOURCE_VALUE        115
 +#define _APS_NEXT_COMMAND_VALUE         40000
 +#define _APS_NEXT_CONTROL_VALUE         1019
 +#define _APS_NEXT_SYMED_VALUE           102
 +#endif
 +#endif
 diff --git a/plugins/Console/src/version.h b/plugins/Console/src/version.h new file mode 100644 index 0000000000..c91b5628e0 --- /dev/null +++ b/plugins/Console/src/version.h @@ -0,0 +1,41 @@ +/*
 +
 +Miranda IM: the free IM client for Microsoft* Windows*
 +
 +Copyright 2000-2008 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.
 +*/
 +
 +
 +#define __FILEVERSION_STRING 0,0,7,3
 +#define __VERSION_STRING     "0.0.7.3"
 +#define __VERSION_DWORD      0x00000703
 +
 +
 +#define __PLUGIN_DESC        "Console log window for Miranda"
 +#define __PLUGIN_LONGDESC    __PLUGIN_DESC ". ["__DATE__"  "__TIME__"]"
 +#define __PLUGIN_AUTHOR      "Bio"
 +#define __PLUGIN_EMAIL       "bio@ktaspb.ru"
 +#define __PLUGIN_RIGHTS      "© 2005-2012 Bio"
 +#define __PLUGIN_FILE        "Console.dll"
 +#define __PLUGIN_SHORTNAME   "Console"
 +
 +#define MIID_CONSOLE { 0x23d4f302, 0xd513, 0x45b7, { 0x90, 0x27, 0x44, 0x5f, 0x29, 0x55, 0x73, 0x11 }} // {23D4F302-D513-45b7-9027-445F29557311}
 +
 +#define __PLUGIN_NAME __PLUGIN_SHORTNAME
 +#define __PLUGIN_URL "http://addons.miranda-im.org/details.php?action=viewfile&id=3791"
  | 
