summaryrefslogtreecommitdiff
path: root/plugins/Console/src/Console.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Console/src/Console.cpp')
-rw-r--r--plugins/Console/src/Console.cpp1430
1 files changed, 1430 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;
+}
+
+////////////////////////////////////////////////////////////////////////////////