diff options
Diffstat (limited to 'miranda-wine/plugins')
67 files changed, 14116 insertions, 0 deletions
diff --git a/miranda-wine/plugins/clist/clc.h b/miranda-wine/plugins/clist/clc.h new file mode 100644 index 0000000..7b825dd --- /dev/null +++ b/miranda-wine/plugins/clist/clc.h @@ -0,0 +1,83 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 FONTID_LAST 7
+
+struct ClcContact {
+ BYTE type;
+ BYTE flags;
+ union {
+ struct {
+ WORD iImage;
+ HANDLE hContact;
+ };
+ struct {
+ WORD groupId;
+ struct ClcGroup *group;
+ };
+ };
+ BYTE iExtraImage[MAXEXTRACOLUMNS];
+ TCHAR szText[120-MAXEXTRACOLUMNS];
+ char * proto; // MS_PROTO_GETBASEPROTO
+};
+
+struct ClcData {
+ struct ClcGroup list;
+ int rowHeight;
+ int yScroll;
+ int selection;
+ struct ClcFontInfo fontInfo[FONTID_MAX+1];
+ int scrollTime;
+ HIMAGELIST himlHighlight;
+ int groupIndent;
+ TCHAR szQuickSearch[128];
+ int iconXSpace;
+ HWND hwndRenameEdit;
+ COLORREF bkColour,selBkColour,selTextColour,hotTextColour,quickSearchColour;
+ int iDragItem,iInsertionMark;
+ int dragStage;
+ POINT ptDragStart;
+ int dragAutoScrolling;
+ int dragAutoScrollHeight;
+ int leftMargin;
+ int insertionMarkHitHeight;
+ HBITMAP hBmpBackground;
+ int backgroundBmpUse,bkChanged;
+ int iHotTrack;
+ int gammaCorrection;
+ DWORD greyoutFlags; //see m_clc.h
+ DWORD offlineModes;
+ DWORD exStyle;
+ POINT ptInfoTip;
+ int infoTipTimeout;
+ HANDLE hInfoTipItem;
+ HIMAGELIST himlExtraColumns;
+ int extraColumnsCount;
+ int extraColumnSpacing;
+ int checkboxSize;
+ int showSelAlways;
+ int showIdle;
+ int noVScrollbar;
+ int useWindowsColours;
+ int needsResort;
+};
diff --git a/miranda-wine/plugins/clist/clcopts.c b/miranda-wine/plugins/clist/clcopts.c new file mode 100644 index 0000000..81f4950 --- /dev/null +++ b/miranda-wine/plugins/clist/clcopts.c @@ -0,0 +1,923 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 DBFONTF_BOLD 1
+#define DBFONTF_ITALIC 2
+#define DBFONTF_UNDERLINE 4
+
+struct CheckBoxToStyleEx_t
+{
+ int id;
+ DWORD flag;
+ int not;
+}
+
+static const checkBoxToStyleEx[] = {
+ {IDC_DISABLEDRAGDROP, CLS_EX_DISABLEDRAGDROP, 0},
+ {IDC_NOTEDITLABELS, CLS_EX_EDITLABELS, 1},
+ {IDC_SHOWSELALWAYS, CLS_EX_SHOWSELALWAYS, 0},
+ {IDC_TRACKSELECT, CLS_EX_TRACKSELECT, 0},
+ {IDC_SHOWGROUPCOUNTS, CLS_EX_SHOWGROUPCOUNTS, 0},
+ {IDC_HIDECOUNTSWHENEMPTY, CLS_EX_HIDECOUNTSWHENEMPTY, 0},
+ {IDC_DIVIDERONOFF, CLS_EX_DIVIDERONOFF, 0},
+ {IDC_NOTNOTRANSLUCENTSEL, CLS_EX_NOTRANSLUCENTSEL, 1},
+ {IDC_LINEWITHGROUPS, CLS_EX_LINEWITHGROUPS, 0},
+ {IDC_QUICKSEARCHVISONLY, CLS_EX_QUICKSEARCHVISONLY, 0},
+ {IDC_SORTGROUPSALPHA, CLS_EX_SORTGROUPSALPHA, 0},
+ {IDC_NOTNOSMOOTHSCROLLING, CLS_EX_NOSMOOTHSCROLLING, 1}
+};
+
+struct CheckBoxValues_t
+{
+ DWORD style;
+ TCHAR* szDescr;
+};
+
+static const struct CheckBoxValues_t greyoutValues[] = {
+ { GREYF_UNFOCUS, _T("Not focused") },
+ { MODEF_OFFLINE, _T("Offline") },
+ { PF2_ONLINE, _T("Online") },
+ { PF2_SHORTAWAY, _T("Away") },
+ { PF2_LONGAWAY, _T("NA") },
+ { PF2_LIGHTDND, _T("Occupied") },
+ { PF2_HEAVYDND, _T("DND") },
+ { PF2_FREECHAT, _T("Free for chat") },
+ { PF2_INVISIBLE, _T("Invisible") },
+ { PF2_OUTTOLUNCH, _T("Out to lunch") },
+ { PF2_ONTHEPHONE, _T("On the phone") }
+};
+
+static const struct CheckBoxValues_t offlineValues[] = {
+ { MODEF_OFFLINE, _T("Offline") },
+ { PF2_ONLINE, _T("Online") },
+ { PF2_SHORTAWAY, _T("Away") },
+ { PF2_LONGAWAY, _T("NA") },
+ { PF2_LIGHTDND, _T("Occupied") },
+ { PF2_HEAVYDND, _T("DND") },
+ { PF2_FREECHAT, _T("Free for chat") },
+ { PF2_INVISIBLE, _T("Invisible") },
+ { PF2_OUTTOLUNCH, _T("Out to lunch") },
+ { PF2_ONTHEPHONE, _T("On the phone") }
+};
+
+static void FillCheckBoxTree(HWND hwndTree, const struct CheckBoxValues_t *values, int nValues, DWORD style)
+{
+ TVINSERTSTRUCT tvis;
+ int i;
+
+ tvis.hParent = NULL;
+ tvis.hInsertAfter = TVI_LAST;
+ tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE;
+ for (i = 0; i < nValues; i++) {
+ tvis.item.lParam = values[i].style;
+ tvis.item.pszText = TranslateTS( values[i].szDescr );
+ tvis.item.stateMask = TVIS_STATEIMAGEMASK;
+ tvis.item.state = INDEXTOSTATEIMAGEMASK((style & tvis.item.lParam) != 0 ? 2 : 1);
+ TreeView_InsertItem( hwndTree, &tvis);
+} }
+
+static DWORD MakeCheckBoxTreeFlags(HWND hwndTree)
+{
+ DWORD flags = 0;
+ TVITEM tvi;
+
+ tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE;
+ tvi.hItem = TreeView_GetRoot(hwndTree);
+ while (tvi.hItem) {
+ TreeView_GetItem(hwndTree, &tvi);
+ if (((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 2))
+ flags |= tvi.lParam;
+ tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem);
+ }
+ return flags;
+}
+
+static BOOL CALLBACK DlgProcClcMainOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), GWL_STYLE,
+ GetWindowLong(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES);
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_HIDEOFFLINEOPTS), GWL_STYLE,
+ GetWindowLong(GetDlgItem(hwndDlg, IDC_HIDEOFFLINEOPTS), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES);
+ {
+ int i;
+ DWORD exStyle = DBGetContactSettingDword(NULL, "CLC", "ExStyle", pcli->pfnGetDefaultExStyle());
+ for (i = 0; i < SIZEOF(checkBoxToStyleEx); i++)
+ CheckDlgButton(hwndDlg, checkBoxToStyleEx[i].id,
+ (exStyle & checkBoxToStyleEx[i].flag) ^ (checkBoxToStyleEx[i].flag *
+ checkBoxToStyleEx[i].not) ? BST_CHECKED : BST_UNCHECKED);
+ }
+ {
+ UDACCEL accel[2] = { {0, 10} , {2, 50} };
+ SendDlgItemMessage(hwndDlg, IDC_SMOOTHTIMESPIN, UDM_SETRANGE, 0, MAKELONG(999, 0));
+ SendDlgItemMessage(hwndDlg, IDC_SMOOTHTIMESPIN, UDM_SETACCEL, SIZEOF(accel), (LPARAM) & accel);
+ SendDlgItemMessage(hwndDlg, IDC_SMOOTHTIMESPIN, UDM_SETPOS, 0,
+ MAKELONG(DBGetContactSettingWord(NULL, "CLC", "ScrollTime", CLCDEFAULT_SCROLLTIME), 0));
+ }
+ CheckDlgButton(hwndDlg, IDC_IDLE, DBGetContactSettingByte(NULL, "CLC", "ShowIdle", CLCDEFAULT_SHOWIDLE) ? BST_CHECKED : BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_LEFTMARGINSPIN, UDM_SETRANGE, 0, MAKELONG(64, 0));
+ SendDlgItemMessage(hwndDlg, IDC_LEFTMARGINSPIN, UDM_SETPOS, 0,
+ MAKELONG(DBGetContactSettingByte(NULL, "CLC", "LeftMargin", CLCDEFAULT_LEFTMARGIN), 0));
+ SendDlgItemMessage(hwndDlg, IDC_GROUPINDENTSPIN, UDM_SETRANGE, 0, MAKELONG(50, 0));
+ SendDlgItemMessage(hwndDlg, IDC_GROUPINDENTSPIN, UDM_SETPOS, 0,
+ MAKELONG(DBGetContactSettingByte(NULL, "CLC", "GroupIndent", CLCDEFAULT_GROUPINDENT), 0));
+ CheckDlgButton(hwndDlg, IDC_GREYOUT,
+ DBGetContactSettingDword(NULL, "CLC", "GreyoutFlags", CLCDEFAULT_GREYOUTFLAGS) ? BST_CHECKED : BST_UNCHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SMOOTHTIME), IsDlgButtonChecked(hwndDlg, IDC_NOTNOSMOOTHSCROLLING));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), IsDlgButtonChecked(hwndDlg, IDC_GREYOUT));
+ FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), greyoutValues, SIZEOF(greyoutValues),
+ DBGetContactSettingDword(NULL, "CLC", "FullGreyoutFlags", CLCDEFAULT_FULLGREYOUTFLAGS));
+ FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_HIDEOFFLINEOPTS), offlineValues, SIZEOF(offlineValues),
+ DBGetContactSettingDword(NULL, "CLC", "OfflineModes", CLCDEFAULT_OFFLINEMODES));
+ CheckDlgButton(hwndDlg, IDC_NOSCROLLBAR, DBGetContactSettingByte(NULL, "CLC", "NoVScrollBar", 0) ? BST_CHECKED : BST_UNCHECKED);
+ return TRUE;
+ case WM_VSCROLL:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_NOTNOSMOOTHSCROLLING)
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SMOOTHTIME), IsDlgButtonChecked(hwndDlg, IDC_NOTNOSMOOTHSCROLLING));
+ if (LOWORD(wParam) == IDC_GREYOUT)
+ EnableWindow(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), IsDlgButtonChecked(hwndDlg, IDC_GREYOUT));
+ if ((LOWORD(wParam) == IDC_LEFTMARGIN || LOWORD(wParam) == IDC_SMOOTHTIME || LOWORD(wParam) == IDC_GROUPINDENT)
+ && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case IDC_GREYOUTOPTS:
+ case IDC_HIDEOFFLINEOPTS:
+ if (((LPNMHDR) lParam)->code == NM_CLICK) {
+ TVHITTESTINFO hti;
+ hti.pt.x = (short) LOWORD(GetMessagePos());
+ hti.pt.y = (short) HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR) lParam)->hwndFrom, &hti.pt);
+ if (TreeView_HitTest(((LPNMHDR) lParam)->hwndFrom, &hti))
+ if (hti.flags & TVHT_ONITEMSTATEICON) {
+ TVITEM tvi;
+ tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvi.hItem = hti.hItem;
+ TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ tvi.iImage = tvi.iSelectedImage = tvi.iImage == 1 ? 2 : 1;
+ TreeView_SetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case 0:
+ if (((LPNMHDR) lParam)->code == PSN_APPLY ) {
+ int i;
+ DWORD exStyle = 0;
+ for (i = 0; i < SIZEOF(checkBoxToStyleEx); i++)
+ if ((IsDlgButtonChecked(hwndDlg, checkBoxToStyleEx[i].id) == 0) == checkBoxToStyleEx[i].not)
+ exStyle |= checkBoxToStyleEx[i].flag;
+
+ DBWriteContactSettingDword(NULL, "CLC", "ExStyle", exStyle);
+ {
+ DWORD fullGreyoutFlags = MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS));
+ DBWriteContactSettingDword(NULL, "CLC", "FullGreyoutFlags", fullGreyoutFlags);
+ if (IsDlgButtonChecked(hwndDlg, IDC_GREYOUT))
+ DBWriteContactSettingDword(NULL, "CLC", "GreyoutFlags", fullGreyoutFlags);
+ else
+ DBWriteContactSettingDword(NULL, "CLC", "GreyoutFlags", 0);
+ }
+ DBWriteContactSettingByte(NULL, "CLC", "ShowIdle", (BYTE) (IsDlgButtonChecked(hwndDlg, IDC_IDLE) ? 1 : 0));
+ DBWriteContactSettingDword(NULL, "CLC", "OfflineModes", MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_HIDEOFFLINEOPTS)));
+ DBWriteContactSettingByte(NULL, "CLC", "LeftMargin",
+ (BYTE) SendDlgItemMessage(hwndDlg, IDC_LEFTMARGINSPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingWord(NULL, "CLC", "ScrollTime",
+ (WORD) SendDlgItemMessage(hwndDlg, IDC_SMOOTHTIMESPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, "CLC", "GroupIndent",
+ (BYTE) SendDlgItemMessage(hwndDlg, IDC_GROUPINDENTSPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, "CLC", "NoVScrollBar", (BYTE) (IsDlgButtonChecked(hwndDlg, IDC_NOSCROLLBAR) ? 1 : 0));
+ pcli->pfnClcOptionsChanged();
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ ImageList_Destroy(TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_GREYOUTOPTS), TVSIL_NORMAL));
+ break;
+ }
+ return FALSE;
+}
+
+static BOOL CALLBACK DlgProcClcBkgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_BITMAP,
+ DBGetContactSettingByte(NULL, "CLC", "UseBitmap", CLCDEFAULT_USEBITMAP) ? BST_CHECKED : BST_UNCHECKED);
+ SendMessage(hwndDlg, WM_USER + 10, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETDEFAULTCOLOUR, 0, CLCDEFAULT_BKCOLOUR);
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, "CLC", "BkColour", CLCDEFAULT_BKCOLOUR));
+ SendDlgItemMessage(hwndDlg, IDC_SELCOLOUR, CPM_SETDEFAULTCOLOUR, 0, CLCDEFAULT_SELBKCOLOUR);
+ SendDlgItemMessage(hwndDlg, IDC_SELCOLOUR, CPM_SETCOLOUR, 0,
+ DBGetContactSettingDword(NULL, "CLC", "SelBkColour", CLCDEFAULT_SELBKCOLOUR));
+ CheckDlgButton(hwndDlg, IDC_WINCOLOUR, DBGetContactSettingByte(NULL, "CLC", "UseWinColours", 0));
+ SendMessage(hwndDlg, WM_USER + 11, 0, 0);
+ {
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(NULL, "CLC", "BkBitmap", &dbv)) {
+ SetDlgItemTextA(hwndDlg, IDC_FILENAME, dbv.pszVal);
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE)) {
+ char szPath[MAX_PATH];
+
+ if (CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) dbv.pszVal, (LPARAM) szPath))
+ SetDlgItemTextA(hwndDlg, IDC_FILENAME, szPath);
+ }
+ else
+ mir_free(dbv.pszVal);
+ }
+ }
+ {
+ WORD bmpUse = DBGetContactSettingWord(NULL, "CLC", "BkBmpUse", CLCDEFAULT_BKBMPUSE);
+ CheckDlgButton(hwndDlg, IDC_STRETCHH, bmpUse & CLB_STRETCHH ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_STRETCHV, bmpUse & CLB_STRETCHV ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_TILEH, bmpUse & CLBF_TILEH ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_TILEV, bmpUse & CLBF_TILEV ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SCROLL, bmpUse & CLBF_SCROLL ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_PROPORTIONAL, bmpUse & CLBF_PROPORTIONAL ? BST_CHECKED : BST_UNCHECKED);
+ }
+ {
+ HRESULT(STDAPICALLTYPE * MySHAutoComplete) (HWND, DWORD);
+ MySHAutoComplete = (HRESULT(STDAPICALLTYPE *) (HWND, DWORD)) GetProcAddress(GetModuleHandleA("shlwapi"), "SHAutoComplete");
+ if (MySHAutoComplete)
+ MySHAutoComplete(GetDlgItem(hwndDlg, IDC_FILENAME), 1);
+ }
+ return TRUE;
+ case WM_USER + 10:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FILENAME), IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE), IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STRETCHH), IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STRETCHV), IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TILEH), IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TILEV), IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SCROLL), IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PROPORTIONAL), IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ break;
+ case WM_USER + 11:
+ {
+ BOOL b = IsDlgButtonChecked(hwndDlg, IDC_WINCOLOUR);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BKGCOLOUR), !b);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SELCOLOUR), !b);
+ break;
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BROWSE) {
+ char str[MAX_PATH];
+ OPENFILENAMEA ofn = { 0 };
+ char filter[512];
+
+ GetDlgItemTextA(hwndDlg, IDC_FILENAME, str, SIZEOF(str));
+ ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+ ofn.hwndOwner = hwndDlg;
+ ofn.hInstance = NULL;
+ CallService(MS_UTILS_GETBITMAPFILTERSTRINGS, SIZEOF(filter), (LPARAM) filter);
+ ofn.lpstrFilter = filter;
+ ofn.lpstrFile = str;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+ ofn.nMaxFile = SIZEOF(str);
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = "bmp";
+ if (!GetOpenFileNameA(&ofn))
+ break;
+ SetDlgItemTextA(hwndDlg, IDC_FILENAME, str);
+ }
+ else if (LOWORD(wParam) == IDC_FILENAME && HIWORD(wParam) != EN_CHANGE)
+ break;
+ if (LOWORD(wParam) == IDC_BITMAP)
+ SendMessage(hwndDlg, WM_USER + 10, 0, 0);
+ if (LOWORD(wParam) == IDC_WINCOLOUR)
+ SendMessage(hwndDlg, WM_USER + 11, 0, 0);
+ if (LOWORD(wParam) == IDC_FILENAME && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ DBWriteContactSettingByte(NULL, "CLC", "UseBitmap", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_BITMAP));
+ {
+ COLORREF col;
+ col = SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0);
+ if (col == CLCDEFAULT_BKCOLOUR)
+ DBDeleteContactSetting(NULL, "CLC", "BkColour");
+ else
+ DBWriteContactSettingDword(NULL, "CLC", "BkColour", col);
+ col = SendDlgItemMessage(hwndDlg, IDC_SELCOLOUR, CPM_GETCOLOUR, 0, 0);
+ if (col == CLCDEFAULT_SELBKCOLOUR)
+ DBDeleteContactSetting(NULL, "CLC", "SelBkColour");
+ else
+ DBWriteContactSettingDword(NULL, "CLC", "SelBkColour", col);
+ DBWriteContactSettingByte(NULL, "CLC", "UseWinColours", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_WINCOLOUR)));
+ }
+ {
+ char str[MAX_PATH], strrel[MAX_PATH];
+ GetDlgItemTextA(hwndDlg, IDC_FILENAME, str, SIZEOF(str));
+ if (ServiceExists(MS_UTILS_PATHTORELATIVE)) {
+ if (CallService(MS_UTILS_PATHTORELATIVE, (WPARAM) str, (LPARAM) strrel))
+ DBWriteContactSettingString(NULL, "CLC", "BkBitmap", strrel);
+ else
+ DBWriteContactSettingString(NULL, "CLC", "BkBitmap", str);
+ }
+ else
+ DBWriteContactSettingString(NULL, "CLC", "BkBitmap", str);
+ }
+ {
+ WORD flags = 0;
+ if (IsDlgButtonChecked(hwndDlg, IDC_STRETCHH))
+ flags |= CLB_STRETCHH;
+ if (IsDlgButtonChecked(hwndDlg, IDC_STRETCHV))
+ flags |= CLB_STRETCHV;
+ if (IsDlgButtonChecked(hwndDlg, IDC_TILEH))
+ flags |= CLBF_TILEH;
+ if (IsDlgButtonChecked(hwndDlg, IDC_TILEV))
+ flags |= CLBF_TILEV;
+ if (IsDlgButtonChecked(hwndDlg, IDC_SCROLL))
+ flags |= CLBF_SCROLL;
+ if (IsDlgButtonChecked(hwndDlg, IDC_PROPORTIONAL))
+ flags |= CLBF_PROPORTIONAL;
+ DBWriteContactSettingWord(NULL, "CLC", "BkBmpUse", flags);
+ }
+ pcli->pfnClcOptionsChanged();
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static const TCHAR* szFontIdDescr[FONTID_LAST + 1] =
+{
+ _T("Standard contacts"),
+ _T("Online contacts to whom you have a different visibility"),
+ _T("Offline contacts"),
+ _T("Contacts which are 'not on list'"),
+ _T("Groups"),
+ _T("Group member counts"),
+ _T("Dividers"),
+ _T("Offline contacts to whom you have a different visibility")
+};
+
+#define SAMEASF_FACE 1
+#define SAMEASF_SIZE 2
+#define SAMEASF_STYLE 4
+#define SAMEASF_COLOUR 8
+#include <pshpack1.h>
+struct
+{
+ BYTE sameAsFlags, sameAs;
+ COLORREF colour;
+ char size;
+ BYTE style;
+ BYTE charset;
+ TCHAR szFace[LF_FACESIZE];
+}
+static fontSettings[FONTID_LAST + 1];
+#include <poppack.h>
+static WORD fontSameAsDefault[FONTID_LAST + 1] = { 0x00FF, 0x0B00, 0x0F00, 0x0700, 0x0B00, 0x0104, 0x0D00, 0x0B02 };
+static char *fontSizes[] = { "7", "8", "10", "14", "16", "18", "20", "24", "28" };
+static int fontListOrder[FONTID_LAST + 1] =
+{ FONTID_CONTACTS, FONTID_INVIS, FONTID_OFFLINE, FONTID_OFFINVIS, FONTID_NOTONLIST, FONTID_GROUPS, FONTID_GROUPCOUNTS, FONTID_DIVIDERS };
+
+#define M_REBUILDFONTGROUP (WM_USER+10)
+#define M_REMAKESAMPLE (WM_USER+11)
+#define M_RECALCONEFONT (WM_USER+12)
+#define M_RECALCOTHERFONTS (WM_USER+13)
+#define M_SAVEFONT (WM_USER+14)
+#define M_REFRESHSAMEASBOXES (WM_USER+15)
+#define M_FILLSCRIPTCOMBO (WM_USER+16)
+#define M_REDOROWHEIGHT (WM_USER+17)
+#define M_LOADFONT (WM_USER+18)
+#define M_GUESSSAMEASBOXES (WM_USER+19)
+#define M_SETSAMEASBOXES (WM_USER+20)
+
+static int CALLBACK EnumFontsProc(ENUMLOGFONTEX * lpelfe, NEWTEXTMETRICEX * lpntme, int FontType, LPARAM lParam)
+{
+ if (!IsWindow((HWND) lParam))
+ return FALSE;
+ if (SendMessage((HWND) lParam, CB_FINDSTRINGEXACT, -1, (LPARAM) lpelfe->elfLogFont.lfFaceName) == CB_ERR)
+ SendMessage((HWND) lParam, CB_ADDSTRING, 0, (LPARAM) lpelfe->elfLogFont.lfFaceName);
+ return TRUE;
+}
+
+void FillFontListThread(HWND hwndDlg)
+{
+ LOGFONT lf = { 0 };
+ HDC hdc = GetDC(hwndDlg);
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfFaceName[0] = 0;
+ lf.lfPitchAndFamily = 0;
+ EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC) EnumFontsProc, (LPARAM) GetDlgItem(hwndDlg, IDC_TYPEFACE), 0);
+ ReleaseDC(hwndDlg, hdc);
+ return;
+}
+
+static int CALLBACK EnumFontScriptsProc(ENUMLOGFONTEX * lpelfe, NEWTEXTMETRICEX * lpntme, int FontType, LPARAM lParam)
+{
+ if (SendMessage((HWND) lParam, CB_FINDSTRINGEXACT, -1, (LPARAM) lpelfe->elfScript) == CB_ERR) {
+ int i = SendMessage((HWND) lParam, CB_ADDSTRING, 0, (LPARAM) lpelfe->elfScript);
+ SendMessage((HWND) lParam, CB_SETITEMDATA, i, lpelfe->elfLogFont.lfCharSet);
+ }
+ return TRUE;
+}
+
+static int TextOptsDlgResizer(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL * urc)
+{
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
+}
+
+static void SwitchTextDlgToMode(HWND hwndDlg, int expert)
+{
+ ShowWindow(GetDlgItem(hwndDlg, IDC_GAMMACORRECT), expert ? SW_SHOW : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STSAMETEXT), expert ? SW_SHOW : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_SAMETYPE), expert ? SW_SHOW : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_SAMESIZE), expert ? SW_SHOW : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_SAMESTYLE), expert ? SW_SHOW : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_SAMECOLOUR), expert ? SW_SHOW : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STSIZETEXT), expert ? SW_HIDE : SW_SHOW);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STCOLOURTEXT), expert ? SW_HIDE : SW_SHOW);
+ SetDlgItemText(hwndDlg, IDC_STASTEXT, TranslateTS(expert ? _T("as:") : _T("based on:")));
+ {
+ UTILRESIZEDIALOG urd = { 0 };
+ urd.cbSize = sizeof(urd);
+ urd.hwndDlg = hwndDlg;
+ urd.hInstance = g_hInst;
+ urd.lpTemplate = MAKEINTRESOURCEA(expert ? IDD_OPT_CLCTEXT : IDD_OPT_CLCTEXTSIMPLE);
+ urd.pfnResizer = TextOptsDlgResizer;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd);
+ }
+ //resizer breaks the sizing of the edit box
+ SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_SETBUDDY, (WPARAM) GetDlgItem(hwndDlg, IDC_ROWHEIGHT), 0);
+ SendMessage(hwndDlg, M_REFRESHSAMEASBOXES,
+ SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETCURSEL, 0, 0), 0), 0);
+}
+
+static BOOL CALLBACK DlgProcClcTextOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static HFONT hFontSample;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ hFontSample = NULL;
+ SetDlgItemTextA(hwndDlg, IDC_SAMPLE, "Sample");
+ TranslateDialogDefault(hwndDlg);
+ if (!SendMessage(GetParent(hwndDlg), PSM_ISEXPERT, 0, 0))
+ SwitchTextDlgToMode(hwndDlg, 0);
+ forkthread(FillFontListThread, 0, hwndDlg);
+ {
+ int i, itemId, fontId;
+ LOGFONT lf;
+ COLORREF colour;
+ WORD sameAs;
+ char str[32];
+
+ for (i = 0; i <= FONTID_LAST; i++) {
+ fontId = fontListOrder[i];
+ pcli->pfnGetFontSetting(fontId, &lf, &colour);
+ wsprintfA(str, "Font%dAs", fontId);
+ sameAs = DBGetContactSettingWord(NULL, "CLC", str, fontSameAsDefault[fontId]);
+ fontSettings[fontId].sameAsFlags = HIBYTE(sameAs);
+ fontSettings[fontId].sameAs = LOBYTE(sameAs);
+ fontSettings[fontId].style =
+ (lf.lfWeight == FW_NORMAL ? 0 : DBFONTF_BOLD) | (lf.lfItalic ? DBFONTF_ITALIC : 0) | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0);
+ if (lf.lfHeight < 0) {
+ HDC hdc;
+ SIZE size;
+ HFONT hFont = CreateFontIndirect(&lf);
+ hdc = GetDC(hwndDlg);
+ SelectObject(hdc, hFont);
+ GetTextExtentPoint32A(hdc, "_W", 2, &size);
+ ReleaseDC(hwndDlg, hdc);
+ DeleteObject(hFont);
+ fontSettings[fontId].size = (char) size.cy;
+ }
+ else fontSettings[fontId].size = (char) lf.lfHeight;
+ fontSettings[fontId].charset = lf.lfCharSet;
+ fontSettings[fontId].colour = colour;
+ lstrcpy(fontSettings[fontId].szFace, lf.lfFaceName);
+ itemId = SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_ADDSTRING, 0, (LPARAM) TranslateTS( szFontIdDescr[fontId] ));
+ SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_SETITEMDATA, itemId, fontId);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_SETCURSEL, 0, 0);
+ for (i = 0; i < SIZEOF(fontSizes); i++)
+ SendDlgItemMessageA(hwndDlg, IDC_FONTSIZE, CB_ADDSTRING, 0, (LPARAM) fontSizes[i]);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_SETRANGE, 0, MAKELONG(255, 0));
+ SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_SETPOS, 0, MAKELONG(DBGetContactSettingByte(NULL, "CLC", "RowHeight", CLCDEFAULT_ROWHEIGHT), 0));
+ SendMessage(hwndDlg, M_REBUILDFONTGROUP, 0, 0);
+ SendMessage(hwndDlg, M_SAVEFONT, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_HOTCOLOUR, CPM_SETDEFAULTCOLOUR, 0, CLCDEFAULT_HOTTEXTCOLOUR);
+ SendDlgItemMessage(hwndDlg, IDC_HOTCOLOUR, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, "CLC", "HotTextColour", CLCDEFAULT_HOTTEXTCOLOUR));
+ CheckDlgButton(hwndDlg, IDC_GAMMACORRECT, DBGetContactSettingByte(NULL, "CLC", "GammaCorrect", CLCDEFAULT_GAMMACORRECT) ? BST_CHECKED : BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_SELCOLOUR, CPM_SETDEFAULTCOLOUR, 0, CLCDEFAULT_SELTEXTCOLOUR);
+ SendDlgItemMessage(hwndDlg, IDC_SELCOLOUR, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, "CLC", "SelTextColour", CLCDEFAULT_SELTEXTCOLOUR));
+ SendDlgItemMessage(hwndDlg, IDC_QUICKCOLOUR, CPM_SETDEFAULTCOLOUR, 0, CLCDEFAULT_QUICKSEARCHCOLOUR);
+ SendDlgItemMessage(hwndDlg, IDC_QUICKCOLOUR, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, "CLC", "QuickSearchColour", CLCDEFAULT_QUICKSEARCHCOLOUR));
+ return TRUE;
+ case M_REBUILDFONTGROUP: //remake all the needed controls when the user changes the font selector at the top
+ {
+ int i = SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETCURSEL, 0, 0), 0);
+ SendMessage(hwndDlg, M_SETSAMEASBOXES, i, 0);
+ {
+ int j, id, itemId;
+ char szText[256];
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_RESETCONTENT, 0, 0);
+ itemId = SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_ADDSTRING, 0, (LPARAM) TranslateT("<none>"));
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETITEMDATA, itemId, 0xFF);
+ if (0xFF == fontSettings[i].sameAs)
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETCURSEL, itemId, 0);
+ for (j = 0; j <= FONTID_LAST; j++) {
+ SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETLBTEXT, j, (LPARAM) szText);
+ id = SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETITEMDATA, j, 0);
+ if (id == i)
+ continue;
+ itemId = SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_ADDSTRING, 0, (LPARAM) szText);
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETITEMDATA, itemId, id);
+ if (id == fontSettings[i].sameAs)
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETCURSEL, itemId, 0);
+ }
+ }
+ SendMessage(hwndDlg, M_LOADFONT, i, 0);
+ SendMessage(hwndDlg, M_REFRESHSAMEASBOXES, i, 0);
+ SendMessage(hwndDlg, M_REMAKESAMPLE, 0, 0);
+ break;
+ }
+ case M_SETSAMEASBOXES: //set the check mark in the 'same as' boxes to the right value for fontid wParam
+ CheckDlgButton(hwndDlg, IDC_SAMETYPE, fontSettings[wParam].sameAsFlags & SAMEASF_FACE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SAMESIZE, fontSettings[wParam].sameAsFlags & SAMEASF_SIZE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SAMESTYLE, fontSettings[wParam].sameAsFlags & SAMEASF_STYLE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SAMECOLOUR, fontSettings[wParam].sameAsFlags & SAMEASF_COLOUR ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ case M_FILLSCRIPTCOMBO: //fill the script combo box and set the selection to the value for fontid wParam
+ {
+ LOGFONT lf = { 0 };
+ int i;
+ HDC hdc = GetDC(hwndDlg);
+ lf.lfCharSet = DEFAULT_CHARSET;
+ GetDlgItemText(hwndDlg, IDC_TYPEFACE, lf.lfFaceName, LF_FACESIZE );
+ lf.lfPitchAndFamily = 0;
+ SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_RESETCONTENT, 0, 0);
+ EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC) EnumFontScriptsProc, (LPARAM) GetDlgItem(hwndDlg, IDC_SCRIPT), 0);
+ ReleaseDC(hwndDlg, hdc);
+ for (i = SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETCOUNT, 0, 0) - 1; i >= 0; i--) {
+ if (SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETITEMDATA, i, 0) == fontSettings[wParam].charset) {
+ SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_SETCURSEL, i, 0);
+ break;
+ }
+ }
+ if (i < 0)
+ SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_SETCURSEL, 0, 0);
+ break;
+ }
+ case WM_CTLCOLORSTATIC:
+ if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_SAMPLE)) {
+ SetTextColor((HDC) wParam, SendDlgItemMessage(hwndDlg, IDC_COLOUR, CPM_GETCOLOUR, 0, 0));
+ SetBkColor((HDC) wParam, GetSysColor(COLOR_3DFACE));
+ return (BOOL) GetSysColorBrush(COLOR_3DFACE);
+ }
+ break;
+ case M_REFRESHSAMEASBOXES: //set the disabled flag on the 'same as' checkboxes to the values for fontid wParam
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAMETYPE), fontSettings[wParam].sameAs != 0xFF);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAMESIZE), fontSettings[wParam].sameAs != 0xFF);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAMESTYLE), fontSettings[wParam].sameAs != 0xFF);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SAMECOLOUR), fontSettings[wParam].sameAs != 0xFF);
+ if (SendMessage(GetParent(hwndDlg), PSM_ISEXPERT, 0, 0)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPEFACE), fontSettings[wParam].sameAs == 0xFF
+ || !(fontSettings[wParam].sameAsFlags & SAMEASF_FACE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SCRIPT), fontSettings[wParam].sameAs == 0xFF
+ || !(fontSettings[wParam].sameAsFlags & SAMEASF_FACE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FONTSIZE), fontSettings[wParam].sameAs == 0xFF
+ || !(fontSettings[wParam].sameAsFlags & SAMEASF_SIZE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BOLD), fontSettings[wParam].sameAs == 0xFF
+ || !(fontSettings[wParam].sameAsFlags & SAMEASF_STYLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITALIC), fontSettings[wParam].sameAs == 0xFF
+ || !(fontSettings[wParam].sameAsFlags & SAMEASF_STYLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_UNDERLINE), fontSettings[wParam].sameAs == 0xFF
+ || !(fontSettings[wParam].sameAsFlags & SAMEASF_STYLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_COLOUR), fontSettings[wParam].sameAs == 0xFF
+ || !(fontSettings[wParam].sameAsFlags & SAMEASF_COLOUR));
+ }
+ else {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPEFACE), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SCRIPT), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FONTSIZE), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BOLD), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ITALIC), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_UNDERLINE), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_COLOUR), TRUE);
+ }
+ break;
+ case M_REMAKESAMPLE: //remake the sample edit box font based on the settings in the controls
+ {
+ LOGFONTA lf;
+ if (hFontSample) {
+ SendDlgItemMessage(hwndDlg, IDC_SAMPLE, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDC_FONTID, WM_GETFONT, 0, 0), 0);
+ DeleteObject(hFontSample);
+ }
+ lf.lfHeight = GetDlgItemInt(hwndDlg, IDC_FONTSIZE, NULL, FALSE);
+ {
+ HDC hdc = GetDC(NULL);
+ lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+ ReleaseDC(NULL, hdc);
+ }
+ lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
+ lf.lfWeight = IsDlgButtonChecked(hwndDlg, IDC_BOLD) ? FW_BOLD : FW_NORMAL;
+ lf.lfItalic = IsDlgButtonChecked(hwndDlg, IDC_ITALIC);
+ lf.lfUnderline = IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE);
+ lf.lfStrikeOut = 0;
+ lf.lfCharSet = (BYTE) SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETCURSEL, 0, 0), 0);
+ lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfQuality = DEFAULT_QUALITY;
+ lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ GetDlgItemTextA(hwndDlg, IDC_TYPEFACE, lf.lfFaceName, SIZEOF(lf.lfFaceName));
+ hFontSample = CreateFontIndirectA(&lf);
+ SendDlgItemMessage(hwndDlg, IDC_SAMPLE, WM_SETFONT, (WPARAM) hFontSample, TRUE);
+ break;
+ }
+ case M_RECALCONEFONT: //copy the 'same as' settings for fontid wParam from their sources
+ if (fontSettings[wParam].sameAs == 0xFF)
+ break;
+ if (fontSettings[wParam].sameAsFlags & SAMEASF_FACE) {
+ lstrcpy(fontSettings[wParam].szFace, fontSettings[fontSettings[wParam].sameAs].szFace);
+ fontSettings[wParam].charset = fontSettings[fontSettings[wParam].sameAs].charset;
+ }
+ if (fontSettings[wParam].sameAsFlags & SAMEASF_SIZE)
+ fontSettings[wParam].size = fontSettings[fontSettings[wParam].sameAs].size;
+ if (fontSettings[wParam].sameAsFlags & SAMEASF_STYLE)
+ fontSettings[wParam].style = fontSettings[fontSettings[wParam].sameAs].style;
+ if (fontSettings[wParam].sameAsFlags & SAMEASF_COLOUR)
+ fontSettings[wParam].colour = fontSettings[fontSettings[wParam].sameAs].colour;
+ break;
+ case M_RECALCOTHERFONTS: //recalculate the 'same as' settings for all fonts but wParam
+ {
+ int i;
+ for (i = 0; i <= FONTID_LAST; i++) {
+ if (i == (int) wParam)
+ continue;
+ SendMessage(hwndDlg, M_RECALCONEFONT, i, 0);
+ }
+ break;
+ }
+ case M_SAVEFONT: //save the font settings from the controls to font wParam
+ fontSettings[wParam].sameAsFlags =
+ (IsDlgButtonChecked(hwndDlg, IDC_SAMETYPE) ? SAMEASF_FACE : 0) | (IsDlgButtonChecked(hwndDlg, IDC_SAMESIZE) ? SAMEASF_SIZE : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_SAMESTYLE) ? SAMEASF_STYLE : 0) | (IsDlgButtonChecked(hwndDlg, IDC_SAMECOLOUR) ? SAMEASF_COLOUR : 0);
+ fontSettings[wParam].sameAs =
+ (BYTE) SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_GETCURSEL, 0, 0), 0);
+ GetDlgItemText(hwndDlg, IDC_TYPEFACE, fontSettings[wParam].szFace, SIZEOF( fontSettings[wParam].szFace ));
+ fontSettings[wParam].charset =
+ (BYTE) SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_SCRIPT, CB_GETCURSEL, 0, 0), 0);
+ fontSettings[wParam].size = (char) GetDlgItemInt(hwndDlg, IDC_FONTSIZE, NULL, FALSE);
+ fontSettings[wParam].style =
+ (IsDlgButtonChecked(hwndDlg, IDC_BOLD) ? DBFONTF_BOLD : 0) | (IsDlgButtonChecked(hwndDlg, IDC_ITALIC) ? DBFONTF_ITALIC : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE) ? DBFONTF_UNDERLINE : 0);
+ fontSettings[wParam].colour = SendDlgItemMessage(hwndDlg, IDC_COLOUR, CPM_GETCOLOUR, 0, 0);
+ SendMessage(hwndDlg, M_REDOROWHEIGHT, 0, 0);
+ break;
+ case M_REDOROWHEIGHT: //recalculate the minimum feasible row height
+ {
+ int i;
+ int minHeight = GetSystemMetrics(SM_CYSMICON);
+ for (i = 0; i <= FONTID_LAST; i++)
+ if (fontSettings[i].size > minHeight)
+ minHeight = fontSettings[i].size;
+ i = SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_GETPOS, 0, 0);
+ if (i < minHeight)
+ SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_SETPOS, 0, MAKELONG(minHeight, 0));
+ break;
+ }
+ case M_LOADFONT: //load font wParam into the controls
+ SetDlgItemText(hwndDlg, IDC_TYPEFACE, fontSettings[wParam].szFace);
+ SendMessage(hwndDlg, M_FILLSCRIPTCOMBO, wParam, 0);
+ SetDlgItemInt(hwndDlg, IDC_FONTSIZE, fontSettings[wParam].size, FALSE);
+ CheckDlgButton(hwndDlg, IDC_BOLD, fontSettings[wParam].style & DBFONTF_BOLD ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ITALIC, fontSettings[wParam].style & DBFONTF_ITALIC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_UNDERLINE, fontSettings[wParam].style & DBFONTF_UNDERLINE ? BST_CHECKED : BST_UNCHECKED);
+ {
+ LOGFONT lf;
+ COLORREF colour;
+ pcli->pfnGetDefaultFontSetting(wParam, &lf, &colour);
+ SendDlgItemMessage(hwndDlg, IDC_COLOUR, CPM_SETDEFAULTCOLOUR, 0, colour);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_COLOUR, CPM_SETCOLOUR, 0, fontSettings[wParam].colour);
+ break;
+ case M_GUESSSAMEASBOXES: //guess suitable values for the 'same as' checkboxes for fontId wParam
+ fontSettings[wParam].sameAsFlags = 0;
+ if (fontSettings[wParam].sameAs == 0xFF)
+ break;
+ if (!lstrcmp(fontSettings[wParam].szFace, fontSettings[fontSettings[wParam].sameAs].szFace) &&
+ fontSettings[wParam].charset == fontSettings[fontSettings[wParam].sameAs].charset)
+ fontSettings[wParam].sameAsFlags |= SAMEASF_FACE;
+ if (fontSettings[wParam].size == fontSettings[fontSettings[wParam].sameAs].size)
+ fontSettings[wParam].sameAsFlags |= SAMEASF_SIZE;
+ if (fontSettings[wParam].style == fontSettings[fontSettings[wParam].sameAs].style)
+ fontSettings[wParam].sameAsFlags |= SAMEASF_STYLE;
+ if (fontSettings[wParam].colour == fontSettings[fontSettings[wParam].sameAs].colour)
+ fontSettings[wParam].sameAsFlags |= SAMEASF_COLOUR;
+ SendMessage(hwndDlg, M_SETSAMEASBOXES, wParam, 0);
+ break;
+ case WM_VSCROLL:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_COMMAND:
+ {
+ int fontId = SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTID, CB_GETCURSEL, 0, 0), 0);
+ switch (LOWORD(wParam)) {
+ case IDC_FONTID:
+ if (HIWORD(wParam) != CBN_SELCHANGE)
+ return FALSE;
+ SendMessage(hwndDlg, M_REBUILDFONTGROUP, 0, 0);
+ return 0;
+ case IDC_SAMETYPE:
+ case IDC_SAMESIZE:
+ case IDC_SAMESTYLE:
+ case IDC_SAMECOLOUR:
+ SendMessage(hwndDlg, M_SAVEFONT, fontId, 0);
+ SendMessage(hwndDlg, M_RECALCONEFONT, fontId, 0);
+ SendMessage(hwndDlg, M_REMAKESAMPLE, 0, 0);
+ SendMessage(hwndDlg, M_REFRESHSAMEASBOXES, fontId, 0);
+ break;
+ case IDC_SAMEAS:
+ if (HIWORD(wParam) != CBN_SELCHANGE)
+ return FALSE;
+ if (SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_GETCURSEL, 0, 0), 0) ==
+ fontId)
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_SETCURSEL, 0, 0);
+ if (!SendMessage(GetParent(hwndDlg), PSM_ISEXPERT, 0, 0)) {
+ int sameAs =
+ SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_SAMEAS, CB_GETCURSEL, 0, 0), 0);
+ if (sameAs != 0xFF)
+ SendMessage(hwndDlg, M_LOADFONT, sameAs, 0);
+ SendMessage(hwndDlg, M_SAVEFONT, fontId, 0);
+ SendMessage(hwndDlg, M_GUESSSAMEASBOXES, fontId, 0);
+ }
+ else
+ SendMessage(hwndDlg, M_SAVEFONT, fontId, 0);
+ SendMessage(hwndDlg, M_RECALCONEFONT, fontId, 0);
+ SendMessage(hwndDlg, M_FILLSCRIPTCOMBO, fontId, 0);
+ SendMessage(hwndDlg, M_REMAKESAMPLE, 0, 0);
+ SendMessage(hwndDlg, M_REFRESHSAMEASBOXES, fontId, 0);
+ break;
+ case IDC_TYPEFACE:
+ case IDC_SCRIPT:
+ case IDC_FONTSIZE:
+ if (HIWORD(wParam) != CBN_EDITCHANGE && HIWORD(wParam) != CBN_SELCHANGE)
+ return FALSE;
+ if (HIWORD(wParam) == CBN_SELCHANGE) {
+ SendDlgItemMessage(hwndDlg, LOWORD(wParam), CB_SETCURSEL, SendDlgItemMessage(hwndDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0), 0);
+ }
+ if (LOWORD(wParam) == IDC_TYPEFACE)
+ SendMessage(hwndDlg, M_FILLSCRIPTCOMBO, fontId, 0);
+ //fall through
+ case IDC_BOLD:
+ case IDC_ITALIC:
+ case IDC_UNDERLINE:
+ case IDC_COLOUR:
+ SendMessage(hwndDlg, M_SAVEFONT, fontId, 0);
+ if (!SendMessage(GetParent(hwndDlg), PSM_ISEXPERT, 0, 0)) {
+ SendMessage(hwndDlg, M_GUESSSAMEASBOXES, fontId, 0);
+ SendMessage(hwndDlg, M_REFRESHSAMEASBOXES, fontId, 0);
+ }
+ SendMessage(hwndDlg, M_RECALCOTHERFONTS, fontId, 0);
+ SendMessage(hwndDlg, M_REMAKESAMPLE, 0, 0);
+ SendMessage(hwndDlg, M_REDOROWHEIGHT, 0, 0);
+ break;
+ case IDC_SAMPLE:
+ return 0;
+ case IDC_ROWHEIGHT:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return 0;
+ break;
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ int i;
+ char str[20];
+
+ // Force min height calculation
+ // This prevents users from setting the row height to be too low
+ SendMessage(hwndDlg, M_REDOROWHEIGHT, 0, 0);
+ for (i = 0; i <= FONTID_LAST; i++) {
+ wsprintfA(str, "Font%dName", i);
+ DBWriteContactSettingTString(NULL, "CLC", str, fontSettings[i].szFace);
+ wsprintfA(str, "Font%dSet", i);
+ DBWriteContactSettingByte(NULL, "CLC", str, fontSettings[i].charset);
+ wsprintfA(str, "Font%dSize", i);
+ DBWriteContactSettingByte(NULL, "CLC", str, fontSettings[i].size);
+ wsprintfA(str, "Font%dSty", i);
+ DBWriteContactSettingByte(NULL, "CLC", str, fontSettings[i].style);
+ wsprintfA(str, "Font%dCol", i);
+ DBWriteContactSettingDword(NULL, "CLC", str, fontSettings[i].colour);
+ wsprintfA(str, "Font%dAs", i);
+ DBWriteContactSettingWord(NULL, "CLC", str, (WORD) ((fontSettings[i].sameAsFlags << 8) | fontSettings[i].sameAs));
+ }
+ }
+ {
+ COLORREF col;
+ col = SendDlgItemMessage(hwndDlg, IDC_SELCOLOUR, CPM_GETCOLOUR, 0, 0);
+ if (col == CLCDEFAULT_SELTEXTCOLOUR)
+ DBDeleteContactSetting(NULL, "CLC", "SelTextColour");
+ else
+ DBWriteContactSettingDword(NULL, "CLC", "SelTextColour", col);
+ col = SendDlgItemMessage(hwndDlg, IDC_HOTCOLOUR, CPM_GETCOLOUR, 0, 0);
+ if (col == CLCDEFAULT_HOTTEXTCOLOUR)
+ DBDeleteContactSetting(NULL, "CLC", "HotTextColour");
+ else
+ DBWriteContactSettingDword(NULL, "CLC", "HotTextColour", col);
+ col = SendDlgItemMessage(hwndDlg, IDC_QUICKCOLOUR, CPM_GETCOLOUR, 0, 0);
+ if (col == CLCDEFAULT_QUICKSEARCHCOLOUR)
+ DBDeleteContactSetting(NULL, "CLC", "QuickSearchColour");
+ else
+ DBWriteContactSettingDword(NULL, "CLC", "QuickSearchColour", col);
+ }
+ DBWriteContactSettingByte(NULL, "CLC", "RowHeight", (BYTE) SendDlgItemMessage(hwndDlg, IDC_ROWHEIGHTSPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, "CLC", "GammaCorrect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_GAMMACORRECT));
+ pcli->pfnClcOptionsChanged();
+ return TRUE;
+ case PSN_EXPERTCHANGED:
+ SwitchTextDlgToMode(hwndDlg, ((PSHNOTIFY *) lParam)->lParam);
+ break;
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ if (hFontSample) {
+ SendDlgItemMessage(hwndDlg, IDC_SAMPLE, WM_SETFONT, SendDlgItemMessage(hwndDlg, IDC_FONTID, WM_GETFONT, 0, 0), 0);
+ DeleteObject(hFontSample);
+ }
+ break;
+ }
+ return FALSE;
+}
+
+/****************************************************************************************/
+
+int ClcOptInit(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp, sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.position = 0;
+ odp.hInstance = g_hInst;
+ odp.pszGroup = "Contact List";
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CLC);
+ odp.pszTitle = "List";
+ odp.pfnDlgProc = DlgProcClcMainOpts;
+ odp.flags = ODPF_BOLDGROUPS | ODPF_EXPERTONLY;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CLCBKG);
+ odp.pszTitle = "List Background";
+ odp.pfnDlgProc = DlgProcClcBkgOpts;
+ odp.flags = ODPF_BOLDGROUPS;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CLCTEXT);
+ odp.pszTitle = "List Text";
+ odp.pfnDlgProc = DlgProcClcTextOpts;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+ return 0;
+}
diff --git a/miranda-wine/plugins/clist/clcpaint.c b/miranda-wine/plugins/clist/clcpaint.c new file mode 100644 index 0000000..d244c88 --- /dev/null +++ b/miranda-wine/plugins/clist/clcpaint.c @@ -0,0 +1,590 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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"
+
+extern HIMAGELIST himlCListClc;
+static BYTE divide3[765] = { 255 };
+
+static void ChangeToFont(HDC hdc, struct ClcData *dat, int id, int *fontHeight)
+{
+ SelectObject(hdc, dat->fontInfo[id].hFont);
+ SetTextColor(hdc, dat->fontInfo[id].colour);
+ if (fontHeight)
+ *fontHeight = dat->fontInfo[id].fontHeight;
+}
+
+static void __inline SetHotTrackColour(HDC hdc, struct ClcData *dat)
+{
+ if (dat->gammaCorrection) {
+ COLORREF oldCol, newCol;
+ int oldLum, newLum;
+
+ oldCol = GetTextColor(hdc);
+ oldLum = (GetRValue(oldCol) * 30 + GetGValue(oldCol) * 59 + GetBValue(oldCol) * 11) / 100;
+ newLum = (GetRValue(dat->hotTextColour) * 30 + GetGValue(dat->hotTextColour) * 59 + GetBValue(dat->hotTextColour) * 11) / 100;
+ if (newLum == 0) {
+ SetTextColor(hdc, dat->hotTextColour);
+ return;
+ }
+ if (newLum >= oldLum + 20) {
+ oldLum += 20;
+ newCol =
+ RGB(GetRValue(dat->hotTextColour) * oldLum / newLum, GetGValue(dat->hotTextColour) * oldLum / newLum,
+ GetBValue(dat->hotTextColour) * oldLum / newLum);
+ }
+ else if (newLum <= oldLum) {
+ int r, g, b;
+ r = GetRValue(dat->hotTextColour) * oldLum / newLum;
+ g = GetGValue(dat->hotTextColour) * oldLum / newLum;
+ b = GetBValue(dat->hotTextColour) * oldLum / newLum;
+ if (r > 255) {
+ g += (r - 255) * 3 / 7;
+ b += (r - 255) * 3 / 7;
+ r = 255;
+ }
+ if (g > 255) {
+ r += (g - 255) * 59 / 41;
+ if (r > 255)
+ r = 255;
+ b += (g - 255) * 59 / 41;
+ g = 255;
+ }
+ if (b > 255) {
+ r += (b - 255) * 11 / 89;
+ if (r > 255)
+ r = 255;
+ g += (b - 255) * 11 / 89;
+ if (g > 255)
+ g = 255;
+ b = 255;
+ }
+ newCol = RGB(r, g, b);
+ }
+ else
+ newCol = dat->hotTextColour;
+ SetTextColor(hdc, newCol);
+ }
+ else
+ SetTextColor(hdc, dat->hotTextColour);
+}
+
+static int GetStatusOnlineness(int status)
+{
+ switch (status) {
+ case ID_STATUS_FREECHAT: return 110;
+ case ID_STATUS_ONLINE: return 100;
+ case ID_STATUS_OCCUPIED: return 60;
+ case ID_STATUS_ONTHEPHONE: return 50;
+ case ID_STATUS_DND: return 40;
+ case ID_STATUS_AWAY: return 30;
+ case ID_STATUS_OUTTOLUNCH: return 20;
+ case ID_STATUS_NA: return 10;
+ case ID_STATUS_INVISIBLE: return 5;
+ }
+ return 0;
+}
+
+static int GetGeneralisedStatus(void)
+{
+ int i, status, thisStatus, statusOnlineness, thisOnlineness;
+
+ status = ID_STATUS_OFFLINE;
+ statusOnlineness = 0;
+
+ for (i = 0; i < pcli->hClcProtoCount; i++) {
+ thisStatus = pcli->clcProto[i].dwStatus;
+ if (thisStatus == ID_STATUS_INVISIBLE)
+ return ID_STATUS_INVISIBLE;
+ thisOnlineness = GetStatusOnlineness(thisStatus);
+ if (thisOnlineness > statusOnlineness) {
+ status = thisStatus;
+ statusOnlineness = thisOnlineness;
+ }
+ }
+ return status;
+}
+
+static int GetRealStatus(struct ClcContact *contact, int status)
+{
+ int i;
+ char *szProto = contact->proto;
+ if (!szProto)
+ return status;
+ for (i = 0; i < pcli->hClcProtoCount; i++) {
+ if (!lstrcmpA(pcli->clcProto[i].szProto, szProto)) {
+ return pcli->clcProto[i].dwStatus;
+ }
+ }
+ return status;
+}
+
+static HMODULE themeAPIHandle = NULL; // handle to uxtheme.dll
+static HANDLE(WINAPI * MyOpenThemeData) (HWND, LPCWSTR);
+static HRESULT(WINAPI * MyCloseThemeData) (HANDLE);
+static HRESULT(WINAPI * MyDrawThemeBackground) (HANDLE, HDC, int, int, const RECT *, const RECT *);
+
+#define MGPROC(x) GetProcAddress(themeAPIHandle,x)
+void PaintClc(HWND hwnd, struct ClcData *dat, HDC hdc, RECT * rcPaint)
+{
+ HDC hdcMem;
+ RECT clRect;
+ int y, indent, index, fontHeight;
+ struct ClcGroup *group;
+ HBITMAP hBmpOsb, hOldBitmap;
+ HFONT hOldFont;
+ DWORD style = GetWindowLong(hwnd, GWL_STYLE);
+ int status = GetGeneralisedStatus();
+ int grey = 0, groupCountsFontTopShift;
+ HBRUSH hBrushAlternateGrey = NULL;
+ // yes I know about GetSysColorBrush()
+ COLORREF tmpbkcolour = style & CLS_CONTACTLIST ? (dat->useWindowsColours ? GetSysColor(COLOR_3DFACE) : dat->bkColour) : dat->bkColour;
+
+ if (dat->greyoutFlags & pcli->pfnClcStatusToPf2(status) || style & WS_DISABLED)
+ grey = 1;
+ else if (GetFocus() != hwnd && dat->greyoutFlags & GREYF_UNFOCUS)
+ grey = 1;
+ GetClientRect(hwnd, &clRect);
+ if (rcPaint == NULL)
+ rcPaint = &clRect;
+ if (IsRectEmpty(rcPaint))
+ return;
+ y = -dat->yScroll;
+ hdcMem = CreateCompatibleDC(hdc);
+ hBmpOsb = CreateBitmap(clRect.right, clRect.bottom, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
+ hOldBitmap = SelectObject(hdcMem, hBmpOsb);
+ {
+ TEXTMETRIC tm;
+ hOldFont = SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPS].hFont);
+ GetTextMetrics(hdcMem, &tm);
+ groupCountsFontTopShift = tm.tmAscent;
+ SelectObject(hdcMem, dat->fontInfo[FONTID_GROUPCOUNTS].hFont);
+ GetTextMetrics(hdcMem, &tm);
+ groupCountsFontTopShift -= tm.tmAscent;
+ }
+ if (style & CLS_GREYALTERNATE)
+ hBrushAlternateGrey =
+ CreateSolidBrush(GetNearestColor(hdcMem, RGB(GetRValue(tmpbkcolour) - 10, GetGValue(tmpbkcolour) - 10, GetBValue(tmpbkcolour) - 10)));
+
+ ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
+ SetBkMode(hdcMem, TRANSPARENT);
+ {
+ HBRUSH hBrush, hoBrush;
+
+ hBrush = CreateSolidBrush(tmpbkcolour);
+ hoBrush = (HBRUSH) SelectObject(hdcMem, hBrush);
+ FillRect(hdcMem, rcPaint, hBrush);
+ SelectObject(hdcMem, hoBrush);
+ DeleteObject(hBrush);
+ if (dat->hBmpBackground) {
+ BITMAP bmp;
+ HDC hdcBmp;
+ int x, y;
+ int maxx, maxy;
+ int destw, desth;
+
+ // XXX: Halftone isnt supported on 9x, however the scretch problems dont happen on 98.
+ SetStretchBltMode(hdcMem, HALFTONE);
+
+ GetObject(dat->hBmpBackground, sizeof(bmp), &bmp);
+ hdcBmp = CreateCompatibleDC(hdcMem);
+ SelectObject(hdcBmp, dat->hBmpBackground);
+ y = dat->backgroundBmpUse & CLBF_SCROLL ? -dat->yScroll : 0;
+ maxx = dat->backgroundBmpUse & CLBF_TILEH ? clRect.right : 1;
+ maxy = dat->backgroundBmpUse & CLBF_TILEV ? maxy = rcPaint->bottom : y + 1;
+ switch (dat->backgroundBmpUse & CLBM_TYPE) {
+ case CLB_STRETCH:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ if (clRect.right * bmp.bmHeight < clRect.bottom * bmp.bmWidth) {
+ desth = clRect.bottom;
+ destw = desth * bmp.bmWidth / bmp.bmHeight;
+ }
+ else {
+ destw = clRect.right;
+ desth = destw * bmp.bmHeight / bmp.bmWidth;
+ }
+ }
+ else {
+ destw = clRect.right;
+ desth = clRect.bottom;
+ }
+ break;
+ case CLB_STRETCHH:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ destw = clRect.right;
+ desth = destw * bmp.bmHeight / bmp.bmWidth;
+ }
+ else {
+ destw = clRect.right;
+ desth = bmp.bmHeight;
+ }
+ break;
+ case CLB_STRETCHV:
+ if (dat->backgroundBmpUse & CLBF_PROPORTIONAL) {
+ desth = clRect.bottom;
+ destw = desth * bmp.bmWidth / bmp.bmHeight;
+ }
+ else {
+ destw = bmp.bmWidth;
+ desth = clRect.bottom;
+ }
+ break;
+ default: //clb_topleft
+ destw = bmp.bmWidth;
+ desth = bmp.bmHeight;
+ break;
+ }
+ for (; y < maxy; y += desth) {
+ if (y < rcPaint->top - desth)
+ continue;
+ for (x = 0; x < maxx; x += destw)
+ StretchBlt(hdcMem, x, y, destw, desth, hdcBmp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
+ }
+ DeleteDC(hdcBmp);
+ }
+ }
+ group = &dat->list;
+ group->scanIndex = 0;
+ indent = 0;
+ for (index = 0; y < rcPaint->bottom;) {
+ if (group->scanIndex == group->cl.count) {
+ group = group->parent;
+ indent--;
+ if (group == NULL)
+ break;
+ group->scanIndex++;
+ continue;
+ }
+ if (y > rcPaint->top - dat->rowHeight) {
+ int iImage = -1;
+ int selected = index == dat->selection && (dat->showSelAlways || dat->exStyle & CLS_EX_SHOWSELALWAYS || GetFocus() == hwnd)
+ && group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER;
+ int hottrack = dat->exStyle & CLS_EX_TRACKSELECT && group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER && dat->iHotTrack == index;
+ SIZE textSize, countsSize, spaceSize;
+ int width, checkboxWidth;
+ char *szCounts;
+
+ //alternating grey
+ if (style & CLS_GREYALTERNATE && index & 1) {
+ RECT rc;
+ rc.top = y;
+ rc.bottom = rc.top + dat->rowHeight;
+ rc.left = 0;
+ rc.right = clRect.right;
+ FillRect(hdcMem, &rc, hBrushAlternateGrey);
+ }
+
+ //setup
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP)
+ ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_INFO) {
+ if (group->cl.items[group->scanIndex]->flags & CLCIIF_GROUPFONT)
+ ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
+ else
+ ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
+ }
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_DIVIDER)
+ ChangeToFont(hdcMem, dat, FONTID_DIVIDERS, &fontHeight);
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_NOTONLIST)
+ ChangeToFont(hdcMem, dat, FONTID_NOTONLIST, &fontHeight);
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT &&
+ ((group->cl.items[group->scanIndex]->flags & CONTACTF_INVISTO
+ && GetRealStatus(group->cl.items[group->scanIndex], status) != ID_STATUS_INVISIBLE)
+ || (group->cl.items[group->scanIndex]->flags & CONTACTF_VISTO
+ && GetRealStatus(group->cl.items[group->scanIndex], status) == ID_STATUS_INVISIBLE)
+ )
+ ) {
+ // the contact is in the always visible list and the proto is invisible
+ // the contact is in the always invisible and the proto is in any other mode
+ ChangeToFont(hdcMem, dat, group->cl.items[group->scanIndex]->flags & CONTACTF_ONLINE ? FONTID_INVIS : FONTID_OFFINVIS, &fontHeight);
+ }
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && !(group->cl.items[group->scanIndex]->flags & CONTACTF_ONLINE))
+ ChangeToFont(hdcMem, dat, FONTID_OFFLINE, &fontHeight);
+ else
+ ChangeToFont(hdcMem, dat, FONTID_CONTACTS, &fontHeight);
+ GetTextExtentPoint32(hdcMem, group->cl.items[group->scanIndex]->szText, lstrlen(group->cl.items[group->scanIndex]->szText), &textSize);
+ width = textSize.cx;
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
+ szCounts = pcli->pfnGetGroupCountsText(dat, group->cl.items[group->scanIndex]);
+ if (szCounts[0]) {
+ GetTextExtentPoint32A(hdcMem, " ", 1, &spaceSize);
+ ChangeToFont(hdcMem, dat, FONTID_GROUPCOUNTS, &fontHeight);
+ GetTextExtentPoint32A(hdcMem, szCounts, lstrlenA(szCounts), &countsSize);
+ width += spaceSize.cx + countsSize.cx;
+ }
+ }
+
+ if ((style & CLS_CHECKBOXES && group->cl.items[group->scanIndex]->type == CLCIT_CONTACT) ||
+ (style & CLS_GROUPCHECKBOXES && group->cl.items[group->scanIndex]->type == CLCIT_GROUP) ||
+ (group->cl.items[group->scanIndex]->type == CLCIT_INFO && group->cl.items[group->scanIndex]->flags & CLCIIF_CHECKBOX))
+ checkboxWidth = dat->checkboxSize + 2;
+ else
+ checkboxWidth = 0;
+
+ //background
+ if (selected) {
+ int x = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace - 2;
+ ImageList_DrawEx(dat->himlHighlight, 0, hdcMem, x, y, min(width + 5, clRect.right - x), dat->rowHeight, CLR_NONE, CLR_NONE,
+ dat->exStyle & CLS_EX_NOTRANSLUCENTSEL ? ILD_NORMAL : ILD_BLEND25);
+ SetTextColor(hdcMem, dat->selTextColour);
+ }
+ else if (hottrack)
+ SetHotTrackColour(hdcMem, dat);
+
+ //checkboxes
+ if (checkboxWidth) {
+ RECT rc;
+ HANDLE hTheme = NULL;
+
+ // THEME
+ if (IsWinVerXPPlus()) {
+ if (!themeAPIHandle) {
+ themeAPIHandle = GetModuleHandleA("uxtheme");
+ if (themeAPIHandle) {
+ MyOpenThemeData = (HANDLE(WINAPI *) (HWND, LPCWSTR)) MGPROC("OpenThemeData");
+ MyCloseThemeData = (HRESULT(WINAPI *) (HANDLE)) MGPROC("CloseThemeData");
+ MyDrawThemeBackground =
+ (HRESULT(WINAPI *) (HANDLE, HDC, int, int, const RECT *, const RECT *)) MGPROC("DrawThemeBackground");
+ }
+ }
+ // Make sure all of these methods are valid (i would hope either all or none work)
+ if (MyOpenThemeData && MyCloseThemeData && MyDrawThemeBackground) {
+ hTheme = MyOpenThemeData(hwnd, L"BUTTON");
+ }
+ }
+ rc.left = dat->leftMargin + indent * dat->groupIndent;
+ rc.right = rc.left + dat->checkboxSize;
+ rc.top = y + ((dat->rowHeight - dat->checkboxSize) >> 1);
+ rc.bottom = rc.top + dat->checkboxSize;
+ if (hTheme) {
+ MyDrawThemeBackground(hTheme, hdcMem, BP_CHECKBOX, group->cl.items[group->scanIndex]->flags & CONTACTF_CHECKED ? (hottrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL) : (hottrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL), &rc, &rc);
+ }
+ else
+ DrawFrameControl(hdcMem, &rc, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT | (group->cl.items[group->scanIndex]->flags & CONTACTF_CHECKED ? DFCS_CHECKED : 0) | (hottrack ? DFCS_HOT : 0));
+ if (hTheme && MyCloseThemeData) {
+ MyCloseThemeData(hTheme);
+ hTheme = NULL;
+ }
+ }
+
+ //icon
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP)
+ iImage = group->cl.items[group->scanIndex]->group->expanded ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT;
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT)
+ iImage = group->cl.items[group->scanIndex]->iImage;
+ if (iImage != -1) {
+ /*COLORREF colourFg=dat->selBkColour;
+ int mode=ILD_NORMAL;
+ if(selected) mode=ILD_SELECTED;
+ else if(hottrack) {mode=ILD_FOCUS; colourFg=dat->hotTextColour;}
+ else if(group->cl.items[group->scanIndex]->type==CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags&CONTACTF_NOTONLIST) {colourFg=dat->fontInfo[FONTID_NOTONLIST].colour; mode=ILD_BLEND50;}
+ ImageList_DrawEx(himlCListClc,iImage,hdcMem,dat->leftMargin+indent*dat->groupIndent+checkboxWidth,y+((dat->rowHeight-16)>>1),0,0,CLR_NONE,colourFg,mode);
+ */
+ // this doesnt use CLS_CONTACTLIST since the colour prolly wont match anyway
+ COLORREF colourFg = dat->selBkColour;
+ int mode = ILD_NORMAL;
+ if (hottrack) {
+ colourFg = dat->hotTextColour;
+ }
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_NOTONLIST) {
+ colourFg = dat->fontInfo[FONTID_NOTONLIST].colour;
+ mode = ILD_BLEND50;
+ }
+ if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && dat->showIdle
+ && (group->cl.items[group->scanIndex]->flags & CONTACTF_IDLE)
+ && GetRealStatus(group->cl.items[group->scanIndex], ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
+ mode = ILD_SELECTED;
+ ImageList_DrawEx(himlCListClc, iImage, hdcMem, dat->leftMargin + indent * dat->groupIndent + checkboxWidth,
+ y + ((dat->rowHeight - 16) >> 1), 0, 0, CLR_NONE, colourFg, mode);
+ }
+
+ //text
+ if (group->cl.items[group->scanIndex]->type == CLCIT_DIVIDER) {
+ RECT rc;
+ rc.top = y + (dat->rowHeight >> 1);
+ rc.bottom = rc.top + 2;
+ rc.left = dat->leftMargin + indent * dat->groupIndent;
+ rc.right = rc.left + ((clRect.right - rc.left - textSize.cx) >> 1) - 3;
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ TextOut(hdcMem, rc.right + 3, y + ((dat->rowHeight - fontHeight) >> 1), group->cl.items[group->scanIndex]->szText,
+ lstrlen(group->cl.items[group->scanIndex]->szText));
+ rc.left = rc.right + 6 + textSize.cx;
+ rc.right = clRect.right;
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ }
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP) {
+ RECT rc;
+ if (szCounts[0]) {
+ fontHeight = dat->fontInfo[FONTID_GROUPS].fontHeight;
+ rc.left = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace;
+ rc.right = min(clRect.right - countsSize.cx, rc.left + textSize.cx + spaceSize.cx);
+ rc.top = y + ((dat->rowHeight - fontHeight) >> 1);
+ rc.bottom = rc.top + textSize.cy;
+ if (rc.right < rc.left + 4)
+ rc.right = clRect.right + 1;
+ else
+ TextOutA(hdcMem, rc.right, rc.top + groupCountsFontTopShift, szCounts, lstrlenA(szCounts));
+ ChangeToFont(hdcMem, dat, FONTID_GROUPS, &fontHeight);
+ if (selected)
+ SetTextColor(hdcMem, dat->selTextColour);
+ else if (hottrack)
+ SetHotTrackColour(hdcMem, dat);
+ rc.right--;
+ ExtTextOut(hdcMem, rc.left, rc.top, ETO_CLIPPED, &rc, group->cl.items[group->scanIndex]->szText,
+ lstrlen(group->cl.items[group->scanIndex]->szText), NULL);
+ }
+ else
+ TextOut(hdcMem, dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace,
+ y + ((dat->rowHeight - fontHeight) >> 1), group->cl.items[group->scanIndex]->szText,
+ lstrlen(group->cl.items[group->scanIndex]->szText));
+ if (dat->exStyle & CLS_EX_LINEWITHGROUPS) {
+ rc.top = y + (dat->rowHeight >> 1);
+ rc.bottom = rc.top + 2;
+ rc.left = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace + width + 3;
+ rc.right = clRect.right - 1 - dat->extraColumnSpacing * dat->extraColumnsCount;
+ if (rc.right - rc.left > 1)
+ DrawEdge(hdcMem, &rc, BDR_SUNKENOUTER, BF_RECT);
+ }
+ }
+ else {
+ TCHAR *szText = group->cl.items[group->scanIndex]->szText;
+ RECT rc;
+ rc.left = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace;
+ rc.top = y + ((dat->rowHeight - fontHeight) >> 1);
+ rc.right = (clRect.right - clRect.left);
+ rc.bottom = rc.top;
+ DrawText(hdcMem, szText, lstrlen(szText), &rc, DT_EDITCONTROL | DT_NOPREFIX | DT_NOCLIP | DT_WORD_ELLIPSIS | DT_SINGLELINE);
+ }
+ if (selected) {
+ if (group->cl.items[group->scanIndex]->type != CLCIT_DIVIDER) {
+ TCHAR *szText = group->cl.items[group->scanIndex]->szText;
+ RECT rc;
+ int qlen = lstrlen(dat->szQuickSearch);
+ SetTextColor(hdcMem, dat->quickSearchColour);
+ rc.left = dat->leftMargin + indent * dat->groupIndent + checkboxWidth + dat->iconXSpace;
+ rc.top = y + ((dat->rowHeight - fontHeight) >> 1);
+ rc.right = (clRect.right - clRect.left);
+ rc.bottom = rc.top;
+ if (qlen)
+ DrawText(hdcMem, szText, qlen, &rc, DT_EDITCONTROL | DT_NOPREFIX | DT_NOCLIP | DT_WORD_ELLIPSIS | DT_SINGLELINE);
+ }
+ }
+
+ //extra icons
+ for (iImage = 0; iImage < dat->extraColumnsCount; iImage++) {
+ COLORREF colourFg = dat->selBkColour;
+ int mode = ILD_NORMAL;
+ if (group->cl.items[group->scanIndex]->iExtraImage[iImage] == 0xFF)
+ continue;
+ if (selected)
+ mode = ILD_SELECTED;
+ else if (hottrack) {
+ mode = ILD_FOCUS;
+ colourFg = dat->hotTextColour;
+ }
+ else if (group->cl.items[group->scanIndex]->type == CLCIT_CONTACT && group->cl.items[group->scanIndex]->flags & CONTACTF_NOTONLIST) {
+ colourFg = dat->fontInfo[FONTID_NOTONLIST].colour;
+ mode = ILD_BLEND50;
+ }
+ ImageList_DrawEx(dat->himlExtraColumns, group->cl.items[group->scanIndex]->iExtraImage[iImage], hdcMem,
+ clRect.right - dat->extraColumnSpacing * (dat->extraColumnsCount - iImage), y + ((dat->rowHeight - 16) >> 1), 0, 0,
+ CLR_NONE, colourFg, mode);
+ }
+ }
+ index++;
+ y += dat->rowHeight;
+ if (group->cl.items[group->scanIndex]->type == CLCIT_GROUP && group->cl.items[group->scanIndex]->group->expanded) {
+ group = group->cl.items[group->scanIndex]->group;
+ indent++;
+ group->scanIndex = 0;
+ continue;
+ }
+ group->scanIndex++;
+ }
+ if (dat->iInsertionMark != -1) { //insertion mark
+ HBRUSH hBrush, hoBrush;
+ POINT pts[8];
+ HRGN hRgn;
+
+ pts[0].x = dat->leftMargin;
+ pts[0].y = dat->iInsertionMark * dat->rowHeight - dat->yScroll - 4;
+ pts[1].x = pts[0].x + 2;
+ pts[1].y = pts[0].y + 3;
+ pts[2].x = clRect.right - 4;
+ pts[2].y = pts[1].y;
+ pts[3].x = clRect.right - 1;
+ pts[3].y = pts[0].y - 1;
+ pts[4].x = pts[3].x;
+ pts[4].y = pts[0].y + 7;
+ pts[5].x = pts[2].x + 1;
+ pts[5].y = pts[1].y + 2;
+ pts[6].x = pts[1].x;
+ pts[6].y = pts[5].y;
+ pts[7].x = pts[0].x;
+ pts[7].y = pts[4].y;
+ hRgn = CreatePolygonRgn(pts, SIZEOF(pts), ALTERNATE);
+ hBrush = CreateSolidBrush(dat->fontInfo[FONTID_CONTACTS].colour);
+ hoBrush = (HBRUSH) SelectObject(hdcMem, hBrush);
+ FillRgn(hdcMem, hRgn, hBrush);
+ SelectObject(hdcMem, hoBrush);
+ DeleteObject(hBrush);
+ }
+ if (!grey)
+ BitBlt(hdc, rcPaint->left, rcPaint->top, rcPaint->right - rcPaint->left, rcPaint->bottom - rcPaint->top, hdcMem, rcPaint->left, rcPaint->top,
+ SRCCOPY);
+ SelectObject(hdcMem,hOldBitmap);
+ SelectObject(hdcMem,hOldFont);
+ DeleteDC(hdcMem);
+ if (hBrushAlternateGrey)
+ DeleteObject(hBrushAlternateGrey);
+ if (grey) {
+ PBYTE bits;
+ BITMAPINFOHEADER bmih = { 0 };
+ int i;
+ int greyRed, greyGreen, greyBlue;
+ COLORREF greyColour;
+ bmih.biBitCount = 32;
+ bmih.biSize = sizeof(bmih);
+ bmih.biCompression = BI_RGB;
+ bmih.biHeight = -clRect.bottom;
+ bmih.biPlanes = 1;
+ bmih.biWidth = clRect.right;
+ bits = (PBYTE) malloc(4 * bmih.biWidth * -bmih.biHeight);
+ GetDIBits(hdc, hBmpOsb, 0, clRect.bottom, bits, (BITMAPINFO *) & bmih, DIB_RGB_COLORS);
+ greyColour = GetSysColor(COLOR_3DFACE);
+ greyRed = GetRValue(greyColour) * 2;
+ greyGreen = GetGValue(greyColour) * 2;
+ greyBlue = GetBValue(greyColour) * 2;
+ if (divide3[0] == 255) {
+ for (i = 0; i < SIZEOF(divide3); i++)
+ divide3[i] = (i + 1) / 3;
+ }
+ for (i = 4 * clRect.right * clRect.bottom - 4; i >= 0; i -= 4) {
+ bits[i] = divide3[bits[i] + greyBlue];
+ bits[i + 1] = divide3[bits[i + 1] + greyGreen];
+ bits[i + 2] = divide3[bits[i + 2] + greyRed];
+ }
+ SetDIBitsToDevice(hdc, 0, 0, clRect.right, clRect.bottom, 0, 0, 0, clRect.bottom, bits, (BITMAPINFO *) & bmih, DIB_RGB_COLORS);
+ free(bits);
+ }
+ DeleteObject(hBmpOsb);
+}
diff --git a/miranda-wine/plugins/clist/clist.h b/miranda-wine/plugins/clist/clist.h new file mode 100644 index 0000000..4184dbe --- /dev/null +++ b/miranda-wine/plugins/clist/clist.h @@ -0,0 +1,30 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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.
+*/
+void LoadContactTree(void);
+int IconFromStatusMode(const char *szProto,int status);
+HTREEITEM GetTreeItemByHContact(HANDLE hContact);
+void TrayIconUpdateWithImageList(int iImage,const char *szNewTip,char *szPreferredProto);
+void SortContacts(void);
+void ChangeContactIcon(HANDLE hContact,int iIcon,int add);
+
+#define NEWSTR_ALLOCA(A) (A==NULL)?NULL:strcpy((char*)alloca(strlen(A)+1),A)
diff --git a/miranda-wine/plugins/clist/clistmenus.c b/miranda-wine/plugins/clist/clistmenus.c new file mode 100644 index 0000000..0480afa --- /dev/null +++ b/miranda-wine/plugins/clist/clistmenus.c @@ -0,0 +1,947 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 FIRSTCUSTOMMENUITEMID 30000
+#define MENU_CUSTOMITEMMAIN 0x80000000
+#define MENU_CUSTOMITEMCONTEXT 0x40000000
+#define SEPARATORPOSITIONINTERVAL 100000
+
+struct CListMenuItem
+{
+ WORD id;
+ int iconId;
+ CLISTMENUITEM mi;
+};
+
+static int nextMenuId;
+static struct CListMenuItem *mainMenuItem, *contextMenuItem;
+static int mainItemCount, contextItemCount;
+static HIMAGELIST hImlMenuIcons;
+static HANDLE hPreBuildContactMenuEvent, hAckHook;
+static HMENU hMainMenu, hStatusMenu, hRootMenu;
+int currentStatusMenuItem, currentDesiredStatusMode;
+static int statusModeList[] =
+{
+ ID_STATUS_OFFLINE, ID_STATUS_ONLINE, ID_STATUS_AWAY, ID_STATUS_NA, ID_STATUS_OCCUPIED, ID_STATUS_DND, ID_STATUS_FREECHAT, ID_STATUS_INVISIBLE,
+ ID_STATUS_ONTHEPHONE, ID_STATUS_OUTTOLUNCH
+};
+
+static int skinIconStatusList[] =
+{
+ SKINICON_STATUS_OFFLINE, SKINICON_STATUS_ONLINE, SKINICON_STATUS_AWAY, SKINICON_STATUS_NA, SKINICON_STATUS_OCCUPIED, SKINICON_STATUS_DND,
+ SKINICON_STATUS_FREE4CHAT, SKINICON_STATUS_INVISIBLE, SKINICON_STATUS_ONTHEPHONE, SKINICON_STATUS_OUTTOLUNCH
+};
+
+static int statusModePf2List[] =
+{ 0xFFFFFFFF, PF2_ONLINE, PF2_SHORTAWAY, PF2_LONGAWAY, PF2_LIGHTDND, PF2_HEAVYDND, PF2_FREECHAT, PF2_INVISIBLE, PF2_ONTHEPHONE, PF2_OUTTOLUNCH };
+
+extern HANDLE hStatusModeChangeEvent;
+
+static TCHAR* LangPackPcharToTchar( const char* pszStr )
+{
+ if ( pszStr == NULL )
+ return NULL;
+
+ #if defined( _UNICODE )
+ { int len = strlen( pszStr );
+ TCHAR* result = ( TCHAR* )alloca(( len+1 )*sizeof( TCHAR ));
+ MultiByteToWideChar( CallService( MS_LANGPACK_GETCODEPAGE, 0, 0 ), 0, pszStr, -1, result, len );
+ result[len] = 0;
+ return wcsdup( TranslateW( result ));
+ }
+ #else
+ return _strdup( Translate( pszStr ));
+ #endif
+}
+
+static void InsertMenuItemWithSeparators(HMENU hMenu, int uItem, BOOL fByPosition, MENUITEMINFO* lpmii)
+{
+ int thisItemPosition, needSeparator;
+ MENUITEMINFO mii;
+
+ if (lpmii->fMask & MIIM_SUBMENU)
+ thisItemPosition = (int) lpmii->dwItemData;
+ else
+ thisItemPosition = mainMenuItem[lpmii->dwItemData & ~MENU_CUSTOMITEMMAIN].mi.position;
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ //check for separator before
+ if (uItem) {
+ mii.fMask = MIIM_SUBMENU | MIIM_DATA | MIIM_TYPE;
+ GetMenuItemInfo(hMenu, uItem - 1, TRUE, &mii);
+ if (mii.fType == MFT_SEPARATOR)
+ needSeparator = 0;
+ else if (mii.hSubMenu == NULL && (mii.dwItemData & MENU_CUSTOMITEMMAIN) == 0)
+ needSeparator = 0;
+ else if (mii.hSubMenu == NULL)
+ needSeparator =
+ ((mainMenuItem[mii.dwItemData & ~MENU_CUSTOMITEMMAIN].mi.position) / SEPARATORPOSITIONINTERVAL) !=
+ thisItemPosition / SEPARATORPOSITIONINTERVAL;
+ else
+ needSeparator = ((int) mii.dwItemData) / SEPARATORPOSITIONINTERVAL != thisItemPosition / SEPARATORPOSITIONINTERVAL;
+ if (needSeparator) {
+ //but might be supposed to be after the next one instead
+ mii.fType = 0;
+ if (uItem < GetMenuItemCount(hMenu)) {
+ mii.fMask = MIIM_SUBMENU | MIIM_DATA | MIIM_TYPE;
+ GetMenuItemInfo(hMenu, uItem, TRUE, &mii);
+ }
+ if (mii.fType != MFT_SEPARATOR) {
+ mii.fMask = MIIM_TYPE;
+ mii.fType = MFT_SEPARATOR;
+ InsertMenuItem(hMenu, uItem, TRUE, &mii);
+ }
+ uItem++;
+ }
+ }
+ //check for separator after
+ if (uItem < GetMenuItemCount(hMenu)) {
+ mii.fMask = MIIM_SUBMENU | MIIM_DATA | MIIM_TYPE;
+ mii.cch = 0;
+ GetMenuItemInfo(hMenu, uItem, TRUE, &mii);
+ if (mii.fType == MFT_SEPARATOR)
+ needSeparator = 0;
+ else if (mii.hSubMenu == NULL && (mii.dwItemData & MENU_CUSTOMITEMMAIN) == 0)
+ needSeparator = 0;
+ else if (mii.hSubMenu == NULL)
+ needSeparator =
+ ((mainMenuItem[mii.dwItemData & ~MENU_CUSTOMITEMMAIN].mi.position) / SEPARATORPOSITIONINTERVAL) !=
+ thisItemPosition / SEPARATORPOSITIONINTERVAL;
+ else
+ needSeparator = ((int) mii.dwItemData) / SEPARATORPOSITIONINTERVAL != thisItemPosition / SEPARATORPOSITIONINTERVAL;
+ if (needSeparator) {
+ mii.fMask = MIIM_TYPE;
+ mii.fType = MFT_SEPARATOR;
+ InsertMenuItem(hMenu, uItem, TRUE, &mii);
+ }
+ }
+ if (uItem == GetMenuItemCount(hMenu) - 1) {
+ TCHAR str[32];
+ mii.fMask = MIIM_SUBMENU | MIIM_DATA | MIIM_TYPE;
+ mii.dwTypeData = str;
+ mii.cch = SIZEOF(str);
+ GetMenuItemInfo(hMenu, uItem, TRUE, &mii);
+ if (mii.fType == MFT_STRING && !_tcscmp(mii.dwTypeData, TranslateT("E&xit"))) {
+ //make sure we keep the separator before the exit menu item
+ mii.fMask = MIIM_TYPE;
+ mii.fType = MFT_SEPARATOR;
+ InsertMenuItem(hMenu, uItem, TRUE, &mii);
+ }
+ }
+ InsertMenuItem(hMenu, uItem, TRUE, lpmii);
+}
+
+//#define PUTPOSITIONSONMENU
+static int AddMainMenuItem(WPARAM wParam, LPARAM lParam)
+{
+ CLISTMENUITEM *mi = (CLISTMENUITEM *) lParam;
+ MENUITEMINFO mii;
+ TCHAR* ptszName;
+ int i;
+ HMENU hMenu;
+
+ if (mi==NULL || mi->cbSize != sizeof(CLISTMENUITEM))
+ return 0;
+ mainMenuItem = (struct CListMenuItem *) realloc(mainMenuItem, sizeof(struct CListMenuItem) * (mainItemCount + 1));
+ mainMenuItem[mainItemCount].id = nextMenuId++;
+ mainMenuItem[mainItemCount].mi = *mi;
+ mainMenuItem[mainItemCount].mi.pszService = strdup(mi->pszService);
+ mainMenuItem[mainItemCount].mi.pszContactOwner = NULL;
+ mainMenuItem[mainItemCount].mi.pszName = NULL;
+ if (mi->hIcon == NULL)
+ mainMenuItem[mainItemCount].iconId = -1;
+ else
+ mainMenuItem[mainItemCount].iconId = ImageList_AddIcon(hImlMenuIcons, mi->hIcon);
+ hMenu = hMainMenu;
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
+ if (mi->pszPopupName != NULL) {
+ TCHAR str[80];
+ TCHAR* ptszPopupName = LangPackPcharToTchar( mi->pszPopupName );
+ for (i = GetMenuItemCount(hMenu) - 1; i >= 0; i--) {
+ mii.cch = SIZEOF(str);
+ mii.dwTypeData = str;
+ GetMenuItemInfo(hMenu, i, TRUE, &mii);
+#ifdef PUTPOSITIONSONMENU
+ if (mii.hSubMenu != NULL && !_tcsnicmp(str, ptszPopupName, _tcslen(ptszPopupName)))
+ break;
+#else
+ if (mii.hSubMenu != NULL && !_tcsicmp(str, ptszPopupName))
+ break;
+#endif
+ }
+ if (i < 0) {
+ mii.fMask = MIIM_SUBMENU | MIIM_DATA | MIIM_TYPE;
+ for (i = GetMenuItemCount(hMenu) - 1; i >= 0; i--) {
+ mii.cch = SIZEOF(str);
+ mii.dwTypeData = str;
+ GetMenuItemInfo(hMenu, i, TRUE, &mii);
+ if (mii.fType == MFT_SEPARATOR)
+ continue;
+ if (mii.hSubMenu == NULL && (mii.dwItemData & MENU_CUSTOMITEMMAIN) == 0)
+ continue;
+ if (mii.hSubMenu == NULL) {
+ if (mainMenuItem[mii.dwItemData & ~MENU_CUSTOMITEMMAIN].mi.position <= mainMenuItem[mainItemCount].mi.popupPosition)
+ break;
+ }
+ else {
+ if ((int) mii.dwItemData <= mainMenuItem[mainItemCount].mi.popupPosition)
+ break;
+ } }
+
+ i++;
+ mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_SUBMENU;
+ mii.fType = MFT_STRING;
+ mii.dwItemData = (DWORD) mi->popupPosition;
+ mii.hSubMenu = CreatePopupMenu();
+#ifdef PUTPOSITIONSONMENU
+ {
+ TCHAR str[256];
+ mir_sntprintf(str, SIZEOF(str), "%s (%d)", ptszPopupName, mi->popupPosition);
+ mii.dwTypeData = str;
+ InsertMenuItemWithSeparators(hMenu, i, TRUE, &mii);
+ }
+#else
+ mii.dwTypeData = ptszPopupName;
+ InsertMenuItemWithSeparators(hMenu, i, TRUE, &mii);
+#endif
+ }
+ free(ptszPopupName);
+ hMenu = mii.hSubMenu;
+ }
+ mii.fMask = MIIM_SUBMENU | MIIM_DATA;
+ for (i = GetMenuItemCount(hMenu) - 1; i >= 0; i--) {
+ GetMenuItemInfo(hMenu, i, TRUE, &mii);
+ if (mii.fType == MFT_SEPARATOR)
+ continue;
+ if (mii.hSubMenu == NULL && (mii.dwItemData & MENU_CUSTOMITEMMAIN) == 0)
+ continue;
+ if (mii.hSubMenu == NULL) {
+ if (mainMenuItem[mii.dwItemData & ~MENU_CUSTOMITEMMAIN].mi.position <= mainMenuItem[mainItemCount].mi.position)
+ break;
+ }
+ else {
+ if ((int) mii.dwItemData <= mainMenuItem[mainItemCount].mi.position)
+ break;
+ }
+ }
+ i++;
+ if (!IsWinVer98Plus()) {
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_ID;
+ }
+ else {
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA | MIIM_ID | MIIM_STRING;
+ if (mainMenuItem[mainItemCount].iconId != -1)
+ mii.fMask |= MIIM_BITMAP;
+ }
+ ptszName = LangPackPcharToTchar( mi->pszName );
+
+ mii.fType = MFT_STRING;
+ mii.wID = mainMenuItem[mainItemCount].id;
+ mii.dwItemData = mainItemCount | MENU_CUSTOMITEMMAIN;
+ mii.hbmpItem = HBMMENU_CALLBACK;
+#ifdef PUTPOSITIONSONMENU
+ {
+ TCHAR str[256];
+ mir_sntprintf(str, SIZEOF(str), "%s (%d)", ptszName, mi->position);
+ mii.dwTypeData = str;
+ InsertMenuItemWithSeparators(hMenu, i, TRUE, &mii);
+ }
+#else
+ mii.dwTypeData = ptszName;
+ InsertMenuItemWithSeparators(hMenu, i, TRUE, &mii);
+#endif
+ free( ptszName );
+ mainItemCount++;
+ return MENU_CUSTOMITEMMAIN | (mainItemCount - 1);
+}
+
+static int AddContactMenuItem(WPARAM wParam, LPARAM lParam)
+{
+ CLISTMENUITEM *mi = (CLISTMENUITEM *) lParam;
+
+ if (mi==NULL || mi->cbSize != sizeof(CLISTMENUITEM))
+ return 0;
+ contextMenuItem = (struct CListMenuItem *) realloc(contextMenuItem, sizeof(struct CListMenuItem) * (contextItemCount + 1));
+ contextMenuItem[contextItemCount].id = nextMenuId++;
+ contextMenuItem[contextItemCount].mi = *mi;
+ contextMenuItem[contextItemCount].mi.pszService = strdup(mi->pszService);
+ contextMenuItem[contextItemCount].mi.ptszName = LangPackPcharToTchar(mi->pszName);
+ if (mi->pszContactOwner != NULL)
+ contextMenuItem[contextItemCount].mi.pszContactOwner = strdup(mi->pszContactOwner);
+ if (mi->hIcon == NULL)
+ contextMenuItem[contextItemCount].iconId = -1;
+ else
+ contextMenuItem[contextItemCount].iconId = ImageList_AddIcon(hImlMenuIcons, mi->hIcon);
+ contextItemCount++;
+ return MENU_CUSTOMITEMCONTEXT | (contextItemCount - 1);
+}
+
+static int ModifyCustomMenuItem(WPARAM wParam, LPARAM lParam)
+{
+ struct CListMenuItem *clmi;
+ CLISTMENUITEM *mi = (CLISTMENUITEM *) lParam;
+ MENUITEMINFO mii;
+
+ if (mi==NULL || mi->cbSize != sizeof(CLISTMENUITEM))
+ return 1;
+ if (wParam & MENU_CUSTOMITEMMAIN) {
+ if ((int) (wParam & ~MENU_CUSTOMITEMMAIN) >= mainItemCount)
+ return 1;
+ clmi = mainMenuItem + (wParam & ~MENU_CUSTOMITEMMAIN);
+ }
+ else if (wParam & MENU_CUSTOMITEMCONTEXT) {
+ if ((int) (wParam & ~MENU_CUSTOMITEMCONTEXT) >= contextItemCount)
+ return 1;
+ clmi = contextMenuItem + (wParam & ~MENU_CUSTOMITEMCONTEXT);
+ }
+ else
+ return 1;
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ if (mi->flags & CMIM_NAME) {
+ if (clmi->mi.pszName != NULL)
+ free(clmi->mi.pszName);
+ clmi->mi.ptszName = LangPackPcharToTchar(mi->pszName);
+ if (wParam & MENU_CUSTOMITEMMAIN) {
+ mii.fMask = IsWinVer98Plus()? MIIM_STRING : MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = clmi->mi.ptszName;
+ SetMenuItemInfo(hMainMenu, clmi->id, FALSE, &mii);
+ }
+ }
+ if (mi->flags & CMIM_FLAGS) {
+ clmi->mi.flags = mi->flags & ~CMIM_ALL;
+ if (wParam & MENU_CUSTOMITEMMAIN) {
+ mii.fMask = MIIM_STATE;
+ mii.fState = ((clmi->mi.flags & CMIF_GRAYED) ? MFS_GRAYED : 0) | ((clmi->mi.flags & CMIF_CHECKED) ? MFS_CHECKED : 0);
+ SetMenuItemInfo(hMainMenu, clmi->id, FALSE, &mii);
+ }
+ }
+ if (mi->flags & CMIM_ICON) {
+ clmi->mi.hIcon = mi->hIcon;
+ if (mi->hIcon != NULL)
+ clmi->iconId = ImageList_ReplaceIcon(hImlMenuIcons, clmi->iconId, mi->hIcon);
+ else
+ clmi->iconId = -1; //fixme, should remove old icon & shuffle all iconIds
+ }
+ if (mi->flags & CMIM_HOTKEY) {
+ clmi->mi.hotKey = mi->hotKey;
+ }
+ return 0;
+}
+
+int MenuProcessCommand(WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ PROTOCOLDESCRIPTOR **proto;
+ int protoCount;
+
+ if (HIWORD(wParam) & MPCF_MAINMENU) {
+ int newStatus, protoIndex;
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM) & protoCount, (LPARAM) & proto);
+ if (LOWORD(wParam) >= ID_STATUS_OFFLINE + SIZEOF(statusModeList)
+ && LOWORD(wParam) < ID_STATUS_OFFLINE + (protoCount + 1) * SIZEOF(statusModeList)) {
+ // one of the protocol-specific status menus
+ protoIndex = (LOWORD(wParam) - ID_STATUS_OFFLINE) / SIZEOF(statusModeList) - 1;
+ newStatus = (LOWORD(wParam) - ID_STATUS_OFFLINE) % SIZEOF(statusModeList) + ID_STATUS_OFFLINE;
+ // let the world know, this need's the translated ID_STATUS_* NOT LOWORD(wParam)
+ // which is offseted by some degree depending on protocol used
+ CallProtoService(proto[protoIndex]->szName, PS_SETSTATUS, newStatus, 0);
+ NotifyEventHooks(hStatusModeChangeEvent, newStatus, (LPARAM) proto[protoIndex]->szName);
+ }
+ switch (LOWORD(wParam)) {
+ case ID_STATUS_OFFLINE:
+ case ID_STATUS_ONLINE:
+ case ID_STATUS_AWAY:
+ case ID_STATUS_DND:
+ case ID_STATUS_NA:
+ case ID_STATUS_OCCUPIED:
+ case ID_STATUS_FREECHAT:
+ case ID_STATUS_INVISIBLE:
+ case ID_STATUS_OUTTOLUNCH:
+ case ID_STATUS_ONTHEPHONE:
+ currentDesiredStatusMode = LOWORD(wParam);
+ for (i = 0; i < protoCount; i++)
+ CallProtoService(proto[i]->szName, PS_SETSTATUS, LOWORD(wParam), 0);
+ DBWriteContactSettingWord(NULL, "CList", "Status", (WORD) currentDesiredStatusMode);
+ NotifyEventHooks(hStatusModeChangeEvent, LOWORD(wParam), 0);
+ return 1;
+ }
+ for (i = 0; i < mainItemCount; i++) {
+ if (LOWORD(wParam) == mainMenuItem[i].id) {
+ CallService(mainMenuItem[i].mi.pszService, 0, (LPARAM) NULL);
+ return 1;
+ }
+ }
+ }
+ if (HIWORD(wParam) & MPCF_CONTACTMENU) {
+ for (i = 0; i < contextItemCount; i++) {
+ if (LOWORD(wParam) == contextMenuItem[i].id) {
+ if ((HANDLE) lParam != NULL)
+ CallService(contextMenuItem[i].mi.pszService, lParam, (LPARAM) (HWND) NULL);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static int MenuProcessHotkey(WPARAM vKey, LPARAM lParam)
+{
+ int i;
+
+ if (lParam & MPCF_MAINMENU) {
+ if (vKey >= '0' && vKey <= '9' && GetKeyState(VK_CONTROL) & 0x8000 && !(GetKeyState(VK_MENU) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000)) {
+ MenuProcessCommand(MAKEWPARAM(statusModeList[vKey - '0'], MPCF_MAINMENU), 0);
+ return 1;
+ }
+ for (i = 0; i < mainItemCount; i++) {
+ if (mainMenuItem[i].mi.hotKey == 0)
+ continue;
+ if (HIWORD(mainMenuItem[i].mi.hotKey) != vKey)
+ continue;
+ if (!(LOWORD(mainMenuItem[i].mi.hotKey) & MOD_ALT) != !(GetKeyState(VK_MENU) & 0x8000))
+ continue;
+ if (!(LOWORD(mainMenuItem[i].mi.hotKey) & MOD_CONTROL) != !(GetKeyState(VK_CONTROL) & 0x8000))
+ continue;
+ if (!(LOWORD(mainMenuItem[i].mi.hotKey) & MOD_SHIFT) != !(GetKeyState(VK_SHIFT) & 0x8000))
+ continue;
+ CallService(mainMenuItem[i].mi.pszService, 0, (LPARAM) NULL);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+//straight subtraction is not possible because I was getting overflows
+static int MenuSortProc(int *item1, int *item2)
+{
+ if (contextMenuItem[*item2].mi.position > contextMenuItem[*item1].mi.position)
+ return 1;
+ if (contextMenuItem[*item2].mi.position < contextMenuItem[*item1].mi.position)
+ return -1;
+ return 0;
+}
+
+static int BuildContactMenu(WPARAM wParam, LPARAM lParam)
+{
+ HMENU hMenu;
+ MENUITEMINFO mii;
+ int i;
+ int *itemOrder, itemCount;
+ int isOnline, isOnList;
+ HANDLE hContact = (HANDLE) wParam;
+ int prevPosition;
+ int chatRoom;
+ DWORD miim_bitmap_verSpecific;
+ char *szProto;
+
+ NotifyEventHooks(hPreBuildContactMenuEvent, (WPARAM) hContact, 0);
+
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ isOnList = 0 == DBGetContactSettingByte(hContact, "CList", "NotOnList", 0);
+ isOnline = szProto != NULL && ID_STATUS_OFFLINE != DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE);
+ chatRoom = szProto?DBGetContactSettingByte(hContact, szProto, "ChatRoom", 0):0;
+ if ( contextItemCount ) {
+ itemOrder = (int *) malloc(sizeof(int) * contextItemCount);
+ ZeroMemory(itemOrder, sizeof(int) * contextItemCount);
+ } else {
+ itemOrder = (int *) malloc(sizeof(int) * 1);
+ ZeroMemory(itemOrder, sizeof(int) * 1);
+ }
+ itemCount = 0;
+ for (i = 0; i < contextItemCount; i++) {
+ if (contextMenuItem[i].id == 0)
+ continue;
+ if (szProto == NULL)
+ continue;
+ // Begin Ugly hack to hide chat room menus
+ if (chatRoom) {
+ if (!strcmp(contextMenuItem[i].mi.pszName,Translate("&Message")))
+ continue;
+ if (!strcmp(contextMenuItem[i].mi.pszName,Translate("&File")))
+ continue;
+ if (!strcmp(contextMenuItem[i].mi.pszName,Translate("User &Details")))
+ continue;
+ if (!strcmp(contextMenuItem[i].mi.pszName,Translate("View &History")))
+ continue;
+ }
+ // End ugly hack
+ if (contextMenuItem[i].mi.pszContactOwner != NULL) {
+ if (strcmp(contextMenuItem[i].mi.pszContactOwner, szProto))
+ continue;
+ }
+ if (contextMenuItem[i].mi.flags & CMIF_HIDDEN)
+ continue;
+ if (contextMenuItem[i].mi.flags & CMIF_NOTONLIST && isOnList)
+ continue;
+ if (contextMenuItem[i].mi.flags & CMIF_NOTOFFLIST && !isOnList)
+ continue;
+ if (contextMenuItem[i].mi.flags & CMIF_NOTONLINE && isOnline)
+ continue;
+ if (contextMenuItem[i].mi.flags & CMIF_NOTOFFLINE && !isOnline)
+ continue;
+ itemOrder[itemCount] = i;
+ itemCount++;
+ }
+ //sorts in reverse order since it's easiest to add items bottom to top
+ qsort(itemOrder, itemCount, sizeof(int), (int (*)(const void *, const void *)) MenuSortProc);
+ hMenu = CreatePopupMenu();
+ ZeroMemory(&mii, sizeof(mii));
+ if (!IsWinVer98Plus()) {
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ mii.fMask = MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_TYPE;
+ miim_bitmap_verSpecific = 0;
+ }
+ else {
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_STRING;
+ miim_bitmap_verSpecific = MIIM_BITMAP;
+ }
+ mii.fType = MFT_STRING;
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ prevPosition = contextMenuItem[itemOrder[0]].mi.position;
+ for (i = 0; i < itemCount; i++) {
+ if (prevPosition / SEPARATORPOSITIONINTERVAL != contextMenuItem[itemOrder[i]].mi.position / SEPARATORPOSITIONINTERVAL) {
+ UINT oldMask = mii.fMask;
+ mii.fMask = MIIM_TYPE;
+ mii.fType = MFT_SEPARATOR;
+ InsertMenuItem(hMenu, 0, TRUE, &mii);
+ mii.fMask = oldMask;
+ mii.fType = MFT_STRING;
+ }
+ prevPosition = contextMenuItem[itemOrder[i]].mi.position;
+ if (contextMenuItem[itemOrder[i]].iconId == -1)
+ mii.fMask &= ~miim_bitmap_verSpecific;
+ else
+ mii.fMask |= miim_bitmap_verSpecific;
+ mii.dwItemData = itemOrder[i] | MENU_CUSTOMITEMCONTEXT;
+ mii.fState =
+ ((contextMenuItem[itemOrder[i]].mi.flags & CMIF_GRAYED) ? MFS_GRAYED : MFS_ENABLED) | ((contextMenuItem[itemOrder[i]].mi.
+ flags & CMIF_CHECKED) ? MFS_CHECKED :
+ MFS_UNCHECKED);
+ mii.wID = contextMenuItem[itemOrder[i]].id;
+ mii.dwTypeData = contextMenuItem[itemOrder[i]].mi.ptszName;
+#ifdef _DEBUG
+ if (GetKeyState(VK_CONTROL) & 0x8000) {
+ TCHAR str[256];
+ wsprintf(str, _T("%s (%d)"), contextMenuItem[itemOrder[i]].mi.pszName, contextMenuItem[itemOrder[i]].mi.position);
+ mii.dwTypeData = str;
+ InsertMenuItem(hMenu, 0, TRUE, &mii);
+ }
+ else InsertMenuItem(hMenu, 0, TRUE, &mii);
+#else
+ InsertMenuItem(hMenu, 0, TRUE, &mii);
+#endif
+ }
+ free(itemOrder);
+ return (int) hMenu;
+}
+
+static int MenuIconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ int i, protoCount, networkProtoCount, j;
+ PROTOCOLDESCRIPTOR **proto;
+ DWORD flags;
+ MENUITEMINFO mii;
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_DATA;
+
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM) & protoCount, (LPARAM) & proto);
+ networkProtoCount = 0;
+ for (i = 0; i < protoCount; i++)
+ if (proto[i]->type == PROTOTYPE_PROTOCOL)
+ networkProtoCount++;
+ if (networkProtoCount > 1) {
+ for (i = 0; i < protoCount; i++) {
+ if (proto[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+ flags = CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0);
+ for (j = 0; j < SIZEOF(statusModeList); j++) {
+ if (!(flags & statusModePf2List[j]))
+ continue;
+ if (!GetMenuItemInfo(hStatusMenu, (i + 1) * SIZEOF(statusModeList) + statusModeList[j], FALSE, &mii))
+ continue;
+ if ((mii.dwItemData & MENU_CUSTOMITEMMAIN) != MENU_CUSTOMITEMMAIN)
+ continue;
+ ImageList_ReplaceIcon(hImlMenuIcons, mainMenuItem[mii.dwItemData & ~MENU_CUSTOMITEMMAIN].iconId,
+ LoadSkinnedProtoIcon(proto[i]->szName, statusModeList[j]));
+ } } }
+
+ for (i = 0; i < SIZEOF(statusModeList); i++) {
+ if (!GetMenuItemInfo(hStatusMenu, statusModeList[i], FALSE, &mii))
+ continue;
+ if ((mii.dwItemData & MENU_CUSTOMITEMMAIN) != MENU_CUSTOMITEMMAIN)
+ continue;
+ ImageList_ReplaceIcon(hImlMenuIcons, mainMenuItem[mii.dwItemData & ~MENU_CUSTOMITEMMAIN].iconId,
+ LoadSkinnedProtoIcon(NULL, statusModeList[i]));
+ }
+ return 0;
+}
+
+static void GiveExistingItemAnIcon(UINT id, HICON hIcon)
+{
+ MENUITEMINFO mii;
+
+ mainMenuItem = (struct CListMenuItem *) realloc(mainMenuItem, sizeof(struct CListMenuItem) * (mainItemCount + 1));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_BITMAP | MIIM_DATA;
+ mii.dwItemData = MENU_CUSTOMITEMMAIN | mainItemCount;
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ mainMenuItem[mainItemCount].iconId = ImageList_AddIcon(hImlMenuIcons, hIcon);
+ mainMenuItem[mainItemCount].id = 0xFFFF;
+ mainMenuItem[mainItemCount].mi.hotKey = 0;
+ mainMenuItem[mainItemCount].mi.pszName = NULL;
+ mainMenuItem[mainItemCount].mi.pszService = NULL;
+ SetMenuItemInfo(hStatusMenu, id, FALSE, &mii);
+ mainItemCount++;
+}
+
+static int MeasureMenuItem(WPARAM wParam, LPARAM lParam)
+{
+ struct CListMenuItem *clmi = NULL;
+ LPMEASUREITEMSTRUCT mis = (LPMEASUREITEMSTRUCT) lParam;
+ if (mis->itemData & MENU_CUSTOMITEMCONTEXT)
+ clmi = &contextMenuItem[mis->itemData & ~MENU_CUSTOMITEMCONTEXT];
+ else if (mis->itemData & MENU_CUSTOMITEMMAIN)
+ clmi = &mainMenuItem[mis->itemData & ~MENU_CUSTOMITEMMAIN];
+ if (clmi == NULL)
+ return FALSE;
+ if (clmi->iconId == -1)
+ return FALSE;
+
+ mis->itemWidth = max(0, GetSystemMetrics(SM_CXSMICON) - GetSystemMetrics(SM_CXMENUCHECK) + 4);
+ mis->itemHeight = GetSystemMetrics(SM_CYSMICON) + 2;
+ return TRUE;
+}
+
+static int DrawMenuItem(WPARAM wParam, LPARAM lParam)
+{
+ struct CListMenuItem *clmi = NULL;
+ int y;
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam;
+
+ if (dis->itemData & MENU_CUSTOMITEMCONTEXT)
+ clmi = &contextMenuItem[dis->itemData & ~MENU_CUSTOMITEMCONTEXT];
+ else if (dis->itemData & MENU_CUSTOMITEMMAIN)
+ clmi = &mainMenuItem[dis->itemData & ~MENU_CUSTOMITEMMAIN];
+ if (clmi == NULL)
+ return FALSE;
+ if (clmi->iconId == -1)
+ return FALSE;
+
+ y = (dis->rcItem.bottom - dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2 + 1;
+ if (dis->itemState & ODS_SELECTED) {
+ if (dis->itemState & ODS_CHECKED) {
+ RECT rc;
+ rc.left = 2;
+ rc.right = GetSystemMetrics(SM_CXSMICON) + 2;
+ rc.top = y;
+ rc.bottom = rc.top + GetSystemMetrics(SM_CYSMICON) + 2;
+ FillRect(dis->hDC, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
+ ImageList_DrawEx(hImlMenuIcons, clmi->iconId, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_DEFAULT, ILD_SELECTED);
+ }
+ else
+ ImageList_DrawEx(hImlMenuIcons, clmi->iconId, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_DEFAULT, ILD_FOCUS);
+ }
+ else {
+ if (dis->itemState & ODS_CHECKED) {
+ HBRUSH hBrush;
+ RECT rc;
+ COLORREF menuCol, hiliteCol;
+ rc.left = 0;
+ rc.right = GetSystemMetrics(SM_CXSMICON) + 4;
+ rc.top = y - 2;
+ rc.bottom = rc.top + GetSystemMetrics(SM_CYSMICON) + 4;
+ DrawEdge(dis->hDC, &rc, BDR_SUNKENOUTER, BF_RECT);
+ InflateRect(&rc, -1, -1);
+ menuCol = GetSysColor(COLOR_MENU);
+ hiliteCol = GetSysColor(COLOR_3DHIGHLIGHT);
+ hBrush =
+ CreateSolidBrush(RGB
+ ((GetRValue(menuCol) + GetRValue(hiliteCol)) / 2, (GetGValue(menuCol) + GetGValue(hiliteCol)) / 2,
+ (GetBValue(menuCol) + GetBValue(hiliteCol)) / 2));
+ FillRect(dis->hDC, &rc, hBrush);
+ DeleteObject(hBrush);
+ ImageList_DrawEx(hImlMenuIcons, clmi->iconId, dis->hDC, 2, y, 0, 0, CLR_NONE, GetSysColor(COLOR_MENU), ILD_BLEND25);
+ }
+ else ImageList_DrawEx(hImlMenuIcons, clmi->iconId, dis->hDC, 2, y, 0, 0, CLR_NONE, CLR_NONE, ILD_NORMAL);
+ }
+ return TRUE;
+}
+
+static int MenuGetMain(WPARAM wParam, LPARAM lParam)
+{
+ return (int) hMainMenu;
+}
+
+static int MenuGetStatus(WPARAM wParam, LPARAM lParam)
+{
+ return (int) hStatusMenu;
+}
+
+static int MenuModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ int i, protoCount, networkProtoCount;
+ char *szProto = NULL;
+ char *szLastProto = NULL;
+ PROTOCOLDESCRIPTOR **proto;
+ DWORD statusFlags = 0, flags, moreflags = 0;
+
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM) & protoCount, (LPARAM) & proto);
+ networkProtoCount = 0;
+ for (i = 0; i < protoCount; i++) /* look for valid protocols */
+ if (proto[i]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0) != 0) {
+ networkProtoCount++;
+ szLastProto = proto[i]->szName; /* remember the protocol name, since it maybe the last */
+ } //if
+
+ if (IsWinVer98Plus()) {
+ /* if a single network protocol is used, load the iconset for the global menu by name */
+ if (networkProtoCount == 1)
+ szProto = szLastProto;
+ for (i = 0; i < SIZEOF(statusModeList); i++) {
+ GiveExistingItemAnIcon(statusModeList[i], LoadSkinnedProtoIcon(szProto, statusModeList[i]));
+ }
+ HookEvent(ME_SKIN_ICONSCHANGED, MenuIconsChanged);
+ }
+
+ if (networkProtoCount > 1) {
+ MENUITEMINFO mii;
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ mii.fMask = MIIM_TYPE;
+ mii.fType = MFT_SEPARATOR;
+ mii.dwTypeData = _T("");
+ InsertMenuItem(hStatusMenu, 0, TRUE, &mii);
+ }
+ for (i = 0; i < protoCount; i++) {
+ if (proto[i]->type != PROTOTYPE_PROTOCOL || CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0) == 0)
+ continue;
+ flags = CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0);
+ moreflags = CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_5, 0);
+ if (networkProtoCount > 1) {
+ MENUITEMINFO mii;
+ char protoName[128];
+ int j;
+ HMENU hMenu = GetSubMenu(LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CLISTMENU)), 1);
+ ZeroMemory(&mii, sizeof(mii));
+ for (j = 0; j < SIZEOF(statusModeList); j++) {
+ if (!(flags & statusModePf2List[j]))
+ DeleteMenu(hMenu, statusModeList[j], MF_BYCOMMAND);
+ else if (moreflags & statusModePf2List[j] && j > 0)
+ DeleteMenu(hMenu, statusModeList[j], MF_BYCOMMAND);
+ else {
+ TCHAR text[128], *ptab;
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ mii.fMask = MIIM_TYPE;
+ mii.cch = SIZEOF(text);
+ mii.dwTypeData = text;
+ GetMenuItemInfo(hMenu, statusModeList[j], FALSE, &mii);
+ _tcscpy(text, TranslateTS(text));
+ ptab = _tcschr(text, '\t');
+ if (ptab != NULL)
+ *ptab = '\0';
+ if (IsWinVer98Plus()) {
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_BITMAP | MIIM_DATA | MIIM_STRING;
+ mainMenuItem = (struct CListMenuItem *)realloc(mainMenuItem, sizeof(struct CListMenuItem) * (mainItemCount + 1));
+ mainMenuItem[mainItemCount].iconId =
+ ImageList_AddIcon(hImlMenuIcons, LoadSkinnedProtoIcon(proto[i]->szName, statusModeList[j]));
+ mainMenuItem[mainItemCount].id = 0xFFFF;
+ mainMenuItem[mainItemCount].mi.hotKey = 0;
+ mainMenuItem[mainItemCount].mi.pszName = NULL;
+ mainMenuItem[mainItemCount].mi.pszService = NULL;
+ mii.dwItemData = MENU_CUSTOMITEMMAIN | mainItemCount;
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ mainItemCount++;
+ }
+ else
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.wID = statusModeList[j] + (i + 1) * SIZEOF(statusModeList);
+ SetMenuItemInfo(hMenu, statusModeList[j], FALSE, &mii);
+ }
+ }
+ if (IsWinVer98Plus()) {
+ HICON hIcon;
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_SUBMENU | MIIM_BITMAP | MIIM_DATA | MIIM_STRING;
+ mainMenuItem = (struct CListMenuItem *) realloc(mainMenuItem, sizeof(struct CListMenuItem) * (mainItemCount + 1));
+ hIcon = (HICON) CallProtoService(proto[i]->szName, PS_LOADICON, PLI_PROTOCOL | PLIF_SMALL, 0);
+ mainMenuItem[mainItemCount].iconId = ImageList_AddIcon(hImlMenuIcons, hIcon);
+ DestroyIcon(hIcon);
+ mainMenuItem[mainItemCount].id = 0xFFFF;
+ mainMenuItem[mainItemCount].mi.hotKey = 0;
+ mainMenuItem[mainItemCount].mi.pszName = NULL;
+ mainMenuItem[mainItemCount].mi.pszService = NULL;
+ mii.dwItemData = MENU_CUSTOMITEMMAIN | mainItemCount;
+ mii.hbmpItem = HBMMENU_CALLBACK;
+ mainItemCount++;
+ }
+ else {
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ mii.fMask = MIIM_SUBMENU | MIIM_TYPE;
+ }
+ mii.fType = MFT_STRING;
+ mii.hSubMenu = hMenu;
+ CallProtoService(proto[i]->szName, PS_GETNAME, SIZEOF(protoName), (LPARAM) protoName);
+ { TCHAR* ptszProtoName = LangPackPcharToTchar(protoName);
+ mii.dwTypeData = ptszProtoName;
+ InsertMenuItem(hStatusMenu, 0, TRUE, &mii);
+ free(ptszProtoName);
+ } }
+ statusFlags |= ( flags & ~moreflags );
+ }
+ for (i = 0; i < SIZEOF(statusModeList); i++)
+ if (!(statusFlags & statusModePf2List[i]))
+ DeleteMenu(hStatusMenu, statusModeList[i], MF_BYCOMMAND);
+ return 0;
+}
+
+static int MenuProtoAck(WPARAM wParam, LPARAM lParam)
+{
+ int protoCount, i, networkProtoCount;
+ PROTOCOLDESCRIPTOR **proto;
+ ACKDATA *ack = (ACKDATA *) lParam;
+ int overallStatus = 0, thisStatus;
+
+ if (ack->type != ACKTYPE_STATUS)
+ return 0;
+ if (ack->result != ACKRESULT_SUCCESS)
+ return 0;
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM) & protoCount, (LPARAM) & proto);
+ networkProtoCount = 0;
+ for (i = 0; i < protoCount; i++)
+ if (proto[i]->type == PROTOTYPE_PROTOCOL) {
+ thisStatus = CallProtoService(proto[i]->szName, PS_GETSTATUS, 0, 0);
+ if (overallStatus == 0)
+ overallStatus = thisStatus;
+ else if (overallStatus != thisStatus)
+ overallStatus = -1;
+ networkProtoCount++;
+ }
+ if (overallStatus > ID_STATUS_CONNECTING) {
+ CheckMenuItem(hStatusMenu, currentStatusMenuItem, MF_BYCOMMAND | MF_UNCHECKED);
+ currentStatusMenuItem = overallStatus;
+ CheckMenuItem(hStatusMenu, currentStatusMenuItem, MF_BYCOMMAND | MF_CHECKED);
+ SetMenuDefaultItem(hStatusMenu, currentStatusMenuItem, FALSE);
+ currentDesiredStatusMode = currentStatusMenuItem;
+ }
+ else {
+ CheckMenuItem(hStatusMenu, currentStatusMenuItem, MF_BYCOMMAND | MF_UNCHECKED);
+ SetMenuDefaultItem(hStatusMenu, -1, FALSE);
+ currentStatusMenuItem = 0;
+ }
+ if (networkProtoCount <= 1)
+ return 0;
+ for (i = 0; i < protoCount; i++)
+ if (!strcmp(proto[i]->szName, ack->szModule))
+ break;
+ //hProcess is previous mode, lParam is new mode
+ if ((int) ack->hProcess >= ID_STATUS_OFFLINE && (int) ack->hProcess < ID_STATUS_OFFLINE + SIZEOF(statusModeList))
+ CheckMenuItem(hStatusMenu, (i + 1) * SIZEOF(statusModeList) + (int) ack->hProcess, MF_BYCOMMAND | MF_UNCHECKED);
+ if (ack->lParam >= ID_STATUS_OFFLINE && ack->lParam < ID_STATUS_OFFLINE + SIZEOF(statusModeList))
+ CheckMenuItem(hStatusMenu, (i + 1) * SIZEOF(statusModeList) + ack->lParam, MF_BYCOMMAND | MF_CHECKED);
+ return 0;
+}
+
+static int MenuModulesShutdown(WPARAM wParam, LPARAM lParam)
+{
+ UnhookEvent(hAckHook);
+ return 0;
+}
+
+int InitCustomMenus(void)
+{
+ CreateServiceFunction(MS_CLIST_ADDMAINMENUITEM, AddMainMenuItem);
+ CreateServiceFunction(MS_CLIST_ADDCONTACTMENUITEM, AddContactMenuItem);
+ CreateServiceFunction(MS_CLIST_MODIFYMENUITEM, ModifyCustomMenuItem);
+ CreateServiceFunction(MS_CLIST_MENUMEASUREITEM, MeasureMenuItem);
+ CreateServiceFunction(MS_CLIST_MENUDRAWITEM, DrawMenuItem);
+ CreateServiceFunction(MS_CLIST_MENUBUILDCONTACT, BuildContactMenu);
+ CreateServiceFunction(MS_CLIST_MENUGETMAIN, MenuGetMain);
+ CreateServiceFunction(MS_CLIST_MENUGETSTATUS, MenuGetStatus);
+ CreateServiceFunction(MS_CLIST_MENUPROCESSCOMMAND, MenuProcessCommand);
+ CreateServiceFunction(MS_CLIST_MENUPROCESSHOTKEY, MenuProcessHotkey);
+ hPreBuildContactMenuEvent = CreateHookableEvent(ME_CLIST_PREBUILDCONTACTMENU);
+ hAckHook = (HANDLE) HookEvent(ME_PROTO_ACK, MenuProtoAck);
+ hRootMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CLISTMENU));
+ hMainMenu = GetSubMenu(hRootMenu, 0);
+ hStatusMenu = GetSubMenu(hRootMenu, 1);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hMainMenu, 0);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hStatusMenu, 0);
+ nextMenuId = FIRSTCUSTOMMENUITEMID;
+ mainMenuItem = contextMenuItem = NULL;
+ mainItemCount = contextItemCount = 0;
+ if (IsWinVerXPPlus()) //need 32-bit icons on XP for alpha channels
+ hImlMenuIcons = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, 15, 100);
+ else //Win2k won't blend icons with imagelist_drawex when color-depth>16-bit. Don't know about WinME, but it certainly doesn't support alpha channels
+ hImlMenuIcons = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR16 | ILC_MASK, 15, 100);
+
+ currentStatusMenuItem = ID_STATUS_OFFLINE;
+ currentDesiredStatusMode = ID_STATUS_OFFLINE;
+ {
+ MENUITEMINFO mii;
+ mii.cbSize = MENUITEMINFO_V4_SIZE;
+ mii.fMask = MIIM_STATE;
+ mii.fState = MFS_CHECKED | MFS_DEFAULT;
+ SetMenuItemInfo(hStatusMenu, currentStatusMenuItem, FALSE, &mii);
+ }
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, MenuModulesLoaded);
+ HookEvent(ME_SYSTEM_SHUTDOWN, MenuModulesShutdown);
+ return 0;
+}
+
+void UninitCustomMenus(void)
+{
+ int i;
+
+ ImageList_Destroy(hImlMenuIcons);
+ for (i = 0; i < mainItemCount; i++) {
+ if (mainMenuItem[i].mi.pszName != NULL)
+ free(mainMenuItem[i].mi.pszName);
+ if (mainMenuItem[i].mi.pszService != NULL)
+ free(mainMenuItem[i].mi.pszService);
+ }
+ for (i = 0; i < contextItemCount; i++) {
+ if (contextMenuItem[i].mi.pszName != NULL)
+ free(contextMenuItem[i].mi.pszName);
+ if (contextMenuItem[i].mi.pszService != NULL)
+ free(contextMenuItem[i].mi.pszService);
+ if (contextMenuItem[i].mi.pszContactOwner != NULL)
+ free(contextMenuItem[i].mi.pszContactOwner);
+ }
+ free(mainMenuItem);
+ free(contextMenuItem);
+ DestroyMenu(hStatusMenu);
+ DestroyMenu(hMainMenu);
+ DestroyMenu(hRootMenu);
+}
diff --git a/miranda-wine/plugins/clist/clistopts.c b/miranda-wine/plugins/clist/clistopts.c new file mode 100644 index 0000000..7db1efa --- /dev/null +++ b/miranda-wine/plugins/clist/clistopts.c @@ -0,0 +1,353 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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"
+
+static BOOL CALLBACK DlgProcGenOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_USER + 1:
+ {
+ HANDLE hContact = (HANDLE) wParam;
+ DBCONTACTWRITESETTING *ws = (DBCONTACTWRITESETTING *) lParam;
+ if (hContact == NULL && ws != NULL && ws->szModule != NULL && ws->szSetting != NULL
+ && lstrcmpiA(ws->szModule, "CList") == 0 && lstrcmpiA(ws->szSetting, "UseGroups") == 0 && IsWindowVisible(hwndDlg)) {
+ CheckDlgButton(hwndDlg, IDC_DISABLEGROUPS, ws->value.bVal == 0);
+ }
+ break;
+ }
+ case WM_DESTROY:
+ {
+ UnhookEvent((HANDLE) GetWindowLong(hwndDlg, GWL_USERDATA));
+ break;
+ }
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) HookEventMessage(ME_DB_CONTACT_SETTINGCHANGED, hwndDlg, WM_USER + 1));
+ CheckDlgButton(hwndDlg, IDC_ONTOP, DBGetContactSettingByte(NULL, "CList", "OnTop", SETTING_ONTOP_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_HIDEOFFLINE,
+ DBGetContactSettingByte(NULL, "CList", "HideOffline", SETTING_HIDEOFFLINE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_HIDEEMPTYGROUPS,
+ DBGetContactSettingByte(NULL, "CList", "HideEmptyGroups", SETTING_HIDEEMPTYGROUPS_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DISABLEGROUPS,
+ DBGetContactSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT) ? BST_UNCHECKED : BST_CHECKED);
+ CheckDlgButton(hwndDlg, IDC_SORTBYNAME, !DBGetContactSettingByte(NULL, "CList", "SortByStatus", SETTING_SORTBYSTATUS_DEFAULT)
+ && !DBGetContactSettingByte(NULL, "CList", "SortByProto", SETTING_SORTBYPROTO_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SORTBYSTATUS,
+ DBGetContactSettingByte(NULL, "CList", "SortByStatus", SETTING_SORTBYSTATUS_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SORTBYPROTO,
+ DBGetContactSettingByte(NULL, "CList", "SortByProto", SETTING_SORTBYPROTO_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_CONFIRMDELETE,
+ DBGetContactSettingByte(NULL, "CList", "ConfirmDelete", SETTING_CONFIRMDELETE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AUTOHIDE,
+ DBGetContactSettingByte(NULL, "CList", "AutoHide", SETTING_AUTOHIDE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HIDETIME), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HIDETIMESPIN), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ {
+ DWORD caps = CallService(MS_CLUI_GETCAPS, CLUICAPS_FLAGS1, 0);
+ if (!(caps & CLUIF_HIDEEMPTYGROUPS))
+ ShowWindow(GetDlgItem(hwndDlg, IDC_HIDEEMPTYGROUPS), SW_HIDE);
+ if (!(caps & CLUIF_DISABLEGROUPS))
+ ShowWindow(GetDlgItem(hwndDlg, IDC_DISABLEGROUPS), SW_HIDE);
+ if (caps & CLUIF_HASONTOPOPTION)
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ONTOP), SW_HIDE);
+ if (caps & CLUIF_HASAUTOHIDEOPTION) {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_AUTOHIDE), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_HIDETIME), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_HIDETIMESPIN), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STAUTOHIDESECS), SW_HIDE);
+ }
+ }
+ SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_SETRANGE, 0, MAKELONG(900, 1));
+ SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_SETPOS, 0,
+ MAKELONG(DBGetContactSettingWord(NULL, "CList", "HideTime", SETTING_HIDETIME_DEFAULT), 0));
+ CheckDlgButton(hwndDlg, IDC_ONECLK,
+ DBGetContactSettingByte(NULL, "CList", "Tray1Click", SETTING_TRAY1CLICK_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ALWAYSSTATUS,
+ DBGetContactSettingByte(NULL, "CList", "AlwaysStatus", SETTING_ALWAYSSTATUS_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ALWAYSMULTI,
+ !DBGetContactSettingByte(NULL, "CList", "AlwaysMulti", SETTING_ALWAYSMULTI_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DONTCYCLE,
+ DBGetContactSettingByte(NULL, "CList", "TrayIcon",
+ SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_SINGLE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_CYCLE,
+ DBGetContactSettingByte(NULL, "CList", "TrayIcon",
+ SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_CYCLE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_MULTITRAY,
+ DBGetContactSettingByte(NULL, "CList", "TrayIcon",
+ SETTING_TRAYICON_DEFAULT) == SETTING_TRAYICON_MULTI ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DISABLEBLINK,
+ DBGetContactSettingByte(NULL, "CList", "DisableTrayFlash", 0) == 1 ? BST_CHECKED : BST_UNCHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKTIME), !IsDlgButtonChecked(hwndDlg, IDC_DISABLEBLINK));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), !IsDlgButtonChecked(hwndDlg, IDC_DISABLEBLINK));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STMSDELAY), !IsDlgButtonChecked(hwndDlg, IDC_DISABLEBLINK));
+ CheckDlgButton(hwndDlg, IDC_ICONBLINK, DBGetContactSettingByte(NULL, "CList", "NoIconBlink", 0) == 1 ? BST_CHECKED : BST_UNCHECKED);
+ if (IsDlgButtonChecked(hwndDlg, IDC_DONTCYCLE)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CYCLETIMESPIN), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CYCLETIME), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ALWAYSMULTI), FALSE);
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_CYCLE)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PRIMARYSTATUS), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ALWAYSMULTI), FALSE);
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_MULTITRAY)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CYCLETIMESPIN), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CYCLETIME), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PRIMARYSTATUS), FALSE);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_CYCLETIMESPIN, UDM_SETRANGE, 0, MAKELONG(120, 1));
+ SendDlgItemMessage(hwndDlg, IDC_CYCLETIMESPIN, UDM_SETPOS, 0,
+ MAKELONG(DBGetContactSettingWord(NULL, "CList", "CycleTime", SETTING_CYCLETIME_DEFAULT), 0));
+ {
+ int i, count, item;
+ PROTOCOLDESCRIPTOR **protos;
+ char szName[64];
+ DBVARIANT dbv = { DBVT_DELETED };
+ DBGetContactSetting(NULL, "CList", "PrimaryStatus", &dbv);
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM) & count, (LPARAM) & protos);
+ item = SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_ADDSTRING, 0, (LPARAM) TranslateT("Global"));
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_SETITEMDATA, item, (LPARAM) 0);
+ for (i = 0; i < count; i++) {
+ if (protos[i]->type != PROTOTYPE_PROTOCOL || CallProtoService(protos[i]->szName, PS_GETCAPS, PFLAGNUM_2, 0) == 0)
+ continue;
+ CallProtoService(protos[i]->szName, PS_GETNAME, SIZEOF(szName), (LPARAM) szName);
+ item = SendDlgItemMessageA(hwndDlg, IDC_PRIMARYSTATUS, CB_ADDSTRING, 0, (LPARAM) szName);
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_SETITEMDATA, item, (LPARAM) protos[i]);
+ if (dbv.type == DBVT_ASCIIZ && !lstrcmpA(dbv.pszVal, protos[i]->szName))
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_SETCURSEL, item, 0);
+ }
+ DBFreeVariant(&dbv);
+ }
+ if (-1 == (int) SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_GETCURSEL, 0, 0))
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_SETCURSEL, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETBUDDY, (WPARAM) GetDlgItem(hwndDlg, IDC_BLINKTIME), 0); // set buddy
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETRANGE, 0, MAKELONG(0x3FFF, 250));
+ SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(DBGetContactSettingWord(NULL, "CList", "IconFlashTime", 550), 0));
+ return TRUE;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_AUTOHIDE) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HIDETIME), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HIDETIMESPIN), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ }
+ if (LOWORD(wParam) == IDC_DONTCYCLE || LOWORD(wParam) == IDC_CYCLE || LOWORD(wParam) == IDC_MULTITRAY) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PRIMARYSTATUS), IsDlgButtonChecked(hwndDlg, IDC_DONTCYCLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CYCLETIME), IsDlgButtonChecked(hwndDlg, IDC_CYCLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CYCLETIMESPIN), IsDlgButtonChecked(hwndDlg, IDC_CYCLE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ALWAYSMULTI), IsDlgButtonChecked(hwndDlg, IDC_MULTITRAY));
+ }
+ if (LOWORD(wParam) == IDC_DISABLEBLINK) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKTIME), !IsDlgButtonChecked(hwndDlg, IDC_DISABLEBLINK));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), !IsDlgButtonChecked(hwndDlg, IDC_DISABLEBLINK));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STMSDELAY), !IsDlgButtonChecked(hwndDlg, IDC_DISABLEBLINK));
+ }
+ if ((LOWORD(wParam) == IDC_HIDETIME || LOWORD(wParam) == IDC_CYCLETIME) && HIWORD(wParam) != EN_CHANGE)
+ break;
+ if (LOWORD(wParam) == IDC_PRIMARYSTATUS && HIWORD(wParam) != CBN_SELCHANGE)
+ break;
+ if ((LOWORD(wParam) == IDC_HIDETIME || LOWORD(wParam) == IDC_CYCLETIME) && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ if (LOWORD(wParam) == IDC_BLINKTIME && HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return 0; // dont make apply enabled during buddy set crap
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ DBWriteContactSettingByte(NULL, "CList", "HideOffline", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_HIDEOFFLINE));
+ {
+ DWORD caps = CallService(MS_CLUI_GETCAPS, CLUICAPS_FLAGS1, 0);
+ if (caps & CLUIF_HIDEEMPTYGROUPS)
+ DBWriteContactSettingByte(NULL, "CList", "HideEmptyGroups",
+ (BYTE) IsDlgButtonChecked(hwndDlg, IDC_HIDEEMPTYGROUPS));
+ if (caps & CLUIF_DISABLEGROUPS)
+ DBWriteContactSettingByte(NULL, "CList", "UseGroups", (BYTE) ! IsDlgButtonChecked(hwndDlg, IDC_DISABLEGROUPS));
+ if (!(caps & CLUIF_HASONTOPOPTION)) {
+ DBWriteContactSettingByte(NULL, "CList", "OnTop", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ONTOP));
+ SetWindowPos((HWND) CallService(MS_CLUI_GETHWND, 0, 0),
+ IsDlgButtonChecked(hwndDlg, IDC_ONTOP) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE);
+ }
+ if (!(caps & CLUIF_HASAUTOHIDEOPTION)) {
+ DBWriteContactSettingByte(NULL, "CList", "AutoHide", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ DBWriteContactSettingWord(NULL, "CList", "HideTime",
+ (WORD) SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_GETPOS, 0, 0));
+ }
+ }
+ DBWriteContactSettingByte(NULL, "CList", "SortByStatus", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SORTBYSTATUS));
+ DBWriteContactSettingByte(NULL, "CList", "SortByProto", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SORTBYPROTO));
+ DBWriteContactSettingByte(NULL, "CList", "ConfirmDelete", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_CONFIRMDELETE));
+ DBWriteContactSettingByte(NULL, "CList", "Tray1Click", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ONECLK));
+ DBWriteContactSettingByte(NULL, "CList", "AlwaysStatus", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ALWAYSSTATUS));
+ DBWriteContactSettingByte(NULL, "CList", "AlwaysMulti", (BYTE) ! IsDlgButtonChecked(hwndDlg, IDC_ALWAYSMULTI));
+ DBWriteContactSettingByte(NULL, "CList", "TrayIcon",
+ (BYTE) (IsDlgButtonChecked(hwndDlg, IDC_DONTCYCLE) ? SETTING_TRAYICON_SINGLE
+ : (IsDlgButtonChecked(hwndDlg, IDC_CYCLE) ? SETTING_TRAYICON_CYCLE :
+ SETTING_TRAYICON_MULTI)));
+ DBWriteContactSettingWord(NULL, "CList", "CycleTime",
+ (WORD) SendDlgItemMessage(hwndDlg, IDC_CYCLETIMESPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingWord(NULL, "CList", "IconFlashTime",
+ (WORD) SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, "CList", "DisableTrayFlash", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DISABLEBLINK));
+ DBWriteContactSettingByte(NULL, "CList", "NoIconBlink", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ICONBLINK));
+ if (!SendDlgItemMessage
+ (hwndDlg, IDC_PRIMARYSTATUS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_GETCURSEL, 0, 0), 0))
+ DBDeleteContactSetting(NULL, "CList", "PrimaryStatus");
+ else
+ DBWriteContactSettingString(NULL, "CList", "PrimaryStatus",
+ ((PROTOCOLDESCRIPTOR *)
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_GETITEMDATA,
+ SendDlgItemMessage(hwndDlg, IDC_PRIMARYSTATUS, CB_GETCURSEL, 0, 0),
+ 0))->szName);
+ pcli->pfnTrayIconIconsChanged();
+ pcli->pfnLoadContactTree(); /* this won't do job properly since it only really works when changes happen */
+ pcli->pfnInvalidateDisplayNameCacheEntry( INVALID_HANDLE_VALUE ); /* force reshuffle */
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static BOOL CALLBACK DlgProcHotkeyOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+
+ TranslateDialogDefault(hwndDlg);
+
+ CheckDlgButton(hwndDlg, IDC_SHOWHIDE, DBGetContactSettingByte(NULL, "CList", "HKEnShowHide", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_READMSG, DBGetContactSettingByte(NULL, "CList", "HKEnReadMsg", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_NETSEARCH, DBGetContactSettingByte(NULL, "CList", "HKEnNetSearch", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWOPTIONS, DBGetContactSettingByte(NULL, "CList", "HKEnShowOptions", 0) ? BST_CHECKED : BST_UNCHECKED);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HKSHOWHIDE), IsDlgButtonChecked(hwndDlg, IDC_SHOWHIDE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HKREADMSG), IsDlgButtonChecked(hwndDlg, IDC_READMSG));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HKSEARCH), IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SEARCHURL), IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SEARCHNEWWND), IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HOTKEYURLSTR), IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HKSHOWOPTIONS), IsDlgButtonChecked(hwndDlg, IDC_SHOWOPTIONS));
+
+ SendDlgItemMessage(hwndDlg, IDC_HKSHOWHIDE, HKM_SETHOTKEY,
+ DBGetContactSettingWord(NULL, "CList", "HKShowHide", MAKEWORD('A', HOTKEYF_CONTROL | HOTKEYF_SHIFT)), 0);
+ SendDlgItemMessage(hwndDlg, IDC_HKREADMSG, HKM_SETHOTKEY,
+ DBGetContactSettingWord(NULL, "CList", "HKReadMsg", MAKEWORD('I', HOTKEYF_CONTROL | HOTKEYF_SHIFT)), 0);
+ SendDlgItemMessage(hwndDlg, IDC_HKSEARCH, HKM_SETHOTKEY,
+ DBGetContactSettingWord(NULL, "CList", "HKNetSearch", MAKEWORD('S', HOTKEYF_CONTROL | HOTKEYF_SHIFT)), 0);
+ SendDlgItemMessage(hwndDlg, IDC_HKSHOWOPTIONS, HKM_SETHOTKEY,
+ DBGetContactSettingWord(NULL, "CList", "HKShowOptions", MAKEWORD('O', HOTKEYF_CONTROL | HOTKEYF_SHIFT)), 0);
+ if (!DBGetContactSetting(NULL, "CList", "SearchUrl", &dbv)) {
+ SetDlgItemTextA(hwndDlg, IDC_SEARCHURL, dbv.pszVal);
+ mir_free(dbv.pszVal);
+ }
+ else
+ SetDlgItemTextA(hwndDlg, IDC_SEARCHURL, "http://www.google.com/");
+ CheckDlgButton(hwndDlg, IDC_SEARCHNEWWND, DBGetContactSettingByte(NULL, "CList", "HKSearchNewWnd", 0) ? BST_CHECKED : BST_UNCHECKED);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_SEARCHURL && (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ switch (LOWORD(wParam)) {
+ case IDC_SHOWHIDE:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HKSHOWHIDE), IsDlgButtonChecked(hwndDlg, IDC_SHOWHIDE));
+ break;
+ case IDC_READMSG:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HKREADMSG), IsDlgButtonChecked(hwndDlg, IDC_READMSG));
+ break;
+ case IDC_NETSEARCH:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HKSEARCH), IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SEARCHURL), IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SEARCHNEWWND), IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HOTKEYURLSTR), IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ break;
+ case IDC_SHOWOPTIONS:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HKSHOWOPTIONS), IsDlgButtonChecked(hwndDlg, IDC_SHOWOPTIONS));
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ char str[256];
+ pcli->pfnHotKeysUnregister((HWND) CallService(MS_CLUI_GETHWND, 0, 0));
+ DBWriteContactSettingByte(NULL, "CList", "HKEnShowHide", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWHIDE));
+ DBWriteContactSettingWord(NULL, "CList", "HKShowHide", (WORD) SendDlgItemMessage(hwndDlg, IDC_HKSHOWHIDE, HKM_GETHOTKEY, 0, 0));
+ DBWriteContactSettingByte(NULL, "CList", "HKEnReadMsg", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_READMSG));
+ DBWriteContactSettingWord(NULL, "CList", "HKReadMsg", (WORD) SendDlgItemMessage(hwndDlg, IDC_HKREADMSG, HKM_GETHOTKEY, 0, 0));
+ DBWriteContactSettingByte(NULL, "CList", "HKEnNetSearch", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NETSEARCH));
+ DBWriteContactSettingWord(NULL, "CList", "HKNetSearch", (WORD) SendDlgItemMessage(hwndDlg, IDC_HKSEARCH, HKM_GETHOTKEY, 0, 0));
+ GetDlgItemTextA(hwndDlg, IDC_SEARCHURL, str, SIZEOF(str));
+ DBWriteContactSettingString(NULL, "CList", "SearchUrl", str);
+ DBWriteContactSettingByte(NULL, "CList", "HKSearchNewWnd", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SEARCHNEWWND));
+ DBWriteContactSettingByte(NULL, "CList", "HKEnShowOptions", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWOPTIONS));
+ DBWriteContactSettingWord(NULL, "CList", "HKShowOptions", (WORD) SendDlgItemMessage(hwndDlg, IDC_HKSHOWOPTIONS, HKM_GETHOTKEY, 0, 0));
+ pcli->pfnHotKeysRegister((HWND) CallService(MS_CLUI_GETHWND, 0, 0));
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+/****************************************************************************************/
+
+static UINT expertOnlyControls[] = { IDC_ALWAYSSTATUS };
+
+int CListOptInit(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp, sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.position = -1000000000;
+ odp.hInstance = g_hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CLIST);
+ odp.pszTitle = "Contact List";
+ odp.pfnDlgProc = DlgProcGenOpts;
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.nIDBottomSimpleControl = IDC_STCLISTGROUP;
+ odp.expertOnlyControls = expertOnlyControls;
+ odp.nExpertOnlyControls = SIZEOF(expertOnlyControls);
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+
+ odp.position = -900000000;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_HOTKEY);
+ odp.pszTitle = "Hotkeys";
+ odp.pszGroup = "Events";
+ odp.pfnDlgProc = DlgProcHotkeyOpts;
+ odp.nIDBottomSimpleControl = 0;
+ odp.nExpertOnlyControls = 0;
+ odp.expertOnlyControls = NULL;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+ return 0;
+}
diff --git a/miranda-wine/plugins/clist/cluiopts.c b/miranda-wine/plugins/clist/cluiopts.c new file mode 100644 index 0000000..588d3b1 --- /dev/null +++ b/miranda-wine/plugins/clist/cluiopts.c @@ -0,0 +1,346 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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"
+
+extern BOOL(WINAPI * MySetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
+
+static BOOL CALLBACK DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_BRINGTOFRONT,
+ DBGetContactSettingByte(NULL, "CList", "BringToFront", SETTING_BRINGTOFRONT_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ONTOP, DBGetContactSettingByte(NULL, "CList", "OnTop", SETTING_ONTOP_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_TOOLWND,
+ DBGetContactSettingByte(NULL, "CList", "ToolWindow", SETTING_TOOLWINDOW_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_MIN2TRAY,
+ DBGetContactSettingByte(NULL, "CList", "Min2Tray", SETTING_MIN2TRAY_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ if (IsDlgButtonChecked(hwndDlg, IDC_TOOLWND))
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MIN2TRAY), FALSE);
+ CheckDlgButton(hwndDlg, IDC_SHOWCAPTION,
+ DBGetContactSettingByte(NULL, "CLUI", "ShowCaption", SETTING_SHOWCAPTION_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWMAINMENU,
+ DBGetContactSettingByte(NULL, "CLUI", "ShowMainMenu", SETTING_SHOWMAINMENU_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_CLIENTDRAG,
+ DBGetContactSettingByte(NULL, "CLUI", "ClientAreaDrag", SETTING_CLIENTDRAG_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ if (!IsDlgButtonChecked(hwndDlg, IDC_SHOWCAPTION)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MIN2TRAY), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TOOLWND), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TITLETEXT), FALSE);
+ }
+ CheckDlgButton(hwndDlg, IDC_FADEINOUT, DBGetContactSettingByte(NULL, "CLUI", "FadeInOut", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AUTOSIZE, DBGetContactSettingByte(NULL, "CLUI", "AutoSize", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DROPSHADOW, DBGetContactSettingByte(NULL, "CList", "WindowShadow", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_ONDESKTOP, DBGetContactSettingByte(NULL, "CList", "OnDesktop", 0) ? BST_CHECKED : BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_MAXSIZESPIN, UDM_SETRANGE, 0, MAKELONG(100, 0));
+ SendDlgItemMessage(hwndDlg, IDC_MAXSIZESPIN, UDM_SETPOS, 0, DBGetContactSettingByte(NULL, "CLUI", "MaxSizeHeight", 75));
+ CheckDlgButton(hwndDlg, IDC_AUTOSIZEUPWARD, DBGetContactSettingByte(NULL, "CLUI", "AutoSizeUpward", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_AUTOHIDE,
+ DBGetContactSettingByte(NULL, "CList", "AutoHide", SETTING_AUTOHIDE_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_SETRANGE, 0, MAKELONG(900, 1));
+ SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_SETPOS, 0,
+ MAKELONG(DBGetContactSettingWord(NULL, "CList", "HideTime", SETTING_HIDETIME_DEFAULT), 0));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HIDETIME), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HIDETIMESPIN), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC01), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ if (!IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC21), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC22), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZEHEIGHT), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZESPIN), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOSIZEUPWARD), FALSE);
+ }
+
+ { DBVARIANT dbv;
+ if ( !DBGetContactSettingTString(NULL, "CList", "TitleText", &dbv)) {
+ SetDlgItemText(hwndDlg, IDC_TITLETEXT, dbv.ptszVal);
+ DBFreeVariant( &dbv );
+ }
+ else SetDlgItemTextA(hwndDlg, IDC_TITLETEXT, MIRANDANAME);
+ }
+ if (!IsWinVer2000Plus()) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_FADEINOUT), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSPARENT), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DROPSHADOW), FALSE);
+ }
+ else
+ CheckDlgButton(hwndDlg, IDC_TRANSPARENT,
+ DBGetContactSettingByte(NULL, "CList", "Transparent", SETTING_TRANSPARENT_DEFAULT) ? BST_CHECKED : BST_UNCHECKED);
+
+ if (!IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC11), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC12), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSACTIVE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSINACTIVE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ACTIVEPERC), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_INACTIVEPERC), FALSE);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_SETRANGE, FALSE, MAKELONG(1, 255));
+ SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_SETRANGE, FALSE, MAKELONG(1, 255));
+ SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_SETPOS, TRUE, DBGetContactSettingByte(NULL, "CList", "Alpha", SETTING_ALPHA_DEFAULT));
+ SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_SETPOS, TRUE,
+ DBGetContactSettingByte(NULL, "CList", "AutoAlpha", SETTING_AUTOALPHA_DEFAULT));
+ SendMessage(hwndDlg, WM_HSCROLL, 0x12345678, 0);
+ return TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_AUTOHIDE) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HIDETIME), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HIDETIMESPIN), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC01), IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ }
+ else if (LOWORD(wParam) == IDC_TRANSPARENT) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC11), IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC12), IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSACTIVE), IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANSINACTIVE), IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ACTIVEPERC), IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_INACTIVEPERC), IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ }
+ else if (LOWORD(wParam) == IDC_AUTOSIZE) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC21), IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC22), IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZEHEIGHT), IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZESPIN), IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOSIZEUPWARD), IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ }
+ else if (LOWORD(wParam) == IDC_TOOLWND) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MIN2TRAY), !IsDlgButtonChecked(hwndDlg, IDC_TOOLWND));
+ }
+ else if (LOWORD(wParam) == IDC_SHOWCAPTION) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TOOLWND), IsDlgButtonChecked(hwndDlg, IDC_SHOWCAPTION));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MIN2TRAY), !IsDlgButtonChecked(hwndDlg, IDC_TOOLWND)
+ && IsDlgButtonChecked(hwndDlg, IDC_SHOWCAPTION));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TITLETEXT), IsDlgButtonChecked(hwndDlg, IDC_SHOWCAPTION));
+ }
+
+ if ((LOWORD(wParam) == IDC_HIDETIME || LOWORD(wParam) == IDC_TITLETEXT || LOWORD(wParam) == IDC_MAXSIZEHEIGHT) &&
+ (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus()))
+ return 0;
+
+ // Enable apply button
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+
+ case WM_HSCROLL:
+ {
+ char str[10];
+ wsprintfA(str, "%d%%", 100 * SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_GETPOS, 0, 0) / 255);
+ SetDlgItemTextA(hwndDlg, IDC_INACTIVEPERC, str);
+ wsprintfA(str, "%d%%", 100 * SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_GETPOS, 0, 0) / 255);
+ SetDlgItemTextA(hwndDlg, IDC_ACTIVEPERC, str);
+ }
+ if (wParam != 0x12345678)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ if (((LPNMHDR) lParam)->code == PSN_APPLY) {
+ DBWriteContactSettingByte(NULL, "CList", "OnTop", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ONTOP));
+ DBWriteContactSettingByte(NULL, "CList", "ToolWindow", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TOOLWND));
+ DBWriteContactSettingByte(NULL, "CList", "BringToFront", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_BRINGTOFRONT));
+ DBWriteContactSettingByte(NULL, "CLUI", "FadeInOut", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FADEINOUT));
+ DBWriteContactSettingByte(NULL, "CLUI", "AutoSize", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZE));
+ DBWriteContactSettingByte(NULL, "CLUI", "MaxSizeHeight", (BYTE) GetDlgItemInt(hwndDlg, IDC_MAXSIZEHEIGHT, NULL, FALSE));
+ DBWriteContactSettingByte(NULL, "CLUI", "AutoSizeUpward", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOSIZEUPWARD));
+ DBWriteContactSettingByte(NULL, "CList", "AutoHide", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOHIDE));
+ DBWriteContactSettingWord(NULL, "CList", "HideTime", (WORD) SendDlgItemMessage(hwndDlg, IDC_HIDETIMESPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, "CList", "Transparent", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT));
+ DBWriteContactSettingByte(NULL, "CList", "Alpha", (BYTE) SendDlgItemMessage(hwndDlg, IDC_TRANSACTIVE, TBM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, "CList", "AutoAlpha", (BYTE) SendDlgItemMessage(hwndDlg, IDC_TRANSINACTIVE, TBM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, "CList", "WindowShadow", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DROPSHADOW));
+ DBWriteContactSettingByte(NULL, "CList", "OnDesktop", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ONDESKTOP));
+ DBWriteContactSettingByte(NULL, "CLUI", "ShowCaption", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWCAPTION));
+ DBWriteContactSettingByte(NULL, "CLUI", "ShowMainMenu", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWMAINMENU));
+ DBWriteContactSettingByte(NULL, "CLUI", "ClientAreaDrag", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_CLIENTDRAG));
+ DBWriteContactSettingByte(NULL, "CList", "Min2Tray", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_MIN2TRAY));
+ {
+ TCHAR title[256];
+ GetDlgItemText(hwndDlg, IDC_TITLETEXT, title, SIZEOF(title));
+ DBWriteContactSettingTString(NULL, "CList", "TitleText", title);
+ SetWindowText(pcli->hwndContactList, title);
+ }
+ pcli->pfnLoadCluiGlobalOpts();
+ SetWindowPos(pcli->hwndContactList, IsDlgButtonChecked(hwndDlg, IDC_ONTOP) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE);
+ if (IsDlgButtonChecked(hwndDlg, IDC_TOOLWND)) {
+ // Window must be hidden to dynamically remove the taskbar button.
+ // See http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_programming/taskbar.asp
+ WINDOWPLACEMENT p;
+ p.length = sizeof(p);
+ GetWindowPlacement(pcli->hwndContactList, &p);
+ ShowWindow(pcli->hwndContactList, SW_HIDE);
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE,
+ GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) | WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE);
+ SetWindowPlacement(pcli->hwndContactList, &p);
+ }
+ else SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) & ~WS_EX_TOOLWINDOW);
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_ONDESKTOP)) {
+ HWND hProgMan = FindWindowA("Progman", NULL);
+ if (IsWindow(hProgMan))
+ SetParent(pcli->hwndContactList, hProgMan);
+ }
+ else SetParent(pcli->hwndContactList, NULL);
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_SHOWCAPTION))
+ SetWindowLong(pcli->hwndContactList, GWL_STYLE,
+ GetWindowLong(pcli->hwndContactList, GWL_STYLE) | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
+ else
+ SetWindowLong(pcli->hwndContactList, GWL_STYLE,
+ GetWindowLong(pcli->hwndContactList, GWL_STYLE) & ~(WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX));
+ if (!IsDlgButtonChecked(hwndDlg, IDC_SHOWMAINMENU))
+ SetMenu(pcli->hwndContactList, NULL);
+ else
+ SetMenu(pcli->hwndContactList, pcli->hMenuMain);
+ SetWindowPos(pcli->hwndContactList, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
+ RedrawWindow(pcli->hwndContactList, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+ if (IsIconic(pcli->hwndContactList) && !IsDlgButtonChecked(hwndDlg, IDC_TOOLWND))
+ ShowWindow(pcli->hwndContactList, IsDlgButtonChecked(hwndDlg, IDC_MIN2TRAY) ? SW_HIDE : SW_SHOW);
+ if (IsDlgButtonChecked(hwndDlg, IDC_TRANSPARENT)) {
+ SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) | WS_EX_LAYERED);
+ if (MySetLayeredWindowAttributes)
+ MySetLayeredWindowAttributes(pcli->hwndContactList, RGB(0, 0, 0),
+ (BYTE) DBGetContactSettingByte(NULL, "CList", "AutoAlpha", SETTING_AUTOALPHA_DEFAULT),
+ LWA_ALPHA);
+ }
+ else SetWindowLong(pcli->hwndContactList, GWL_EXSTYLE, GetWindowLong(pcli->hwndContactList, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+
+ SendMessage(pcli->hwndContactTree, WM_SIZE, 0, 0); //forces it to send a cln_listsizechanged
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static BOOL CALLBACK DlgProcSBarOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_SHOWSBAR, DBGetContactSettingByte(NULL, "CLUI", "ShowSBar", 1) ? BST_CHECKED : BST_UNCHECKED);
+ {
+ BYTE showOpts = DBGetContactSettingByte(NULL, "CLUI", "SBarShow", 1);
+ CheckDlgButton(hwndDlg, IDC_SHOWICON, showOpts & 1 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWPROTO, showOpts & 2 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWSTATUS, showOpts & 4 ? BST_CHECKED : BST_UNCHECKED);
+ }
+ CheckDlgButton(hwndDlg, IDC_RIGHTSTATUS, DBGetContactSettingByte(NULL, "CLUI", "SBarRightClk", 0) ? BST_UNCHECKED : BST_CHECKED);
+ CheckDlgButton(hwndDlg, IDC_RIGHTMIRANDA, !IsDlgButtonChecked(hwndDlg, IDC_RIGHTSTATUS) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_EQUALSECTIONS, DBGetContactSettingByte(NULL, "CLUI", "EqualSections", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SBPANELBEVEL, DBGetContactSettingByte(NULL, "CLUI", "SBarBevel", 1) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SHOWGRIP, DBGetContactSettingByte(NULL, "CLUI", "ShowGrip", 1) ? BST_CHECKED : BST_UNCHECKED);
+ if (!IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWICON), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWPROTO), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWSTATUS), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RIGHTSTATUS), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RIGHTMIRANDA), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EQUALSECTIONS), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SBPANELBEVEL), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWGRIP), FALSE);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_SHOWSBAR) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWICON), IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWPROTO), IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWSTATUS), IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RIGHTSTATUS), IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RIGHTMIRANDA), IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EQUALSECTIONS), IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SBPANELBEVEL), IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWGRIP), IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ if (((LPNMHDR) lParam)->code == PSN_APPLY ) {
+ DBWriteContactSettingByte(NULL, "CLUI", "ShowSBar", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR));
+ DBWriteContactSettingByte(NULL, "CLUI", "SBarShow",
+ (BYTE) ((IsDlgButtonChecked(hwndDlg, IDC_SHOWICON) ? 1 : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_SHOWPROTO) ? 2 : 0) |
+ (IsDlgButtonChecked(hwndDlg, IDC_SHOWSTATUS) ? 4 : 0)));
+ DBWriteContactSettingByte(NULL, "CLUI", "SBarRightClk", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RIGHTMIRANDA));
+ DBWriteContactSettingByte(NULL, "CLUI", "EqualSections", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_EQUALSECTIONS));
+ DBWriteContactSettingByte(NULL, "CLUI", "SBarBevel", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SBPANELBEVEL));
+ pcli->pfnLoadCluiGlobalOpts();
+ if (DBGetContactSettingByte(NULL, "CLUI", "ShowGrip", 1) != (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWGRIP)) {
+ HWND parent = GetParent(pcli->hwndStatus);
+ int flags = WS_CHILD | CCS_BOTTOM;
+ DBWriteContactSettingByte(NULL, "CLUI", "ShowGrip", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWGRIP));
+ ShowWindow(pcli->hwndStatus, SW_HIDE);
+ DestroyWindow(pcli->hwndStatus);
+ flags |= DBGetContactSettingByte(NULL, "CLUI", "ShowSBar", 1) ? WS_VISIBLE : 0;
+ flags |= DBGetContactSettingByte(NULL, "CLUI", "ShowGrip", 1) ? SBARS_SIZEGRIP : 0;
+ pcli->hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, flags, 0, 0, 0, 0, parent, NULL, g_hInst, NULL);
+ }
+ if (IsDlgButtonChecked(hwndDlg, IDC_SHOWSBAR))
+ ShowWindow(pcli->hwndStatus, SW_SHOW);
+ else
+ ShowWindow(pcli->hwndStatus, SW_HIDE);
+ SendMessage(pcli->hwndContactList, WM_SIZE, 0, 0);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+/****************************************************************************************/
+
+static UINT expertOnlyControls[] =
+{
+ IDC_BRINGTOFRONT, IDC_AUTOSIZE, IDC_STATIC21, IDC_MAXSIZEHEIGHT, IDC_MAXSIZESPIN,
+ IDC_STATIC22, IDC_AUTOSIZEUPWARD, IDC_SHOWMAINMENU, IDC_SHOWCAPTION, IDC_CLIENTDRAG
+};
+
+int CluiOptInit(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp, sizeof(odp));
+ odp.cbSize = sizeof(odp);
+ odp.position = 0;
+ odp.hInstance = g_hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CLUI);
+ odp.pszTitle = "Window";
+ odp.pszGroup = "Contact List";
+ odp.pfnDlgProc = DlgProcCluiOpts;
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.nIDBottomSimpleControl = IDC_STWINDOWGROUP;
+ odp.expertOnlyControls = expertOnlyControls;
+ odp.nExpertOnlyControls = SIZEOF(expertOnlyControls);
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_SBAR);
+ odp.pszTitle = "Status Bar";
+ odp.pfnDlgProc = DlgProcSBarOpts;
+ odp.flags = ODPF_BOLDGROUPS | ODPF_EXPERTONLY;
+ odp.nIDBottomSimpleControl = 0;
+ odp.nExpertOnlyControls = 0;
+ odp.expertOnlyControls = NULL;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+ return 0;
+}
diff --git a/miranda-wine/plugins/clist/commonheaders.c b/miranda-wine/plugins/clist/commonheaders.c new file mode 100644 index 0000000..14f99f7 --- /dev/null +++ b/miranda-wine/plugins/clist/commonheaders.c @@ -0,0 +1 @@ +#include "commonheaders.h"
diff --git a/miranda-wine/plugins/clist/commonheaders.h b/miranda-wine/plugins/clist/commonheaders.h new file mode 100644 index 0000000..6a061ff --- /dev/null +++ b/miranda-wine/plugins/clist/commonheaders.h @@ -0,0 +1,96 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2005 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.
+*/
+
+#if defined(UNICODE)
+#define _UNICODE 1
+#endif
+
+#include <tchar.h>
+#include <malloc.h>
+
+#ifdef _DEBUG
+# define _CRTDBG_MAP_ALLOC
+# include <stdlib.h>
+# include <crtdbg.h>
+#endif
+
+#define _WIN32_WINNT 0x0501
+#include <windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <time.h>
+#include <stddef.h>
+#include <process.h>
+#include <io.h>
+#include <string.h>
+#include <direct.h>
+#include "resource.h"
+#include "forkthread.h"
+#include <win2k.h>
+#include <newpluginapi.h>
+#include <m_clist.h>
+#include <m_clc.h>
+#include <m_clistint.h>
+#include <m_clui.h>
+#include <m_plugins.h>
+#include <m_system.h>
+#include <m_database.h>
+#include <m_langpack.h>
+#include <m_button.h>
+#include <m_options.h>
+#include <m_protosvc.h>
+#include <m_utils.h>
+#include <m_skin.h>
+#include <m_contacts.h>
+#include <m_file.h>
+#include <m_addcontact.h>
+#include "clc.h"
+#include "clist.h"
+
+// shared vars
+extern HINSTANCE g_hInst;
+
+/* most free()'s are invalid when the code is executed from a dll, so this changes
+ all the bad free()'s to good ones, however it's still incorrect code. The reasons for not
+ changing them include:
+
+ * DBFreeVariant has a CallService() lookup
+ * free() is executed in some large loops to do with clist creation of group data
+ * easy search and replace
+
+*/
+
+extern struct MM_INTERFACE memoryManagerInterface;
+
+#define mir_alloc(n) memoryManagerInterface.mmi_malloc(n)
+#define mir_free(ptr) memoryManagerInterface.mmi_free(ptr)
+#define mir_realloc(ptr,size) memoryManagerInterface.mmi_realloc(ptr,size)
+
+static __inline char * mir_strdup(const char * src)
+{
+ char * p = 0;
+ if ( src == NULL ) return NULL;
+ p=mir_alloc( strlen(src)+1 );
+ strcpy(p, src);
+ return p;
+}
diff --git a/miranda-wine/plugins/clist/forkthread.c b/miranda-wine/plugins/clist/forkthread.c new file mode 100644 index 0000000..920fc1f --- /dev/null +++ b/miranda-wine/plugins/clist/forkthread.c @@ -0,0 +1,94 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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"
+
+struct FORK_ARG
+{
+ HANDLE hEvent;
+ void (__cdecl * threadcode) (void *);
+ unsigned (__stdcall * threadcodeex) (void *);
+ void *arg;
+};
+
+void __cdecl forkthread_r(struct FORK_ARG *fa)
+{
+ void (*callercode) (void *) = fa->threadcode;
+ void *arg = fa->arg;
+ CallService(MS_SYSTEM_THREAD_PUSH, 0, 0);
+ SetEvent(fa->hEvent);
+ __try {
+ callercode(arg);
+ }
+ __finally {
+ CallService(MS_SYSTEM_THREAD_POP, 0, 0);
+ }
+ return;
+}
+
+unsigned long forkthread(void (__cdecl * threadcode) (void *), unsigned long stacksize, void *arg)
+{
+ unsigned long rc;
+ struct FORK_ARG fa;
+ fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ fa.threadcode = threadcode;
+ fa.arg = arg;
+ rc = _beginthread(forkthread_r, stacksize, &fa);
+ if ((unsigned long) -1L != rc) {
+ WaitForSingleObject(fa.hEvent, INFINITE);
+ } //if
+ CloseHandle(fa.hEvent);
+ return rc;
+}
+
+unsigned long __stdcall forkthreadex_r(struct FORK_ARG *fa)
+{
+ unsigned (__stdcall * threadcode) (void *) = fa->threadcodeex;
+ void *arg = fa->arg;
+ unsigned long rc;
+
+ CallService(MS_SYSTEM_THREAD_PUSH, 0, 0);
+ SetEvent(fa->hEvent);
+ __try {
+ rc = threadcode(arg);
+ }
+ __finally {
+ CallService(MS_SYSTEM_THREAD_POP, 0, 0);
+ }
+ return rc;
+}
+
+unsigned long forkthreadex(void *sec, unsigned stacksize, unsigned (__stdcall * threadcode) (void *), void *arg, unsigned cf, unsigned *thraddr)
+{
+ unsigned long rc;
+ struct FORK_ARG fa;
+ fa.threadcodeex = threadcode;
+ fa.arg = arg;
+ fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ rc = _beginthreadex(sec, stacksize, forkthreadex_r, &fa, 0, thraddr);
+ if (rc) {
+ WaitForSingleObject(fa.hEvent, INFINITE);
+ }
+ CloseHandle(fa.hEvent);
+ return rc;
+}
diff --git a/miranda-wine/plugins/clist/forkthread.h b/miranda-wine/plugins/clist/forkthread.h new file mode 100644 index 0000000..9abcf5e --- /dev/null +++ b/miranda-wine/plugins/clist/forkthread.h @@ -0,0 +1,63 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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.
+*/
+
+/*
+
+Purpose:
+
+ A safe version of _beginthread()
+
+Description:
+
+ A new thread is created and the source thread is paused until
+ internal code to call MS_SYSTEM_THREAD_PUSH is made in the context
+ if the new thread.
+
+ The source thread is then released and then the user supplied
+ code is called, when that function returns -- MS_SYSTEM_THREAD_POP
+ is called and then the thread returns.
+
+ This insures that Miranda will not exit whilst new threads
+ are trying to be born; and the unwind wait stack will unsure
+ that Miranda will wait for all created threads to return as well.
+
+Cavets:
+
+ The function must be reimplemented across MT plugins, since thread
+ creation depends on CRT which can not be shared.
+
+*/
+unsigned long forkthread (
+ void (__cdecl *threadcode)(void*),
+ unsigned long stacksize,
+ void *arg
+);
+
+unsigned long forkthreadex(
+ void *sec,
+ unsigned stacksize,
+ unsigned (__stdcall *threadcode)(void*),
+ void *arg,
+ unsigned cf,
+ unsigned *thraddr
+);
diff --git a/miranda-wine/plugins/clist/init.c b/miranda-wine/plugins/clist/init.c new file mode 100644 index 0000000..843a5bb --- /dev/null +++ b/miranda-wine/plugins/clist/init.c @@ -0,0 +1,175 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2005 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"
+
+HINSTANCE g_hInst = 0;
+PLUGINLINK *pluginLink;
+CLIST_INTERFACE* pcli = NULL;
+HIMAGELIST himlCListClc = NULL;
+HANDLE hStatusModeChangeEvent;
+
+extern int currentDesiredStatusMode;
+
+struct MM_INTERFACE memoryManagerInterface;
+BOOL(WINAPI * MySetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD) = NULL;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// external functions
+
+int MenuProcessCommand(WPARAM wParam, LPARAM lParam);
+int InitCustomMenus(void);
+void UninitCustomMenus(void);
+
+void PaintClc(HWND hwnd, struct ClcData *dat, HDC hdc, RECT * rcPaint);
+
+int ClcOptInit(WPARAM wParam, LPARAM lParam);
+int CluiOptInit(WPARAM wParam, LPARAM lParam);
+int CListOptInit(WPARAM wParam, LPARAM lParam);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// dll stub
+
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved)
+{
+ g_hInst = hInstDLL;
+ DisableThreadLibraryCalls(g_hInst);
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// returns the plugin information
+
+PLUGININFO pluginInfo = {
+ sizeof(PLUGININFO),
+ #if defined( _UNICODE )
+ "Classic contact list (Unicode)",
+ #else
+ "Classic contact list",
+ #endif
+ PLUGIN_MAKE_VERSION(0, 5, 1, 1),
+
+ "Display contacts, event notifications, protocol status",
+ "Miranda IM project",
+ "ghazan@miranda-im.org",
+ "Copyright 2000-2006 Miranda IM project",
+ "http://www.miranda-im.org",
+ UNICODE_AWARE,
+ DEFMOD_CLISTALL
+};
+
+__declspec(dllexport) PLUGININFO *MirandaPluginInfo(DWORD mirandaVersion)
+{
+ if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 4, 3, 0))
+ return NULL;
+ return &pluginInfo;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// called when all modules got loaded
+
+static int OnModulesLoaded( WPARAM wParam, LPARAM lParam )
+{
+ himlCListClc = (HIMAGELIST) CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// options iniatialization
+
+static int OnOptsInit(WPARAM wParam, LPARAM lParam)
+{
+ ClcOptInit(wParam, lParam);
+ CluiOptInit(wParam, lParam);
+ CListOptInit(wParam, lParam);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// menu status services
+
+static int SetStatusMode(WPARAM wParam, LPARAM lParam)
+{
+ //todo: check wParam is valid so people can't use this to run random menu items
+ MenuProcessCommand(MAKEWPARAM(LOWORD(wParam), MPCF_MAINMENU), 0);
+ return 0;
+}
+
+static int GetStatusMode(WPARAM wParam, LPARAM lParam)
+{
+ return currentDesiredStatusMode;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// main clist initialization routine
+
+int __declspec(dllexport) CListInitialise(PLUGINLINK * link)
+{
+ int rc = 0;
+ pluginLink = link;
+ #ifdef _DEBUG
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+ #endif
+
+ // get the internal malloc/free()
+ memset(&memoryManagerInterface, 0, sizeof(memoryManagerInterface));
+ memoryManagerInterface.cbSize = sizeof(memoryManagerInterface);
+ CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM) & memoryManagerInterface);
+
+ pcli = ( CLIST_INTERFACE* )CallService(MS_CLIST_RETRIEVE_INTERFACE, 0, (LPARAM)g_hInst);
+ if ( (int)pcli == CALLSERVICE_NOTFOUND ) {
+ MessageBoxA( NULL, "This version of plugin requires Miranda IM 0.5 or later", "Fatal error", MB_OK );
+ return 1;
+ }
+ pcli->pfnPaintClc = PaintClc;
+
+ MySetLayeredWindowAttributes = (BOOL(WINAPI *) (HWND, COLORREF, BYTE, DWORD)) GetProcAddress(
+ LoadLibraryA("user32.dll"), "SetLayeredWindowAttributes");
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+ HookEvent(ME_OPT_INITIALISE, OnOptsInit);
+
+ hStatusModeChangeEvent = CreateHookableEvent(ME_CLIST_STATUSMODECHANGE);
+
+ InitCustomMenus();
+ CreateServiceFunction(MS_CLIST_SETSTATUSMODE, SetStatusMode);
+ CreateServiceFunction(MS_CLIST_GETSTATUSMODE, GetStatusMode);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// a plugin loader aware of CList exports will never call this.
+
+int __declspec(dllexport) Load(PLUGINLINK * link)
+{
+ return 1;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// a plugin unloader
+
+int __declspec(dllexport) Unload(void)
+{
+ UninitCustomMenus();
+ return 0;
+}
diff --git a/miranda-wine/plugins/clist/res/blank.ico b/miranda-wine/plugins/clist/res/blank.ico Binary files differnew file mode 100644 index 0000000..7845f62 --- /dev/null +++ b/miranda-wine/plugins/clist/res/blank.ico diff --git a/miranda-wine/plugins/clist/res/delete.ico b/miranda-wine/plugins/clist/res/delete.ico Binary files differnew file mode 100644 index 0000000..9b0f0ff --- /dev/null +++ b/miranda-wine/plugins/clist/res/delete.ico diff --git a/miranda-wine/plugins/clist/res/dragcopy.cur b/miranda-wine/plugins/clist/res/dragcopy.cur Binary files differnew file mode 100644 index 0000000..89c7c96 --- /dev/null +++ b/miranda-wine/plugins/clist/res/dragcopy.cur diff --git a/miranda-wine/plugins/clist/res/dropuser.cur b/miranda-wine/plugins/clist/res/dropuser.cur Binary files differnew file mode 100644 index 0000000..a84b19e --- /dev/null +++ b/miranda-wine/plugins/clist/res/dropuser.cur diff --git a/miranda-wine/plugins/clist/res/hyperlin.cur b/miranda-wine/plugins/clist/res/hyperlin.cur Binary files differnew file mode 100644 index 0000000..f0f548c --- /dev/null +++ b/miranda-wine/plugins/clist/res/hyperlin.cur diff --git a/miranda-wine/plugins/clist/res/rename.ico b/miranda-wine/plugins/clist/res/rename.ico Binary files differnew file mode 100644 index 0000000..2c6bc2a --- /dev/null +++ b/miranda-wine/plugins/clist/res/rename.ico diff --git a/miranda-wine/plugins/clist/resource.h b/miranda-wine/plugins/clist/resource.h new file mode 100644 index 0000000..d6aeddf --- /dev/null +++ b/miranda-wine/plugins/clist/resource.h @@ -0,0 +1,554 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDC_AUTHICON 1
+#define IDC_NOTOALL 3
+#define IDC_APPLY 3
+#define IDI_MIRANDA 102
+#define IDD_ABOUT 103
+#define IDI_SMS 103
+#define IDI_ONLINE 104
+#define IDI_OFFLINE 105
+#define IDD_GNUPL 110
+#define IDD_ADDED 115
+#define IDD_URLSEND 119
+#define IDD_URLRECV 120
+#define IDD_AUTHREQ 121
+#define IDD_DETAILS 125
+#define IDD_OPT_CLIST 126
+#define IDD_HISTORY 127
+#define IDI_AWAY 128
+#define IDI_FREE4CHAT 129
+#define IDI_INVISIBLE 130
+#define IDI_NA 131
+#define IDD_OPT_SOUND 134
+#define IDI_SENDURL 135
+#define IDI_RECVMSG 136
+#define IDI_SENDMSG 137
+#define IDI_URL 138
+#define IDI_DND 158
+#define IDI_OCCUPIED 159
+#define IDI_USERDETAILS 160
+#define IDI_FINDUSER 161
+#define IDI_HELP 162
+#define IDI_OPTIONS 163
+#define IDI_MIRANDAWEBSITE 172
+#define IDI_RENAME 173
+#define IDI_HISTORY 174
+#define IDI_DELETE 175
+#define IDR_CONTEXT 180
+#define IDC_DROP 183
+#define IDD_OPT_HOTKEY 184
+#define IDD_HISTORY_FIND 192
+#define IDI_SENDEMAIL 193
+#define IDD_FILERECV 194
+#define IDD_PROFILEMANAGER 197
+#define IDD_NEWPROFILE 198
+#define IDR_CLISTMENU 199
+#define IDI_BLANK 200
+#define IDD_FINDADD 201
+#define IDI_USERONLINE 201
+#define IDD_OPT_AUTOAWAY 202
+#define IDI_GROUPSHUT 202
+#define IDD_OPTIONS 203
+#define IDI_GROUPOPEN 203
+#define IDD_PLUGINCONFLICT 204
+#define IDD_FILESEND 205
+#define IDI_NOTICK 205
+#define IDD_OPT_PLUGINS 206
+#define IDI_TICK 206
+#define IDD_OPT_ICONS 207
+#define IDI_FILE 207
+#define IDI_TIMESTAMP 208
+#define IDI_CHANGEFONT 209
+#define IDI_ADDCONTACT 210
+#define IDI_SMALLDOT 211
+#define IDI_FILLEDBLOB 212
+#define IDD_READAWAYMSG 213
+#define IDI_EMPTYBLOB 213
+#define IDD_OPT_IGNORE 214
+#define IDC_HYPERLINKHAND 214
+#define IDD_OPT_VISIBILITY 215
+#define IDC_DROPUSER 215
+#define IDD_SETAWAYMSG 216
+#define IDI_DETAILSLOGO 216
+#define IDD_OPT_AWAYMSG 217
+#define IDD_OPT_CLUI 218
+#define IDD_INFO_SUMMARY 220
+#define IDD_INFO_CONTACT 221
+#define IDD_INFO_BACKGROUND 222
+#define IDD_INFO_NOTES 223
+#define IDD_ADDEMAIL 226
+#define IDD_ICONINDEX 227
+#define IDD_OPT_CLC 228
+#define IDD_OPT_CLCTEXT 229
+#define IDD_OPT_CLCBKG 230
+#define IDD_INFO_LOCATION 231
+#define IDD_INFO_WORK 232
+#define IDD_ADDPHONE 233
+#define IDD_OPT_SBAR 234
+#define IDD_INSTALLINI 235
+#define IDD_WARNINICHANGE 236
+#define IDD_INIIMPORTDONE 237
+#define IDD_OPT_CLCTEXTSIMPLE 239
+#define IDB_SORTCOLUP 239
+#define IDB_SORTCOLDOWN 240
+#define IDD_OPT_NETLIB 246
+#define IDD_NETLIBLOGOPTS 247
+#define IDD_FILETRANSFERINFO 249
+#define IDD_OPT_FILETRANSFER 250
+#define IDD_FILEEXISTS 251
+#define IDD_DELETECONTACT 254
+#define IDD_DENYREASON 256
+#define IDD_ADDCONTACT 257
+#define IDD_OPT_CONTACT 261
+#define IDI_MULTISEND 263
+#define IDI_DOWNARROW 264
+#define IDD_CREDITS 265
+#define IDD_OPT_IDLE 268
+#define IDC_SAVE 1001
+#define IDI_ONTHEPHONE 1002
+#define IDC_MESSAGE 1002
+#define IDI_OUTTOLUNCH 1003
+#define IDC_AUTOCLOSE 1004
+#define IDC_FROM 1005
+#define IDC_AUTOMIN 1005
+#define IDC_DATE 1006
+#define IDC_DUMPRECV 1006
+#define IDC_MSG 1008
+#define IDC_PROXYDNS 1008
+#define IDC_NAME 1009
+#define IDC_PROXYTYPE 1009
+#define IDC_STATIC23 1010
+#define IDC_SPECIFYPORTS 1013
+#define IDC_ST_ENTERMSG 1013
+#define IDC_ST_ENTERURL 1014
+#define IDC_SPECIFYPORTSO 1014
+#define IDC_TEXT 1019
+#define IDC_SHOWNAMES 1024
+#define IDC_ABOUT 1032
+#define IDC_MYNOTES 1033
+#define IDC_URLS 1037
+#define IDC_REPLY 1039
+#define IDC_URL 1041
+#define IDC_REASON 1046
+#define IDC_EMAIL 1048
+#define IDC_NAMENICK 1049
+#define IDC_NAMEFIRST 1050
+#define IDC_NAMELAST 1051
+#define IDC_NICK 1053
+#define IDC_GENDER 1060
+#define IDC_CITY 1061
+#define IDC_STATE 1062
+#define IDC_COUNTRY 1063
+#define IDC_AGE 1064
+#define IDC_ZIP 1064
+#define IDC_PHONE 1065
+#define IDC_STREET 1065
+#define IDC_COMPANY 1066
+#define IDC_LANGUAGE1 1066
+#define IDC_TIMEZONE 1067
+#define IDC_DEPARTMENT 1067
+#define IDC_LOCALTIME 1068
+#define IDC_DETAILS 1069
+#define IDC_POSITION 1069
+#define IDC_LANGUAGE2 1069
+#define IDC_ADD 1070
+#define IDC_LANGUAGE3 1070
+#define IDC_MOREOPTIONS 1071
+#define IDC_USERMENU 1071
+#define IDC_MIN2TRAY 1073
+#define IDC_ONTOP 1074
+#define IDC_SHOWMAINMENU 1075
+#define IDC_CLIENTDRAG 1076
+#define IDC_EDIT 1078
+#define IDC_LIST 1079
+#define IDC_HISTORY 1080
+#define IDC_USESOUND 1085
+#define IDC_TOOLWND 1097
+#define IDC_ONECLK 1098
+#define IDC_SHOWCAPTION 1098
+#define IDC_HIDEOFFLINE 1099
+#define IDC_SHOWHIDE 1100
+#define IDC_HIDEEMPTYGROUPS 1100
+#define IDC_SORTBYSTATUS 1101
+#define IDC_FADEINOUT 1101
+#define IDC_READMSG 1102
+#define IDC_AUTOSIZE 1102
+#define IDC_DISABLEGROUPS 1102
+#define IDC_AUTOSIZEUPWARD 1103
+#define IDC_ALWAYSSTATUS 1103
+#define IDC_NETSEARCH 1104
+#define IDC_CONFIRMDELETE 1104
+#define IDC_SORTBYPROTO 1105
+#define IDC_SHOWOPTIONS 1105
+#define IDC_SEARCHURL 1106
+#define IDC_BUILDTIME 1108
+#define IDC_NUMBER 1113
+#define IDC_UIN 1123
+#define IDC_TRANSPARENT 1124
+#define IDC_TRANSINACTIVE 1126
+#define IDC_TRANSACTIVE 1128
+#define IDC_FINDWHAT 1131
+#define IDC_FIND 1132
+#define IDC_FILE 1133
+#define IDC_PROFILELIST 1134
+#define IDC_NEWPROFILE 1135
+#define IDC_NEWPROFILENAME 1136
+#define IDC_TABS 1141
+#define IDC_RESULTS 1142
+#define IDC_STATUS 1144
+#define IDC_SCREENSAVE 1145
+#define IDC_TIMED 1146
+#define IDC_AWAYTIME 1147
+#define IDC_USEPROXY 1148
+#define IDC_SETNA 1148
+#define IDC_PROXYAUTH 1149
+#define IDC_NATIME 1149
+#define IDC_PROXYHOST 1150
+#define IDC_PROXYPORT 1151
+#define IDC_PROXYUSER 1152
+#define IDC_PROXYPASS 1153
+#define IDC_STATIC11 1154
+#define IDC_STATIC12 1155
+#define IDC_STATIC21 1156
+#define IDC_STATIC22 1157
+#define IDC_STATIC31 1158
+#define IDC_STATIC32 1159
+#define IDC_PROXYAUTHNTLM 1160
+#define IDC_HKSHOWHIDE 1162
+#define IDC_HKREADMSG 1163
+#define IDC_SOUNDLIST 1163
+#define IDC_HKSEARCH 1164
+#define IDC_CHANGE 1164
+#define IDC_PREVIEW 1165
+#define IDC_HKSHOWOPTIONS 1165
+#define IDC_PLUGINLIST 1167
+#define IDC_FEATURENAME 1168
+#define IDC_CHOOSE 1169
+#define IDC_TO 1170
+#define IDC_ABOUTGROUP 1175
+#define IDC_DESCRIPTION 1176
+#define IDC_AUTHOR 1177
+#define IDC_COPYRIGHT 1178
+#define IDC_VERSION 1179
+#define IDC_HOMEPAGE 1181
+#define IDC_RESTARTREQD 1182
+#define IDC_ICONSET 1183
+#define IDC_BROWSE 1184
+#define IDC_RUNATSTARTBROWSE 1185
+#define IDC_PAGETREE 1186
+#define IDC_RUNNOW 1186
+#define IDC_INACTIVEPERC 1187
+#define IDC_ACTIVEPERC 1188
+#define IDC_SEARCHNEWWND 1188
+#define IDC_RETRIEVING 1193
+#define IDC_TITLETEXT 1196
+#define IDC_GETMORE 1200
+#define IDC_VISIBLEICON 1204
+#define IDC_INVISIBLEICON 1205
+#define IDC_FILEICON 1206
+#define IDC_ONLINEICON 1207
+#define IDC_FILENAMES 1208
+#define IDC_ALLICON 1208
+#define IDC_DONTREPLY 1209
+#define IDC_NONEICON 1209
+#define IDC_USEPREVIOUS 1210
+#define IDC_NODIALOG 1211
+#define IDC_USESPECIFIC 1212
+#define IDC_FILEDIR 1213
+#define IDC_ALLFILESPROGRESS 1217
+#define IDC_CURRENTSPEED 1219
+#define IDC_STAWAYTYPE 1220
+#define IDC_WHITERECT 1221
+#define IDC_ALLSPEED 1221
+#define IDC_CURRENTFILEPROGRESS 1222
+#define IDC_CURRENTFILEGROUP 1223
+#define IDC_FIRSTNAME 1224
+#define IDC_LASTNAME 1225
+#define IDC_CURRENTTRANSFERRED 1225
+#define IDC_DOBDAY 1226
+#define IDC_DOBMONTH 1227
+#define IDC_WEBPAGE 1228
+#define IDC_DOBYEAR 1228
+#define IDC_UPDATING 1231
+#define IDC_NAMEORDER 1234
+#define IDC_AUTOHIDE 1235
+#define IDC_HIDETIME 1236
+#define IDC_RECONNECTREQD 1239
+#define IDC_IMPORT 1241
+#define IDC_TOMAIN 1243
+#define IDC_TOPROTO 1244
+#define IDC_PROTOLIST 1245
+#define IDC_TODEFICON 1246
+#define IDC_IMPORTMULTI 1247
+#define IDC_MAXSIZEHEIGHT 1254
+#define IDC_MAXSIZESPIN 1255
+#define IDC_FONTID 1256
+#define IDC_SAMETYPE 1257
+#define IDC_SAMESTYLE 1258
+#define IDC_SAMECOLOUR 1259
+#define IDC_SAMEAS 1260
+#define IDC_TYPEFACE 1261
+#define IDC_BOLD 1262
+#define IDC_ITALIC 1263
+#define IDC_COLOUR 1264
+#define IDC_UNDERLINE 1265
+#define IDC_HOTCOLOUR 1267
+#define IDC_SAMESIZE 1268
+#define IDC_BKGCOLOUR 1269
+#define IDC_FILENAME 1271
+#define IDC_SCROLL 1277
+#define IDC_PROPORTIONAL 1278
+#define IDC_SELCOLOUR 1281
+#define IDC_QUICKCOLOUR 1282
+#define IDC_SMOOTHTIME 1283
+#define IDC_SMOOTHTIMESPIN 1284
+#define IDC_GREYOUT 1285
+#define IDC_ROWHEIGHT 1285
+#define IDC_ROWHEIGHTSPIN 1286
+#define IDC_GREYOUTOPTS 1288
+#define IDC_GROUPINDENT 1289
+#define IDC_GROUPINDENTSPIN 1290
+#define IDC_LEFTMARGIN 1291
+#define IDC_SAMPLE 1292
+#define IDC_LEFTMARGINSPIN 1292
+#define IDC_FONTSIZE 1293
+#define IDC_STRETCHH 1298
+#define IDC_STRETCHV 1299
+#define IDC_TILEH 1300
+#define IDC_SCRIPT 1300
+#define IDC_TILEV 1301
+#define IDC_GAMMACORRECT 1302
+#define IDC_INTERESTS 1305
+#define IDC_EMAILS 1306
+#define IDC_PAST 1307
+#define IDC_HIDEOFFLINEOPTS 1308
+#define IDC_PHONES 1308
+#define IDC_SMS 1310
+#define IDC_AREA 1312
+#define IDC_UPDATE 1313
+#define IDC_DONTCYCLE 1315
+#define IDC_PRIMARYSTATUS 1316
+#define IDC_CYCLE 1317
+#define IDC_CYCLETIME 1318
+#define IDC_CYCLETIMESPIN 1319
+#define IDC_HIDETIMESPIN 1320
+#define IDC_MULTITRAY 1321
+#define IDC_ALWAYSMULTI 1322
+#define IDC_SHOWICON 1323
+#define IDC_SHOWPROTO 1324
+#define IDC_SHOWSTATUS 1325
+#define IDC_EQUALSECTIONS 1326
+#define IDC_SHOWSBAR 1329
+#define IDC_RIGHTMIRANDA 1330
+#define IDC_RIGHTSTATUS 1331
+#define IDC_ININAME 1333
+#define IDC_VIEWINI 1334
+#define IDC_SECURITYINFO 1335
+#define IDC_SETTINGNAME 1336
+#define IDC_NEWVALUE 1337
+#define IDC_WARNNOMORE 1338
+#define IDC_DELETE 1339
+#define IDC_RECYCLE 1340
+#define IDC_NEWNAME 1341
+#define IDC_MOVE 1342
+#define IDC_LEAVE 1343
+#define IDC_EXPERT 1346
+#define IDC_SORTBYNAME 1347
+#define IDC_STAUTOHIDESECS 1349
+#define IDC_STCLISTGROUP 1350
+#define IDC_DISABLEDRAGDROP 1351
+#define IDC_NOTEDITLABELS 1352
+#define IDC_SHOWSELALWAYS 1353
+#define IDC_TRACKSELECT 1354
+#define IDC_SHOWGROUPCOUNTS 1355
+#define IDC_HIDECOUNTSWHENEMPTY 1356
+#define IDC_DIVIDERONOFF 1357
+#define IDC_NOTNOTRANSLUCENTSEL 1358
+#define IDC_LINEWITHGROUPS 1359
+#define IDC_QUICKSEARCHVISONLY 1360
+#define IDC_SORTGROUPSALPHA 1361
+#define IDC_NOTNOSMOOTHSCROLLING 1362
+#define IDC_BITMAP 1363
+#define IDC_STWINDOWGROUP 1364
+#define IDC_STATIC01 1365
+#define IDC_CATEGORYLIST 1366
+#define IDC_LOADICONS 1369
+#define IDC_STICONSGROUP 1371
+#define IDC_MSGICON 1375
+#define IDC_URLICON 1376
+#define IDC_STNOPAGE 1377
+#define IDC_STCHECKMARKS 1380
+#define IDC_STSAMETEXT 1382
+#define IDC_STASTEXT 1383
+#define IDC_STSIZETEXT 1384
+#define IDC_STCOLOURTEXT 1385
+#define IDC_STHORZBAR 1386
+#define IDC_MIRANDA 1388
+#define IDC_STATUSBAR 1389
+#define IDC_PROTOIDGROUP 1392
+#define IDC_BYPROTOID 1393
+#define IDC_PROTOID 1394
+#define IDC_EMAILGROUP 1395
+#define IDC_BYEMAIL 1396
+#define IDC_STNAMENICK 1397
+#define IDC_NAMEGROUP 1398
+#define IDC_BYNAME 1399
+#define IDC_STNAMEFIRST 1400
+#define IDC_STNAMELAST 1401
+#define IDC_ADVANCEDGROUP 1402
+#define IDC_BYADVANCED 1403
+#define IDC_ADVANCED 1404
+#define IDC_STSIMPLERIGHT 1440
+#define IDC_NETLIBUSERS 1443
+#define IDC_STOFTENPORT 1445
+#define IDC_STATIC51 1446
+#define IDC_STATIC52 1447
+#define IDC_STATIC43 1448
+#define IDC_LOGOPTIONS 1449
+#define IDC_PORTSRANGE 1450
+#define IDC_TOCONSOLE 1451
+#define IDC_STATIC53 1451
+#define IDC_SHOWCONSOLEATSTART 1452
+#define IDC_PORTSRANGEO 1452
+#define IDC_STATIC54 1453
+#define IDC_SHOWCONSOLE 1454
+#define IDC_TOOUTPUTDEBUGSTRING 1455
+#define IDC_TOFILE 1456
+#define IDC_CLEARCONSOLE 1457
+#define IDC_RUNATSTART 1458
+#define IDC_DUMPSENT 1464
+#define IDC_DUMPPROXY 1466
+#define IDC_TEXTDUMPS 1467
+#define IDC_AUTODETECTTEXT 1468
+#define IDC_TIMEFORMAT 1469
+#define IDC_FILENAMEBROWSE 1470
+#define IDC_SHOWTHISDLGATSTART 1471
+#define IDC_FILEDIRBROWSE 1475
+#define IDC_ALLFILESGROUP 1476
+#define IDC_SCANCMDLINEBROWSE 1476
+#define IDC_ALLTRANSFERRED 1477
+#define IDC_OPENFOLDER 1478
+#define IDC_OPENFILE 1479
+#define IDC_TOTALSIZE 1480
+#define IDC_APPENDNICKTODIR 1483
+#define IDC_AUTOACCEPT 1484
+#define IDC_SCANCMDLINE 1485
+#define IDC_WARNBEFOREOPENING 1488
+#define IDC_SCANDURINGDL 1489
+#define IDC_SCANAFTERDL 1490
+#define IDC_NOSCANNER 1491
+#define IDC_ST_CMDLINE 1492
+#define IDC_ST_CMDLINEHELP 1493
+#define IDC_PROPERTIES 1496
+#define IDC_RESUME 1497
+#define IDC_EXISTINGICON 1499
+#define IDC_RESUMEALL 1500
+#define IDC_OVERWRITE 1501
+#define IDC_OVERWRITEALL 1502
+#define IDC_SKIP 1503
+#define IDC_EXISTINGSIZE 1506
+#define IDC_EXISTINGDATE 1507
+#define IDC_EXISTINGTYPE 1508
+#define IDC_NEWICON 1509
+#define IDC_NEWSIZE 1510
+#define IDC_NEWDATE 1511
+#define IDC_NEWTYPE 1512
+#define IDC_SAVEAS 1513
+#define IDC_ASK 1516
+#define IDC_RENAME 1519
+#define IDC_VIRUSSCANNERGROUP 1520
+#define IDC_HIDE 1534
+#define IDC_TOPLINE 1535
+#define IDC_GPLBTN 1536
+#define IDC_MAIL 1536
+#define IDC_MYHANDLE 1540
+#define IDC_GROUP 1541
+#define IDC_ADDED 1542
+#define IDC_AUTH 1543
+#define IDC_PLUGINSTATIC1 1559
+#define IDC_DELETEHISTORY 1560
+#define IDC_HOTKEYURLSTR 1567
+#define IDC_SETNASTR 1568
+#define IDC_AAUTHOR 1569
+#define IDC_AHOMEPAGE 1570
+#define IDC_AVERSION 1571
+#define IDC_ACOPYRIGHT 1572
+#define IDC_ADESCRIPTION 1573
+#define IDC_PLUGINENABLE 1574
+#define IDC_AUTHREQ 1577
+#define IDC_AUTHGB 1578
+#define IDC_BRINGTOFRONT 1579
+#define IDC_PROTOCOL 1580
+#define IDC_CONTRIBLINK 1586
+#define IDC_HOMELINK 1587
+#define IDC_SUPPORTLINK 1588
+#define IDC_DEVS 1589
+#define IDC_GPL 1590
+#define IDC_LOGO 1591
+#define IDC_CREDITSTEXT 1595
+#define IDC_WSLOCK 1599
+#define IDC_BLINKTIME 1607
+#define IDC_BLINKSPIN 1608
+#define IDC_DISABLEBLINK 1609
+#define IDC_IDLE 1610
+#define IDC_SBPANELBEVEL 1611
+#define IDC_DROPSHADOW 1612
+#define IDC_SHOWGRIP 1612
+#define IDC_NOSCROLLBAR 1613
+#define IDC_BUTTON1 1633
+#define IDC_IDLECHECK 1636
+#define IDC_IDLEONWINDOWS 1637
+#define IDC_IDLEONMIRANDA 1638
+#define IDC_IDLEUSEGLI 1639
+#define IDC_SCREENSAVER 1642
+#define IDC_LOCKED 1643
+#define IDC_IDLESHORT 1644
+#define IDC_IDLELONG 1645
+#define IDC_IDLE1STTIME 1646
+#define IDC_IDLE2NDTIME 1647
+#define IDC_IDLEPRIVATE 1649
+#define IDC_AASTATUS 1650
+#define IDC_AASHORTIDLE 1651
+#define IDC_AALONGSTATUS 1652
+#define IDC_AALONGIDLE 1656
+#define IDC_ONDESKTOP 1657
+#define IDC_WINCOLOUR 1659
+#define IDC_ICONBLINK 1660
+#define IDC_STMSDELAY 1661
+#define IDI_SEARCHALL 32548
+#define ID_ICQ_EXIT 40001
+#define IDM_COPY 40001
+#define ID_RESET 40002
+#define POPUP_HIDEEMPTYGROUPS 40003
+#define POPUP_NEWSUBGROUP 40004
+#define POPUP_HIDEOFFLINE 40005
+#define POPUP_GROUPHIDEOFFLINE 40006
+#define POPUP_HIDEOFFLINEROOT 40007
+#define POPUP_DISABLEGROUPS 40008
+#define IDC_SENDMESSAGE 40009
+#define IDM_COPYALL 40011
+#define IDM_SELECTALL 40012
+#define IDM_CLEAR 40013
+#define IDM_OPENNEW 40014
+#define IDM_OPENEXISTING 40015
+#define IDM_COPYLINK 40016
+#define POPUP_HIDEMIRANDA 40017
+#define ID_TRAY_HIDE 40038
+#define ID_TRAY_EXIT 40040
+#define POPUP_NEWGROUP 40050
+#define POPUP_RENAMEGROUP 40052
+#define POPUP_DELETEGROUP 40053
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 269
+#define _APS_NEXT_COMMAND_VALUE 40018
+#define _APS_NEXT_CONTROL_VALUE 1662
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/miranda-wine/plugins/clist/resource.rc b/miranda-wine/plugins/clist/resource.rc new file mode 100644 index 0000000..698307c --- /dev/null +++ b/miranda-wine/plugins/clist/resource.rc @@ -0,0 +1,706 @@ +// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+#include <winres.h>
+#include <statusmodes.h>
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DELETECONTACT DIALOGEX 0, 0, 284, 90
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS |
+ DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Delete Contact"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "No",IDNO,162,38,65,14
+ PUSHBUTTON "Yes",IDYES,54,38,65,14
+ CONTROL "Hide from list only, in order to keep their history and ignore/visibility settings",
+ IDC_HIDE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
+ WS_TABSTOP,7,65,270,9
+ LTEXT "Use Options->Ignore (expert mode) to unhide contacts.",
+ IDC_STATIC,20,78,257,8
+ CONTROL "Are you sure you want to delete %s?",IDC_TOPLINE,"Static",
+ SS_SIMPLE | SS_NOPREFIX | WS_GROUP,7,7,270,8
+ LTEXT "This will erase all history and settings for this contact!",
+ IDC_STATIC,7,18,239,14
+END
+
+IDD_OPT_HOTKEY DIALOGEX 0, 0, 238, 136
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Hotkeys",IDC_STATIC,4,4,230,126
+ CONTROL "Show/Hide:",IDC_SHOWHIDE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,14,19,78,9
+ CONTROL "HotKey1",IDC_HKSHOWHIDE,"msctls_hotkey32",WS_BORDER |
+ WS_TABSTOP,92,17,93,12
+ CONTROL "Read Msg:",IDC_READMSG,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,14,36,78,9
+ CONTROL "HotKey1",IDC_HKREADMSG,"msctls_hotkey32",WS_BORDER |
+ WS_TABSTOP,92,34,93,12
+ CONTROL "Net Search:",IDC_NETSEARCH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,14,53,78,9
+ CONTROL "HotKey1",IDC_HKSEARCH,"msctls_hotkey32",WS_BORDER |
+ WS_TABSTOP,92,51,93,12
+ LTEXT "URL:",IDC_HOTKEYURLSTR,26,71,22,8
+ EDITTEXT IDC_SEARCHURL,92,69,136,12,ES_AUTOHSCROLL
+ CONTROL "Open in new browser window",IDC_SEARCHNEWWND,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,92,86,136,10
+ CONTROL "Show Options",IDC_SHOWOPTIONS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,14,107,71,9
+ CONTROL "HotKey1",IDC_HKSHOWOPTIONS,"msctls_hotkey32",WS_BORDER |
+ WS_TABSTOP,92,105,93,12
+END
+
+IDD_OPT_CLIST DIALOGEX 0, 0, 314, 204
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Hide offline users",IDC_HIDEOFFLINE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,10,17,124,10
+ CONTROL "Hide empty groups",IDC_HIDEEMPTYGROUPS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,10,33,124,10
+ CONTROL "Disable groups",IDC_DISABLEGROUPS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,10,50,124,10
+ CONTROL "Ask before deleting contacts",IDC_CONFIRMDELETE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,10,67,124,10
+ CONTROL "Sort contacts by name",IDC_SORTBYNAME,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,153,14,144,10
+ CONTROL "Sort contacts by status",IDC_SORTBYSTATUS,"Button",
+ BS_AUTORADIOBUTTON,153,26,149,10
+ CONTROL "Sort contacts by protocol",IDC_SORTBYPROTO,"Button",
+ BS_AUTORADIOBUTTON,153,38,151,10
+ CONTROL "Single click interface",IDC_ONECLK,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,152,68,150,10
+ CONTROL "Always show status in tooltip",IDC_ALWAYSSTATUS,"Button",
+ BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,152,
+ 81,151,11
+ CONTROL "Disable icon blinking",IDC_DISABLEBLINK,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,152,95,86,9
+ EDITTEXT IDC_BLINKTIME,153,109,35,12,ES_NUMBER
+ LTEXT "ms delay",IDC_STMSDELAY,192,110,113,8
+ CONTROL "Show",IDC_DONTCYCLE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,10,143,97,10
+ COMBOBOX IDC_PRIMARYSTATUS,107,142,78,70,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "icon when statuses differ",IDC_STATIC,189,144,116,8,NOT
+ WS_GROUP
+ CONTROL "Cycle icons every",IDC_CYCLE,"Button",
+ BS_AUTORADIOBUTTON,10,160,97,10
+ EDITTEXT IDC_CYCLETIME,107,159,30,12,ES_RIGHT | ES_NUMBER
+ CONTROL "Spin1",IDC_CYCLETIMESPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,127,158,
+ 10,14
+ LTEXT "seconds, when statuses differ",IDC_STATIC,140,161,165,8,
+ NOT WS_GROUP
+ CONTROL "Show multiple icons",IDC_MULTITRAY,"Button",
+ BS_AUTORADIOBUTTON,10,177,98,10
+ CONTROL "Only when statuses differ",IDC_ALWAYSMULTI,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,108,177,198,10
+ GROUPBOX "Contact List",IDC_STCLISTGROUP,2,2,135,126
+ GROUPBOX "System tray icon",IDC_STATIC,143,57,169,70
+ GROUPBOX "System tray icon when using multiple protocols",
+ IDC_STATIC,2,131,310,66
+ GROUPBOX "Contact List Sorting",IDC_STATIC,143,2,169,54,WS_GROUP
+ CONTROL "Spin5",IDC_BLINKSPIN,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS |
+ UDS_HOTTRACK,173,97,11,21
+ CONTROL "Disable icon blinking",IDC_ICONBLINK,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,10,84,97,10
+END
+
+IDD_OPT_CLUI DIALOGEX 0, 0, 313, 245
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Window",IDC_STWINDOWGROUP,4,4,305,154
+ CONTROL "Always on top",IDC_ONTOP,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,18,128,10
+ CONTROL "Tool style main window",IDC_TOOLWND,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,32,128,10
+ CONTROL "Minimize to tray",IDC_MIN2TRAY,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,46,128,10
+ CONTROL "Hide contact list after it has been idle for",
+ IDC_AUTOHIDE,"Button",BS_AUTOCHECKBOX | BS_TOP |
+ BS_MULTILINE | WS_TABSTOP,141,18,162,10
+ EDITTEXT IDC_HIDETIME,151,33,30,12,ES_RIGHT | ES_NUMBER
+ CONTROL "Spin1",IDC_HIDETIMESPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,172,32,10,
+ 14
+ LTEXT "seconds",IDC_STATIC01,186,35,56,8
+ CONTROL "Automatically resize window to height of list",
+ IDC_AUTOSIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,141,
+ 55,162,10
+ LTEXT "maximum",IDC_STATIC21,151,71,45,8
+ EDITTEXT IDC_MAXSIZEHEIGHT,197,69,31,12,ES_RIGHT | ES_AUTOHSCROLL |
+ ES_NUMBER
+ CONTROL "Spin1",IDC_MAXSIZESPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_HOTTRACK,218,68,10,14
+ LTEXT "% of screen",IDC_STATIC22,230,71,69,8
+ CONTROL "Size upwards",IDC_AUTOSIZEUPWARD,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,151,86,147,10
+ LTEXT "Title bar text:",IDC_STATIC,12,106,51,8
+ GROUPBOX "Translucency options (Windows 2000/XP only)",IDC_STATIC,
+ 4,161,305,80
+ CONTROL "Fade contact list in/out",IDC_FADEINOUT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,174,163,10
+ CONTROL "Transparent contact list",IDC_TRANSPARENT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,191,151,9
+ LTEXT "Inactive opacity:",IDC_STATIC11,23,206,89,8
+ CONTROL "Slider2",IDC_TRANSINACTIVE,"msctls_trackbar32",TBS_TOP |
+ TBS_NOTICKS | WS_TABSTOP,112,205,130,11
+ LTEXT "Active opacity:",IDC_STATIC12,23,221,89,8
+ CONTROL "Slider2",IDC_TRANSACTIVE,"msctls_trackbar32",TBS_TOP |
+ TBS_NOTICKS | WS_TABSTOP,112,221,130,11
+ LTEXT "000%",IDC_INACTIVEPERC,246,206,29,8,SS_NOPREFIX
+ LTEXT "000%",IDC_ACTIVEPERC,246,222,29,8,SS_NOPREFIX
+ CONTROL "Show menu bar",IDC_SHOWMAINMENU,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,60,128,10
+ CONTROL "Easy move",IDC_CLIENTDRAG,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,74,128,10
+ CONTROL "Show title bar",IDC_SHOWCAPTION,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,88,128,10
+ CONTROL "If window is partially covered, bring to front instead of hiding",
+ IDC_BRINGTOFRONT,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
+ WS_TABSTOP,141,102,162,16
+ EDITTEXT IDC_TITLETEXT,63,104,72,12,ES_AUTOHSCROLL
+ CONTROL "Show drop shadow (restart required)",IDC_DROPSHADOW,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,122,138,10
+ CONTROL "Pin to desktop",IDC_ONDESKTOP,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,13,137,128,10
+END
+
+IDD_OPT_CLC DIALOGEX 0, 0, 314, 251
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Items",IDC_STATIC,2,2,310,114
+ CONTROL "Show divider between online and offline contacts",
+ IDC_DIVIDERONOFF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 11,13,179,10
+ CONTROL "Hot track items as mouse passes over",IDC_TRACKSELECT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,28,179,10
+ CONTROL "Disable drag and drop of items",IDC_DISABLEDRAGDROP,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,43,179,10
+ CONTROL "Disable rename of items by clicking twice",
+ IDC_NOTEDITLABELS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 11,58,179,10
+ CONTROL "Show selection even when list is not focused",
+ IDC_SHOWSELALWAYS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 11,73,179,10
+ CONTROL "Make selection highlight translucent",
+ IDC_NOTNOTRANSLUCENTSEL,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,11,88,179,10
+ LTEXT "'Hide Offline' means to hide:",IDC_STATIC,191,10,112,8
+ CONTROL "Tree1",IDC_HIDEOFFLINEOPTS,"SysTreeView32",
+ TVS_DISABLEDRAGDROP | TVS_NOTOOLTIPS | WS_BORDER |
+ WS_TABSTOP | 0x4000,191,20,112,86
+ GROUPBOX "Groups",IDC_STATIC,2,120,148,121
+ CONTROL "Draw a line alongside group names",IDC_LINEWITHGROUPS,
+ "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,11,
+ 129,131,16
+ CONTROL "Show counts of number of contacts in a group",
+ IDC_SHOWGROUPCOUNTS,"Button",BS_AUTOCHECKBOX |
+ BS_MULTILINE | WS_TABSTOP,11,147,131,16
+ CONTROL "Hide group counts when there are none online",
+ IDC_HIDECOUNTSWHENEMPTY,"Button",BS_AUTOCHECKBOX |
+ BS_MULTILINE | WS_TABSTOP,11,165,131,16
+ CONTROL "Sort groups alphabetically",IDC_SORTGROUPSALPHA,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,11,183,131,
+ 16
+ CONTROL "Quicksearch in open groups only",IDC_QUICKSEARCHVISONLY,
+ "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,11,
+ 201,131,16
+ LTEXT "Indent groups by:",IDC_STATIC,11,221,67,8
+ EDITTEXT IDC_GROUPINDENT,78,219,31,12,ES_RIGHT | ES_NUMBER
+ CONTROL "Spin1",IDC_GROUPINDENTSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,95,215,10,
+ 14
+ LTEXT "pixels",IDC_STATIC,112,221,36,8
+ GROUPBOX "Visual",IDC_STATIC,156,120,156,121
+ CONTROL "Scroll list smoothly",IDC_NOTNOSMOOTHSCROLLING,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,164,130,139,10
+ LTEXT "Time:",IDC_STATIC11,174,144,42,8
+ EDITTEXT IDC_SMOOTHTIME,216,142,31,12,ES_RIGHT | ES_NUMBER
+ CONTROL "Spin1",IDC_SMOOTHTIMESPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,237,137,
+ 10,14
+ LTEXT "milliseconds",IDC_STATIC12,250,140,56,8,SS_CENTERIMAGE
+ LTEXT "Left margin:",IDC_STATIC,165,180,52,8
+ EDITTEXT IDC_LEFTMARGIN,215,180,31,12,ES_RIGHT | ES_NUMBER
+ CONTROL "Spin1",IDC_LEFTMARGINSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,240,180,
+ 10,14
+ LTEXT "pixels",IDC_STATIC,250,180,54,8
+ CONTROL "Grey out entire list when:",IDC_GREYOUT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,165,195,139,10
+ CONTROL "Tree1",IDC_GREYOUTOPTS,"SysTreeView32",
+ TVS_DISABLEDRAGDROP | TVS_NOTOOLTIPS | WS_BORDER |
+ WS_TABSTOP | 0x4000,165,205,139,30
+ CONTROL "Dim idle contacts",IDC_IDLE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,11,102,153,10
+ CONTROL "Hide vertical scroll bar",IDC_NOSCROLLBAR,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,165,160,140,10
+END
+
+IDD_OPT_CLCTEXT DIALOGEX 0, 0, 277, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Fonts",IDC_STATIC,4,4,269,125
+ COMBOBOX IDC_FONTID,12,17,253,87,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "same",IDC_STSAMETEXT,19,32,45,10,SS_CENTERIMAGE
+ CONTROL "Typeface",IDC_SAMETYPE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,64,32,52,10
+ CONTROL "Size",IDC_SAMESIZE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,117,32,45,10
+ CONTROL "Style",IDC_SAMESTYLE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,163,32,48,10
+ CONTROL "Colour",IDC_SAMECOLOUR,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,212,32,53,10
+ LTEXT "as:",IDC_STASTEXT,19,46,45,10,SS_CENTERIMAGE
+ COMBOBOX IDC_SAMEAS,64,45,196,88,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "",IDC_STHORZBAR,"Static",SS_ETCHEDHORZ,9,64,259,1
+ COMBOBOX IDC_TYPEFACE,12,72,136,182,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_SCRIPT,156,72,60,68,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE,225,72,40,69,CBS_DROPDOWN | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Bold",IDC_BOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,
+ 88,45,10
+ CONTROL "Italic",IDC_ITALIC,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,65,88,52,10
+ CONTROL "Underline",IDC_UNDERLINE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,117,88,66,10
+ CONTROL "",IDC_COLOUR,"ColourPicker",WS_TABSTOP,206,87,59,12
+ EDITTEXT IDC_SAMPLE,63,104,151,16,ES_CENTER | ES_READONLY | NOT
+ WS_TABSTOP
+ GROUPBOX "Rows",IDC_STATIC,4,134,269,31
+ LTEXT "Row height:",IDC_STATIC,12,148,65,8
+ EDITTEXT IDC_ROWHEIGHT,77,146,31,12,ES_RIGHT | ES_NUMBER
+ CONTROL "Spin1",IDC_ROWHEIGHTSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,97,145,10,
+ 14
+ LTEXT "pixels",IDC_STATIC,112,148,62,8
+ GROUPBOX "Additional Colours",IDC_STATIC,4,171,269,65
+ LTEXT "Selected text:",IDC_STATIC,12,186,65,8
+ CONTROL "",IDC_SELCOLOUR,"ColourPicker",WS_TABSTOP,77,184,29,12
+ LTEXT "Hottrack text:",IDC_STATIC,12,202,65,8
+ CONTROL "",IDC_HOTCOLOUR,"ColourPicker",WS_TABSTOP,77,200,29,12
+ CONTROL "Gamma correction",IDC_GAMMACORRECT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,119,201,117,10
+ LTEXT "Quicksearch text:",IDC_STATIC,12,218,65,8
+ CONTROL "",IDC_QUICKCOLOUR,"ColourPicker",WS_TABSTOP,77,216,29,
+ 12
+ LTEXT "Size:",IDC_STSIZETEXT,231,114,34,8,NOT WS_VISIBLE
+ LTEXT "Colour:",IDC_STCOLOURTEXT,228,102,37,8,NOT WS_VISIBLE
+END
+
+IDD_OPT_CLCBKG DIALOGEX 0, 0, 235, 154
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Contact List Background",IDC_STATIC,4,4,227,146
+ LTEXT "Background colour",IDC_STATIC,59,35,72,8,NOT WS_GROUP
+ CONTROL "",IDC_BKGCOLOUR,"ColourPicker",WS_TABSTOP,22,35,32,10
+ LTEXT "Selection colour",IDC_STATIC,59,51,72,8
+ CONTROL "",IDC_SELCOLOUR,"ColourPicker",WS_TABSTOP,22,51,32,10
+ CONTROL "Use background image",IDC_BITMAP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,12,70,161,10
+ EDITTEXT IDC_FILENAME,22,88,184,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_BROWSE,208,88,15,11
+ CONTROL "Stretch to width",IDC_STRETCHH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,22,105,100,10
+ CONTROL "Stretch to height",IDC_STRETCHV,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,122,105,101,10
+ CONTROL "Tile horizontally",IDC_TILEH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,22,118,100,10
+ CONTROL "Tile vertically",IDC_TILEV,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,122,118,101,10
+ CONTROL "Scroll with text",IDC_SCROLL,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,22,131,100,10
+ CONTROL "Stretch proportionally",IDC_PROPORTIONAL,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,122,131,101,10
+ CONTROL "Use Windows colours",IDC_WINCOLOUR,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,12,20,156,10
+END
+
+IDD_OPT_SBAR DIALOGEX 0, 0, 178, 212
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Status Bar",IDC_STATIC,4,4,170,204
+ CONTROL "Show status bar",IDC_SHOWSBAR,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,12,17,152,10
+ CONTROL "Show icons",IDC_SHOWICON,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,22,33,142,10
+ CONTROL "Show protocol names",IDC_SHOWPROTO,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,22,48,142,10
+ CONTROL "Show status text",IDC_SHOWSTATUS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,22,63,142,10
+ CONTROL "Right click opens status menu",IDC_RIGHTSTATUS,"Button",
+ BS_AUTORADIOBUTTON,22,160,142,10
+ CONTROL "Right click opens Miranda IM menu",IDC_RIGHTMIRANDA,
+ "Button",BS_AUTORADIOBUTTON,22,147,142,10
+ CONTROL "Make sections equal width",IDC_EQUALSECTIONS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,22,78,142,10
+ CONTROL "Show bevels on panels",IDC_SBPANELBEVEL,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,22,94,107,10
+ CONTROL "Show resize grip indicator",IDC_SHOWGRIP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,22,110,96,10
+END
+
+IDD_OPT_CLCTEXTSIMPLE DIALOGEX 0, 0, 277, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Fonts",IDC_STATIC,4,4,269,125
+ COMBOBOX IDC_FONTID,12,17,253,87,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "as:",IDC_STASTEXT,25,34,52,10,SS_CENTERIMAGE
+ COMBOBOX IDC_SAMEAS,77,33,163,88,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "",IDC_STHORZBAR,"Static",SS_ETCHEDHORZ,9,51,259,1
+ COMBOBOX IDC_TYPEFACE,12,58,172,182,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_SCRIPT,192,58,73,68,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "Size:",IDC_STSIZETEXT,33,76,34,8
+ COMBOBOX IDC_FONTSIZE,67,74,54,69,CBS_DROPDOWN | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "Colour:",IDC_STCOLOURTEXT,147,76,37,8
+ CONTROL "",IDC_COLOUR,"ColourPicker",WS_TABSTOP,184,74,59,12
+ CONTROL "Bold",IDC_BOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,58,
+ 90,45,10
+ CONTROL "Italic",IDC_ITALIC,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,117,90,52,10
+ CONTROL "Underline",IDC_UNDERLINE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,179,90,66,10
+ EDITTEXT IDC_SAMPLE,63,104,151,16,ES_CENTER | ES_READONLY | NOT
+ WS_TABSTOP
+ GROUPBOX "Rows",IDC_STATIC,4,134,269,31
+ LTEXT "Row height:",IDC_STATIC,12,148,65,8
+ EDITTEXT IDC_ROWHEIGHT,77,146,31,12,ES_RIGHT | ES_NUMBER
+ CONTROL "Spin1",IDC_ROWHEIGHTSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,97,145,10,
+ 14
+ LTEXT "pixels",IDC_STATIC,112,148,62,8
+ GROUPBOX "Additional Colours",IDC_STATIC,4,171,269,65
+ LTEXT "Selected text:",IDC_STATIC,12,186,65,8
+ CONTROL "",IDC_SELCOLOUR,"ColourPicker",WS_TABSTOP,77,184,29,12
+ LTEXT "Hottrack text:",IDC_STATIC,12,202,65,8
+ CONTROL "",IDC_HOTCOLOUR,"ColourPicker",WS_TABSTOP,77,200,29,12
+ LTEXT "Quicksearch text:",IDC_STATIC,12,218,65,8
+ CONTROL "",IDC_QUICKCOLOUR,"ColourPicker",WS_TABSTOP,77,216,29,
+ 12
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DELETECONTACT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 277
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 85
+ END
+
+ IDD_OPT_HOTKEY, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 234
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 132
+ HORZGUIDE, 23
+ HORZGUIDE, 40
+ HORZGUIDE, 57
+ END
+
+ IDD_OPT_CLIST, DIALOG
+ BEGIN
+ LEFTMARGIN, 2
+ RIGHTMARGIN, 312
+ VERTGUIDE, 10
+ VERTGUIDE, 107
+ TOPMARGIN, 2
+ BOTTOMMARGIN, 202
+ HORZGUIDE, 179
+ HORZGUIDE, 196
+ END
+
+ IDD_OPT_CLUI, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 309
+ VERTGUIDE, 13
+ VERTGUIDE, 23
+ VERTGUIDE, 112
+ VERTGUIDE, 141
+ VERTGUIDE, 151
+ VERTGUIDE, 175
+ VERTGUIDE, 242
+ VERTGUIDE, 246
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 241
+ HORZGUIDE, 18
+ HORZGUIDE, 39
+ HORZGUIDE, 75
+ HORZGUIDE, 180
+ HORZGUIDE, 196
+ END
+
+ IDD_OPT_CLC, DIALOG
+ BEGIN
+ LEFTMARGIN, 2
+ RIGHTMARGIN, 312
+ VERTGUIDE, 11
+ VERTGUIDE, 164
+ VERTGUIDE, 216
+ TOPMARGIN, 2
+ BOTTOMMARGIN, 249
+ HORZGUIDE, 145
+ HORZGUIDE, 163
+ HORZGUIDE, 222
+ END
+
+ IDD_OPT_CLCTEXT, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 273
+ VERTGUIDE, 12
+ VERTGUIDE, 19
+ VERTGUIDE, 77
+ VERTGUIDE, 258
+ VERTGUIDE, 265
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 236
+ HORZGUIDE, 37
+ HORZGUIDE, 51
+ HORZGUIDE, 79
+ HORZGUIDE, 94
+ HORZGUIDE, 152
+ HORZGUIDE, 190
+ HORZGUIDE, 206
+ HORZGUIDE, 222
+ END
+
+ IDD_OPT_CLCBKG, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 231
+ VERTGUIDE, 12
+ VERTGUIDE, 22
+ VERTGUIDE, 122
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 150
+ HORZGUIDE, 24
+ HORZGUIDE, 35
+ HORZGUIDE, 73
+ HORZGUIDE, 89
+ HORZGUIDE, 102
+ HORZGUIDE, 115
+ END
+
+ IDD_OPT_SBAR, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 174
+ VERTGUIDE, 12
+ VERTGUIDE, 22
+ VERTGUIDE, 164
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 208
+ END
+
+ IDD_OPT_CLCTEXTSIMPLE, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 273
+ VERTGUIDE, 12
+ VERTGUIDE, 19
+ VERTGUIDE, 77
+ VERTGUIDE, 258
+ VERTGUIDE, 265
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 236
+ HORZGUIDE, 37
+ HORZGUIDE, 64
+ HORZGUIDE, 80
+ HORZGUIDE, 95
+ HORZGUIDE, 152
+ HORZGUIDE, 190
+ HORZGUIDE, 206
+ HORZGUIDE, 222
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include <windows.h>\r\n"
+ "#include <winres.h>\r\n"
+ "#include <statusmodes.h>\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_RENAME ICON "res\\rename.ico"
+IDI_BLANK ICON "res\\blank.ico"
+IDI_DELETE ICON "res\\delete.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Cursor
+//
+
+IDC_HYPERLINKHAND CURSOR "res\\hyperlin.cur"
+IDC_DROP CURSOR "res\\dragcopy.cur"
+IDC_DROPUSER CURSOR "res\\dropuser.cur"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_CLISTMENU MENU
+BEGIN
+ POPUP "&¤"
+ BEGIN
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", ID_ICQ_EXIT
+ END
+ POPUP "&Status"
+ BEGIN
+ MENUITEM "&Offline\tCtrl+0", ID_STATUS_OFFLINE, CHECKED
+ MENUITEM "On&line\tCtrl+1", ID_STATUS_ONLINE
+ MENUITEM "&Away\tCtrl+2", ID_STATUS_AWAY
+ MENUITEM "&NA\tCtrl+3", ID_STATUS_NA
+ MENUITEM "Occ&upied\tCtrl+4", ID_STATUS_OCCUPIED
+ MENUITEM "&DND\tCtrl+5", ID_STATUS_DND
+ MENUITEM "&Free for chat\tCtrl+6", ID_STATUS_FREECHAT
+ MENUITEM "&Invisible\tCtrl+7", ID_STATUS_INVISIBLE
+ MENUITEM "On the &Phone\tCtrl+8", ID_STATUS_ONTHEPHONE
+ MENUITEM "Out to &Lunch\tCtrl+9", ID_STATUS_OUTTOLUNCH
+ END
+END
+
+IDR_CONTEXT MENU
+BEGIN
+ POPUP "Tray"
+ BEGIN
+ MENUITEM "&Hide/Show", ID_TRAY_HIDE
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", ID_TRAY_EXIT
+ END
+ POPUP "Nowhere"
+ BEGIN
+ MENUITEM "&New Group", POPUP_NEWGROUP
+ MENUITEM SEPARATOR
+ MENUITEM "&Hide Offline Users", POPUP_HIDEOFFLINE
+ MENUITEM "Hide &Offline Users out here", POPUP_HIDEOFFLINEROOT
+ MENUITEM "Hide &Empty Groups", POPUP_HIDEEMPTYGROUPS
+ MENUITEM "Disable &Groups", POPUP_DISABLEGROUPS
+ MENUITEM SEPARATOR
+ MENUITEM "Hide Miranda", POPUP_HIDEMIRANDA
+ END
+ POPUP "Group"
+ BEGIN
+ MENUITEM "&New Subgroup", POPUP_NEWSUBGROUP
+ MENUITEM "&Hide Offline Users in here", POPUP_GROUPHIDEOFFLINE
+ MENUITEM SEPARATOR
+ MENUITEM "&Rename Group", POPUP_RENAMEGROUP
+ MENUITEM "&Delete Group", POPUP_DELETEGROUP
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/miranda-wine/plugins/db3x/Makefile b/miranda-wine/plugins/db3x/Makefile new file mode 100644 index 0000000..5a75630 --- /dev/null +++ b/miranda-wine/plugins/db3x/Makefile @@ -0,0 +1,53 @@ +SRC = commonheaders.c \
+ database.c \
+ dbcache.c \
+ dbcontacts.c \
+ dbevents.c \
+ dbheaders.c \
+ dbini.c \
+ dblists.c \
+ dbmodulechain.c \
+ dbsettings.c \
+ dbtime.c \
+ encrypt.c \
+ init.c
+OBJ = $(SRC:.c=.o)
+RES = resource.res
+LIB = -lgdi32 -lversion -lcomctl32 -lcomdlg32 -lole32
+
+CC = gcc
+RC = windres
+RM = rm
+
+# Install location
+ifdef DEBUG
+BIN = ..\..\bin\debug\plugins\dbx_3x.dll
+else
+BIN = ..\..\bin\release\plugins\dbx_3x.dll
+endif
+
+# Defines
+DEFINES = -DWIN32 -D__SEH_NOOP
+ifdef DEBUG
+DEFINES := $(DEFINES) -D_DEBUG
+endif
+
+# Flags
+LFLAGS = -shared
+RCFLAGS = --input-format rc --output-format coff
+ifdef DEBUG
+CFLAGS = -g $(DEFINES) -I../../include
+else
+CFLAGS = -O1 $(DEFINES) -I../../include
+endif
+
+# Targets
+all : $(OBJ) $(RES)
+ $(CC) $(LFLAGS) $(CFLAGS) -o $(BIN) $(OBJ) $(RES) $(LIB) -Wl
+
+$(RES) : $(RES:.res=.rc) $(RES:.res=.h) Makefile
+ $(RC) $(RCFLAGS) -o $(RES) -i $(RES:.res=.rc)
+
+clean :
+ $(RM) -f $(OBJ) $(RES)
+
diff --git a/miranda-wine/plugins/db3x/commonheaders.c b/miranda-wine/plugins/db3x/commonheaders.c new file mode 100644 index 0000000..14f99f7 --- /dev/null +++ b/miranda-wine/plugins/db3x/commonheaders.c @@ -0,0 +1 @@ +#include "commonheaders.h"
diff --git a/miranda-wine/plugins/db3x/commonheaders.h b/miranda-wine/plugins/db3x/commonheaders.h new file mode 100644 index 0000000..c0a8146 --- /dev/null +++ b/miranda-wine/plugins/db3x/commonheaders.h @@ -0,0 +1,66 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 _WIN32_WINNT 0x0501
+#include <windows.h>
+
+#include <malloc.h>
+
+#ifdef _DEBUG
+# define _ALPHA_BASE_ 1 // defined for CVS builds
+# define _ALPHA_FUSE_ 1 // defined for fuse powered core
+# define _CRTDBG_MAP_ALLOC
+# include <stdlib.h>
+# include <crtdbg.h>
+#endif
+
+#include <commctrl.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <stddef.h>
+#include <process.h>
+#include <io.h>
+#include <string.h>
+#include <direct.h>
+#include "resource.h"
+#include <newpluginapi.h>
+#include <win2k.h>
+#include <m_system.h>
+#include <m_database.h>
+#include <m_langpack.h>
+
+extern PLUGINLINK *pluginLink;
+
+extern struct MM_INTERFACE memoryManagerInterface;
+extern struct LIST_INTERFACE li;
+
+#define mir_alloc(n) memoryManagerInterface.mmi_malloc(n)
+#define mir_free(ptr) memoryManagerInterface.mmi_free(ptr)
+#define mir_realloc(ptr,size) memoryManagerInterface.mmi_realloc(ptr,size)
+
+#ifdef __GNUC__
+#define mir_i64(x) (x##LL)
+#else
+#define mir_i64(x) (x##i64)
+#endif
diff --git a/miranda-wine/plugins/db3x/database.c b/miranda-wine/plugins/db3x/database.c new file mode 100644 index 0000000..38843a7 --- /dev/null +++ b/miranda-wine/plugins/db3x/database.c @@ -0,0 +1,186 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+int ProfileManager(char *szDbDest,int cbDbDest);
+int ShouldAutoCreate(void);
+int CreateDbHeaders(HANDLE hFile);
+int InitialiseDbHeaders(void);
+int InitSettings(void);
+void UninitSettings(void);
+int InitContacts(void);
+void UninitContacts(void);
+int InitEvents(void);
+void UninitEvents(void);
+int InitCrypt(void);
+int InitTime(void);
+int InitModuleNames(void);
+void UninitModuleNames(void);
+int InitCache(void);
+void UninitCache(void);
+int InitIni(void);
+void UninitIni(void);
+
+HANDLE hDbFile=INVALID_HANDLE_VALUE;
+CRITICAL_SECTION csDbAccess;
+struct DBHeader dbHeader;
+char szDbPath[MAX_PATH];
+
+static void UnloadDatabase(void)
+{
+ CloseHandle(hDbFile);
+}
+
+DWORD CreateNewSpace(int bytes)
+{
+ DWORD ofsNew;
+
+ ofsNew=dbHeader.ofsFileEnd;
+ dbHeader.ofsFileEnd+=bytes;
+ DBWrite(0,&dbHeader,sizeof(dbHeader));
+ log2("newspace %d@%08x",bytes,ofsNew);
+ return ofsNew;
+}
+
+void DeleteSpace(DWORD ofs,int bytes)
+{
+ PBYTE buf;
+ log2("deletespace %d@%08x",bytes,ofs);
+ dbHeader.slackSpace+=bytes;
+ DBWrite(0,&dbHeader,sizeof(dbHeader));
+ buf=(PBYTE)mir_alloc(bytes);
+ memset(buf,0,bytes);
+ DBWrite(ofs,buf,bytes);
+ mir_free(buf);
+}
+
+void UnloadDatabaseModule(void)
+{
+ //UninitIni();
+ UninitEvents();
+ UninitSettings();
+ UninitContacts();
+ UninitModuleNames();
+ UninitCache();
+ UnloadDatabase();
+ DeleteCriticalSection(&csDbAccess);
+}
+
+static int GetProfileName(WPARAM wParam, LPARAM lParam)
+{
+ char * p = 0;
+ p = strrchr(szDbPath, '\\');
+ if ( p == 0 ) return 1;
+ p++;
+ strncpy((char*)lParam, p, (size_t) wParam);
+ return 0;
+}
+
+static int GetProfilePath(WPARAM wParam, LPARAM lParam)
+{
+ char * dst = (char*)lParam;
+ char * p = 0;
+ strncpy(dst,szDbPath,wParam);
+ p = strrchr(dst, '\\');
+ if ( p == NULL ) return 1;
+ *p=0;
+ return 0;
+}
+
+int LoadDatabaseModule(void)
+{
+ InitializeCriticalSection(&csDbAccess);
+ log0("DB logging running");
+ {
+ DWORD dummy=0;
+ hDbFile=CreateFile(szDbPath,GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL);
+ if ( hDbFile == INVALID_HANDLE_VALUE ) {
+ return 1;
+ }
+ if ( !ReadFile(hDbFile,&dbHeader,sizeof(dbHeader),&dummy,NULL) ) {
+ CloseHandle(hDbFile);
+ return 1;
+ }
+ }
+ //if(ParseCommandLine()) return 1;
+ if(InitCache()) return 1;
+ if(InitModuleNames()) return 1;
+ if(InitContacts()) return 1;
+ if(InitSettings()) return 1;
+ if(InitEvents()) return 1;
+ if(InitCrypt()) return 1;
+ //if(InitTime()) return 1;
+ //if(InitIni()) return 1;
+ CreateServiceFunction(MS_DB_GETPROFILENAME,GetProfileName);
+ CreateServiceFunction(MS_DB_GETPROFILEPATH,GetProfilePath);
+ return 0;
+}
+
+static DWORD DatabaseCorrupted=0;
+
+void __cdecl dbpanic(void *arg)
+{
+
+ MessageBox(0,Translate("Miranda has detected corruption in your database. This corruption maybe fixed by DBTool. Please download it from http://www.miranda-im.org. Miranda will now shutdown."),Translate("Database Panic"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK);
+ TerminateProcess(GetCurrentProcess(),255);
+ return;
+}
+
+void DatabaseCorruption(void)
+{
+ int kill=0;
+
+ EnterCriticalSection(&csDbAccess);
+ if (DatabaseCorrupted==0) {
+ DatabaseCorrupted++;
+ kill++;
+ } else {
+ /* db is already corrupted, someone else is dealing with it, wait here
+ so that we don't do any more damage */
+ LeaveCriticalSection(&csDbAccess);
+ Sleep(INFINITE);
+ return;
+ }
+ LeaveCriticalSection(&csDbAccess);
+ if (kill) {
+ _beginthread(dbpanic,0,NULL);
+ Sleep(INFINITE);
+ }
+}
+
+#ifdef DBLOGGING
+void DBLog(const char *file,int line,const char *fmt,...)
+{
+ FILE *fp;
+ va_list vararg;
+ char str[1024];
+
+ va_start(vararg,fmt);
+ mir_vsnprintf(str,sizeof(str),fmt,vararg);
+ va_end(vararg);
+ fp=fopen("c:\\mirandadatabase.log.txt","at");
+ fprintf(fp,"%u: %s %d: %s\n",GetTickCount(),file,line,str);
+ fclose(fp);
+}
+#endif
diff --git a/miranda-wine/plugins/db3x/database.h b/miranda-wine/plugins/db3x/database.h new file mode 100644 index 0000000..d2a6a8f --- /dev/null +++ b/miranda-wine/plugins/db3x/database.h @@ -0,0 +1,218 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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.
+*/
+
+
+//all offsets are relative to the start of the file
+//offsets are 0 if there is nothing in the chain or this is the last in the
+//chain
+
+/* tree diagram
+
+DBHeader
+ |-->end of file (plain offset)
+ |-->first contact (DBContact)
+ | |-->next contact (DBContact)
+ | | \--> ...
+ | |-->first settings (DBContactSettings)
+ | | |-->next settings (DBContactSettings)
+ | | | \--> ...
+ | | \-->module name (DBModuleName)
+ | \-->first/last/firstunread event
+ |-->user contact (DBContact)
+ | |-->next contact=NULL
+ | |-->first settings as above
+ | \-->first/last/firstunread event as above
+ \-->first module name (DBModuleName)
+ \-->next module name (DBModuleName)
+ \--> ...
+*/
+
+#define DB_RESIZE_GRANULARITY 16384
+#define DB_THIS_VERSION 0x00000700u
+#define DB_SETTINGS_RESIZE_GRANULARITY 128
+
+#include <pshpack1.h>
+struct DBHeader {
+ BYTE signature[16]; // 'Miranda ICQ DB',0,26
+ DWORD version; //as 4 bytes, ie 1.2.3.10=0x0102030a
+ //this version is 0x00000700
+ DWORD ofsFileEnd; //offset of the end of the database - place to write
+ //new structures
+ DWORD slackSpace; //a counter of the number of bytes that have been
+ //wasted so far due to deleting structures and/or
+ //re-making them at the end. We should compact when
+ //this gets above a threshold
+ DWORD contactCount; //number of contacts in the chain,excluding the user
+ DWORD ofsFirstContact; //offset to first struct DBContact in the chain
+ DWORD ofsUser; //offset to struct DBContact representing the user
+ DWORD ofsFirstModuleName; //offset to first struct DBModuleName in the chain
+};
+
+#define DBCONTACT_SIGNATURE 0x43DECADEu
+struct DBContact {
+ DWORD signature;
+ DWORD ofsNext; //offset to the next contact in the chain. zero if
+ //this is the 'user' contact or the last contact
+ //in the chain
+ DWORD ofsFirstSettings; //offset to the first DBContactSettings in the
+ //chain for this contact.
+ DWORD eventCount; //number of events in the chain for this contact
+ DWORD ofsFirstEvent,ofsLastEvent; //offsets to the first and last DBEvent in
+ //the chain for this contact
+ DWORD ofsFirstUnreadEvent; //offset to the first (chronological) unread event
+ //in the chain, 0 if all are read
+ DWORD timestampFirstUnread; //timestamp of the event at ofsFirstUnreadEvent
+};
+
+#define DBMODULENAME_SIGNATURE 0x4DDECADEu
+struct DBModuleName {
+ DWORD signature;
+ DWORD ofsNext; //offset to the next module name in the chain
+ BYTE cbName; //number of characters in this module name
+ char name[1]; //name, no nul terminator
+};
+
+#define DBCONTACTSETTINGS_SIGNATURE 0x53DECADEu
+struct DBContactSettings {
+ DWORD signature;
+ DWORD ofsNext; //offset to the next contactsettings in the chain
+ DWORD ofsModuleName; //offset to the DBModuleName of the owner of these
+ //settings
+ DWORD cbBlob; //size of the blob in bytes. May be larger than the
+ //actual size for reducing the number of moves
+ //required using granularity in resizing
+ BYTE blob[1]; //the blob. a back-to-back sequence of DBSetting
+ //structs, the last has cbName=0
+};
+
+/* not a valid structure, content is figured out on the fly
+struct DBSetting {
+ BYTE cbName; //number of bytes in the name of this setting
+ //this =0 marks the end
+ char szName[...]; //setting name, excluding nul
+ BYTE dataType; //type of data. see m_database.h, db/contact/getsetting
+ union { //a load of types of data, length is defined by dataType
+ BYTE bVal; WORD wVal; DWORD dVal;
+ struct {
+ WORD cbString;
+ char szVal[...]; //excludes nul terminator
+ };
+ struct {
+ WORD cbBlob;
+ BYTE blobVal[...];
+ };
+ };
+};
+*/
+
+#define DBEVENT_SIGNATURE 0x45DECADEu
+struct DBEvent {
+ DWORD signature;
+ DWORD ofsPrev,ofsNext; //offset to the previous and next events in the
+ //chain. Chain is sorted chronologically
+ DWORD ofsModuleName; //offset to a DBModuleName struct of the name of
+ //the owner of this event
+ DWORD timestamp; //seconds since 00:00:00 01/01/1970
+ DWORD flags; //see m_database.h, db/event/add
+ WORD eventType; //module-defined event type
+ DWORD cbBlob; //number of bytes in the blob
+ BYTE blob[1]; //the blob. module-defined formatting
+};
+#include <poppack.h>
+
+typedef struct
+{
+ BYTE bIsResident;
+ char name[1];
+}
+ DBCachedSettingName;
+
+typedef struct
+{
+ char* name;
+ DBVARIANT value;
+}
+ DBCachedGlobalValue;
+
+typedef struct DBCachedContactValue_tag
+{
+ char* name;
+ DBVARIANT value;
+ struct DBCachedContactValue_tag* next;
+}
+ DBCachedContactValue;
+
+typedef struct
+{
+ HANDLE hContact;
+ HANDLE hNext;
+ DBCachedContactValue* first;
+}
+ DBCachedContactValueList;
+
+
+//databasecorruption: called if any signatures are broken. very very fatal
+void DatabaseCorruption(void);
+PBYTE DBRead(DWORD ofs,int bytesRequired,int *bytesAvail); //any preview result could be invalidated by the next call
+void DBWrite(DWORD ofs,PVOID pData,int count);
+void DBFlush(int setting);
+void DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes);
+DWORD CreateNewSpace(int bytes);
+void DeleteSpace(DWORD ofs,int bytes);
+void GetProfileDirectory(char *szPath,int cbPath);
+int GetDefaultProfilePath(char *szPath,int cbPath,int *specified);
+int ShouldShowProfileManager(void);
+int CheckDbHeaders(struct DBHeader * hdr);
+int CreateDbHeaders(HANDLE hFile);
+int LoadDatabaseModule(void);
+void UnloadDatabaseModule(void);
+
+void Utf8Decode( char* str, wchar_t** ucs2 );
+char* Utf8Encode( const char* src );
+char* Utf8EncodeUcs2( const wchar_t* src );
+
+#ifdef _DEBUG
+#define MAXCACHEDREADSIZE 512
+#else
+#define MAXCACHEDREADSIZE 2048 //push it to 1K //technically 4096 would work, but I'm not going to push it
+#endif
+
+#ifdef _DEBUG
+//#define DBLOGGING
+#endif
+#ifdef DBLOGGING
+void DBLog(const char *file,int line,const char *fmt,...);
+#define logg() DBLog(__FILE__,__LINE__,"")
+#define log0(s) DBLog(__FILE__,__LINE__,s)
+#define log1(s,a) DBLog(__FILE__,__LINE__,s,a)
+#define log2(s,a,b) DBLog(__FILE__,__LINE__,s,a,b)
+#define log3(s,a,b,c) DBLog(__FILE__,__LINE__,s,a,b,c)
+#define log4(s,a,b,c,d) DBLog(__FILE__,__LINE__,s,a,b,c,d)
+#else
+#define logg()
+#define log0(s)
+#define log1(s,a)
+#define log2(s,a,b)
+#define log3(s,a,b,c)
+#define log4(s,a,b,c,d)
+#endif
diff --git a/miranda-wine/plugins/db3x/dbcache.c b/miranda-wine/plugins/db3x/dbcache.c new file mode 100644 index 0000000..dd3bc5a --- /dev/null +++ b/miranda-wine/plugins/db3x/dbcache.c @@ -0,0 +1,229 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+
+#define CACHESECTIONSIZE 4096
+#define CACHESECTIONCOUNT 32
+
+extern HANDLE hDbFile;
+extern CRITICAL_SECTION csDbAccess;
+
+static BOOL safetyMode=TRUE;
+static PBYTE pDbCache;
+static DWORD lastUseCounter;
+struct DBCacheSectionInfo {
+ DWORD ofsBase;
+ DWORD lastUsed;
+} static cacheSectionInfo[CACHESECTIONCOUNT];
+
+static __inline int FindSectionForOffset(const DWORD ofs)
+{
+ int i;
+ for(i=0;i<CACHESECTIONCOUNT;i++)
+ if(ofs>=cacheSectionInfo[i].ofsBase && ofs<cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE)
+ return i;
+ return -1;
+}
+
+static __inline int FindLRUSection(void)
+{
+ int i,lru=0;
+ DWORD lowestLastUse=cacheSectionInfo[0].lastUsed;
+ for(i=1;i<CACHESECTIONCOUNT;i++) if(cacheSectionInfo[i].lastUsed<lowestLastUse) {lru=i; lowestLastUse=cacheSectionInfo[i].lastUsed;}
+ return lru;
+}
+
+static __inline void LoadSection(const int i,DWORD ofs)
+{
+ cacheSectionInfo[i].ofsBase=ofs-ofs%CACHESECTIONSIZE;
+ log1("readsect %08x",ofs);
+ SetFilePointer(hDbFile,cacheSectionInfo[i].ofsBase,NULL,FILE_BEGIN);
+ ReadFile(hDbFile,pDbCache+i*CACHESECTIONSIZE,CACHESECTIONSIZE,&ofs,NULL);
+}
+
+static __inline void MoveSection(int *sectId,int dest)
+{
+ CopyMemory(pDbCache+dest*CACHESECTIONSIZE,pDbCache+(*sectId)*CACHESECTIONSIZE,CACHESECTIONSIZE);
+ cacheSectionInfo[dest].ofsBase=cacheSectionInfo[*sectId].ofsBase;
+ *sectId=dest;
+}
+
+
+
+//we are assumed to be in a mutex here
+PBYTE DBRead(DWORD ofs,int bytesRequired,int *bytesAvail)
+{
+
+ int part1sect;
+ int part2sect;
+
+
+ part1sect = FindSectionForOffset(ofs);
+ if (ofs%CACHESECTIONSIZE+bytesRequired<CACHESECTIONSIZE) {
+ //only one section required
+ if(part1sect==-1) {
+ part1sect=FindLRUSection();
+ LoadSection(part1sect,ofs);
+ }
+ cacheSectionInfo[part1sect].lastUsed=++lastUseCounter;
+ if(bytesAvail!=NULL) *bytesAvail=cacheSectionInfo[part1sect].ofsBase+CACHESECTIONSIZE-ofs;
+ return pDbCache+part1sect*CACHESECTIONSIZE+(ofs-cacheSectionInfo[part1sect].ofsBase);
+ }
+ //two sections are required
+ part2sect=FindSectionForOffset(ofs+CACHESECTIONSIZE);
+ if(part1sect!=-1) {
+ if(part2sect==-1) { //first part in cache, but not second part
+ if(part1sect==CACHESECTIONCOUNT-1) MoveSection(&part1sect,0);
+ LoadSection(part1sect+1,ofs+CACHESECTIONSIZE);
+ }
+ else if(part2sect!=part1sect+1) { //both parts are in cache, but not already consecutive
+ if(part1sect==CACHESECTIONCOUNT-1) {
+ //first part is at end, move to before second part
+ if(part2sect==0) //second part is at start: need to move both
+ MoveSection(&part2sect,1);
+ MoveSection(&part1sect,part2sect-1);
+ }
+ else //move second part to after first part
+ MoveSection(&part2sect,part1sect+1);
+ }
+ }
+ else {
+ if(part2sect==-1) { //neither section is in cache
+ part1sect=0; part2sect=1;
+ LoadSection(part1sect,ofs); LoadSection(part2sect,ofs+CACHESECTIONSIZE);
+ }
+ else { //part 2 is in cache, but not part 1
+ if(part2sect==0) MoveSection(&part2sect,1);
+ part1sect=part2sect-1;
+ LoadSection(part1sect,ofs);
+ }
+ }
+ //both sections are now consecutive, starting at part1sect
+ cacheSectionInfo[part1sect].lastUsed=++lastUseCounter;
+ cacheSectionInfo[part1sect+1].lastUsed=++lastUseCounter;
+ if(bytesAvail!=NULL) *bytesAvail=cacheSectionInfo[part1sect+1].ofsBase+CACHESECTIONSIZE-ofs;
+ return pDbCache+part1sect*CACHESECTIONSIZE+(ofs-cacheSectionInfo[part1sect].ofsBase);
+}
+
+
+
+//we are assumed to be in a mutex here
+void DBWrite(DWORD ofs,PVOID pData,int bytes)
+{
+ //write direct, and rely on Windows' write caching
+ DWORD bytesWritten;
+ int i;
+
+ log2("write %d@%08x",bytes,ofs);
+ SetFilePointer(hDbFile,ofs,NULL,FILE_BEGIN);
+ if (WriteFile(hDbFile,pData,bytes,&bytesWritten,NULL)==0)
+ {
+ DatabaseCorruption();
+ }
+ logg();
+ //check if any of the cache sections contain this bit
+ for(i=0;i<CACHESECTIONCOUNT;i++) {
+ if(ofs+bytes>=cacheSectionInfo[i].ofsBase && ofs<cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) {
+ if(ofs<cacheSectionInfo[i].ofsBase) { //don't start at beginning
+ if(ofs+bytes>=cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) //don't finish at end
+ CopyMemory(pDbCache+i*CACHESECTIONSIZE,(PBYTE)pData+cacheSectionInfo[i].ofsBase-ofs,CACHESECTIONSIZE);
+ else CopyMemory(pDbCache+i*CACHESECTIONSIZE,(PBYTE)pData+cacheSectionInfo[i].ofsBase-ofs,bytes-(cacheSectionInfo[i].ofsBase-ofs));
+ }
+ else { //start at beginning
+ if(ofs+bytes>=cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) //don't finish at end
+ CopyMemory(pDbCache+i*CACHESECTIONSIZE+ofs-cacheSectionInfo[i].ofsBase,pData,cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE-ofs);
+ else CopyMemory(pDbCache+i*CACHESECTIONSIZE+ofs-cacheSectionInfo[i].ofsBase,pData,bytes);
+ }
+ }
+ }
+}
+
+void DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes)
+{
+ DWORD bytesRead;
+ PBYTE buf;
+
+ log3("move %d %08x->%08x",bytes,ofsSource,ofsDest);
+ buf=(PBYTE)mir_alloc(bytes);
+ SetFilePointer(hDbFile,ofsSource,NULL,FILE_BEGIN);
+ ReadFile(hDbFile,buf,bytes,&bytesRead,NULL);
+ DBWrite(ofsDest,buf,bytes);
+ mir_free(buf);
+ logg();
+}
+
+static int flushBuffersTimerId;
+static VOID CALLBACK DoBufferFlushTimerProc(HWND hwnd,UINT message,UINT idEvent,DWORD dwTime)
+{
+ KillTimer(NULL,flushBuffersTimerId);
+ log0("tflush1");
+ FlushFileBuffers(hDbFile);
+ log0("tflush2");
+}
+
+void DBFlush(int setting)
+{
+ if(!setting) {
+ log0("nflush1");
+ if(safetyMode) FlushFileBuffers(hDbFile);
+ log0("nflush2");
+ return;
+ }
+ KillTimer(NULL,flushBuffersTimerId);
+ flushBuffersTimerId=SetTimer(NULL,flushBuffersTimerId,50,DoBufferFlushTimerProc);
+}
+
+static int CacheSetSafetyMode(WPARAM wParam,LPARAM lParam)
+{
+ EnterCriticalSection(&csDbAccess);
+ safetyMode=wParam;
+ LeaveCriticalSection(&csDbAccess);
+ if(safetyMode) FlushFileBuffers(hDbFile);
+ return 0;
+}
+
+int InitCache(void)
+{
+ int i;
+ DWORD bytesRead;
+
+ CreateServiceFunction(MS_DB_SETSAFETYMODE,CacheSetSafetyMode);
+ pDbCache=(PBYTE)mir_alloc(CACHESECTIONSIZE*CACHESECTIONCOUNT);
+ lastUseCounter=CACHESECTIONCOUNT;
+ for(i=0;i<CACHESECTIONCOUNT;i++) {
+ cacheSectionInfo[i].ofsBase=0;
+ cacheSectionInfo[i].lastUsed=i;
+ SetFilePointer(hDbFile,cacheSectionInfo[i].ofsBase,NULL,FILE_BEGIN);
+ ReadFile(hDbFile,pDbCache+i*CACHESECTIONSIZE,CACHESECTIONSIZE,&bytesRead,NULL);
+ }
+ return 0;
+}
+
+void UninitCache(void)
+{
+ mir_free(pDbCache);
+ KillTimer(NULL,flushBuffersTimerId);
+}
diff --git a/miranda-wine/plugins/db3x/dbcontacts.c b/miranda-wine/plugins/db3x/dbcontacts.c new file mode 100644 index 0000000..2a8d038 --- /dev/null +++ b/miranda-wine/plugins/db3x/dbcontacts.c @@ -0,0 +1,270 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+static int GetContactCount(WPARAM wParam,LPARAM lParam);
+static int FindFirstContact(WPARAM wParam,LPARAM lParam);
+static int FindNextContact(WPARAM wParam,LPARAM lParam);
+static int DeleteContact(WPARAM wParam,LPARAM lParam);
+static int AddContact(WPARAM wParam,LPARAM lParam);
+static int IsDbContact(WPARAM wParam,LPARAM lParam);
+
+extern CRITICAL_SECTION csDbAccess;
+extern struct DBHeader dbHeader;
+static HANDLE hContactDeletedEvent,hContactAddedEvent;
+
+extern HANDLE hCacheHeap;
+extern SortedList lContacts;
+
+int InitContacts(void)
+{
+ CreateServiceFunction(MS_DB_CONTACT_GETCOUNT,GetContactCount);
+ CreateServiceFunction(MS_DB_CONTACT_FINDFIRST,FindFirstContact);
+ CreateServiceFunction(MS_DB_CONTACT_FINDNEXT,FindNextContact);
+ CreateServiceFunction(MS_DB_CONTACT_DELETE,DeleteContact);
+ CreateServiceFunction(MS_DB_CONTACT_ADD,AddContact);
+ CreateServiceFunction(MS_DB_CONTACT_IS,IsDbContact);
+ hContactDeletedEvent=CreateHookableEvent(ME_DB_CONTACT_DELETED);
+ hContactAddedEvent=CreateHookableEvent(ME_DB_CONTACT_ADDED);
+ return 0;
+}
+
+void UninitContacts(void)
+{
+}
+
+static int GetContactCount(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+
+ EnterCriticalSection(&csDbAccess);
+ ret=dbHeader.contactCount;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int FindFirstContact(WPARAM wParam,LPARAM lParam)
+{
+ int ret = 0;
+ EnterCriticalSection(&csDbAccess);
+ ret = (int)(HANDLE)dbHeader.ofsFirstContact;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int FindNextContact(WPARAM wParam,LPARAM lParam)
+{
+ int ret, index;
+ struct DBContact *dbc;
+ DBCachedContactValueList *VL = NULL;
+
+ EnterCriticalSection(&csDbAccess);
+ {
+ DBCachedContactValueList VLtemp;
+ VLtemp.hContact = (HANDLE)wParam;
+ if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) {
+ VL = ( DBCachedContactValueList* )lContacts.items[index];
+ if ( VL->hNext != NULL ) {
+ LeaveCriticalSection(&csDbAccess);
+ return (int)VL->hNext;
+ } } }
+
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbc->signature!=DBCONTACT_SIGNATURE)
+ ret=(int)(HANDLE)NULL;
+ else {
+ if ( VL == NULL ) {
+ VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_NO_SERIALIZE+HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList));
+ VL->hContact = (HANDLE)wParam;
+ li.List_Insert(&lContacts,VL,index);
+ }
+ VL->hNext = (HANDLE)dbc->ofsNext;
+ ret=(int)(HANDLE)dbc->ofsNext;
+ }
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int DeleteContact(WPARAM wParam,LPARAM lParam)
+{
+ struct DBContact *dbc,*dbcPrev;
+ DWORD ofsThis,ofsNext,ofsFirstEvent;
+ struct DBContactSettings *dbcs;
+ struct DBEvent *dbe;
+ int index;
+
+ if((HANDLE)wParam==NULL) return 1;
+ EnterCriticalSection(&csDbAccess);
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbc->signature!=DBCONTACT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ if ( (HANDLE)wParam == (HANDLE)dbHeader.ofsUser ) {
+ LeaveCriticalSection(&csDbAccess);
+ log0("FATAL: del of user chain attempted.");
+ return 1;
+ }
+ log0("del contact");
+ LeaveCriticalSection(&csDbAccess);
+ //call notifier while outside mutex
+ NotifyEventHooks(hContactDeletedEvent,wParam,0);
+ //get back in
+ EnterCriticalSection(&csDbAccess);
+
+ { DBCachedContactValueList VLtemp;
+ VLtemp.hContact = (HANDLE)wParam;
+ if ( li.List_GetIndex(&lContacts,&VLtemp,&index))
+ {
+ DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index];
+ DBCachedContactValue* V = VL->first;
+ while ( V != NULL ) {
+ DBCachedContactValue* V1 = V->next;
+ if ( V->value.type == DBVT_ASCIIZ )
+ HeapFree( hCacheHeap, HEAP_NO_SERIALIZE, V->value.pszVal );
+ HeapFree( hCacheHeap, HEAP_NO_SERIALIZE, V );
+ V = V1;
+ }
+ HeapFree( hCacheHeap, HEAP_NO_SERIALIZE, VL );
+
+ li.List_Remove(&lContacts,index);
+ } }
+
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ //delete settings chain
+ ofsThis=dbc->ofsFirstSettings;
+ ofsFirstEvent=dbc->ofsFirstEvent;
+ while(ofsThis) {
+ dbcs=(struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL);
+ ofsNext=dbcs->ofsNext;
+ DeleteSpace(ofsThis,offsetof(struct DBContactSettings,blob)+dbcs->cbBlob);
+ ofsThis=ofsNext;
+ }
+ //delete event chain
+ ofsThis=ofsFirstEvent;
+ while(ofsThis) {
+ dbe=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL);
+ ofsNext=dbe->ofsNext;
+ DeleteSpace(ofsThis,offsetof(struct DBEvent,blob)+dbe->cbBlob);
+ ofsThis=ofsNext;
+ }
+ //find previous contact in chain and change ofsNext
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbHeader.ofsFirstContact==wParam) {
+ dbHeader.ofsFirstContact=dbc->ofsNext;
+ DBWrite(0,&dbHeader,sizeof(dbHeader));
+ }
+ else {
+ ofsNext=dbc->ofsNext;
+ ofsThis=dbHeader.ofsFirstContact;
+ dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL);
+ while(dbcPrev->ofsNext!=wParam) {
+ if(dbcPrev->ofsNext==0) DatabaseCorruption();
+ ofsThis=dbcPrev->ofsNext;
+ dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL);
+ }
+ dbcPrev->ofsNext=ofsNext;
+ DBWrite(ofsThis,dbcPrev,sizeof(struct DBContact));
+ {
+ DBCachedContactValueList VLtemp;
+ VLtemp.hContact = (HANDLE)ofsThis;
+ if ( li.List_GetIndex(&lContacts,&VLtemp,&index))
+ {
+ DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index];
+ VL->hNext = ( HANDLE )ofsNext;
+ } }
+ }
+ //delete contact
+ DeleteSpace(wParam,sizeof(struct DBContact));
+ //decrement contact count
+ dbHeader.contactCount--;
+ DBWrite(0,&dbHeader,sizeof(dbHeader));
+ DBFlush(0);
+ //quit
+ LeaveCriticalSection(&csDbAccess);
+ return 0;
+}
+
+static int AddContact(WPARAM wParam,LPARAM lParam)
+{
+ struct DBContact dbc;
+ DWORD ofsNew;
+
+ log0("add contact");
+ EnterCriticalSection(&csDbAccess);
+ ofsNew=CreateNewSpace(sizeof(struct DBContact));
+ dbc.signature=DBCONTACT_SIGNATURE;
+ dbc.eventCount=0;
+ dbc.ofsFirstEvent=dbc.ofsLastEvent=0;
+ dbc.ofsFirstSettings=0;
+ dbc.ofsNext=dbHeader.ofsFirstContact;
+ dbc.ofsFirstUnreadEvent=0;
+ dbc.timestampFirstUnread=0;
+ dbHeader.ofsFirstContact=ofsNew;
+ dbHeader.contactCount++;
+ DBWrite(ofsNew,&dbc,sizeof(struct DBContact));
+ DBWrite(0,&dbHeader,sizeof(dbHeader));
+ DBFlush(0);
+
+ { int index;
+
+ DBCachedContactValueList *VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_NO_SERIALIZE+HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList));
+ VL->hContact = (HANDLE)ofsNew;
+
+ li.List_GetIndex(&lContacts,VL,&index);
+ li.List_Insert(&lContacts,VL,index);
+ }
+
+ LeaveCriticalSection(&csDbAccess);
+ NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0);
+ return (int)ofsNew;
+}
+
+static int IsDbContact(WPARAM wParam,LPARAM lParam)
+{
+ struct DBContact dbc;
+ DWORD ofsContact=(DWORD)wParam;
+ int ret;
+
+ EnterCriticalSection(&csDbAccess);
+ {
+ int index;
+ DBCachedContactValueList VLtemp,*VL;
+ VLtemp.hContact = (HANDLE)wParam;
+ if ( li.List_GetIndex(&lContacts,&VLtemp,&index))
+ ret = TRUE;
+ else {
+ dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL);
+ ret=dbc.signature==DBCONTACT_SIGNATURE;
+
+ if (ret) {
+ VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_NO_SERIALIZE+HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList));
+ VL->hContact = (HANDLE)wParam;
+ li.List_Insert(&lContacts,VL,index);
+ } } }
+
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
diff --git a/miranda-wine/plugins/db3x/dbevents.c b/miranda-wine/plugins/db3x/dbevents.c new file mode 100644 index 0000000..ffc5eed --- /dev/null +++ b/miranda-wine/plugins/db3x/dbevents.c @@ -0,0 +1,436 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+
+DWORD GetModuleNameOfs(const char *szName);
+char *GetModuleNameByOfs(DWORD ofs);
+
+static int GetEventCount(WPARAM wParam,LPARAM lParam);
+static int AddEvent(WPARAM wParam,LPARAM lParam);
+static int DeleteEvent(WPARAM wParam,LPARAM lParam);
+static int GetBlobSize(WPARAM wParam,LPARAM lParam);
+static int GetEvent(WPARAM wParam,LPARAM lParam);
+static int MarkEventRead(WPARAM wParam,LPARAM lParam);
+static int GetEventContact(WPARAM wParam,LPARAM lParam);
+static int FindFirstEvent(WPARAM wParam,LPARAM lParam);
+static int FindFirstUnreadEvent(WPARAM wParam,LPARAM lParam);
+static int FindLastEvent(WPARAM wParam,LPARAM lParam);
+static int FindNextEvent(WPARAM wParam,LPARAM lParam);
+static int FindPrevEvent(WPARAM wParam,LPARAM lParam);
+
+extern CRITICAL_SECTION csDbAccess;
+extern struct DBHeader dbHeader;
+
+static HANDLE hEventDeletedEvent,hEventAddedEvent,hEventFilterAddedEvent;
+
+int InitEvents(void)
+{
+ CreateServiceFunction(MS_DB_EVENT_GETCOUNT,GetEventCount);
+ CreateServiceFunction(MS_DB_EVENT_ADD,AddEvent);
+ CreateServiceFunction(MS_DB_EVENT_DELETE,DeleteEvent);
+ CreateServiceFunction(MS_DB_EVENT_GETBLOBSIZE,GetBlobSize);
+ CreateServiceFunction(MS_DB_EVENT_GET,GetEvent);
+ CreateServiceFunction(MS_DB_EVENT_MARKREAD,MarkEventRead);
+ CreateServiceFunction(MS_DB_EVENT_GETCONTACT,GetEventContact);
+ CreateServiceFunction(MS_DB_EVENT_FINDFIRST,FindFirstEvent);
+ CreateServiceFunction(MS_DB_EVENT_FINDFIRSTUNREAD,FindFirstUnreadEvent);
+ CreateServiceFunction(MS_DB_EVENT_FINDLAST,FindLastEvent);
+ CreateServiceFunction(MS_DB_EVENT_FINDNEXT,FindNextEvent);
+ CreateServiceFunction(MS_DB_EVENT_FINDPREV,FindPrevEvent);
+ hEventDeletedEvent=CreateHookableEvent(ME_DB_EVENT_DELETED);
+ hEventAddedEvent=CreateHookableEvent(ME_DB_EVENT_ADDED);
+ hEventFilterAddedEvent=CreateHookableEvent(ME_DB_EVENT_FILTER_ADD);
+ return 0;
+}
+
+void UninitEvents(void)
+{
+}
+
+static int GetEventCount(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBContact *dbc;
+
+ EnterCriticalSection(&csDbAccess);
+ if(wParam==0) wParam=dbHeader.ofsUser;
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbc->signature!=DBCONTACT_SIGNATURE) ret=-1;
+ else ret=dbc->eventCount;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int AddEvent(WPARAM wParam,LPARAM lParam)
+{
+ DBEVENTINFO *dbei=(DBEVENTINFO*)lParam;
+ struct DBContact dbc;
+ struct DBEvent dbe,*dbeTest;
+ DWORD ofsNew,ofsModuleName,ofsContact,ofsThis;
+
+ if(dbei==NULL||dbei->cbSize!=sizeof(DBEVENTINFO)) return (int)NULL;
+ if(dbei->timestamp==0) return (int)NULL;
+ if (NotifyEventHooks(hEventFilterAddedEvent,wParam,lParam)) {
+ return (int)NULL;
+ }
+ EnterCriticalSection(&csDbAccess);
+ if(wParam==0) ofsContact=dbHeader.ofsUser;
+ else ofsContact=wParam;
+ dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL);
+ if(dbc.signature!=DBCONTACT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return (int)NULL;
+ }
+ ofsNew=CreateNewSpace(offsetof(struct DBEvent,blob)+dbei->cbBlob);
+ ofsModuleName=GetModuleNameOfs(dbei->szModule);
+
+ dbe.signature=DBEVENT_SIGNATURE;
+ dbe.ofsModuleName=ofsModuleName;
+ dbe.timestamp=dbei->timestamp;
+ dbe.flags=dbei->flags;
+ dbe.eventType=dbei->eventType;
+ dbe.cbBlob=dbei->cbBlob;
+ //find where to put it - sort by timestamp
+ if(dbc.eventCount==0) {
+ dbe.ofsPrev=wParam;
+ dbe.ofsNext=0;
+ dbe.flags|=DBEF_FIRST;
+ dbc.ofsFirstEvent=dbc.ofsLastEvent=ofsNew;
+ }
+ else {
+ dbeTest=(struct DBEvent*)DBRead(dbc.ofsFirstEvent,sizeof(struct DBEvent),NULL);
+ // Should new event be placed before first event in chain?
+ if (dbei->timestamp < dbeTest->timestamp) {
+ dbe.ofsPrev=wParam;
+ dbe.ofsNext=dbc.ofsFirstEvent;
+ dbe.flags|=DBEF_FIRST;
+ dbc.ofsFirstEvent=ofsNew;
+ dbeTest=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL);
+ dbeTest->flags&=~DBEF_FIRST;
+ dbeTest->ofsPrev=ofsNew;
+ DBWrite(dbe.ofsNext,dbeTest,sizeof(struct DBEvent));
+ }
+ else {
+ // Loop through the chain, starting at the end
+ ofsThis = dbc.ofsLastEvent;
+ dbeTest = (struct DBEvent*)DBRead(ofsThis, sizeof(struct DBEvent), NULL);
+ for(;;) {
+ // If the new event's timesstamp is equal to or greater than the
+ // current dbevent, it will be inserted after. If not, continue
+ // with the previous dbevent in chain.
+ if (dbe.timestamp >= dbeTest->timestamp) {
+ dbe.ofsPrev = ofsThis;
+ dbe.ofsNext = dbeTest->ofsNext;
+ dbeTest->ofsNext = ofsNew;
+ DBWrite(ofsThis, dbeTest, sizeof(struct DBEvent));
+ if (dbe.ofsNext == 0)
+ dbc.ofsLastEvent = ofsNew;
+ else {
+ dbeTest = (struct DBEvent*)DBRead(dbe.ofsNext, sizeof(struct DBEvent), NULL);
+ dbeTest->ofsPrev = ofsNew;
+ DBWrite(dbe.ofsNext, dbeTest, sizeof(struct DBEvent));
+ }
+ break;
+ }
+ ofsThis = dbeTest->ofsPrev;
+ dbeTest = (struct DBEvent*)DBRead(ofsThis, sizeof(struct DBEvent), NULL);
+ }
+ }
+ }
+ dbc.eventCount++;
+ if(!(dbe.flags&(DBEF_READ|DBEF_SENT))) {
+ if(dbe.timestamp<dbc.timestampFirstUnread || dbc.timestampFirstUnread==0) {
+ dbc.timestampFirstUnread=dbe.timestamp;
+ dbc.ofsFirstUnreadEvent=ofsNew;
+ }
+ }
+ DBWrite(ofsContact,&dbc,sizeof(struct DBContact));
+ DBWrite(ofsNew,&dbe,offsetof(struct DBEvent,blob));
+ DBWrite(ofsNew+offsetof(struct DBEvent,blob),dbei->pBlob,dbei->cbBlob);
+ DBFlush(0);
+ LeaveCriticalSection(&csDbAccess);
+ log1("add event @ %08x",ofsNew);
+ NotifyEventHooks(hEventAddedEvent,wParam,(LPARAM)ofsNew);
+ return (int)ofsNew;
+}
+
+static int DeleteEvent(WPARAM wParam,LPARAM lParam)
+{
+ struct DBContact dbc;
+ DWORD ofsContact,ofsThis;
+ struct DBEvent dbe,*dbeNext,*dbePrev;
+
+ EnterCriticalSection(&csDbAccess);
+ if(wParam==0) ofsContact=dbHeader.ofsUser;
+ else ofsContact=wParam;
+ dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL);
+ dbe=*(struct DBEvent*)DBRead(lParam,sizeof(struct DBEvent),NULL);
+ if(dbc.signature!=DBCONTACT_SIGNATURE || dbe.signature!=DBEVENT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ log1("delete event @ %08x",wParam);
+ LeaveCriticalSection(&csDbAccess);
+ //call notifier while outside mutex
+ NotifyEventHooks(hEventDeletedEvent,wParam,lParam);
+ //get back in
+ EnterCriticalSection(&csDbAccess);
+ dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL);
+ dbe=*(struct DBEvent*)DBRead(lParam,sizeof(struct DBEvent),NULL);
+ //check if this was the first unread, if so, recalc the first unread
+ if(dbc.ofsFirstUnreadEvent==(DWORD)lParam) {
+ dbeNext=&dbe;
+ for(;;) {
+ if(dbeNext->ofsNext==0) {
+ dbc.ofsFirstUnreadEvent=0;
+ dbc.timestampFirstUnread=0;
+ break;
+ }
+ ofsThis=dbeNext->ofsNext;
+ dbeNext=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL);
+ if(!(dbeNext->flags&(DBEF_READ|DBEF_SENT))) {
+ dbc.ofsFirstUnreadEvent=ofsThis;
+ dbc.timestampFirstUnread=dbeNext->timestamp;
+ break;
+ }
+ }
+ }
+ //get previous and next events in chain and change offsets
+ if(dbe.flags&DBEF_FIRST) {
+ if(dbe.ofsNext==0) {
+ dbc.ofsFirstEvent=dbc.ofsLastEvent=0;
+ }
+ else {
+ dbeNext=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL);
+ dbeNext->flags|=DBEF_FIRST;
+ dbeNext->ofsPrev=dbe.ofsPrev;
+ DBWrite(dbe.ofsNext,dbeNext,sizeof(struct DBEvent));
+ dbc.ofsFirstEvent=dbe.ofsNext;
+ }
+ }
+ else {
+ if(dbe.ofsNext==0) {
+ dbePrev=(struct DBEvent*)DBRead(dbe.ofsPrev,sizeof(struct DBEvent),NULL);
+ dbePrev->ofsNext=0;
+ DBWrite(dbe.ofsPrev,dbePrev,sizeof(struct DBEvent));
+ dbc.ofsLastEvent=dbe.ofsPrev;
+ }
+ else {
+ dbePrev=(struct DBEvent*)DBRead(dbe.ofsPrev,sizeof(struct DBEvent),NULL);
+ dbePrev->ofsNext=dbe.ofsNext;
+ DBWrite(dbe.ofsPrev,dbePrev,sizeof(struct DBEvent));
+ dbeNext=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL);
+ dbeNext->ofsPrev=dbe.ofsPrev;
+ DBWrite(dbe.ofsNext,dbeNext,sizeof(struct DBEvent));
+ }
+ }
+ //delete event
+ DeleteSpace(lParam,offsetof(struct DBEvent,blob)+dbe.cbBlob);
+ //decrement event count
+ dbc.eventCount--;
+ DBWrite(ofsContact,&dbc,sizeof(struct DBContact));
+ DBFlush(0);
+ //quit
+ LeaveCriticalSection(&csDbAccess);
+ return 0;
+}
+
+static int GetBlobSize(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBEvent *dbe;
+
+ EnterCriticalSection(&csDbAccess);
+ dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL);
+ if(dbe->signature!=DBEVENT_SIGNATURE) ret=-1;
+ else ret=dbe->cbBlob;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int GetEvent(WPARAM wParam,LPARAM lParam)
+{
+ struct DBEvent *dbe;
+ DBEVENTINFO *dbei=(DBEVENTINFO*)lParam;
+ int bytesToCopy,i;
+
+ if(dbei==NULL||dbei->cbSize!=sizeof(DBEVENTINFO)) return 1;
+ EnterCriticalSection(&csDbAccess);
+ dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL);
+ if(dbe->signature!=DBEVENT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ dbei->szModule=GetModuleNameByOfs(dbe->ofsModuleName);
+ dbei->timestamp=dbe->timestamp;
+ dbei->flags=dbe->flags;
+ dbei->eventType=dbe->eventType;
+ if(dbei->cbBlob<dbe->cbBlob) bytesToCopy=dbei->cbBlob;
+ else bytesToCopy=dbe->cbBlob;
+ dbei->cbBlob=dbe->cbBlob;
+ for(i=0;;i+=MAXCACHEDREADSIZE) {
+ if(bytesToCopy-i<=MAXCACHEDREADSIZE) {
+ CopyMemory(dbei->pBlob+i,DBRead(wParam+offsetof(struct DBEvent,blob)+i,bytesToCopy-i,NULL),bytesToCopy-i);
+ break;
+ }
+ CopyMemory(dbei->pBlob+i,DBRead(wParam+offsetof(struct DBEvent,blob)+i,MAXCACHEDREADSIZE,NULL),MAXCACHEDREADSIZE);
+ }
+ LeaveCriticalSection(&csDbAccess);
+ return 0;
+}
+
+static int MarkEventRead(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBEvent *dbe;
+ struct DBContact dbc;
+ DWORD ofsThis;
+
+ EnterCriticalSection(&csDbAccess);
+ if(wParam==0) wParam=dbHeader.ofsUser;
+ dbc=*(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ dbe=(struct DBEvent*)DBRead(lParam,sizeof(struct DBEvent),NULL);
+ if(dbe->signature!=DBEVENT_SIGNATURE || dbc.signature!=DBCONTACT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return -1;
+ }
+ if(dbe->flags&DBEF_READ || dbe->flags&DBEF_SENT) {
+ ret=(int)dbe->flags;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+ }
+ log1("mark read @ %08x",wParam);
+ dbe->flags|=DBEF_READ;
+ DBWrite(lParam,dbe,sizeof(struct DBEvent));
+ ret=(int)dbe->flags;
+ if(dbc.ofsFirstUnreadEvent==(DWORD)lParam) {
+ for(;;) {
+ if(dbe->ofsNext==0) {
+ dbc.ofsFirstUnreadEvent=0;
+ dbc.timestampFirstUnread=0;
+ break;
+ }
+ ofsThis=dbe->ofsNext;
+ dbe=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL);
+ if(!(dbe->flags&(DBEF_READ|DBEF_SENT))) {
+ dbc.ofsFirstUnreadEvent=ofsThis;
+ dbc.timestampFirstUnread=dbe->timestamp;
+ break;
+ }
+ }
+ }
+ DBWrite(wParam,&dbc,sizeof(struct DBContact));
+ DBFlush(0);
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int GetEventContact(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBEvent *dbe;
+
+ EnterCriticalSection(&csDbAccess);
+ dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL);
+ if(dbe->signature!=DBEVENT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return -1;
+ }
+ while(!(dbe->flags&DBEF_FIRST))
+ dbe=(struct DBEvent*)DBRead(dbe->ofsPrev,sizeof(struct DBEvent),NULL);
+ ret=(int)(HANDLE)dbe->ofsPrev;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int FindFirstEvent(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBContact *dbc;
+
+ EnterCriticalSection(&csDbAccess);
+ if(wParam==0) wParam=dbHeader.ofsUser;
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbc->signature!=DBCONTACT_SIGNATURE) ret=(int)(HANDLE)NULL;
+ else ret=(int)dbc->ofsFirstEvent;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int FindFirstUnreadEvent(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBContact *dbc;
+
+ EnterCriticalSection(&csDbAccess);
+ if(wParam==0) wParam=dbHeader.ofsUser;
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbc->signature!=DBCONTACT_SIGNATURE) ret=(int)(HANDLE)NULL;
+ else ret=(int)dbc->ofsFirstUnreadEvent;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int FindLastEvent(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBContact *dbc;
+
+ EnterCriticalSection(&csDbAccess);
+ if(wParam==0) wParam=dbHeader.ofsUser;
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbc->signature!=DBCONTACT_SIGNATURE) ret=(int)(HANDLE)NULL;
+ else ret=(int)dbc->ofsLastEvent;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int FindNextEvent(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBEvent *dbe;
+
+ EnterCriticalSection(&csDbAccess);
+ dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL);
+ if(dbe->signature!=DBEVENT_SIGNATURE) ret=(int)(HANDLE)NULL;
+ else ret=(int)(HANDLE)dbe->ofsNext;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
+
+static int FindPrevEvent(WPARAM wParam,LPARAM lParam)
+{
+ int ret;
+ struct DBEvent *dbe;
+
+ EnterCriticalSection(&csDbAccess);
+ dbe=(struct DBEvent*)DBRead(wParam,sizeof(struct DBEvent),NULL);
+ if(dbe->signature!=DBEVENT_SIGNATURE) ret=(int)(HANDLE)NULL;
+ else if(dbe->flags&DBEF_FIRST) ret=(int)(HANDLE)NULL;
+ else ret=(int)(HANDLE)dbe->ofsPrev;
+ LeaveCriticalSection(&csDbAccess);
+ return ret;
+}
diff --git a/miranda-wine/plugins/db3x/dbheaders.c b/miranda-wine/plugins/db3x/dbheaders.c new file mode 100644 index 0000000..da7cb6e --- /dev/null +++ b/miranda-wine/plugins/db3x/dbheaders.c @@ -0,0 +1,78 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+extern struct DBHeader dbHeader;
+extern HANDLE hDbFile;
+
+struct DBSignature {
+ char name[15];
+ BYTE eof;
+};
+static struct DBSignature dbSignature={"Miranda ICQ DB",0x1A};
+
+//the cache has not been loaded when these functions are used
+
+int CreateDbHeaders(HANDLE hFile)
+{
+ struct DBContact user;
+ DWORD bytesWritten;
+
+ CopyMemory(dbHeader.signature,&dbSignature,sizeof(dbHeader.signature));
+ dbHeader.version=DB_THIS_VERSION;
+ dbHeader.ofsFileEnd=sizeof(struct DBHeader);
+ dbHeader.slackSpace=0;
+ dbHeader.contactCount=0;
+ dbHeader.ofsFirstContact=0;
+ dbHeader.ofsFirstModuleName=0;
+ dbHeader.ofsUser=0;
+ //create user
+ dbHeader.ofsUser=dbHeader.ofsFileEnd;
+ dbHeader.ofsFileEnd+=sizeof(struct DBContact);
+ SetFilePointer(hFile,0,NULL,FILE_BEGIN);
+ WriteFile(hFile,&dbHeader,sizeof(dbHeader),&bytesWritten,NULL);
+ user.signature=DBCONTACT_SIGNATURE;
+ user.ofsNext=0;
+ user.ofsFirstSettings=0;
+ user.eventCount=0;
+ user.ofsFirstEvent=user.ofsLastEvent=0;
+ SetFilePointer(hFile,dbHeader.ofsUser,NULL,FILE_BEGIN);
+ WriteFile(hFile,&user,sizeof(struct DBContact),&bytesWritten,NULL);
+ FlushFileBuffers(hFile);
+ return 0;
+}
+
+int CheckDbHeaders(struct DBHeader * hdr)
+{
+ if(memcmp(hdr->signature,&dbSignature,sizeof(hdr->signature))) return 1;
+ if(hdr->version!=DB_THIS_VERSION) return 2;
+ if(hdr->ofsUser==0) return 3;
+ return 0;
+}
+
+int InitialiseDbHeaders(void)
+{
+ return 0;
+}
diff --git a/miranda-wine/plugins/db3x/dbmodulechain.c b/miranda-wine/plugins/db3x/dbmodulechain.c new file mode 100644 index 0000000..352a06c --- /dev/null +++ b/miranda-wine/plugins/db3x/dbmodulechain.c @@ -0,0 +1,132 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+extern struct DBHeader dbHeader;
+
+static int EnumModuleNames(WPARAM wParam,LPARAM lParam);
+
+struct ModuleName {
+ char *name;
+ DWORD hash;
+ DWORD ofs;
+};
+static struct ModuleName *moduleName;
+static int moduleNameCount;
+
+int InitModuleNames(void)
+{
+ struct DBModuleName *dbmn;
+ DWORD ofsThis,ofsNext;
+ int nameLen;
+
+ moduleNameCount=0;
+ moduleName=NULL;
+ ofsThis=dbHeader.ofsFirstModuleName;
+ dbmn=(struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL);
+ while(ofsThis) {
+ if(dbmn->signature!=DBMODULENAME_SIGNATURE) DatabaseCorruption();
+ moduleName=(struct ModuleName*)mir_realloc(moduleName,sizeof(struct ModuleName)*(moduleNameCount+1));
+ moduleName[moduleNameCount].ofs=ofsThis;
+ moduleName[moduleNameCount].hash=dbmn->cbName; //very very simple hash so far
+ moduleName[moduleNameCount].name=(char*)mir_alloc(dbmn->cbName+1);
+ ofsNext=dbmn->ofsNext;
+ nameLen=dbmn->cbName;
+ CopyMemory(moduleName[moduleNameCount].name,DBRead(ofsThis+offsetof(struct DBModuleName,name),nameLen,NULL),nameLen);
+ moduleName[moduleNameCount].name[nameLen]=0;
+ moduleNameCount++;
+ ofsThis=ofsNext;
+ dbmn=(struct DBModuleName*)DBRead(ofsThis,sizeof(struct DBModuleName),NULL);
+ }
+ CreateServiceFunction(MS_DB_MODULES_ENUM,EnumModuleNames);
+ return 0;
+}
+
+void UninitModuleNames(void)
+{
+ int i;
+ for(i=0;i<moduleNameCount;i++) mir_free(moduleName[i].name);
+ if(moduleNameCount) mir_free(moduleName);
+}
+
+static DWORD FindExistingModuleNameOfs(const char *szName,int nameLen)
+{
+ int i;
+ for(i=0;i<moduleNameCount;i++)
+ if(moduleName[i].hash==(DWORD)nameLen && !strcmp(moduleName[i].name,szName)) return moduleName[i].ofs;
+ return 0;
+}
+
+//will create the offset if it needs to
+DWORD GetModuleNameOfs(const char *szName)
+{
+ struct DBModuleName dbmn;
+ int nameLen=strlen(szName);
+ DWORD ofsNew,ofsExisting;
+
+ ofsExisting=FindExistingModuleNameOfs(szName,nameLen);
+ if(ofsExisting) return ofsExisting;
+ //need to create the module name
+ ofsNew=CreateNewSpace(nameLen+offsetof(struct DBModuleName,name));
+ dbmn.signature=DBMODULENAME_SIGNATURE;
+ dbmn.cbName=nameLen;
+ dbmn.ofsNext=dbHeader.ofsFirstModuleName;
+ dbHeader.ofsFirstModuleName=ofsNew;
+ DBWrite(0,&dbHeader,sizeof(dbHeader));
+ DBWrite(ofsNew,&dbmn,offsetof(struct DBModuleName,name));
+ DBWrite(ofsNew+offsetof(struct DBModuleName,name),(PVOID)szName,nameLen);
+ DBFlush(0);
+ //add to cache
+ moduleName=(struct ModuleName*)mir_realloc(moduleName,sizeof(struct ModuleName)*(moduleNameCount+1));
+ moduleName[moduleNameCount].ofs=ofsNew;
+ moduleName[moduleNameCount].hash=nameLen; //very very simple hash so far
+ moduleName[moduleNameCount].name=(char*)mir_alloc(nameLen+1);
+ strcpy(moduleName[moduleNameCount].name,szName);
+ moduleNameCount++;
+ //quit
+ return ofsNew;
+}
+
+//it's OK that this is a bit slow - it's rarely used
+char *GetModuleNameByOfs(DWORD ofs)
+{
+ int i;
+
+ for(i=0;i<moduleNameCount;i++)
+ if(moduleName[i].ofs==ofs) return moduleName[i].name;
+ DatabaseCorruption();
+ return NULL;
+}
+
+static int EnumModuleNames(WPARAM wParam,LPARAM lParam)
+{
+ int i;
+ int ret;
+ for(i=0;i<moduleNameCount;i++) {
+ ret=((DBMODULEENUMPROC)lParam)(moduleName[i].name,moduleName[i].ofs,wParam);
+ if(ret) return ret;
+ }
+ return 0;
+}
diff --git a/miranda-wine/plugins/db3x/dbsettings.c b/miranda-wine/plugins/db3x/dbsettings.c new file mode 100644 index 0000000..d01988e --- /dev/null +++ b/miranda-wine/plugins/db3x/dbsettings.c @@ -0,0 +1,957 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+DWORD GetModuleNameOfs(const char *szName);
+
+extern CRITICAL_SECTION csDbAccess;
+extern struct DBHeader dbHeader;
+
+HANDLE hCacheHeap = NULL;
+SortedList lContacts;
+
+static SortedList lSettings, lGlobalSettings;
+static HANDLE hSettingChangeEvent = NULL;
+
+#define SETTINGSGROUPOFSCOUNT 32
+struct SettingsGroupOfsCacheEntry {
+ DWORD ofsContact;
+ DWORD ofsModuleName;
+ DWORD ofsSettingsGroup;
+};
+static struct SettingsGroupOfsCacheEntry settingsGroupOfsCache[SETTINGSGROUPOFSCOUNT];
+static int nextSGOCacheEntry;
+
+//this function caches results
+static DWORD GetSettingsGroupOfsByModuleNameOfs(struct DBContact *dbc,DWORD ofsContact,DWORD ofsModuleName)
+{
+ struct DBContactSettings *dbcs;
+ DWORD ofsThis;
+ int i;
+
+ for(i=0;i<SETTINGSGROUPOFSCOUNT;i++) {
+ if(settingsGroupOfsCache[i].ofsContact==ofsContact && settingsGroupOfsCache[i].ofsModuleName==ofsModuleName)
+ return settingsGroupOfsCache[i].ofsSettingsGroup;
+ }
+ ofsThis=dbc->ofsFirstSettings;
+ while(ofsThis) {
+ dbcs=(struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL);
+ if(dbcs->signature!=DBCONTACTSETTINGS_SIGNATURE) DatabaseCorruption();
+ if(dbcs->ofsModuleName==ofsModuleName) {
+ settingsGroupOfsCache[nextSGOCacheEntry].ofsContact=ofsContact;
+ settingsGroupOfsCache[nextSGOCacheEntry].ofsModuleName=ofsModuleName;
+ settingsGroupOfsCache[nextSGOCacheEntry].ofsSettingsGroup=ofsThis;
+ if(++nextSGOCacheEntry==SETTINGSGROUPOFSCOUNT) nextSGOCacheEntry=0;
+ return ofsThis;
+ }
+ ofsThis=dbcs->ofsNext;
+ }
+ return 0;
+}
+
+static void InvalidateSettingsGroupOfsCacheEntry(DWORD ofsSettingsGroup)
+{
+ int i;
+
+ for(i=0;i<SETTINGSGROUPOFSCOUNT;i++) {
+ if(settingsGroupOfsCache[i].ofsSettingsGroup==ofsSettingsGroup) {
+ settingsGroupOfsCache[i].ofsContact=0;
+ settingsGroupOfsCache[i].ofsModuleName=0;
+ settingsGroupOfsCache[i].ofsSettingsGroup=0;
+ break;
+} } }
+
+static DWORD __inline GetSettingValueLength(PBYTE pSetting)
+{
+ if(pSetting[0]&DBVTF_VARIABLELENGTH) return 2+*(PWORD)(pSetting+1);
+ return pSetting[0];
+}
+
+static char* InsertCachedSetting( const char* szName, size_t cbNameLen, int index )
+{
+ char* newValue = (char*)HeapAlloc( hCacheHeap, HEAP_NO_SERIALIZE, cbNameLen );
+ *newValue = 0;
+ strcpy(newValue+1,szName+1);
+ li.List_Insert(&lSettings,newValue,index);
+ return newValue;
+}
+
+static char* GetCachedSetting(const char *szModuleName,const char *szSettingName,int settingNameLen)
+{
+ int moduleNameLen = strlen(szModuleName),index;
+ char *szFullName = (char*)alloca(moduleNameLen+settingNameLen+3);
+
+ strcpy(szFullName+1,szModuleName);
+ szFullName[moduleNameLen+1]='/';
+ strcpy(szFullName+moduleNameLen+2,szSettingName);
+
+ if ( li.List_GetIndex(&lSettings, szFullName, &index))
+ return((char*)lSettings.items[index] + 1);
+
+ return InsertCachedSetting( szFullName, moduleNameLen+settingNameLen+3, index )+1;
+}
+
+static void SetCachedVariant( DBVARIANT* s /* new */, DBVARIANT* d /* cached */ )
+{
+ char* szSave = ( d->type == DBVT_UTF8 || d->type == DBVT_ASCIIZ ) ? d->pszVal : NULL;
+
+ memcpy( d, s, sizeof( DBVARIANT ));
+ if (( s->type == DBVT_UTF8 || s->type == DBVT_ASCIIZ ) && s->pszVal != NULL ) {
+ if ( szSave != NULL )
+ d->pszVal = (char*)HeapReAlloc(hCacheHeap,HEAP_NO_SERIALIZE,szSave,strlen(s->pszVal)+1);
+ else
+ d->pszVal = (char*)HeapAlloc(hCacheHeap,HEAP_NO_SERIALIZE,strlen(s->pszVal)+1);
+ strcpy(d->pszVal,s->pszVal);
+ }
+
+ switch( d->type ) {
+ case DBVT_BYTE: log1( "set cached byte: %d", d->bVal ); break;
+ case DBVT_WORD: log1( "set cached word: %d", d->wVal ); break;
+ case DBVT_DWORD: log1( "set cached dword: %d", d->dVal ); break;
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ: log1( "set cached string: '%s'", d->pszVal ); break;
+ default: log1( "set cached crap: %d", d->type ); break;
+} }
+
+static void FreeCachedVariant( DBVARIANT* V )
+{
+ if (( V->type == DBVT_ASCIIZ || V->type == DBVT_UTF8 ) && V->pszVal != NULL )
+ HeapFree(hCacheHeap,HEAP_NO_SERIALIZE,V->pszVal);
+}
+
+static DBVARIANT* GetCachedValuePtr( HANDLE hContact, char* szSetting, int bAllocate )
+{
+ int index;
+
+ if ( hContact == 0 ) {
+ DBCachedGlobalValue Vtemp, *V;
+ Vtemp.name = szSetting;
+ if ( li.List_GetIndex(&lGlobalSettings,&Vtemp,&index)) {
+ V = (DBCachedGlobalValue*)lGlobalSettings.items[index];
+ if ( bAllocate == -1 ) {
+ FreeCachedVariant( &V->value );
+ li.List_Remove(&lGlobalSettings,index);
+ HeapFree(hCacheHeap,HEAP_NO_SERIALIZE,V);
+ return NULL;
+ } }
+ else {
+ if ( bAllocate != 1 )
+ return NULL;
+
+ V = (DBCachedGlobalValue*)HeapAlloc(hCacheHeap,HEAP_NO_SERIALIZE+HEAP_ZERO_MEMORY,sizeof(DBCachedGlobalValue));
+ V->name = szSetting;
+ li.List_Insert(&lGlobalSettings,V,index);
+ }
+
+ return &V->value;
+ }
+ else {
+ DBCachedContactValue *V, *V1;
+ DBCachedContactValueList VLtemp,*VL;
+
+ VLtemp.hContact=hContact;
+ if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) {
+ VL = (DBCachedContactValueList*)lContacts.items[index];
+ }
+ else {
+ if ( bAllocate == -1 )
+ return NULL;
+
+ VL = (DBCachedContactValueList*)HeapAlloc(hCacheHeap,HEAP_NO_SERIALIZE+HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList));
+ VL->hContact = hContact;
+ li.List_Insert(&lContacts,VL,index);
+ }
+
+ for ( V = VL->first; V != NULL; V = V->next)
+ if (strcmp(V->name,szSetting)==0)
+ break;
+
+ if ( V == NULL )
+ { if ( bAllocate != 1 )
+ return NULL;
+
+ V = HeapAlloc(hCacheHeap,HEAP_NO_SERIALIZE+HEAP_ZERO_MEMORY,sizeof(DBCachedContactValue));
+ V->next = VL->first;
+ VL->first = V;
+ V->name = szSetting;
+ }
+ else if ( bAllocate == -1 ) {
+ FreeCachedVariant(&V->value);
+ if ( VL->first == V )
+ VL->first = V->next;
+ for ( V1=VL->first; V1 != NULL; V1 = V1->next )
+ if ( V1->next == V ) {
+ V1->next = V->next;
+ break;
+ }
+ HeapFree(hCacheHeap,HEAP_NO_SERIALIZE,V);
+ return NULL;
+ }
+
+ return &V->value;
+} }
+
+#define NeedBytes(n) if(bytesRemaining<(n)) pBlob=(PBYTE)DBRead(ofsBlobPtr,(n),&bytesRemaining)
+#define MoveAlong(n) {int x=n; pBlob+=(x); ofsBlobPtr+=(x); bytesRemaining-=(x);}
+#define VLT(n) ((n==DBVT_UTF8)?DBVT_ASCIIZ:n)
+static __inline int GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic)
+{
+ struct DBContact dbc;
+ struct DBContactSettings dbcs;
+ DWORD ofsModuleName,ofsContact,ofsSettingsGroup,ofsBlobPtr;
+ int settingNameLen;
+ int bytesRemaining;
+ PBYTE pBlob;
+ char* szCachedSettingName;
+
+ if ((!dbcgs->szSetting) || (!dbcgs->szModule))
+ return 1;
+ settingNameLen=strlen(dbcgs->szSetting);
+
+ EnterCriticalSection(&csDbAccess);
+
+ log3("get [%08p] %s/%s",hContact,dbcgs->szModule,dbcgs->szSetting);
+
+ szCachedSettingName = GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,settingNameLen);
+ {
+ DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 0 );
+ if ( pCachedValue != NULL ) {
+ if ( pCachedValue->type == DBVT_ASCIIZ || pCachedValue->type == DBVT_UTF8 ) {
+ int cbOrigLen = dbcgs->pValue->cchVal;
+ char* cbOrigPtr = dbcgs->pValue->pszVal;
+ memcpy( dbcgs->pValue, pCachedValue, sizeof( DBVARIANT ));
+ if ( isStatic ) {
+ int cbLen = 0;
+ if ( pCachedValue->pszVal != NULL )
+ cbLen = strlen( pCachedValue->pszVal );
+
+ cbOrigLen--;
+ dbcgs->pValue->pszVal = cbOrigPtr;
+ if(cbLen<cbOrigLen) cbOrigLen=cbLen;
+ CopyMemory(dbcgs->pValue->pszVal,pCachedValue->pszVal,cbOrigLen);
+ dbcgs->pValue->pszVal[cbOrigLen]=0;
+ dbcgs->pValue->cchVal=cbLen;
+ }
+ else {
+ dbcgs->pValue->pszVal = (char*)mir_alloc(strlen(pCachedValue->pszVal)+1);
+ strcpy(dbcgs->pValue->pszVal,pCachedValue->pszVal);
+ }
+ }
+ else
+ memcpy( dbcgs->pValue, pCachedValue, sizeof( DBVARIANT ));
+
+ switch( dbcgs->pValue->type ) {
+ case DBVT_BYTE: log1( "get cached byte: %d", dbcgs->pValue->bVal ); break;
+ case DBVT_WORD: log1( "get cached word: %d", dbcgs->pValue->wVal ); break;
+ case DBVT_DWORD: log1( "get cached dword: %d", dbcgs->pValue->dVal ); break;
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ: log1( "get cached string: '%s'", dbcgs->pValue->pszVal); break;
+ default: log1( "get cached crap: %d", dbcgs->pValue->type ); break;
+ }
+
+ LeaveCriticalSection(&csDbAccess);
+ return ( pCachedValue->type == DBVT_DELETED ) ? 1 : 0;
+ } }
+
+ ofsModuleName=GetModuleNameOfs(dbcgs->szModule);
+ if(hContact==NULL) ofsContact=dbHeader.ofsUser;
+ else ofsContact=(DWORD)hContact;
+ dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL);
+ if(dbc.signature!=DBCONTACT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsContact,ofsModuleName);
+ if(ofsSettingsGroup) {
+ dbcs=*(struct DBContactSettings*)DBRead(ofsSettingsGroup,sizeof(struct DBContactSettings),&bytesRemaining);
+ ofsBlobPtr=ofsSettingsGroup+offsetof(struct DBContactSettings,blob);
+ pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining);
+ while(pBlob[0]) {
+ NeedBytes(1+settingNameLen);
+ if(pBlob[0]==settingNameLen && !memcmp(pBlob+1,dbcgs->szSetting,settingNameLen)) {
+ MoveAlong(1+settingNameLen);
+ NeedBytes(5);
+ if(isStatic && pBlob[0]&DBVTF_VARIABLELENGTH && VLT(dbcgs->pValue->type) != VLT(pBlob[0])) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ dbcgs->pValue->type=pBlob[0];
+ switch(pBlob[0]) {
+ case DBVT_DELETED: { /* this setting is deleted */
+ dbcgs->pValue->type=DBVT_DELETED;
+ LeaveCriticalSection(&csDbAccess);
+ return 2;
+ }
+ case DBVT_BYTE: dbcgs->pValue->bVal=pBlob[1]; break;
+ case DBVT_WORD: dbcgs->pValue->wVal=*(PWORD)(pBlob+1); break;
+ case DBVT_DWORD: dbcgs->pValue->dVal=*(PDWORD)(pBlob+1); break;
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ:
+ NeedBytes(3+*(PWORD)(pBlob+1));
+ if(isStatic) {
+ dbcgs->pValue->cchVal--;
+ if(*(PWORD)(pBlob+1)<dbcgs->pValue->cchVal) dbcgs->pValue->cchVal=*(PWORD)(pBlob+1);
+ CopyMemory(dbcgs->pValue->pszVal,pBlob+3,dbcgs->pValue->cchVal);
+ dbcgs->pValue->pszVal[dbcgs->pValue->cchVal]=0;
+ dbcgs->pValue->cchVal=*(PWORD)(pBlob+1);
+ }
+ else {
+ dbcgs->pValue->pszVal=(char*)mir_alloc(1+*(PWORD)(pBlob+1));
+ CopyMemory(dbcgs->pValue->pszVal,pBlob+3,*(PWORD)(pBlob+1));
+ dbcgs->pValue->pszVal[*(PWORD)(pBlob+1)]=0;
+ }
+ break;
+ case DBVT_BLOB:
+ NeedBytes(3+*(PWORD)(pBlob+1));
+ if(isStatic) {
+ if(*(PWORD)(pBlob+1)<dbcgs->pValue->cpbVal) dbcgs->pValue->cpbVal=*(PWORD)(pBlob+1);
+ CopyMemory(dbcgs->pValue->pbVal,pBlob+3,dbcgs->pValue->cchVal);
+ }
+ else {
+ dbcgs->pValue->pbVal=(char*)mir_alloc(*(PWORD)(pBlob+1));
+ CopyMemory(dbcgs->pValue->pbVal,pBlob+3,*(PWORD)(pBlob+1));
+ }
+ dbcgs->pValue->cpbVal=*(PWORD)(pBlob+1);
+ break;
+ }
+
+ /**** add to cache **********************/
+ if ( dbcgs->pValue->type != DBVT_BLOB )
+ {
+ DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 );
+ if ( pCachedValue != NULL )
+ SetCachedVariant(dbcgs->pValue,pCachedValue);
+ }
+
+ LeaveCriticalSection(&csDbAccess);
+ logg();
+ return 0;
+ }
+ NeedBytes(1);
+ MoveAlong(pBlob[0]+1);
+ NeedBytes(3);
+ MoveAlong(1+GetSettingValueLength(pBlob));
+ NeedBytes(1);
+ } }
+
+ /**** add missing setting to cache **********************/
+ if ( dbcgs->pValue->type != DBVT_BLOB )
+ {
+ DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 );
+ if ( pCachedValue != NULL )
+ pCachedValue->type = DBVT_DELETED;
+ }
+
+ LeaveCriticalSection(&csDbAccess);
+ logg();
+ return 1;
+}
+
+static int GetContactSetting(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTGETSETTING* dgs = ( DBCONTACTGETSETTING* )lParam;
+ dgs->pValue->type = 0;
+ if ( GetContactSettingWorker(( HANDLE )wParam, dgs, 0 ))
+ return 1;
+
+ if ( dgs->pValue->type == DBVT_UTF8 ) {
+ Utf8Decode( dgs->pValue->pszVal, NULL );
+ dgs->pValue->type = DBVT_ASCIIZ;
+ }
+
+ return 0;
+}
+
+static int GetContactSettingStr(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTGETSETTING* dgs = (DBCONTACTGETSETTING*)lParam;
+ int iSaveType = dgs->pValue->type;
+
+ if ( GetContactSettingWorker(( HANDLE )wParam, dgs, 0 ))
+ return 1;
+
+ if ( iSaveType == 0 || iSaveType == dgs->pValue->type )
+ return 0;
+
+ if ( dgs->pValue->type != DBVT_ASCIIZ && dgs->pValue->type != DBVT_UTF8 )
+ return 0;
+
+ if ( iSaveType == DBVT_WCHAR ) {
+ if ( dgs->pValue->type != DBVT_UTF8 ) {
+ int len = MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, NULL, 0 );
+ wchar_t* wszResult = ( wchar_t* )mir_alloc(( len+1 )*sizeof( wchar_t ));
+ if ( wszResult == NULL )
+ return 1;
+
+ MultiByteToWideChar( CP_ACP, 0, dgs->pValue->pszVal, -1, wszResult, len );
+ wszResult[ len ] = 0;
+ mir_free( dgs->pValue->pszVal );
+ dgs->pValue->pwszVal = wszResult;
+ }
+ else {
+ char* savePtr = dgs->pValue->pszVal;
+ Utf8Decode( dgs->pValue->pszVal, &dgs->pValue->pwszVal );
+ mir_free( savePtr );
+ }
+ }
+ else if ( iSaveType == DBVT_UTF8 ) {
+ char* tmpBuf = Utf8Encode( dgs->pValue->pszVal );
+ if ( tmpBuf == NULL )
+ return 1;
+
+ mir_free( dgs->pValue->pszVal );
+ dgs->pValue->pszVal = tmpBuf;
+ }
+ else if ( iSaveType == DBVT_ASCIIZ )
+ Utf8Decode( dgs->pValue->pszVal, NULL );
+
+ dgs->pValue->type = iSaveType;
+ return 0;
+}
+
+static int GetContactSettingStatic(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTGETSETTING* dgs = (DBCONTACTGETSETTING*)lParam;
+ if ( GetContactSettingWorker(( HANDLE )wParam, dgs, 1 ))
+ return 1;
+
+ if ( dgs->pValue->type == DBVT_UTF8 ) {
+ Utf8Decode( dgs->pValue->pszVal, NULL );
+ dgs->pValue->type = DBVT_ASCIIZ;
+ }
+
+ return 0;
+}
+
+static int FreeVariant(WPARAM wParam,LPARAM lParam)
+{
+ DBVARIANT *dbv=(DBVARIANT*)lParam;
+ if ( dbv == 0 ) return 1;
+ switch ( dbv->type ) {
+ case DBVT_ASCIIZ:
+ case DBVT_UTF8:
+ case DBVT_WCHAR:
+ {
+ if ( dbv->pszVal ) mir_free(dbv->pszVal);
+ dbv->pszVal=0;
+ break;
+ }
+ case DBVT_BLOB:
+ {
+ if ( dbv->pbVal ) mir_free(dbv->pbVal);
+ dbv->pbVal=0;
+ break;
+ }
+ }
+ dbv->type=0;
+ return 0;
+}
+
+static int SetSettingResident(WPARAM wParam,LPARAM lParam)
+{
+ char* szSetting;
+ size_t cbSettingNameLen = strlen(( char* )lParam );
+ int idx;
+ char* szTemp = ( char* )alloca( cbSettingNameLen+2 );
+ strcpy( szTemp+1, ( char* )lParam );
+
+ EnterCriticalSection(&csDbAccess);
+ if ( !li.List_GetIndex( &lSettings, szTemp, &idx ))
+ szSetting = InsertCachedSetting( szTemp, cbSettingNameLen+2, idx );
+ else
+ szSetting = lSettings.items[ idx ];
+
+ *szSetting = (char)wParam;
+
+ LeaveCriticalSection(&csDbAccess);
+ return 0;
+}
+
+static int WriteContactSetting(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam;
+ struct DBContact dbc;
+ DWORD ofsModuleName;
+ struct DBContactSettings dbcs;
+ PBYTE pBlob;
+ int settingNameLen=0;
+ int moduleNameLen=0;
+ int settingDataLen=0;
+
+ int bytesRequired,bytesRemaining;
+ DWORD ofsContact,ofsSettingsGroup,ofsBlobPtr;
+
+ if (dbcws == NULL)
+ return 1;
+
+ if (dbcws->value.type == DBVT_WCHAR) {
+ if (dbcws->value.pszVal != NULL) {
+ char* val = Utf8EncodeUcs2(dbcws->value.pwszVal);
+ if ( val == NULL )
+ return 1;
+
+ dbcws->value.pszVal = ( char* )alloca( strlen( val )+1 );
+ strcpy( dbcws->value.pszVal, val );
+ mir_free(val);
+ dbcws->value.type = DBVT_UTF8;
+ }
+ else return 1;
+ }
+
+ if(dbcws->value.type!=DBVT_BYTE && dbcws->value.type!=DBVT_WORD && dbcws->value.type!=DBVT_DWORD && dbcws->value.type!=DBVT_ASCIIZ && dbcws->value.type!=DBVT_UTF8 && dbcws->value.type!=DBVT_BLOB)
+ return 1;
+ if ((!dbcws->szModule) || (!dbcws->szSetting) || ((dbcws->value.type == DBVT_ASCIIZ || dbcws->value.type == DBVT_UTF8 )&& dbcws->value.pszVal == NULL) || (dbcws->value.type == DBVT_BLOB && dbcws->value.pbVal == NULL) )
+ return 1;
+ // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name
+ settingNameLen=strlen(dbcws->szSetting);
+ moduleNameLen=strlen(dbcws->szModule);
+ if ( settingNameLen > 0xFE )
+ {
+ #ifdef _DEBUG
+ OutputDebugString("WriteContactSetting() got a > 255 setting name length. \n");
+ #endif
+ return 1;
+ }
+ if ( moduleNameLen > 0xFE )
+ {
+ #ifdef _DEBUG
+ OutputDebugString("WriteContactSetting() got a > 255 module name length. \n");
+ #endif
+ return 1;
+ }
+
+ // the db can not tolerate strings/blobs longer than 0xFFFF since the format writes 2 lengths
+ switch( dbcws->value.type ) {
+ case DBVT_ASCIIZ: case DBVT_BLOB: case DBVT_UTF8:
+ { int len = ( dbcws->value.type != DBVT_BLOB ) ? strlen(dbcws->value.pszVal) : dbcws->value.cpbVal;
+ if ( len >= 0xFFFF ) {
+ #ifdef _DEBUG
+ OutputDebugString("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n");
+ #endif
+ return 1;
+ }
+ }
+ }
+
+ EnterCriticalSection(&csDbAccess);
+ {
+ char* szCachedSettingName = GetCachedSetting(dbcws->szModule, dbcws->szSetting, settingNameLen);
+ if ( dbcws->value.type != DBVT_BLOB ) {
+ DBVARIANT* pCachedValue = GetCachedValuePtr((HANDLE)wParam, szCachedSettingName, 1);
+ if ( pCachedValue != NULL ) {
+ BOOL bIsIdentical = FALSE;
+ if ( pCachedValue->type == dbcws->value.type ) {
+ switch(dbcws->value.type) {
+ case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == dbcws->value.bVal; break;
+ case DBVT_WORD: bIsIdentical = pCachedValue->wVal == dbcws->value.wVal; break;
+ case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == dbcws->value.dVal; break;
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ: bIsIdentical = strcmp( pCachedValue->pszVal, dbcws->value.pszVal ) == 0; break;
+ }
+ if ( bIsIdentical ) {
+ LeaveCriticalSection(&csDbAccess);
+ return 0;
+ }
+ }
+ SetCachedVariant(&dbcws->value, pCachedValue);
+ }
+ if ( szCachedSettingName[-1] != 0 ) {
+ LeaveCriticalSection(&csDbAccess);
+ NotifyEventHooks(hSettingChangeEvent,wParam,lParam);
+ return 0;
+ }
+ }
+ else GetCachedValuePtr((HANDLE)wParam, szCachedSettingName, -1);
+ }
+
+ ofsModuleName=GetModuleNameOfs(dbcws->szModule);
+ if(wParam==0) ofsContact=dbHeader.ofsUser;
+ else ofsContact=wParam;
+
+ dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL);
+ if(dbc.signature!=DBCONTACT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ log0("write setting");
+ //make sure the module group exists
+ ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsContact,ofsModuleName);
+ if(ofsSettingsGroup==0) { //module group didn't exist - make it
+ if(dbcws->value.type&DBVTF_VARIABLELENGTH) {
+ if(dbcws->value.type==DBVT_ASCIIZ || dbcws->value.type==DBVT_UTF8) bytesRequired=strlen(dbcws->value.pszVal)+2;
+ else if(dbcws->value.type==DBVT_BLOB) bytesRequired=dbcws->value.cpbVal+2;
+ }
+ else bytesRequired=dbcws->value.type;
+ bytesRequired+=2+settingNameLen;
+ bytesRequired+=(DB_SETTINGS_RESIZE_GRANULARITY-(bytesRequired%DB_SETTINGS_RESIZE_GRANULARITY))%DB_SETTINGS_RESIZE_GRANULARITY;
+ ofsSettingsGroup=CreateNewSpace(bytesRequired+offsetof(struct DBContactSettings,blob));
+ dbcs.signature=DBCONTACTSETTINGS_SIGNATURE;
+ dbcs.ofsNext=dbc.ofsFirstSettings;
+ dbcs.ofsModuleName=ofsModuleName;
+ dbcs.cbBlob=bytesRequired;
+ dbcs.blob[0]=0;
+ dbc.ofsFirstSettings=ofsSettingsGroup;
+ DBWrite(ofsContact,&dbc,sizeof(struct DBContact));
+ DBWrite(ofsSettingsGroup,&dbcs,sizeof(struct DBContactSettings));
+ ofsBlobPtr=ofsSettingsGroup+offsetof(struct DBContactSettings,blob);
+ pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining);
+ }
+ else {
+ dbcs=*(struct DBContactSettings*)DBRead(ofsSettingsGroup,sizeof(struct DBContactSettings),&bytesRemaining);
+ //find if the setting exists
+ ofsBlobPtr=ofsSettingsGroup+offsetof(struct DBContactSettings,blob);
+ pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining);
+ while(pBlob[0]) {
+ NeedBytes(settingNameLen+1);
+ if(pBlob[0]==settingNameLen && !memcmp(pBlob+1,dbcws->szSetting,settingNameLen))
+ break;
+ NeedBytes(1);
+ MoveAlong(pBlob[0]+1);
+ NeedBytes(3);
+ MoveAlong(1+GetSettingValueLength(pBlob));
+ NeedBytes(1);
+ }
+ if(pBlob[0]) { //setting already existed, and up to end of name is in cache
+ MoveAlong(1+settingNameLen);
+ //if different type or variable length and length is different
+ NeedBytes(3);
+ if(pBlob[0]!=dbcws->value.type || ((pBlob[0]==DBVT_ASCIIZ || pBlob[0]==DBVT_UTF8) && *(PWORD)(pBlob+1)!=strlen(dbcws->value.pszVal)) || (pBlob[0]==DBVT_BLOB && *(PWORD)(pBlob+1)!=dbcws->value.cpbVal)) {
+ //bin it
+ int nameLen,valLen;
+ DWORD ofsSettingToCut;
+ NeedBytes(3);
+ nameLen=1+settingNameLen;
+ valLen=1+GetSettingValueLength(pBlob);
+ ofsSettingToCut=ofsBlobPtr-nameLen;
+ MoveAlong(valLen);
+ NeedBytes(1);
+ while(pBlob[0]) {
+ MoveAlong(pBlob[0]+1);
+ NeedBytes(3);
+ MoveAlong(1+GetSettingValueLength(pBlob));
+ NeedBytes(1);
+ }
+ DBMoveChunk(ofsSettingToCut,ofsSettingToCut+nameLen+valLen,ofsBlobPtr+1-ofsSettingToCut);
+ ofsBlobPtr-=nameLen+valLen;
+ pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining);
+ }
+ else {
+ //replace existing setting at pBlob
+ MoveAlong(1); //skip data type
+ switch(dbcws->value.type) {
+ case DBVT_BYTE: DBWrite(ofsBlobPtr,&dbcws->value.bVal,1); break;
+ case DBVT_WORD: DBWrite(ofsBlobPtr,&dbcws->value.wVal,2); break;
+ case DBVT_DWORD: DBWrite(ofsBlobPtr,&dbcws->value.dVal,4); break;
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ: DBWrite(ofsBlobPtr+2,dbcws->value.pszVal,strlen(dbcws->value.pszVal)); break;
+ case DBVT_BLOB: DBWrite(ofsBlobPtr+2,dbcws->value.pbVal,dbcws->value.cpbVal); break;
+ }
+ //quit
+ DBFlush(1);
+ LeaveCriticalSection(&csDbAccess);
+ //notify
+ NotifyEventHooks(hSettingChangeEvent,wParam,lParam);
+ return 0;
+ }
+ }
+ }
+ //cannot do a simple replace, add setting to end of list
+ //pBlob already points to end of list
+ //see if it fits
+ if(dbcws->value.type&DBVTF_VARIABLELENGTH) {
+ if(dbcws->value.type==DBVT_ASCIIZ || dbcws->value.type==DBVT_UTF8) bytesRequired=strlen(dbcws->value.pszVal)+2;
+ else if(dbcws->value.type==DBVT_BLOB) bytesRequired=dbcws->value.cpbVal+2;
+ }
+ else bytesRequired=dbcws->value.type;
+ bytesRequired+=2+settingNameLen;
+ bytesRequired+=ofsBlobPtr+1-(ofsSettingsGroup+offsetof(struct DBContactSettings,blob));
+ if((DWORD)bytesRequired>dbcs.cbBlob) {
+ //doesn't fit: move entire group
+ struct DBContactSettings *dbcsPrev;
+ DWORD ofsDbcsPrev,oldSize,ofsNew;
+
+ InvalidateSettingsGroupOfsCacheEntry(ofsSettingsGroup);
+ bytesRequired+=(DB_SETTINGS_RESIZE_GRANULARITY-(bytesRequired%DB_SETTINGS_RESIZE_GRANULARITY))%DB_SETTINGS_RESIZE_GRANULARITY;
+ //find previous group to change its offset
+ ofsDbcsPrev=dbc.ofsFirstSettings;
+ if(ofsDbcsPrev==ofsSettingsGroup) ofsDbcsPrev=0;
+ else {
+ dbcsPrev=(struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL);
+ while(dbcsPrev->ofsNext!=ofsSettingsGroup) {
+ if(dbcsPrev->ofsNext==0) DatabaseCorruption();
+ ofsDbcsPrev=dbcsPrev->ofsNext;
+ dbcsPrev=(struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL);
+ }
+ }
+ //create the new one
+ ofsNew=CreateNewSpace(bytesRequired+offsetof(struct DBContactSettings,blob));
+ //copy across
+ DBMoveChunk(ofsNew,ofsSettingsGroup,bytesRequired+offsetof(struct DBContactSettings,blob));
+ oldSize=dbcs.cbBlob;
+ dbcs.cbBlob=bytesRequired;
+ DBWrite(ofsNew,&dbcs,offsetof(struct DBContactSettings,blob));
+ if(ofsDbcsPrev==0) {
+ dbc.ofsFirstSettings=ofsNew;
+ DBWrite(ofsContact,&dbc,sizeof(struct DBContact));
+ }
+ else {
+ dbcsPrev=(struct DBContactSettings*)DBRead(ofsDbcsPrev,sizeof(struct DBContactSettings),NULL);
+ dbcsPrev->ofsNext=ofsNew;
+ DBWrite(ofsDbcsPrev,dbcsPrev,offsetof(struct DBContactSettings,blob));
+ }
+ DeleteSpace(ofsSettingsGroup,oldSize+offsetof(struct DBContactSettings,blob));
+ ofsBlobPtr+=ofsNew-ofsSettingsGroup;
+ ofsSettingsGroup=ofsNew;
+ pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining);
+ }
+ //we now have a place to put it and enough space: make it
+ DBWrite(ofsBlobPtr,&settingNameLen,1);
+ DBWrite(ofsBlobPtr+1,(PVOID)dbcws->szSetting,settingNameLen);
+ MoveAlong(1+settingNameLen);
+ DBWrite(ofsBlobPtr,&dbcws->value.type,1);
+ MoveAlong(1);
+ switch(dbcws->value.type) {
+ case DBVT_BYTE: DBWrite(ofsBlobPtr,&dbcws->value.bVal,1); MoveAlong(1); break;
+ case DBVT_WORD: DBWrite(ofsBlobPtr,&dbcws->value.wVal,2); MoveAlong(2); break;
+ case DBVT_DWORD: DBWrite(ofsBlobPtr,&dbcws->value.dVal,4); MoveAlong(4); break;
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ:
+ { int len=strlen(dbcws->value.pszVal);
+ DBWrite(ofsBlobPtr,&len,2);
+ DBWrite(ofsBlobPtr+2,dbcws->value.pszVal,len);
+ MoveAlong(2+len);
+ }
+ break;
+ case DBVT_BLOB:
+ DBWrite(ofsBlobPtr,&dbcws->value.cpbVal,2);
+ DBWrite(ofsBlobPtr+2,dbcws->value.pbVal,dbcws->value.cpbVal);
+ MoveAlong(2+dbcws->value.cpbVal);
+ break;
+ }
+ { BYTE zero=0;
+ DBWrite(ofsBlobPtr,&zero,1);
+ }
+ //quit
+ DBFlush(1);
+ LeaveCriticalSection(&csDbAccess);
+ //notify
+ NotifyEventHooks(hSettingChangeEvent,wParam,lParam);
+ return 0;
+}
+
+static int DeleteContactSetting(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTGETSETTING *dbcgs=(DBCONTACTGETSETTING*)lParam;
+ struct DBContact *dbc;
+ DWORD ofsModuleName,ofsSettingsGroup,ofsBlobPtr;
+ struct DBContactSettings dbcs;
+ PBYTE pBlob;
+ int settingNameLen=strlen(dbcgs->szSetting),bytesRemaining;
+ char* szCachedSettingName;
+ WPARAM saveWparam = wParam;
+
+ if ((!dbcgs->szModule) || (!dbcgs->szSetting))
+ return 1;
+
+ EnterCriticalSection(&csDbAccess);
+ ofsModuleName=GetModuleNameOfs(dbcgs->szModule);
+ if(wParam==0) wParam=dbHeader.ofsUser;
+
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbc->signature!=DBCONTACT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ //make sure the module group exists
+ ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(dbc,wParam,ofsModuleName);
+ if(ofsSettingsGroup==0) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL);
+ if(dbc->signature!=DBCONTACT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(dbc,wParam,ofsModuleName);
+ if(ofsSettingsGroup==0) {
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ dbcs=*(struct DBContactSettings*)DBRead(ofsSettingsGroup,sizeof(struct DBContactSettings),NULL);
+ //find if the setting exists
+ ofsBlobPtr=ofsSettingsGroup+offsetof(struct DBContactSettings,blob);
+ pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining);
+ while(pBlob[0]) {
+ NeedBytes(settingNameLen+1);
+ if(pBlob[0]==settingNameLen && !memcmp(pBlob+1,dbcgs->szSetting,settingNameLen))
+ break;
+ NeedBytes(1);
+ MoveAlong(pBlob[0]+1);
+ NeedBytes(3);
+ MoveAlong(1+GetSettingValueLength(pBlob));
+ NeedBytes(1);
+ }
+ if(!pBlob[0]) { //setting didn't exist
+ LeaveCriticalSection(&csDbAccess);
+ return 1;
+ }
+ { //bin it
+ int nameLen,valLen;
+ DWORD ofsSettingToCut;
+ MoveAlong(1+settingNameLen);
+ NeedBytes(3);
+ nameLen=1+settingNameLen;
+ valLen=1+GetSettingValueLength(pBlob);
+ ofsSettingToCut=ofsBlobPtr-nameLen;
+ MoveAlong(valLen);
+ NeedBytes(1);
+ while(pBlob[0]) {
+ MoveAlong(pBlob[0]+1);
+ NeedBytes(3);
+ MoveAlong(1+GetSettingValueLength(pBlob));
+ NeedBytes(1);
+ }
+ DBMoveChunk(ofsSettingToCut,ofsSettingToCut+nameLen+valLen,ofsBlobPtr+1-ofsSettingToCut);
+ }
+
+ szCachedSettingName = GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,settingNameLen);
+ GetCachedValuePtr((HANDLE)saveWparam, szCachedSettingName, -1 );
+
+ //quit
+ DBFlush(1);
+ LeaveCriticalSection(&csDbAccess);
+ { //notify
+ DBCONTACTWRITESETTING dbcws;
+ dbcws.szModule=dbcgs->szModule;
+ dbcws.szSetting=dbcgs->szSetting;
+ dbcws.value.type=DBVT_DELETED;
+ NotifyEventHooks(hSettingChangeEvent,saveWparam,(LPARAM)&dbcws);
+ }
+ return 0;
+}
+
+static int EnumContactSettings(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTENUMSETTINGS *dbces=(DBCONTACTENUMSETTINGS*)lParam;
+ struct DBContact dbc;
+ struct DBContactSettings dbcs;
+ DWORD ofsModuleName,ofsContact,ofsBlobPtr;
+ int bytesRemaining, result;
+ PBYTE pBlob;
+ char szSetting[256];
+
+ if (!dbces->szModule)
+ return -1;
+
+ EnterCriticalSection(&csDbAccess);
+
+ ofsModuleName=GetModuleNameOfs(dbces->szModule);
+ if(wParam==0) ofsContact=dbHeader.ofsUser;
+ else ofsContact=wParam;
+ dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL);
+ if(dbc.signature!=DBCONTACT_SIGNATURE) {
+ LeaveCriticalSection(&csDbAccess);
+ return -1;
+ }
+ dbces->ofsSettings=GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsContact,ofsModuleName);
+ if(!dbces->ofsSettings) {
+ LeaveCriticalSection(&csDbAccess);
+ return -1;
+ }
+ dbcs=*(struct DBContactSettings*)DBRead(dbces->ofsSettings,sizeof(struct DBContactSettings),&bytesRemaining);
+ ofsBlobPtr=dbces->ofsSettings+offsetof(struct DBContactSettings,blob);
+ pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining);
+ if(pBlob[0]==0) {
+ LeaveCriticalSection(&csDbAccess);
+ return -1;
+ }
+ result = 0;
+ while(pBlob[0]) {
+ NeedBytes(1);
+ NeedBytes(1+pBlob[0]);
+ CopyMemory(szSetting,pBlob+1,pBlob[0]); szSetting[pBlob[0]]=0;
+ result = (dbces->pfnEnumProc)(szSetting,dbces->lParam);
+ MoveAlong(1+pBlob[0]);
+ NeedBytes(3);
+ MoveAlong(1+GetSettingValueLength(pBlob));
+ NeedBytes(1);
+ }
+ LeaveCriticalSection(&csDbAccess);
+ return result;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//
+// Module initialization procedure
+
+static int stringCompare( DBCachedSettingName* p1, DBCachedSettingName* p2 )
+{
+ return strcmp( p1->name, p2->name );
+}
+
+static int stringCompare2( DBCachedGlobalValue* p1, DBCachedGlobalValue* p2 )
+{
+ return strcmp( p1->name, p2->name );
+}
+
+static int handleCompare( void* p1, void* p2 )
+{
+ if ( *( long* )p1 == *( long* )p2 )
+ return 0;
+
+ return *( long* )p1 - *( long* )p2;
+}
+
+int InitSettings(void)
+{
+ CreateServiceFunction(MS_DB_CONTACT_GETSETTING,GetContactSetting);
+ CreateServiceFunction(MS_DB_CONTACT_GETSETTING_STR,GetContactSettingStr);
+ CreateServiceFunction(MS_DB_CONTACT_GETSETTINGSTATIC,GetContactSettingStatic);
+ CreateServiceFunction(MS_DB_CONTACT_FREEVARIANT,FreeVariant);
+ CreateServiceFunction(MS_DB_CONTACT_WRITESETTING,WriteContactSetting);
+ CreateServiceFunction(MS_DB_CONTACT_DELETESETTING,DeleteContactSetting);
+ CreateServiceFunction(MS_DB_CONTACT_ENUMSETTINGS,EnumContactSettings);
+ CreateServiceFunction(MS_DB_SETSETTINGRESIDENT,SetSettingResident);
+ hSettingChangeEvent=CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED);
+
+ hCacheHeap=HeapCreate(HEAP_NO_SERIALIZE,0,0);
+ lSettings.sortFunc=stringCompare;
+ lSettings.increment=50;
+ lContacts.sortFunc=handleCompare;
+ lContacts.increment=100;
+ lGlobalSettings.sortFunc=stringCompare2;
+ lGlobalSettings.increment=100;
+ return 0;
+}
+
+void UninitSettings(void)
+{
+ HeapDestroy(hCacheHeap);
+ li.List_Destroy(&lContacts);
+ li.List_Destroy(&lSettings);
+ li.List_Destroy(&lGlobalSettings);
+}
diff --git a/miranda-wine/plugins/db3x/dbtime.c b/miranda-wine/plugins/db3x/dbtime.c new file mode 100644 index 0000000..e9189b9 --- /dev/null +++ b/miranda-wine/plugins/db3x/dbtime.c @@ -0,0 +1,163 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+static int daysInMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};
+static int IsLeapYear(int year)
+{
+ if(year&3) return 0;
+ if(year%100) return 1;
+ if(year%400) return 0;
+ return 1;
+}
+
+static int CompareSystemTimes(SYSTEMTIME *st,SYSTEMTIME *switchDate)
+{
+ FILETIME ft1,ft2;
+
+ if(switchDate->wYear==0) { //strange day-in-month thing
+ SYSTEMTIME tempst;
+
+ //short-circuit if the months aren't the same
+ if(st->wMonth<switchDate->wMonth) return -1;
+ if(st->wMonth>switchDate->wMonth) return 1;
+
+ tempst=*switchDate;
+ tempst.wYear=st->wYear;
+ tempst.wDay=1;
+ SystemTimeToFileTime(&tempst,&ft1);
+ FileTimeToSystemTime(&ft1,&tempst); //gets the day of week of the first of the month
+ tempst.wDay=1+(7+switchDate->wDayOfWeek-tempst.wDayOfWeek)%7;
+ if(switchDate->wDay==5) { //last wDayOfWeek in month
+ if(tempst.wMonth==2) {
+ if(IsLeapYear(tempst.wYear)) daysInMonth[1]=29;
+ else daysInMonth[1]=28;
+ }
+ tempst.wDay+=7*3; //can't be less than 4 of that day in the month
+ if(tempst.wDay+7<=daysInMonth[switchDate->wMonth-1]) tempst.wDay+=7;
+ }
+ else tempst.wDay+=7*(switchDate->wDay-1); //nth of month
+ SystemTimeToFileTime(&tempst,&ft2);
+ }
+ else {
+ switchDate->wYear=st->wYear;
+ SystemTimeToFileTime(switchDate,&ft2);
+ }
+ SystemTimeToFileTime(st,&ft1);
+ return CompareFileTime(&ft1,&ft2);
+}
+
+static int TimestampToLocal(WPARAM wParam,LPARAM lParam)
+{
+ TIME_ZONE_INFORMATION tzInfo;
+ LARGE_INTEGER liFiletime;
+ FILETIME filetime;
+ SYSTEMTIME st;
+
+ GetTimeZoneInformation(&tzInfo);
+ if(tzInfo.StandardDate.wMonth==0) { //no daylight savings time
+ return (int)(wParam-tzInfo.Bias*60);
+ }
+ //this huge number is the difference between 1970 and 1601 in seconds
+ liFiletime.QuadPart=(mir_i64(11644473600)+(__int64)wParam)*10000000;
+ filetime.dwHighDateTime=liFiletime.HighPart;
+ filetime.dwLowDateTime=liFiletime.LowPart;
+ FileTimeToSystemTime(&filetime,&st);
+ if(tzInfo.DaylightDate.wMonth<tzInfo.StandardDate.wMonth) {
+ //northern hemisphere
+ if(CompareSystemTimes(&st,&tzInfo.DaylightDate)<0 ||
+ CompareSystemTimes(&st,&tzInfo.StandardDate)>0) {
+ return (int)(wParam-(tzInfo.Bias+tzInfo.StandardBias)*60);
+ }
+ return (int)(wParam-(tzInfo.Bias+tzInfo.DaylightBias)*60);
+ }
+ else {
+ //southern hemisphere
+ if(CompareSystemTimes(&st,&tzInfo.StandardDate)<0 ||
+ CompareSystemTimes(&st,&tzInfo.DaylightDate)>0) {
+ return (int)(wParam-(tzInfo.Bias+tzInfo.DaylightBias)*60);
+ }
+ return (int)(wParam-(tzInfo.Bias+tzInfo.StandardBias)*60);
+ }
+ return 0;
+}
+
+static int TimestampToString(WPARAM wParam,LPARAM lParam)
+{
+ DBTIMETOSTRING *tts=(DBTIMETOSTRING*)lParam;
+ LARGE_INTEGER liFiletime;
+ FILETIME filetime;
+ SYSTEMTIME st;
+ char dateTimeStr[64];
+ char *pDest,*pFormat;
+ int destCharsLeft,dateTimeStrLen;
+
+ //this huge number is the difference between 1970 and 1601 in seconds
+ liFiletime.QuadPart=(mir_i64(11644473600)+(__int64)(DWORD)TimestampToLocal(wParam,0))*10000000;
+ filetime.dwHighDateTime=liFiletime.HighPart;
+ filetime.dwLowDateTime=liFiletime.LowPart;
+ FileTimeToSystemTime(&filetime,&st);
+ destCharsLeft=tts->cbDest;
+ for(pFormat=tts->szFormat,pDest=tts->szDest;*pFormat;pFormat++) {
+ switch(*pFormat) {
+ case 't':
+ GetTimeFormat(LOCALE_USER_DEFAULT,TIME_NOSECONDS,&st,NULL,dateTimeStr,sizeof(dateTimeStr));
+ break;
+ case 's':
+ GetTimeFormat(LOCALE_USER_DEFAULT,0,&st,NULL,dateTimeStr,sizeof(dateTimeStr));
+ break;
+ case 'm':
+ GetTimeFormat(LOCALE_USER_DEFAULT,TIME_NOMINUTESORSECONDS,&st,NULL,dateTimeStr,sizeof(dateTimeStr));
+ break;
+ case 'd':
+ GetDateFormat(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&st,NULL,dateTimeStr,sizeof(dateTimeStr));
+ break;
+ case 'D':
+ GetDateFormat(LOCALE_USER_DEFAULT,DATE_LONGDATE,&st,NULL,dateTimeStr,sizeof(dateTimeStr));
+ break;
+ default:
+ if(destCharsLeft) {
+ *pDest++=*pFormat;
+ destCharsLeft--;
+ }
+ continue;
+ }
+ dateTimeStrLen=strlen(dateTimeStr);
+ if(destCharsLeft<dateTimeStrLen) dateTimeStrLen=destCharsLeft;
+ CopyMemory(pDest,dateTimeStr,dateTimeStrLen);
+ destCharsLeft-=dateTimeStrLen;
+ pDest+=dateTimeStrLen;
+ }
+ if(destCharsLeft) *pDest=0;
+ else tts->szDest[tts->cbDest-1]=0;
+ return 0;
+}
+
+int InitTime(void)
+{
+ CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOLOCAL,TimestampToLocal);
+ CreateServiceFunction(MS_DB_TIME_TIMESTAMPTOSTRING,TimestampToString);
+ return 0;
+}
diff --git a/miranda-wine/plugins/db3x/encrypt.c b/miranda-wine/plugins/db3x/encrypt.c new file mode 100644 index 0000000..1382a27 --- /dev/null +++ b/miranda-wine/plugins/db3x/encrypt.c @@ -0,0 +1,67 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+//VERY VERY VERY BASIC ENCRYPTION FUNCTION
+
+
+void Encrypt(char*msg,BOOL up)
+{
+ int i;
+ int jump;
+ if (up)
+ {
+ jump=5;
+ }
+ else
+ {
+ jump=-5;
+ }
+
+ for (i=0;msg[i];i++)
+ {
+ msg[i]=msg[i]+jump;
+ }
+
+}
+
+static int EncodeString(WPARAM wParam,LPARAM lParam)
+{
+ Encrypt((char*)lParam,TRUE);
+ return 0;
+}
+
+static int DecodeString(WPARAM wParam,LPARAM lParam)
+{
+ Encrypt((char*)lParam,FALSE);
+ return 0;
+}
+
+int InitCrypt(void)
+{
+ CreateServiceFunction(MS_DB_CRYPT_ENCODESTRING,EncodeString);
+ CreateServiceFunction(MS_DB_CRYPT_DECODESTRING,DecodeString);
+ return 0;
+}
diff --git a/miranda-wine/plugins/db3x/encryption.h b/miranda-wine/plugins/db3x/encryption.h new file mode 100644 index 0000000..73c2d7e --- /dev/null +++ b/miranda-wine/plugins/db3x/encryption.h @@ -0,0 +1,23 @@ +/*
+Miranda ICQ: the free icq client for MS Windows
+Copyright (C) 2000-2 Richard Hughes, Roland Rabien & Tristan Van de Vreede
+
+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.
+*/
+#ifndef MODULAR
+#include <windows.h>
+
+void Encrypt(char*msg,BOOL up);
+#endif
\ No newline at end of file diff --git a/miranda-wine/plugins/db3x/init.c b/miranda-wine/plugins/db3x/init.c new file mode 100644 index 0000000..91834ed --- /dev/null +++ b/miranda-wine/plugins/db3x/init.c @@ -0,0 +1,193 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+#include <m_plugins.h>
+
+struct MM_INTERFACE memoryManagerInterface;
+struct LIST_INTERFACE li;
+extern char szDbPath[MAX_PATH];
+
+HINSTANCE g_hInst=NULL;
+PLUGINLINK *pluginLink;
+
+static int getCapability( int flag )
+{
+ return 0;
+}
+
+// returns 0 if the profile is created, EMKPRF*
+static int makeDatabase(char * profile, int * error)
+{
+ HANDLE hFile=CreateFile(profile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ if ( hFile != INVALID_HANDLE_VALUE ) {
+ CreateDbHeaders(hFile);
+ CloseHandle(hFile);
+ return 0;
+ }
+ if ( error != NULL ) *error=EMKPRF_CREATEFAILED;
+ return 1;
+}
+
+// returns 0 if the given profile has a valid header
+static int grokHeader( char * profile, int * error )
+{
+ int rc=1;
+ int chk=0;
+ struct DBHeader hdr;
+ HANDLE hFile = INVALID_HANDLE_VALUE;
+ DWORD dummy=0;
+
+ hFile = CreateFile(profile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if ( hFile == INVALID_HANDLE_VALUE ) {
+ if ( error != NULL ) *error=EGROKPRF_CANTREAD;
+ return 1;
+ }
+ // read the header, which can fail (for various reasons)
+ if ( !ReadFile(hFile, &hdr, sizeof(struct DBHeader), &dummy, NULL) ) {
+ if ( error != NULL) *error=EGROKPRF_CANTREAD;
+ CloseHandle(hFile);
+ return 1;
+ }
+ chk=CheckDbHeaders(&hdr);
+ if ( chk == 0 ) {
+ // all the internal tests passed, hurrah
+ rc=0;
+ if ( error != NULL ) *error=0;
+ } else {
+ // didn't pass at all, or some did.
+ switch ( chk ) {
+ case 1:
+ {
+ // "Miranda ICQ DB" wasn't present
+ if ( error != NULL ) *error = EGROKPRF_UNKHEADER;
+ break;
+ }
+ case 2:
+ {
+ // header was present, but version information newer
+ if ( error != NULL ) *error= EGROKPRF_VERNEWER;
+ break;
+ }
+ case 3:
+ {
+ // header/version OK, internal data missing
+ if ( error != NULL ) *error=EGROKPRF_DAMAGED;
+ break;
+ }
+ } // switch
+ } //if
+ CloseHandle(hFile);
+ return rc;
+}
+
+// returns 0 if all the APIs are injected otherwise, 1
+static int LoadDatabase( char * profile, void * plink )
+{
+ PLUGINLINK *link = plink;
+#ifdef _DEBUG
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+ // don't need thread notifications
+ strncpy(szDbPath, profile, sizeof(szDbPath));
+ // this is like Load()'s pluginLink
+ pluginLink=link;
+ // set the memory manager
+ memoryManagerInterface.cbSize=sizeof(struct MM_INTERFACE);
+ CallService(MS_SYSTEM_GET_MMI,0,(LPARAM)&memoryManagerInterface);
+ // set the lists manager;
+ li.cbSize = sizeof( li );
+ if ( CallService(MS_SYSTEM_GET_LI,0,(LPARAM)&li) == CALLSERVICE_NOTFOUND ) {
+ MessageBoxA( NULL, "This version of plugin requires Miranda IM 0.5 or later", "Fatal error", MB_OK );
+ return 1;
+ }
+
+ // inject all APIs and hooks into the core
+ return LoadDatabaseModule();
+}
+
+static int UnloadDatabase(int wasLoaded)
+{
+ if ( !wasLoaded) return 0;
+ UnloadDatabaseModule();
+ return 0;
+}
+
+static int getFriendlyName( char * buf, size_t cch, int shortName )
+{
+ strncpy(buf,shortName ? "db3x driver" : "db3x database support",cch);
+ return 0;
+}
+
+
+static DATABASELINK dblink = {
+ sizeof(DATABASELINK),
+ getCapability,
+ getFriendlyName,
+ makeDatabase,
+ grokHeader,
+ LoadDatabase,
+ UnloadDatabase,
+};
+
+static PLUGININFO pluginInfo = {
+ sizeof(PLUGININFO),
+ "Miranda database driver",
+ PLUGIN_MAKE_VERSION(0,6,0,0),
+ "Provides Miranda database support: global settings, contacts, history, settings per contact.",
+ "Miranda-IM project",
+ "ghazan@miranda-im.org",
+ "Copyright 2000-2006 Miranda IM project",
+ "",
+ 0,
+ DEFMOD_DB
+};
+
+
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved)
+{
+ g_hInst=hInstDLL;
+ return TRUE;
+}
+
+__declspec(dllexport) DATABASELINK* DatabasePluginInfo(void * reserved)
+{
+ return &dblink;
+}
+
+__declspec(dllexport) PLUGININFO * MirandaPluginInfo(DWORD mirandaVersion)
+{
+ if ( mirandaVersion < PLUGIN_MAKE_VERSION(0,4,0,0) ) return NULL;
+ return &pluginInfo;
+}
+
+int __declspec(dllexport) Load(PLUGINLINK * link)
+{
+ return 1;
+}
+
+int __declspec(dllexport) Unload(void)
+{
+ return 0;
+}
diff --git a/miranda-wine/plugins/db3x/resource.h b/miranda-wine/plugins/db3x/resource.h new file mode 100644 index 0000000..96abbff --- /dev/null +++ b/miranda-wine/plugins/db3x/resource.h @@ -0,0 +1,30 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDC_NOTOALL 3
+#define IDD_INSTALLINI 235
+#define IDD_WARNINICHANGE 236
+#define IDD_INIIMPORTDONE 237
+#define IDC_ININAME 1333
+#define IDC_VIEWINI 1334
+#define IDC_SECURITYINFO 1335
+#define IDC_SETTINGNAME 1336
+#define IDC_NEWVALUE 1337
+#define IDC_WARNNOMORE 1338
+#define IDC_DELETE 1339
+#define IDC_RECYCLE 1340
+#define IDC_NEWNAME 1341
+#define IDC_MOVE 1342
+#define IDC_LEAVE 1343
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 269
+#define _APS_NEXT_COMMAND_VALUE 40018
+#define _APS_NEXT_CONTROL_VALUE 1657
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/miranda-wine/plugins/db3x/resource.rc b/miranda-wine/plugins/db3x/resource.rc new file mode 100644 index 0000000..daa99f3 --- /dev/null +++ b/miranda-wine/plugins/db3x/resource.rc @@ -0,0 +1,169 @@ +//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <winres.h>
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_INSTALLINI DIALOGEX 0, 0, 212, 102
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER |
+ WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Install Database Settings"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Yes",IDOK,26,83,50,14
+ PUSHBUTTON "No",IDCANCEL,81,83,50,14
+ LTEXT "A file containing new database settings has been placed in the Miranda IM directory.",
+ IDC_STATIC,5,5,202,16
+ LTEXT "Do you want to import the settings now?",IDC_STATIC,5,
+ 69,202,8
+ PUSHBUTTON "No to all",IDC_NOTOALL,136,83,50,14
+ LTEXT "",IDC_ININAME,5,24,143,16,SS_NOPREFIX | SS_CENTERIMAGE
+ PUSHBUTTON "&View contents",IDC_VIEWINI,149,25,58,14
+ LTEXT "Security systems to prevent malicious changes are in place and you will be warned before changes that are not known to be safe.",
+ IDC_SECURITYINFO,5,43,202,24
+END
+
+IDD_WARNINICHANGE DIALOGEX 0, 0, 187, 113
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER |
+ WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Database Setting Change"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "Database settings are being imported from",IDC_STATIC,5,
+ 5,177,8
+ CONTROL "",IDC_ININAME,"Static",SS_SIMPLE | SS_NOPREFIX |
+ WS_GROUP,5,13,177,8
+ LTEXT "This file wishes to change the setting",IDC_STATIC,5,24,
+ 177,8
+ CONTROL "",IDC_SETTINGNAME,"Static",SS_SIMPLE | SS_NOPREFIX |
+ WS_GROUP,12,33,170,8
+ LTEXT "to the value",IDC_STATIC,5,42,177,8
+ CONTROL "",IDC_NEWVALUE,"Static",SS_SIMPLE | SS_NOPREFIX |
+ WS_GROUP,12,51,170,8
+ LTEXT "",IDC_SECURITYINFO,5,60,177,8
+ LTEXT "Do you want to allow this change?",IDC_STATIC,5,71,177,
+ 8
+ CONTROL "&Allow all further changes to this section",
+ IDC_WARNNOMORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,
+ 80,169,10
+ DEFPUSHBUTTON "&Yes",IDYES,5,94,50,14
+ PUSHBUTTON "&No",IDNO,59,94,50,14
+ PUSHBUTTON "Cancel Import",IDCANCEL,123,94,59,14
+END
+
+IDD_INIIMPORTDONE DIALOGEX 0, 0, 186, 73
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER |
+ WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Database Import Complete"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "The import has completed from",IDC_STATIC,5,5,176,8
+ CONTROL "",IDC_ININAME,"Static",SS_SIMPLE | SS_NOPREFIX |
+ WS_GROUP,5,13,176,8
+ LTEXT "What do you want to do with the file now?",IDC_STATIC,5,
+ 24,176,8
+ PUSHBUTTON "&Recycle",IDC_RECYCLE,5,36,50,14
+ PUSHBUTTON "&Delete",IDC_DELETE,68,36,50,14
+ EDITTEXT IDC_NEWNAME,5,55,117,12,ES_AUTOHSCROLL
+ PUSHBUTTON "&Move/Rename",IDC_MOVE,124,54,57,14
+ PUSHBUTTON "&Leave",IDC_LEAVE,131,36,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_INSTALLINI, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 207
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 97
+ END
+
+ IDD_WARNINICHANGE, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 182
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 108
+ END
+
+ IDD_INIIMPORTDONE, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 181
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 68
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include <winres.h>\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/miranda-wine/plugins/db3x/utf.c b/miranda-wine/plugins/db3x/utf.c new file mode 100644 index 0000000..52064a6 --- /dev/null +++ b/miranda-wine/plugins/db3x/utf.c @@ -0,0 +1,166 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2003 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 "database.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Utf8Decode - converts UTF8-encoded string to the UCS2/MBCS format
+
+void Utf8Decode( char* str, wchar_t** ucs2 )
+{
+ int len;
+ wchar_t* tempBuf;
+
+ if ( str == NULL )
+ return;
+
+ len = strlen( str );
+ if ( len < 2 ) {
+ if ( ucs2 != NULL ) {
+ *ucs2 = ( wchar_t* )mir_alloc(( len+1 )*sizeof( wchar_t ));
+ MultiByteToWideChar( CP_ACP, 0, str, len, *ucs2, len );
+ ( *ucs2 )[ len ] = 0;
+ }
+ return;
+ }
+
+ tempBuf = ( wchar_t* )alloca(( len+1 )*sizeof( wchar_t ));
+ {
+ wchar_t* d = tempBuf;
+ BYTE* s = ( BYTE* )str;
+
+ while( *s )
+ {
+ if (( *s & 0x80 ) == 0 ) {
+ *d++ = *s++;
+ continue;
+ }
+
+ if (( s[0] & 0xE0 ) == 0xE0 && ( s[1] & 0xC0 ) == 0x80 && ( s[2] & 0xC0 ) == 0x80 ) {
+ *d++ = (( WORD )( s[0] & 0x0F) << 12 ) + ( WORD )(( s[1] & 0x3F ) << 6 ) + ( WORD )( s[2] & 0x3F );
+ s += 3;
+ continue;
+ }
+
+ if (( s[0] & 0xE0 ) == 0xC0 && ( s[1] & 0xC0 ) == 0x80 ) {
+ *d++ = ( WORD )(( s[0] & 0x1F ) << 6 ) + ( WORD )( s[1] & 0x3F );
+ s += 2;
+ continue;
+ }
+
+ *d++ = *s++;
+ }
+
+ *d = 0;
+ }
+
+ if ( ucs2 != NULL ) {
+ int fullLen = ( len+1 )*sizeof( wchar_t );
+ *ucs2 = ( wchar_t* )mir_alloc( fullLen );
+ memcpy( *ucs2, tempBuf, fullLen );
+ }
+
+ WideCharToMultiByte( CP_ACP, 0, tempBuf, -1, str, len, NULL, NULL );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Utf8Encode - converts MBCS string to the UTF8-encoded format
+
+char* Utf8Encode( const char* src )
+{
+ int len;
+ char* result;
+ wchar_t* tempBuf;
+
+ if ( src == NULL )
+ return NULL;
+
+ len = strlen( src );
+ result = ( char* )mir_alloc( len*3 + 1 );
+ if ( result == NULL )
+ return NULL;
+
+ tempBuf = ( wchar_t* )alloca(( len+1 )*sizeof( wchar_t ));
+ MultiByteToWideChar( CP_ACP, 0, src, -1, tempBuf, len );
+ tempBuf[ len ] = 0;
+ {
+ wchar_t* s = tempBuf;
+ BYTE* d = ( BYTE* )result;
+
+ while( *s ) {
+ int U = *s++;
+
+ if ( U < 0x80 ) {
+ *d++ = ( BYTE )U;
+ }
+ else if ( U < 0x800 ) {
+ *d++ = 0xC0 + (( U >> 6 ) & 0x3F );
+ *d++ = 0x80 + ( U & 0x003F );
+ }
+ else {
+ *d++ = 0xE0 + ( U >> 12 );
+ *d++ = 0x80 + (( U >> 6 ) & 0x3F );
+ *d++ = 0x80 + ( U & 0x3F );
+ } }
+
+ *d = 0;
+ }
+
+ return result;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Utf8Encode - converts UCS2 string to the UTF8-encoded format
+
+char* Utf8EncodeUcs2( const wchar_t* src )
+{
+ int len = wcslen( src );
+ char* result = ( char* )mir_alloc( len*3 + 1 );
+ if ( result == NULL )
+ return NULL;
+
+ { const wchar_t* s = src;
+ BYTE* d = ( BYTE* )result;
+
+ while( *s ) {
+ int U = *s++;
+
+ if ( U < 0x80 ) {
+ *d++ = ( BYTE )U;
+ }
+ else if ( U < 0x800 ) {
+ *d++ = 0xC0 + (( U >> 6 ) & 0x3F );
+ *d++ = 0x80 + ( U & 0x003F );
+ }
+ else {
+ *d++ = 0xE0 + ( U >> 12 );
+ *d++ = 0x80 + (( U >> 6 ) & 0x3F );
+ *d++ = 0x80 + ( U & 0x3F );
+ } }
+
+ *d = 0;
+ }
+
+ return result;
+}
diff --git a/miranda-wine/plugins/png2dib/m_png.h b/miranda-wine/plugins/png2dib/m_png.h new file mode 100644 index 0000000..cd037ba --- /dev/null +++ b/miranda-wine/plugins/png2dib/m_png.h @@ -0,0 +1,64 @@ +/*
+Plugin of Miranda IM for reading/writing PNG images.
+Copyright (c) 2004-6 George Hazan (ghazan@postman.ru)
+
+Portions of this code are gotten from the libpng codebase.
+Copyright 2000, Willem van Schaik. For conditions of distribution and
+use, see the copyright/license/disclaimer notice in png.h
+
+Miranda IM: the free icq client for MS Windows
+Copyright (C) 2000-2002 Richard Hughes, Roland Rabien & Tristan Van de Vreede
+
+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.
+
+File name : $Source: /cvsroot/miranda/miranda/plugins/png2dib/m_png.h,v $
+Revision : $Revision: 3502 $
+Last change on : $Date: 2006-08-16 01:21:49 +0400 (Срд, 16 Ðвг 2006) $
+Last change by : $Author: ghazan $
+
+*/
+
+/* Image/Dib2Png
+Converts a Device Independent Bitmap to a png stored in memory
+ wParam=0
+ lParam=(WPARAM)(DIB2PNG*)descr
+*/
+
+typedef struct
+{
+ BITMAPINFO* pbmi;
+ BYTE* pDiData;
+ BYTE* pResult;
+ long* pResultLen;
+}
+ DIB2PNG;
+
+#define MS_DIB2PNG "Image/Dib2Png"
+
+/* Image/Png2Dib
+Converts a png stored in memory to a Device Independent Bitmap
+ wParam=0
+ lParam=(WPARAM)(PNG2DIB*)descr
+*/
+
+typedef struct
+{
+ BYTE* pSource;
+ DWORD cbSourceSize;
+ BITMAPINFOHEADER** pResult;
+}
+ PNG2DIB;
+
+#define MS_PNG2DIB "Image/Png2Dib"
diff --git a/miranda-wine/plugins/png2dib/png2dib.c b/miranda-wine/plugins/png2dib/png2dib.c new file mode 100644 index 0000000..5e531ef --- /dev/null +++ b/miranda-wine/plugins/png2dib/png2dib.c @@ -0,0 +1,411 @@ +/*
+Plugin of Miranda IM for reading/writing PNG images.
+Copyright (c) 2004-6 George Hazan (ghazan@postman.ru)
+
+Portions of this code are gotten from the libpng codebase.
+Copyright 2000, Willem van Schaik. For conditions of distribution and
+use, see the copyright/license/disclaimer notice in png.h
+
+Miranda IM: the free icq client for MS Windows
+Copyright (C) 2000-2002 Richard Hughes, Roland Rabien & Tristan Van de Vreede
+
+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.
+
+File name : $Source: /cvsroot/miranda/miranda/plugins/png2dib/png2dib.c,v $
+Revision : $Revision: 3502 $
+Last change on : $Date: 2006-08-16 01:21:49 +0400 (Срд, 16 Ðвг 2006) $
+Last change by : $Author: ghazan $
+
+*/
+
+#include <windows.h>
+#include <commdlg.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libpng/png.h"
+
+#include "newpluginapi.h"
+#include "version.h"
+#include "m_png.h"
+
+DWORD __declspec(dllexport) getver( void )
+{
+ return __VERSION_DWORD;
+}
+
+// PNG image handler functions
+
+typedef struct {
+ char* mBuffer;
+ size_t mBufSize;
+ size_t mBufPtr;
+}
+ HMemBufInfo;
+
+static void png_read_data( png_structp png_ptr, png_bytep data, png_size_t length )
+{
+ HMemBufInfo* io = ( HMemBufInfo* )png_ptr->io_ptr;
+ if ( length + io->mBufPtr > io->mBufSize )
+ length = io->mBufSize - io->mBufPtr;
+
+ if ( length > 0 ) {
+ memcpy( data, io->mBuffer + io->mBufPtr, length );
+ io->mBufPtr += length;
+ }
+ else png_error(png_ptr, "Read Error");
+}
+
+static void png_write_data( png_structp png_ptr, png_bytep data, png_size_t length )
+{
+ HMemBufInfo* io = ( HMemBufInfo* )png_ptr->io_ptr;
+ if ( io->mBuffer != NULL )
+ memcpy( io->mBuffer + io->mBufPtr, data, length );
+
+ io->mBufPtr += length;
+}
+
+static void png_flush( png_structp png_ptr )
+{
+}
+
+/*
+ * Converting a png image into a bitmap
+ */
+
+BOOL __declspec(dllexport) mempng2dib(
+ BYTE* pSource,
+ DWORD cbSourceSize,
+ BITMAPINFOHEADER** ppDibData )
+{
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ HMemBufInfo sBuffer = { pSource, cbSourceSize, 8 };
+
+ BOOL bResult = FALSE;
+ int iWidth;
+ int iHeight;
+ png_color pBkgColor;
+ int iBitDepth;
+ int iColorType;
+ double dGamma;
+ png_color_16* pBackground;
+ png_uint_32 ulChannels;
+ png_uint_32 ulRowBytes;
+ png_byte* pbImageData;
+ png_byte** ppbRowPointers = NULL;
+ int i;
+ int wDIRowBytes;
+ BYTE* pImageData;
+
+ *ppDibData = NULL;
+
+ if ( pSource == NULL || cbSourceSize == 0 )
+ return FALSE;
+
+ if ( !png_check_sig( pSource, 8 ))
+ return FALSE;
+
+ // create the two png(-info) structures
+ png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
+ if (!png_ptr)
+ return FALSE;
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if ( !info_ptr ) {
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ return FALSE;
+ }
+
+ // initialize the png structure
+ png_set_read_fn(png_ptr, (png_voidp)&sBuffer, png_read_data);
+ png_set_sig_bytes(png_ptr, 8);
+
+ // read all PNG info up to image data
+ png_read_info(png_ptr, info_ptr);
+
+ // get width, height, bit-depth and color-type
+
+ png_get_IHDR(png_ptr, info_ptr, &iWidth, &iHeight, &iBitDepth, &iColorType, NULL, NULL, NULL);
+
+ // expand images of all color-type and bit-depth to 3x8 bit RGB images
+ // let the library process things like alpha, transparency, background
+
+ if ( iBitDepth == 16 )
+ png_set_strip_16( png_ptr );
+ if ( iColorType == PNG_COLOR_TYPE_PALETTE )
+ png_set_expand( png_ptr );
+ if ( iBitDepth < 8 )
+ png_set_expand( png_ptr );
+ if (png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ))
+ png_set_expand( png_ptr );
+ if ( iColorType == PNG_COLOR_TYPE_GRAY || iColorType == PNG_COLOR_TYPE_GRAY_ALPHA )
+ png_set_gray_to_rgb( png_ptr );
+
+ // set the background color to draw transparent and alpha images over.
+ if (png_get_bKGD( png_ptr, info_ptr, &pBackground )) {
+ png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ pBkgColor.red = (byte) pBackground->red;
+ pBkgColor.green = (byte) pBackground->green;
+ pBkgColor.blue = (byte) pBackground->blue;
+ }
+
+ // if required set gamma conversion
+ if ( png_get_gAMA( png_ptr, info_ptr, &dGamma ))
+ png_set_gamma( png_ptr, (double) 2.2, dGamma );
+
+ // after the transformations have been registered update info_ptr data
+ png_read_update_info(png_ptr, info_ptr);
+
+ // get again width, height and the new bit-depth and color-type
+ png_get_IHDR(png_ptr, info_ptr, &iWidth, &iHeight, &iBitDepth, &iColorType, NULL, NULL, NULL);
+
+ // row_bytes is the width x number of channels
+ ulRowBytes = png_get_rowbytes(png_ptr, info_ptr);
+ ulChannels = png_get_channels(png_ptr, info_ptr);
+ wDIRowBytes = (WORD) (( ulChannels * iWidth + 3L) >> 2) << 2;
+
+ // now we can allocate memory to store the image
+ { DWORD cbMemSize = sizeof( BITMAPINFOHEADER );
+ cbMemSize += wDIRowBytes * iHeight;
+ if (( pbImageData = ( png_byte* )GlobalAlloc( LPTR, cbMemSize )) == NULL ) {
+ png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
+ return FALSE;
+ } }
+
+ // initialize the dib-structure
+ { BITMAPINFOHEADER* pbmih = ( BITMAPINFOHEADER* )pbImageData;
+ *ppDibData = pbmih;
+
+ pbmih->biSize = sizeof( BITMAPINFOHEADER );
+ pbmih->biWidth = iWidth;
+ pbmih->biHeight = iHeight;
+ pbmih->biPlanes = 1;
+ pbmih->biBitCount = ulChannels * 8;
+ pbmih->biCompression = 0;
+ pbmih->biSizeImage = iWidth * iHeight * ulChannels;
+
+ pbImageData += sizeof( BITMAPINFOHEADER );
+ }
+
+ pImageData = (BYTE*)malloc( ulRowBytes * iHeight );
+ if ( pImageData == NULL ) {
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ return FALSE;
+ }
+
+ // and allocate memory for an array of row-pointers
+ ppbRowPointers = ( png_bytepp )alloca( iHeight * sizeof( png_bytep ));
+
+ // set the individual row-pointers to point at the correct offsets
+ for ( i = 0; i < iHeight; i++ )
+ ppbRowPointers[i] = ( png_bytep )&pImageData[ i*ulRowBytes ];
+
+ // now we can go ahead and just read the whole image
+ png_read_image( png_ptr, ppbRowPointers );
+ png_read_end(png_ptr, NULL);
+
+ // repack bytes to fill the bitmap
+ for ( i = iHeight-1; i >= 0; i-- )
+ {
+ int j;
+ png_byte a;
+ png_bytep s = ppbRowPointers[i];
+ BYTE* dest = pbImageData; pbImageData += wDIRowBytes;
+
+ for ( j = 0; j < iWidth; j++ ) {
+ png_byte r = *s++;
+ png_byte g = *s++;
+ png_byte b = *s++;
+ if ( ulChannels == 4 )
+ a = *s++;
+
+ *dest++ = b;
+ *dest++ = g;
+ *dest++ = r;
+ if ( ulChannels == 4 )
+ *dest++ = a;
+ } }
+
+ free( pImageData );
+ png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
+ return TRUE;
+}
+
+/*
+ * Converting a bitmap into a png image
+ */
+
+BOOL __declspec(dllexport) dib2mempng( BITMAPINFO* pbmi, png_byte* pDiData, BYTE* pResult, long* pResultLen )
+{
+ int ciBitDepth = 8;
+ int ciChannels = pbmi->bmiHeader.biBitCount / 8;
+
+ png_uint_32 ulSrcRowBytes, ulDstRowBytes;
+ int i;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_bytepp ppbRowPointers;
+ png_bytep pTempBuffer;
+
+ HMemBufInfo sBuffer = { pResult, 0, 0 };
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)NULL, (png_error_ptr)NULL);
+ if (!png_ptr)
+ return FALSE;
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+ return FALSE;
+ }
+
+ // initialize the png structure
+ png_set_write_fn(png_ptr, (png_voidp)&sBuffer, png_write_data, png_flush);
+
+ png_set_IHDR(png_ptr, info_ptr, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, ciBitDepth,
+ PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ // write the file header information
+ png_write_info(png_ptr, info_ptr);
+
+ // swap the BGR pixels in the DiData structure to RGB
+ png_set_bgr(png_ptr);
+
+ // row_bytes is the width x number of channels
+ ulSrcRowBytes = ((( pbmi->bmiHeader.biWidth * ciChannels + 3 ) >> 2 ) << 2 );
+ ulDstRowBytes = ((( pbmi->bmiHeader.biWidth * 3 + 3 ) >> 2 ) << 2 );
+
+ ppbRowPointers = (png_bytepp)alloca( pbmi->bmiHeader.biHeight * sizeof(png_bytep));
+
+ pTempBuffer = ( png_bytep )malloc( pbmi->bmiHeader.biHeight * ulDstRowBytes );
+ if ( pTempBuffer != NULL ) {
+ png_bytep pDest = pTempBuffer;
+ for ( i = pbmi->bmiHeader.biHeight-1; i >= 0; i--) {
+ BYTE *s, *d;
+ int j;
+ s = pDiData; pDiData += ulSrcRowBytes;
+ d = ppbRowPointers[i] = pDest; pDest += ulDstRowBytes;
+
+ if ( ciChannels >= 3 ) {
+ for ( j = 0; j < pbmi->bmiHeader.biWidth; j++ ) {
+ png_byte b = *s++;
+ png_byte g = *s++;
+ png_byte r = *s++;
+ png_byte a = 0;
+
+ if ( ciChannels == 4 )
+ a = *s++;
+
+ *d++ = b;
+ *d++ = g;
+ *d++ = r;
+ } }
+ else {
+ for ( j = 0; j < pbmi->bmiHeader.biWidth; j++ ) {
+ DWORD point;
+ if ( ciChannels == 1 ) {
+ *d++ = ( BYTE )( point & 0x03 ) << 6;
+ *d++ = ( BYTE )(( point & 0x0C ) >> 2 ) << 6;
+ *d++ = ( BYTE )(( point & 0x30 ) >> 4 ) << 6;
+ point = *s++;
+ }
+ else {
+ point = *( WORD* )s;
+ s += sizeof( WORD );
+ *d++ = ( BYTE )(( point & 0x001F ) << 3 );
+ *d++ = ( BYTE )((( point & 0x07e0 ) >> 6 ) << 3 );
+ *d++ = ( BYTE )((( point & 0xF800 ) >> 11 ) << 3 );
+ } } } }
+
+ png_write_image (png_ptr, ppbRowPointers);
+ png_write_end(png_ptr, info_ptr);
+
+ if ( pResultLen != NULL )
+ *pResultLen = sBuffer.mBufPtr;
+
+ free( pTempBuffer );
+ }
+
+ png_destroy_write_struct(&png_ptr, &info_ptr );
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Standard Miranda structures & functions
+
+HINSTANCE hInst = NULL;
+PLUGINLINK *pluginLink;
+
+static HANDLE hDib2mempng = NULL;
+static HANDLE hMempng2Dib = NULL;
+
+PLUGININFO pluginInfo = {
+ sizeof( PLUGININFO ),
+ "PNG images processor",
+ __VERSION_DWORD,
+ "png2dib plugin for Miranda IM ( "__DATE__" )",
+ "George Hazan",
+ "ghazan@miranda-im.org",
+ "(c) 2004-06 George Hazan",
+ "http://addons.miranda-im.org/details.php?action=viewfile&id=1420",
+ 0,
+ 0
+};
+
+__declspec( dllexport ) PLUGININFO* MirandaPluginInfo( DWORD mirandaVersion )
+{
+ if ( mirandaVersion < PLUGIN_MAKE_VERSION( 0,4,3,0 )) {
+ MessageBox( NULL, "The png2dib plugin cannot be loaded. It requires Miranda IM 0.5 or later.", "png2dib Plugin", MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST );
+ return NULL;
+ }
+
+ return &pluginInfo;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Load - initializes the plugin instance
+
+static int serviceDib2Png( WPARAM wParam, LPARAM lParam )
+{
+ DIB2PNG* param = ( DIB2PNG* )lParam;
+ return dib2mempng( param->pbmi, param->pDiData, param->pResult, param->pResultLen );
+}
+
+static int servicePng2Dib( WPARAM wParam, LPARAM lParam )
+{
+ PNG2DIB* param = ( PNG2DIB* )lParam;
+ return mempng2dib( param->pSource, param->cbSourceSize, param->pResult );
+}
+
+int __declspec( dllexport ) Load( PLUGINLINK *link )
+{
+ pluginLink = link;
+
+ hDib2mempng = CreateServiceFunction( MS_DIB2PNG, serviceDib2Png );
+ hMempng2Dib = CreateServiceFunction( MS_PNG2DIB, servicePng2Dib );
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Unload - destroys the plugin instance
+
+int __declspec( dllexport ) Unload( void )
+{
+ DestroyServiceFunction( hDib2mempng );
+ DestroyServiceFunction( hMempng2Dib );
+ return 0;
+}
diff --git a/miranda-wine/plugins/png2dib/version.h b/miranda-wine/plugins/png2dib/version.h new file mode 100644 index 0000000..d21c408 --- /dev/null +++ b/miranda-wine/plugins/png2dib/version.h @@ -0,0 +1,3 @@ +#define __FILEVERSION_STRING 0,1,3,1
+#define __VERSION_STRING "0.1.3.1"
+#define __VERSION_DWORD 0x00010301
diff --git a/miranda-wine/plugins/png2dib/version.rc b/miranda-wine/plugins/png2dib/version.rc new file mode 100644 index 0000000..e9f49ed --- /dev/null +++ b/miranda-wine/plugins/png2dib/version.rc @@ -0,0 +1,36 @@ +
+#include <windows.h>
+#include "version.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", " "
+ VALUE "FileDescription", "Miranda png2dib plugin"
+ VALUE "FileVersion", __VERSION_STRING
+ VALUE "InternalName", "png2dib"
+ VALUE "LegalCopyright", "Copyright c 2004-2006 George Hazan"
+ VALUE "OriginalFilename", "png2dib.dll"
+ VALUE "ProductName", "Miranda"
+ VALUE "ProductVersion", __VERSION_STRING
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/miranda-wine/plugins/srmm/cmdlist.c b/miranda-wine/plugins/srmm/cmdlist.c new file mode 100644 index 0000000..4897751 --- /dev/null +++ b/miranda-wine/plugins/srmm/cmdlist.c @@ -0,0 +1,124 @@ +/*
+SRMM
+
+Copyright 2000-2005 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "commonheaders.h"
+
+static unsigned long tcmdlist_hash(const CMDCHAR *data) {
+ unsigned long hash = 0;
+ int i, shift = 0;
+
+ for(i=0; data[i]; i++) {
+ hash ^= data[i]<<shift;
+ if(shift>24) hash ^= (data[i]>>(32-shift))&0x7F;
+ shift = (shift+5)&0x1F;
+ }
+ return hash;
+}
+
+TCmdList *tcmdlist_append(TCmdList *list, CMDCHAR *data) {
+ TCmdList *n;
+ TCmdList *new_list = malloc(sizeof(TCmdList));
+ TCmdList *attach_to = NULL;
+
+ if (!data) {
+ free(new_list);
+ return list;
+ }
+ new_list->next = NULL;
+#ifdef _UNICODE
+ new_list->szCmd = _tcsdup(data);
+#else
+ new_list->szCmd = _strdup(data);
+#endif
+ new_list->hash = tcmdlist_hash(data);
+ for (n=list; n!=NULL; n=n->next) {
+ attach_to = n;
+ }
+ if (attach_to==NULL) {
+ new_list->prev = NULL;
+ return new_list;
+ }
+ else {
+ new_list->prev = attach_to;
+ attach_to->next = new_list;
+ if (tcmdlist_len(list)>20) {
+ list = tcmdlist_remove(list, list->szCmd);
+ }
+ return list;
+ }
+}
+
+TCmdList *tcmdlist_remove(TCmdList *list, CMDCHAR *data) {
+ TCmdList *n;
+ unsigned long hash;
+
+ if (!data) return list;
+ hash = tcmdlist_hash(data);
+ for (n=list; n!=NULL; n=n->next) {
+#ifdef _UNICODE
+ if (n->hash==hash&&!_tcscmp(n->szCmd, data)) {
+#else
+ if (n->hash==hash&&!strcmp(n->szCmd, data)) {
+#endif
+ if (n->next) n->next->prev = n->prev;
+ if (n->prev) n->prev->next = n->next;
+ if (n==list) list = n->next;
+ free(n->szCmd);
+ free(n);
+ return list;
+ }
+ }
+ return list;
+}
+
+int tcmdlist_len(TCmdList *list) {
+ TCmdList *n;
+ int i = 0;
+
+ for (n=list; n!=NULL; n=n->next) {
+ i++;
+ }
+ return i;
+}
+
+TCmdList *tcmdlist_last(TCmdList *list) {
+ TCmdList *n;
+
+ for (n=list; n!=NULL; n=n->next) {
+ if (!n->next)
+ return n;
+ }
+ return NULL;
+}
+
+void tcmdlist_free(TCmdList *list) {
+ TCmdList *n = list, *next;
+
+ while (n!=NULL) {
+ next = n->next;
+ free(n->szCmd);
+ free(n);
+ n = next;
+ }
+}
diff --git a/miranda-wine/plugins/srmm/cmdlist.h b/miranda-wine/plugins/srmm/cmdlist.h new file mode 100644 index 0000000..54b057a --- /dev/null +++ b/miranda-wine/plugins/srmm/cmdlist.h @@ -0,0 +1,48 @@ +/*
+SRMM
+
+Copyright 2000-2005 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.
+*/
+#ifndef SRMM_CMDLIST_H
+#define SRMM_CMDLIST_H
+
+#ifdef _UNICODE
+ #define CMDCHAR TCHAR
+#else
+ #define CMDCHAR char
+#endif
+
+typedef struct _TCmdList {
+ struct _TCmdList *next;
+ struct _TCmdList *prev;
+#ifdef _UNICODE
+ wchar_t *szCmd;
+#else
+ char *szCmd;
+#endif
+ unsigned long hash;
+} TCmdList;
+
+TCmdList *tcmdlist_append(TCmdList *list, CMDCHAR *data);
+TCmdList *tcmdlist_remove(TCmdList *list, CMDCHAR *data);
+int tcmdlist_len(TCmdList *list);
+TCmdList *tcmdlist_last(TCmdList *list);
+void tcmdlist_free(TCmdList * list);
+
+#endif
diff --git a/miranda-wine/plugins/srmm/commonheaders.h b/miranda-wine/plugins/srmm/commonheaders.h new file mode 100644 index 0000000..4236248 --- /dev/null +++ b/miranda-wine/plugins/srmm/commonheaders.h @@ -0,0 +1,57 @@ +/*
+SRMM
+
+Copyright 2000-2005 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.
+*/
+
+#if defined(UNICODE) && !defined(_UNICODE)
+ #define _UNICODE
+#endif
+#include <tchar.h>
+#define _WIN32_WINNT 0x0501
+#include <windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <time.h>
+#include <stddef.h>
+#include <process.h>
+#include "resource.h"
+#include <win2k.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_database.h>
+#include <m_langpack.h>
+#include <m_button.h>
+#include <m_clist.h>
+#include <m_clc.h>
+#include <m_clui.h>
+#include <m_options.h>
+#include <m_protosvc.h>
+#include <m_utils.h>
+#include <m_skin.h>
+#include <m_contacts.h>
+#include <m_userinfo.h>
+#include <m_history.h>
+#include <m_addcontact.h>
+#include <m_message.h>
+#include <m_file.h>
+#include "cmdlist.h"
+#include "msgs.h"
+#include "globals.h"
+#include "richutil.h"
diff --git a/miranda-wine/plugins/srmm/globals.c b/miranda-wine/plugins/srmm/globals.c new file mode 100644 index 0000000..3247e1a --- /dev/null +++ b/miranda-wine/plugins/srmm/globals.c @@ -0,0 +1,107 @@ +/*
+SRMM
+
+Copyright 2000-2005 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"
+
+struct GlobalMessageData *g_dat=NULL;
+extern HINSTANCE g_hInst;
+static HANDLE g_hDbEvent = 0, g_hAck = 0;
+static int dbaddedevent(WPARAM wParam, LPARAM lParam);
+static int ackevent(WPARAM wParam, LPARAM lParam);
+
+void InitGlobals() {
+ g_dat = (struct GlobalMessageData *)malloc(sizeof(struct GlobalMessageData));
+ g_dat->hMessageWindowList = (HANDLE) CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0);
+ g_hDbEvent = HookEvent(ME_DB_EVENT_ADDED, dbaddedevent);
+ g_hAck = HookEvent(ME_PROTO_ACK, ackevent);
+ ReloadGlobals();
+ g_dat->hIcons[SMF_ICON_ADD] = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(IDI_ADDCONTACT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+ g_dat->hIcons[SMF_ICON_USERDETAIL] = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(IDI_USERDETAILS), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+ g_dat->hIcons[SMF_ICON_HISTORY] = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(IDI_HISTORY), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+ g_dat->hIcons[SMF_ICON_ARROW] = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(IDI_DOWNARROW), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+ g_dat->hIcons[SMF_ICON_TYPING] = (HICON) LoadImage(g_hInst, MAKEINTRESOURCE(IDI_TYPING), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+}
+
+void FreeGlobals() {
+ int i;
+
+ if (g_dat) {
+ for (i=0; i < SIZEOF(g_dat->hIcons); i++)
+ DestroyIcon(g_dat->hIcons[i]);
+ free(g_dat);
+ }
+ if (g_hDbEvent) UnhookEvent(g_hDbEvent);
+ if (g_hAck) UnhookEvent(g_hAck);
+}
+
+void ReloadGlobals() {
+ g_dat->flags = 0;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWINFOLINE, SRMSGDEFSET_SHOWINFOLINE))
+ g_dat->flags |= SMF_SHOWINFO;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWBUTTONLINE, SRMSGDEFSET_SHOWBUTTONLINE))
+ g_dat->flags |= SMF_SHOWBTNS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDBUTTON, SRMSGDEFSET_SENDBUTTON))
+ g_dat->flags |= SMF_SENDBTN;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPING, SRMSGDEFSET_SHOWTYPING))
+ g_dat->flags |= SMF_SHOWTYPING;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGWIN, SRMSGDEFSET_SHOWTYPINGWIN))
+ g_dat->flags |= SMF_SHOWTYPINGWIN;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGNOWIN, SRMSGDEFSET_SHOWTYPINGNOWIN))
+ g_dat->flags |= SMF_SHOWTYPINGTRAY;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGCLIST, SRMSGDEFSET_SHOWTYPINGCLIST))
+ g_dat->flags |= SMF_SHOWTYPINGCLIST;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWLOGICONS, SRMSGDEFSET_SHOWLOGICONS))
+ g_dat->flags |= SMF_SHOWICONS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTIME, SRMSGDEFSET_SHOWTIME))
+ g_dat->flags |= SMF_SHOWTIME;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AVATARENABLE, SRMSGDEFSET_AVATARENABLE))
+ g_dat->flags |= SMF_AVATAR;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWDATE, SRMSGDEFSET_SHOWDATE))
+ g_dat->flags |= SMF_SHOWDATE;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSECS, SRMSGDEFSET_SHOWSECS))
+ g_dat->flags |= SMF_SHOWSECS;
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDENAMES, SRMSGDEFSET_HIDENAMES))
+ g_dat->flags |= SMF_HIDENAMES;
+ g_dat->openFlags = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_POPFLAGS, SRMSGDEFSET_POPFLAGS);
+}
+
+static int dbaddedevent(WPARAM wParam, LPARAM lParam) {
+ if (wParam) {
+ HWND h = WindowList_Find(g_dat->hMessageWindowList, (HANDLE)wParam);
+ if(h) SendMessage(h, HM_DBEVENTADDED, wParam, lParam);
+ }
+ return 0;
+}
+
+static int ackevent(WPARAM wParam, LPARAM lParam) {
+ ACKDATA *pAck = (ACKDATA *)lParam;
+
+ if (!pAck) return 0;
+ else if (pAck->type==ACKTYPE_AVATAR) {
+ HWND h = WindowList_Find(g_dat->hMessageWindowList, (HANDLE)pAck->hContact);
+ if(h) SendMessage(h, HM_AVATARACK, wParam, lParam);
+ }
+ else if (pAck->type==ACKTYPE_MESSAGE) {
+ HWND h = WindowList_Find(g_dat->hMessageWindowList, (HANDLE)pAck->hContact);
+ if(h) SendMessage(h, HM_EVENTSENT, wParam, lParam);
+ }
+ return 0;
+}
diff --git a/miranda-wine/plugins/srmm/globals.h b/miranda-wine/plugins/srmm/globals.h new file mode 100644 index 0000000..12723fa --- /dev/null +++ b/miranda-wine/plugins/srmm/globals.h @@ -0,0 +1,59 @@ +/*
+SRMM
+
+Copyright 2000-2005 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.
+*/
+#ifndef SRMM_GLOBALS_H
+#define SRMM_GLOBALS_H
+
+#define SMF_SHOWINFO 0x00000001
+#define SMF_SHOWBTNS 0x00000002
+#define SMF_SENDBTN 0x00000004
+#define SMF_SHOWTYPING 0x00000008
+#define SMF_SHOWTYPINGWIN 0x00000010
+#define SMF_SHOWTYPINGTRAY 0x00000020
+#define SMF_SHOWTYPINGCLIST 0x00000040
+#define SMF_SHOWICONS 0x00000080
+#define SMF_SHOWTIME 0x00000100
+#define SMF_AVATAR 0x00000200
+#define SMF_SHOWDATE 0x00000400
+#define SMF_HIDENAMES 0x00000800
+#define SMF_SHOWSECS 0x00001000
+
+#define SMF_ICON_ADD 0
+#define SMF_ICON_USERDETAIL 1
+#define SMF_ICON_HISTORY 2
+#define SMF_ICON_ARROW 3
+#define SMF_ICON_TYPING 4
+
+struct GlobalMessageData
+{
+ unsigned int flags;
+ HICON hIcons[5];
+ HANDLE hMessageWindowList;
+ DWORD openFlags;
+};
+
+void InitGlobals();
+void FreeGlobals();
+void ReloadGlobals();
+
+extern struct GlobalMessageData *g_dat;
+
+#endif
diff --git a/miranda-wine/plugins/srmm/msgdialog.c b/miranda-wine/plugins/srmm/msgdialog.c new file mode 100644 index 0000000..0d8085e --- /dev/null +++ b/miranda-wine/plugins/srmm/msgdialog.c @@ -0,0 +1,1859 @@ +/*
+SRMM
+
+Copyright 2000-2005 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 _USE_32BIT_TIME_T
+
+#include "commonheaders.h"
+#pragma hdrstop
+
+#include <malloc.h>
+
+#define TIMERID_MSGSEND 0
+#define TIMERID_FLASHWND 1
+#define TIMERID_TYPE 2
+#define TIMEOUT_FLASHWND 900
+#define TIMEOUT_TYPEOFF 10000 //send type off after 10 seconds of inactivity
+#define SB_CHAR_WIDTH 45;
+#define VALID_AVATAR(x) (x==PA_FORMAT_PNG||x==PA_FORMAT_JPEG||x==PA_FORMAT_ICON||x==PA_FORMAT_BMP||x==PA_FORMAT_GIF)
+
+#if defined(_UNICODE)
+ #define SEND_FLAGS PREF_UNICODE
+#else
+ #define SEND_FLAGS 0
+#endif
+
+extern HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand;
+extern HANDLE hHookWinEvt;
+extern struct CREOleCallback reOleCallback;
+extern HINSTANCE g_hInst;
+
+static void UpdateReadChars(HWND hwndDlg, HWND hwndStatus);
+
+static WNDPROC OldMessageEditProc, OldSplitterProc;
+static const UINT infoLineControls[] = { IDC_PROTOCOL, IDC_NAME };
+static const UINT buttonLineControls[] = { IDC_ADD, IDC_USERMENU, IDC_DETAILS, IDC_HISTORY };
+static const UINT sendControls[] = { IDC_MESSAGE };
+
+static void NotifyLocalWinEvent(HANDLE hContact, HWND hwnd, unsigned int type) {
+ MessageWindowEventData mwe = { 0 };
+
+ if (hContact==NULL || hwnd==NULL) return;
+ mwe.cbSize = sizeof(mwe);
+ mwe.hContact = hContact;
+ mwe.hwndWindow = hwnd;
+ mwe.szModule = SRMMMOD;
+ mwe.uType = type;
+ mwe.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+ NotifyEventHooks(hHookWinEvt, 0, (LPARAM)&mwe);
+}
+
+static char *MsgServiceName(HANDLE hContact)
+{
+#ifdef _UNICODE
+ char szServiceName[100];
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto == NULL)
+ return PSS_MESSAGE;
+
+ mir_snprintf(szServiceName, SIZEOF(szServiceName), "%s%sW", szProto, PSS_MESSAGE);
+ if (ServiceExists(szServiceName))
+ return PSS_MESSAGE "W";
+#endif
+ return PSS_MESSAGE;
+}
+
+#if defined(_UNICODE)
+static int RTL_Detect(WCHAR *pszwText)
+{
+ WORD *infoTypeC2;
+ int i;
+ int iLen = lstrlenW(pszwText);
+
+ infoTypeC2 = (WORD *)malloc(sizeof(WORD) * (iLen + 2));
+
+ if(infoTypeC2) {
+ ZeroMemory(infoTypeC2, sizeof(WORD) * (iLen + 2));
+
+ GetStringTypeW(CT_CTYPE2, pszwText, iLen, infoTypeC2);
+
+ for(i = 0; i < iLen; i++) {
+ if(infoTypeC2[i] == C2_RIGHTTOLEFT) {
+ free(infoTypeC2);
+ //_DebugTraceA("RTL text found");
+ return 1;
+ }
+ }
+ free(infoTypeC2);
+ //_DebugTraceA("NO RTL text detected");
+ }
+ return 0;
+}
+#endif
+
+// mod from tabsrmm
+static void AddToFileList(char ***pppFiles,int *totalCount,const char *szFilename) {
+ *pppFiles=(char**)realloc(*pppFiles,(++*totalCount+1)*sizeof(char*));
+ (*pppFiles)[*totalCount]=NULL;
+ (*pppFiles)[*totalCount-1]=_strdup(szFilename);
+ if(GetFileAttributesA(szFilename)&FILE_ATTRIBUTE_DIRECTORY) {
+ WIN32_FIND_DATAA fd;
+ HANDLE hFind;
+ char szPath[MAX_PATH];
+ lstrcpyA(szPath,szFilename);
+ lstrcatA(szPath,"\\*");
+ if(hFind=FindFirstFileA(szPath,&fd)) {
+ do {
+ if(!lstrcmpA(fd.cFileName,".") || !lstrcmpA(fd.cFileName,"..")) continue;
+ lstrcpyA(szPath,szFilename);
+ lstrcatA(szPath,"\\");
+ lstrcatA(szPath,fd.cFileName);
+ AddToFileList(pppFiles,totalCount,szPath);
+ } while(FindNextFileA(hFind,&fd));
+ FindClose(hFind);
+ }
+ }
+}
+
+static void ShowMultipleControls(HWND hwndDlg, const UINT * controls, int cControls, int state)
+{
+ int i;
+ for (i = 0; i < cControls; i++)
+ ShowWindow(GetDlgItem(hwndDlg, controls[i]), state);
+}
+
+static void SetDialogToType(HWND hwndDlg)
+{
+ struct MessageWindowData *dat;
+ WINDOWPLACEMENT pl = { 0 };
+
+ dat = (struct MessageWindowData *) GetWindowLong(hwndDlg, GWL_USERDATA);
+ if (dat->hContact) {
+ ShowMultipleControls(hwndDlg, infoLineControls, SIZEOF(infoLineControls), (g_dat->flags&SMF_SHOWINFO) ? SW_SHOW : SW_HIDE);
+ }
+ else
+ ShowMultipleControls(hwndDlg, infoLineControls, SIZEOF(infoLineControls), SW_HIDE);
+ if (dat->hContact) {
+ ShowMultipleControls(hwndDlg, buttonLineControls, SIZEOF(buttonLineControls), (g_dat->flags&SMF_SHOWBTNS) ? SW_SHOW : SW_HIDE);
+ if (!DBGetContactSettingByte(dat->hContact, "CList", "NotOnList", 0))
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), SW_HIDE);
+ }
+ else {
+ ShowMultipleControls(hwndDlg, buttonLineControls, SIZEOF(buttonLineControls), SW_HIDE);
+ }
+ ShowMultipleControls(hwndDlg, sendControls, SIZEOF(sendControls), SW_SHOW);
+ if (!dat->hwndStatus) {
+ dat->hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL);
+ SendMessage(dat->hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0);
+ }
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CHARCOUNT, SRMSGDEFSET_CHARCOUNT)) {
+ RECT rc;
+ int statwidths[2];
+
+ GetWindowRect(dat->hwndStatus, &rc);
+ statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH;
+ statwidths[1] = -1;
+ SendMessage(dat->hwndStatus, SB_SETPARTS, 2, (LPARAM) statwidths);
+ }
+ else {
+ int statwidths[] = { -1 };
+
+ SendMessage(dat->hwndStatus, SB_SETPARTS, 1, (LPARAM) statwidths);
+ }
+ UpdateReadChars(hwndDlg, dat->hwndStatus);
+ ShowWindow(GetDlgItem(hwndDlg, IDCANCEL), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_SPLITTER), SW_SHOW);
+ ShowWindow(GetDlgItem(hwndDlg, IDOK), (g_dat->flags&SMF_SENDBTN) ? SW_SHOW : SW_HIDE);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE))?TRUE:FALSE);
+ if (dat->avatarPic==0||!(g_dat->flags&SMF_AVATAR))
+ ShowWindow(GetDlgItem(hwndDlg, IDC_AVATAR), SW_HIDE);
+ SendMessage(hwndDlg, DM_UPDATETITLE, 0, 0);
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ pl.length = sizeof(pl);
+ GetWindowPlacement(hwndDlg, &pl);
+ if (!IsWindowVisible(hwndDlg))
+ pl.showCmd = SW_HIDE;
+ SetWindowPlacement(hwndDlg, &pl); //in case size is smaller than new minimum
+}
+
+struct SavedMessageData
+{
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+ DWORD keyStates; //use MOD_ defines from RegisterHotKey()
+};
+
+struct MsgEditSubclassData
+{
+ DWORD lastEnterTime;
+ struct SavedMessageData *keyboardMsgQueue;
+ int msgQueueCount;
+};
+
+static void SaveKeyboardMessage(struct MsgEditSubclassData *dat, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ dat->keyboardMsgQueue = (struct SavedMessageData *) realloc(dat->keyboardMsgQueue, sizeof(struct SavedMessageData) * (dat->msgQueueCount + 1));
+ dat->keyboardMsgQueue[dat->msgQueueCount].message = message;
+ dat->keyboardMsgQueue[dat->msgQueueCount].wParam = wParam;
+ dat->keyboardMsgQueue[dat->msgQueueCount].lParam = lParam;
+ dat->keyboardMsgQueue[dat->msgQueueCount].keyStates = (GetKeyState(VK_SHIFT) & 0x8000 ? MOD_SHIFT : 0) | (GetKeyState(VK_CONTROL) & 0x8000 ? MOD_CONTROL : 0) | (GetKeyState(VK_MENU) & 0x8000 ? MOD_ALT : 0);
+ dat->msgQueueCount++;
+}
+
+#define EM_REPLAYSAVEDKEYSTROKES (WM_USER+0x100)
+#define EM_SUBCLASSED (WM_USER+0x101)
+#define EM_UNSUBCLASSED (WM_USER+0x102)
+#define ENTERCLICKTIME 1000 //max time in ms during which a double-tap on enter will cause a send
+#define EDITMSGQUEUE_PASSTHRUCLIPBOARD //if set the typing queue won't capture ctrl-C etc because people might want to use them on the read only text
+ //todo: decide if this should be set or not
+static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct MsgEditSubclassData *dat;
+ struct MessageWindowData *pdat;
+
+ pdat=(struct MessageWindowData *)GetWindowLong(GetParent(hwnd),GWL_USERDATA);
+ dat = (struct MsgEditSubclassData *) GetWindowLong(hwnd, GWL_USERDATA);
+ switch (msg) {
+ case WM_DROPFILES:
+ SendMessage(GetParent(hwnd), WM_DROPFILES, (WPARAM)wParam, (LPARAM)lParam);
+ break;
+ case EM_SUBCLASSED:
+ dat = (struct MsgEditSubclassData *) malloc(sizeof(struct MsgEditSubclassData));
+ SetWindowLong(hwnd, GWL_USERDATA, (LONG) dat);
+ dat->lastEnterTime = 0;
+ dat->keyboardMsgQueue = NULL;
+ dat->msgQueueCount = 0;
+ return 0;
+ case EM_SETREADONLY:
+ if (wParam) {
+ if (dat->keyboardMsgQueue)
+ free(dat->keyboardMsgQueue);
+ dat->keyboardMsgQueue = NULL;
+ dat->msgQueueCount = 0;
+ }
+ break;
+ case EM_REPLAYSAVEDKEYSTROKES:
+ {
+ int i;
+ BYTE keyStateArray[256], originalKeyStateArray[256];
+ MSG msg;
+
+ while (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ GetKeyboardState(originalKeyStateArray);
+ GetKeyboardState(keyStateArray);
+ for (i = 0; i < dat->msgQueueCount; i++) {
+ keyStateArray[VK_SHIFT] = dat->keyboardMsgQueue[i].keyStates & MOD_SHIFT ? 0x80 : 0;
+ keyStateArray[VK_CONTROL] = dat->keyboardMsgQueue[i].keyStates & MOD_CONTROL ? 0x80 : 0;
+ keyStateArray[VK_MENU] = dat->keyboardMsgQueue[i].keyStates & MOD_ALT ? 0x80 : 0;
+ SetKeyboardState(keyStateArray);
+ PostMessage(hwnd, dat->keyboardMsgQueue[i].message, dat->keyboardMsgQueue[i].wParam, dat->keyboardMsgQueue[i].lParam);
+ while (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ if (dat->keyboardMsgQueue)
+ free(dat->keyboardMsgQueue);
+ dat->keyboardMsgQueue = NULL;
+ dat->msgQueueCount = 0;
+ SetKeyboardState(originalKeyStateArray);
+ return 0;
+ }
+ case WM_CHAR:
+ if (GetWindowLong(hwnd, GWL_STYLE) & ES_READONLY)
+ break;
+ //for saved msg queue the keyup/keydowns generate wm_chars themselves
+ if (wParam == '\n' || wParam == '\r') {
+ if (((GetKeyState(VK_CONTROL) & 0x8000) != 0) ^ (0 != DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER))) {
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER)) {
+ if (dat->lastEnterTime + ENTERCLICKTIME < GetTickCount())
+ dat->lastEnterTime = GetTickCount();
+ else {
+ SendMessage(hwnd, WM_CHAR, '\b', 0);
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ }
+ }
+ else
+ dat->lastEnterTime = 0;
+ if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) { //ctrl-a
+ SendMessage(hwnd, EM_SETSEL, 0, -1);
+ return 0;
+ }
+ if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w
+ SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0);
+ return 0;
+ }
+ if (wParam == 127 && GetKeyState(VK_CONTROL) & 0x8000) { //ctrl-backspace
+ DWORD start, end;
+ TCHAR *text;
+ int textLen;
+ SendMessage(hwnd, EM_GETSEL, (WPARAM) & end, (LPARAM) (PDWORD) NULL);
+ SendMessage(hwnd, WM_KEYDOWN, VK_LEFT, 0);
+ SendMessage(hwnd, EM_GETSEL, (WPARAM) & start, (LPARAM) (PDWORD) NULL);
+ textLen = GetWindowTextLength(hwnd);
+ text = (TCHAR *) malloc(sizeof(TCHAR) * (textLen + 1));
+ GetWindowText(hwnd, text, textLen + 1);
+ MoveMemory(text + start, text + end, sizeof(TCHAR) * (textLen + 1 - end));
+ SetWindowText(hwnd, text);
+ free(text);
+ SendMessage(hwnd, EM_SETSEL, start, start);
+ SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), EN_CHANGE), (LPARAM) hwnd);
+ return 0;
+ }
+ break;
+ case WM_KEYUP:
+ if (GetWindowLong(hwnd, GWL_STYLE) & ES_READONLY) {
+ int i;
+ //mustn't allow keyups for which there is no keydown
+ for (i = 0; i < dat->msgQueueCount; i++)
+ if (dat->keyboardMsgQueue[i].message == WM_KEYDOWN && dat->keyboardMsgQueue[i].wParam == wParam)
+ break;
+ if (i == dat->msgQueueCount)
+ break;
+ #ifdef EDITMSGQUEUE_PASSTHRUCLIPBOARD
+ if (GetKeyState(VK_CONTROL) & 0x8000) {
+ if (wParam == 'X' || wParam == 'C' || wParam == 'V' || wParam == VK_INSERT)
+ break;
+ }
+ if (GetKeyState(VK_SHIFT) & 0x8000) {
+ if (wParam == VK_INSERT || wParam == VK_DELETE)
+ break;
+ }
+ #endif
+ SaveKeyboardMessage(dat, msg, wParam, lParam);
+ return 0;
+ }
+ break;
+ case WM_KEYDOWN:
+ if (GetWindowLong(hwnd, GWL_STYLE) & ES_READONLY) {
+ #ifdef EDITMSGQUEUE_PASSTHRUCLIPBOARD
+ if (GetKeyState(VK_CONTROL) & 0x8000) {
+ if (wParam == 'X' || wParam == 'C' || wParam == 'V' || wParam == VK_INSERT)
+ break;
+ }
+ if (GetKeyState(VK_SHIFT) & 0x8000) {
+ if (wParam == VK_INSERT || wParam == VK_DELETE)
+ break;
+ }
+ #endif
+ SaveKeyboardMessage(dat, msg, wParam, lParam);
+ return 0;
+ }
+ if (wParam == VK_UP && (GetKeyState(VK_CONTROL) & 0x8000) && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CTRLSUPPORT, SRMSGDEFSET_CTRLSUPPORT) && !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOCLOSE, SRMSGDEFSET_AUTOCLOSE)) {
+ if (pdat->cmdList) {
+ if (!pdat->cmdListCurrent) {
+ pdat->cmdListCurrent = tcmdlist_last(pdat->cmdList);
+ SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
+ SetWindowText(hwnd, pdat->cmdListCurrent->szCmd);
+ SendMessage(hwnd, EM_SCROLLCARET, 0,0);
+ SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
+ SendMessage(hwnd, EM_SETSEL, 0, -1);
+ }
+ else if (pdat->cmdListCurrent->prev) {
+ pdat->cmdListCurrent = pdat->cmdListCurrent->prev;
+ SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
+ SetWindowText(hwnd, pdat->cmdListCurrent->szCmd);
+ SendMessage(hwnd, EM_SCROLLCARET, 0,0);
+ SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
+ SendMessage(hwnd, EM_SETSEL, 0, -1);
+ }
+ }
+ EnableWindow(GetDlgItem(GetParent(hwnd), IDOK), GetWindowTextLength(GetDlgItem(GetParent(hwnd), IDC_MESSAGE)) != 0);
+ UpdateReadChars(GetParent(hwnd), pdat->hwndStatus);
+ }
+ else if (wParam == VK_DOWN && (GetKeyState(VK_CONTROL) & 0x8000) && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CTRLSUPPORT, SRMSGDEFSET_CTRLSUPPORT) && !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOCLOSE, SRMSGDEFSET_AUTOCLOSE)) {
+ if (pdat->cmdList) {
+ if (!pdat->cmdListCurrent)
+ pdat->cmdListCurrent = tcmdlist_last(pdat->cmdList);
+ if (pdat->cmdListCurrent->next) {
+ pdat->cmdListCurrent = pdat->cmdListCurrent->next;
+ SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
+ SetWindowText(hwnd, pdat->cmdListCurrent->szCmd);
+ SendMessage(hwnd, EM_SCROLLCARET, 0,0);
+ SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
+ SendMessage(hwnd, EM_SETSEL, 0, -1);
+ }
+ else {
+ pdat->cmdListCurrent = 0;
+ SetWindowTextA(hwnd, "");
+ }
+ }
+ EnableWindow(GetDlgItem(GetParent(hwnd), IDOK), GetWindowTextLength(GetDlgItem(GetParent(hwnd), IDC_MESSAGE)) != 0);
+ UpdateReadChars(GetParent(hwnd), pdat->hwndStatus);
+ }
+ if (wParam == VK_RETURN)
+ break;
+ //fall through
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_MOUSEWHEEL:
+ case WM_KILLFOCUS:
+ dat->lastEnterTime = 0;
+ break;
+ case WM_SYSCHAR:
+ dat->lastEnterTime = 0;
+ if ((wParam == 's' || wParam == 'S') && GetKeyState(VK_MENU) & 0x8000) {
+ if (GetWindowLong(hwnd, GWL_STYLE) & ES_READONLY)
+ SaveKeyboardMessage(dat, msg, wParam, lParam);
+ else
+ PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ break;
+ case EM_UNSUBCLASSED:
+ if (dat->keyboardMsgQueue)
+ free(dat->keyboardMsgQueue);
+ free(dat);
+ return 0;
+ }
+ return CallWindowProc(OldMessageEditProc, hwnd, msg, wParam, lParam);
+}
+
+static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_NCHITTEST:
+ return HTCLIENT;
+ case WM_SETCURSOR:
+ {
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ SetCursor(rc.right > rc.bottom ? hCurSplitNS : hCurSplitWE);
+ return TRUE;
+ }
+ case WM_LBUTTONDOWN:
+ SetCapture(hwnd);
+ return 0;
+ case WM_MOUSEMOVE:
+ if (GetCapture() == hwnd) {
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ SendMessage(GetParent(hwnd), DM_SPLITTERMOVED, rc.right > rc.bottom ? (short) HIWORD(GetMessagePos()) + rc.bottom / 2 : (short) LOWORD(GetMessagePos()) + rc.right / 2, (LPARAM) hwnd);
+ }
+ return 0;
+ case WM_LBUTTONUP:
+ ReleaseCapture();
+ return 0;
+ }
+ return CallWindowProc(OldSplitterProc, hwnd, msg, wParam, lParam);
+}
+
+static int MessageDialogResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL * urc)
+{
+ struct MessageWindowData *dat = (struct MessageWindowData *) lParam;
+
+ if (!(g_dat->flags&SMF_SHOWINFO) && !(g_dat->flags&SMF_SHOWBTNS)) {
+ int i;
+ for (i = 0; i < SIZEOF(buttonLineControls); i++)
+ if (buttonLineControls[i] == urc->wId)
+ OffsetRect(&urc->rcItem, 0, -dat->lineHeight);
+ }
+ switch (urc->wId) {
+ case IDC_NAME:
+ {
+ int len;
+ HWND h;
+
+ h = GetDlgItem(hwndDlg, IDC_NAME);
+ len = GetWindowTextLength(h);
+ if (len > 0) {
+ HDC hdc;
+ SIZE textSize;
+ TCHAR buf[256];
+ HFONT hFont;
+
+ GetWindowText(h, buf, SIZEOF(buf));
+
+ hdc = GetDC(h);
+ hFont = SelectObject(hdc, (HFONT) SendMessage(GetDlgItem(hwndDlg, IDOK), WM_GETFONT, 0, 0));
+ GetTextExtentPoint32(hdc, buf, lstrlen(buf), &textSize);
+ urc->rcItem.right = urc->rcItem.left + textSize.cx + 10;
+ if ((g_dat->flags&SMF_SHOWBTNS) && urc->rcItem.right > urc->dlgNewSize.cx - dat->nLabelRight)
+ urc->rcItem.right = urc->dlgNewSize.cx - dat->nLabelRight;
+ SelectObject(hdc, hFont);
+ ReleaseDC(h, hdc);
+ }
+ }
+ case IDC_PROTOCOL:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
+ case IDC_ADD:
+ case IDC_USERMENU:
+ case IDC_DETAILS:
+ case IDC_HISTORY:
+ return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP;
+ case IDC_LOG:
+ if (!(g_dat->flags&SMF_SHOWINFO) && !(g_dat->flags&SMF_SHOWBTNS))
+ urc->rcItem.top -= dat->lineHeight;
+ urc->rcItem.bottom -= dat->splitterPos - dat->originalSplitterPos;
+ return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
+ case IDC_SPLITTER:
+ urc->rcItem.top -= dat->splitterPos - dat->originalSplitterPos;
+ urc->rcItem.bottom -= dat->splitterPos - dat->originalSplitterPos;
+ return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM;
+ case IDC_MESSAGE:
+ {
+ if (!(g_dat->flags&SMF_SENDBTN))
+ urc->rcItem.right = urc->dlgNewSize.cx - urc->rcItem.left;
+ if ((g_dat->flags&SMF_AVATAR)&&dat->avatarPic) {
+ urc->rcItem.left = dat->avatarWidth+4;
+ }
+ urc->rcItem.top -= dat->splitterPos - dat->originalSplitterPos;
+ if (!(g_dat->flags&SMF_SENDBTN))
+ return RD_ANCHORX_CUSTOM | RD_ANCHORY_BOTTOM;
+ return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM;
+ }
+ case IDCANCEL:
+ case IDOK:
+ urc->rcItem.top -= dat->splitterPos - dat->originalSplitterPos;
+ return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
+ case IDC_AVATAR:
+ urc->rcItem.top=urc->rcItem.bottom-(dat->avatarHeight + 2);
+ urc->rcItem.right=urc->rcItem.left+(dat->avatarWidth + 2);
+ return RD_ANCHORX_LEFT|RD_ANCHORY_BOTTOM;
+ }
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
+}
+
+static void UpdateReadChars(HWND hwndDlg, HWND hwndStatus)
+{
+ if (hwndStatus && SendMessage(hwndStatus, SB_GETPARTS, 0, 0) == 2) {
+ TCHAR buf[128];
+ int len = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE));
+
+ mir_sntprintf(buf, SIZEOF(buf), _T("%d"), len);
+ SendMessage(hwndStatus, SB_SETTEXT, 1, (LPARAM) buf);
+ }
+}
+
+void ShowAvatar(HWND hwndDlg, struct MessageWindowData *dat) {
+ DBVARIANT dbv;
+
+ if (dat->avatarPic) {
+ DeleteObject(dat->avatarPic);
+ dat->avatarPic=0;
+ }
+ if (!DBGetContactSetting(dat->hContact, SRMMMOD, SRMSGSET_AVATAR, &dbv)) {
+ if(dbv.pszVal) {
+ HANDLE hFile;
+
+ hFile = CreateFileA(dbv.pszVal, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile!=INVALID_HANDLE_VALUE) {
+ dat->avatarPic=(HBITMAP)CallService(MS_UTILS_LOADBITMAP,0,(LPARAM)dbv.pszVal);
+ CloseHandle(hFile);
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+ SendMessage(hwndDlg, DM_UPDATESIZEBAR, 0, 0);
+ SendMessage(hwndDlg, DM_AVATARSIZECHANGE, 0, 0);
+}
+
+static void NotifyTyping(struct MessageWindowData *dat, int mode)
+{
+ DWORD protoStatus;
+ DWORD protoCaps;
+ DWORD typeCaps;
+
+ if (!dat->hContact)
+ return;
+ // Don't send to protocols who don't support typing
+ // Don't send to users who are unchecked in the typing notification options
+ // Don't send to protocols that are offline
+ // Don't send to users who are not visible and
+ // Don't send to users who are not on the visible list when you are in invisible mode.
+ if (!DBGetContactSettingByte(dat->hContact, SRMMMOD, SRMSGSET_TYPING, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW)))
+ return;
+ if (!dat->szProto)
+ return;
+ protoStatus = CallProtoService(dat->szProto, PS_GETSTATUS, 0, 0);
+ protoCaps = CallProtoService(dat->szProto, PS_GETCAPS, PFLAGNUM_1, 0);
+ typeCaps = CallProtoService(dat->szProto, PS_GETCAPS, PFLAGNUM_4, 0);
+
+ if (!(typeCaps & PF4_SUPPORTTYPING))
+ return;
+ if (protoStatus < ID_STATUS_ONLINE)
+ return;
+ if (protoCaps & PF1_VISLIST && DBGetContactSettingWord(dat->hContact, dat->szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE)
+ return;
+ if (protoCaps & PF1_INVISLIST && protoStatus == ID_STATUS_INVISIBLE && DBGetContactSettingWord(dat->hContact, dat->szProto, "ApparentMode", 0) != ID_STATUS_ONLINE)
+ return;
+ if (DBGetContactSettingByte(dat->hContact, "CList", "NotOnList", 0)
+ && !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGUNKNOWN, SRMSGDEFSET_TYPINGUNKNOWN))
+ return;
+ // End user check
+ dat->nTypeMode = mode;
+ CallService(MS_PROTO_SELFISTYPING, (WPARAM) dat->hContact, dat->nTypeMode);
+}
+
+BOOL CALLBACK DlgProcMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ struct MessageWindowData *dat;
+
+ dat = (struct MessageWindowData *) GetWindowLong(hwndDlg, GWL_USERDATA);
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ struct NewMessageWindowLParam *newData = (struct NewMessageWindowLParam *) lParam;
+ TranslateDialogDefault(hwndDlg);
+ dat = (struct MessageWindowData *) calloc(sizeof(struct MessageWindowData),1);
+ SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) dat);
+ {
+ dat->hContact = newData->hContact;
+ NotifyLocalWinEvent(dat->hContact, hwndDlg, MSG_WINDOW_EVT_OPENING);
+ if (newData->szInitialText) {
+ int len;
+#if defined(_UNICODE)
+ if(newData->isWchar)
+ SetDlgItemText(hwndDlg, IDC_MESSAGE, (TCHAR *)newData->szInitialText);
+ else
+ SetDlgItemTextA(hwndDlg, IDC_MESSAGE, newData->szInitialText);
+#else
+ SetDlgItemTextA(hwndDlg, IDC_MESSAGE, newData->szInitialText);
+#endif
+ len = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ PostMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), EM_SETSEL, len, len);
+ }
+ }
+ dat->szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) dat->hContact, 0);
+ RichUtil_SubClass(GetDlgItem(hwndDlg, IDC_LOG));
+ { // avatar stuff
+ dat->avatarPic = 0;
+ dat->avatarWidth = 0;
+ dat->avatarHeight = 0;
+ dat->limitAvatarH = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITAVHEIGHT, SRMSGDEFSET_LIMITAVHEIGHT)?DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_AVHEIGHT, SRMSGDEFSET_AVHEIGHT):0;
+ }
+ if (dat->hContact && dat->szProto != NULL)
+ dat->wStatus = DBGetContactSettingWord(dat->hContact, dat->szProto, "Status", ID_STATUS_OFFLINE);
+ else
+ dat->wStatus = ID_STATUS_OFFLINE;
+ dat->wOldStatus = dat->wStatus;
+ dat->hSendId = NULL;
+ dat->hBkgBrush = NULL;
+ dat->hDbEventFirst = NULL;
+ dat->sendBuffer = NULL;
+ dat->splitterPos = (int) DBGetContactSettingDword(DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT)?dat->hContact:NULL, SRMMMOD, "splitterPos", (DWORD) - 1);
+ dat->windowWasCascaded = 0;
+ dat->nFlash = 0;
+ dat->nTypeSecs = 0;
+ dat->nLastTyping = 0;
+ dat->showTyping = 0;
+ dat->cmdList = 0;
+ dat->cmdListCurrent = 0;
+ dat->nTypeMode = PROTOTYPE_SELFTYPING_OFF;
+ SetTimer(hwndDlg, TIMERID_TYPE, 1000, NULL);
+ dat->lastMessage = 0;
+ dat->lastEventType = -1;
+ dat->nFlashMax = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_FLASHCOUNT, SRMSGDEFSET_FLASHCOUNT);
+ {
+ RECT rc, rc2;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_USERMENU), &rc);
+ GetWindowRect(hwndDlg, &rc2);
+ dat->nLabelRight = rc2.right - rc.left;
+ }
+ {
+ RECT rc;
+ POINT pt;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_SPLITTER), &rc);
+ pt.y = (rc.top + rc.bottom) / 2;
+ pt.x = 0;
+ ScreenToClient(hwndDlg, &pt);
+ dat->originalSplitterPos = pt.y;
+ if (dat->splitterPos == -1)
+ dat->splitterPos = dat->originalSplitterPos;// + 60;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_ADD), &rc);
+ dat->lineHeight = rc.bottom - rc.top + 3;
+ }
+ WindowList_Add(g_dat->hMessageWindowList, hwndDlg, dat->hContact);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_MESSAGE), &dat->minEditInit);
+ SendMessage(hwndDlg, DM_UPDATESIZEBAR, 0, 0);
+ dat->hwndStatus = NULL;
+ SendDlgItemMessage(hwndDlg, IDC_ADD, BM_SETIMAGE, IMAGE_ICON, (LPARAM) g_dat->hIcons[SMF_ICON_ADD]);
+ SendDlgItemMessage(hwndDlg, IDC_DETAILS, BM_SETIMAGE, IMAGE_ICON, (LPARAM) g_dat->hIcons[SMF_ICON_USERDETAIL]);
+ SendDlgItemMessage(hwndDlg, IDC_HISTORY, BM_SETIMAGE, IMAGE_ICON, (LPARAM) g_dat->hIcons[SMF_ICON_HISTORY]);
+ SendDlgItemMessage(hwndDlg, IDC_USERMENU, BM_SETIMAGE, IMAGE_ICON, (LPARAM) g_dat->hIcons[SMF_ICON_ARROW]);
+ // Make them flat buttons
+ {
+ int i;
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_NAME), BUTTONSETASFLATBTN, 0, 0);
+ for (i = 0; i < SIZEOF(buttonLineControls); i++)
+ SendMessage(GetDlgItem(hwndDlg, buttonLineControls[i]), BUTTONSETASFLATBTN, 0, 0);
+ }
+ SendMessage(GetDlgItem(hwndDlg, IDC_ADD), BUTTONADDTOOLTIP, (WPARAM) Translate("Add Contact Permanently to List"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_USERMENU), BUTTONADDTOOLTIP, (WPARAM) Translate("User Menu"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_DETAILS), BUTTONADDTOOLTIP, (WPARAM) Translate("View User's Details"), 0);
+ SendMessage(GetDlgItem(hwndDlg, IDC_HISTORY), BUTTONADDTOOLTIP, (WPARAM) Translate("View User's History"), 0);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOCOL), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AVATAR), FALSE);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETOLECALLBACK, 0, (LPARAM) & reOleCallback);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK);
+ /* duh, how come we didnt use this from the start? */
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_AUTOURLDETECT, (WPARAM) TRUE, 0);
+ if (dat->hContact) {
+ if (dat->szProto) {
+ int nMax;
+ nMax = CallProtoService(dat->szProto, PS_GETCAPS, PFLAG_MAXLENOFMESSAGE, (LPARAM) dat->hContact);
+ if (nMax)
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_LIMITTEXT, (WPARAM) nMax, 0);
+ /* get around a lame bug in the Windows template resource code where richedits are limited to 0x7FFF */
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_LIMITTEXT, (WPARAM) sizeof(TCHAR) * 0x7FFFFFFF, 0);
+ }
+ }
+ OldMessageEditProc = (WNDPROC) SetWindowLong(GetDlgItem(hwndDlg, IDC_MESSAGE), GWL_WNDPROC, (LONG) MessageEditSubclassProc);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SUBCLASSED, 0, 0);
+ OldSplitterProc = (WNDPROC) SetWindowLong(GetDlgItem(hwndDlg, IDC_SPLITTER), GWL_WNDPROC, (LONG) SplitterSubclassProc);
+ if (dat->hContact) {
+ int historyMode = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, SRMSGDEFSET_LOADHISTORY);
+ // This finds the first message to display, it works like shit
+ dat->hDbEventFirst = (HANDLE) CallService(MS_DB_EVENT_FINDFIRSTUNREAD, (WPARAM) dat->hContact, 0);
+ switch (historyMode) {
+ case LOADHISTORY_COUNT:
+ {
+ int i;
+ HANDLE hPrevEvent;
+ DBEVENTINFO dbei = { 0 };
+ dbei.cbSize = sizeof(dbei);
+ for (i = DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADCOUNT, SRMSGDEFSET_LOADCOUNT); i > 0; i--) {
+ if (dat->hDbEventFirst == NULL)
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDLAST, (WPARAM) dat->hContact, 0);
+ else
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDPREV, (WPARAM) dat->hDbEventFirst, 0);
+ if (hPrevEvent == NULL)
+ break;
+ dbei.cbBlob = 0;
+ dat->hDbEventFirst = hPrevEvent;
+ CallService(MS_DB_EVENT_GET, (WPARAM) dat->hDbEventFirst, (LPARAM) & dbei);
+ if (!DbEventIsShown(&dbei, dat))
+ i++;
+ }
+ break;
+ }
+ case LOADHISTORY_TIME:
+ {
+ HANDLE hPrevEvent;
+ DBEVENTINFO dbei = { 0 };
+ DWORD firstTime;
+
+ dbei.cbSize = sizeof(dbei);
+ if (dat->hDbEventFirst == NULL)
+ dbei.timestamp = time(NULL);
+ else
+ CallService(MS_DB_EVENT_GET, (WPARAM) dat->hDbEventFirst, (LPARAM) & dbei);
+ firstTime = dbei.timestamp - 60 * DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADTIME, SRMSGDEFSET_LOADTIME);
+ for (;;) {
+ if (dat->hDbEventFirst == NULL)
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDLAST, (WPARAM) dat->hContact, 0);
+ else
+ hPrevEvent = (HANDLE) CallService(MS_DB_EVENT_FINDPREV, (WPARAM) dat->hDbEventFirst, 0);
+ if (hPrevEvent == NULL)
+ break;
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM) hPrevEvent, (LPARAM) & dbei);
+ if (dbei.timestamp < firstTime)
+ break;
+ dat->hDbEventFirst = hPrevEvent;
+ }
+ break;
+ }
+ }
+ }
+ SendMessage(hwndDlg, DM_OPTIONSAPPLIED, 1, 0);
+ {
+ int savePerContact = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT);
+ if (Utils_RestoreWindowPosition(hwndDlg, savePerContact ? dat->hContact : NULL, SRMMMOD, "")) {
+ if (savePerContact) {
+ if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMMMOD, ""))
+ SetWindowPos(hwndDlg, 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE);
+ }
+ else
+ SetWindowPos(hwndDlg, 0, 0, 0, 450, 300, SWP_NOZORDER | SWP_NOMOVE);
+ }
+ if (!savePerContact && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE))
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_CASCADENEWWINDOW, (WPARAM) hwndDlg, (LPARAM) & dat->windowWasCascaded);
+ }
+ {
+ DBEVENTINFO dbei = { 0 };
+ HANDLE hdbEvent;
+
+ dbei.cbSize = sizeof(dbei);
+ hdbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDLAST, (WPARAM) dat->hContact, 0);
+ if (hdbEvent) {
+ do {
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ CallService(MS_DB_EVENT_GET, (WPARAM) hdbEvent, (LPARAM) & dbei);
+ if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
+ dat->lastMessage = dbei.timestamp;
+ SendMessage(hwndDlg, DM_UPDATELASTMESSAGE, 0, 0);
+ break;
+ }
+ }
+ while (hdbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDPREV, (WPARAM) hdbEvent, 0));
+ }
+
+ }
+ SendMessage(hwndDlg, DM_GETAVATAR, 0, 0);
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ NotifyLocalWinEvent(dat->hContact, hwndDlg, MSG_WINDOW_EVT_OPEN);
+ return TRUE;
+ }
+ case WM_CONTEXTMENU:
+ {
+ if (dat->hwndStatus && dat->hwndStatus == (HWND) wParam) {
+ POINT pt;
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) dat->hContact, 0);
+
+ GetCursorPos(&pt);
+ TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hwndDlg, NULL);
+ DestroyMenu(hMenu);
+ }
+ break;
+ }
+ // Mod from tabsrmm
+ case WM_DROPFILES:
+ {
+ if (dat->szProto==NULL) break;
+ if (!(CallProtoService(dat->szProto, PS_GETCAPS, PFLAGNUM_1,0)&PF1_FILESEND)) break;
+ if (dat->wStatus==ID_STATUS_OFFLINE) break;
+ if (dat->hContact!=NULL) {
+ HDROP hDrop;
+ char **ppFiles=NULL;
+ char szFilename[MAX_PATH];
+ int fileCount,totalCount=0,i;
+
+ hDrop=(HDROP)wParam;
+ fileCount=DragQueryFile(hDrop,-1,NULL,0);
+ ppFiles=NULL;
+ for(i=0;i<fileCount;i++) {
+ DragQueryFileA(hDrop, i, szFilename, SIZEOF(szFilename));
+ AddToFileList(&ppFiles, &totalCount, szFilename);
+ }
+ CallServiceSync(MS_FILE_SENDSPECIFICFILES, (WPARAM)dat->hContact, (LPARAM)ppFiles);
+ for(i=0;ppFiles[i];i++) free(ppFiles[i]);
+ free(ppFiles);
+ }
+ break;
+ }
+ case HM_AVATARACK:
+ {
+ ACKDATA *pAck = (ACKDATA *)lParam;
+ PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION *)pAck->hProcess;
+ HWND hwnd = 0;
+
+ if (pAck->hContact!=dat->hContact)
+ return 0;
+ if (pAck->type != ACKTYPE_AVATAR)
+ return 0;
+ if (pAck->result == ACKRESULT_STATUS) {
+ SendMessage(hwndDlg, DM_GETAVATAR, 0, 0);
+ break;
+ }
+ if (pai==NULL)
+ return 0;
+ if (pAck->result == ACKRESULT_SUCCESS) {
+ if (pai->filename&&strlen(pai->filename)&&VALID_AVATAR(pai->format)) {
+ DBWriteContactSettingString(dat->hContact, SRMMMOD, SRMSGSET_AVATAR, pai->filename);
+ ShowAvatar(hwndDlg, dat);
+ }
+ }
+ else if (pAck->result == ACKRESULT_FAILED) {
+ DBWriteContactSettingString(dat->hContact, SRMMMOD, SRMSGSET_AVATAR, "");
+ ShowAvatar(hwndDlg, dat);
+ }
+ break;
+ }
+ case DM_AVATARCALCSIZE:
+ {
+ BITMAP bminfo;
+
+ if (dat->avatarPic==0||!(g_dat->flags&SMF_AVATAR)) {
+ dat->avatarWidth=50;
+ dat->avatarHeight=50;
+ ShowWindow(GetDlgItem(hwndDlg, IDC_AVATAR), SW_HIDE);
+ return 0;
+ }
+ GetObject(dat->avatarPic, sizeof(bminfo), &bminfo);
+ dat->avatarWidth=bminfo.bmWidth+2;
+ dat->avatarHeight=bminfo.bmHeight+2;
+ if (dat->limitAvatarH&&dat->avatarHeight>dat->limitAvatarH) {
+ double aspect = 0;
+
+ aspect = (double)dat->limitAvatarH / (double)bminfo.bmHeight;
+ dat->avatarWidth = (int)(bminfo.bmWidth * aspect + 2);
+ dat->avatarHeight = dat->limitAvatarH + 2;
+ }
+ ShowWindow(GetDlgItem(hwndDlg, IDC_AVATAR), SW_SHOW);
+ break;
+ }
+ case DM_UPDATESIZEBAR:
+ {
+ dat->minEditBoxSize.cx = dat->minEditInit.right - dat->minEditInit.left;
+ dat->minEditBoxSize.cy = dat->minEditInit.bottom - dat->minEditInit.top;
+ if (g_dat->flags&SMF_AVATAR) {
+ SendMessage(hwndDlg, DM_AVATARCALCSIZE, 0, 0);
+ if(dat->avatarPic) {
+ if (dat->minEditBoxSize.cy<=dat->avatarHeight)
+ dat->minEditBoxSize.cy = dat->avatarHeight;
+ }
+ }
+ break;
+ }
+ case DM_AVATARSIZECHANGE:
+ {
+ RECT rc;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_MESSAGE), &rc);
+ if (rc.bottom-rc.top<dat->minEditBoxSize.cy) {
+ SendMessage(hwndDlg, DM_SPLITTERMOVED, rc.top-(rc.bottom-rc.top-dat->minEditBoxSize.cy-4), (LPARAM) GetDlgItem(hwndDlg, IDC_SPLITTER));
+ }
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ SendMessage(hwndDlg, DM_SCROLLLOGTOBOTTOM, 0, 0);
+ break;
+ }
+ case DM_GETAVATAR:
+ {
+ PROTO_AVATAR_INFORMATION pai;
+ int caps = 0, result;
+
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, 0);
+ if (!(g_dat->flags&SMF_AVATAR)||!(CallProtoService(dat->szProto, PS_GETCAPS, PFLAGNUM_4, 0)&PF4_AVATARS)) {
+ SendMessage(hwndDlg, DM_UPDATESIZEBAR, 0, 0);
+ SendMessage(hwndDlg, DM_AVATARSIZECHANGE, 0, 0);
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, 1);
+ return 0;
+ }
+ if(DBGetContactSettingWord(dat->hContact, dat->szProto, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) {
+ ShowAvatar(hwndDlg, dat);
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, 1);
+ return 0;
+ }
+ ZeroMemory((void *)&pai, sizeof(pai));
+ pai.cbSize = sizeof(pai);
+ pai.hContact = dat->hContact;
+ pai.format = PA_FORMAT_UNKNOWN;
+ strcpy(pai.filename, "");
+ result = CallProtoService(dat->szProto, PS_GETAVATARINFO, GAIF_FORCE, (LPARAM)&pai);
+ if (result==GAIR_SUCCESS) {
+ if (VALID_AVATAR(pai.format))
+ DBWriteContactSettingString(dat->hContact, SRMMMOD, SRMSGSET_AVATAR, pai.filename);
+ else DBWriteContactSettingString(dat->hContact, SRMMMOD, SRMSGSET_AVATAR, "");
+ ShowAvatar(hwndDlg, dat);
+ } else if (result == GAIR_NOAVATAR) {
+ DBWriteContactSettingString(dat->hContact, SRMMMOD, SRMSGSET_AVATAR, "");
+ ShowAvatar(hwndDlg, dat);
+ }
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, 1);
+ break;
+ }
+ case DM_TYPING:
+ {
+ dat->nTypeSecs = (int) lParam > 0 ? (int) lParam : 0;
+ break;
+ }
+ case DM_UPDATEWINICON:
+ {
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON)) {
+ WORD wStatus;
+
+ if (dat->szProto) {
+ wStatus = DBGetContactSettingWord(dat->hContact, dat->szProto, "Status", ID_STATUS_OFFLINE);
+ SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedProtoIcon(dat->szProto, wStatus));
+ break;
+ }
+ }
+ SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedIcon(SKINICON_EVENT_MESSAGE));
+ break;
+ }
+ case DM_USERNAMETOCLIP:
+ {
+ CONTACTINFO ci;
+ char buf[128];
+ HGLOBAL hData;
+
+ buf[0] = 0;
+ if(dat->hContact) {
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = dat->hContact;
+ ci.szProto = dat->szProto;
+ ci.dwFlag = CNF_UNIQUEID;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ switch (ci.type) {
+ case CNFT_ASCIIZ:
+ mir_snprintf(buf, SIZEOF(buf), "%s", ci.pszVal);
+ miranda_sys_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ mir_snprintf(buf, SIZEOF(buf), "%u", ci.dVal);
+ break;
+ }
+ }
+ if (!OpenClipboard(hwndDlg) || !lstrlenA(buf)) break;
+ EmptyClipboard();
+ hData = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(buf) + 1);
+ lstrcpyA(GlobalLock(hData), buf);
+ GlobalUnlock(hData);
+ SetClipboardData(CF_TEXT, hData);
+ CloseClipboard();
+ }
+ break;
+ }
+ case DM_UPDATELASTMESSAGE:
+ {
+ if (!dat->hwndStatus || dat->nTypeSecs)
+ break;
+ if (dat->lastMessage) {
+ DBTIMETOSTRINGT dbtts;
+ TCHAR date[64], time[64], fmt[128];
+
+ dbtts.szFormat = _T("d");
+ dbtts.cbDest = SIZEOF(date);
+ dbtts.szDest = date;
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, dat->lastMessage, (LPARAM) & dbtts);
+ dbtts.szFormat = _T("t");
+ dbtts.cbDest = SIZEOF(time);
+ dbtts.szDest = time;
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, dat->lastMessage, (LPARAM) & dbtts);
+ mir_sntprintf(fmt, SIZEOF(fmt), TranslateT("Last message received on %s at %s."), date, time);
+ SendMessage(dat->hwndStatus, SB_SETTEXT, 0, (LPARAM) fmt);
+ SendMessage(dat->hwndStatus, SB_SETICON, 0, (LPARAM) NULL);
+ }
+ else {
+ SendMessage(dat->hwndStatus, SB_SETTEXT, 0, (LPARAM) _T(""));
+ SendMessage(dat->hwndStatus, SB_SETICON, 0, (LPARAM) NULL);
+ }
+ break;
+ }
+ case DM_OPTIONSAPPLIED:
+ SetDialogToType(hwndDlg);
+ if (dat->hBkgBrush)
+ DeleteObject(dat->hBkgBrush);
+ {
+ COLORREF colour = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR);
+ dat->hBkgBrush = CreateSolidBrush(colour);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETBKGNDCOLOR, 0, colour);
+ }
+ { // avatar stuff
+ dat->avatarPic = 0;
+ dat->limitAvatarH = 0;
+ if (CallProtoService(dat->szProto, PS_GETCAPS, PFLAGNUM_4, 0)&PF4_AVATARS) {
+ dat->limitAvatarH = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITAVHEIGHT, SRMSGDEFSET_LIMITAVHEIGHT)?DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_AVHEIGHT, SRMSGDEFSET_AVHEIGHT):0;
+ }
+ if (!wParam) SendMessage(hwndDlg, DM_GETAVATAR, 0, 0);
+ }
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_MESSAGE), NULL, FALSE);
+ {
+ HFONT hFont;
+ LOGFONT lf;
+ hFont = (HFONT) SendDlgItemMessage(hwndDlg, IDC_MESSAGE, WM_GETFONT, 0, 0);
+ if (hFont != NULL && hFont != (HFONT) SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0))
+ DeleteObject(hFont);
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, NULL);
+ hFont = CreateFontIndirect(&lf);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, WM_SETFONT, (WPARAM) hFont, MAKELPARAM(TRUE, 0));
+ }
+
+ /*
+ * configure message history for proper RTL formatting
+ */
+
+ {
+ PARAFORMAT2 pf2;
+ ZeroMemory((void *)&pf2, sizeof(pf2));
+ pf2.cbSize = sizeof(pf2);
+
+ pf2.wEffects = PFE_RTLPARA;
+ pf2.dwMask = PFM_RTLPARA;
+ SetDlgItemText(hwndDlg, IDC_LOG, _T(""));
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ pf2.wEffects = 0;
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETLANGOPTIONS, 0, (LPARAM) SendDlgItemMessage(hwndDlg, IDC_LOG, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
+ }
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ SendMessage(hwndDlg, DM_UPDATEWINICON, 0, 0);
+ break;
+ case DM_UPDATETITLE:
+ {
+ TCHAR newtitle[256], oldtitle[256], *szStatus;
+ TCHAR *contactName, *pszNewTitleEnd;
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) wParam;
+
+ pszNewTitleEnd = _T("Message Session");
+ if (dat->hContact) {
+ if (dat->szProto) {
+ CONTACTINFO ci;
+ char buf[128];
+ int statusIcon = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON);
+
+ buf[0] = 0;
+ dat->wStatus = DBGetContactSettingWord(dat->hContact, dat->szProto, "Status", ID_STATUS_OFFLINE);
+ contactName = ( TCHAR* )CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) dat->hContact, GCDNF_TCHAR);
+ ZeroMemory(&ci, sizeof(ci));
+ ci.cbSize = sizeof(ci);
+ ci.hContact = dat->hContact;
+ ci.szProto = dat->szProto;
+ ci.dwFlag = CNF_UNIQUEID;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ switch (ci.type) {
+ case CNFT_ASCIIZ:
+ mir_snprintf(buf, SIZEOF(buf), "%s", ci.pszVal);
+ miranda_sys_free(ci.pszVal);
+ break;
+ case CNFT_DWORD:
+ mir_snprintf(buf, SIZEOF(buf), "%u", ci.dVal);
+ break;
+ }
+ }
+ if ( buf[0] )
+ SetDlgItemTextA(hwndDlg, IDC_NAME, buf );
+ else
+ SetDlgItemText(hwndDlg, IDC_NAME, contactName);
+
+ szStatus = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, dat->szProto == NULL ? ID_STATUS_OFFLINE : DBGetContactSettingWord(dat->hContact, dat->szProto, "Status", ID_STATUS_OFFLINE), GCMDF_TCHAR);
+ if (statusIcon)
+ mir_sntprintf(newtitle, SIZEOF(newtitle), _T("%s - %s"), contactName, TranslateTS(pszNewTitleEnd));
+ else
+ mir_sntprintf(newtitle, SIZEOF(newtitle), _T("%s (%s): %s"), contactName, szStatus, TranslateTS(pszNewTitleEnd));
+ if (!cws || (!strcmp(cws->szModule, dat->szProto) && !strcmp(cws->szSetting, "Status"))) {
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_PROTOCOL), NULL, TRUE);
+ if (statusIcon) {
+ SendMessage(hwndDlg, DM_UPDATEWINICON, 0, 0);
+ }
+ }
+
+ // log
+ if ((dat->wStatus != dat->wOldStatus || lParam != 0)
+ && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCH, SRMSGDEFSET_SHOWSTATUSCH)) {
+ DBEVENTINFO dbei;
+ TCHAR buffer[200];
+ HANDLE hNewEvent;
+ int iLen;
+
+ TCHAR *szOldStatus = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM) dat->wOldStatus, GCMDF_TCHAR);
+ TCHAR *szNewStatus = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM) dat->wStatus, GCMDF_TCHAR);
+
+ if (dat->wStatus == ID_STATUS_OFFLINE) {
+ iLen = mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("signed off (was %s)"), szOldStatus);
+ SendMessage(hwndDlg, DM_TYPING, 0, 0);
+ }
+ else if (dat->wOldStatus == ID_STATUS_OFFLINE)
+ iLen = mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("signed on (%s)"), szNewStatus);
+ else
+ iLen = mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("is now %s (was %s)"), szNewStatus, szOldStatus);
+
+ {
+ char* blob = ( char* )alloca( 1000 );
+ #if defined( _UNICODE )
+ int ansiLen = WideCharToMultiByte(CP_ACP, 0, buffer, -1, blob, 1000, 0, 0);
+ memcpy( blob+ansiLen, buffer, sizeof(TCHAR)*(iLen+1));
+ dbei.cbBlob = ansiLen + sizeof(TCHAR)*(iLen+1);
+ #else
+ int wLen = MultiByteToWideChar(CP_ACP, 0, buffer, -1, NULL, 0 );
+ memcpy( blob, buffer, iLen+1 );
+ MultiByteToWideChar(CP_ACP, 0, buffer, -1, (WCHAR*)&blob[iLen+1], wLen+1 );
+ dbei.cbBlob = iLen+1 + sizeof(WCHAR)*wLen;
+ #endif
+
+ dbei.cbSize = sizeof(dbei);
+ dbei.pBlob = (PBYTE) blob;
+ dbei.eventType = EVENTTYPE_STATUSCHANGE;
+ dbei.flags = 0;
+ dbei.timestamp = time(NULL);
+ dbei.szModule = dat->szProto;
+ hNewEvent = (HANDLE) CallService(MS_DB_EVENT_ADD, (WPARAM) dat->hContact, (LPARAM) & dbei);
+ if (dat->hDbEventFirst == NULL) {
+ dat->hDbEventFirst = hNewEvent;
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ }
+ }
+ }
+ dat->wOldStatus = dat->wStatus;
+ }
+ }
+ else lstrcpyn(newtitle, pszNewTitleEnd, SIZEOF(newtitle));
+
+ GetWindowText(hwndDlg, oldtitle, SIZEOF(oldtitle));
+ if ( lstrcmp(newtitle, oldtitle )) { //swt() flickers even if the title hasn't actually changed
+ SetWindowText(hwndDlg, newtitle);
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ }
+ break;
+ }
+ case DM_GETWINDOWSTATE:
+ {
+ UINT state = 0;
+
+ state |= MSG_WINDOW_STATE_EXISTS;
+ if (IsWindowVisible(hwndDlg))
+ state |= MSG_WINDOW_STATE_VISIBLE;
+ if (GetForegroundWindow()==hwndDlg)
+ state |= MSG_WINDOW_STATE_FOCUS;
+ if (IsIconic(hwndDlg))
+ state |= MSG_WINDOW_STATE_ICONIC;
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, state);
+ return TRUE;
+
+ }
+ 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 WM_ACTIVATE:
+ if (LOWORD(wParam) != WA_ACTIVE)
+ break;
+ //fall through
+ case WM_MOUSEACTIVATE:
+ if (KillTimer(hwndDlg, TIMERID_FLASHWND))
+ FlashWindow(hwndDlg, FALSE);
+ break;
+ case WM_SETFOCUS:
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ break;
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *mmi = (MINMAXINFO *) lParam;
+ RECT rcWindow, rcLog;
+ GetWindowRect(hwndDlg, &rcWindow);
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_LOG), &rcLog);
+ mmi->ptMinTrackSize.x = rcWindow.right - rcWindow.left - ((rcLog.right - rcLog.left) - dat->minEditBoxSize.cx);
+ mmi->ptMinTrackSize.y = rcWindow.bottom - rcWindow.top - ((rcLog.bottom - rcLog.top) - dat->minEditBoxSize.cy);
+ return 0;
+ }
+ case WM_SIZE:
+ {
+ UTILRESIZEDIALOG urd;
+ if (IsIconic(hwndDlg))
+ break;
+ if (dat->hwndStatus) {
+ SendMessage(dat->hwndStatus, WM_SIZE, 0, 0);
+ if (SendMessage(dat->hwndStatus, SB_GETPARTS, 0, 0) == 2) {
+ int statwidths[2];
+ RECT rc;
+
+ GetWindowRect(dat->hwndStatus, &rc);
+ statwidths[0] = rc.right - rc.left - SB_CHAR_WIDTH;
+ statwidths[1] = -1;
+ SendMessage(dat->hwndStatus, SB_SETPARTS, 2, (LPARAM) statwidths);
+ }
+ }
+ ZeroMemory(&urd, sizeof(urd));
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = g_hInst;
+ urd.hwndDlg = hwndDlg;
+ urd.lParam = (LPARAM) dat;
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_MSG);
+ urd.pfnResizer = MessageDialogResize;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd);
+ // The statusbar sometimes draws over these 2 controls so
+ // redraw them
+ if (dat->hwndStatus) {
+ RedrawWindow(GetDlgItem(hwndDlg, IDOK), NULL, NULL, RDW_INVALIDATE);
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_MESSAGE), NULL, NULL, RDW_INVALIDATE);
+ }
+ if ((g_dat->flags&SMF_AVATAR)&&dat->avatarPic)
+ RedrawWindow(GetDlgItem(hwndDlg, IDC_AVATAR), NULL, NULL, RDW_INVALIDATE);
+ break;
+ }
+ case DM_SPLITTERMOVED:
+ {
+ POINT pt;
+ RECT rc;
+ RECT rcLog;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_LOG), &rcLog);
+ if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_SPLITTER)) {
+ int oldSplitterY;
+ GetClientRect(hwndDlg, &rc);
+ pt.x = 0;
+ pt.y = wParam;
+ ScreenToClient(hwndDlg, &pt);
+
+ oldSplitterY = dat->splitterPos;
+ dat->splitterPos = rc.bottom - pt.y + 23;
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_MESSAGE), &rc);
+ if (rc.bottom - rc.top + (dat->splitterPos - oldSplitterY) < dat->minEditBoxSize.cy)
+ dat->splitterPos = oldSplitterY + dat->minEditBoxSize.cy - (rc.bottom - rc.top);
+ if (rcLog.bottom - rcLog.top - (dat->splitterPos - oldSplitterY) < dat->minEditBoxSize.cy)
+ dat->splitterPos = oldSplitterY - dat->minEditBoxSize.cy + (rcLog.bottom - rcLog.top);
+ }
+ SendMessage(hwndDlg, WM_SIZE, 0, 0);
+ break;
+ }
+ case DM_REMAKELOG:
+ dat->lastEventType = -1;
+ StreamInEvents(hwndDlg, dat->hDbEventFirst, -1, 0);
+ break;
+ case DM_APPENDTOLOG: //takes wParam=hDbEvent
+ StreamInEvents(hwndDlg, (HANDLE) wParam, 1, 1);
+ break;
+ case DM_SCROLLLOGTOBOTTOM:
+ {
+ SCROLLINFO si = { 0 };
+ if ((GetWindowLong(GetDlgItem(hwndDlg, IDC_LOG), GWL_STYLE) & WS_VSCROLL) == 0)
+ break;
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_PAGE | SIF_RANGE;
+ GetScrollInfo(GetDlgItem(hwndDlg, IDC_LOG), SB_VERT, &si);
+ si.fMask = SIF_POS;
+ si.nPos = si.nMax - si.nPage + 1;
+ SetScrollInfo(GetDlgItem(hwndDlg, IDC_LOG), SB_VERT, &si, TRUE);
+ PostMessage(GetDlgItem(hwndDlg, IDC_LOG), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0);
+ break;
+ }
+ case HM_DBEVENTADDED:
+ if ((HANDLE) wParam != dat->hContact)
+ break;
+ {
+ DBEVENTINFO dbei = { 0 };
+
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, lParam, (LPARAM) & dbei);
+ if (dat->hDbEventFirst == NULL)
+ dat->hDbEventFirst = (HANDLE) lParam;
+ if (dbei.eventType == EVENTTYPE_MESSAGE && (dbei.flags & DBEF_READ))
+ break;
+ if (DbEventIsShown(&dbei, dat)) {
+ if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & (DBEF_SENT))) {
+ if (GetForegroundWindow()==hwndDlg)
+ SkinPlaySound("RecvMsgActive");
+ else SkinPlaySound("RecvMsgInactive");
+ }
+ if (dbei.eventType == EVENTTYPE_MESSAGE && dat->hwndStatus && !(dbei.flags & (DBEF_SENT))) {
+ dat->lastMessage = dbei.timestamp;
+ SendMessage(hwndDlg, DM_UPDATELASTMESSAGE, 0, 0);
+ }
+ if ((HANDLE) lParam != dat->hDbEventFirst && (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, lParam, 0) == NULL)
+ SendMessage(hwndDlg, DM_APPENDTOLOG, lParam, 0);
+ else
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ if ((GetActiveWindow() != hwndDlg || GetForegroundWindow() != hwndDlg) && !(dbei.flags & DBEF_SENT)
+ && dbei.eventType != EVENTTYPE_STATUSCHANGE) {
+ SetTimer(hwndDlg, TIMERID_FLASHWND, TIMEOUT_FLASHWND, NULL);
+ }
+ }
+ break;
+ }
+ case WM_TIMER:
+ if (wParam == TIMERID_MSGSEND) {
+ KillTimer(hwndDlg, wParam);
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ EnableWindow(hwndDlg, FALSE);
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGSENDERROR), hwndDlg, ErrorDlgProc, (LPARAM) strdup( Translate("The message send timed out.")));
+ }
+ else if (wParam == TIMERID_FLASHWND) {
+ FlashWindow(hwndDlg, TRUE);
+ if (dat->nFlash > dat->nFlashMax) {
+ KillTimer(hwndDlg, TIMERID_FLASHWND);
+ FlashWindow(hwndDlg, FALSE);
+ dat->nFlash = 0;
+ }
+ dat->nFlash++;
+ }
+ else if (wParam == TIMERID_TYPE) {
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_ON && GetTickCount() - dat->nLastTyping > TIMEOUT_TYPEOFF) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_OFF);
+ }
+ if (dat->showTyping) {
+ if (dat->nTypeSecs) {
+ dat->nTypeSecs--;
+ if (GetForegroundWindow() == hwndDlg)
+ SendMessage(hwndDlg, DM_UPDATEWINICON, 0, 0);
+ }
+ else {
+ SendMessage(hwndDlg, DM_UPDATELASTMESSAGE, 0, 0);
+ if (g_dat->flags&SMF_SHOWTYPINGWIN)
+ SendMessage(hwndDlg, DM_UPDATEWINICON, 0, 0);
+ dat->showTyping = 0;
+ }
+ }
+ else {
+ if (dat->nTypeSecs) {
+ TCHAR szBuf[256];
+ TCHAR *szContactName = ( TCHAR* ) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) dat->hContact, GCDNF_TCHAR);
+
+ mir_sntprintf(szBuf, SIZEOF(szBuf), TranslateT("%s is typing a message..."), szContactName);
+ dat->nTypeSecs--;
+ SendMessage(dat->hwndStatus, SB_SETTEXT, 0, (LPARAM) szBuf);
+ SendMessage(dat->hwndStatus, SB_SETICON, 0, (LPARAM) g_dat->hIcons[SMF_ICON_TYPING]);
+ if ((g_dat->flags&SMF_SHOWTYPINGWIN) && GetForegroundWindow() != hwndDlg)
+ SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) g_dat->hIcons[SMF_ICON_TYPING]);
+ dat->showTyping = 1;
+ }
+ }
+ }
+ break;
+ case DM_ERRORDECIDED:
+ EnableWindow(hwndDlg, TRUE);
+ switch (wParam) {
+ case MSGERROR_CANCEL:
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETREADONLY, FALSE, 0);
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ break;
+ case MSGERROR_RETRY:
+ {
+ if (dat->hSendId == NULL && dat->hContact == NULL)
+ return 0;
+ dat->hSendId = (HANDLE) CallContactService(dat->hContact, MsgServiceName(dat->hContact), SEND_FLAGS, (LPARAM) dat->sendBuffer);
+ }
+ SetTimer(hwndDlg, TIMERID_MSGSEND, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_MSGTIMEOUT, SRMSGDEFSET_MSGTIMEOUT), NULL);
+ break;
+ }
+ break;
+ case WM_CTLCOLOREDIT:
+ {
+ COLORREF colour;
+ if ((HWND) lParam != GetDlgItem(hwndDlg, IDC_MESSAGE))
+ break;
+ LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &colour);
+ SetTextColor((HDC) wParam, colour);
+ SetBkColor((HDC) wParam, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR));
+ return (BOOL) dat->hBkgBrush;
+ }
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ case WM_DRAWITEM:
+ {
+ LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT) lParam;
+ if (dis->hwndItem == GetDlgItem(hwndDlg, IDC_PROTOCOL)) {
+ if (dat->szProto) {
+ HICON hIcon;
+ int dwStatus;
+
+ dwStatus = DBGetContactSettingWord(dat->hContact, dat->szProto, "Status", ID_STATUS_OFFLINE);
+ hIcon = LoadSkinnedProtoIcon(dat->szProto, dwStatus);
+ if (hIcon) {
+ if (DBGetContactSettingDword(dat->hContact, dat->szProto, "IdleTS", 0)) {
+ HIMAGELIST hImageList;
+
+ hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON), IsWinVerXPPlus()? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 1, 0);
+ ImageList_AddIcon(hImageList, hIcon);
+ ImageList_DrawEx(hImageList, 0, dis->hDC, dis->rcItem.left, dis->rcItem.top, 0, 0, CLR_NONE, CLR_NONE, ILD_SELECTED);
+ ImageList_RemoveAll(hImageList);
+ ImageList_Destroy(hImageList);
+ }
+ else DrawIconEx(dis->hDC, dis->rcItem.left, dis->rcItem.top, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL);
+ }
+ }
+ }
+ else if (dis->hwndItem == GetDlgItem(hwndDlg, IDC_AVATAR) && dat->avatarPic && (g_dat->flags&SMF_AVATAR)) {
+ BITMAP bminfo;
+ HPEN hPen, hOldPen;
+
+ hPen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
+ hOldPen = SelectObject(dis->hDC, hPen);
+ Rectangle(dis->hDC, 0, 0, dat->avatarWidth, dat->avatarHeight);
+ SelectObject(dis->hDC,hOldPen);
+ DeleteObject(hPen);
+ GetObject(dat->avatarPic, sizeof(bminfo), &bminfo);
+ {
+ HDC hdcMem = CreateCompatibleDC(dis->hDC);
+ HBITMAP hbmMem = (HBITMAP)SelectObject(hdcMem, dat->avatarPic);
+ {
+ double aspect = 0, w = 0;
+
+ aspect = (double)dat->limitAvatarH / (double)bminfo.bmHeight;
+ w = (double)bminfo.bmWidth * aspect;
+ SetStretchBltMode(dis->hDC, HALFTONE);
+ StretchBlt(dis->hDC, 1, 1, dat->avatarWidth-2, dat->avatarHeight-2, hdcMem, 0, 0, bminfo.bmWidth, bminfo.bmHeight, SRCCOPY);
+ }
+ SelectObject(hdcMem,hbmMem);
+ DeleteDC(hdcMem);
+ }
+ }
+ 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 IDOK:
+ if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDOK)))
+ break;
+ {
+ int flags = SEND_FLAGS;
+ //this is a 'send' button
+ int bufSize = GetWindowTextLengthA(GetDlgItem(hwndDlg, IDC_MESSAGE)) + 1;
+ dat->sendBuffer = (char *) realloc(dat->sendBuffer, bufSize * (sizeof(TCHAR) + 1));
+ dat->bIsRtl = 0;
+ GetDlgItemTextA(hwndDlg, IDC_MESSAGE, dat->sendBuffer, bufSize);
+ #if defined( _UNICODE )
+ // all that crap with temporary buffers is related to the bug #0001466 (empty messages
+ // on x64 machines). GetDlgItemTextW should use the 2-byte aligned buffer
+ { WCHAR* temp = ( WCHAR* )alloca( bufSize * sizeof( TCHAR ));
+ GetDlgItemTextW(hwndDlg, IDC_MESSAGE, temp, bufSize);
+ memcpy(( TCHAR*)&dat->sendBuffer[bufSize], temp, bufSize * sizeof( TCHAR ));
+ if ( RTL_Detect( temp )) {
+ flags |= PREF_RTL;
+ dat->bIsRtl = 1;
+ }
+ }
+ #endif
+ if (dat->sendBuffer[0] == 0)
+ break;
+ #if defined( _UNICODE )
+ dat->cmdList = tcmdlist_append(dat->cmdList, (TCHAR *) & dat->sendBuffer[bufSize]);
+ #else
+ dat->cmdList = tcmdlist_append(dat->cmdList, dat->sendBuffer);
+ #endif
+ dat->cmdListCurrent = 0;
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_ON) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_OFF);
+ }
+
+ if (dat->hContact == NULL)
+ break; //never happens
+ dat->sendCount = 1;
+ dat->hSendId = (HANDLE) CallContactService(dat->hContact, MsgServiceName(dat->hContact), flags, (LPARAM) dat->sendBuffer);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETREADONLY, TRUE, 0);
+
+ //create a timeout timer
+ SetTimer(hwndDlg, TIMERID_MSGSEND, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_MSGTIMEOUT, SRMSGDEFSET_MSGTIMEOUT), NULL);
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOMIN, SRMSGDEFSET_AUTOMIN))
+ ShowWindow(hwndDlg, SW_MINIMIZE);
+ }
+ return TRUE;
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ return TRUE;
+ case IDC_USERMENU:
+ case IDC_NAME:
+ {
+ if(GetKeyState(VK_SHIFT) & 0x8000) { // copy user name
+ SendMessage(hwndDlg, DM_USERNAMETOCLIP, 0, 0);
+ }
+ else {
+ RECT rc;
+ HMENU hMenu = (HMENU) CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM) dat->hContact, 0);
+ GetWindowRect(GetDlgItem(hwndDlg, LOWORD(wParam)), &rc);
+ TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL);
+ DestroyMenu(hMenu);
+ }
+ }
+ break;
+ case IDC_HISTORY:
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM) dat->hContact, 0);
+ break;
+ case IDC_DETAILS:
+ CallService(MS_USERINFO_SHOWDIALOG, (WPARAM) dat->hContact, 0);
+ break;
+ case IDC_ADD:
+ {
+ ADDCONTACTSTRUCT acs = { 0 };
+
+ acs.handle = dat->hContact;
+ acs.handleType = HANDLE_CONTACT;
+ acs.szProto = 0;
+ CallService(MS_ADDCONTACT_SHOW, (WPARAM) hwndDlg, (LPARAM) & acs);
+ }
+ if (!DBGetContactSettingByte(dat->hContact, "CList", "NotOnList", 0)) {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE);
+ }
+ break;
+ case IDC_MESSAGE:
+ if (HIWORD(wParam) == EN_CHANGE) {
+ int len = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ UpdateReadChars(hwndDlg, dat->hwndStatus);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), len != 0);
+ if (!(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000)) {
+ dat->nLastTyping = GetTickCount();
+ if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE))) {
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_OFF) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_ON);
+ }
+ }
+ else {
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_ON) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_OFF);
+ }
+ }
+ }
+ }
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((NMHDR *) lParam)->idFrom) {
+ case IDC_LOG:
+ switch (((NMHDR *) lParam)->code) {
+ case EN_MSGFILTER:
+ switch (((MSGFILTER *) lParam)->msg) {
+ case WM_LBUTTONDOWN:
+ {
+ HCURSOR hCur = GetCursor();
+ if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE)
+ || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE)) {
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
+ }
+ case WM_MOUSEMOVE:
+ {
+ HCURSOR hCur = GetCursor();
+ if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE)
+ || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE))
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ break;
+ }
+ case WM_RBUTTONUP:
+ {
+ HMENU hMenu, hSubMenu;
+ POINT pt;
+ CHARRANGE sel, all = { 0, -1 };
+
+ hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT));
+ hSubMenu = GetSubMenu(hMenu, 0);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0);
+ SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXGETSEL, 0, (LPARAM) & sel);
+ if (sel.cpMin == sel.cpMax)
+ EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED);
+ pt.x = (short) LOWORD(((ENLINK *) lParam)->lParam);
+ pt.y = (short) HIWORD(((ENLINK *) lParam)->lParam);
+ ClientToScreen(((NMHDR *) lParam)->hwndFrom, &pt);
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) {
+ case IDM_COPY:
+ SendMessage(((NMHDR *) lParam)->hwndFrom, WM_COPY, 0, 0);
+ break;
+ case IDM_COPYALL:
+ SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & all);
+ SendMessage(((NMHDR *) lParam)->hwndFrom, WM_COPY, 0, 0);
+ SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & sel);
+ break;
+ case IDM_SELECTALL:
+ SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & all);
+ break;
+ case IDM_CLEAR:
+ SetDlgItemText(hwndDlg, IDC_LOG, _T(""));
+ dat->hDbEventFirst = NULL;
+ break;
+ }
+ DestroyMenu(hMenu);
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ }
+ break;
+ case EN_LINK:
+ switch (((ENLINK *) lParam)->msg) {
+ case WM_SETCURSOR:
+ SetCursor(hCurHyperlinkHand);
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, TRUE);
+ return TRUE;
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONUP:
+ {
+ TEXTRANGEA tr;
+ CHARRANGE sel;
+
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXGETSEL, 0, (LPARAM) & sel);
+ if (sel.cpMin != sel.cpMax)
+ break;
+ tr.chrg = ((ENLINK *) lParam)->chrg;
+ tr.lpstrText = malloc(tr.chrg.cpMax - tr.chrg.cpMin + 8);
+ SendDlgItemMessageA(hwndDlg, IDC_LOG, EM_GETTEXTRANGE, 0, (LPARAM) & tr);
+ if (strchr(tr.lpstrText, '@') != NULL && strchr(tr.lpstrText, ':') == NULL && strchr(tr.lpstrText, '/') == NULL) {
+ MoveMemory(tr.lpstrText + 7, tr.lpstrText, tr.chrg.cpMax - tr.chrg.cpMin + 1);
+ CopyMemory(tr.lpstrText, "mailto:", 7);
+ }
+ if (((ENLINK *) lParam)->msg == WM_RBUTTONDOWN) {
+ HMENU hMenu, hSubMenu;
+ POINT pt;
+
+ hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT));
+ hSubMenu = GetSubMenu(hMenu, 1);
+ CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0);
+ pt.x = (short) LOWORD(((ENLINK *) lParam)->lParam);
+ pt.y = (short) HIWORD(((ENLINK *) lParam)->lParam);
+ ClientToScreen(((NMHDR *) lParam)->hwndFrom, &pt);
+ switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) {
+ case IDM_OPENNEW:
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM) tr.lpstrText);
+ break;
+ case IDM_OPENEXISTING:
+ CallService(MS_UTILS_OPENURL, 0, (LPARAM) tr.lpstrText);
+ break;
+ case IDM_COPYLINK:
+ {
+ HGLOBAL hData;
+ if (!OpenClipboard(hwndDlg))
+ break;
+ EmptyClipboard();
+ hData = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(tr.lpstrText) + 1);
+ lstrcpyA(GlobalLock(hData), tr.lpstrText);
+ GlobalUnlock(hData);
+ SetClipboardData(CF_TEXT, hData);
+ CloseClipboard();
+ break;
+ }
+ }
+ free(tr.lpstrText);
+ DestroyMenu(hMenu);
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ else {
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM) tr.lpstrText);
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ }
+
+ free(tr.lpstrText);
+ break;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ case HM_EVENTSENT:
+ {
+ ACKDATA *ack = (ACKDATA *) lParam;
+ DBEVENTINFO dbei = { 0 };
+ HANDLE hNewEvent;
+
+ if (ack->type != ACKTYPE_MESSAGE)
+ break;
+ if (dat->sendCount==0)
+ break;
+ switch (ack->result) {
+ case ACKRESULT_FAILED:
+ KillTimer(hwndDlg, TIMERID_MSGSEND);
+ ShowWindow(hwndDlg, SW_SHOWNORMAL);
+ EnableWindow(hwndDlg, FALSE);
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGSENDERROR), hwndDlg, ErrorDlgProc, (ack->lParam == 0) ? 0 : (LPARAM) strdup((char *) ack->lParam));
+ return 0;
+ }
+ if (dat->sendBuffer==NULL) return 0;
+ dbei.cbSize = sizeof(dbei);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_SENT + (( dat->bIsRtl ) ? DBEF_RTL : 0 );
+
+ dbei.szModule = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) dat->hContact, 0);
+ dbei.timestamp = time(NULL);
+ dbei.cbBlob = lstrlenA(dat->sendBuffer) + 1;
+ #if defined( _UNICODE )
+ dbei.cbBlob *= sizeof(TCHAR) + 1;
+ #endif
+ dbei.pBlob = (PBYTE) dat->sendBuffer;
+ hNewEvent = (HANDLE) CallService(MS_DB_EVENT_ADD, (WPARAM) dat->hContact, (LPARAM) & dbei);
+ SkinPlaySound("SendMsg");
+ if (dat->hDbEventFirst == NULL) {
+ dat->hDbEventFirst = hNewEvent;
+ SendMessage(hwndDlg, DM_REMAKELOG, 0, 0);
+ }
+
+ dat->hSendId = NULL;
+ {
+ int len;
+ //all messages sent
+ dat->sendCount = 0;
+ KillTimer(hwndDlg, TIMERID_MSGSEND);
+ SetDlgItemText(hwndDlg, IDC_MESSAGE, _T(""));
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_SETREADONLY, FALSE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_REPLAYSAVEDKEYSTROKES, 0, 0);
+ if (GetForegroundWindow() == hwndDlg)
+ SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ len = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_MESSAGE));
+ UpdateReadChars(hwndDlg, dat->hwndStatus);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), len != 0);
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOCLOSE, SRMSGDEFSET_AUTOCLOSE))
+ DestroyWindow(hwndDlg);
+ }
+ break;
+ }
+ case WM_DESTROY:
+ NotifyLocalWinEvent(dat->hContact, hwndDlg, MSG_WINDOW_EVT_CLOSING);
+ if (dat->nTypeMode == PROTOTYPE_SELFTYPING_ON) {
+ NotifyTyping(dat, PROTOTYPE_SELFTYPING_OFF);
+ }
+ if (dat->hBkgBrush)
+ DeleteObject(dat->hBkgBrush);
+ if (dat->sendBuffer != NULL)
+ free(dat->sendBuffer);
+ if (dat->hwndStatus)
+ DestroyWindow(dat->hwndStatus);
+ tcmdlist_free(dat->cmdList);
+ WindowList_Remove(g_dat->hMessageWindowList, hwndDlg);
+ DBWriteContactSettingDword(DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT)?dat->hContact:NULL, SRMMMOD, "splitterPos", dat->splitterPos);
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_SPLITTER), GWL_WNDPROC, (LONG) OldSplitterProc);
+ SendDlgItemMessage(hwndDlg, IDC_MESSAGE, EM_UNSUBCLASSED, 0, 0);
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_MESSAGE), GWL_WNDPROC, (LONG) OldMessageEditProc);
+ {
+ HFONT hFont;
+ hFont = (HFONT) SendDlgItemMessage(hwndDlg, IDC_MESSAGE, WM_GETFONT, 0, 0);
+ if (hFont != NULL && hFont != (HFONT) SendDlgItemMessage(hwndDlg, IDOK, WM_GETFONT, 0, 0))
+ DeleteObject(hFont);
+ }
+ {
+ WINDOWPLACEMENT wp = { 0 };
+ HANDLE hContact;
+
+ if (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT))
+ hContact = dat->hContact;
+ else
+ hContact = NULL;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(hwndDlg, &wp);
+ if (!dat->windowWasCascaded) {
+ DBWriteContactSettingDword(hContact, SRMMMOD, "x", wp.rcNormalPosition.left);
+ DBWriteContactSettingDword(hContact, SRMMMOD, "y", wp.rcNormalPosition.top);
+ }
+ DBWriteContactSettingDword(hContact, SRMMMOD, "width", wp.rcNormalPosition.right - wp.rcNormalPosition.left);
+ DBWriteContactSettingDword(hContact, SRMMMOD, "height", wp.rcNormalPosition.bottom - wp.rcNormalPosition.top);
+ }
+ if (dat->avatarPic)
+ DeleteObject(dat->avatarPic);
+ NotifyLocalWinEvent(dat->hContact, hwndDlg, MSG_WINDOW_EVT_CLOSE);
+ if (dat->hContact&&DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_DELTEMP, SRMSGDEFSET_DELTEMP)) {
+ if (DBGetContactSettingByte(dat->hContact, "CList", "NotOnList", 0)) {
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)dat->hContact, 0);
+ }
+ }
+ free(dat);
+ SetWindowLong(hwndDlg, GWL_USERDATA, 0);
+ break;
+ }
+ return FALSE;
+}
diff --git a/miranda-wine/plugins/srmm/msglog.c b/miranda-wine/plugins/srmm/msglog.c new file mode 100644 index 0000000..a988868 --- /dev/null +++ b/miranda-wine/plugins/srmm/msglog.c @@ -0,0 +1,549 @@ +/*
+SRMM
+
+Copyright 2000-2005 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"
+#pragma hdrstop
+#include <ctype.h>
+#include <malloc.h>
+#include <mbstring.h>
+
+extern HINSTANCE g_hInst;
+
+static int logPixelSY;
+#define LOGICON_MSG_IN 0
+#define LOGICON_MSG_OUT 1
+#define LOGICON_MSG_NOTICE 2
+static PBYTE pLogIconBmpBits[3];
+static int logIconBmpSize[ SIZEOF(pLogIconBmpBits) ];
+static HIMAGELIST g_hImageList;
+
+#define STREAMSTAGE_HEADER 0
+#define STREAMSTAGE_EVENTS 1
+#define STREAMSTAGE_TAIL 2
+#define STREAMSTAGE_STOP 3
+struct LogStreamData
+{
+ int stage;
+ HANDLE hContact;
+ HANDLE hDbEvent, hDbEventLast;
+ char *buffer;
+ int bufferOffset, bufferLen;
+ int eventsToInsert;
+ int isEmpty;
+ struct MessageWindowData *dlgDat;
+};
+
+static char szSep2[40], szSep2_RTL[50];
+
+static void AppendToBuffer(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, const char *fmt, ...)
+{
+ va_list va;
+ int charsDone;
+
+ va_start(va, fmt);
+ for (;;) {
+ charsDone = mir_vsnprintf(*buffer + *cbBufferEnd, *cbBufferAlloced - *cbBufferEnd, fmt, va);
+ if (charsDone >= 0)
+ break;
+ *cbBufferAlloced += 1024;
+ *buffer = (char *) realloc(*buffer, *cbBufferAlloced);
+ }
+ va_end(va);
+ *cbBufferEnd += charsDone;
+}
+
+static int AppendToBufferWithRTF(char **buffer, int *cbBufferEnd, int *cbBufferAlloced, TCHAR* line)
+{
+ DWORD textCharsCount = 0;
+ char *d;
+
+ int lineLen = _tcslen(line) * 9 + 8;
+ if (*cbBufferEnd + lineLen > *cbBufferAlloced) {
+ cbBufferAlloced[0] += (lineLen + 1024 - lineLen % 1024);
+ *buffer = (char *) realloc(*buffer, *cbBufferAlloced);
+ }
+
+ d = *buffer + *cbBufferEnd;
+ strcpy(d, "{\\uc1 ");
+ d += 6;
+
+ for (; *line; line++, textCharsCount++) {
+ if (*line == '\r' && line[1] == '\n') {
+ CopyMemory(d, "\\par ", 5);
+ line++;
+ d += 5;
+ }
+ else if (*line == '\n') {
+ CopyMemory(d, "\\par ", 5);
+ d += 5;
+ }
+ else if (*line == '\t') {
+ CopyMemory(d, "\\tab ", 5);
+ d += 5;
+ }
+ else if (*line == '\\' || *line == '{' || *line == '}') {
+ *d++ = '\\';
+ *d++ = (char) *line;
+ }
+ else if (*line < 128) {
+ *d++ = (char) *line;
+ }
+ else d += sprintf(d, "\\u%d ?", *line);
+ }
+
+ strcpy(d, "}");
+ d++;
+
+ *cbBufferEnd = (int) (d - *buffer);
+ return textCharsCount;
+}
+
+#if defined( _UNICODE )
+ #define FONT_FORMAT "{\\f%u\\fnil\\fcharset%u %S;}"
+#else
+ #define FONT_FORMAT "{\\f%u\\fnil\\fcharset%u %s;}"
+#endif
+
+static char *CreateRTFHeader(struct MessageWindowData *dat)
+{
+ char *buffer;
+ int bufferAlloced, bufferEnd;
+ int i;
+ LOGFONT lf;
+ COLORREF colour;
+ HDC hdc;
+
+ hdc = GetDC(NULL);
+ logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+ bufferEnd = 0;
+ bufferAlloced = 1024;
+ buffer = (char *) malloc(bufferAlloced);
+ buffer[0] = '\0';
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "{\\rtf1\\ansi\\deff0{\\fonttbl");
+
+ for (i = 0; i < msgDlgFontCount; i++) {
+ LoadMsgDlgFont(i, &lf, NULL);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, FONT_FORMAT, i, lf.lfCharSet, lf.lfFaceName);
+ }
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}{\\colortbl ");
+ for (i = 0; i < msgDlgFontCount; i++) {
+ LoadMsgDlgFont(i, NULL, &colour);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour));
+ }
+ if (GetSysColorBrush(COLOR_HOTLIGHT) == NULL)
+ colour = RGB(0, 0, 255);
+ else
+ colour = GetSysColor(COLOR_HOTLIGHT);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\red%u\\green%u\\blue%u;", GetRValue(colour), GetGValue(colour), GetBValue(colour));
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}");
+ //AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}\\pard");
+ return buffer;
+}
+
+//free() the return value
+static char *CreateRTFTail(struct MessageWindowData *dat)
+{
+ char *buffer;
+ int bufferAlloced, bufferEnd;
+
+ bufferEnd = 0;
+ bufferAlloced = 1024;
+ buffer = (char *) malloc(bufferAlloced);
+ buffer[0] = '\0';
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "}");
+ return buffer;
+}
+
+//return value is static
+static char *SetToStyle(int style)
+{
+ static char szStyle[128];
+ LOGFONT lf;
+
+ LoadMsgDlgFont(style, &lf, NULL);
+ wsprintfA(szStyle, "\\f%u\\cf%u\\b%d\\i%d\\fs%u", style, style, lf.lfWeight >= FW_BOLD ? 1 : 0, lf.lfItalic, 2 * abs(lf.lfHeight) * 74 / logPixelSY);
+ return szStyle;
+}
+
+int DbEventIsShown(DBEVENTINFO * dbei, struct MessageWindowData *dat)
+{
+ switch (dbei->eventType) {
+ case EVENTTYPE_MESSAGE:
+ return 1;
+ case EVENTTYPE_STATUSCHANGE:
+ if (dbei->flags & DBEF_READ)
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+//free() the return value
+static char *CreateRTFFromDbEvent(struct MessageWindowData *dat, HANDLE hContact, HANDLE hDbEvent, struct LogStreamData *streamData)
+{
+ char *buffer;
+ int bufferAlloced, bufferEnd;
+ DBEVENTINFO dbei = { 0 };
+ int showColon = 0;
+
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM) hDbEvent, 0);
+ if (dbei.cbBlob == -1)
+ return NULL;
+ dbei.pBlob = (PBYTE) malloc(dbei.cbBlob);
+ CallService(MS_DB_EVENT_GET, (WPARAM) hDbEvent, (LPARAM) & dbei);
+ if (!DbEventIsShown(&dbei, dat)) {
+ free(dbei.pBlob);
+ return NULL;
+ }
+ if (!(dbei.flags & DBEF_SENT) && dbei.eventType == EVENTTYPE_MESSAGE) {
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM) hContact, (LPARAM) hDbEvent);
+ CallService(MS_CLIST_REMOVEEVENT, (WPARAM) hContact, (LPARAM) hDbEvent);
+ }
+ else if (dbei.eventType == EVENTTYPE_STATUSCHANGE) {
+ CallService(MS_DB_EVENT_MARKREAD, (WPARAM) hContact, (LPARAM) hDbEvent);
+ }
+ bufferEnd = 0;
+ bufferAlloced = 1024;
+ buffer = (char *) malloc(bufferAlloced);
+ buffer[0] = '\0';
+
+ if (!dat->bIsAutoRTL && !streamData->isEmpty)
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\par");
+
+ if (dbei.flags & DBEF_RTL) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\rtlpar");
+ dat->bIsAutoRTL = TRUE;
+ }
+ else
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\ltrpar");
+
+ streamData->isEmpty = 0;
+
+ if (dat->bIsAutoRTL) {
+ if(dbei.flags & DBEF_RTL) {
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\ltrch\\rtlch");
+ }else{
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\rtlch\\ltrch");
+ }
+ }
+
+ if (g_dat->flags&SMF_SHOWICONS) {
+ int i;
+
+ switch (dbei.eventType) {
+ case EVENTTYPE_MESSAGE:
+ if (dbei.flags & DBEF_SENT) {
+ i = LOGICON_MSG_OUT;
+ }
+ else {
+ i = LOGICON_MSG_IN;
+ }
+ break;
+ case EVENTTYPE_STATUSCHANGE:
+ i = LOGICON_MSG_NOTICE;
+ break;
+ }
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\f0\\fs14");
+ while (bufferAlloced - bufferEnd < logIconBmpSize[i])
+ bufferAlloced += 1024;
+ buffer = (char *) realloc(buffer, bufferAlloced);
+ CopyMemory(buffer + bufferEnd, pLogIconBmpBits[i], logIconBmpSize[i]);
+ bufferEnd += logIconBmpSize[i];
+ }
+ if (g_dat->flags&SMF_SHOWTIME) {
+ DBTIMETOSTRINGT dbtts;
+ TCHAR str[64];
+
+ if (g_dat->flags&SMF_SHOWSECS)
+ dbtts.szFormat = g_dat->flags&SMF_SHOWDATE ? _T("d s") : _T("s");
+ else
+ dbtts.szFormat = g_dat->flags&SMF_SHOWDATE ? _T("d t") : _T("t");
+ dbtts.cbDest = SIZEOF(str);
+ dbtts.szDest = str;
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, dbei.timestamp, (LPARAM)&dbtts);
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " %s ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYTIME : MSGFONTID_YOURTIME));
+ AppendToBufferWithRTF(&buffer, &bufferEnd, &bufferAlloced, str);
+ showColon = 1;
+ }
+ if (!(g_dat->flags&SMF_HIDENAMES) && dbei.eventType != EVENTTYPE_STATUSCHANGE) {
+ TCHAR* szName;
+ CONTACTINFO ci;
+ ZeroMemory(&ci, sizeof(ci));
+
+ if (dbei.flags & DBEF_SENT) {
+ ci.cbSize = sizeof(ci);
+ ci.hContact = NULL;
+ ci.szProto = dbei.szModule;
+ ci.dwFlag = CNF_DISPLAY;
+ #if defined( _UNICODE )
+ ci.dwFlag += CNF_UNICODE;
+ #endif
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ // CNF_DISPLAY always returns a string type
+ szName = ( TCHAR* )ci.pszVal;
+ }
+ }
+ else szName = ( TCHAR* ) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR);
+
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " %s ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYNAME : MSGFONTID_YOURNAME));
+ AppendToBufferWithRTF(&buffer, &bufferEnd, &bufferAlloced, szName);
+ showColon = 1;
+ if (ci.pszVal)
+ miranda_sys_free(ci.pszVal);
+ }
+
+ if (showColon)
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "%s :", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYCOLON : MSGFONTID_YOURCOLON));
+
+ switch (dbei.eventType) {
+ case EVENTTYPE_MESSAGE:
+ {
+ TCHAR* msg;
+
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " %s ", SetToStyle(dbei.flags & DBEF_SENT ? MSGFONTID_MYMSG : MSGFONTID_YOURMSG));
+
+ #if defined( _UNICODE )
+ {
+ int msglen = strlen((char *) dbei.pBlob) + 1;
+ if (msglen != (int) dbei.cbBlob)
+ msg = (TCHAR *) & dbei.pBlob[msglen];
+ else {
+ msg = (TCHAR *) alloca(sizeof(TCHAR) * msglen);
+ MultiByteToWideChar(CP_ACP, 0, (char *) dbei.pBlob, -1, msg, msglen);
+ }
+ }
+ #else
+ msg = (BYTE *) dbei.pBlob;
+ #endif
+ AppendToBufferWithRTF(&buffer, &bufferEnd, &bufferAlloced, msg);
+ break;
+ }
+ case EVENTTYPE_STATUSCHANGE:
+ {
+ TCHAR *msg, *szName;
+ CONTACTINFO ci;
+ ZeroMemory(&ci, sizeof(ci));
+
+ if (dbei.flags & DBEF_SENT) {
+ ci.cbSize = sizeof(ci);
+ ci.hContact = NULL;
+ ci.szProto = dbei.szModule;
+ ci.dwFlag = CNF_DISPLAY;
+ #if defined( _UNICODE )
+ ci.dwFlag += CNF_UNICODE;
+ #endif
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ // CNF_DISPLAY always returns a string type
+ szName = ( TCHAR* )ci.pszVal;
+ }
+ }
+ else szName = ( TCHAR* )CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR);
+
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, " %s ", SetToStyle(MSGFONTID_NOTICE));
+ AppendToBufferWithRTF(&buffer, &bufferEnd, &bufferAlloced, szName);
+ AppendToBufferWithRTF(&buffer, &bufferEnd, &bufferAlloced, _T(" "));
+ #if defined( _UNICODE )
+ {
+ int msglen = strlen((char *) dbei.pBlob) + 1;
+ msg = ( TCHAR* )alloca(sizeof(TCHAR) * msglen);
+ MultiByteToWideChar(CP_ACP, 0, (char *) dbei.pBlob, -1, msg, msglen);
+ }
+ #else
+ msg = (BYTE *) dbei.pBlob;
+ #endif
+ AppendToBufferWithRTF(&buffer, &bufferEnd, &bufferAlloced, msg);
+ if (ci.pszVal)
+ miranda_sys_free(ci.pszVal);
+ break;
+ }
+ }
+ if(dat->bIsAutoRTL)
+ AppendToBuffer(&buffer, &bufferEnd, &bufferAlloced, "\\par");
+
+ dat->lastEventType = dbei.flags;
+ free(dbei.pBlob);
+ return buffer;
+}
+
+static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb)
+{
+ struct LogStreamData *dat = (struct LogStreamData *) dwCookie;
+
+ if (dat->buffer == NULL) {
+ dat->bufferOffset = 0;
+ switch (dat->stage) {
+ case STREAMSTAGE_HEADER:
+ dat->buffer = CreateRTFHeader(dat->dlgDat);
+ dat->stage = STREAMSTAGE_EVENTS;
+ break;
+ case STREAMSTAGE_EVENTS:
+ if (dat->eventsToInsert) {
+ do {
+ dat->buffer = CreateRTFFromDbEvent(dat->dlgDat, dat->hContact, dat->hDbEvent, dat);
+ if (dat->buffer)
+ dat->hDbEventLast = dat->hDbEvent;
+ dat->hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) dat->hDbEvent, 0);
+ if (--dat->eventsToInsert == 0)
+ break;
+ } while (dat->buffer == NULL && dat->hDbEvent);
+ if (dat->buffer) {
+ dat->isEmpty = 0;
+ break;
+ }
+ }
+ dat->stage = STREAMSTAGE_TAIL;
+ //fall through
+ case STREAMSTAGE_TAIL:
+ dat->buffer = CreateRTFTail(dat->dlgDat);
+ dat->stage = STREAMSTAGE_STOP;
+ break;
+ case STREAMSTAGE_STOP:
+ *pcb = 0;
+ return 0;
+ }
+ dat->bufferLen = lstrlenA(dat->buffer);
+ }
+ *pcb = min(cb, dat->bufferLen - dat->bufferOffset);
+ CopyMemory(pbBuff, dat->buffer + dat->bufferOffset, *pcb);
+ dat->bufferOffset += *pcb;
+ if (dat->bufferOffset == dat->bufferLen) {
+ free(dat->buffer);
+ dat->buffer = NULL;
+ }
+ return 0;
+}
+
+void StreamInEvents(HWND hwndDlg, HANDLE hDbEventFirst, int count, int fAppend)
+{
+ EDITSTREAM stream = { 0 };
+ struct LogStreamData streamData = { 0 };
+ struct MessageWindowData *dat = (struct MessageWindowData *) GetWindowLong(hwndDlg, GWL_USERDATA);
+ CHARRANGE oldSel, sel;
+
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_HIDESELECTION, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXGETSEL, 0, (LPARAM) & oldSel);
+ streamData.hContact = dat->hContact;
+ streamData.hDbEvent = hDbEventFirst;
+ streamData.dlgDat = dat;
+ streamData.eventsToInsert = count;
+ streamData.isEmpty = fAppend ? GetWindowTextLength(GetDlgItem(hwndDlg, IDC_LOG)) == 0 : 1;
+ stream.pfnCallback = LogStreamInEvents;
+ stream.dwCookie = (DWORD_PTR) & streamData;
+ if (fAppend) {
+ sel.cpMin = sel.cpMax = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_LOG));
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXSETSEL, 0, (LPARAM) & sel);
+ }
+ else dat->bIsFirstAppend = TRUE;
+
+ strcpy(szSep2, fAppend ? "\\par\\sl0" : "\\sl1000");
+ strcpy(szSep2_RTL, fAppend ? "\\rtlpar\\rtlmark\\par\\sl1000" : "\\sl1000");
+
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_STREAMIN, fAppend ? SFF_SELECTION | SF_RTF : SFF_SELECTION | SF_RTF, (LPARAM) & stream);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXSETSEL, 0, (LPARAM) & oldSel);
+ SendDlgItemMessage(hwndDlg, IDC_LOG, EM_HIDESELECTION, FALSE, 0);
+ dat->hDbEventLast = streamData.hDbEventLast;
+ if (GetWindowLong(GetDlgItem(hwndDlg, IDC_LOG), GWL_STYLE) & WS_VSCROLL)
+ PostMessage(hwndDlg, DM_SCROLLLOGTOBOTTOM, 0, 0);
+}
+
+#define RTFPICTHEADERMAXSIZE 78
+void LoadMsgLogIcons(void)
+{
+ HICON hIcon;
+ HBITMAP hBmp, hoBmp;
+ HDC hdc, hdcMem;
+ BITMAPINFOHEADER bih = { 0 };
+ int widthBytes, i;
+ RECT rc;
+ HBRUSH hBkgBrush;
+ int rtfHeaderSize;
+ PBYTE pBmpBits;
+
+ g_hImageList = ImageList_Create(10, 10, IsWinVerXPPlus()? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, SIZEOF(pLogIconBmpBits), 0);
+ hBkgBrush = CreateSolidBrush(DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR));
+ bih.biSize = sizeof(bih);
+ bih.biBitCount = 24;
+ bih.biCompression = BI_RGB;
+ bih.biHeight = 10;
+ bih.biPlanes = 1;
+ bih.biWidth = 10;
+ widthBytes = ((bih.biWidth * bih.biBitCount + 31) >> 5) * 4;
+ rc.top = rc.left = 0;
+ rc.right = bih.biWidth;
+ rc.bottom = bih.biHeight;
+ hdc = GetDC(NULL);
+ hBmp = CreateCompatibleBitmap(hdc, bih.biWidth, bih.biHeight);
+ hdcMem = CreateCompatibleDC(hdc);
+ pBmpBits = (PBYTE) malloc(widthBytes * bih.biHeight);
+ for (i = 0; i < SIZEOF(pLogIconBmpBits); i++) {
+ switch (i) {
+ case LOGICON_MSG_IN:
+ hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_INCOMING));
+ ImageList_AddIcon(g_hImageList, hIcon);
+ hIcon = ImageList_GetIcon(g_hImageList, LOGICON_MSG_IN, ILD_NORMAL);
+ break;
+ case LOGICON_MSG_OUT:
+ hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_OUTGOING));
+ ImageList_AddIcon(g_hImageList, hIcon);
+ hIcon = ImageList_GetIcon(g_hImageList, LOGICON_MSG_OUT, ILD_NORMAL);
+ break;
+ case LOGICON_MSG_NOTICE:
+ hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_NOTICE));
+ ImageList_AddIcon(g_hImageList, hIcon);
+ hIcon = ImageList_GetIcon(g_hImageList, LOGICON_MSG_NOTICE, ILD_NORMAL);
+ break;
+ }
+ pLogIconBmpBits[i] = (PBYTE) malloc(RTFPICTHEADERMAXSIZE + (bih.biSize + widthBytes * bih.biHeight) * 2);
+ //I can't seem to get binary mode working. No matter.
+ rtfHeaderSize = sprintf(pLogIconBmpBits[i], "{\\pict\\dibitmap0\\wbmbitspixel%u\\wbmplanes1\\wbmwidthbytes%u\\picw%u\\pich%u ", bih.biBitCount, widthBytes, bih.biWidth, bih.biHeight);
+ hoBmp = (HBITMAP) SelectObject(hdcMem, hBmp);
+ FillRect(hdcMem, &rc, hBkgBrush);
+ DrawIconEx(hdcMem, 0, 0, hIcon, bih.biWidth, bih.biHeight, 0, NULL, DI_NORMAL);
+ SelectObject(hdcMem, hoBmp);
+ GetDIBits(hdc, hBmp, 0, bih.biHeight, pBmpBits, (BITMAPINFO *) & bih, DIB_RGB_COLORS);
+ DestroyIcon(hIcon);
+ {
+ int n;
+ for (n = 0; n < sizeof(BITMAPINFOHEADER); n++)
+ sprintf(pLogIconBmpBits[i] + rtfHeaderSize + n * 2, "%02X", ((PBYTE) & bih)[n]);
+ for (n = 0; n < widthBytes * bih.biHeight; n += 4)
+ sprintf(pLogIconBmpBits[i] + rtfHeaderSize + (bih.biSize + n) * 2, "%02X%02X%02X%02X", pBmpBits[n], pBmpBits[n + 1], pBmpBits[n + 2], pBmpBits[n + 3]);
+ }
+ logIconBmpSize[i] = rtfHeaderSize + (bih.biSize + widthBytes * bih.biHeight) * 2 + 1;
+ pLogIconBmpBits[i][logIconBmpSize[i] - 1] = '}';
+ }
+ free(pBmpBits);
+ DeleteDC(hdcMem);
+ DeleteObject(hBmp);
+ ReleaseDC(NULL, hdc);
+ DeleteObject(hBkgBrush);
+}
+
+void FreeMsgLogIcons(void)
+{
+ int i;
+ for (i = 0; i < SIZEOF(pLogIconBmpBits); i++)
+ free(pLogIconBmpBits[i]);
+ ImageList_RemoveAll(g_hImageList);
+ ImageList_Destroy(g_hImageList);
+}
diff --git a/miranda-wine/plugins/srmm/msgoptions.c b/miranda-wine/plugins/srmm/msgoptions.c new file mode 100644 index 0000000..4bb89e7 --- /dev/null +++ b/miranda-wine/plugins/srmm/msgoptions.c @@ -0,0 +1,723 @@ +/*
+SRMM
+
+Copyright 2000-2005 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"
+#pragma hdrstop
+
+extern HINSTANCE g_hInst;
+
+#define FONTF_BOLD 1
+#define FONTF_ITALIC 2
+struct FontOptionsList
+{
+ TCHAR* szDescr;
+ COLORREF defColour;
+ TCHAR* szDefFace;
+ BYTE defCharset, defStyle;
+ char defSize;
+ COLORREF colour;
+ TCHAR szFace[LF_FACESIZE];
+ BYTE charset, style;
+ char size;
+}
+static fontOptionsList[] = {
+ {_T("Outgoing messages"), RGB(106, 106, 106), _T("Arial"), DEFAULT_CHARSET, 0, -12},
+ {_T("Incoming messages"), RGB(0, 0, 0), _T("Arial"), DEFAULT_CHARSET, 0, -12},
+ {_T("Outgoing name"), RGB(89, 89, 89), _T("Arial"), DEFAULT_CHARSET, FONTF_BOLD, -12},
+ {_T("Outgoing time"), RGB(0, 0, 0), _T("Terminal"), DEFAULT_CHARSET, FONTF_BOLD, -9},
+ {_T("Outgoing colon"), RGB(89, 89, 89), _T("Arial"), DEFAULT_CHARSET, 0, -11},
+ {_T("Incoming name"), RGB(215, 0, 0), _T("Arial"), DEFAULT_CHARSET, FONTF_BOLD, -12},
+ {_T("Incoming time"), RGB(0, 0, 0), _T("Terminal"), DEFAULT_CHARSET, FONTF_BOLD, -9},
+ {_T("Incoming colon"), RGB(215, 0, 0), _T("Arial"), DEFAULT_CHARSET, 0, -11},
+ {_T("Message area"), RGB(0, 0, 0), _T("Arial"), DEFAULT_CHARSET, 0, -12},
+ {_T("Notices"), RGB(90, 90, 160), _T("Arial"), DEFAULT_CHARSET, 0, -12},
+};
+const int msgDlgFontCount = SIZEOF(fontOptionsList);
+
+void LoadMsgDlgFont(int i, LOGFONT* lf, COLORREF * colour)
+{
+ char str[32];
+ int style;
+ DBVARIANT dbv;
+
+ if (colour) {
+ wsprintfA(str, "SRMFont%dCol", i);
+ *colour = DBGetContactSettingDword(NULL, SRMMMOD, str, fontOptionsList[i].defColour);
+ }
+ if (lf) {
+ wsprintfA(str, "SRMFont%dSize", i);
+ lf->lfHeight = (char) DBGetContactSettingByte(NULL, SRMMMOD, str, fontOptionsList[i].defSize);
+ lf->lfWidth = 0;
+ lf->lfEscapement = 0;
+ lf->lfOrientation = 0;
+ wsprintfA(str, "SRMFont%dSty", i);
+ style = DBGetContactSettingByte(NULL, SRMMMOD, str, fontOptionsList[i].defStyle);
+ lf->lfWeight = style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ lf->lfItalic = style & FONTF_ITALIC ? 1 : 0;
+ lf->lfUnderline = 0;
+ lf->lfStrikeOut = 0;
+ wsprintfA(str, "SRMFont%dSet", i);
+ lf->lfCharSet = DBGetContactSettingByte(NULL, SRMMMOD, str, fontOptionsList[i].defCharset);
+ lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf->lfQuality = DEFAULT_QUALITY;
+ lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ wsprintfA(str, "SRMFont%d", i);
+ if (DBGetContactSettingTString(NULL, SRMMMOD, str, &dbv))
+ lstrcpy(lf->lfFaceName, fontOptionsList[i].szDefFace);
+ else {
+ lstrcpyn(lf->lfFaceName, dbv.ptszVal, SIZEOF(lf->lfFaceName));
+ DBFreeVariant(&dbv);
+ }
+ }
+}
+struct CheckBoxValues_t
+{
+ DWORD style;
+ TCHAR* szDescr;
+}
+static const statusValues[] =
+{
+ { PF2_ONLINE, _T("Online") },
+ { PF2_SHORTAWAY, _T("Away") },
+ { PF2_LONGAWAY, _T("NA") },
+ { PF2_LIGHTDND, _T("Occupied") },
+ { PF2_HEAVYDND, _T("DND") },
+ { PF2_FREECHAT, _T("Free for chat") },
+ { PF2_INVISIBLE, _T("Invisible") },
+ { PF2_OUTTOLUNCH, _T("Out to lunch") },
+ { PF2_ONTHEPHONE, _T("On the phone") }
+};
+
+static void FillCheckBoxTree(HWND hwndTree, const struct CheckBoxValues_t *values, int nValues, DWORD style)
+{
+ TVINSERTSTRUCT tvis;
+ int i;
+
+ tvis.hParent = NULL;
+ tvis.hInsertAfter = TVI_LAST;
+ tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE;
+ for (i = 0; i < nValues; i++) {
+ tvis.item.lParam = values[i].style;
+ tvis.item.pszText = TranslateTS(values[i].szDescr);
+ tvis.item.stateMask = TVIS_STATEIMAGEMASK;
+ tvis.item.state = INDEXTOSTATEIMAGEMASK((style & tvis.item.lParam) != 0 ? 2 : 1);
+ TreeView_InsertItem( hwndTree, &tvis );
+} }
+
+static DWORD MakeCheckBoxTreeFlags(HWND hwndTree)
+{
+ DWORD flags = 0;
+ TVITEM tvi;
+
+ tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE;
+ tvi.hItem = TreeView_GetRoot(hwndTree);
+ while (tvi.hItem) {
+ TreeView_GetItem(hwndTree, &tvi);
+ if (((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 2))
+ flags |= tvi.lParam;
+ tvi.hItem = TreeView_GetNextSibling(hwndTree, tvi.hItem);
+ }
+ return flags;
+}
+
+static BOOL CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ DWORD msgTimeout, avatarHeight;
+
+ TranslateDialogDefault(hwndDlg);
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_POPLIST), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, IDC_POPLIST), GWL_STYLE) | TVS_NOHSCROLL | TVS_CHECKBOXES);
+ FillCheckBoxTree(GetDlgItem(hwndDlg, IDC_POPLIST), statusValues, SIZEOF(statusValues),
+ DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_POPFLAGS, SRMSGDEFSET_POPFLAGS));
+ CheckDlgButton(hwndDlg, IDC_SHOWBUTTONLINE, g_dat->flags&SMF_SHOWBTNS);
+ CheckDlgButton(hwndDlg, IDC_SHOWINFOLINE, g_dat->flags&SMF_SHOWINFO);
+ CheckDlgButton(hwndDlg, IDC_AUTOMIN, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOMIN, SRMSGDEFSET_AUTOMIN));
+ CheckDlgButton(hwndDlg, IDC_AUTOCLOSE, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOCLOSE, SRMSGDEFSET_AUTOCLOSE));
+ CheckDlgButton(hwndDlg, IDC_SAVEPERCONTACT, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, SRMSGDEFSET_SAVEPERCONTACT));
+ CheckDlgButton(hwndDlg, IDC_CASCADE, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, SRMSGDEFSET_CASCADE));
+ CheckDlgButton(hwndDlg, IDC_SENDONENTER, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER));
+ CheckDlgButton(hwndDlg, IDC_SENDONDBLENTER, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER));
+ CheckDlgButton(hwndDlg, IDC_STATUSWIN, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, SRMSGDEFSET_STATUSICON));
+
+ CheckDlgButton(hwndDlg, IDC_AVATARSUPPORT, g_dat->flags&SMF_AVATAR);
+ CheckDlgButton(hwndDlg, IDC_LIMITAVATARH, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITAVHEIGHT, SRMSGDEFSET_LIMITAVHEIGHT));
+ avatarHeight = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_AVHEIGHT, SRMSGDEFSET_AVHEIGHT);
+ SetDlgItemInt(hwndDlg, IDC_AVATARHEIGHT, avatarHeight, FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITAVATARH), IsDlgButtonChecked(hwndDlg, IDC_AVATARSUPPORT));
+ if (!IsDlgButtonChecked(hwndDlg, IDC_AVATARSUPPORT))
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AVATARHEIGHT), FALSE);
+ else EnableWindow(GetDlgItem(hwndDlg, IDC_AVATARHEIGHT), IsDlgButtonChecked(hwndDlg, IDC_LIMITAVATARH));
+ CheckDlgButton(hwndDlg, IDC_SHOWSENDBTN, g_dat->flags&SMF_SENDBTN);
+ CheckDlgButton(hwndDlg, IDC_CHARCOUNT, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CHARCOUNT, SRMSGDEFSET_CHARCOUNT));
+ CheckDlgButton(hwndDlg, IDC_CTRLSUPPORT, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_CTRLSUPPORT, SRMSGDEFSET_CTRLSUPPORT));
+ CheckDlgButton(hwndDlg, IDC_DELTEMP, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_DELTEMP, SRMSGDEFSET_DELTEMP));
+ msgTimeout = DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_MSGTIMEOUT, SRMSGDEFSET_MSGTIMEOUT);
+ SetDlgItemInt(hwndDlg, IDC_SECONDS, msgTimeout >= SRMSGSET_MSGTIMEOUT_MIN ? msgTimeout / 1000 : SRMSGDEFSET_MSGTIMEOUT / 1000, FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CASCADE), !IsDlgButtonChecked(hwndDlg, IDC_SAVEPERCONTACT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CTRLSUPPORT), !IsDlgButtonChecked(hwndDlg, IDC_AUTOCLOSE));
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_AUTOMIN:
+ CheckDlgButton(hwndDlg, IDC_AUTOCLOSE, BST_UNCHECKED);
+ break;
+ case IDC_AUTOCLOSE:
+ CheckDlgButton(hwndDlg, IDC_AUTOMIN, BST_UNCHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CTRLSUPPORT), !IsDlgButtonChecked(hwndDlg, IDC_AUTOCLOSE));
+ break;
+ case IDC_SENDONENTER:
+ CheckDlgButton(hwndDlg, IDC_SENDONDBLENTER, BST_UNCHECKED);
+ break;
+ case IDC_SENDONDBLENTER:
+ CheckDlgButton(hwndDlg, IDC_SENDONENTER, BST_UNCHECKED);
+ break;
+ case IDC_SAVEPERCONTACT:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CASCADE), !IsDlgButtonChecked(hwndDlg, IDC_SAVEPERCONTACT));
+ break;
+ case IDC_SECONDS:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return 0;
+ break;
+ case IDC_AVATARSUPPORT:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LIMITAVATARH), IsDlgButtonChecked(hwndDlg, IDC_AVATARSUPPORT));
+ if (!IsDlgButtonChecked(hwndDlg, IDC_AVATARSUPPORT))
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AVATARHEIGHT), FALSE);
+ else EnableWindow(GetDlgItem(hwndDlg, IDC_AVATARHEIGHT), IsDlgButtonChecked(hwndDlg, IDC_LIMITAVATARH));
+ break;
+ case IDC_LIMITAVATARH:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AVATARHEIGHT), IsDlgButtonChecked(hwndDlg, IDC_LIMITAVATARH));
+ break;
+ case IDC_AVATARHEIGHT:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return 0;
+ break;
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case IDC_POPLIST:
+ if (((LPNMHDR) lParam)->code == NM_CLICK) {
+ TVHITTESTINFO hti;
+ hti.pt.x = (short) LOWORD(GetMessagePos());
+ hti.pt.y = (short) HIWORD(GetMessagePos());
+ ScreenToClient(((LPNMHDR) lParam)->hwndFrom, &hti.pt);
+ if (TreeView_HitTest(((LPNMHDR) lParam)->hwndFrom, &hti))
+ if (hti.flags & TVHT_ONITEMSTATEICON) {
+ TVITEM tvi;
+ tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvi.hItem = hti.hItem;
+ TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ tvi.iImage = tvi.iSelectedImage = tvi.iImage == 1 ? 2 : 1;
+ TreeView_SetItem(((LPNMHDR) lParam)->hwndFrom, &tvi);
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+ break;
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ DWORD msgTimeout, avatarHeight;
+
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_POPFLAGS, MakeCheckBoxTreeFlags(GetDlgItem(hwndDlg, IDC_POPLIST)));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWBUTTONLINE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWBUTTONLINE));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWINFOLINE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWINFOLINE));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOMIN, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOMIN));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_AUTOCLOSE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AUTOCLOSE));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SAVEPERCONTACT, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPERCONTACT));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_CASCADE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_CASCADE));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONENTER, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SENDONENTER));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDONDBLENTER, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SENDONDBLENTER));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_STATUSICON, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_STATUSWIN));
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_AVATARENABLE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARSUPPORT));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LIMITAVHEIGHT, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LIMITAVATARH));
+ avatarHeight = GetDlgItemInt(hwndDlg, IDC_AVATARHEIGHT, NULL, TRUE);
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_AVHEIGHT, avatarHeight<=0?SRMSGDEFSET_AVHEIGHT:avatarHeight);
+
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SENDBUTTON, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWSENDBTN));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_CHARCOUNT, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_CHARCOUNT));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_CTRLSUPPORT, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_CTRLSUPPORT));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_DELTEMP, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_DELTEMP));
+ msgTimeout = GetDlgItemInt(hwndDlg, IDC_SECONDS, NULL, TRUE) >= SRMSGSET_MSGTIMEOUT_MIN / 1000 ? GetDlgItemInt(hwndDlg, IDC_SECONDS, NULL, TRUE) * 1000 : SRMSGDEFSET_MSGTIMEOUT;
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_MSGTIMEOUT, msgTimeout);
+ ReloadGlobals();
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_OPTIONSAPPLIED, 0, 0);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+static BOOL CALLBACK DlgProcLogOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static HBRUSH hBkgColourBrush;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ switch (DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, SRMSGDEFSET_LOADHISTORY)) {
+ case LOADHISTORY_UNREAD:
+ CheckDlgButton(hwndDlg, IDC_LOADUNREAD, BST_CHECKED);
+ break;
+ case LOADHISTORY_COUNT:
+ CheckDlgButton(hwndDlg, IDC_LOADCOUNT, BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTN), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTSPIN), TRUE);
+ break;
+ case LOADHISTORY_TIME:
+ CheckDlgButton(hwndDlg, IDC_LOADTIME, BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADTIMEN), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADTIMESPIN), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STMINSOLD), TRUE);
+ break;
+ }
+ SendDlgItemMessage(hwndDlg, IDC_LOADCOUNTSPIN, UDM_SETRANGE, 0, MAKELONG(100, 0));
+ SendDlgItemMessage(hwndDlg, IDC_LOADCOUNTSPIN, UDM_SETPOS, 0, DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADCOUNT, SRMSGDEFSET_LOADCOUNT));
+ SendDlgItemMessage(hwndDlg, IDC_LOADTIMESPIN, UDM_SETRANGE, 0, MAKELONG(12 * 60, 0));
+ SendDlgItemMessage(hwndDlg, IDC_LOADTIMESPIN, UDM_SETPOS, 0, DBGetContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADTIME, SRMSGDEFSET_LOADTIME));
+
+ CheckDlgButton(hwndDlg, IDC_SHOWLOGICONS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWLOGICONS, SRMSGDEFSET_SHOWLOGICONS));
+ CheckDlgButton(hwndDlg, IDC_SHOWNAMES, !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDENAMES, SRMSGDEFSET_HIDENAMES));
+ CheckDlgButton(hwndDlg, IDC_SHOWTIMES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTIME, SRMSGDEFSET_SHOWTIME));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWSECS), IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ CheckDlgButton(hwndDlg, IDC_SHOWSECS, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSECS, SRMSGDEFSET_SHOWSECS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWDATES), IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ CheckDlgButton(hwndDlg, IDC_SHOWDATES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWDATE, SRMSGDEFSET_SHOWDATE));
+ CheckDlgButton(hwndDlg, IDC_SHOWSTATUSCHANGES, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCH, SRMSGDEFSET_SHOWSTATUSCH));
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR));
+ SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_SETDEFAULTCOLOUR, 0, SRMSGDEFSET_BKGCOLOUR);
+
+ hBkgColourBrush = CreateSolidBrush(SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0));
+
+ { int i;
+ LOGFONT lf;
+ for (i = 0; i < SIZEOF(fontOptionsList); i++) {
+ LoadMsgDlgFont(i, &lf, &fontOptionsList[i].colour);
+ lstrcpy(fontOptionsList[i].szFace, lf.lfFaceName);
+ fontOptionsList[i].size = (char) lf.lfHeight;
+ fontOptionsList[i].style = (lf.lfWeight >= FW_BOLD ? FONTF_BOLD : 0) | (lf.lfItalic ? FONTF_ITALIC : 0);
+ fontOptionsList[i].charset = lf.lfCharSet;
+ //I *think* some OSs will fail LB_ADDSTRING if lParam==0
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_ADDSTRING, 0, i + 1);
+ }
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETSEL, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_SETCOLOUR, 0, fontOptionsList[0].colour);
+ SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_SETDEFAULTCOLOUR, 0, fontOptionsList[0].defColour);
+ }
+ return TRUE;
+ case WM_CTLCOLORLISTBOX:
+ SetBkColor((HDC) wParam, SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0));
+ return (BOOL) hBkgColourBrush;
+ case WM_MEASUREITEM:
+ {
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *) lParam;
+ HFONT hFont, hoFont;
+ HDC hdc;
+ SIZE fontSize;
+ int iItem = mis->itemData - 1;
+ hFont = CreateFont(fontOptionsList[iItem].size, 0, 0, 0,
+ fontOptionsList[iItem].style & FONTF_BOLD ? FW_BOLD : FW_NORMAL,
+ fontOptionsList[iItem].style & FONTF_ITALIC ? 1 : 0, 0, 0, fontOptionsList[iItem].charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontOptionsList[iItem].szFace);
+ hdc = GetDC(GetDlgItem(hwndDlg, mis->CtlID));
+ hoFont = (HFONT) SelectObject(hdc, hFont);
+ GetTextExtentPoint32(hdc, fontOptionsList[iItem].szDescr, lstrlen(fontOptionsList[iItem].szDescr), &fontSize);
+ SelectObject(hdc, hoFont);
+ ReleaseDC(GetDlgItem(hwndDlg, mis->CtlID), hdc);
+ DeleteObject(hFont);
+ mis->itemWidth = fontSize.cx;
+ mis->itemHeight = fontSize.cy;
+ return TRUE;
+ }
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT* dis = (DRAWITEMSTRUCT *) lParam;
+ HFONT hFont, hoFont;
+ TCHAR* pszText;
+ int iItem = dis->itemData - 1;
+ hFont = CreateFont(fontOptionsList[iItem].size, 0, 0, 0,
+ fontOptionsList[iItem].style & FONTF_BOLD ? FW_BOLD : FW_NORMAL,
+ fontOptionsList[iItem].style & FONTF_ITALIC ? 1 : 0, 0, 0, fontOptionsList[iItem].charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontOptionsList[iItem].szFace);
+ hoFont = (HFONT) SelectObject(dis->hDC, hFont);
+ SetBkMode(dis->hDC, TRANSPARENT);
+ FillRect(dis->hDC, &dis->rcItem, hBkgColourBrush);
+ if (dis->itemState & ODS_SELECTED)
+ FrameRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT));
+ SetTextColor(dis->hDC, fontOptionsList[iItem].colour);
+ pszText = TranslateTS(fontOptionsList[iItem].szDescr);
+ TextOut(dis->hDC, dis->rcItem.left, dis->rcItem.top, pszText, lstrlen(pszText));
+ SelectObject(dis->hDC, hoFont);
+ DeleteObject(hFont);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_LOADUNREAD:
+ case IDC_LOADCOUNT:
+ case IDC_LOADTIME:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTN), IsDlgButtonChecked(hwndDlg, IDC_LOADCOUNT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADCOUNTSPIN), IsDlgButtonChecked(hwndDlg, IDC_LOADCOUNT));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADTIMEN), IsDlgButtonChecked(hwndDlg, IDC_LOADTIME));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LOADTIMESPIN), IsDlgButtonChecked(hwndDlg, IDC_LOADTIME));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STMINSOLD), IsDlgButtonChecked(hwndDlg, IDC_LOADTIME));
+ break;
+ case IDC_SHOWTIMES:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWSECS), IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SHOWDATES), IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ break;
+ case IDC_BKGCOLOUR:
+ DeleteObject(hBkgColourBrush);
+ hBkgColourBrush = CreateSolidBrush(SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0));
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE);
+ break;
+ case IDC_FONTLIST:
+ if (HIWORD(wParam) == LBN_SELCHANGE) {
+ if (SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0) > 1) {
+ SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_SETCOLOUR, 0, GetSysColor(COLOR_3DFACE));
+ SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT));
+ }
+ else {
+ int i = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA,
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCURSEL, 0, 0), 0) - 1;
+ SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_SETCOLOUR, 0, fontOptionsList[i].colour);
+ SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_SETDEFAULTCOLOUR, 0, fontOptionsList[i].defColour);
+ }
+ }
+ if (HIWORD(wParam) != LBN_DBLCLK)
+ return TRUE;
+ //fall through
+ case IDC_CHOOSEFONT:
+ {
+ CHOOSEFONT cf = { 0 };
+ LOGFONT lf = { 0 };
+ int i = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCURSEL, 0, 0),
+ 0) - 1;
+ lf.lfHeight = fontOptionsList[i].size;
+ lf.lfWeight = fontOptionsList[i].style & FONTF_BOLD ? FW_BOLD : FW_NORMAL;
+ lf.lfItalic = fontOptionsList[i].style & FONTF_ITALIC ? 1 : 0;
+ lf.lfCharSet = fontOptionsList[i].charset;
+ lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfQuality = DEFAULT_QUALITY;
+ lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ lstrcpy(lf.lfFaceName, fontOptionsList[i].szFace);
+ cf.lStructSize = sizeof(cf);
+ cf.hwndOwner = hwndDlg;
+ cf.lpLogFont = &lf;
+ cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
+ if (ChooseFont(&cf)) {
+ int selItems[ SIZEOF(fontOptionsList) ];
+ int sel, selCount;
+
+ selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, SIZEOF(fontOptionsList), (LPARAM) selItems);
+ for (sel = 0; sel < selCount; sel++) {
+ i = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[sel], 0) - 1;
+ fontOptionsList[i].size = (char) lf.lfHeight;
+ fontOptionsList[i].style = (lf.lfWeight >= FW_BOLD ? FONTF_BOLD : 0) | (lf.lfItalic ? FONTF_ITALIC : 0);
+ fontOptionsList[i].charset = lf.lfCharSet;
+ lstrcpy(fontOptionsList[i].szFace, lf.lfFaceName);
+ {
+ MEASUREITEMSTRUCT mis = { 0 };
+ mis.CtlID = IDC_FONTLIST;
+ mis.itemData = i + 1;
+ SendMessage(hwndDlg, WM_MEASUREITEM, 0, (LPARAM) & mis);
+ SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETITEMHEIGHT, selItems[sel], mis.itemHeight);
+ }
+ }
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE);
+ break;
+ }
+ return TRUE;
+ }
+ case IDC_FONTCOLOUR:
+ {
+ int selItems[ SIZEOF(fontOptionsList) ];
+ int sel, selCount, i;
+
+ selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, SIZEOF(fontOptionsList), (LPARAM) selItems);
+ for (sel = 0; sel < selCount; sel++) {
+ i = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, selItems[sel], 0) - 1;
+ fontOptionsList[i].colour = SendDlgItemMessage(hwndDlg, IDC_FONTCOLOUR, CPM_GETCOLOUR, 0, 0);
+ }
+ InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE);
+ break;
+ }
+ case IDC_LOADCOUNTN:
+ case IDC_LOADTIMEN:
+ if (HIWORD(wParam) != EN_CHANGE || (HWND) lParam != GetFocus())
+ return TRUE;
+ break;
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ if (IsDlgButtonChecked(hwndDlg, IDC_LOADCOUNT))
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, LOADHISTORY_COUNT);
+ else if (IsDlgButtonChecked(hwndDlg, IDC_LOADTIME))
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, LOADHISTORY_TIME);
+ else
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, LOADHISTORY_UNREAD);
+ DBWriteContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADCOUNT, (WORD) SendDlgItemMessage(hwndDlg, IDC_LOADCOUNTSPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingWord(NULL, SRMMMOD, SRMSGSET_LOADTIME, (WORD) SendDlgItemMessage(hwndDlg, IDC_LOADTIMESPIN, UDM_GETPOS, 0, 0));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWLOGICONS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWLOGICONS));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_HIDENAMES, (BYTE) ! IsDlgButtonChecked(hwndDlg, IDC_SHOWNAMES));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTIME, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWTIMES));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSECS, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWSECS));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWDATE, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWDATES));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWSTATUSCH, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWSTATUSCHANGES));
+ DBWriteContactSettingDword(NULL, SRMMMOD, SRMSGSET_BKGCOLOUR, SendDlgItemMessage(hwndDlg, IDC_BKGCOLOUR, CPM_GETCOLOUR, 0, 0));
+
+ {
+ int i;
+ char str[32];
+ for (i = 0; i < SIZEOF(fontOptionsList); i++) {
+ wsprintfA(str, "SRMFont%d", i);
+ DBWriteContactSettingTString(NULL, SRMMMOD, str, fontOptionsList[i].szFace);
+ wsprintfA(str, "SRMFont%dSize", i);
+ DBWriteContactSettingByte(NULL, SRMMMOD, str, fontOptionsList[i].size);
+ wsprintfA(str, "SRMFont%dSty", i);
+ DBWriteContactSettingByte(NULL, SRMMMOD, str, fontOptionsList[i].style);
+ wsprintfA(str, "SRMFont%dSet", i);
+ DBWriteContactSettingByte(NULL, SRMMMOD, str, fontOptionsList[i].charset);
+ wsprintfA(str, "SRMFont%dCol", i);
+ DBWriteContactSettingDword(NULL, SRMMMOD, str, fontOptionsList[i].colour);
+ }
+ }
+
+ FreeMsgLogIcons();
+ LoadMsgLogIcons();
+ ReloadGlobals();
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_OPTIONSAPPLIED, 0, 0);
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ DeleteObject(hBkgColourBrush);
+ break;
+ }
+ return FALSE;
+}
+
+static ResetCList(HWND hwndDlg)
+{
+ int i;
+
+ if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_DISABLEGROUPS && !DBGetContactSettingByte(NULL, "CList", "UseGroups", SETTING_USEGROUPS_DEFAULT))
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETUSEGROUPS, (WPARAM) FALSE, 0);
+ else
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETUSEGROUPS, (WPARAM) TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETHIDEEMPTYGROUPS, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETGREYOUTFLAGS, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETLEFTMARGIN, 2, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETBKBITMAP, 0, (LPARAM) (HBITMAP) NULL);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0);
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETINDENT, 10, 0);
+ for (i = 0; i <= FONTID_MAX; i++)
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT));
+}
+
+static void RebuildList(HWND hwndDlg, HANDLE hItemNew, HANDLE hItemUnknown)
+{
+ HANDLE hContact, hItem;
+ BYTE defType = DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW);
+
+ if (hItemNew && defType) {
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItemNew, 1);
+ }
+ if (hItemUnknown && DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGUNKNOWN, SRMSGDEFSET_TYPINGUNKNOWN)) {
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItemUnknown, 1);
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ do {
+ hItem = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM) hContact, 0);
+ if (hItem && DBGetContactSettingByte(hContact, SRMMMOD, SRMSGSET_TYPING, defType)) {
+ SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETCHECKMARK, (WPARAM) hItem, 1);
+ }
+ } while (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0));
+}
+
+static void SaveList(HWND hwndDlg, HANDLE hItemNew, HANDLE hItemUnknown)
+{
+ HANDLE hContact, hItem;
+
+ if (hItemNew) {
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGNEW, (BYTE) (SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItemNew, 0) ? 1 : 0));
+ }
+ if (hItemUnknown) {
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_TYPINGUNKNOWN, (BYTE) (SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItemUnknown, 0) ? 1 : 0));
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ do {
+ hItem = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_FINDCONTACT, (WPARAM) hContact, 0);
+ if (hItem) {
+ DBWriteContactSettingByte(hContact, SRMMMOD, SRMSGSET_TYPING, (BYTE) (SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETCHECKMARK, (WPARAM) hItem, 0) ? 1 : 0));
+ }
+ } while (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0));
+}
+
+static BOOL CALLBACK DlgProcTypeOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static HANDLE hItemNew, hItemUnknown;
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ CLCINFOITEM cii = { 0 };
+ cii.cbSize = sizeof(cii);
+ cii.flags = CLCIIF_GROUPFONT | CLCIIF_CHECKBOX;
+ cii.pszText = TranslateT("** New contacts **");
+ hItemNew = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_ADDINFOITEM, 0, (LPARAM) & cii);
+ cii.pszText = TranslateT("** Unknown contacts **");
+ hItemUnknown = (HANDLE) SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_ADDINFOITEM, 0, (LPARAM) & cii);
+ }
+ SetWindowLong(GetDlgItem(hwndDlg, IDC_CLIST), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, IDC_CLIST), GWL_STYLE) | (CLS_SHOWHIDDEN) | (CLS_NOHIDEOFFLINE));
+ ResetCList(hwndDlg);
+ RebuildList(hwndDlg, hItemNew, hItemUnknown);
+ CheckDlgButton(hwndDlg, IDC_SHOWNOTIFY, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPING, SRMSGDEFSET_SHOWTYPING));
+ CheckDlgButton(hwndDlg, IDC_TYPEWIN, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGWIN, SRMSGDEFSET_SHOWTYPINGWIN));
+ CheckDlgButton(hwndDlg, IDC_TYPETRAY, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGNOWIN, SRMSGDEFSET_SHOWTYPINGNOWIN));
+ CheckDlgButton(hwndDlg, IDC_NOTIFYTRAY, DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGCLIST, SRMSGDEFSET_SHOWTYPINGCLIST));
+ CheckDlgButton(hwndDlg, IDC_NOTIFYBALLOON, !DBGetContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGCLIST, SRMSGDEFSET_SHOWTYPINGCLIST));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPEWIN), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPETRAY), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), IsDlgButtonChecked(hwndDlg, IDC_TYPETRAY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), IsDlgButtonChecked(hwndDlg, IDC_TYPETRAY));
+ if (!ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), FALSE);
+ CheckDlgButton(hwndDlg, IDC_NOTIFYTRAY, BST_CHECKED);
+ SetWindowTextA(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), Translate("Show balloon popup (unsupported system)"));
+ }
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_TYPETRAY:
+ if (IsDlgButtonChecked(hwndDlg, IDC_TYPETRAY)) {
+ if (!ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), TRUE);
+ }
+ else {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), TRUE);
+ }
+ }
+ else {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), FALSE);
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case IDC_SHOWNOTIFY:
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPEWIN), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TYPETRAY), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYTRAY), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTIFYBALLOON), IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY)
+ && ServiceExists(MS_CLIST_SYSTRAY_NOTIFY));
+ //fall-thru
+ case IDC_TYPEWIN:
+ case IDC_NOTIFYTRAY:
+ case IDC_NOTIFYBALLOON:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((NMHDR *) lParam)->idFrom) {
+ case IDC_CLIST:
+ switch (((NMHDR *) lParam)->code) {
+ case CLN_OPTIONSCHANGED:
+ ResetCList(hwndDlg);
+ break;
+ case CLN_CHECKCHANGED:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ break;
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY:
+ {
+ SaveList(hwndDlg, hItemNew, hItemUnknown);
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPING, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOWNOTIFY));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGWIN, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TYPEWIN));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGNOWIN, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_TYPETRAY));
+ DBWriteContactSettingByte(NULL, SRMMMOD, SRMSGSET_SHOWTYPINGCLIST, (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NOTIFYTRAY));
+ ReloadGlobals();
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_OPTIONSAPPLIED, 0, 0);
+ }
+ }
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static int OptInitialise(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+
+ odp.cbSize = sizeof(odp);
+ odp.position = 910000000;
+ odp.hInstance = g_hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MSGDLG);
+ odp.pszTitle = "Messaging";
+ odp.pszGroup = "Events";
+ odp.pfnDlgProc = DlgProcOptions;
+ odp.flags = ODPF_BOLDGROUPS;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MSGLOG);
+ odp.pszTitle = "Messaging Log";
+ odp.pfnDlgProc = DlgProcLogOptions;
+ odp.nIDBottomSimpleControl = IDC_STMSGLOGGROUP;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MSGTYPE);
+ odp.pszTitle = "Typing Notify";
+ odp.pfnDlgProc = DlgProcTypeOptions;
+ odp.nIDBottomSimpleControl = 0;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp);
+ return 0;
+}
+
+int InitOptions(void)
+{
+ HookEvent(ME_OPT_INITIALISE, OptInitialise);
+ return 0;
+}
diff --git a/miranda-wine/plugins/srmm/msgs.c b/miranda-wine/plugins/srmm/msgs.c new file mode 100644 index 0000000..a8ac9ff --- /dev/null +++ b/miranda-wine/plugins/srmm/msgs.c @@ -0,0 +1,587 @@ +/*
+SRMM
+
+Copyright 2000-2005 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"
+#pragma hdrstop
+
+static void InitREOleCallback(void);
+
+HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand;
+static HANDLE hEventDbEventAdded, hEventDbSettingChange, hEventContactDeleted;
+HANDLE *hMsgMenuItem = NULL, hHookWinEvt=NULL;
+int hMsgMenuItemCount = 0;
+
+extern HINSTANCE g_hInst;
+
+static int SRMMStatusToPf2(int status)
+{
+ switch (status) {
+ case ID_STATUS_ONLINE:
+ return PF2_ONLINE;
+ case ID_STATUS_AWAY:
+ return PF2_SHORTAWAY;
+ case ID_STATUS_DND:
+ return PF2_HEAVYDND;
+ case ID_STATUS_NA:
+ return PF2_LONGAWAY;
+ case ID_STATUS_OCCUPIED:
+ return PF2_LIGHTDND;
+ case ID_STATUS_FREECHAT:
+ return PF2_FREECHAT;
+ case ID_STATUS_INVISIBLE:
+ return PF2_INVISIBLE;
+ case ID_STATUS_ONTHEPHONE:
+ return PF2_ONTHEPHONE;
+ case ID_STATUS_OUTTOLUNCH:
+ return PF2_OUTTOLUNCH;
+ case ID_STATUS_OFFLINE:
+ return MODEF_OFFLINE;
+ }
+ return 0;
+}
+
+static int ReadMessageCommand(WPARAM wParam, LPARAM lParam)
+{
+ struct NewMessageWindowLParam newData = { 0 };
+ HWND hwndExisting;
+
+ hwndExisting = WindowList_Find(g_dat->hMessageWindowList, ((CLISTEVENT *) lParam)->hContact);
+ newData.hContact = ((CLISTEVENT *) lParam)->hContact;
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), NULL, DlgProcMessage, (LPARAM) & newData);
+ return 0;
+}
+
+static int MessageEventAdded(WPARAM wParam, LPARAM lParam)
+{
+ CLISTEVENT cle;
+ DBEVENTINFO dbei;
+ HWND hwnd;
+
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, lParam, (LPARAM) & dbei);
+
+ if (dbei.flags & DBEF_SENT || dbei.eventType != EVENTTYPE_MESSAGE || dbei.flags & DBEF_READ)
+ return 0;
+
+ CallServiceSync(MS_CLIST_REMOVEEVENT, wParam, (LPARAM) 1);
+ /* does a window for the contact exist? */
+ hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam);
+ if (hwnd) {
+ if (GetForegroundWindow()==hwnd)
+ SkinPlaySound("RecvMsgActive");
+ else SkinPlaySound("RecvMsgInactive");
+ return 0;
+ }
+ /* new message */
+ SkinPlaySound("AlertMsg");
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) wParam, 0);
+ if (szProto && (g_dat->openFlags & SRMMStatusToPf2(CallProtoService(szProto, PS_GETSTATUS, 0, 0)))) {
+ struct NewMessageWindowLParam newData = { 0 };
+ newData.hContact = (HANDLE) wParam;
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), NULL, DlgProcMessage, (LPARAM) & newData);
+ return 0;
+ }
+ }
+ {
+ TCHAR toolTip[256], *contactName;
+ ZeroMemory(&cle, sizeof(cle));
+ cle.cbSize = sizeof(cle);
+ cle.hContact = (HANDLE) wParam;
+ cle.hDbEvent = (HANDLE) lParam;
+ cle.flags = CLEF_TCHAR;
+ cle.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ cle.pszService = "SRMsg/ReadMessage";
+ contactName = (TCHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, wParam, GCDNF_TCHAR);
+ mir_sntprintf(toolTip, SIZEOF(toolTip), TranslateT("Message from %s"), contactName);
+ cle.ptszTooltip = toolTip;
+ CallService(MS_CLIST_ADDEVENT, 0, (LPARAM) & cle);
+ }
+ return 0;
+}
+
+#if defined(_UNICODE)
+static int SendMessageCommand_W(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwnd;
+ struct NewMessageWindowLParam newData = { 0 };
+
+ {
+ /* does the HCONTACT's protocol support IM messages? */
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if (szProto) {
+ if (!CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMSEND)
+ return 1;
+ }
+ else {
+ /* unknown contact */
+ return 1;
+ } //if
+ }
+
+ if (hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam)) {
+ if (lParam) {
+ HWND hEdit;
+ hEdit = GetDlgItem(hwnd, IDC_MESSAGE);
+ SendMessage(hEdit, EM_SETSEL, -1, SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0));
+ SendMessage(hEdit, EM_REPLACESEL, FALSE, (LPARAM) (char *) lParam);
+ }
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ SetForegroundWindow(hwnd);
+ SetFocus(hwnd);
+ }
+ else {
+ newData.hContact = (HANDLE) wParam;
+ newData.szInitialText = (const char *) lParam;
+ newData.isWchar = 1;
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), NULL, DlgProcMessage, (LPARAM) & newData);
+ }
+ return 0;
+}
+#endif
+
+static int SendMessageCommand(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwnd;
+ struct NewMessageWindowLParam newData = { 0 };
+
+ {
+ /* does the HCONTACT's protocol support IM messages? */
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if (szProto) {
+ if (!CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMSEND)
+ return 1;
+ }
+ else {
+ /* unknown contact */
+ return 1;
+ } //if
+ }
+
+ if (hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam)) {
+ if (lParam) {
+ HWND hEdit;
+ hEdit = GetDlgItem(hwnd, IDC_MESSAGE);
+ SendMessage(hEdit, EM_SETSEL, -1, SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0));
+ SendMessageA(hEdit, EM_REPLACESEL, FALSE, (LPARAM) (char *) lParam);
+ }
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ SetForegroundWindow(hwnd);
+ SetFocus(hwnd);
+ }
+ else {
+ newData.hContact = (HANDLE) wParam;
+ newData.szInitialText = (const char *) lParam;
+ newData.isWchar = 0;
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), NULL, DlgProcMessage, (LPARAM) & newData);
+ }
+ return 0;
+}
+
+static int TypingMessageCommand(WPARAM wParam, LPARAM lParam)
+{
+ CLISTEVENT *cle = (CLISTEVENT *) lParam;
+
+ if (!cle)
+ return 0;
+ SendMessageCommand((WPARAM) cle->hContact, 0);
+ return 0;
+}
+
+static int TypingMessage(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwnd;
+ int foundWin = 0;
+
+ if (!(g_dat->flags&SMF_SHOWTYPING))
+ return 0;
+ if (hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam)) {
+ SendMessage(hwnd, DM_TYPING, 0, lParam);
+ foundWin = 1;
+ }
+ if ((int) lParam && !foundWin && (g_dat->flags&SMF_SHOWTYPINGTRAY)) {
+ char szTip[256];
+ mir_snprintf(szTip, SIZEOF(szTip), Translate("%s is typing a message"), (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, wParam, 0));
+
+ if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY) && !(g_dat->flags&SMF_SHOWTYPINGCLIST)) {
+ MIRANDASYSTRAYNOTIFY tn;
+ tn.szProto = NULL;
+ tn.cbSize = sizeof(tn);
+ tn.szInfoTitle = Translate("Typing Notification");
+ tn.szInfo = szTip;
+ tn.dwInfoFlags = NIIF_INFO;
+ tn.uTimeout = 1000 * 4;
+ CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM) & tn);
+ }
+ else {
+ CLISTEVENT cle;
+
+ ZeroMemory(&cle, sizeof(cle));
+ cle.cbSize = sizeof(cle);
+ cle.hContact = (HANDLE) wParam;
+ cle.hDbEvent = (HANDLE) 1;
+ cle.flags = CLEF_ONLYAFEW;
+ cle.hIcon = g_dat->hIcons[SMF_ICON_TYPING];
+ cle.pszService = "SRMsg/TypingMessage";
+ cle.pszTooltip = szTip;
+ CallServiceSync(MS_CLIST_REMOVEEVENT, wParam, (LPARAM) 1);
+ CallServiceSync(MS_CLIST_ADDEVENT, wParam, (LPARAM) & cle);
+ }
+ }
+ return 0;
+}
+
+static int MessageSettingChanged(WPARAM wParam, LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam;
+ char *szProto;
+
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if (lstrcmpA(cws->szModule, "CList") && (szProto == NULL || lstrcmpA(cws->szModule, szProto)))
+ return 0;
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_UPDATETITLE, (WPARAM) cws, 0);
+ return 0;
+}
+
+static int ContactDeleted(WPARAM wParam, LPARAM lParam)
+{
+ HWND hwnd;
+
+ if (hwnd = WindowList_Find(g_dat->hMessageWindowList, (HANDLE) wParam)) {
+ SendMessage(hwnd, WM_CLOSE, 0, 0);
+ }
+ return 0;
+}
+
+static void RestoreUnreadMessageAlerts(void)
+{
+ CLISTEVENT cle = { 0 };
+ DBEVENTINFO dbei = { 0 };
+ char toolTip[256];
+ int windowAlreadyExists;
+ HANDLE hDbEvent, hContact;
+ int autoPopup;
+
+ dbei.cbSize = sizeof(dbei);
+ cle.cbSize = sizeof(cle);
+ cle.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ cle.pszService = "SRMsg/ReadMessage";
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact) {
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDFIRSTUNREAD, (WPARAM) hContact, 0);
+ while (hDbEvent) {
+ autoPopup = 0;
+ dbei.cbBlob = 0;
+ CallService(MS_DB_EVENT_GET, (WPARAM) hDbEvent, (LPARAM) & dbei);
+ if (!(dbei.flags & (DBEF_SENT | DBEF_READ)) && dbei.eventType == EVENTTYPE_MESSAGE) {
+ windowAlreadyExists = WindowList_Find(g_dat->hMessageWindowList, hContact) != NULL;
+ if (windowAlreadyExists)
+ continue;
+ {
+ char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto && (g_dat->openFlags & SRMMStatusToPf2(CallProtoService(szProto, PS_GETSTATUS, 0, 0)))) {
+ autoPopup = 1;
+ }
+ }
+ if (autoPopup && !windowAlreadyExists) {
+ struct NewMessageWindowLParam newData = { 0 };
+ newData.hContact = hContact;
+ CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSG), NULL, DlgProcMessage, (LPARAM) & newData);
+ }
+ else {
+ cle.hContact = hContact;
+ cle.hDbEvent = hDbEvent;
+ mir_snprintf(toolTip, SIZEOF(toolTip), Translate("Message from %s"), (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0));
+ cle.pszTooltip = toolTip;
+ CallService(MS_CLIST_ADDEVENT, 0, (LPARAM) & cle);
+ }
+ }
+ hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hDbEvent, 0);
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+}
+
+static int SplitmsgModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ CLISTMENUITEM mi;
+ PROTOCOLDESCRIPTOR **protocol;
+ int protoCount, i;
+
+ LoadMsgLogIcons();
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.position = -2000090000;
+ mi.flags = 0;
+ mi.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ mi.pszName = Translate("&Message");
+ mi.pszService = MS_MSG_SENDMESSAGE;
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM) & protoCount, (LPARAM) & protocol);
+ for (i = 0; i < protoCount; i++) {
+ if (protocol[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+ if (CallProtoService(protocol[i]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMSEND) {
+ mi.pszContactOwner = protocol[i]->szName;
+ hMsgMenuItem = realloc(hMsgMenuItem, (hMsgMenuItemCount + 1) * sizeof(HANDLE));
+ hMsgMenuItem[hMsgMenuItemCount++] = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) & mi);
+ }
+ }
+ HookEvent(ME_CLIST_DOUBLECLICKED, SendMessageCommand);
+ RestoreUnreadMessageAlerts();
+ return 0;
+}
+
+int PreshutdownSendRecv(WPARAM wParam, LPARAM lParam)
+{
+ WindowList_BroadcastAsync(g_dat->hMessageWindowList, WM_CLOSE, 0, 0);
+ return 0;
+}
+
+int SplitmsgShutdown(void)
+{
+ DestroyCursor(hCurSplitNS);
+ DestroyCursor(hCurHyperlinkHand);
+ DestroyCursor(hCurSplitWE);
+ UnhookEvent(hEventDbEventAdded);
+ UnhookEvent(hEventDbSettingChange);
+ UnhookEvent(hEventContactDeleted);
+ FreeMsgLogIcons();
+ FreeLibrary(GetModuleHandleA("riched20"));
+ OleUninitialize();
+ if (hMsgMenuItem) {
+ free(hMsgMenuItem);
+ hMsgMenuItem = NULL;
+ hMsgMenuItemCount = 0;
+ }
+ RichUtil_Unload();
+ FreeGlobals();
+ return 0;
+}
+
+static int IconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ if (hMsgMenuItem) {
+ int j;
+ CLISTMENUITEM mi;
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_ICON;
+ mi.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+
+ for (j = 0; j < hMsgMenuItemCount; j++) {
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) hMsgMenuItem[j], (LPARAM) & mi);
+ }
+ }
+ FreeMsgLogIcons();
+ LoadMsgLogIcons();
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_REMAKELOG, 0, 0);
+ // change all the icons
+ WindowList_Broadcast(g_dat->hMessageWindowList, DM_UPDATEWINICON, 0, 0);
+ return 0;
+}
+
+static int GetWindowAPI(WPARAM wParam, LPARAM lParam)
+{
+ return PLUGIN_MAKE_VERSION(0,0,0,3);
+}
+
+static int GetWindowClass(WPARAM wParam, LPARAM lParam)
+{
+ char *szBuf = (char*)wParam;
+ int size = (int)lParam;
+ mir_snprintf(szBuf, size, SRMMMOD);
+ return 0;
+}
+
+static int GetWindowData(WPARAM wParam, LPARAM lParam)
+{
+ MessageWindowInputData *mwid = (MessageWindowInputData*)wParam;
+ MessageWindowData *mwd = (MessageWindowData*)lParam;
+ HWND hwnd;
+
+ if (mwid==NULL||mwd==NULL) return 1;
+ if (mwid->cbSize!=sizeof(MessageWindowInputData)||mwd->cbSize!=sizeof(MessageWindowData)) return 1;
+ if (mwid->hContact==NULL) return 1;
+ if (mwid->uFlags!=MSG_WINDOW_UFLAG_MSG_BOTH) return 1;
+ hwnd = WindowList_Find(g_dat->hMessageWindowList, mwid->hContact);
+ mwd->uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+ mwd->hwndWindow = hwnd;
+ mwd->local = 0;
+ mwd->uState = SendMessage(hwnd, DM_GETWINDOWSTATE, 0, 0);
+ return 0;
+}
+
+int LoadSendRecvMessageModule(void)
+{
+ if (LoadLibraryA("riched20.dll") == NULL) {
+ if (IDYES !=
+ MessageBoxA(0,
+ Translate
+ ("Miranda could not load the built-in message module, riched20.dll is missing. If you are using Windows 95 or WINE please make sure you have riched20.dll installed. Press 'Yes' to continue loading Miranda."),
+ Translate("Information"), MB_YESNO | MB_ICONINFORMATION))
+ return 1;
+ return 0;
+ }
+ InitGlobals();
+ RichUtil_Load();
+ OleInitialize(NULL);
+ InitREOleCallback();
+ InitOptions();
+ hEventDbEventAdded = HookEvent(ME_DB_EVENT_ADDED, MessageEventAdded);
+ hEventDbSettingChange = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, MessageSettingChanged);
+ hEventContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, ContactDeleted);
+ HookEvent(ME_SYSTEM_MODULESLOADED, SplitmsgModulesLoaded);
+ HookEvent(ME_SKIN_ICONSCHANGED, IconsChanged);
+ HookEvent(ME_PROTO_CONTACTISTYPING, TypingMessage);
+ HookEvent(ME_SYSTEM_PRESHUTDOWN, PreshutdownSendRecv);
+ CreateServiceFunction(MS_MSG_SENDMESSAGE, SendMessageCommand);
+#if defined(_UNICODE)
+ CreateServiceFunction(MS_MSG_SENDMESSAGE "W", SendMessageCommand_W);
+#endif
+ CreateServiceFunction(MS_MSG_GETWINDOWAPI, GetWindowAPI);
+ CreateServiceFunction(MS_MSG_GETWINDOWCLASS, GetWindowClass);
+ CreateServiceFunction(MS_MSG_GETWINDOWDATA, GetWindowData);
+ CreateServiceFunction("SRMsg/ReadMessage", ReadMessageCommand);
+ CreateServiceFunction("SRMsg/TypingMessage", TypingMessageCommand);
+ hHookWinEvt=CreateHookableEvent(ME_MSG_WINDOWEVENT);
+ SkinAddNewSoundEx("RecvMsgActive", Translate("Messages"), Translate("Incoming (Focused Window)"));
+ SkinAddNewSoundEx("RecvMsgInactive", Translate("Messages"), Translate("Incoming (Unfocused Window)"));
+ SkinAddNewSoundEx("AlertMsg", Translate("Messages"), Translate("Incoming (New Session)"));
+ SkinAddNewSoundEx("SendMsg", Translate("Messages"), Translate("Outgoing"));
+ hCurSplitNS = LoadCursor(NULL, IDC_SIZENS);
+ hCurSplitWE = LoadCursor(NULL, IDC_SIZEWE);
+ hCurHyperlinkHand = LoadCursor(NULL, IDC_HAND);
+ if (hCurHyperlinkHand == NULL)
+ hCurHyperlinkHand = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_HYPERLINKHAND));
+ return 0;
+}
+
+static IRichEditOleCallbackVtbl reOleCallbackVtbl;
+struct CREOleCallback reOleCallback;
+
+static STDMETHODIMP_(ULONG) CREOleCallback_QueryInterface(struct CREOleCallback *lpThis, REFIID riid, LPVOID * ppvObj)
+{
+ if (IsEqualIID(riid, &IID_IRichEditOleCallback)) {
+ *ppvObj = lpThis;
+ lpThis->lpVtbl->AddRef((IRichEditOleCallback *) lpThis);
+ return S_OK;
+ }
+ *ppvObj = NULL;
+ return E_NOINTERFACE;
+}
+
+static STDMETHODIMP_(ULONG) CREOleCallback_AddRef(struct CREOleCallback *lpThis)
+{
+ if (lpThis->refCount == 0) {
+ if (S_OK != StgCreateDocfile(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &lpThis->pictStg))
+ lpThis->pictStg = NULL;
+ lpThis->nextStgId = 0;
+ }
+ return ++lpThis->refCount;
+}
+
+static STDMETHODIMP_(ULONG) CREOleCallback_Release(struct CREOleCallback *lpThis)
+{
+ if (--lpThis->refCount == 0) {
+ if (lpThis->pictStg)
+ lpThis->pictStg->lpVtbl->Release(lpThis->pictStg);
+ }
+ return lpThis->refCount;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_ContextSensitiveHelp(struct CREOleCallback *lpThis, BOOL fEnterMode)
+{
+ return S_OK;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_DeleteObject(struct CREOleCallback *lpThis, LPOLEOBJECT lpoleobj)
+{
+ return S_OK;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_GetClipboardData(struct CREOleCallback *lpThis, CHARRANGE * lpchrg, DWORD reco, LPDATAOBJECT * lplpdataobj)
+{
+ return E_NOTIMPL;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_GetContextMenu(struct CREOleCallback *lpThis, WORD seltype, LPOLEOBJECT lpoleobj, CHARRANGE * lpchrg, HMENU * lphmenu)
+{
+ return E_INVALIDARG;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_GetDragDropEffect(struct CREOleCallback *lpThis, BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect)
+{
+ return S_OK;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_GetInPlaceContext(struct CREOleCallback *lpThis, LPOLEINPLACEFRAME * lplpFrame, LPOLEINPLACEUIWINDOW * lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo)
+{
+ return E_INVALIDARG;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_GetNewStorage(struct CREOleCallback *lpThis, LPSTORAGE * lplpstg)
+{
+ WCHAR szwName[64];
+ char szName[64];
+ wsprintfA(szName, "s%u", lpThis->nextStgId);
+ MultiByteToWideChar(CP_ACP, 0, szName, -1, szwName, SIZEOF(szwName));
+ if (lpThis->pictStg == NULL)
+ return STG_E_MEDIUMFULL;
+ return lpThis->pictStg->lpVtbl->CreateStorage(lpThis->pictStg, szwName, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, lplpstg);
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_QueryAcceptData(struct CREOleCallback *lpThis, LPDATAOBJECT lpdataobj, CLIPFORMAT * lpcfFormat, DWORD reco, BOOL fReally, HGLOBAL hMetaPict)
+{
+ return S_OK;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_QueryInsertObject(struct CREOleCallback *lpThis, LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp)
+{
+ return S_OK;
+}
+
+static STDMETHODIMP_(HRESULT) CREOleCallback_ShowContainerUI(struct CREOleCallback *lpThis, BOOL fShow)
+{
+ return S_OK;
+}
+
+static void InitREOleCallback(void)
+{
+ reOleCallback.lpVtbl = &reOleCallbackVtbl;
+ reOleCallback.lpVtbl->AddRef = (ULONG(__stdcall *) (IRichEditOleCallback *)) CREOleCallback_AddRef;
+ reOleCallback.lpVtbl->Release = (ULONG(__stdcall *) (IRichEditOleCallback *)) CREOleCallback_Release;
+ reOleCallback.lpVtbl->QueryInterface = (ULONG(__stdcall *) (IRichEditOleCallback *, REFIID, PVOID *)) CREOleCallback_QueryInterface;
+ reOleCallback.lpVtbl->ContextSensitiveHelp = (HRESULT(__stdcall *) (IRichEditOleCallback *, BOOL)) CREOleCallback_ContextSensitiveHelp;
+ reOleCallback.lpVtbl->DeleteObject = (HRESULT(__stdcall *) (IRichEditOleCallback *, LPOLEOBJECT)) CREOleCallback_DeleteObject;
+ reOleCallback.lpVtbl->GetClipboardData = (HRESULT(__stdcall *) (IRichEditOleCallback *, CHARRANGE *, DWORD, LPDATAOBJECT *)) CREOleCallback_GetClipboardData;
+ reOleCallback.lpVtbl->GetContextMenu = (HRESULT(__stdcall *) (IRichEditOleCallback *, WORD, LPOLEOBJECT, CHARRANGE *, HMENU *)) CREOleCallback_GetContextMenu;
+ reOleCallback.lpVtbl->GetDragDropEffect = (HRESULT(__stdcall *) (IRichEditOleCallback *, BOOL, DWORD, LPDWORD)) CREOleCallback_GetDragDropEffect;
+ reOleCallback.lpVtbl->GetInPlaceContext = (HRESULT(__stdcall *) (IRichEditOleCallback *, LPOLEINPLACEFRAME *, LPOLEINPLACEUIWINDOW *, LPOLEINPLACEFRAMEINFO))
+ CREOleCallback_GetInPlaceContext;
+ reOleCallback.lpVtbl->GetNewStorage = (HRESULT(__stdcall *) (IRichEditOleCallback *, LPSTORAGE *)) CREOleCallback_GetNewStorage;
+ reOleCallback.lpVtbl->QueryAcceptData = (HRESULT(__stdcall *) (IRichEditOleCallback *, LPDATAOBJECT, CLIPFORMAT *, DWORD, BOOL, HGLOBAL)) CREOleCallback_QueryAcceptData;
+ reOleCallback.lpVtbl->QueryInsertObject = (HRESULT(__stdcall *) (IRichEditOleCallback *, LPCLSID, LPSTORAGE, LONG)) CREOleCallback_QueryInsertObject;
+ reOleCallback.lpVtbl->ShowContainerUI = (HRESULT(__stdcall *) (IRichEditOleCallback *, BOOL)) CREOleCallback_ShowContainerUI;
+ reOleCallback.refCount = 0;
+}
diff --git a/miranda-wine/plugins/srmm/msgs.h b/miranda-wine/plugins/srmm/msgs.h new file mode 100644 index 0000000..538f8b5 --- /dev/null +++ b/miranda-wine/plugins/srmm/msgs.h @@ -0,0 +1,211 @@ +/*
+SRMM
+
+Copyright 2000-2005 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.
+*/
+#ifndef SRMM_MSGS_H
+#define SRMM_MSGS_H
+
+#include <richedit.h>
+#include <richole.h>
+#define MSGERROR_CANCEL 0
+#define MSGERROR_RETRY 1
+
+struct NewMessageWindowLParam
+{
+ HANDLE hContact;
+ const char *szInitialText;
+ int isWchar;
+};
+
+struct MessageWindowData
+{
+ HANDLE hContact;
+ HANDLE hDbEventFirst, hDbEventLast;
+ HANDLE hSendId;
+ int sendCount;
+ HBRUSH hBkgBrush;
+ int splitterPos, originalSplitterPos;
+ char *sendBuffer;
+ SIZE minEditBoxSize;
+ RECT minEditInit;
+ int lineHeight;
+ int windowWasCascaded;
+ int nFlash;
+ int nFlashMax;
+ int nLabelRight;
+ int nTypeSecs;
+ int nTypeMode;
+ int avatarWidth;
+ int avatarHeight;
+ int limitAvatarH;
+ HBITMAP avatarPic;
+ DWORD nLastTyping;
+ int showTyping;
+ HWND hwndStatus;
+ DWORD lastMessage;
+ char *szProto;
+ WORD wStatus;
+ WORD wOldStatus;
+ TCmdList *cmdList;
+ TCmdList *cmdListCurrent;
+ int bIsRtl, bIsFirstAppend, bIsAutoRTL;
+ int lastEventType;
+};
+
+#define HM_EVENTSENT (WM_USER+10)
+#define DM_REMAKELOG (WM_USER+11)
+#define HM_DBEVENTADDED (WM_USER+12)
+#define DM_CASCADENEWWINDOW (WM_USER+13)
+#define DM_OPTIONSAPPLIED (WM_USER+14)
+#define DM_SPLITTERMOVED (WM_USER+15)
+#define DM_UPDATETITLE (WM_USER+16)
+#define DM_APPENDTOLOG (WM_USER+17)
+#define DM_ERRORDECIDED (WM_USER+18)
+#define DM_SCROLLLOGTOBOTTOM (WM_USER+19)
+#define DM_TYPING (WM_USER+20)
+#define DM_UPDATEWINICON (WM_USER+21)
+#define DM_UPDATELASTMESSAGE (WM_USER+22)
+#define DM_USERNAMETOCLIP (WM_USER+23)
+#define DM_AVATARSIZECHANGE (WM_USER+24)
+#define DM_AVATARCALCSIZE (WM_USER+25)
+#define DM_GETAVATAR (WM_USER+26)
+#define DM_UPDATESIZEBAR (WM_USER+27)
+#define HM_AVATARACK (WM_USER+28)
+#define HM_ACKEVENT (WM_USER+29)
+#define DM_GETWINDOWSTATE (WM_USER+30)
+
+#define EVENTTYPE_STATUSCHANGE 25368
+
+struct CREOleCallback
+{
+ IRichEditOleCallbackVtbl *lpVtbl;
+ unsigned refCount;
+ IStorage *pictStg;
+ int nextStgId;
+};
+
+BOOL CALLBACK DlgProcMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+int InitOptions(void);
+BOOL CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+int DbEventIsShown(DBEVENTINFO * dbei, struct MessageWindowData *dat);
+void StreamInEvents(HWND hwndDlg, HANDLE hDbEventFirst, int count, int fAppend);
+void LoadMsgLogIcons(void);
+void FreeMsgLogIcons(void);
+
+#define MSGFONTID_MYMSG 0
+#define MSGFONTID_YOURMSG 1
+#define MSGFONTID_MYNAME 2
+#define MSGFONTID_MYTIME 3
+#define MSGFONTID_MYCOLON 4
+#define MSGFONTID_YOURNAME 5
+#define MSGFONTID_YOURTIME 6
+#define MSGFONTID_YOURCOLON 7
+#define MSGFONTID_MESSAGEAREA 8
+#define MSGFONTID_NOTICE 9
+
+void LoadMsgDlgFont(int i, LOGFONT* lf, COLORREF* colour);
+extern const int msgDlgFontCount;
+
+#define LOADHISTORY_UNREAD 0
+#define LOADHISTORY_COUNT 1
+#define LOADHISTORY_TIME 2
+
+#define SRMMMOD "SRMM"
+
+#define SRMSGSET_POPFLAGS "PopupFlags"
+#define SRMSGDEFSET_POPFLAGS 0
+#define SRMSGSET_SHOWBUTTONLINE "ShowButtonLine"
+#define SRMSGDEFSET_SHOWBUTTONLINE 1
+#define SRMSGSET_SHOWINFOLINE "ShowInfoLine"
+#define SRMSGDEFSET_SHOWINFOLINE 1
+#define SRMSGSET_AUTOMIN "AutoMin"
+#define SRMSGDEFSET_AUTOMIN 0
+#define SRMSGSET_AUTOCLOSE "AutoClose"
+#define SRMSGDEFSET_AUTOCLOSE 0
+#define SRMSGSET_SAVEPERCONTACT "SavePerContact"
+#define SRMSGDEFSET_SAVEPERCONTACT 0
+#define SRMSGSET_CASCADE "Cascade"
+#define SRMSGDEFSET_CASCADE 1
+#define SRMSGSET_SENDONENTER "SendOnEnter"
+#define SRMSGDEFSET_SENDONENTER 1
+#define SRMSGSET_SENDONDBLENTER "SendOnDblEnter"
+#define SRMSGDEFSET_SENDONDBLENTER 0
+#define SRMSGSET_STATUSICON "UseStatusWinIcon"
+#define SRMSGDEFSET_STATUSICON 0
+#define SRMSGSET_SENDBUTTON "UseSendButton"
+#define SRMSGDEFSET_SENDBUTTON 0
+#define SRMSGSET_CHARCOUNT "ShowCharCount"
+#define SRMSGDEFSET_CHARCOUNT 0
+#define SRMSGSET_CTRLSUPPORT "SupportCtrlUpDn"
+#define SRMSGDEFSET_CTRLSUPPORT 1
+#define SRMSGSET_DELTEMP "DeleteTempCont"
+#define SRMSGDEFSET_DELTEMP 0
+#define SRMSGSET_MSGTIMEOUT "MessageTimeout"
+#define SRMSGDEFSET_MSGTIMEOUT 10000
+#define SRMSGSET_MSGTIMEOUT_MIN 4000 // minimum value (4 seconds)
+#define SRMSGSET_FLASHCOUNT "FlashMax"
+#define SRMSGDEFSET_FLASHCOUNT 5
+
+#define SRMSGSET_LOADHISTORY "LoadHistory"
+#define SRMSGDEFSET_LOADHISTORY LOADHISTORY_UNREAD
+#define SRMSGSET_LOADCOUNT "LoadCount"
+#define SRMSGDEFSET_LOADCOUNT 10
+#define SRMSGSET_LOADTIME "LoadTime"
+#define SRMSGDEFSET_LOADTIME 10
+
+#define SRMSGSET_SHOWLOGICONS "ShowLogIcon"
+#define SRMSGDEFSET_SHOWLOGICONS 1
+#define SRMSGSET_HIDENAMES "HideNames"
+#define SRMSGDEFSET_HIDENAMES 1
+#define SRMSGSET_SHOWTIME "ShowTime"
+#define SRMSGDEFSET_SHOWTIME 1
+#define SRMSGSET_SHOWSECS "ShowSeconds"
+#define SRMSGDEFSET_SHOWSECS 1
+#define SRMSGSET_SHOWDATE "ShowDate"
+#define SRMSGDEFSET_SHOWDATE 0
+#define SRMSGSET_SHOWSTATUSCH "ShowStatusChanges"
+#define SRMSGDEFSET_SHOWSTATUSCH 1
+#define SRMSGSET_BKGCOLOUR "BkgColour"
+#define SRMSGDEFSET_BKGCOLOUR GetSysColor(COLOR_WINDOW)
+
+#define SRMSGSET_TYPING "SupportTyping"
+#define SRMSGSET_TYPINGNEW "DefaultTyping"
+#define SRMSGDEFSET_TYPINGNEW 1
+#define SRMSGSET_TYPINGUNKNOWN "UnknownTyping"
+#define SRMSGDEFSET_TYPINGUNKNOWN 0
+#define SRMSGSET_SHOWTYPING "ShowTyping"
+#define SRMSGDEFSET_SHOWTYPING 1
+#define SRMSGSET_SHOWTYPINGWIN "ShowTypingWin"
+#define SRMSGDEFSET_SHOWTYPINGWIN 1
+#define SRMSGSET_SHOWTYPINGNOWIN "ShowTypingTray"
+#define SRMSGDEFSET_SHOWTYPINGNOWIN 0
+#define SRMSGSET_SHOWTYPINGCLIST "ShowTypingClist"
+#define SRMSGDEFSET_SHOWTYPINGCLIST 1
+
+
+#define SRMSGSET_AVATARENABLE "AvatarEnable"
+#define SRMSGDEFSET_AVATARENABLE 1
+#define SRMSGSET_LIMITAVHEIGHT "AvatarLimitHeight"
+#define SRMSGDEFSET_LIMITAVHEIGHT 1
+#define SRMSGSET_AVHEIGHT "AvatarHeight"
+#define SRMSGDEFSET_AVHEIGHT 60
+#define SRMSGSET_AVATAR "Avatar"
+
+#endif
diff --git a/miranda-wine/plugins/srmm/msgtimedout.c b/miranda-wine/plugins/srmm/msgtimedout.c new file mode 100644 index 0000000..5539ff0 --- /dev/null +++ b/miranda-wine/plugins/srmm/msgtimedout.c @@ -0,0 +1,71 @@ +/*
+SRMM
+
+Copyright 2000-2005 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"
+#pragma hdrstop
+#include "msgs.h"
+
+BOOL CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ char* pszError = ( char* )GetWindowLong(hwndDlg, GWL_USERDATA);
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ {
+ RECT rc, rcParent;
+
+ SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) pszError);
+
+ TranslateDialogDefault(hwndDlg);
+
+ if (lParam) {
+ pszError = (char *) lParam;
+ if (!pszError||!strlen(pszError))
+ pszError = strdup(Translate("An unknown error has occured."));
+ SetDlgItemTextA(hwndDlg, IDC_ERRORTEXT, pszError);
+ }
+
+ GetWindowRect(hwndDlg, &rc);
+ GetWindowRect(GetParent(hwndDlg), &rcParent);
+ SetWindowPos(hwndDlg, 0, (rcParent.left + rcParent.right - (rc.right - rc.left)) / 2, (rcParent.top + rcParent.bottom - (rc.bottom - rc.top)) / 2, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDOK:
+ if (pszError)
+ free(pszError);
+ SendMessage(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_RETRY, 0);
+ DestroyWindow(hwndDlg);
+ break;
+ case IDCANCEL:
+ if (pszError)
+ free(pszError);
+ SendMessage(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_CANCEL, 0);
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
diff --git a/miranda-wine/plugins/srmm/res/add.ico b/miranda-wine/plugins/srmm/res/add.ico Binary files differnew file mode 100644 index 0000000..2efc4dc --- /dev/null +++ b/miranda-wine/plugins/srmm/res/add.ico diff --git a/miranda-wine/plugins/srmm/res/clock.ico b/miranda-wine/plugins/srmm/res/clock.ico Binary files differnew file mode 100644 index 0000000..83b8abf --- /dev/null +++ b/miranda-wine/plugins/srmm/res/clock.ico diff --git a/miranda-wine/plugins/srmm/res/details.ico b/miranda-wine/plugins/srmm/res/details.ico Binary files differnew file mode 100644 index 0000000..a2c16ae --- /dev/null +++ b/miranda-wine/plugins/srmm/res/details.ico diff --git a/miranda-wine/plugins/srmm/res/downarrow.ico b/miranda-wine/plugins/srmm/res/downarrow.ico Binary files differnew file mode 100644 index 0000000..76a473c --- /dev/null +++ b/miranda-wine/plugins/srmm/res/downarrow.ico diff --git a/miranda-wine/plugins/srmm/res/history.ico b/miranda-wine/plugins/srmm/res/history.ico Binary files differnew file mode 100644 index 0000000..2749b50 --- /dev/null +++ b/miranda-wine/plugins/srmm/res/history.ico diff --git a/miranda-wine/plugins/srmm/res/incoming.ico b/miranda-wine/plugins/srmm/res/incoming.ico Binary files differnew file mode 100644 index 0000000..fabbf97 --- /dev/null +++ b/miranda-wine/plugins/srmm/res/incoming.ico diff --git a/miranda-wine/plugins/srmm/res/notice.ico b/miranda-wine/plugins/srmm/res/notice.ico Binary files differnew file mode 100644 index 0000000..23527a9 --- /dev/null +++ b/miranda-wine/plugins/srmm/res/notice.ico diff --git a/miranda-wine/plugins/srmm/res/outgoing.ico b/miranda-wine/plugins/srmm/res/outgoing.ico Binary files differnew file mode 100644 index 0000000..f772ab3 --- /dev/null +++ b/miranda-wine/plugins/srmm/res/outgoing.ico diff --git a/miranda-wine/plugins/srmm/res/typing.ico b/miranda-wine/plugins/srmm/res/typing.ico Binary files differnew file mode 100644 index 0000000..6dd597e --- /dev/null +++ b/miranda-wine/plugins/srmm/res/typing.ico diff --git a/miranda-wine/plugins/srmm/resource.h b/miranda-wine/plugins/srmm/resource.h new file mode 100644 index 0000000..d1e7ce3 --- /dev/null +++ b/miranda-wine/plugins/srmm/resource.h @@ -0,0 +1,93 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_MSGSENDERROR 102
+#define IDI_USERDETAILS 160
+#define IDI_HISTORY 174
+#define IDR_CONTEXT 180
+#define IDC_DROP 183
+#define IDI_ADDCONTACT 210
+#define IDC_HYPERLINKHAND 214
+#define IDC_DROPUSER 215
+#define IDD_OPT_MSGDLG 243
+#define IDD_MSG 244
+#define IDD_OPT_MSGLOG 245
+#define IDI_DOWNARROW 264
+#define IDI_TYPING 268
+#define IDD_OPT_MSGTYPE 275
+#define IDI_INCOMING 276
+#define IDI_OUTGOING 277
+#define IDI_NOTICE 282
+#define IDC_LOG 1001
+#define IDC_MESSAGE 1002
+#define IDC_AUTOCLOSE 1004
+#define IDC_AUTOMIN 1005
+#define IDC_NAME 1009
+#define IDC_SPLITTER 1017
+#define IDC_SHOWNAMES 1024
+#define IDC_SHOWSENDBTN 1029
+#define IDC_SHOWLOGICONS 1032
+#define IDC_SHOWTIMES 1033
+#define IDC_SHOWDATES 1034
+#define IDC_CLIST 1035
+#define IDC_SHOWSTATUSCHANGES 1035
+#define IDC_SAVEPERCONTACT 1037
+#define IDC_LOADCOUNTN 1039
+#define IDC_LOADCOUNTSPIN 1040
+#define IDC_SHOWINFOLINE 1041
+#define IDC_SHOWBUTTONLINE 1042
+#define IDC_LOADUNREAD 1043
+#define IDC_SENDONENTER 1043
+#define IDC_LOADCOUNT 1044
+#define IDC_SENDONDBLENTER 1044
+#define IDC_LOADTIMEN 1045
+#define IDC_LOADTIMESPIN 1046
+#define IDC_LOADTIME 1047
+#define IDC_FONTLIST 1048
+#define IDC_CHOOSEFONT 1049
+#define IDC_STMINSOLD 1051
+#define IDC_DETAILS 1069
+#define IDC_ADD 1070
+#define IDC_USERMENU 1071
+#define IDC_HISTORY 1080
+#define IDC_BKGCOLOUR 1269
+#define IDC_FONTCOLOUR 1282
+#define IDC_STMSGLOGGROUP 1442
+#define IDC_PROTOCOL 1580
+#define IDC_ERRORTEXT 1596
+#define IDC_SHOWNOTIFY 1600
+#define IDC_STATUSWIN 1601
+#define IDC_TYPEWIN 1602
+#define IDC_CHARCOUNT 1603
+#define IDC_TYPETRAY 1603
+#define IDC_CASCADE 1604
+#define IDC_SECONDS 1605
+#define IDC_NOTIFYTRAY 1606
+#define IDC_NOTIFYBALLOON 1607
+#define IDC_CTRLSUPPORT 1608
+#define IDC_DELTEMP 1609
+#define IDC_AVATAR 1610
+#define IDC_AVATARSUPPORT 1611
+#define IDC_LIMITAVATARH 1612
+#define IDC_AVATARHEIGHT 1613
+#define IDC_SHOWSECS 1614
+#define IDC_POPLIST 1616
+#define IDM_COPY 40001
+#define IDM_COPYALL 40011
+#define IDM_SELECTALL 40012
+#define IDM_CLEAR 40013
+#define IDM_OPENNEW 40014
+#define IDM_OPENEXISTING 40015
+#define IDM_COPYLINK 40016
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 286
+#define _APS_NEXT_COMMAND_VALUE 40019
+#define _APS_NEXT_CONTROL_VALUE 1617
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/miranda-wine/plugins/srmm/resource.rc b/miranda-wine/plugins/srmm/resource.rc new file mode 100644 index 0000000..3dfc7e8 --- /dev/null +++ b/miranda-wine/plugins/srmm/resource.rc @@ -0,0 +1,356 @@ +//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+#include <winres.h>
+#include "../../include/statusmodes.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPT_MSGDLG DIALOGEX 0, 0, 312, 234
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Message Window Options",IDC_STATIC,2,0,310,231
+ CONTROL "Close the message window on send",IDC_AUTOCLOSE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,8,58,212,10
+ CONTROL "Minimize the message window on send",IDC_AUTOMIN,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,8,70,221,10
+ CONTROL "Use the contact's status icon as the window icon",
+ IDC_STATUSWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,82,
+ 273,10
+ CONTROL "Save the window size and location individually for each contact",
+ IDC_SAVEPERCONTACT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 8,94,300,10
+ CONTROL "Cascade new windows",IDC_CASCADE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,8,106,136,10
+ CONTROL "Show 'Send' button",IDC_SHOWSENDBTN,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,8,174,135,10
+ CONTROL "Show username on top row",IDC_SHOWINFOLINE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,8,187,138,10
+ CONTROL "Show toolbar buttons on top row",IDC_SHOWBUTTONLINE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,200,137,10
+ CONTROL "Send message on double 'Enter'",IDC_SENDONDBLENTER,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,148,174,137,10
+ CONTROL "Send message on 'Enter'",IDC_SENDONENTER,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,148,187,137,10
+ CONTROL "Show character count",IDC_CHARCOUNT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,148,200,133,10
+ LTEXT "Show warning when message has not been received after",
+ IDC_STATIC,8,216,211,8
+ EDITTEXT IDC_SECONDS,223,214,25,12,ES_AUTOHSCROLL
+ LTEXT "seconds.",IDC_STATIC,253,216,44,8
+ CONTROL "Support control up/down in message area to show previously sent messages",
+ IDC_CTRLSUPPORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,
+ 118,298,10
+ CONTROL "Delete temporary contacts when closing message window",
+ IDC_DELTEMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,130,
+ 287,10
+ CONTROL "Enable avatar support in the message window",
+ IDC_AVATARSUPPORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 8,143,279,10
+ CONTROL "Limit avatar height to ",IDC_LIMITAVATARH,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,22,157,106,10
+ EDITTEXT IDC_AVATARHEIGHT,148,156,28,13,ES_AUTOHSCROLL
+ LTEXT "pixels.",IDC_STATIC,181,158,35,8
+ CONTROL "Tree1",IDC_POPLIST,"SysTreeView32",TVS_DISABLEDRAGDROP |
+ TVS_NOTOOLTIPS | TVS_NONEVENHEIGHT | WS_BORDER |
+ WS_TABSTOP,163,14,98,42
+ LTEXT "Automatically popup window when:",IDC_STATIC,10,15,141,
+ 13
+END
+
+IDD_MSGSENDERROR DIALOGEX 0, 0, 187, 97
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP |
+ WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_SETFONT
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Send Error"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "An error has occured. The protocol reported the following error:",
+ IDC_STATIC,5,5,177,28
+ DEFPUSHBUTTON "Try again",IDOK,22,78,63,14
+ PUSHBUTTON "Cancel",IDCANCEL,104,78,61,14
+ EDITTEXT IDC_ERRORTEXT,5,37,177,35,ES_MULTILINE | ES_READONLY |
+ WS_VSCROLL
+END
+
+IDD_MSG DIALOGEX 0, 0, 184, 78
+STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER |
+ WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CLIPCHILDREN |
+ WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | DS_SETFONT
+EXSTYLE WS_EX_ACCEPTFILES
+CAPTION "Message Session"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_MESSAGE,1,49,141,13,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_WANTRETURN | WS_VSCROLL,WS_EX_ACCEPTFILES
+ DEFPUSHBUTTON "&Send",IDOK,143,48,39,15
+ PUSHBUTTON "Close",IDCANCEL,129,0,54,15,NOT WS_VISIBLE
+ CONTROL "",IDC_PROTOCOL,"Button",BS_OWNERDRAW,2,5,12,12
+ CONTROL "",IDC_NAME,"MButtonClass",WS_TABSTOP,15,2,95,14,
+ 0x18000000L
+ CONTROL "",IDC_ADD,"MButtonClass",WS_TABSTOP,110,2,16,14,
+ 0x18000000L
+ CONTROL "",IDC_USERMENU,"MButtonClass",WS_TABSTOP,128,2,16,14,
+ 0x18000000L
+ CONTROL "&D",IDC_DETAILS,"MButtonClass",WS_TABSTOP,146,2,16,14,
+ 0x18000000L
+ CONTROL "&H",IDC_HISTORY,"MButtonClass",WS_TABSTOP,164,2,16,14,
+ 0x18000000L
+ CONTROL "",IDC_LOG,"RichEdit20A",WS_VSCROLL | WS_TABSTOP | 0x844,
+ 1,18,181,26,WS_EX_CLIENTEDGE
+ CONTROL "",IDC_SPLITTER,"Static",SS_ENHMETAFILE,0,45,183,2
+ CONTROL "",IDC_AVATAR,"Button",BS_OWNERDRAW | NOT WS_VISIBLE,1,
+ 50,1,13
+END
+
+IDD_OPT_MSGLOG DIALOGEX 0, 0, 306, 229
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Message Window Event Log",IDC_STMSGLOGGROUP,0,0,158,158
+ CONTROL "Show icons",IDC_SHOWLOGICONS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,10,12,146,10
+ CONTROL "Show names",IDC_SHOWNAMES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,10,28,146,10
+ CONTROL "Show timestamp",IDC_SHOWTIMES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,10,44,146,10
+ CONTROL "Show dates",IDC_SHOWDATES,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,21,75,135,10
+ GROUPBOX "Fonts",IDC_STATIC,163,0,143,158
+ LTEXT "Background colour:",IDC_STATIC,169,16,81,8
+ CONTROL "",IDC_BKGCOLOUR,"ColourPicker",WS_TABSTOP,261,14,39,12
+ LISTBOX IDC_FONTLIST,169,31,131,82,LBS_OWNERDRAWVARIABLE |
+ LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "",IDC_FONTCOLOUR,"ColourPicker",WS_TABSTOP,169,117,57,
+ 14
+ PUSHBUTTON "Choose font...",IDC_CHOOSEFONT,243,117,57,14
+ GROUPBOX "Load History Events",IDC_STATIC,0,163,306,66
+ CONTROL "Load unread events only",IDC_LOADUNREAD,"Button",
+ BS_AUTORADIOBUTTON | WS_TABSTOP,10,177,138,10
+ CONTROL "Load number of previous events",IDC_LOADCOUNT,"Button",
+ BS_AUTORADIOBUTTON,10,193,138,10
+ EDITTEXT IDC_LOADCOUNTN,148,192,33,12,ES_RIGHT | ES_NUMBER |
+ WS_DISABLED
+ CONTROL "Spin1",IDC_LOADCOUNTSPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK |
+ WS_DISABLED,170,191,10,14
+ CONTROL "Load previous events less than",IDC_LOADTIME,"Button",
+ BS_AUTORADIOBUTTON,10,209,138,10
+ EDITTEXT IDC_LOADTIMEN,148,208,33,12,ES_RIGHT | ES_NUMBER |
+ WS_DISABLED
+ CONTROL "Spin1",IDC_LOADTIMESPIN,"msctls_updown32",
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK |
+ WS_DISABLED,170,207,10,14
+ LTEXT "minutes old",IDC_STMINSOLD,185,210,90,8,WS_DISABLED
+ CTEXT "Select multiple fonts by dragging or by using the control key",
+ IDC_STATIC,169,135,131,16
+ CONTROL "Show status changes",IDC_SHOWSTATUSCHANGES,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,10,92,146,10
+ CONTROL "Show seconds",IDC_SHOWSECS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,21,59,127,10
+END
+
+IDD_OPT_MSGTYPE DIALOGEX 0, 0, 283, 252
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Typing Notification Options",IDC_STATIC,7,7,269,238
+ CONTROL "",IDC_CLIST,"CListControl",WS_TABSTOP | 0x348,18,42,248,
+ 131,WS_EX_CLIENTEDGE
+ LTEXT "Send typing notifications to the following users when you are typing a message to them:",
+ IDC_STATIC,19,18,245,19
+ CONTROL "Show typing notifications when a user is typing a message",
+ IDC_SHOWNOTIFY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,
+ 178,233,13
+ CONTROL "Update inactive message window icons when a user is typing",
+ IDC_TYPEWIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,29,193,
+ 230,10
+ CONTROL "Show typing notification when no message dialog is open",
+ IDC_TYPETRAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,29,
+ 206,230,10
+ CONTROL "Flash in the system tray and in the contact list",
+ IDC_NOTIFYTRAY,"Button",BS_AUTORADIOBUTTON,44,219,206,10
+ CONTROL "Show balloon popup",IDC_NOTIFYBALLOON,"Button",
+ BS_AUTORADIOBUTTON,44,231,206,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_OPT_MSGDLG, DIALOG
+ BEGIN
+ VERTGUIDE, 10
+ VERTGUIDE, 22
+ VERTGUIDE, 51
+ VERTGUIDE, 148
+ VERTGUIDE, 300
+ VERTGUIDE, 310
+ BOTTOMMARGIN, 231
+ END
+
+ IDD_MSGSENDERROR, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 182
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 92
+ END
+
+ IDD_MSG, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 179
+ TOPMARGIN, 5
+ HORZGUIDE, 16
+ HORZGUIDE, 53
+ END
+
+ IDD_OPT_MSGLOG, DIALOG
+ BEGIN
+ VERTGUIDE, 10
+ VERTGUIDE, 148
+ VERTGUIDE, 156
+ VERTGUIDE, 169
+ VERTGUIDE, 300
+ HORZGUIDE, 183
+ HORZGUIDE, 199
+ END
+
+ IDD_OPT_MSGTYPE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 276
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 245
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include <windows.h>\r\n"
+ "#include <winres.h>\r\n"
+ "#include ""../../include/statusmodes.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_USERDETAILS ICON DISCARDABLE "res/Details.ico"
+IDI_ADDCONTACT ICON DISCARDABLE "res\\add.ico"
+IDI_HISTORY ICON DISCARDABLE "res/History.ico"
+IDI_DOWNARROW ICON DISCARDABLE "res/Downarrow.ico"
+IDI_TYPING ICON DISCARDABLE "res/Typing.ico"
+IDI_OUTGOING ICON DISCARDABLE "res\\outgoing.ico"
+IDI_INCOMING ICON DISCARDABLE "res\\incoming.ico"
+IDI_NOTICE ICON DISCARDABLE "res\\notice.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Cursor
+//
+
+IDC_HYPERLINKHAND CURSOR DISCARDABLE "../../src/res/hyperlin.cur"
+IDC_DROP CURSOR DISCARDABLE "../../src/res/dragcopy.cur"
+IDC_DROPUSER CURSOR DISCARDABLE "../../src/res/dropuser.cur"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_CONTEXT MENU DISCARDABLE
+BEGIN
+ POPUP "Log"
+ BEGIN
+ MENUITEM "C&lear Log", IDM_CLEAR
+ MENUITEM SEPARATOR
+ MENUITEM "&Copy", IDM_COPY
+ MENUITEM "Co&py All", IDM_COPYALL
+ MENUITEM SEPARATOR
+ MENUITEM "Select &All", IDM_SELECTALL
+ END
+ POPUP "LogLink"
+ BEGIN
+ MENUITEM "Open in &new window", IDM_OPENNEW
+ MENUITEM "&Open in existing window", IDM_OPENEXISTING
+ MENUITEM "&Copy link", IDM_COPYLINK
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/miranda-wine/plugins/srmm/richutil.c b/miranda-wine/plugins/srmm/richutil.c new file mode 100644 index 0000000..d803af8 --- /dev/null +++ b/miranda-wine/plugins/srmm/richutil.c @@ -0,0 +1,234 @@ +/*
+SRMM
+
+Copyright 2000-2005 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 "richutil.h"
+
+/*
+ To initialize this library, call:
+ RichUtil_Load();
+ Before the application exits, call:
+ RichUtil_Unload();
+
+ Then to use the library (it draws the xp border around it), you need
+ to make sure you control has the WS_EX_CLIENTEDGE flag. Then you just
+ subclass it with:
+ RichUtil_SubClass(hwndEdit);
+
+ If no xptheme is present, the window isn't subclassed the SubClass function
+ just returns. And if WS_EX_CLIENTEDGE isn't present, the subclass does nothing.
+ Otherwise it removes the border and draws it by itself.
+*/
+
+static struct LIST_INTERFACE li;
+static SortedList sListInt;
+
+static int RichUtil_CmpVal(void *p1, void *p2) {
+ TRichUtil *tp1 = (TRichUtil*)p1;
+ TRichUtil *tp2 = (TRichUtil*)p2;
+ if (tp1->hwnd==tp2->hwnd)
+ return 0;
+ return (int)((int)tp1->hwnd-(int)tp2->hwnd);
+}
+
+// UxTheme Stuff
+static HMODULE mTheme = 0;
+static HANDLE (WINAPI *MyOpenThemeData)(HWND,LPCWSTR) = 0;
+static HRESULT (WINAPI *MyCloseThemeData)(HANDLE) = 0;
+static BOOL (WINAPI *MyIsThemeActive)() = 0;
+static HRESULT (WINAPI *MyDrawThemeBackground)(HANDLE,HDC,int,int,const RECT*,const RECT *) = 0;
+static HRESULT (WINAPI *MyGetThemeBackgroundContentRect)(HANDLE,HDC,int,int,const RECT *,RECT *) = 0;
+static HRESULT (WINAPI *MyDrawThemeParentBackground)(HWND,HDC,RECT*) = 0;
+static BOOL (WINAPI *MyIsThemeBackgroundPartiallyTransparent)(HANDLE,int,int) = 0;
+
+static CRITICAL_SECTION csRich;
+
+static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+static RichUtil_ClearUglyBorder(TRichUtil *ru);
+
+void RichUtil_Load() {
+ li.cbSize = sizeof(li);
+ CallService(MS_SYSTEM_GET_LI,0,(LPARAM)&li);
+ ZeroMemory(&sListInt, sizeof(sListInt));
+ sListInt.increment = 10;
+ sListInt.sortFunc = RichUtil_CmpVal;
+ mTheme = RIsWinVerXPPlus()?LoadLibraryA("uxtheme.dll"):0;
+ InitializeCriticalSection(&csRich);
+ if (!mTheme) return;
+ MyOpenThemeData = (HANDLE (WINAPI *)(HWND, LPCWSTR))GetProcAddress(mTheme, "OpenThemeData");
+ MyCloseThemeData = (HRESULT (WINAPI *)(HANDLE))GetProcAddress(mTheme, "CloseThemeData");
+ MyIsThemeActive = (BOOL (WINAPI *)())GetProcAddress(mTheme, "IsThemeActive");
+ MyDrawThemeBackground = (HRESULT (WINAPI *)(HANDLE, HDC, int, int, const RECT*, const RECT *))GetProcAddress(mTheme, "DrawThemeBackground");
+ MyGetThemeBackgroundContentRect = (HRESULT (WINAPI *)(HANDLE, HDC, int, int, const RECT *, RECT *))GetProcAddress(mTheme, "GetThemeBackgroundContentRect");
+ MyDrawThemeParentBackground = (HRESULT (WINAPI *)(HWND, HDC, RECT*))GetProcAddress(mTheme, "DrawThemeParentBackground");
+ MyIsThemeBackgroundPartiallyTransparent = (BOOL (WINAPI *)(HANDLE, int, int))GetProcAddress(mTheme, "IsThemeBackgroundPartiallyTransparent");
+ if (!MyOpenThemeData||
+ !MyCloseThemeData||
+ !MyIsThemeActive||
+ !MyDrawThemeBackground||
+ !MyGetThemeBackgroundContentRect||
+ !MyDrawThemeParentBackground||
+ !MyIsThemeBackgroundPartiallyTransparent) {
+ FreeLibrary(mTheme);
+ mTheme=NULL;
+ }
+}
+
+void RichUtil_Unload() {
+ li.List_Destroy(&sListInt);
+ DeleteCriticalSection(&csRich);
+ if (mTheme) {
+ FreeLibrary(mTheme);
+ }
+}
+
+int RichUtil_SubClass(HWND hwndEdit) {
+ if (IsWindow(hwndEdit)) {
+ int idx;
+
+ TRichUtil *ru = (TRichUtil*)malloc(sizeof(TRichUtil));
+
+ ZeroMemory(ru, sizeof(TRichUtil));
+ ru->hwnd = hwndEdit;
+ ru->hasUglyBorder = 0;
+ EnterCriticalSection(&csRich);
+ if (!li.List_GetIndex(&sListInt, ru, &idx))
+ li.List_Insert(&sListInt, ru, idx);
+ LeaveCriticalSection(&csRich);
+ SetWindowLong(ru->hwnd, GWL_USERDATA, (LONG)ru); // Ugly hack
+ ru->origProc = (WNDPROC)SetWindowLong(ru->hwnd, GWL_WNDPROC, (LONG)&RichUtil_Proc);
+ RichUtil_ClearUglyBorder(ru);
+ return 1;
+ }
+ return 0;
+}
+
+static LRESULT CALLBACK RichUtil_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ TRichUtil *ru = 0, tru;
+ int idx;
+
+ EnterCriticalSection(&csRich);
+ tru.hwnd = hwnd;
+ if (li.List_GetIndex(&sListInt, &tru, &idx))
+ ru = (TRichUtil*)sListInt.items[idx];
+ LeaveCriticalSection(&csRich);
+ switch(msg) {
+ case WM_THEMECHANGED:
+ case WM_STYLECHANGED:
+ {
+ RichUtil_ClearUglyBorder(ru);
+ break;
+ }
+ case WM_NCPAINT:
+ {
+ LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam);
+ if (ru->hasUglyBorder&&MyIsThemeActive()) {
+ HANDLE hTheme = MyOpenThemeData(ru->hwnd, L"EDIT");
+
+ if (hTheme) {
+ RECT rcBorder;
+ RECT rcClient;
+ int nState;
+ HDC hdc = GetWindowDC(ru->hwnd);
+
+ GetWindowRect(hwnd, &rcBorder);
+ rcBorder.right -= rcBorder.left; rcBorder.bottom -= rcBorder.top;
+ rcBorder.left = rcBorder.top = 0;
+ CopyRect(&rcClient, &rcBorder);
+ rcClient.left += ru->rect.left;
+ rcClient.top += ru->rect.top;
+ rcClient.right -= ru->rect.right;
+ rcClient.bottom -= ru->rect.bottom;
+ ExcludeClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
+ if(MyIsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL))
+ MyDrawThemeParentBackground(hwnd, hdc, &rcBorder);
+ if(!IsWindowEnabled(hwnd))
+ nState = ETS_DISABLED;
+ else if(SendMessage(hwnd, EM_GETOPTIONS, 0, 0) & ECO_READONLY)
+ nState = ETS_READONLY;
+ else nState = ETS_NORMAL;
+ MyDrawThemeBackground(hTheme, hdc, EP_EDITTEXT, nState, &rcBorder, NULL);
+ MyCloseThemeData(hTheme);
+ ReleaseDC(hwnd, hdc);
+ return 0;
+ }
+ }
+ return ret;
+ }
+ case WM_NCCALCSIZE:
+ {
+ LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam);
+ NCCALCSIZE_PARAMS *ncsParam = (NCCALCSIZE_PARAMS*)lParam;
+
+ if (ru->hasUglyBorder&&MyIsThemeActive()) {
+ HANDLE hTheme = MyOpenThemeData(hwnd, L"EDIT");
+
+ if (hTheme) {
+ RECT rcClient;
+ HDC hdc = GetDC(GetParent(hwnd));
+
+ ZeroMemory(&rcClient, sizeof(RECT));
+ if(MyGetThemeBackgroundContentRect(hTheme, hdc, EP_EDITTEXT, ETS_NORMAL, &ncsParam->rgrc[0], &rcClient) == S_OK) {
+ ru->rect.left = rcClient.left-ncsParam->rgrc[0].left;
+ ru->rect.top = rcClient.top-ncsParam->rgrc[0].top;
+ ru->rect.right = ncsParam->rgrc[0].right-rcClient.right;
+ ru->rect.bottom = ncsParam->rgrc[0].bottom-rcClient.bottom;
+ CopyRect(&ncsParam->rgrc[0], &rcClient);
+ MyCloseThemeData(hTheme);
+ ReleaseDC(GetParent(hwnd), hdc);
+ return WVR_REDRAW;
+ }
+ ReleaseDC(GetParent(hwnd), hdc);
+ MyCloseThemeData(hTheme);
+ }
+ }
+ return ret;
+ }
+ case WM_ENABLE:
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE|RDW_NOCHILDREN|RDW_UPDATENOW|RDW_FRAME);
+ break;
+ case WM_DESTROY:
+ {
+ LRESULT ret = CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam);
+
+ if(IsWindow(hwnd)) {
+ if((WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC) == &RichUtil_Proc)
+ SetWindowLong(hwnd, GWL_WNDPROC, (LONG)ru->origProc);
+ }
+ EnterCriticalSection(&csRich);
+ li.List_Remove(&sListInt, idx);
+ LeaveCriticalSection(&csRich);
+ if (ru) free(ru);
+ return ret;
+ }
+ }
+ return CallWindowProc(ru->origProc, hwnd, msg, wParam, lParam);
+}
+
+static RichUtil_ClearUglyBorder(TRichUtil *ru) {
+ if (mTheme&&MyIsThemeActive()&&GetWindowLong(ru->hwnd, GWL_EXSTYLE)&WS_EX_CLIENTEDGE) {
+ ru->hasUglyBorder = 1;
+ SetWindowLong(ru->hwnd, GWL_EXSTYLE, GetWindowLong(ru->hwnd, GWL_EXSTYLE)^WS_EX_CLIENTEDGE);
+ }
+ // Redraw window since the style may have changed
+ SetWindowPos(ru->hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);
+ RedrawWindow(ru->hwnd, NULL, NULL, RDW_INVALIDATE|RDW_NOCHILDREN|RDW_UPDATENOW|RDW_FRAME);
+}
diff --git a/miranda-wine/plugins/srmm/richutil.h b/miranda-wine/plugins/srmm/richutil.h new file mode 100644 index 0000000..dff6a53 --- /dev/null +++ b/miranda-wine/plugins/srmm/richutil.h @@ -0,0 +1,55 @@ +/*
+SRMM
+
+Copyright 2000-2005 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.
+*/
+#ifndef SRMM_RICHUTIL_H
+#define SRMM_RICHUTIL_H
+
+#define RWinVerMajor() LOBYTE(LOWORD(GetVersion()))
+#define RIsWinVerXPPlus() (RWinVerMajor()>=5 && LOWORD(GetVersion())!=5)
+
+#ifndef WM_THEMECHANGED
+#define WM_THEMECHANGED 0x031A
+#endif
+#ifndef EP_EDITTEXT
+#define EP_EDITTEXT 1
+#endif
+#ifndef ETS_NORMAL
+#define ETS_NORMAL 1
+#endif
+#ifndef ETS_DISABLED
+#define ETS_DISABLED 4
+#endif
+#ifndef ETS_READONLY
+#define ETS_READONLY 6
+#endif
+
+typedef struct {
+ HWND hwnd;
+ RECT rect;
+ int hasUglyBorder;
+ WNDPROC origProc;
+} TRichUtil;
+
+void RichUtil_Load();
+void RichUtil_Unload();
+int RichUtil_SubClass(HWND hwndEdit);
+
+#endif
diff --git a/miranda-wine/plugins/srmm/srmm.c b/miranda-wine/plugins/srmm/srmm.c new file mode 100644 index 0000000..f416ef6 --- /dev/null +++ b/miranda-wine/plugins/srmm/srmm.c @@ -0,0 +1,71 @@ +/*
+SRMM
+
+Copyright 2000-2005 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"
+
+int LoadSendRecvMessageModule(void);
+int SplitmsgShutdown(void);
+
+PLUGINLINK *pluginLink;
+HINSTANCE g_hInst;
+
+PLUGININFO pluginInfo = {
+ sizeof(PLUGININFO),
+#ifdef _UNICODE
+ "Send/Receive Messages (Unicode)",
+#else
+ "Send/Receive Messages",
+#endif
+ PLUGIN_MAKE_VERSION(3, 0, 0, 0),
+ "Send and receive instant messages",
+ "Miranda IM Development Team",
+ "rainwater@miranda-im.org",
+ "Copyright 2000-2006 Miranda IM project",
+ "http://www.miranda-im.org",
+ 0,
+ DEFMOD_SRMESSAGE // replace internal version (if any)
+};
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ g_hInst = hinstDLL;
+ return TRUE;
+}
+
+__declspec(dllexport)
+ PLUGININFO *MirandaPluginInfo(DWORD mirandaVersion)
+{
+ if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 4, 0, 0))
+ return NULL;
+ return &pluginInfo;
+}
+
+int __declspec(dllexport) Load(PLUGINLINK * link)
+{
+ pluginLink = link;
+ return LoadSendRecvMessageModule();
+}
+
+int __declspec(dllexport) Unload(void)
+{
+ return SplitmsgShutdown();
+}
|