From ba2f55ddc45ea29cce65ad1bfcc178da9684141f Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@4f64403b-2f21-0410-a795-97e2b3489a10> Date: Sun, 29 Mar 2009 15:42:01 +0000 Subject: x64 portability Fixed breaking hook chain on clist infotips git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@438 4f64403b-2f21-0410-a795-97e2b3489a10 --- tipper/common.h | 14 +- tipper/message_pump.cpp | 16 +- tipper/message_pump.h | 9 +- tipper/options.cpp | 2420 +++++++++++++++++++++++------------------------ tipper/popwin.cpp | 1810 +++++++++++++++++------------------ tipper/tipper.cpp | 4 +- tipper/tipper.dsp | 4 +- tipper/tipper_8.vcproj | 2 +- tipper/tipper_9.sln | 38 + tipper/tipper_9.vcproj | 448 ++++++++- tipper/translations.cpp | 1276 ++++++++++++------------- 11 files changed, 3268 insertions(+), 2773 deletions(-) create mode 100644 tipper/tipper_9.sln diff --git a/tipper/common.h b/tipper/common.h index 0a442d6..d6986e5 100644 --- a/tipper/common.h +++ b/tipper/common.h @@ -51,7 +51,7 @@ #include #include #include -#include +#include "m_cluiframes.h" #include #include #include @@ -62,19 +62,19 @@ #include -#include +#include "m_updater.h" #include #include -#include +#include "m_variables.h" -#include +#include "m_notify.h" -#include +#include "m_smr.h" -#include +#include "m_metacontacts.h" #include -#include +#include "m_ersatz.h" #include #define MODULE "Tipper" diff --git a/tipper/message_pump.cpp b/tipper/message_pump.cpp index 72e0aa2..ace9229 100644 --- a/tipper/message_pump.cpp +++ b/tipper/message_pump.cpp @@ -111,7 +111,7 @@ void DeinitMessagePump() { UnregisterClass(POP_WIN_CLASS, hInst); } -int ShowTip(WPARAM wParam, LPARAM lParam) { +INT_PTR ShowTip(WPARAM wParam, LPARAM lParam) { CLCINFOTIP *clcit = (CLCINFOTIP *)lParam; if(clcit->isGroup) return 0; // no group tips (since they're pretty useless) if(clcit->isTreeFocused == 0 && options.show_no_focus == false) return 0; @@ -133,7 +133,12 @@ int ShowTip(WPARAM wParam, LPARAM lParam) { return 1; } -int ShowTipW(WPARAM wParam, LPARAM lParam) { +int ShowTipHook(WPARAM wParam, LPARAM lParam) { + ShowTip(wParam, lParam); + return 0; +} + +INT_PTR ShowTipW(WPARAM wParam, LPARAM lParam) { CLCINFOTIP *clcit = (CLCINFOTIP *)lParam; if(clcit->isGroup) return 0; // no group tips (since they're pretty useless) if(clcit->isTreeFocused == 0 && options.show_no_focus == false) return 0; @@ -153,12 +158,17 @@ int ShowTipW(WPARAM wParam, LPARAM lParam) { return 1; } -int HideTip(WPARAM wParam, LPARAM lParam) { +INT_PTR HideTip(WPARAM wParam, LPARAM lParam) { //CLCINFOTIP *clcit = (CLCINFOTIP *)lParam; PostMPMessage(MUM_DELETEPOPUP, 0, 0); return 1; } +int HideTipHook(WPARAM wParam, LPARAM lParam) { + HideTip(wParam, lParam); + return 0; +} + int ProtoAck(WPARAM wParam, LPARAM lParam) { ACKDATA *ack = (ACKDATA *)lParam; char *szMsg = (char *)ack->lParam; diff --git a/tipper/message_pump.h b/tipper/message_pump.h index 4ed5eed..309b5e7 100644 --- a/tipper/message_pump.h +++ b/tipper/message_pump.h @@ -17,9 +17,12 @@ extern BOOL (WINAPI *MyAnimateWindow)(HWND hWnd,DWORD dwTime,DWORD dwFlags); void InitMessagePump(); void DeinitMessagePump(); -int ShowTip(WPARAM wParam, LPARAM lParam); -int ShowTipW(WPARAM wParam, LPARAM lParam); -int HideTip(WPARAM wParam, LPARAM lParam); +INT_PTR ShowTip(WPARAM wParam, LPARAM lParam); +INT_PTR ShowTipW(WPARAM wParam, LPARAM lParam); +INT_PTR HideTip(WPARAM wParam, LPARAM lParam); + +int ShowTipHook(WPARAM wParam, LPARAM lParam); +int HideTipHook(WPARAM wParam, LPARAM lParam); int FramesShowSBTip(WPARAM wParam, LPARAM lParam); int FramesHideSBTip(WPARAM wParam, LPARAM lParam); diff --git a/tipper/options.cpp b/tipper/options.cpp index 79372da..41271e5 100644 --- a/tipper/options.cpp +++ b/tipper/options.cpp @@ -1,1085 +1,1085 @@ -#include "common.h" -#include "options.h" -#include "resource.h" -#include "popwin.h" -#include -#include "str_utils.h" - -#include - -Options options; - -#define WMU_ENABLE_LIST_BUTTONS (WM_USER + 0x030) -#define WMU_ENABLE_MODULE_ENTRY (WM_USER + 0x031) - -void CreateDefaultItems() { - DSListNode *ds_node; - DIListNode *di_node; - - // last message item - di_node = (DIListNode *)malloc(sizeof(DIListNode)); - _tcsncpy(di_node->di.label, _T("Last message: (%sys:last_msg_reltime% ago)"), LABEL_LEN); - _tcsncpy(di_node->di.value, _T("%sys:last_msg%"), VALUE_LEN); - di_node->di.line_above = di_node->di.value_newline = true; - di_node->next = options.di_list; - options.di_list = di_node; - options.di_count++; - - // status message item - di_node = (DIListNode *)malloc(sizeof(DIListNode)); - _tcsncpy(di_node->di.label, _T("Status message:"), LABEL_LEN); - _tcsncpy(di_node->di.value, _T("%sys:status_msg%"), VALUE_LEN); - di_node->di.line_above = di_node->di.value_newline = true; - di_node->next = options.di_list; - options.di_list = di_node; - options.di_count++; - - // status substitution - ds_node = (DSListNode *)malloc(sizeof(DSListNode)); - _tcsncpy(ds_node->ds.name, _T("status"), LABEL_LEN); - ds_node->ds.type = DVT_PROTODB; - strncpy(ds_node->ds.setting_name, "Status", SETTING_NAME_LEN); - ds_node->ds.translate_func_id = 1; - ds_node->next = options.ds_list; - options.ds_list = ds_node; - options.ds_count++; - - // status item - di_node = (DIListNode *)malloc(sizeof(DIListNode)); - _tcsncpy(di_node->di.label, _T("Status:"), LABEL_LEN); - _tcsncpy(di_node->di.value, _T("%status%"), VALUE_LEN); - di_node->di.line_above = di_node->di.value_newline = false; - di_node->next = options.di_list; - options.di_list = di_node; - options.di_count++; - - // client substitution - ds_node = (DSListNode *)malloc(sizeof(DSListNode)); - _tcsncpy(ds_node->ds.name, _T("client"), LABEL_LEN); - ds_node->ds.type = DVT_PROTODB; - strncpy(ds_node->ds.setting_name, "MirVer", SETTING_NAME_LEN); - ds_node->ds.translate_func_id = 0; - ds_node->next = options.ds_list; - options.ds_list = ds_node; - options.ds_count++; - - // client item - di_node = (DIListNode *)malloc(sizeof(DIListNode)); - _tcsncpy(di_node->di.label, _T("Client:"), LABEL_LEN); - _tcsncpy(di_node->di.value, _T("%client%"), VALUE_LEN); - di_node->di.line_above = di_node->di.value_newline = false; - di_node->next = options.di_list; - options.di_list = di_node; - options.di_count++; - - // idle time substitution (long date) - ds_node = (DSListNode *)malloc(sizeof(DSListNode)); - _tcsncpy(ds_node->ds.name, _T("idle"), LABEL_LEN); - ds_node->ds.type = DVT_PROTODB; - strncpy(ds_node->ds.setting_name, "IdleTS", SETTING_NAME_LEN); - ds_node->ds.translate_func_id = 15; - ds_node->next = options.ds_list; - options.ds_list = ds_node; - options.ds_count++; - - // idle time substitution (time difference) - ds_node = (DSListNode *)malloc(sizeof(DSListNode)); - _tcsncpy(ds_node->ds.name, _T("idle_diff"), LABEL_LEN); - ds_node->ds.type = DVT_PROTODB; - strncpy(ds_node->ds.setting_name, "IdleTS", SETTING_NAME_LEN); - ds_node->ds.translate_func_id = 3; - ds_node->next = options.ds_list; - options.ds_list = ds_node; - options.ds_count++; - - - // idle item - di_node = (DIListNode *)malloc(sizeof(DIListNode)); - _tcsncpy(di_node->di.label, _T("Idle:"), LABEL_LEN); - _tcsncpy(di_node->di.value, _T("%idle% (%idle_diff% ago)"), VALUE_LEN); - di_node->di.line_above = di_node->di.value_newline = false; - di_node->next = options.di_list; - options.di_list = di_node; - options.di_count++; - - // first name substitution - ds_node = (DSListNode *)malloc(sizeof(DSListNode)); - _tcsncpy(ds_node->ds.name, _T("first_name"), LABEL_LEN); - ds_node->ds.type = DVT_PROTODB; - strncpy(ds_node->ds.setting_name, "FirstName", SETTING_NAME_LEN); - ds_node->ds.translate_func_id = 0; - ds_node->next = options.ds_list; - options.ds_list = ds_node; - options.ds_count++; - - // last name substitution - ds_node = (DSListNode *)malloc(sizeof(DSListNode)); - _tcsncpy(ds_node->ds.name, _T("last_name"), LABEL_LEN); - ds_node->ds.type = DVT_PROTODB; - strncpy(ds_node->ds.setting_name, "LastName", SETTING_NAME_LEN); - ds_node->ds.translate_func_id = 0; - ds_node->next = options.ds_list; - options.ds_list = ds_node; - options.ds_count++; - - // name item - di_node = (DIListNode *)malloc(sizeof(DIListNode)); - _tcsncpy(di_node->di.label, _T("Name:"), LABEL_LEN); - _tcsncpy(di_node->di.value, _T("%first_name% %last_name%"), VALUE_LEN); - di_node->di.line_above = di_node->di.value_newline = false; - di_node->next = options.di_list; - options.di_list = di_node; - options.di_count++; - -} - -bool LoadDS(DisplaySubst *ds, int index) { - char setting[512]; - DBVARIANT dbv; - mir_snprintf(setting, 512, "Name%d", index); - ds->name[0] = 0; - if(!DBGetContactSettingWString(0, MODULE, setting, &dbv)) { - w2t(dbv.pwszVal, ds->name, LABEL_LEN); - DBFreeVariant(&dbv); - } else if(!DBGetContactSettingStringUtf(0, MODULE, setting, &dbv)) { - u2t(dbv.pszVal, ds->name, LABEL_LEN); - DBFreeVariant(&dbv); - } else if(!DBGetContactSetting(0, MODULE, setting, &dbv)) { - if(dbv.type == DBVT_ASCIIZ) a2t(dbv.pszVal, ds->name, LABEL_LEN); - DBFreeVariant(&dbv); - } else - return false; - ds->name[LABEL_LEN - 1] = 0; - - mir_snprintf(setting, 512, "Type%d", index); - ds->type = (DisplaySubstType)DBGetContactSettingByte(0, MODULE, setting, DVT_PROTODB); - - mir_snprintf(setting, 512, "Module%d", index); - ds->module_name[0] = 0; - if(!DBGetContactSettingString(0, MODULE, setting, &dbv)) { - strncpy(ds->module_name, dbv.pszVal, MODULE_NAME_LEN); - ds->module_name[MODULE_NAME_LEN - 1] = 0; - DBFreeVariant(&dbv); - } - - mir_snprintf(setting, 512, "Setting%d", index); - ds->setting_name[0] = 0; - if(!DBGetContactSettingString(0, MODULE, setting, &dbv)) { - strncpy(ds->setting_name, dbv.pszVal, SETTING_NAME_LEN); - ds->setting_name[SETTING_NAME_LEN - 1] = 0; - DBFreeVariant(&dbv); - } - - mir_snprintf(setting, 512, "TransFuncId%d", index); - ds->translate_func_id = DBGetContactSettingDword(0, MODULE, setting, (DWORD)-1); - - // a little backward compatibility - if((DWORD)ds->translate_func_id == (DWORD)-1) { - mir_snprintf(setting, 512, "TransFunc%d", index); - ds->translate_func_id = (DWORD)DBGetContactSettingWord(0, MODULE, setting, 0); - } - return true; -} - -void SaveDS(DisplaySubst *ds, int index) { - char setting[512]; - mir_snprintf(setting, 512, "Name%d", index); - if(DBWriteContactSettingTString(0, MODULE, setting, ds->name)) { - char buff[LABEL_LEN]; - t2a(ds->name, buff, LABEL_LEN); - DBWriteContactSettingString(0, MODULE, setting, buff); - } - mir_snprintf(setting, 512, "Type%d", index); - DBWriteContactSettingByte(0, MODULE, setting, (BYTE)ds->type); - mir_snprintf(setting, 512, "Module%d", index); - DBWriteContactSettingString(0, MODULE, setting, ds->module_name); - mir_snprintf(setting, 512, "Setting%d", index); - DBWriteContactSettingString(0, MODULE, setting, ds->setting_name); - mir_snprintf(setting, 512, "TransFuncId%d", index); - DBWriteContactSettingDword(0, MODULE, setting, (WORD)ds->translate_func_id); -} - -bool LoadDI(DisplayItem *di, int index) { - char setting[512]; - DBVARIANT dbv; - mir_snprintf(setting, 512, "DILabel%d", index); - di->label[0] = 0; - if(!DBGetContactSettingWString(0, MODULE, setting, &dbv)) { - w2t(dbv.pwszVal, di->label, LABEL_LEN); - DBFreeVariant(&dbv); - } else if(!DBGetContactSettingStringUtf(0, MODULE, setting, &dbv)) { - u2t(dbv.pszVal, di->label, LABEL_LEN); - DBFreeVariant(&dbv); - } else if(!DBGetContactSetting(0, MODULE, setting, &dbv)) { - if(dbv.type == DBVT_ASCIIZ) a2t(dbv.pszVal, di->label, LABEL_LEN); - DBFreeVariant(&dbv); - } else - return false; - di->label[LABEL_LEN - 1] = 0; - - mir_snprintf(setting, 512, "DIValue%d", index); - di->value[0] = 0; - if(!DBGetContactSettingWString(0, MODULE, setting, &dbv)) { - w2t(dbv.pwszVal, di->value, VALUE_LEN); - DBFreeVariant(&dbv); - } else if(!DBGetContactSettingStringUtf(0, MODULE, setting, &dbv)) { - u2t(dbv.pszVal, di->value, VALUE_LEN); - DBFreeVariant(&dbv); - } else if(!DBGetContactSetting(0, MODULE, setting, &dbv)) { - if(dbv.type == DBVT_ASCIIZ) a2t(dbv.pszVal, di->value, VALUE_LEN); - DBFreeVariant(&dbv); - } - - di->value[VALUE_LEN - 1] = 0; - - mir_snprintf(setting, 512, "DILineAbove%d", index); - di->line_above = (DBGetContactSettingByte(0, MODULE, setting, 0) == 1); - mir_snprintf(setting, 512, "DIValNewline%d", index); - di->value_newline = (DBGetContactSettingByte(0, MODULE, setting, 0) == 1); - - return true; -} - -void SaveDI(DisplayItem *di, int index) { - char setting[512]; - mir_snprintf(setting, 512, "DILabel%d", index); - if(DBWriteContactSettingTString(0, MODULE, setting, di->label)) { - char buff[LABEL_LEN]; - t2a(di->label, buff, LABEL_LEN); - DBWriteContactSettingString(0, MODULE, setting, buff); - } - mir_snprintf(setting, 512, "DIValue%d", index); - if(DBWriteContactSettingTString(0, MODULE, setting, di->value)) { - char buff[VALUE_LEN]; - t2a(di->value, buff, VALUE_LEN); - DBWriteContactSettingString(0, MODULE, setting, buff); - } - mir_snprintf(setting, 512, "DILineAbove%d", index); - DBWriteContactSettingByte(0, MODULE, setting, di->line_above ? 1 : 0); - mir_snprintf(setting, 512, "DIValNewline%d", index); - DBWriteContactSettingByte(0, MODULE, setting, di->value_newline ? 1 : 0); -} - -void SaveOptions() { - DBWriteContactSettingDword(0, MODULE, "MaxWidth", options.win_width); - DBWriteContactSettingDword(0, MODULE, "MaxHeight", options.win_max_height); - DBWriteContactSettingByte(0, MODULE, "Opacity", (BYTE)options.opacity); - DBWriteContactSettingByte(0, MODULE, "Border", (options.border ? 1 : 0)); - DBWriteContactSettingByte(0, MODULE, "DropShadow", (options.drop_shadow ? 1 : 0)); - DBWriteContactSettingByte(0, MODULE, "RoundCorners", (options.round ? 1 : 0)); - DBWriteContactSettingByte(0, MODULE, "AvatarRoundCorners", (options.av_round ? 1 : 0)); - DBWriteContactSettingByte(0, MODULE, "Animate", (options.animate ? 1 : 0)); - DBWriteContactSettingByte(0, MODULE, "TransparentBg", (options.trans_bg ? 1 : 0)); - DBWriteContactSettingByte(0, MODULE, "TitleLayout", (BYTE)options.title_layout); - if(ServiceExists(MS_AV_DRAWAVATAR)) - DBWriteContactSettingByte(0, MODULE, "AVLayout", (BYTE)options.av_layout); - DBWriteContactSettingDword(0, MODULE, "AVSize", options.av_size); - DBWriteContactSettingDword(0, MODULE, "TextIndent", options.text_indent); - DBWriteContactSettingByte(0, MODULE, "ShowNoFocus", (options.show_no_focus ? 1 : 0)); - - int index = 0; - DSListNode *ds_node = options.ds_list; - while(ds_node) { - SaveDS(&ds_node->ds, index); - ds_node = ds_node->next; - index++; - } - DBWriteContactSettingWord(0, MODULE, "DSNumValues", index); - - index = 0; - DIListNode *di_node = options.di_list; - while(di_node) { - SaveDI(&di_node->di, index); - di_node = di_node->next; - index++; - } - DBWriteContactSettingWord(0, MODULE, "DINumValues", index); - - DBWriteContactSettingWord(0, MODULE, "TimeIn", options.time_in); - CallService(MS_CLC_SETINFOTIPHOVERTIME, options.time_in, 0); - - DBWriteContactSettingWord(0, MODULE, "Padding", options.padding); - DBWriteContactSettingWord(0, MODULE, "AvatarPadding", options.av_padding); - DBWriteContactSettingWord(0, MODULE, "TextPadding", options.text_padding); - DBWriteContactSettingByte(0, MODULE, "Position", (BYTE)options.pos); - DBWriteContactSettingDword(0, MODULE, "MinWidth", (DWORD)options.min_width); - DBWriteContactSettingDword(0, MODULE, "MinHeight", (DWORD)options.min_height); - DBWriteContactSettingDword(0, MODULE, "SidebarWidth", (DWORD)options.sidebar_width); - DBWriteContactSettingByte(0, MODULE, "MouseTollerance", (BYTE)options.mouse_tollerance); - DBWriteContactSettingByte(0, MODULE, "SBarTips", (options.status_bar_tips ? 1 : 0)); - - DBWriteContactSettingWord(0, MODULE, "LabelVAlign", options.label_valign); - DBWriteContactSettingWord(0, MODULE, "LabelHAlign", options.label_halign); - DBWriteContactSettingWord(0, MODULE, "ValueVAlign", options.value_valign); - DBWriteContactSettingWord(0, MODULE, "ValueHAlign", options.value_halign); - - DBWriteContactSettingByte(0, MODULE, "NoAvatarResize", options.no_resize_av ? 1 : 0); - DBWriteContactSettingTString(0, MODULE, "BackgroundFilename", options.bg_fn); - DBWriteContactSettingByte(0, MODULE, "StretchBgImg", options.stretch_bg_img ? 1 : 0); -} - -void LoadOptions() { - options.win_width = DBGetContactSettingDword(0, MODULE, "MaxWidth", 420); - options.win_max_height = DBGetContactSettingDword(0, MODULE, "MaxHeight", 400); - options.opacity = DBGetContactSettingByte(0, MODULE, "Opacity", 75); - options.border = (DBGetContactSettingByte(0, MODULE, "Border", 1) == 1); - options.drop_shadow = (DBGetContactSettingByte(0, MODULE, "DropShadow", 1) == 1); - options.round = (DBGetContactSettingByte(0, MODULE, "RoundCorners", 1) == 1); - options.av_round = (DBGetContactSettingByte(0, MODULE, "AvatarRoundCorners", options.round ? 1 : 0) == 1); - options.animate = (DBGetContactSettingByte(0, MODULE, "Animate", 0) == 1); - options.trans_bg = (DBGetContactSettingByte(0, MODULE, "TransparentBg", 0) == 1); - options.title_layout = (PopupTitleLayout)DBGetContactSettingByte(0, MODULE, "TitleLayout", (BYTE)PTL_LEFTICON); - if(ServiceExists(MS_AV_DRAWAVATAR)) - options.av_layout = (PopupAvLayout)DBGetContactSettingByte(0, MODULE, "AVLayout", PAV_RIGHT); - else - options.av_layout = PAV_NONE; - options.av_size = DBGetContactSettingDword(0, MODULE, "AVSize", 60); //tweety - options.text_indent = DBGetContactSettingDword(0, MODULE, "TextIndent", 22); - options.sidebar_width = DBGetContactSettingDword(0, MODULE, "SidebarWidth", 22); - options.show_no_focus = (DBGetContactSettingByte(0, MODULE, "ShowNoFocus", 1) == 1); - - int i, real_count = 0; - options.ds_list = 0; - DSListNode *ds_node; - options.ds_count = DBGetContactSettingWord(0, MODULE, "DSNumValues", 0); - for(i = options.ds_count - 1; i >= 0; i--) { - ds_node = (DSListNode *)malloc(sizeof(DSListNode)); - if(LoadDS(&ds_node->ds, i)) { - ds_node->next = options.ds_list; - options.ds_list = ds_node; - real_count++; - } else free(ds_node); - } - options.ds_count = real_count; - - real_count = 0; - options.di_list = 0; - DIListNode *di_node; - options.di_count = DBGetContactSettingWord(0, MODULE, "DINumValues", 0); - for(i = options.di_count - 1; i >= 0; i--) { - di_node = (DIListNode *)malloc(sizeof(DIListNode)); - if(LoadDI(&di_node->di, i)) { - di_node->next = options.di_list; - options.di_list = di_node; - real_count++; - } else free(di_node); - } - options.di_count = real_count; - - options.time_in = DBGetContactSettingWord(0, MODULE, "TimeIn", 750); - options.padding = DBGetContactSettingWord(0, MODULE, "Padding", 4); - options.av_padding = DBGetContactSettingWord(0, MODULE, "AvatarPadding", 6); - options.text_padding = DBGetContactSettingWord(0, MODULE, "TextPadding", 4); - options.pos = (PopupPosition)DBGetContactSettingByte(0, MODULE, "Position", (BYTE)PP_BOTTOMRIGHT); - options.min_width = DBGetContactSettingDword(0, MODULE, "MinWidth", 0); - options.min_height = DBGetContactSettingDword(0, MODULE, "MinHeight", 0); - - options.mouse_tollerance = DBGetContactSettingByte(0, MODULE, "MouseTollerance", (BYTE)GetSystemMetrics(SM_CXSMICON)); - options.status_bar_tips = (DBGetContactSettingByte(0, MODULE, "SBarTips", 1) == 1); - - // convert defunct last message and status message options to new 'sys' items, and remove the old settings - if(DBGetContactSettingByte(0, MODULE, "ShowLastMessage", 0)) { - DBDeleteContactSetting(0, MODULE, "ShowLastMessage"); - - // find end of list - di_node = options.di_list; - while(di_node && di_node->next) di_node = di_node->next; - - // last message item - if(di_node) { - di_node->next = (DIListNode *)malloc(sizeof(DIListNode)); - di_node = di_node->next; - } else { - options.di_list = (DIListNode *)malloc(sizeof(DIListNode)); - di_node = options.di_list; - } - - _tcsncpy(di_node->di.label, _T("Last message: (%sys:last_msg_reltime% ago)"), LABEL_LEN); - _tcsncpy(di_node->di.value, _T("%sys:last_msg%"), VALUE_LEN); - di_node->di.line_above = di_node->di.value_newline = true; - di_node->next = 0; - options.di_count++; - } - - if(DBGetContactSettingByte(0, MODULE, "ShowStatusMessage", 0)) { - DBDeleteContactSetting(0, MODULE, "ShowStatusMessage"); - - // find end of list - di_node = options.di_list; - while(di_node && di_node->next) di_node = di_node->next; - - // status message item - if(di_node) { - di_node->next = (DIListNode *)malloc(sizeof(DIListNode)); - di_node = di_node->next; - } else { - options.di_list = (DIListNode *)malloc(sizeof(DIListNode)); - di_node = options.di_list; - } - - _tcsncpy(di_node->di.label, _T("Status message:"), LABEL_LEN); - _tcsncpy(di_node->di.value, _T("%sys:status_msg%"), VALUE_LEN); - di_node->di.line_above = di_node->di.value_newline = true; - di_node->next = 0; - options.di_count++; - } - - options.label_valign = DBGetContactSettingWord(0, MODULE, "LabelVAlign", DT_TOP /*DT_VCENTER*/); - options.label_halign = DBGetContactSettingWord(0, MODULE, "LabelHAlign", DT_LEFT); - options.value_valign = DBGetContactSettingWord(0, MODULE, "ValueVAlign", DT_TOP /*DT_VCENTER*/); - options.value_halign = DBGetContactSettingWord(0, MODULE, "ValueHAlign", DT_LEFT); - - if(options.ds_count == 0 && options.di_count == 0 && DBGetContactSettingByte(0, MODULE, "DefaultsCreated", 0) == 0) { - // set up some reasonable defaults - but only 'once' - CreateDefaultItems(); - DBWriteContactSettingByte(0, MODULE, "DefaultsCreated", 1); - SaveOptions(); - } - - options.no_resize_av = (DBGetContactSettingByte(0, MODULE, "NoAvatarResize", 0) == 1); - DBVARIANT dbv; - if(!DBGetContactSettingTString(0, MODULE, "BackgroundFilename", &dbv)) { - _tcsncpy(options.bg_fn, dbv.ptszVal, MAX_PATH); - DBFreeVariant(&dbv); - } else - options.bg_fn[0] = 0; - options.stretch_bg_img = (DBGetContactSettingByte(0, MODULE, "StretchBgImg", 0) == 1); -} - -static BOOL CALLBACK DlgProcAddItem(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - DisplayItem *di = (DisplayItem *)GetWindowLong(hwndDlg, GWL_USERDATA); - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - di = (DisplayItem *)lParam; - SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)di); - - SetDlgItemText(hwndDlg, IDC_ED_LABEL, di->label); - SetDlgItemText(hwndDlg, IDC_ED_VALUE, di->value); - - CheckDlgButton(hwndDlg, IDC_CHK_LINEABOVE, di->line_above ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_VALNEWLINE, di->value_newline ? TRUE : FALSE); - SetFocus(GetDlgItem(hwndDlg, IDC_ED_LABEL)); - return TRUE; - case WM_COMMAND: - if(HIWORD(wParam) == BN_CLICKED) { - switch(LOWORD(wParam)) { - case IDOK: - GetDlgItemText(hwndDlg, IDC_ED_LABEL, di->label, LABEL_LEN); - GetDlgItemText(hwndDlg, IDC_ED_VALUE, di->value, VALUE_LEN); - - di->line_above = (IsDlgButtonChecked(hwndDlg, IDC_CHK_LINEABOVE) ? true : false); - di->value_newline = (IsDlgButtonChecked(hwndDlg, IDC_CHK_VALNEWLINE) ? true : false); - - EndDialog(hwndDlg, IDOK); - return TRUE; - case IDCANCEL: - EndDialog(hwndDlg, IDCANCEL); - return TRUE; - } - } - break; - } - - return 0; -} - -static BOOL CALLBACK DlgProcAddSubst(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - DisplaySubst *ds = (DisplaySubst *)GetWindowLong(hwndDlg, GWL_USERDATA); - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - ds = (DisplaySubst *)lParam; - SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)ds); - - SetDlgItemText(hwndDlg, IDC_ED_LABEL, ds->name); - - switch(ds->type) { - case DVT_PROTODB: - CheckDlgButton(hwndDlg, IDC_CHK_PROTOMOD, TRUE); - SetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name); - break; - case DVT_DB: - SetDlgItemTextA(hwndDlg, IDC_ED_MODULE, ds->module_name); - SetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name); - break; - } - - { - int index, id, i; - for(i = 0; i < num_tfuncs; i++) { - index = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_ADDSTRING, (WPARAM)-1, (LPARAM)TranslateTS(translations[i].name)); - SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_SETITEMDATA, index, (LPARAM)translations[i].id); - } - for(i = 0; i < num_tfuncs; i++) { - id = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETITEMDATA, i, 0); - if(id == ds->translate_func_id) - SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_SETCURSEL, i, 0); - } - } - - SendMessage(hwndDlg, WMU_ENABLE_MODULE_ENTRY, 0, 0); - SetFocus(GetDlgItem(hwndDlg, IDC_ED_LABEL)); - return TRUE; - case WMU_ENABLE_MODULE_ENTRY: - { - HWND hw = GetDlgItem(hwndDlg, IDC_CHK_PROTOMOD); - EnableWindow(hw, TRUE); - hw = GetDlgItem(hwndDlg, IDC_ED_MODULE); - EnableWindow(hw, !IsDlgButtonChecked(hwndDlg, IDC_CHK_PROTOMOD)); - hw = GetDlgItem(hwndDlg, IDC_ED_SETTING); - EnableWindow(hw, TRUE); - } - return TRUE; - case WM_COMMAND: - if ( HIWORD( wParam ) == CBN_SELCHANGE) { - return TRUE; - } else if(HIWORD(wParam) == BN_CLICKED) { - switch(LOWORD(wParam)) { - case IDC_CHK_PROTOMOD: - SendMessage(hwndDlg, WMU_ENABLE_MODULE_ENTRY, 0, 0); - break; - case IDOK: - GetDlgItemText(hwndDlg, IDC_ED_LABEL, ds->name, LABEL_LEN); - if(ds->name[0] == 0) { - MessageBox(hwndDlg, TranslateT("You must enter a label"), TranslateT("Invalid Substitution"), MB_OK | MB_ICONWARNING); - return TRUE; - } - - if(IsDlgButtonChecked(hwndDlg, IDC_CHK_PROTOMOD)) - ds->type = DVT_PROTODB; - else { - ds->type = DVT_DB; - GetDlgItemTextA(hwndDlg, IDC_ED_MODULE, ds->module_name, MODULE_NAME_LEN); - } - GetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name, SETTING_NAME_LEN); - - { - int sel = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETCURSEL, 0, 0); - ds->translate_func_id = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETITEMDATA, sel, 0); - } - - EndDialog(hwndDlg, IDOK); - return TRUE; - case IDCANCEL: - EndDialog(hwndDlg, IDCANCEL); - return TRUE; - } - } - break; - } - - return 0; -} - -static BOOL CALLBACK DlgProcOptContent(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - { - int index; - DIListNode *di_node = options.di_list, *di_value; - while(di_node) { - di_value = (DIListNode *)malloc(sizeof(DIListNode)); - *di_value = *di_node; - if(di_value->di.label[0] == 0) - index = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_ADDSTRING, 0, (LPARAM)TranslateT("")); - else - index = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_ADDSTRING, 0, (LPARAM)di_value->di.label); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, index, (LPARAM)di_value); - - di_node = di_node->next; - } - - DSListNode *ds_node = options.ds_list, *ds_value; - while(ds_node) { - ds_value = (DSListNode *)malloc(sizeof(DSListNode)); - *ds_value = *ds_node; - index = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)ds_value->ds.name); - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, index, (LPARAM)ds_value); - - ds_node = ds_node->next; - } - } - - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - return FALSE; - case WMU_ENABLE_LIST_BUTTONS: - { - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); - if(sel == -1) { - HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE); - EnableWindow(hw, FALSE); - hw = GetDlgItem(hwndDlg, IDC_BTN_UP); - EnableWindow(hw, FALSE); - hw = GetDlgItem(hwndDlg, IDC_BTN_DOWN); - EnableWindow(hw, FALSE); - hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT); - EnableWindow(hw, FALSE); - } else { - int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0); - HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE); - EnableWindow(hw, TRUE); - hw = GetDlgItem(hwndDlg, IDC_BTN_UP); - EnableWindow(hw, sel > 0); - hw = GetDlgItem(hwndDlg, IDC_BTN_DOWN); - EnableWindow(hw, sel < count - 1); - hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT); - EnableWindow(hw, TRUE); - } - - sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0); - if(sel == -1) { - HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE2); - EnableWindow(hw, FALSE); - hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT2); - EnableWindow(hw, FALSE); - } else { - HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE2); - EnableWindow(hw, TRUE); - hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT2); - EnableWindow(hw, TRUE); - } - } - return TRUE; - case WM_COMMAND: - if ( HIWORD( wParam ) == LBN_SELCHANGE && LOWORD(wParam) == IDC_LST_ITEMS) { - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - } else if ( HIWORD( wParam ) == LBN_SELCHANGE && LOWORD(wParam) == IDC_LST_SUBST) { - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - } else if ( HIWORD( wParam ) == CBN_SELCHANGE) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } else if ( HIWORD( wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_LST_ITEMS) { - { - DIListNode *value; - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); - if(sel != -1) { - value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0); - if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) { - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0); - - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value->di.label); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value); - - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel, 0); - - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - } - } else if ( HIWORD( wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_LST_SUBST) { - { - DSListNode *value; - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0); - if(sel != -1) { - value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0); - if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) { - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0); - - sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name); - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, sel, (LPARAM)value); - - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, sel, 0); - - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - } - } else if ( HIWORD( wParam ) == BN_CLICKED ) { - switch(LOWORD(wParam)) { - case IDC_BTN_ADD: - { - DIListNode *value = (DIListNode *)malloc(sizeof(DIListNode)); - memset(value, 0, sizeof(DIListNode)); - if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) { - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0), index = sel + 1; - if(value->di.label[0] == 0) - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, index, (LPARAM)TranslateT("")); - else - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, index, (LPARAM)value->di.label); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, index, (LPARAM)value); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, index, 0); - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - - } - return TRUE; - case IDC_BTN_REMOVE: - { - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); - if(sel != -1) { - DIListNode *value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0); - free(value); - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - return TRUE; - case IDC_BTN_UP: - { - DIListNode *value_up; - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); - if(sel > 0) { - value_up = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel - 1, 0); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel - 1, 0); - - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value_up->di.label); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value_up); - - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel - 1, 0); - } - } - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_BTN_DOWN: - { - DIListNode *value_down; - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); - int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0); - if(sel < count - 1) { - value_down = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel + 1, 0); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel + 1, 0); - - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value_down->di.label); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value_down); - - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel + 1, 0); - } - } - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_BTN_EDIT: - { - DIListNode *value; - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); - if(sel != -1) { - value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0); - if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) { - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0); - - if(value->di.label[0] == 0) - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)TranslateT("")); - else - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value->di.label); - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value); - - SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel, 0); - - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - } - return TRUE; - - case IDC_BTN_ADD2: - { - DSListNode *value = (DSListNode *)malloc(sizeof(DSListNode)); - memset(value, 0, sizeof(DSListNode)); - if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) { - int index = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name); - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, index, (LPARAM)value); - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, index, 0); - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - - } - return TRUE; - case IDC_BTN_REMOVE2: - { - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0); - if(sel != -1) { - DSListNode *value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0); - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0); - free(value); - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - return TRUE; - case IDC_BTN_EDIT2: - { - DSListNode *value; - int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0); - if(sel != -1) { - value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0); - if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) { - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0); - - sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name); - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, sel, (LPARAM)value); - - SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, sel, 0); - - SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - } - return TRUE; - default: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - } - } - break; - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) { - DIListNode *di_node; - int i; - while(options.di_list) { - di_node = options.di_list; - options.di_list = options.di_list->next; - free(di_node); - } - - DIListNode *di_value; - options.di_count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0); - for(i = options.di_count - 1; i >= 0; i--) { - di_node = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, i, 0); - di_value = (DIListNode *)malloc(sizeof(DIListNode)); - *di_value = *di_node; - - di_value->next = options.di_list; - options.di_list = di_value; - } - - DSListNode *ds_node; - while(options.ds_list) { - ds_node = options.ds_list; - options.ds_list = options.ds_list->next; - free(ds_node); - } - - DSListNode *ds_value; - options.ds_count = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCOUNT, 0, 0); - for(i = options.ds_count - 1; i >= 0; i--) { - ds_node = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, i, 0); - ds_value = (DSListNode *)malloc(sizeof(DSListNode)); - *ds_value = *ds_node; - - ds_value->next = options.ds_list; - options.ds_list = ds_value; - } - - SaveOptions(); - return TRUE; - } - break; - case WM_DESTROY: - { - DIListNode *di_value; - int i; - int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0); - for(i = 0; i < count; i++) { - di_value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, i, 0); - free(di_value); - } - DSListNode *ds_value; - count = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCOUNT, 0, 0); - for(i = 0; i < count; i++) { - ds_value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, i, 0); - free(ds_value); - } - } - break; - } - - return 0; -} - -static BOOL CALLBACK DlgProcOptWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - SendDlgItemMessage(hwndDlg, IDC_SPIN_WIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_MINWIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_MAXHEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_MINHEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16)); - SetDlgItemInt(hwndDlg, IDC_ED_WIDTH, options.win_width, FALSE); - SetDlgItemInt(hwndDlg, IDC_ED_MAXHEIGHT, options.win_max_height, FALSE); - SetDlgItemInt(hwndDlg, IDC_ED_MINWIDTH, options.min_width, FALSE); - SetDlgItemInt(hwndDlg, IDC_ED_MINHEIGHT, options.min_height, FALSE); - - SetDlgItemInt(hwndDlg, IDC_ED_TRANS, options.opacity, FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_TRANSBG, options.trans_bg); - - CheckDlgButton(hwndDlg, IDC_CHK_NOFOCUS, options.show_no_focus ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_SBAR, options.status_bar_tips ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_CHK_BORDER, options.border); - CheckDlgButton(hwndDlg, IDC_CHK_ROUNDCORNERS, options.round); - CheckDlgButton(hwndDlg, IDC_CHK_ROUNDCORNERSAV, options.av_round); - - CheckDlgButton(hwndDlg, IDC_CHK_ANIMATE, options.animate); - CheckDlgButton(hwndDlg, IDC_CHK_SHADOW, options.drop_shadow); - - SendDlgItemMessage(hwndDlg, IDC_SPIN_HOVER, UDM_SETRANGE, 0, (LPARAM)MAKELONG(5000, 5)); - SetDlgItemInt(hwndDlg, IDC_ED_HOVER, options.time_in, FALSE); - break; - case WM_COMMAND: - if ( HIWORD( wParam ) == CBN_SELCHANGE) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } else if ( HIWORD( wParam ) == BN_CLICKED ) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - break; - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) { - BOOL trans; - int new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_WIDTH, &trans, FALSE); - if(trans) options.win_width = new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_MINWIDTH, &trans, FALSE); - if(trans) options.min_width = new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_MAXHEIGHT, &trans, FALSE); - if(trans) options.win_max_height = new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_MINHEIGHT, &trans, FALSE); - if(trans) options.min_height = new_val; - - new_val = GetDlgItemInt(hwndDlg, IDC_ED_TRANS, &trans, FALSE); - if(trans) options.opacity = new_val; - options.trans_bg = IsDlgButtonChecked(hwndDlg, IDC_CHK_TRANSBG) ? true : false; - - new_val = GetDlgItemInt(hwndDlg, IDC_ED_HOVER, &trans, FALSE); - if(trans) options.time_in = new_val; - - options.border = IsDlgButtonChecked(hwndDlg, IDC_CHK_BORDER) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_BORDER)) ? true : false; - options.round = IsDlgButtonChecked(hwndDlg, IDC_CHK_ROUNDCORNERS) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_ROUNDCORNERS)) ? true : false; - options.av_round = IsDlgButtonChecked(hwndDlg, IDC_CHK_ROUNDCORNERSAV) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_ROUNDCORNERSAV)) ? true : false; - options.animate = IsDlgButtonChecked(hwndDlg, IDC_CHK_ANIMATE) ? true : false; - options.drop_shadow = IsDlgButtonChecked(hwndDlg, IDC_CHK_SHADOW) ? true : false; - - options.show_no_focus = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOFOCUS) ? true : false; - options.status_bar_tips = IsDlgButtonChecked(hwndDlg, IDC_CHK_SBAR) ? true : false; - - SaveOptions(); - return TRUE; - } - break; - } - return 0; -} - -static BOOL CALLBACK DlgProcOptLayout(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - - SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("Icon on left")); - SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("Icon on right")); - SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("No icon")); - SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("No title")); - SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_SETCURSEL, (int)options.title_layout, 0); - - SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom right")); - SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom left")); - SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top right")); - SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top left")); - SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_SETCURSEL, (int)options.pos, 0); - - SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top")); - SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Centre")); - SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom")); - switch(options.label_valign) { - case DT_TOP: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 0, 0); break; - case DT_VCENTER: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 1, 0); break; - case DT_BOTTOM: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 2, 0); break; - } - - SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top")); - SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Centre")); - SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom")); - switch(options.value_valign) { - case DT_TOP: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 0, 0); break; - case DT_VCENTER: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 1, 0); break; - case DT_BOTTOM: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 2, 0); break; - } - - SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left")); - SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right")); - switch(options.label_halign) { - case DT_LEFT: SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_SETCURSEL, 0, 0); break; - case DT_RIGHT: SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_SETCURSEL, 1, 0); break; - } - - SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left")); - SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right")); - switch(options.value_halign) { - case DT_LEFT: SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_SETCURSEL, 0, 0); break; - case DT_RIGHT: SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_SETCURSEL, 1, 0); break; - } - - SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("No avatar")); - if(ServiceExists(MS_AV_DRAWAVATAR)) { - SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left avatar")); - SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right avatar")); - } else { - HWND hw = GetDlgItem(hwndDlg, IDC_CMB_AV); - EnableWindow(hw, FALSE); - hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE); - EnableWindow(hw, FALSE); - hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE); - EnableWindow(hw, FALSE); - } - SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_SETCURSEL, (int)options.av_layout, 0); - - SendDlgItemMessage(hwndDlg, IDC_SPIN_TRANS, UDM_SETRANGE, 0, (LPARAM)MAKELONG(99, 0)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_AVSIZE, UDM_SETRANGE, 0, (LPARAM)MAKELONG(100, 16)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_INDENT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(400, 0)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_PADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_TEXTPADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_AVPADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0)); - SendDlgItemMessage(hwndDlg, IDC_SPIN_SBWIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 0)); - - CheckDlgButton(hwndDlg, IDC_CHK_NORESIZEAV, options.no_resize_av); - if(options.no_resize_av) { - HWND hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE); - EnableWindow(hw, FALSE); - hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE); - EnableWindow(hw, FALSE); - } - SetDlgItemInt(hwndDlg, IDC_ED_AVSIZE, options.av_size, FALSE); - SetDlgItemInt(hwndDlg, IDC_ED_INDENT, options.text_indent, FALSE); - SetDlgItemInt(hwndDlg, IDC_ED_PADDING, options.padding, FALSE); - SetDlgItemInt(hwndDlg, IDC_ED_TEXTPADDING, options.text_padding, FALSE); - SetDlgItemInt(hwndDlg, IDC_ED_AVPADDING, options.av_padding, FALSE); - SetDlgItemInt(hwndDlg, IDC_ED_SBWIDTH, options.sidebar_width, FALSE); +#include "common.h" +#include "options.h" +#include "resource.h" +#include "popwin.h" +#include +#include "str_utils.h" + +#include + +Options options; + +#define WMU_ENABLE_LIST_BUTTONS (WM_USER + 0x030) +#define WMU_ENABLE_MODULE_ENTRY (WM_USER + 0x031) + +void CreateDefaultItems() { + DSListNode *ds_node; + DIListNode *di_node; + + // last message item + di_node = (DIListNode *)malloc(sizeof(DIListNode)); + _tcsncpy(di_node->di.label, _T("Last message: (%sys:last_msg_reltime% ago)"), LABEL_LEN); + _tcsncpy(di_node->di.value, _T("%sys:last_msg%"), VALUE_LEN); + di_node->di.line_above = di_node->di.value_newline = true; + di_node->next = options.di_list; + options.di_list = di_node; + options.di_count++; + + // status message item + di_node = (DIListNode *)malloc(sizeof(DIListNode)); + _tcsncpy(di_node->di.label, _T("Status message:"), LABEL_LEN); + _tcsncpy(di_node->di.value, _T("%sys:status_msg%"), VALUE_LEN); + di_node->di.line_above = di_node->di.value_newline = true; + di_node->next = options.di_list; + options.di_list = di_node; + options.di_count++; + + // status substitution + ds_node = (DSListNode *)malloc(sizeof(DSListNode)); + _tcsncpy(ds_node->ds.name, _T("status"), LABEL_LEN); + ds_node->ds.type = DVT_PROTODB; + strncpy(ds_node->ds.setting_name, "Status", SETTING_NAME_LEN); + ds_node->ds.translate_func_id = 1; + ds_node->next = options.ds_list; + options.ds_list = ds_node; + options.ds_count++; + + // status item + di_node = (DIListNode *)malloc(sizeof(DIListNode)); + _tcsncpy(di_node->di.label, _T("Status:"), LABEL_LEN); + _tcsncpy(di_node->di.value, _T("%status%"), VALUE_LEN); + di_node->di.line_above = di_node->di.value_newline = false; + di_node->next = options.di_list; + options.di_list = di_node; + options.di_count++; + + // client substitution + ds_node = (DSListNode *)malloc(sizeof(DSListNode)); + _tcsncpy(ds_node->ds.name, _T("client"), LABEL_LEN); + ds_node->ds.type = DVT_PROTODB; + strncpy(ds_node->ds.setting_name, "MirVer", SETTING_NAME_LEN); + ds_node->ds.translate_func_id = 0; + ds_node->next = options.ds_list; + options.ds_list = ds_node; + options.ds_count++; + + // client item + di_node = (DIListNode *)malloc(sizeof(DIListNode)); + _tcsncpy(di_node->di.label, _T("Client:"), LABEL_LEN); + _tcsncpy(di_node->di.value, _T("%client%"), VALUE_LEN); + di_node->di.line_above = di_node->di.value_newline = false; + di_node->next = options.di_list; + options.di_list = di_node; + options.di_count++; + + // idle time substitution (long date) + ds_node = (DSListNode *)malloc(sizeof(DSListNode)); + _tcsncpy(ds_node->ds.name, _T("idle"), LABEL_LEN); + ds_node->ds.type = DVT_PROTODB; + strncpy(ds_node->ds.setting_name, "IdleTS", SETTING_NAME_LEN); + ds_node->ds.translate_func_id = 15; + ds_node->next = options.ds_list; + options.ds_list = ds_node; + options.ds_count++; + + // idle time substitution (time difference) + ds_node = (DSListNode *)malloc(sizeof(DSListNode)); + _tcsncpy(ds_node->ds.name, _T("idle_diff"), LABEL_LEN); + ds_node->ds.type = DVT_PROTODB; + strncpy(ds_node->ds.setting_name, "IdleTS", SETTING_NAME_LEN); + ds_node->ds.translate_func_id = 3; + ds_node->next = options.ds_list; + options.ds_list = ds_node; + options.ds_count++; + + + // idle item + di_node = (DIListNode *)malloc(sizeof(DIListNode)); + _tcsncpy(di_node->di.label, _T("Idle:"), LABEL_LEN); + _tcsncpy(di_node->di.value, _T("%idle% (%idle_diff% ago)"), VALUE_LEN); + di_node->di.line_above = di_node->di.value_newline = false; + di_node->next = options.di_list; + options.di_list = di_node; + options.di_count++; + + // first name substitution + ds_node = (DSListNode *)malloc(sizeof(DSListNode)); + _tcsncpy(ds_node->ds.name, _T("first_name"), LABEL_LEN); + ds_node->ds.type = DVT_PROTODB; + strncpy(ds_node->ds.setting_name, "FirstName", SETTING_NAME_LEN); + ds_node->ds.translate_func_id = 0; + ds_node->next = options.ds_list; + options.ds_list = ds_node; + options.ds_count++; + + // last name substitution + ds_node = (DSListNode *)malloc(sizeof(DSListNode)); + _tcsncpy(ds_node->ds.name, _T("last_name"), LABEL_LEN); + ds_node->ds.type = DVT_PROTODB; + strncpy(ds_node->ds.setting_name, "LastName", SETTING_NAME_LEN); + ds_node->ds.translate_func_id = 0; + ds_node->next = options.ds_list; + options.ds_list = ds_node; + options.ds_count++; + + // name item + di_node = (DIListNode *)malloc(sizeof(DIListNode)); + _tcsncpy(di_node->di.label, _T("Name:"), LABEL_LEN); + _tcsncpy(di_node->di.value, _T("%first_name% %last_name%"), VALUE_LEN); + di_node->di.line_above = di_node->di.value_newline = false; + di_node->next = options.di_list; + options.di_list = di_node; + options.di_count++; + +} + +bool LoadDS(DisplaySubst *ds, int index) { + char setting[512]; + DBVARIANT dbv; + mir_snprintf(setting, 512, "Name%d", index); + ds->name[0] = 0; + if(!DBGetContactSettingWString(0, MODULE, setting, &dbv)) { + w2t(dbv.pwszVal, ds->name, LABEL_LEN); + DBFreeVariant(&dbv); + } else if(!DBGetContactSettingStringUtf(0, MODULE, setting, &dbv)) { + u2t(dbv.pszVal, ds->name, LABEL_LEN); + DBFreeVariant(&dbv); + } else if(!DBGetContactSetting(0, MODULE, setting, &dbv)) { + if(dbv.type == DBVT_ASCIIZ) a2t(dbv.pszVal, ds->name, LABEL_LEN); + DBFreeVariant(&dbv); + } else + return false; + ds->name[LABEL_LEN - 1] = 0; + + mir_snprintf(setting, 512, "Type%d", index); + ds->type = (DisplaySubstType)DBGetContactSettingByte(0, MODULE, setting, DVT_PROTODB); + + mir_snprintf(setting, 512, "Module%d", index); + ds->module_name[0] = 0; + if(!DBGetContactSettingString(0, MODULE, setting, &dbv)) { + strncpy(ds->module_name, dbv.pszVal, MODULE_NAME_LEN); + ds->module_name[MODULE_NAME_LEN - 1] = 0; + DBFreeVariant(&dbv); + } + + mir_snprintf(setting, 512, "Setting%d", index); + ds->setting_name[0] = 0; + if(!DBGetContactSettingString(0, MODULE, setting, &dbv)) { + strncpy(ds->setting_name, dbv.pszVal, SETTING_NAME_LEN); + ds->setting_name[SETTING_NAME_LEN - 1] = 0; + DBFreeVariant(&dbv); + } + + mir_snprintf(setting, 512, "TransFuncId%d", index); + ds->translate_func_id = DBGetContactSettingDword(0, MODULE, setting, (DWORD)-1); + + // a little backward compatibility + if((DWORD)ds->translate_func_id == (DWORD)-1) { + mir_snprintf(setting, 512, "TransFunc%d", index); + ds->translate_func_id = (DWORD)DBGetContactSettingWord(0, MODULE, setting, 0); + } + return true; +} + +void SaveDS(DisplaySubst *ds, int index) { + char setting[512]; + mir_snprintf(setting, 512, "Name%d", index); + if(DBWriteContactSettingTString(0, MODULE, setting, ds->name)) { + char buff[LABEL_LEN]; + t2a(ds->name, buff, LABEL_LEN); + DBWriteContactSettingString(0, MODULE, setting, buff); + } + mir_snprintf(setting, 512, "Type%d", index); + DBWriteContactSettingByte(0, MODULE, setting, (BYTE)ds->type); + mir_snprintf(setting, 512, "Module%d", index); + DBWriteContactSettingString(0, MODULE, setting, ds->module_name); + mir_snprintf(setting, 512, "Setting%d", index); + DBWriteContactSettingString(0, MODULE, setting, ds->setting_name); + mir_snprintf(setting, 512, "TransFuncId%d", index); + DBWriteContactSettingDword(0, MODULE, setting, (WORD)ds->translate_func_id); +} + +bool LoadDI(DisplayItem *di, int index) { + char setting[512]; + DBVARIANT dbv; + mir_snprintf(setting, 512, "DILabel%d", index); + di->label[0] = 0; + if(!DBGetContactSettingWString(0, MODULE, setting, &dbv)) { + w2t(dbv.pwszVal, di->label, LABEL_LEN); + DBFreeVariant(&dbv); + } else if(!DBGetContactSettingStringUtf(0, MODULE, setting, &dbv)) { + u2t(dbv.pszVal, di->label, LABEL_LEN); + DBFreeVariant(&dbv); + } else if(!DBGetContactSetting(0, MODULE, setting, &dbv)) { + if(dbv.type == DBVT_ASCIIZ) a2t(dbv.pszVal, di->label, LABEL_LEN); + DBFreeVariant(&dbv); + } else + return false; + di->label[LABEL_LEN - 1] = 0; + + mir_snprintf(setting, 512, "DIValue%d", index); + di->value[0] = 0; + if(!DBGetContactSettingWString(0, MODULE, setting, &dbv)) { + w2t(dbv.pwszVal, di->value, VALUE_LEN); + DBFreeVariant(&dbv); + } else if(!DBGetContactSettingStringUtf(0, MODULE, setting, &dbv)) { + u2t(dbv.pszVal, di->value, VALUE_LEN); + DBFreeVariant(&dbv); + } else if(!DBGetContactSetting(0, MODULE, setting, &dbv)) { + if(dbv.type == DBVT_ASCIIZ) a2t(dbv.pszVal, di->value, VALUE_LEN); + DBFreeVariant(&dbv); + } + + di->value[VALUE_LEN - 1] = 0; + + mir_snprintf(setting, 512, "DILineAbove%d", index); + di->line_above = (DBGetContactSettingByte(0, MODULE, setting, 0) == 1); + mir_snprintf(setting, 512, "DIValNewline%d", index); + di->value_newline = (DBGetContactSettingByte(0, MODULE, setting, 0) == 1); + + return true; +} + +void SaveDI(DisplayItem *di, int index) { + char setting[512]; + mir_snprintf(setting, 512, "DILabel%d", index); + if(DBWriteContactSettingTString(0, MODULE, setting, di->label)) { + char buff[LABEL_LEN]; + t2a(di->label, buff, LABEL_LEN); + DBWriteContactSettingString(0, MODULE, setting, buff); + } + mir_snprintf(setting, 512, "DIValue%d", index); + if(DBWriteContactSettingTString(0, MODULE, setting, di->value)) { + char buff[VALUE_LEN]; + t2a(di->value, buff, VALUE_LEN); + DBWriteContactSettingString(0, MODULE, setting, buff); + } + mir_snprintf(setting, 512, "DILineAbove%d", index); + DBWriteContactSettingByte(0, MODULE, setting, di->line_above ? 1 : 0); + mir_snprintf(setting, 512, "DIValNewline%d", index); + DBWriteContactSettingByte(0, MODULE, setting, di->value_newline ? 1 : 0); +} + +void SaveOptions() { + DBWriteContactSettingDword(0, MODULE, "MaxWidth", options.win_width); + DBWriteContactSettingDword(0, MODULE, "MaxHeight", options.win_max_height); + DBWriteContactSettingByte(0, MODULE, "Opacity", (BYTE)options.opacity); + DBWriteContactSettingByte(0, MODULE, "Border", (options.border ? 1 : 0)); + DBWriteContactSettingByte(0, MODULE, "DropShadow", (options.drop_shadow ? 1 : 0)); + DBWriteContactSettingByte(0, MODULE, "RoundCorners", (options.round ? 1 : 0)); + DBWriteContactSettingByte(0, MODULE, "AvatarRoundCorners", (options.av_round ? 1 : 0)); + DBWriteContactSettingByte(0, MODULE, "Animate", (options.animate ? 1 : 0)); + DBWriteContactSettingByte(0, MODULE, "TransparentBg", (options.trans_bg ? 1 : 0)); + DBWriteContactSettingByte(0, MODULE, "TitleLayout", (BYTE)options.title_layout); + if(ServiceExists(MS_AV_DRAWAVATAR)) + DBWriteContactSettingByte(0, MODULE, "AVLayout", (BYTE)options.av_layout); + DBWriteContactSettingDword(0, MODULE, "AVSize", options.av_size); + DBWriteContactSettingDword(0, MODULE, "TextIndent", options.text_indent); + DBWriteContactSettingByte(0, MODULE, "ShowNoFocus", (options.show_no_focus ? 1 : 0)); + + int index = 0; + DSListNode *ds_node = options.ds_list; + while(ds_node) { + SaveDS(&ds_node->ds, index); + ds_node = ds_node->next; + index++; + } + DBWriteContactSettingWord(0, MODULE, "DSNumValues", index); + + index = 0; + DIListNode *di_node = options.di_list; + while(di_node) { + SaveDI(&di_node->di, index); + di_node = di_node->next; + index++; + } + DBWriteContactSettingWord(0, MODULE, "DINumValues", index); + + DBWriteContactSettingWord(0, MODULE, "TimeIn", options.time_in); + CallService(MS_CLC_SETINFOTIPHOVERTIME, options.time_in, 0); + + DBWriteContactSettingWord(0, MODULE, "Padding", options.padding); + DBWriteContactSettingWord(0, MODULE, "AvatarPadding", options.av_padding); + DBWriteContactSettingWord(0, MODULE, "TextPadding", options.text_padding); + DBWriteContactSettingByte(0, MODULE, "Position", (BYTE)options.pos); + DBWriteContactSettingDword(0, MODULE, "MinWidth", (DWORD)options.min_width); + DBWriteContactSettingDword(0, MODULE, "MinHeight", (DWORD)options.min_height); + DBWriteContactSettingDword(0, MODULE, "SidebarWidth", (DWORD)options.sidebar_width); + DBWriteContactSettingByte(0, MODULE, "MouseTollerance", (BYTE)options.mouse_tollerance); + DBWriteContactSettingByte(0, MODULE, "SBarTips", (options.status_bar_tips ? 1 : 0)); + + DBWriteContactSettingWord(0, MODULE, "LabelVAlign", options.label_valign); + DBWriteContactSettingWord(0, MODULE, "LabelHAlign", options.label_halign); + DBWriteContactSettingWord(0, MODULE, "ValueVAlign", options.value_valign); + DBWriteContactSettingWord(0, MODULE, "ValueHAlign", options.value_halign); + + DBWriteContactSettingByte(0, MODULE, "NoAvatarResize", options.no_resize_av ? 1 : 0); + DBWriteContactSettingTString(0, MODULE, "BackgroundFilename", options.bg_fn); + DBWriteContactSettingByte(0, MODULE, "StretchBgImg", options.stretch_bg_img ? 1 : 0); +} + +void LoadOptions() { + options.win_width = DBGetContactSettingDword(0, MODULE, "MaxWidth", 420); + options.win_max_height = DBGetContactSettingDword(0, MODULE, "MaxHeight", 400); + options.opacity = DBGetContactSettingByte(0, MODULE, "Opacity", 75); + options.border = (DBGetContactSettingByte(0, MODULE, "Border", 1) == 1); + options.drop_shadow = (DBGetContactSettingByte(0, MODULE, "DropShadow", 1) == 1); + options.round = (DBGetContactSettingByte(0, MODULE, "RoundCorners", 1) == 1); + options.av_round = (DBGetContactSettingByte(0, MODULE, "AvatarRoundCorners", options.round ? 1 : 0) == 1); + options.animate = (DBGetContactSettingByte(0, MODULE, "Animate", 0) == 1); + options.trans_bg = (DBGetContactSettingByte(0, MODULE, "TransparentBg", 0) == 1); + options.title_layout = (PopupTitleLayout)DBGetContactSettingByte(0, MODULE, "TitleLayout", (BYTE)PTL_LEFTICON); + if(ServiceExists(MS_AV_DRAWAVATAR)) + options.av_layout = (PopupAvLayout)DBGetContactSettingByte(0, MODULE, "AVLayout", PAV_RIGHT); + else + options.av_layout = PAV_NONE; + options.av_size = DBGetContactSettingDword(0, MODULE, "AVSize", 60); //tweety + options.text_indent = DBGetContactSettingDword(0, MODULE, "TextIndent", 22); + options.sidebar_width = DBGetContactSettingDword(0, MODULE, "SidebarWidth", 22); + options.show_no_focus = (DBGetContactSettingByte(0, MODULE, "ShowNoFocus", 1) == 1); + + int i, real_count = 0; + options.ds_list = 0; + DSListNode *ds_node; + options.ds_count = DBGetContactSettingWord(0, MODULE, "DSNumValues", 0); + for(i = options.ds_count - 1; i >= 0; i--) { + ds_node = (DSListNode *)malloc(sizeof(DSListNode)); + if(LoadDS(&ds_node->ds, i)) { + ds_node->next = options.ds_list; + options.ds_list = ds_node; + real_count++; + } else free(ds_node); + } + options.ds_count = real_count; + + real_count = 0; + options.di_list = 0; + DIListNode *di_node; + options.di_count = DBGetContactSettingWord(0, MODULE, "DINumValues", 0); + for(i = options.di_count - 1; i >= 0; i--) { + di_node = (DIListNode *)malloc(sizeof(DIListNode)); + if(LoadDI(&di_node->di, i)) { + di_node->next = options.di_list; + options.di_list = di_node; + real_count++; + } else free(di_node); + } + options.di_count = real_count; + + options.time_in = DBGetContactSettingWord(0, MODULE, "TimeIn", 750); + options.padding = DBGetContactSettingWord(0, MODULE, "Padding", 4); + options.av_padding = DBGetContactSettingWord(0, MODULE, "AvatarPadding", 6); + options.text_padding = DBGetContactSettingWord(0, MODULE, "TextPadding", 4); + options.pos = (PopupPosition)DBGetContactSettingByte(0, MODULE, "Position", (BYTE)PP_BOTTOMRIGHT); + options.min_width = DBGetContactSettingDword(0, MODULE, "MinWidth", 0); + options.min_height = DBGetContactSettingDword(0, MODULE, "MinHeight", 0); + + options.mouse_tollerance = DBGetContactSettingByte(0, MODULE, "MouseTollerance", (BYTE)GetSystemMetrics(SM_CXSMICON)); + options.status_bar_tips = (DBGetContactSettingByte(0, MODULE, "SBarTips", 1) == 1); + + // convert defunct last message and status message options to new 'sys' items, and remove the old settings + if(DBGetContactSettingByte(0, MODULE, "ShowLastMessage", 0)) { + DBDeleteContactSetting(0, MODULE, "ShowLastMessage"); + + // find end of list + di_node = options.di_list; + while(di_node && di_node->next) di_node = di_node->next; + + // last message item + if(di_node) { + di_node->next = (DIListNode *)malloc(sizeof(DIListNode)); + di_node = di_node->next; + } else { + options.di_list = (DIListNode *)malloc(sizeof(DIListNode)); + di_node = options.di_list; + } + + _tcsncpy(di_node->di.label, _T("Last message: (%sys:last_msg_reltime% ago)"), LABEL_LEN); + _tcsncpy(di_node->di.value, _T("%sys:last_msg%"), VALUE_LEN); + di_node->di.line_above = di_node->di.value_newline = true; + di_node->next = 0; + options.di_count++; + } + + if(DBGetContactSettingByte(0, MODULE, "ShowStatusMessage", 0)) { + DBDeleteContactSetting(0, MODULE, "ShowStatusMessage"); + + // find end of list + di_node = options.di_list; + while(di_node && di_node->next) di_node = di_node->next; + + // status message item + if(di_node) { + di_node->next = (DIListNode *)malloc(sizeof(DIListNode)); + di_node = di_node->next; + } else { + options.di_list = (DIListNode *)malloc(sizeof(DIListNode)); + di_node = options.di_list; + } + + _tcsncpy(di_node->di.label, _T("Status message:"), LABEL_LEN); + _tcsncpy(di_node->di.value, _T("%sys:status_msg%"), VALUE_LEN); + di_node->di.line_above = di_node->di.value_newline = true; + di_node->next = 0; + options.di_count++; + } + + options.label_valign = DBGetContactSettingWord(0, MODULE, "LabelVAlign", DT_TOP /*DT_VCENTER*/); + options.label_halign = DBGetContactSettingWord(0, MODULE, "LabelHAlign", DT_LEFT); + options.value_valign = DBGetContactSettingWord(0, MODULE, "ValueVAlign", DT_TOP /*DT_VCENTER*/); + options.value_halign = DBGetContactSettingWord(0, MODULE, "ValueHAlign", DT_LEFT); + + if(options.ds_count == 0 && options.di_count == 0 && DBGetContactSettingByte(0, MODULE, "DefaultsCreated", 0) == 0) { + // set up some reasonable defaults - but only 'once' + CreateDefaultItems(); + DBWriteContactSettingByte(0, MODULE, "DefaultsCreated", 1); + SaveOptions(); + } + + options.no_resize_av = (DBGetContactSettingByte(0, MODULE, "NoAvatarResize", 0) == 1); + DBVARIANT dbv; + if(!DBGetContactSettingTString(0, MODULE, "BackgroundFilename", &dbv)) { + _tcsncpy(options.bg_fn, dbv.ptszVal, MAX_PATH); + DBFreeVariant(&dbv); + } else + options.bg_fn[0] = 0; + options.stretch_bg_img = (DBGetContactSettingByte(0, MODULE, "StretchBgImg", 0) == 1); +} + +static INT_PTR CALLBACK DlgProcAddItem(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + DisplayItem *di = (DisplayItem *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + di = (DisplayItem *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)di); + + SetDlgItemText(hwndDlg, IDC_ED_LABEL, di->label); + SetDlgItemText(hwndDlg, IDC_ED_VALUE, di->value); + + CheckDlgButton(hwndDlg, IDC_CHK_LINEABOVE, di->line_above ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_VALNEWLINE, di->value_newline ? TRUE : FALSE); + SetFocus(GetDlgItem(hwndDlg, IDC_ED_LABEL)); + return TRUE; + case WM_COMMAND: + if(HIWORD(wParam) == BN_CLICKED) { + switch(LOWORD(wParam)) { + case IDOK: + GetDlgItemText(hwndDlg, IDC_ED_LABEL, di->label, LABEL_LEN); + GetDlgItemText(hwndDlg, IDC_ED_VALUE, di->value, VALUE_LEN); + + di->line_above = (IsDlgButtonChecked(hwndDlg, IDC_CHK_LINEABOVE) ? true : false); + di->value_newline = (IsDlgButtonChecked(hwndDlg, IDC_CHK_VALNEWLINE) ? true : false); + + EndDialog(hwndDlg, IDOK); + return TRUE; + case IDCANCEL: + EndDialog(hwndDlg, IDCANCEL); + return TRUE; + } + } + break; + } + + return 0; +} + +static INT_PTR CALLBACK DlgProcAddSubst(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + DisplaySubst *ds = (DisplaySubst *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + ds = (DisplaySubst *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)ds); + + SetDlgItemText(hwndDlg, IDC_ED_LABEL, ds->name); + + switch(ds->type) { + case DVT_PROTODB: + CheckDlgButton(hwndDlg, IDC_CHK_PROTOMOD, TRUE); + SetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name); + break; + case DVT_DB: + SetDlgItemTextA(hwndDlg, IDC_ED_MODULE, ds->module_name); + SetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name); + break; + } + + { + int index, id, i; + for(i = 0; i < num_tfuncs; i++) { + index = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_ADDSTRING, (WPARAM)-1, (LPARAM)TranslateTS(translations[i].name)); + SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_SETITEMDATA, index, (LPARAM)translations[i].id); + } + for(i = 0; i < num_tfuncs; i++) { + id = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETITEMDATA, i, 0); + if(id == ds->translate_func_id) + SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_SETCURSEL, i, 0); + } + } + + SendMessage(hwndDlg, WMU_ENABLE_MODULE_ENTRY, 0, 0); + SetFocus(GetDlgItem(hwndDlg, IDC_ED_LABEL)); + return TRUE; + case WMU_ENABLE_MODULE_ENTRY: + { + HWND hw = GetDlgItem(hwndDlg, IDC_CHK_PROTOMOD); + EnableWindow(hw, TRUE); + hw = GetDlgItem(hwndDlg, IDC_ED_MODULE); + EnableWindow(hw, !IsDlgButtonChecked(hwndDlg, IDC_CHK_PROTOMOD)); + hw = GetDlgItem(hwndDlg, IDC_ED_SETTING); + EnableWindow(hw, TRUE); + } + return TRUE; + case WM_COMMAND: + if ( HIWORD( wParam ) == CBN_SELCHANGE) { + return TRUE; + } else if(HIWORD(wParam) == BN_CLICKED) { + switch(LOWORD(wParam)) { + case IDC_CHK_PROTOMOD: + SendMessage(hwndDlg, WMU_ENABLE_MODULE_ENTRY, 0, 0); + break; + case IDOK: + GetDlgItemText(hwndDlg, IDC_ED_LABEL, ds->name, LABEL_LEN); + if(ds->name[0] == 0) { + MessageBox(hwndDlg, TranslateT("You must enter a label"), TranslateT("Invalid Substitution"), MB_OK | MB_ICONWARNING); + return TRUE; + } + + if(IsDlgButtonChecked(hwndDlg, IDC_CHK_PROTOMOD)) + ds->type = DVT_PROTODB; + else { + ds->type = DVT_DB; + GetDlgItemTextA(hwndDlg, IDC_ED_MODULE, ds->module_name, MODULE_NAME_LEN); + } + GetDlgItemTextA(hwndDlg, IDC_ED_SETTING, ds->setting_name, SETTING_NAME_LEN); + + { + int sel = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETCURSEL, 0, 0); + ds->translate_func_id = SendDlgItemMessage(hwndDlg, IDC_CMB_TRANSLATE, CB_GETITEMDATA, sel, 0); + } + + EndDialog(hwndDlg, IDOK); + return TRUE; + case IDCANCEL: + EndDialog(hwndDlg, IDCANCEL); + return TRUE; + } + } + break; + } + + return 0; +} + +static INT_PTR CALLBACK DlgProcOptContent(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + { + int index; + DIListNode *di_node = options.di_list, *di_value; + while(di_node) { + di_value = (DIListNode *)malloc(sizeof(DIListNode)); + *di_value = *di_node; + if(di_value->di.label[0] == 0) + index = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_ADDSTRING, 0, (LPARAM)TranslateT("")); + else + index = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_ADDSTRING, 0, (LPARAM)di_value->di.label); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, index, (LPARAM)di_value); + + di_node = di_node->next; + } + + DSListNode *ds_node = options.ds_list, *ds_value; + while(ds_node) { + ds_value = (DSListNode *)malloc(sizeof(DSListNode)); + *ds_value = *ds_node; + index = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)ds_value->ds.name); + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, index, (LPARAM)ds_value); + + ds_node = ds_node->next; + } + } + + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + return FALSE; + case WMU_ENABLE_LIST_BUTTONS: + { + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); + if(sel == -1) { + HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE); + EnableWindow(hw, FALSE); + hw = GetDlgItem(hwndDlg, IDC_BTN_UP); + EnableWindow(hw, FALSE); + hw = GetDlgItem(hwndDlg, IDC_BTN_DOWN); + EnableWindow(hw, FALSE); + hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT); + EnableWindow(hw, FALSE); + } else { + int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0); + HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE); + EnableWindow(hw, TRUE); + hw = GetDlgItem(hwndDlg, IDC_BTN_UP); + EnableWindow(hw, sel > 0); + hw = GetDlgItem(hwndDlg, IDC_BTN_DOWN); + EnableWindow(hw, sel < count - 1); + hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT); + EnableWindow(hw, TRUE); + } + + sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0); + if(sel == -1) { + HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE2); + EnableWindow(hw, FALSE); + hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT2); + EnableWindow(hw, FALSE); + } else { + HWND hw = GetDlgItem(hwndDlg, IDC_BTN_REMOVE2); + EnableWindow(hw, TRUE); + hw = GetDlgItem(hwndDlg, IDC_BTN_EDIT2); + EnableWindow(hw, TRUE); + } + } + return TRUE; + case WM_COMMAND: + if ( HIWORD( wParam ) == LBN_SELCHANGE && LOWORD(wParam) == IDC_LST_ITEMS) { + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + } else if ( HIWORD( wParam ) == LBN_SELCHANGE && LOWORD(wParam) == IDC_LST_SUBST) { + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + } else if ( HIWORD( wParam ) == CBN_SELCHANGE) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } else if ( HIWORD( wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_LST_ITEMS) { + { + DIListNode *value; + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); + if(sel != -1) { + value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0); + if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) { + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0); + + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value->di.label); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value); + + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel, 0); + + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + } + } else if ( HIWORD( wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_LST_SUBST) { + { + DSListNode *value; + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0); + if(sel != -1) { + value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0); + if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) { + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0); + + sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name); + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, sel, (LPARAM)value); + + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, sel, 0); + + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + } + } else if ( HIWORD( wParam ) == BN_CLICKED ) { + switch(LOWORD(wParam)) { + case IDC_BTN_ADD: + { + DIListNode *value = (DIListNode *)malloc(sizeof(DIListNode)); + memset(value, 0, sizeof(DIListNode)); + if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) { + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0), index = sel + 1; + if(value->di.label[0] == 0) + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, index, (LPARAM)TranslateT("")); + else + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, index, (LPARAM)value->di.label); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, index, (LPARAM)value); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, index, 0); + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + + } + return TRUE; + case IDC_BTN_REMOVE: + { + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); + if(sel != -1) { + DIListNode *value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0); + free(value); + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + return TRUE; + case IDC_BTN_UP: + { + DIListNode *value_up; + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); + if(sel > 0) { + value_up = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel - 1, 0); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel - 1, 0); + + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value_up->di.label); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value_up); + + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel - 1, 0); + } + } + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_BTN_DOWN: + { + DIListNode *value_down; + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); + int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0); + if(sel < count - 1) { + value_down = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel + 1, 0); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel + 1, 0); + + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value_down->di.label); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value_down); + + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel + 1, 0); + } + } + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_BTN_EDIT: + { + DIListNode *value; + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCURSEL, 0, 0); + if(sel != -1) { + value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, sel, 0); + if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEM), hwndDlg, DlgProcAddItem, (LPARAM)&value->di) == IDOK) { + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_DELETESTRING, (WPARAM)sel, 0); + + if(value->di.label[0] == 0) + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)TranslateT("")); + else + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_INSERTSTRING, sel, (LPARAM)value->di.label); + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETITEMDATA, sel, (LPARAM)value); + + SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_SETCURSEL, sel, 0); + + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + } + return TRUE; + + case IDC_BTN_ADD2: + { + DSListNode *value = (DSListNode *)malloc(sizeof(DSListNode)); + memset(value, 0, sizeof(DSListNode)); + if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) { + int index = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name); + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, index, (LPARAM)value); + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, index, 0); + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + + } + return TRUE; + case IDC_BTN_REMOVE2: + { + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0); + if(sel != -1) { + DSListNode *value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0); + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0); + free(value); + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + return TRUE; + case IDC_BTN_EDIT2: + { + DSListNode *value; + int sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCURSEL, 0, 0); + if(sel != -1) { + value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, sel, 0); + if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SUBST), hwndDlg, DlgProcAddSubst, (LPARAM)&value->ds) == IDOK) { + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_DELETESTRING, (WPARAM)sel, 0); + + sel = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_ADDSTRING, 0, (LPARAM)value->ds.name); + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETITEMDATA, sel, (LPARAM)value); + + SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_SETCURSEL, sel, 0); + + SendMessage(hwndDlg, WMU_ENABLE_LIST_BUTTONS, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + } + return TRUE; + default: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return TRUE; + } + } + break; + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) { + DIListNode *di_node; + int i; + while(options.di_list) { + di_node = options.di_list; + options.di_list = options.di_list->next; + free(di_node); + } + + DIListNode *di_value; + options.di_count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0); + for(i = options.di_count - 1; i >= 0; i--) { + di_node = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, i, 0); + di_value = (DIListNode *)malloc(sizeof(DIListNode)); + *di_value = *di_node; + + di_value->next = options.di_list; + options.di_list = di_value; + } + + DSListNode *ds_node; + while(options.ds_list) { + ds_node = options.ds_list; + options.ds_list = options.ds_list->next; + free(ds_node); + } + + DSListNode *ds_value; + options.ds_count = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCOUNT, 0, 0); + for(i = options.ds_count - 1; i >= 0; i--) { + ds_node = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, i, 0); + ds_value = (DSListNode *)malloc(sizeof(DSListNode)); + *ds_value = *ds_node; + + ds_value->next = options.ds_list; + options.ds_list = ds_value; + } + + SaveOptions(); + return TRUE; + } + break; + case WM_DESTROY: + { + DIListNode *di_value; + int i; + int count = SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETCOUNT, 0, 0); + for(i = 0; i < count; i++) { + di_value = (DIListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_ITEMS, LB_GETITEMDATA, i, 0); + free(di_value); + } + DSListNode *ds_value; + count = SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETCOUNT, 0, 0); + for(i = 0; i < count; i++) { + ds_value = (DSListNode *)SendDlgItemMessage(hwndDlg, IDC_LST_SUBST, LB_GETITEMDATA, i, 0); + free(ds_value); + } + } + break; + } + + return 0; +} + +static INT_PTR CALLBACK DlgProcOptWindow(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + SendDlgItemMessage(hwndDlg, IDC_SPIN_WIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_MINWIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_MAXHEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_MINHEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 16)); + SetDlgItemInt(hwndDlg, IDC_ED_WIDTH, options.win_width, FALSE); + SetDlgItemInt(hwndDlg, IDC_ED_MAXHEIGHT, options.win_max_height, FALSE); + SetDlgItemInt(hwndDlg, IDC_ED_MINWIDTH, options.min_width, FALSE); + SetDlgItemInt(hwndDlg, IDC_ED_MINHEIGHT, options.min_height, FALSE); + + SetDlgItemInt(hwndDlg, IDC_ED_TRANS, options.opacity, FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_TRANSBG, options.trans_bg); + + CheckDlgButton(hwndDlg, IDC_CHK_NOFOCUS, options.show_no_focus ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_SBAR, options.status_bar_tips ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_BORDER, options.border); + CheckDlgButton(hwndDlg, IDC_CHK_ROUNDCORNERS, options.round); + CheckDlgButton(hwndDlg, IDC_CHK_ROUNDCORNERSAV, options.av_round); + + CheckDlgButton(hwndDlg, IDC_CHK_ANIMATE, options.animate); + CheckDlgButton(hwndDlg, IDC_CHK_SHADOW, options.drop_shadow); + + SendDlgItemMessage(hwndDlg, IDC_SPIN_HOVER, UDM_SETRANGE, 0, (LPARAM)MAKELONG(5000, 5)); + SetDlgItemInt(hwndDlg, IDC_ED_HOVER, options.time_in, FALSE); + break; + case WM_COMMAND: + if ( HIWORD( wParam ) == CBN_SELCHANGE) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } else if ( HIWORD( wParam ) == BN_CLICKED ) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) { + BOOL trans; + int new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_WIDTH, &trans, FALSE); + if(trans) options.win_width = new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_MINWIDTH, &trans, FALSE); + if(trans) options.min_width = new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_MAXHEIGHT, &trans, FALSE); + if(trans) options.win_max_height = new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_MINHEIGHT, &trans, FALSE); + if(trans) options.min_height = new_val; + + new_val = GetDlgItemInt(hwndDlg, IDC_ED_TRANS, &trans, FALSE); + if(trans) options.opacity = new_val; + options.trans_bg = IsDlgButtonChecked(hwndDlg, IDC_CHK_TRANSBG) ? true : false; + + new_val = GetDlgItemInt(hwndDlg, IDC_ED_HOVER, &trans, FALSE); + if(trans) options.time_in = new_val; + + options.border = IsDlgButtonChecked(hwndDlg, IDC_CHK_BORDER) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_BORDER)) ? true : false; + options.round = IsDlgButtonChecked(hwndDlg, IDC_CHK_ROUNDCORNERS) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_ROUNDCORNERS)) ? true : false; + options.av_round = IsDlgButtonChecked(hwndDlg, IDC_CHK_ROUNDCORNERSAV) && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHK_ROUNDCORNERSAV)) ? true : false; + options.animate = IsDlgButtonChecked(hwndDlg, IDC_CHK_ANIMATE) ? true : false; + options.drop_shadow = IsDlgButtonChecked(hwndDlg, IDC_CHK_SHADOW) ? true : false; + + options.show_no_focus = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOFOCUS) ? true : false; + options.status_bar_tips = IsDlgButtonChecked(hwndDlg, IDC_CHK_SBAR) ? true : false; + + SaveOptions(); + return TRUE; + } + break; + } + return 0; +} + +static INT_PTR CALLBACK DlgProcOptLayout(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + + SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("Icon on left")); + SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("Icon on right")); + SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("No icon")); + SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_ADDSTRING, 0, (LPARAM)TranslateT("No title")); + SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_SETCURSEL, (int)options.title_layout, 0); + + SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom right")); + SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom left")); + SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top right")); + SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top left")); + SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_SETCURSEL, (int)options.pos, 0); + + SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top")); + SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Centre")); + SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom")); + switch(options.label_valign) { + case DT_TOP: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 0, 0); break; + case DT_VCENTER: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 1, 0); break; + case DT_BOTTOM: SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_SETCURSEL, 2, 0); break; + } + + SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Top")); + SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Centre")); + SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Bottom")); + switch(options.value_valign) { + case DT_TOP: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 0, 0); break; + case DT_VCENTER: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 1, 0); break; + case DT_BOTTOM: SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_SETCURSEL, 2, 0); break; + } + + SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left")); + SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right")); + switch(options.label_halign) { + case DT_LEFT: SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_SETCURSEL, 0, 0); break; + case DT_RIGHT: SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_SETCURSEL, 1, 0); break; + } + + SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left")); + SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right")); + switch(options.value_halign) { + case DT_LEFT: SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_SETCURSEL, 0, 0); break; + case DT_RIGHT: SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_SETCURSEL, 1, 0); break; + } + + SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("No avatar")); + if(ServiceExists(MS_AV_DRAWAVATAR)) { + SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Left avatar")); + SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_ADDSTRING, 0, (LPARAM)TranslateT("Right avatar")); + } else { + HWND hw = GetDlgItem(hwndDlg, IDC_CMB_AV); + EnableWindow(hw, FALSE); + hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE); + EnableWindow(hw, FALSE); + hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE); + EnableWindow(hw, FALSE); + } + SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_SETCURSEL, (int)options.av_layout, 0); + + SendDlgItemMessage(hwndDlg, IDC_SPIN_TRANS, UDM_SETRANGE, 0, (LPARAM)MAKELONG(99, 0)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_AVSIZE, UDM_SETRANGE, 0, (LPARAM)MAKELONG(100, 16)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_INDENT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(400, 0)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_PADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_TEXTPADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_AVPADDING, UDM_SETRANGE, 0, (LPARAM)MAKELONG(128, 0)); + SendDlgItemMessage(hwndDlg, IDC_SPIN_SBWIDTH, UDM_SETRANGE, 0, (LPARAM)MAKELONG(2048, 0)); + + CheckDlgButton(hwndDlg, IDC_CHK_NORESIZEAV, options.no_resize_av); + if(options.no_resize_av) { + HWND hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE); + EnableWindow(hw, FALSE); + hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE); + EnableWindow(hw, FALSE); + } + SetDlgItemInt(hwndDlg, IDC_ED_AVSIZE, options.av_size, FALSE); + SetDlgItemInt(hwndDlg, IDC_ED_INDENT, options.text_indent, FALSE); + SetDlgItemInt(hwndDlg, IDC_ED_PADDING, options.padding, FALSE); + SetDlgItemInt(hwndDlg, IDC_ED_TEXTPADDING, options.text_padding, FALSE); + SetDlgItemInt(hwndDlg, IDC_ED_AVPADDING, options.av_padding, FALSE); + SetDlgItemInt(hwndDlg, IDC_ED_SBWIDTH, options.sidebar_width, FALSE); SetDlgItemText(hwndDlg, IDC_ED_BGFN, options.bg_fn); - CheckDlgButton(hwndDlg, IDC_CHK_STRETCHBG, options.stretch_bg_img); - if(!ServiceExists(MS_IMG_LOAD)) { - HWND hw = GetDlgItem(hwndDlg, IDC_ED_BGFN); - EnableWindow(hw, FALSE); - hw = GetDlgItem(hwndDlg, IDC_CHK_STRETCHBG); - EnableWindow(hw, FALSE); - } - - return FALSE; - case WM_COMMAND: - if ( HIWORD( wParam ) == CBN_SELCHANGE) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } else if ( HIWORD( wParam ) == BN_CLICKED ) { - if(LOWORD(wParam) == IDC_BTN_BROWSE) { - TCHAR tempBgFn[MAX_PATH]; - tempBgFn[0] = 0; + CheckDlgButton(hwndDlg, IDC_CHK_STRETCHBG, options.stretch_bg_img); + if(!ServiceExists(MS_IMG_LOAD)) { + HWND hw = GetDlgItem(hwndDlg, IDC_ED_BGFN); + EnableWindow(hw, FALSE); + hw = GetDlgItem(hwndDlg, IDC_CHK_STRETCHBG); + EnableWindow(hw, FALSE); + } + + return FALSE; + case WM_COMMAND: + if ( HIWORD( wParam ) == CBN_SELCHANGE) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } else if ( HIWORD( wParam ) == BN_CLICKED ) { + if(LOWORD(wParam) == IDC_BTN_BROWSE) { + TCHAR tempBgFn[MAX_PATH]; + tempBgFn[0] = 0; OPENFILENAME ofn={0}; ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = hwndDlg; @@ -1092,134 +1092,134 @@ static BOOL CALLBACK DlgProcOptLayout(HWND hwndDlg, UINT msg, WPARAM wParam, LPA ofn.lpstrDefExt=_T(""); if (GetOpenFileName(&ofn)) { SetDlgItemText(hwndDlg, IDC_ED_BGFN, tempBgFn); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } else { + if(LOWORD(wParam) == IDC_CHK_NORESIZEAV) { + bool checked = IsDlgButtonChecked(hwndDlg, IDC_CHK_NORESIZEAV) != BST_UNCHECKED; + HWND hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE); + EnableWindow(hw, !checked); + hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE); + EnableWindow(hw, !checked); } - } else { - if(LOWORD(wParam) == IDC_CHK_NORESIZEAV) { - bool checked = IsDlgButtonChecked(hwndDlg, IDC_CHK_NORESIZEAV); - HWND hw = GetDlgItem(hwndDlg, IDC_ED_AVSIZE); - EnableWindow(hw, !checked); - hw = GetDlgItem(hwndDlg, IDC_SPIN_AVSIZE); - EnableWindow(hw, !checked); - } - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - break; - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) { - BOOL trans; - int new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_AVSIZE, &trans, FALSE); - if(trans) options.av_size = new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_INDENT, &trans, FALSE); - if(trans) options.text_indent = new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_PADDING, &trans, FALSE); - if(trans) options.padding = new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_TEXTPADDING, &trans, FALSE); - if(trans) options.text_padding = new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_AVPADDING, &trans, FALSE); - if(trans) options.av_padding = new_val; - new_val = GetDlgItemInt(hwndDlg, IDC_ED_SBWIDTH, &trans, FALSE); - if(trans) options.sidebar_width = new_val; - - options.title_layout = (PopupTitleLayout)SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_GETCURSEL, 0, 0); - options.av_layout = (PopupAvLayout)SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_GETCURSEL, 0, 0); - options.pos = (PopupPosition)SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_GETCURSEL, 0, 0); - - switch(SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_GETCURSEL, 0, 0)) { - case 0: options.label_valign = DT_TOP; break; - case 1: options.label_valign = DT_VCENTER; break; - case 2: options.label_valign = DT_BOTTOM; break; - } - switch(SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_GETCURSEL, 0, 0)) { - case 0: options.value_valign = DT_TOP; break; - case 1: options.value_valign = DT_VCENTER; break; - case 2: options.value_valign = DT_BOTTOM; break; - } - - switch(SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_GETCURSEL, 0, 0)) { - case 0: options.label_halign = DT_LEFT; break; - case 1: options.label_halign = DT_RIGHT; break; - } - switch(SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_GETCURSEL, 0, 0)) { - case 0: options.value_halign = DT_LEFT; break; - case 1: options.value_halign = DT_RIGHT; break; - } - - options.no_resize_av = IsDlgButtonChecked(hwndDlg, IDC_CHK_NORESIZEAV) ? true : false; - GetDlgItemText(hwndDlg, IDC_ED_BGFN, options.bg_fn, MAX_PATH); - options.stretch_bg_img = IsDlgButtonChecked(hwndDlg, IDC_CHK_STRETCHBG) ? true : false; - - SaveOptions(); - return TRUE; - } - break; - } - - return 0; -} - -int OptInit(WPARAM wParam, LPARAM lParam) { - OPTIONSDIALOGPAGE odp = { 0 }; -#define OPTIONPAGE_OLD_SIZE2 60 - DWORD mirVir = (DWORD)CallService(MS_SYSTEM_GETVERSION, 0, 0); - odp.cbSize = (mirVir >= 0x00060000 ? sizeof(odp) : OPTIONPAGE_OLD_SIZE2); - //odp.cbSize = sizeof(odp); - - odp.flags = ODPF_BOLDGROUPS; - //odp.flags |= ODPF_UNICODE; - odp.position = -790000000; - odp.hInstance = hInst; - - - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_WINDOW); - odp.pszTab = Translate("Window"); - odp.pszTitle = (mirVir >= 0x00060000 ? Translate("Tooltips") : Translate("Tooltips View"));; - odp.pszGroup = Translate("Customize"); - odp.nIDBottomSimpleControl = 0; - odp.pfnDlgProc = DlgProcOptWindow; - CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp ); - - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_LAYOUT); - odp.pszTab = Translate("Layout"); - odp.pszTitle = (mirVir >= 0x00060000 ? Translate("Tooltips") : Translate("Tooltips View"));; - odp.pszGroup = Translate("Customize"); - odp.nIDBottomSimpleControl = 0; - odp.pfnDlgProc = DlgProcOptLayout; - CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp ); - - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CONTENT); - odp.pszTab = Translate("Content"); - odp.pszTitle = (mirVir >= 0x00060000 ? Translate("Tooltips") : Translate("Tooltips Content"));; - odp.pszGroup = Translate("Customize"); - odp.nIDBottomSimpleControl = 0; - odp.pfnDlgProc = DlgProcOptContent; - CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp ); - - return 0; -} - -HANDLE hEventOptInit; - -void InitOptions() { - hEventOptInit = HookEvent(ME_OPT_INITIALISE, OptInit); -} - -void DeinitOptions() { - UnhookEvent(hEventOptInit); - - DIListNode *di_node = options.di_list; - while(options.di_list) { - di_node = options.di_list; - options.di_list = options.di_list->next; - free(di_node); - } - - DSListNode *ds_node = options.ds_list; - while(options.ds_list) { - ds_node = options.ds_list; - options.ds_list = options.ds_list->next; - free(ds_node); - } -} + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + break; + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) { + BOOL trans; + int new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_AVSIZE, &trans, FALSE); + if(trans) options.av_size = new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_INDENT, &trans, FALSE); + if(trans) options.text_indent = new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_PADDING, &trans, FALSE); + if(trans) options.padding = new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_TEXTPADDING, &trans, FALSE); + if(trans) options.text_padding = new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_AVPADDING, &trans, FALSE); + if(trans) options.av_padding = new_val; + new_val = GetDlgItemInt(hwndDlg, IDC_ED_SBWIDTH, &trans, FALSE); + if(trans) options.sidebar_width = new_val; + + options.title_layout = (PopupTitleLayout)SendDlgItemMessage(hwndDlg, IDC_CMB_ICON, CB_GETCURSEL, 0, 0); + options.av_layout = (PopupAvLayout)SendDlgItemMessage(hwndDlg, IDC_CMB_AV, CB_GETCURSEL, 0, 0); + options.pos = (PopupPosition)SendDlgItemMessage(hwndDlg, IDC_CMB_POS, CB_GETCURSEL, 0, 0); + + switch(SendDlgItemMessage(hwndDlg, IDC_CMB_LV, CB_GETCURSEL, 0, 0)) { + case 0: options.label_valign = DT_TOP; break; + case 1: options.label_valign = DT_VCENTER; break; + case 2: options.label_valign = DT_BOTTOM; break; + } + switch(SendDlgItemMessage(hwndDlg, IDC_CMB_VV, CB_GETCURSEL, 0, 0)) { + case 0: options.value_valign = DT_TOP; break; + case 1: options.value_valign = DT_VCENTER; break; + case 2: options.value_valign = DT_BOTTOM; break; + } + + switch(SendDlgItemMessage(hwndDlg, IDC_CMB_LH, CB_GETCURSEL, 0, 0)) { + case 0: options.label_halign = DT_LEFT; break; + case 1: options.label_halign = DT_RIGHT; break; + } + switch(SendDlgItemMessage(hwndDlg, IDC_CMB_VH, CB_GETCURSEL, 0, 0)) { + case 0: options.value_halign = DT_LEFT; break; + case 1: options.value_halign = DT_RIGHT; break; + } + + options.no_resize_av = IsDlgButtonChecked(hwndDlg, IDC_CHK_NORESIZEAV) ? true : false; + GetDlgItemText(hwndDlg, IDC_ED_BGFN, options.bg_fn, MAX_PATH); + options.stretch_bg_img = IsDlgButtonChecked(hwndDlg, IDC_CHK_STRETCHBG) ? true : false; + + SaveOptions(); + return TRUE; + } + break; + } + + return 0; +} + +int OptInit(WPARAM wParam, LPARAM lParam) { + OPTIONSDIALOGPAGE odp = { 0 }; +#define OPTIONPAGE_OLD_SIZE2 60 + DWORD mirVir = (DWORD)CallService(MS_SYSTEM_GETVERSION, 0, 0); + odp.cbSize = (mirVir >= 0x00060000 ? sizeof(odp) : OPTIONPAGE_OLD_SIZE2); + //odp.cbSize = sizeof(odp); + + odp.flags = ODPF_BOLDGROUPS; + //odp.flags |= ODPF_UNICODE; + odp.position = -790000000; + odp.hInstance = hInst; + + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_WINDOW); + odp.pszTab = Translate("Window"); + odp.pszTitle = (mirVir >= 0x00060000 ? Translate("Tooltips") : Translate("Tooltips View"));; + odp.pszGroup = Translate("Customize"); + odp.nIDBottomSimpleControl = 0; + odp.pfnDlgProc = DlgProcOptWindow; + CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp ); + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_LAYOUT); + odp.pszTab = Translate("Layout"); + odp.pszTitle = (mirVir >= 0x00060000 ? Translate("Tooltips") : Translate("Tooltips View"));; + odp.pszGroup = Translate("Customize"); + odp.nIDBottomSimpleControl = 0; + odp.pfnDlgProc = DlgProcOptLayout; + CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp ); + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_CONTENT); + odp.pszTab = Translate("Content"); + odp.pszTitle = (mirVir >= 0x00060000 ? Translate("Tooltips") : Translate("Tooltips Content"));; + odp.pszGroup = Translate("Customize"); + odp.nIDBottomSimpleControl = 0; + odp.pfnDlgProc = DlgProcOptContent; + CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp ); + + return 0; +} + +HANDLE hEventOptInit; + +void InitOptions() { + hEventOptInit = HookEvent(ME_OPT_INITIALISE, OptInit); +} + +void DeinitOptions() { + UnhookEvent(hEventOptInit); + + DIListNode *di_node = options.di_list; + while(options.di_list) { + di_node = options.di_list; + options.di_list = options.di_list->next; + free(di_node); + } + + DSListNode *ds_node = options.ds_list; + while(options.ds_list) { + ds_node = options.ds_list; + options.ds_list = options.ds_list->next; + free(ds_node); + } +} diff --git a/tipper/popwin.cpp b/tipper/popwin.cpp index e241464..5d19bde 100644 --- a/tipper/popwin.cpp +++ b/tipper/popwin.cpp @@ -1,328 +1,328 @@ -#include "common.h" -#include "subst.h" -#include "popwin.h" -#include "message_pump.h" -#include "str_utils.h" - -#define TITLE_TEXT_LEN 512 - -#define ANIM_STEPS 20 -#define ANIM_ELAPSE 10 - -#define CHECKMOUSE_ELAPSE 250 - -#define ID_TIMER_ANIMATE 0x0100 -#define ID_TIMER_CHECKMOUSE 0x0101 - -typedef struct { - TCHAR *swzLabel, *swzValue; - bool value_newline; - bool line_above; - int label_height, value_height, total_height; -} RowData; - -struct PopupWindowData { - HBRUSH bkBrush, barBrush; - HPEN bPen, dPen; - int tb_height, av_height, text_height, sm_height, lm_height, label_width; - int real_av_width, real_av_height; - //TCHAR *lm_text, *sm_text; - HANDLE hContact; - int iconIndex; - CLCINFOTIPEX clcit; - TCHAR swzTitle[TITLE_TEXT_LEN]; - RowData *rows; - int row_count; - int anim_step; - bool text_tip; - int indent, sb_width; - POINT start_cursor_pos; // work around bugs with hiding tips (timer check mouse position) - HBITMAP hBm; -}; - -LRESULT CALLBACK PopupWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - PopupWindowData *pwd = (PopupWindowData *)GetWindowLong(hwnd, GWL_USERDATA); - - switch(uMsg) { - case WM_CREATE: - { - - CREATESTRUCT *cs = (CREATESTRUCT *)lParam; - pwd = (PopupWindowData *)malloc(sizeof(PopupWindowData)); - memset(pwd, 0, sizeof(PopupWindowData)); - pwd->clcit = *(CLCINFOTIPEX *)cs->lpCreateParams; - pwd->iconIndex = -1; - pwd->bkBrush = CreateSolidBrush(options.bg_col); - pwd->barBrush = CreateSolidBrush(options.sidebar_col); - pwd->bPen = options.border ? (HPEN)CreatePen(PS_SOLID, 1, options.border_col) : (HPEN)CreatePen(PS_SOLID, 1, options.bg_col); - pwd->dPen = (HPEN)CreatePen(PS_SOLID, 1, options.div_col); - - SetWindowLong(hwnd, GWL_USERDATA, (LONG)pwd); - - // work around bug hiding tips - GetCursorPos(&pwd->start_cursor_pos); - SetTimer(hwnd, ID_TIMER_CHECKMOUSE, CHECKMOUSE_ELAPSE, 0); - - if(pwd->clcit.proto) { - pwd->text_tip = false; - pwd->indent = options.text_indent; - pwd->sb_width = options.sidebar_width; - - a2t(pwd->clcit.proto, pwd->swzTitle, TITLE_TEXT_LEN); - - TCHAR uid_buff[256], uid_name_buff[256]; - if(uid(0, pwd->clcit.proto, uid_buff, 256) && uid_name(pwd->clcit.proto, uid_name_buff, 253)) { // 253 to leave room for ': ' - _tcscat(uid_name_buff, _T(": ")); - - pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); - - pwd->rows[pwd->row_count].swzLabel = _tcsdup(uid_name_buff); - pwd->rows[pwd->row_count].swzValue = _tcsdup(uid_buff); - pwd->rows[pwd->row_count].value_newline = false; - pwd->rows[pwd->row_count].line_above = false; - pwd->row_count++; - } - - WORD status = CallProtoService(pwd->clcit.proto, PS_GETSTATUS, 0, 0); - char *strptr = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, (LPARAM)0); - if(strptr) { - TCHAR *swzText = a2t(strptr); - - pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); - - pwd->rows[pwd->row_count].swzLabel = _tcsdup(TranslateT("Status:")); - pwd->rows[pwd->row_count].swzValue = swzText; - pwd->rows[pwd->row_count].value_newline = false; - pwd->rows[pwd->row_count].line_above = false; - pwd->row_count++; - } - - if(status >= ID_STATUS_OFFLINE && status <= ID_STATUS_IDLE) { - TCHAR *swzText = 0; - char *status_msg = 0; - if(ServiceExists(MS_AWAY_GETPROTOSTATUSMESSAGET)) { - TCHAR *temp = (TCHAR *)CallService(MS_AWAY_GETPROTOSTATUSMESSAGET, (LPARAM)status, (WPARAM)pwd->clcit.proto); - swzText = _tcsdup(temp); - mir_free(temp); - } else if(ServiceExists(MS_AWAY_GETPROTOSTATUSMESSAGE)) { - status_msg = (char *)CallService(MS_AWAY_GETPROTOSTATUSMESSAGE, (LPARAM)status, (WPARAM)pwd->clcit.proto); - } else { - char svc[256]; - mir_snprintf(svc, 256, "%s%s", pwd->clcit.proto, PS_GETMYAWAYMSG); - if(ServiceExists(svc)) { - status_msg = (char *)CallService(svc, status, 0); - } else - status_msg = (char *)CallService(MS_AWAYMSG_GETSTATUSMSG, status, 0); - } - - if(status_msg && status_msg[0]) swzText = a2t(status_msg); - - if(swzText && swzText[0]) { - StripBBCodesInPlace(swzText); - pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); - - pwd->rows[pwd->row_count].swzLabel = _tcsdup(TranslateT("Status message:")); - pwd->rows[pwd->row_count].swzValue = swzText; - pwd->rows[pwd->row_count].value_newline = true; - pwd->rows[pwd->row_count].line_above = true; - pwd->row_count++; - - } - - if(status_msg) mir_free(status_msg); - } - } else if(pwd->clcit.text) { - pwd->text_tip = true; - pwd->indent = 0; - pwd->sb_width = 0; - - - //MessageBox(0, swzText, _T("tip"), MB_OK); - - TCHAR buff[2048], *swzText = pwd->clcit.text; - int buff_pos, i = 0, size = _tcslen(pwd->clcit.text); - bool top_message = false; - - while(i < size && swzText[i] != _T('<')) { - buff_pos = 0; - while(swzText[i] != _T('\n') && swzText[i] != _T('\r') && i < size && buff_pos < 2048) { - if(swzText[i] != _T('\t')) - buff[buff_pos++] = swzText[i]; - i++; - } - buff[buff_pos] = 0; - - if(buff_pos) { - pwd->rows = (RowData *)realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); - pwd->rows[pwd->row_count].line_above = false; - pwd->rows[pwd->row_count].value_newline = true; - pwd->rows[pwd->row_count].swzLabel = _tcsdup(_T("")); - pwd->rows[pwd->row_count].swzValue = _tcsdup(buff); - pwd->row_count++; - top_message = true; - } - while(i < size && (swzText[i] == _T('\n') || swzText[i] == _T('\r'))) - i++; - } - - // parse bold bits into labels and the rest into items - while(i < size) { - while(i + 2 < size - && (swzText[i] != _T('<') - || swzText[i + 1] != _T('b') - || swzText[i + 2] != _T('>'))) - { - i++; - } - - i += 3; - - buff_pos = 0; - while(i + 3 < size - && buff_pos < 2048 - && (swzText[i] != _T('<') - || swzText[i + 1] != _T('/') - || swzText[i + 2] != _T('b') - || swzText[i + 3] != _T('>'))) - { - if(swzText[i] != _T('\t')) - buff[buff_pos++] = swzText[i]; - i++; - } - - i += 4; - - buff[buff_pos] = 0; - - if(buff_pos) { - pwd->rows = (RowData *)realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); - pwd->rows[pwd->row_count].value_newline = false; - pwd->rows[pwd->row_count].swzLabel = _tcsdup(buff); - if(pwd->row_count == 1 && top_message) - pwd->rows[pwd->row_count].line_above = true; - else - pwd->rows[pwd->row_count].line_above = false; - - buff_pos = 0; - while(i < size - && buff_pos < 2048 - && swzText[i] != _T('\n')) - { - if(swzText[i] != _T('\t') && swzText[i] != _T('\r')) - buff[buff_pos++] = swzText[i]; - i++; - } - buff[buff_pos] = 0; - - pwd->rows[pwd->row_count].swzValue = _tcsdup(buff); - - pwd->row_count++; - } - - i++; - } - - if(pwd->row_count == 0) { - // single item - pwd->row_count = 1; - pwd->rows = (RowData *)malloc(sizeof(RowData)); - pwd->rows[0].line_above = pwd->rows[0].value_newline = false; - pwd->rows[0].swzLabel = 0; - pwd->rows[0].swzValue = _tcsdup(swzText); - } - - free(pwd->clcit.text); - pwd->clcit.text = 0; - } else { - pwd->text_tip = false; - pwd->indent = options.text_indent; - pwd->sb_width = options.sidebar_width; - pwd->hContact = pwd->clcit.hItem; - pwd->iconIndex = (int)CallService(MS_CLIST_GETCONTACTICON, (WPARAM)pwd->hContact, 0); - - // don't use stored status message - // problem with delete setting? - //DBDeleteContactSetting(pwd->hContact, MODULE, "TempStatusMsg"); - DBWriteContactSettingTString(pwd->hContact, MODULE, "TempStatusMsg", _T("")); - - if(unicode_system) { - TCHAR *stzCDN = (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)pwd->hContact, GCDNF_TCHAR); - - if(stzCDN) _tcsncpy(pwd->swzTitle, stzCDN, TITLE_TEXT_LEN); - else _tcscpy(pwd->swzTitle, TranslateT("(Unknown)")); - } else { - char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)pwd->hContact, 0); - - if(szCDN) a2t(szCDN, pwd->swzTitle, TITLE_TEXT_LEN); - else _tcscpy(pwd->swzTitle, TranslateT("(Unknown)")); - } - - //get avatar if possible - char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pwd->hContact, 0); - if(proto) { - char svc[256]; - mir_snprintf(svc, 256, "%s%s", proto, PS_GETAVATARINFO); - PROTO_AVATAR_INFORMATION AI = {0}; - AI.cbSize = sizeof(AI); - AI.hContact = pwd->hContact; - CallService(svc, (WPARAM)GAIF_FORCE, (LPARAM)&AI); - } - SendMessage(hwnd, PUM_REFRESH_VALUES, 0, 0); - } - } - - // transparency -#ifdef WS_EX_LAYERED - SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); -#endif - -// not defined in my mingw winuser.h -#ifdef __GNUC__ -#define CS_DROPSHADOW 0x00020000 -#endif -#ifdef CS_DROPSHADOW - if (options.drop_shadow) SetClassLong(hwnd, GCL_STYLE, CS_DROPSHADOW); - else SetClassLong(hwnd, GCL_STYLE, 0); -#endif - -#ifdef LWA_ALPHA - if(MySetLayeredWindowAttributes) { - MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (int)(options.opacity / 100.0 * 255), LWA_ALPHA); - if(options.trans_bg) { - MySetLayeredWindowAttributes(hwnd, options.bg_col, 0, LWA_COLORKEY); - } - } -#endif - SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height - SendMessage(hwnd, PUM_CALCPOS, 0, 0); - - if(options.animate) - SetTimer(hwnd, ID_TIMER_ANIMATE, ANIM_ELAPSE, 0); - - ShowWindow(hwnd, SW_SHOWNOACTIVATE); - UpdateWindow(hwnd); - /* - // move clist under? - { - HWND hwndClist = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); - if(GetWindowLong(hwndClist, GWL_EXSTYLE) & WS_EX_TOPMOST) - SetWindowPos(hwndClist, hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - } - */ - // since tipper win is topmost, this should put it at top of topmost windows - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - return 0; - case WM_ERASEBKGND: - { - HDC hdc = (HDC) wParam; - RECT r, r_bar; - GetClientRect(hwnd, &r); - - // bg - if(options.bg_fn[0]) { - BITMAP bm; - HBITMAP hBg = (HBITMAP)CallService(MS_IMG_LOAD, (WPARAM)options.bg_fn, (LPARAM)IMGL_WCHAR); - if(hBg) { +#include "common.h" +#include "subst.h" +#include "popwin.h" +#include "message_pump.h" +#include "str_utils.h" + +#define TITLE_TEXT_LEN 512 + +#define ANIM_STEPS 20 +#define ANIM_ELAPSE 10 + +#define CHECKMOUSE_ELAPSE 250 + +#define ID_TIMER_ANIMATE 0x0100 +#define ID_TIMER_CHECKMOUSE 0x0101 + +typedef struct { + TCHAR *swzLabel, *swzValue; + bool value_newline; + bool line_above; + int label_height, value_height, total_height; +} RowData; + +struct PopupWindowData { + HBRUSH bkBrush, barBrush; + HPEN bPen, dPen; + int tb_height, av_height, text_height, sm_height, lm_height, label_width; + int real_av_width, real_av_height; + //TCHAR *lm_text, *sm_text; + HANDLE hContact; + int iconIndex; + CLCINFOTIPEX clcit; + TCHAR swzTitle[TITLE_TEXT_LEN]; + RowData *rows; + int row_count; + int anim_step; + bool text_tip; + int indent, sb_width; + POINT start_cursor_pos; // work around bugs with hiding tips (timer check mouse position) + HBITMAP hBm; +}; + +LRESULT CALLBACK PopupWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + PopupWindowData *pwd = (PopupWindowData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); + + switch(uMsg) { + case WM_CREATE: + { + + CREATESTRUCT *cs = (CREATESTRUCT *)lParam; + pwd = (PopupWindowData *)malloc(sizeof(PopupWindowData)); + memset(pwd, 0, sizeof(PopupWindowData)); + pwd->clcit = *(CLCINFOTIPEX *)cs->lpCreateParams; + pwd->iconIndex = -1; + pwd->bkBrush = CreateSolidBrush(options.bg_col); + pwd->barBrush = CreateSolidBrush(options.sidebar_col); + pwd->bPen = options.border ? (HPEN)CreatePen(PS_SOLID, 1, options.border_col) : (HPEN)CreatePen(PS_SOLID, 1, options.bg_col); + pwd->dPen = (HPEN)CreatePen(PS_SOLID, 1, options.div_col); + + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pwd); + + // work around bug hiding tips + GetCursorPos(&pwd->start_cursor_pos); + SetTimer(hwnd, ID_TIMER_CHECKMOUSE, CHECKMOUSE_ELAPSE, 0); + + if(pwd->clcit.proto) { + pwd->text_tip = false; + pwd->indent = options.text_indent; + pwd->sb_width = options.sidebar_width; + + a2t(pwd->clcit.proto, pwd->swzTitle, TITLE_TEXT_LEN); + + TCHAR uid_buff[256], uid_name_buff[256]; + if(uid(0, pwd->clcit.proto, uid_buff, 256) && uid_name(pwd->clcit.proto, uid_name_buff, 253)) { // 253 to leave room for ': ' + _tcscat(uid_name_buff, _T(": ")); + + pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); + + pwd->rows[pwd->row_count].swzLabel = _tcsdup(uid_name_buff); + pwd->rows[pwd->row_count].swzValue = _tcsdup(uid_buff); + pwd->rows[pwd->row_count].value_newline = false; + pwd->rows[pwd->row_count].line_above = false; + pwd->row_count++; + } + + WORD status = CallProtoService(pwd->clcit.proto, PS_GETSTATUS, 0, 0); + char *strptr = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, (LPARAM)0); + if(strptr) { + TCHAR *swzText = a2t(strptr); + + pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); + + pwd->rows[pwd->row_count].swzLabel = _tcsdup(TranslateT("Status:")); + pwd->rows[pwd->row_count].swzValue = swzText; + pwd->rows[pwd->row_count].value_newline = false; + pwd->rows[pwd->row_count].line_above = false; + pwd->row_count++; + } + + if(status >= ID_STATUS_OFFLINE && status <= ID_STATUS_IDLE) { + TCHAR *swzText = 0; + char *status_msg = 0; + if(ServiceExists(MS_AWAY_GETPROTOSTATUSMESSAGET)) { + TCHAR *temp = (TCHAR *)CallService(MS_AWAY_GETPROTOSTATUSMESSAGET, (LPARAM)status, (WPARAM)pwd->clcit.proto); + swzText = _tcsdup(temp); + mir_free(temp); + } else if(ServiceExists(MS_AWAY_GETPROTOSTATUSMESSAGE)) { + status_msg = (char *)CallService(MS_AWAY_GETPROTOSTATUSMESSAGE, (LPARAM)status, (WPARAM)pwd->clcit.proto); + } else { + char svc[256]; + mir_snprintf(svc, 256, "%s%s", pwd->clcit.proto, PS_GETMYAWAYMSG); + if(ServiceExists(svc)) { + status_msg = (char *)CallService(svc, status, 0); + } else + status_msg = (char *)CallService(MS_AWAYMSG_GETSTATUSMSG, status, 0); + } + + if(status_msg && status_msg[0]) swzText = a2t(status_msg); + + if(swzText && swzText[0]) { + StripBBCodesInPlace(swzText); + pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); + + pwd->rows[pwd->row_count].swzLabel = _tcsdup(TranslateT("Status message:")); + pwd->rows[pwd->row_count].swzValue = swzText; + pwd->rows[pwd->row_count].value_newline = true; + pwd->rows[pwd->row_count].line_above = true; + pwd->row_count++; + + } + + if(status_msg) mir_free(status_msg); + } + } else if(pwd->clcit.text) { + pwd->text_tip = true; + pwd->indent = 0; + pwd->sb_width = 0; + + + //MessageBox(0, swzText, _T("tip"), MB_OK); + + TCHAR buff[2048], *swzText = pwd->clcit.text; + int buff_pos, i = 0, size = _tcslen(pwd->clcit.text); + bool top_message = false; + + while(i < size && swzText[i] != _T('<')) { + buff_pos = 0; + while(swzText[i] != _T('\n') && swzText[i] != _T('\r') && i < size && buff_pos < 2048) { + if(swzText[i] != _T('\t')) + buff[buff_pos++] = swzText[i]; + i++; + } + buff[buff_pos] = 0; + + if(buff_pos) { + pwd->rows = (RowData *)realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); + pwd->rows[pwd->row_count].line_above = false; + pwd->rows[pwd->row_count].value_newline = true; + pwd->rows[pwd->row_count].swzLabel = _tcsdup(_T("")); + pwd->rows[pwd->row_count].swzValue = _tcsdup(buff); + pwd->row_count++; + top_message = true; + } + while(i < size && (swzText[i] == _T('\n') || swzText[i] == _T('\r'))) + i++; + } + + // parse bold bits into labels and the rest into items + while(i < size) { + while(i + 2 < size + && (swzText[i] != _T('<') + || swzText[i + 1] != _T('b') + || swzText[i + 2] != _T('>'))) + { + i++; + } + + i += 3; + + buff_pos = 0; + while(i + 3 < size + && buff_pos < 2048 + && (swzText[i] != _T('<') + || swzText[i + 1] != _T('/') + || swzText[i + 2] != _T('b') + || swzText[i + 3] != _T('>'))) + { + if(swzText[i] != _T('\t')) + buff[buff_pos++] = swzText[i]; + i++; + } + + i += 4; + + buff[buff_pos] = 0; + + if(buff_pos) { + pwd->rows = (RowData *)realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); + pwd->rows[pwd->row_count].value_newline = false; + pwd->rows[pwd->row_count].swzLabel = _tcsdup(buff); + if(pwd->row_count == 1 && top_message) + pwd->rows[pwd->row_count].line_above = true; + else + pwd->rows[pwd->row_count].line_above = false; + + buff_pos = 0; + while(i < size + && buff_pos < 2048 + && swzText[i] != _T('\n')) + { + if(swzText[i] != _T('\t') && swzText[i] != _T('\r')) + buff[buff_pos++] = swzText[i]; + i++; + } + buff[buff_pos] = 0; + + pwd->rows[pwd->row_count].swzValue = _tcsdup(buff); + + pwd->row_count++; + } + + i++; + } + + if(pwd->row_count == 0) { + // single item + pwd->row_count = 1; + pwd->rows = (RowData *)malloc(sizeof(RowData)); + pwd->rows[0].line_above = pwd->rows[0].value_newline = false; + pwd->rows[0].swzLabel = 0; + pwd->rows[0].swzValue = _tcsdup(swzText); + } + + free(pwd->clcit.text); + pwd->clcit.text = 0; + } else { + pwd->text_tip = false; + pwd->indent = options.text_indent; + pwd->sb_width = options.sidebar_width; + pwd->hContact = pwd->clcit.hItem; + pwd->iconIndex = (int)CallService(MS_CLIST_GETCONTACTICON, (WPARAM)pwd->hContact, 0); + + // don't use stored status message + // problem with delete setting? + //DBDeleteContactSetting(pwd->hContact, MODULE, "TempStatusMsg"); + DBWriteContactSettingTString(pwd->hContact, MODULE, "TempStatusMsg", _T("")); + + if(unicode_system) { + TCHAR *stzCDN = (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)pwd->hContact, GCDNF_TCHAR); + + if(stzCDN) _tcsncpy(pwd->swzTitle, stzCDN, TITLE_TEXT_LEN); + else _tcscpy(pwd->swzTitle, TranslateT("(Unknown)")); + } else { + char *szCDN = (char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)pwd->hContact, 0); + + if(szCDN) a2t(szCDN, pwd->swzTitle, TITLE_TEXT_LEN); + else _tcscpy(pwd->swzTitle, TranslateT("(Unknown)")); + } + + //get avatar if possible + char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)pwd->hContact, 0); + if(proto) { + char svc[256]; + mir_snprintf(svc, 256, "%s%s", proto, PS_GETAVATARINFO); + PROTO_AVATAR_INFORMATION AI = {0}; + AI.cbSize = sizeof(AI); + AI.hContact = pwd->hContact; + CallService(svc, (WPARAM)GAIF_FORCE, (LPARAM)&AI); + } + SendMessage(hwnd, PUM_REFRESH_VALUES, 0, 0); + } + } + + // transparency +#ifdef WS_EX_LAYERED + SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); +#endif + +// not defined in my mingw winuser.h +#ifdef __GNUC__ +#define CS_DROPSHADOW 0x00020000 +#endif +#ifdef CS_DROPSHADOW + if (options.drop_shadow) SetClassLong(hwnd, GCL_STYLE, CS_DROPSHADOW); + else SetClassLong(hwnd, GCL_STYLE, 0); +#endif + +#ifdef LWA_ALPHA + if(MySetLayeredWindowAttributes) { + MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (int)(options.opacity / 100.0 * 255), LWA_ALPHA); + if(options.trans_bg) { + MySetLayeredWindowAttributes(hwnd, options.bg_col, 0, LWA_COLORKEY); + } + } +#endif + SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height + SendMessage(hwnd, PUM_CALCPOS, 0, 0); + + if(options.animate) + SetTimer(hwnd, ID_TIMER_ANIMATE, ANIM_ELAPSE, 0); + + ShowWindow(hwnd, SW_SHOWNOACTIVATE); + UpdateWindow(hwnd); + /* + // move clist under? + { + HWND hwndClist = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); + if(GetWindowLong(hwndClist, GWL_EXSTYLE) & WS_EX_TOPMOST) + SetWindowPos(hwndClist, hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + */ + // since tipper win is topmost, this should put it at top of topmost windows + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + return 0; + case WM_ERASEBKGND: + { + HDC hdc = (HDC) wParam; + RECT r, r_bar; + GetClientRect(hwnd, &r); + + // bg + if(options.bg_fn[0]) { + BITMAP bm; + HBITMAP hBg = (HBITMAP)CallService(MS_IMG_LOAD, (WPARAM)options.bg_fn, (LPARAM)IMGL_WCHAR); + if(hBg) { HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hBg); @@ -335,72 +335,72 @@ LRESULT CALLBACK PopupWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa } SelectObject(hdcMem, hbmOld); - DeleteDC(hdcMem); - DeleteObject(hBg); - } else - FillRect(hdc, &r, pwd->bkBrush); - } else - FillRect(hdc, &r, pwd->bkBrush); - - // sidebar - r_bar = r; - r_bar.right = r.left + pwd->sb_width; - FillRect(hdc, &r_bar, pwd->barBrush); - // border - if(options.border) { - - HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH)); - HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->bPen); - - int h = 0; - if(options.round) { - int v; - int w=14; - h=(r.right-r.left)>(w*2)?w:(r.right-r.left); - v=(r.bottom-r.top)>(w*2)?w:(r.bottom-r.top); - h=(htext_tip && options.av_layout != PAV_NONE && pwd->av_height && pwd->hBm) { - RECT avr; - avr.top = options.av_padding; - - if(options.av_layout == PAV_LEFT) { - avr.left = r.left + options.av_padding; - avr.right = avr.left + pwd->real_av_width; - r2.left += pwd->real_av_width + (2 * options.av_padding - options.padding); // padding re-added for text - } else if(options.av_layout == PAV_RIGHT) { - avr.right = r.right - options.av_padding; - avr.left = avr.right - pwd->real_av_width; - r2.right -= pwd->real_av_width + (2 * options.av_padding - options.padding); - } - - avr.bottom = avr.top + pwd->real_av_height; - + DeleteDC(hdcMem); + DeleteObject(hBg); + } else + FillRect(hdc, &r, pwd->bkBrush); + } else + FillRect(hdc, &r, pwd->bkBrush); + + // sidebar + r_bar = r; + r_bar.right = r.left + pwd->sb_width; + FillRect(hdc, &r_bar, pwd->barBrush); + // border + if(options.border) { + + HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH)); + HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->bPen); + + int h = 0; + if(options.round) { + int v; + int w=14; + h=(r.right-r.left)>(w*2)?w:(r.right-r.left); + v=(r.bottom-r.top)>(w*2)?w:(r.bottom-r.top); + h=(htext_tip && options.av_layout != PAV_NONE && pwd->av_height && pwd->hBm) { + RECT avr; + avr.top = options.av_padding; + + if(options.av_layout == PAV_LEFT) { + avr.left = r.left + options.av_padding; + avr.right = avr.left + pwd->real_av_width; + r2.left += pwd->real_av_width + (2 * options.av_padding - options.padding); // padding re-added for text + } else if(options.av_layout == PAV_RIGHT) { + avr.right = r.right - options.av_padding; + avr.left = avr.right - pwd->real_av_width; + r2.right -= pwd->real_av_width + (2 * options.av_padding - options.padding); + } + + avr.bottom = avr.top + pwd->real_av_height; + HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, pwd->hBm); BITMAP bm; @@ -425,517 +425,517 @@ LRESULT CALLBACK PopupWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa } SelectObject(hdcMem, hbmOld); - DeleteDC(hdcMem); - - /* - AVATARDRAWREQUEST adr = {0}; - adr.cbSize = sizeof(adr); - adr.hContact = pwd->hContact; - adr.hTargetDC = ps.hdc; - adr.rcDraw = avr; - adr.dwFlags = (options.av_round ? AVDRQ_ROUNDEDCORNER : 0);// | (options.no_resize_av ? AVDRQ_DONTRESIZEIFSMALLER : 0); - if(!pwd->hContact) { // status bar tip? - adr.dwFlags |= AVDRQ_OWNPIC; - adr.szProto = pwd->clcit.proto; - } - adr.radius = (options.av_round ? 5 : 0); - - CallService(MS_AV_DRAWAVATAR, 0, (LPARAM)&adr); - */ - } - - RECT tr; - tr.left = r2.left + options.padding; tr.right = r2.right - options.padding; tr.top = tr.bottom = 0; - if(!pwd->text_tip && options.title_layout != PTL_NOTITLE) { - // title icon - if(options.title_layout != PTL_NOICON) { - HICON hIcon = 0; - bool destroy_icon = true; - if(pwd->iconIndex != -1) hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), pwd->iconIndex, 0); - else if(!pwd->hContact) { - WORD status = CallProtoService(pwd->clcit.proto, PS_GETSTATUS, 0, 0); - hIcon = LoadSkinnedProtoIcon(pwd->clcit.proto, status); - destroy_icon = false; - } - if(hIcon) { - int iconx; - if(options.title_layout == PTL_RIGHTICON) { - iconx = r2.right - 16 - options.padding; - tr.right -= 16 + options.padding; - } else { - iconx = r2.left + options.padding; - tr.left += 16 + options.padding; - } - DrawIconEx(ps.hdc, iconx, options.padding + (pwd->tb_height - options.padding - 16) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL); - if(destroy_icon) DestroyIcon(hIcon); - } - } - - // title text - if(hFontTitle) SelectObject(ps.hdc, (HGDIOBJ)hFontTitle); - - SetTextColor(ps.hdc, options.title_col); - - tr.top = r.top + options.padding; tr.bottom = tr.top + pwd->tb_height - options.padding; - DrawText(ps.hdc, pwd->swzTitle, _tcslen(pwd->swzTitle), &tr, DT_VCENTER | DT_LEFT | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX); - } - - // values - pwd->text_height = 0; - bool use_r = true; - int row_height; - for(int i = 0; i < pwd->row_count; i++) { - tr.top = tr.bottom; - use_r = (tr.top + options.text_padding >= pwd->av_height); - - if(use_r) { - if(pwd->rows[i].line_above) { - HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->dPen); - tr.top += options.text_padding; - Rectangle(hdc, r.left + options.padding + pwd->indent, tr.top, r.right - options.padding, tr.top + 1); - SelectObject(hdc, hOldPen); - } - tr.left = r.left + options.padding + pwd->indent; - if(pwd->rows[i].value_newline) - tr.right = r.right - options.padding; - else - tr.right = r.left + options.padding + pwd->indent + pwd->label_width; - } else { - if(pwd->rows[i].line_above) { - HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->dPen); - tr.top += options.text_padding; - Rectangle(hdc, r2.left + options.padding + pwd->indent, tr.top, r2.right - options.padding, tr.top + 1); - SelectObject(hdc, hOldPen); - } - tr.left = r2.left + options.padding + pwd->indent; - if(pwd->rows[i].value_newline) - tr.right = r2.right - options.padding; - else - tr.right = r2.left + options.padding + pwd->indent + pwd->label_width; - } - - if(pwd->rows[i].value_newline) - row_height = pwd->rows[i].label_height; - else - row_height = max(pwd->rows[i].label_height, pwd->rows[i].value_height); - - if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels); - if(pwd->rows[i].label_height) { - tr.top += options.text_padding; - tr.bottom = tr.top + row_height; - SetTextColor(ps.hdc, options.label_col); - DrawText(ps.hdc, pwd->rows[i].swzLabel, _tcslen(pwd->rows[i].swzLabel), &tr, options.label_valign | ((options.label_halign == DT_RIGHT && !pwd->rows[i].value_newline) ? DT_RIGHT : DT_LEFT) | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX); - if(pwd->rows[i].value_newline) - tr.top = tr.bottom; - } else - tr.bottom = tr.top; - - if(pwd->rows[i].value_newline) - row_height = pwd->rows[i].value_height; - - if(hFontValues) SelectObject(hdc, (HGDIOBJ)hFontValues); - SetTextColor(ps.hdc, options.value_col); - if(use_r) { - if(pwd->rows[i].value_newline) - tr.left = r.left + options.padding + pwd->indent; - else - tr.left = r.left + options.padding + pwd->indent + pwd->label_width + options.padding; - tr.right = r.right - options.padding; - } else { - if(pwd->rows[i].value_newline) - tr.left = r2.left + options.padding + pwd->indent; - else - tr.left = r2.left + options.padding + pwd->indent + pwd->label_width + options.padding; - tr.right = r2.right - options.padding; - } - if(pwd->rows[i].value_height) { - if(pwd->rows[i].value_newline || !pwd->rows[i].label_height) tr.top += options.text_padding; - tr.bottom = tr.top + row_height; - DrawText(ps.hdc, pwd->rows[i].swzValue, _tcslen(pwd->rows[i].swzValue), &tr, options.value_valign | options.value_halign | DT_WORDBREAK | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX); - } - } - - SelectObject(hdc, hOldFont); - EndPaint(hwnd, &ps); - //} - } - return 0; - case WM_DESTROY: - { - KillTimer(hwnd, ID_TIMER_CHECKMOUSE); - KillTimer(hwnd, ID_TIMER_ANIMATE); - ShowWindow(hwnd, SW_HIDE); - - DeleteObject(pwd->bkBrush); - DeleteObject(pwd->barBrush); - DeleteObject(pwd->bPen); - DeleteObject(pwd->dPen); - - for(int i = 0; i < pwd->row_count; i++) { - free(pwd->rows[i].swzLabel); - free(pwd->rows[i].swzValue); - } - if(pwd->rows) free(pwd->rows); - - if(pwd->hBm) DeleteObject(pwd->hBm); - free(pwd); pwd = 0; - SetWindowLong(hwnd, GWL_USERDATA, 0); - } - break; - - case WM_TIMER: - if(wParam == ID_TIMER_ANIMATE) { - pwd->anim_step++; - if(pwd->anim_step == ANIM_STEPS) - KillTimer(hwnd, ID_TIMER_ANIMATE); - SendMessage(hwnd, PUM_UPDATERGN, 0, 0); - InvalidateRect(hwnd, 0, TRUE); - UpdateWindow(hwnd); - } else if(wParam == ID_TIMER_CHECKMOUSE) { - // workaround for tips that just won't go away - - POINT pt; - GetCursorPos(&pt); - - /* - // works well, except in e.g. options->events->ignore :( - bool hide = false; - if(pwd->text_tip) { - // tip may be off clist (e.g. systray) - if(pt.x != pwd->start_cursor_pos.x || pt.y != pwd->start_cursor_pos.y) // mouse has moved - hide = false; - } else { - // check window under cursor - hide if not clist - HWND hwnd_clist = (HWND)CallService(MS_CLUI_GETHWND, 0, 0), - hwnd_under = WindowFromPoint(pt); - if(hwnd_under != hwnd_clist && !IsChild(hwnd_clist, hwnd_under)) - hide = true; - } - if(hide) PostMPMessage(MUM_DELETEPOPUP, 0, 0); - */ - - if(abs(pt.x - pwd->start_cursor_pos.x) > options.mouse_tollerance - || abs(pt.y - pwd->start_cursor_pos.y) > options.mouse_tollerance) // mouse has moved beyond tollerance - { - PostMPMessage(MUM_DELETEPOPUP, 0, 0); - } - } - break; - - case PUM_SETSTATUSTEXT: - { - if(pwd && (HANDLE)wParam == pwd->hContact) { - // in case we have the status message in a row - DBWriteContactSettingTString(pwd->hContact, MODULE, "TempStatusMsg", (TCHAR*)lParam); - SendMessage(hwnd, PUM_REFRESH_VALUES, 0, 0); - } - if(lParam) free((void *)lParam); - } - return TRUE; - case PUM_SETAVATAR: - { - if(pwd && (HANDLE)wParam == pwd->hContact) { - SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height - SendMessage(hwnd, PUM_CALCPOS, 0, 0); - InvalidateRect(hwnd, 0, TRUE); - } - } - return TRUE; - case PUM_REFRESH_VALUES: - if(pwd && pwd->clcit.proto == 0 && pwd->text_tip == false) { - for(int i = 0; i < pwd->row_count; i++) { - free(pwd->rows[i].swzLabel); - free(pwd->rows[i].swzValue); - } - if(pwd->rows) { - free(pwd->rows); - pwd->rows = 0; - } - pwd->row_count = 0; - - DIListNode *node = options.di_list; - TCHAR buff_label[LABEL_LEN], buff[VALUE_LEN]; - while(node) { - if(GetLabelText(pwd->hContact, node->di, buff_label, LABEL_LEN) && GetValueText(pwd->hContact, node->di, buff, VALUE_LEN)) { - if(node->di.line_above // we have a line above - && pwd->row_count > 0 // and we're not the first row - && pwd->rows[pwd->row_count - 1].line_above // and above us there's a line above - && pwd->rows[pwd->row_count - 1].swzLabel[0] == 0 // with no label - && pwd->rows[pwd->row_count - 1].swzValue[0] == 0) // and no value - { - // overwrite item above - pwd->row_count--; - free(pwd->rows[pwd->row_count].swzLabel); - free(pwd->rows[pwd->row_count].swzValue); - } else - pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); - - pwd->rows[pwd->row_count].swzLabel = _tcsdup(buff_label); - pwd->rows[pwd->row_count].swzValue = _tcsdup(buff); - pwd->rows[pwd->row_count].value_newline = node->di.value_newline; - pwd->rows[pwd->row_count].line_above = node->di.line_above; - pwd->row_count++; - } - node = node->next; - } - - // if the last item is just a divider, remove it - if(pwd->row_count > 0 - && pwd->rows[pwd->row_count - 1].line_above // and above us there's a line above - && pwd->rows[pwd->row_count - 1].swzLabel[0] == 0 // with no label - && pwd->rows[pwd->row_count - 1].swzValue[0] == 0) // and no value - { - pwd->row_count--; - free(pwd->rows[pwd->row_count].swzLabel); - free(pwd->rows[pwd->row_count].swzValue); - - if(pwd->row_count == 0) { - free(pwd->rows); - pwd->rows = NULL; - } - } - - SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height - SendMessage(hwnd, PUM_CALCPOS, 0, 0); - InvalidateRect(hwnd, 0, TRUE); - } - return TRUE; - case PUM_GETHEIGHT: - { - int *pHeight = (int *)wParam; - HDC hdc = GetDC(hwnd); - SIZE size; - RECT r; - r.top = r.left = 0; - r.right = options.win_width; - int width = options.padding; - HFONT hOldFont = (HFONT)GetCurrentObject(hdc,OBJ_FONT); - - // titlebar height - if(!pwd->text_tip && pwd->swzTitle && options.title_layout != PTL_NOTITLE) { - if(hFontTitle) SelectObject(hdc, (HGDIOBJ)hFontTitle); - GetTextExtentPoint32(hdc, pwd->swzTitle, _tcslen(pwd->swzTitle), &size); - width += options.padding + size.cx; - if(options.title_layout != PTL_NOICON) { - pwd->tb_height = options.padding + max(size.cy, 16); - width += 16 + options.padding; - } else - pwd->tb_height = options.padding + size.cy; - } else - pwd->tb_height = 0; - - // avatar height - pwd->av_height = 0; - if(!pwd->text_tip && options.av_layout != PAV_NONE && ServiceExists(MS_AV_DRAWAVATAR)) { - AVATARCACHEENTRY *ace = 0; - if(pwd->hContact) ace = (AVATARCACHEENTRY *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)pwd->hContact, 0); - else ace = (AVATARCACHEENTRY *)CallService(MS_AV_GETMYAVATAR, 0, (LPARAM)pwd->clcit.proto); - - if(ace && (ace->dwFlags & AVS_BITMAP_VALID) && !(ace->dwFlags & AVS_HIDEONCLIST)) { - if(pwd->hBm) DeleteObject(pwd->hBm); - pwd->hBm = (HBITMAP)CallService(MS_UTILS_LOADBITMAP,0,(LPARAM)ace->szFilename); - BITMAP bm; - GetObject(pwd->hBm, sizeof(bm), &bm); - if(options.no_resize_av || (bm.bmHeight <= options.av_size && bm.bmWidth <= options.av_size)) { - pwd->real_av_width = bm.bmWidth; - pwd->real_av_height = bm.bmHeight; - } else { - if(bm.bmHeight >= bm.bmWidth) { - pwd->real_av_height = options.av_size; - pwd->real_av_width = (int)(options.av_size * (bm.bmWidth / (double)bm.bmHeight)); - } else { - pwd->real_av_height = (int)(options.av_size * (bm.bmHeight / (double)bm.bmWidth)); - pwd->real_av_width = options.av_size; - } - } - pwd->av_height = options.av_padding * 2 + pwd->real_av_height; - width += pwd->real_av_width + (2 * options.av_padding - options.padding); - } - } - - int i; - // text height - pwd->text_height = pwd->label_width = 0; - // iterate once to find max label width for items with label and value on same line, but don't consider width of labels on a new line - for(i = 0; i < pwd->row_count; i++) { - if(pwd->rows[i].swzLabel && pwd->rows[i].value_newline == false) { - if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels); - GetTextExtentPoint32(hdc, pwd->rows[i].swzLabel, _tcslen(pwd->rows[i].swzLabel), &size); - if(size.cx > pwd->label_width) - pwd->label_width = size.cx; - } - } - - for(i = 0; i < pwd->row_count; i++) { - if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels); - if(pwd->rows[i].swzLabel) - GetTextExtentPoint32(hdc, pwd->rows[i].swzLabel, _tcslen(pwd->rows[i].swzLabel), &size); - else - size.cy = size.cx = 0; - - // save so we don't have to recalculate - pwd->rows[i].label_height = size.cy; - - if(hFontValues) SelectObject(hdc, (HGDIOBJ)hFontValues); - RECT smr; - smr.top = smr.bottom = 0; - smr.left = r.left + options.padding + pwd->indent; - smr.right = r.right; - if(pwd->tb_height + pwd->text_height + options.text_padding < pwd->av_height) - smr.right -= pwd->real_av_width + 2 * options.av_padding; - else - smr.right -= options.padding; - if(!pwd->rows[i].value_newline) smr.right -= pwd->label_width + options.padding; - if(pwd->rows[i].swzValue) - DrawText(hdc, pwd->rows[i].swzValue, _tcslen(pwd->rows[i].swzValue), &smr, DT_CALCRECT | DT_VCENTER | DT_LEFT | DT_WORDBREAK | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX); - - // save so we don't have to recalculate - pwd->rows[i].value_height = smr.bottom; - - pwd->rows[i].total_height = (pwd->rows[i].line_above ? options.text_padding : 0); - if(pwd->rows[i].value_newline) { - if(size.cy) pwd->rows[i].total_height += size.cy + options.text_padding; - if(smr.bottom) pwd->rows[i].total_height += smr.bottom + options.text_padding; - } else { - int maxheight = max(size.cy, smr.bottom); - if(maxheight) pwd->rows[i].total_height += maxheight + options.text_padding; - } - - // only consider this item's width, and include it's height, if it doesn't make the window too big - if(max(pwd->tb_height + pwd->text_height + options.padding + pwd->rows[i].total_height, pwd->av_height) <= options.win_max_height) { - if(width < options.win_width) { - int wid = options.padding + pwd->indent + (pwd->rows[i].value_newline ? max(size.cx, smr.right - smr.left) : pwd->label_width + options.padding + (smr.right - smr.left)); - if(pwd->tb_height + pwd->text_height + options.text_padding < pwd->av_height) - width = max(width, wid + pwd->real_av_width + 2 * options.av_padding); - else - width = max(width, wid + options.padding); - } - - pwd->text_height += pwd->rows[i].total_height; - } - } - - SelectObject(hdc, hOldFont); - ReleaseDC(hwnd, hdc); - - int height = max(pwd->tb_height + pwd->text_height + options.padding, pwd->av_height); - - if(height < options.min_height) height = options.min_height; - // ignore minwidth for text tips - if((!pwd->text_tip) && width < options.min_width) width = options.min_width; - - if(height > options.win_max_height) height = options.win_max_height; - if(width > options.win_width) width = options.win_width; - - GetWindowRect(hwnd, &r); - if(r.right - r.left != width || r.bottom - r.top != height) { - - SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); - SendMessage(hwnd, PUM_UPDATERGN, 0, 0); - - InvalidateRect(hwnd, 0, TRUE); - } - - if(pHeight) *pHeight = height; - } - return TRUE; - case PUM_UPDATERGN: - { - HRGN hRgn1; - RECT r; - - int v,h; - int w=11; - GetWindowRect(hwnd,&r); - r.right -= r.left; - r.left = 0; - r.bottom -= r.top; - r.top = 0; - - if(options.animate && pwd->anim_step < ANIM_STEPS) { - float frac = 1.0f - pwd->anim_step / (float)ANIM_STEPS; - int wi = r.right, hi = r.bottom; - - r.left += (int)(wi / 2.0f * frac + 0.5f); - r.right -= (int)(wi / 2.0f * frac + 0.5f); - r.top += (int)(hi / 2.0f * frac + 0.5f); - r.bottom -= (int)(hi / 2.0f * frac + 0.5f); - } - - // round corners - if(options.round) { - h=(r.right-r.left)>(w*2)?w:(r.right-r.left); - v=(r.bottom-r.top)>(w*2)?w:(r.bottom-r.top); - h=(hclcit.ptCursor, MONITOR_DEFAULTTONEAREST); - - MONITORINFO mi; - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); - - wa_rect = mi.rcWork; - - GetWindowRect(hwnd, &r); - - CURSORINFO ci = {sizeof(CURSORINFO)}; - GetCursorInfo(&ci); - - - - int x = 0, y = 0, width = (r.right - r.left), height = (r.bottom - r.top); - - switch(options.pos) { - case PP_BOTTOMRIGHT: - x = pwd->clcit.ptCursor.x + GetSystemMetrics(SM_CXSMICON); // cursor size is too large - use small icon size - y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON); - break; - case PP_BOTTOMLEFT: - x = pwd->clcit.ptCursor.x - width - GetSystemMetrics(SM_CXSMICON); - y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON); - break; - case PP_TOPRIGHT: - x = pwd->clcit.ptCursor.x + GetSystemMetrics(SM_CXSMICON); - y = pwd->clcit.ptCursor.y - height - GetSystemMetrics(SM_CYSMICON); - break; - case PP_TOPLEFT: - x = pwd->clcit.ptCursor.x - width - GetSystemMetrics(SM_CXSMICON); - y = pwd->clcit.ptCursor.y - height - GetSystemMetrics(SM_CYSMICON); - break; - } - - if(x + width + 8 > wa_rect.right) - x = wa_rect.right - width - 8; - if(y + height > wa_rect.bottom) - y = pwd->clcit.ptCursor.y - height - 8; - if(x - 8 < wa_rect.left) - x = wa_rect.left + 8; - if(y - 8 < wa_rect.top) - y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON); - - SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); - } - return TRUE; - } - - - return DefWindowProc(hwnd, uMsg, wParam, lParam); -} - -int AvatarChanged(WPARAM wParam, LPARAM lParam) { - HANDLE hContact = (HANDLE)wParam; - PostMPMessage(MUM_GOTAVATAR, (WPARAM)hContact, 0); - return 0; -} - - + DeleteDC(hdcMem); + + /* + AVATARDRAWREQUEST adr = {0}; + adr.cbSize = sizeof(adr); + adr.hContact = pwd->hContact; + adr.hTargetDC = ps.hdc; + adr.rcDraw = avr; + adr.dwFlags = (options.av_round ? AVDRQ_ROUNDEDCORNER : 0);// | (options.no_resize_av ? AVDRQ_DONTRESIZEIFSMALLER : 0); + if(!pwd->hContact) { // status bar tip? + adr.dwFlags |= AVDRQ_OWNPIC; + adr.szProto = pwd->clcit.proto; + } + adr.radius = (options.av_round ? 5 : 0); + + CallService(MS_AV_DRAWAVATAR, 0, (LPARAM)&adr); + */ + } + + RECT tr; + tr.left = r2.left + options.padding; tr.right = r2.right - options.padding; tr.top = tr.bottom = 0; + if(!pwd->text_tip && options.title_layout != PTL_NOTITLE) { + // title icon + if(options.title_layout != PTL_NOICON) { + HICON hIcon = 0; + bool destroy_icon = true; + if(pwd->iconIndex != -1) hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), pwd->iconIndex, 0); + else if(!pwd->hContact) { + WORD status = CallProtoService(pwd->clcit.proto, PS_GETSTATUS, 0, 0); + hIcon = LoadSkinnedProtoIcon(pwd->clcit.proto, status); + destroy_icon = false; + } + if(hIcon) { + int iconx; + if(options.title_layout == PTL_RIGHTICON) { + iconx = r2.right - 16 - options.padding; + tr.right -= 16 + options.padding; + } else { + iconx = r2.left + options.padding; + tr.left += 16 + options.padding; + } + DrawIconEx(ps.hdc, iconx, options.padding + (pwd->tb_height - options.padding - 16) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL); + if(destroy_icon) DestroyIcon(hIcon); + } + } + + // title text + if(hFontTitle) SelectObject(ps.hdc, (HGDIOBJ)hFontTitle); + + SetTextColor(ps.hdc, options.title_col); + + tr.top = r.top + options.padding; tr.bottom = tr.top + pwd->tb_height - options.padding; + DrawText(ps.hdc, pwd->swzTitle, _tcslen(pwd->swzTitle), &tr, DT_VCENTER | DT_LEFT | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX); + } + + // values + pwd->text_height = 0; + bool use_r = true; + int row_height; + for(int i = 0; i < pwd->row_count; i++) { + tr.top = tr.bottom; + use_r = (tr.top + options.text_padding >= pwd->av_height); + + if(use_r) { + if(pwd->rows[i].line_above) { + HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->dPen); + tr.top += options.text_padding; + Rectangle(hdc, r.left + options.padding + pwd->indent, tr.top, r.right - options.padding, tr.top + 1); + SelectObject(hdc, hOldPen); + } + tr.left = r.left + options.padding + pwd->indent; + if(pwd->rows[i].value_newline) + tr.right = r.right - options.padding; + else + tr.right = r.left + options.padding + pwd->indent + pwd->label_width; + } else { + if(pwd->rows[i].line_above) { + HPEN hOldPen = (HPEN)SelectObject(hdc, pwd->dPen); + tr.top += options.text_padding; + Rectangle(hdc, r2.left + options.padding + pwd->indent, tr.top, r2.right - options.padding, tr.top + 1); + SelectObject(hdc, hOldPen); + } + tr.left = r2.left + options.padding + pwd->indent; + if(pwd->rows[i].value_newline) + tr.right = r2.right - options.padding; + else + tr.right = r2.left + options.padding + pwd->indent + pwd->label_width; + } + + if(pwd->rows[i].value_newline) + row_height = pwd->rows[i].label_height; + else + row_height = max(pwd->rows[i].label_height, pwd->rows[i].value_height); + + if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels); + if(pwd->rows[i].label_height) { + tr.top += options.text_padding; + tr.bottom = tr.top + row_height; + SetTextColor(ps.hdc, options.label_col); + DrawText(ps.hdc, pwd->rows[i].swzLabel, _tcslen(pwd->rows[i].swzLabel), &tr, options.label_valign | ((options.label_halign == DT_RIGHT && !pwd->rows[i].value_newline) ? DT_RIGHT : DT_LEFT) | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX); + if(pwd->rows[i].value_newline) + tr.top = tr.bottom; + } else + tr.bottom = tr.top; + + if(pwd->rows[i].value_newline) + row_height = pwd->rows[i].value_height; + + if(hFontValues) SelectObject(hdc, (HGDIOBJ)hFontValues); + SetTextColor(ps.hdc, options.value_col); + if(use_r) { + if(pwd->rows[i].value_newline) + tr.left = r.left + options.padding + pwd->indent; + else + tr.left = r.left + options.padding + pwd->indent + pwd->label_width + options.padding; + tr.right = r.right - options.padding; + } else { + if(pwd->rows[i].value_newline) + tr.left = r2.left + options.padding + pwd->indent; + else + tr.left = r2.left + options.padding + pwd->indent + pwd->label_width + options.padding; + tr.right = r2.right - options.padding; + } + if(pwd->rows[i].value_height) { + if(pwd->rows[i].value_newline || !pwd->rows[i].label_height) tr.top += options.text_padding; + tr.bottom = tr.top + row_height; + DrawText(ps.hdc, pwd->rows[i].swzValue, _tcslen(pwd->rows[i].swzValue), &tr, options.value_valign | options.value_halign | DT_WORDBREAK | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX); + } + } + + SelectObject(hdc, hOldFont); + EndPaint(hwnd, &ps); + //} + } + return 0; + case WM_DESTROY: + { + KillTimer(hwnd, ID_TIMER_CHECKMOUSE); + KillTimer(hwnd, ID_TIMER_ANIMATE); + ShowWindow(hwnd, SW_HIDE); + + DeleteObject(pwd->bkBrush); + DeleteObject(pwd->barBrush); + DeleteObject(pwd->bPen); + DeleteObject(pwd->dPen); + + for(int i = 0; i < pwd->row_count; i++) { + free(pwd->rows[i].swzLabel); + free(pwd->rows[i].swzValue); + } + if(pwd->rows) free(pwd->rows); + + if(pwd->hBm) DeleteObject(pwd->hBm); + free(pwd); pwd = 0; + SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + } + break; + + case WM_TIMER: + if(wParam == ID_TIMER_ANIMATE) { + pwd->anim_step++; + if(pwd->anim_step == ANIM_STEPS) + KillTimer(hwnd, ID_TIMER_ANIMATE); + SendMessage(hwnd, PUM_UPDATERGN, 0, 0); + InvalidateRect(hwnd, 0, TRUE); + UpdateWindow(hwnd); + } else if(wParam == ID_TIMER_CHECKMOUSE) { + // workaround for tips that just won't go away + + POINT pt; + GetCursorPos(&pt); + + /* + // works well, except in e.g. options->events->ignore :( + bool hide = false; + if(pwd->text_tip) { + // tip may be off clist (e.g. systray) + if(pt.x != pwd->start_cursor_pos.x || pt.y != pwd->start_cursor_pos.y) // mouse has moved + hide = false; + } else { + // check window under cursor - hide if not clist + HWND hwnd_clist = (HWND)CallService(MS_CLUI_GETHWND, 0, 0), + hwnd_under = WindowFromPoint(pt); + if(hwnd_under != hwnd_clist && !IsChild(hwnd_clist, hwnd_under)) + hide = true; + } + if(hide) PostMPMessage(MUM_DELETEPOPUP, 0, 0); + */ + + if(abs(pt.x - pwd->start_cursor_pos.x) > options.mouse_tollerance + || abs(pt.y - pwd->start_cursor_pos.y) > options.mouse_tollerance) // mouse has moved beyond tollerance + { + PostMPMessage(MUM_DELETEPOPUP, 0, 0); + } + } + break; + + case PUM_SETSTATUSTEXT: + { + if(pwd && (HANDLE)wParam == pwd->hContact) { + // in case we have the status message in a row + DBWriteContactSettingTString(pwd->hContact, MODULE, "TempStatusMsg", (TCHAR*)lParam); + SendMessage(hwnd, PUM_REFRESH_VALUES, 0, 0); + } + if(lParam) free((void *)lParam); + } + return TRUE; + case PUM_SETAVATAR: + { + if(pwd && (HANDLE)wParam == pwd->hContact) { + SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height + SendMessage(hwnd, PUM_CALCPOS, 0, 0); + InvalidateRect(hwnd, 0, TRUE); + } + } + return TRUE; + case PUM_REFRESH_VALUES: + if(pwd && pwd->clcit.proto == 0 && pwd->text_tip == false) { + for(int i = 0; i < pwd->row_count; i++) { + free(pwd->rows[i].swzLabel); + free(pwd->rows[i].swzValue); + } + if(pwd->rows) { + free(pwd->rows); + pwd->rows = 0; + } + pwd->row_count = 0; + + DIListNode *node = options.di_list; + TCHAR buff_label[LABEL_LEN], buff[VALUE_LEN]; + while(node) { + if(GetLabelText(pwd->hContact, node->di, buff_label, LABEL_LEN) && GetValueText(pwd->hContact, node->di, buff, VALUE_LEN)) { + if(node->di.line_above // we have a line above + && pwd->row_count > 0 // and we're not the first row + && pwd->rows[pwd->row_count - 1].line_above // and above us there's a line above + && pwd->rows[pwd->row_count - 1].swzLabel[0] == 0 // with no label + && pwd->rows[pwd->row_count - 1].swzValue[0] == 0) // and no value + { + // overwrite item above + pwd->row_count--; + free(pwd->rows[pwd->row_count].swzLabel); + free(pwd->rows[pwd->row_count].swzValue); + } else + pwd->rows = (RowData *) realloc(pwd->rows, sizeof(RowData) * (pwd->row_count + 1)); + + pwd->rows[pwd->row_count].swzLabel = _tcsdup(buff_label); + pwd->rows[pwd->row_count].swzValue = _tcsdup(buff); + pwd->rows[pwd->row_count].value_newline = node->di.value_newline; + pwd->rows[pwd->row_count].line_above = node->di.line_above; + pwd->row_count++; + } + node = node->next; + } + + // if the last item is just a divider, remove it + if(pwd->row_count > 0 + && pwd->rows[pwd->row_count - 1].line_above // and above us there's a line above + && pwd->rows[pwd->row_count - 1].swzLabel[0] == 0 // with no label + && pwd->rows[pwd->row_count - 1].swzValue[0] == 0) // and no value + { + pwd->row_count--; + free(pwd->rows[pwd->row_count].swzLabel); + free(pwd->rows[pwd->row_count].swzValue); + + if(pwd->row_count == 0) { + free(pwd->rows); + pwd->rows = NULL; + } + } + + SendMessage(hwnd, PUM_GETHEIGHT, 0, 0); // calculate window height + SendMessage(hwnd, PUM_CALCPOS, 0, 0); + InvalidateRect(hwnd, 0, TRUE); + } + return TRUE; + case PUM_GETHEIGHT: + { + int *pHeight = (int *)wParam; + HDC hdc = GetDC(hwnd); + SIZE size; + RECT r; + r.top = r.left = 0; + r.right = options.win_width; + int width = options.padding; + HFONT hOldFont = (HFONT)GetCurrentObject(hdc,OBJ_FONT); + + // titlebar height + if(!pwd->text_tip && pwd->swzTitle && options.title_layout != PTL_NOTITLE) { + if(hFontTitle) SelectObject(hdc, (HGDIOBJ)hFontTitle); + GetTextExtentPoint32(hdc, pwd->swzTitle, _tcslen(pwd->swzTitle), &size); + width += options.padding + size.cx; + if(options.title_layout != PTL_NOICON) { + pwd->tb_height = options.padding + max(size.cy, 16); + width += 16 + options.padding; + } else + pwd->tb_height = options.padding + size.cy; + } else + pwd->tb_height = 0; + + // avatar height + pwd->av_height = 0; + if(!pwd->text_tip && options.av_layout != PAV_NONE && ServiceExists(MS_AV_DRAWAVATAR)) { + AVATARCACHEENTRY *ace = 0; + if(pwd->hContact) ace = (AVATARCACHEENTRY *)CallService(MS_AV_GETAVATARBITMAP, (WPARAM)pwd->hContact, 0); + else ace = (AVATARCACHEENTRY *)CallService(MS_AV_GETMYAVATAR, 0, (LPARAM)pwd->clcit.proto); + + if(ace && (ace->dwFlags & AVS_BITMAP_VALID) && !(ace->dwFlags & AVS_HIDEONCLIST)) { + if(pwd->hBm) DeleteObject(pwd->hBm); + pwd->hBm = (HBITMAP)CallService(MS_UTILS_LOADBITMAP,0,(LPARAM)ace->szFilename); + BITMAP bm; + GetObject(pwd->hBm, sizeof(bm), &bm); + if(options.no_resize_av || (bm.bmHeight <= options.av_size && bm.bmWidth <= options.av_size)) { + pwd->real_av_width = bm.bmWidth; + pwd->real_av_height = bm.bmHeight; + } else { + if(bm.bmHeight >= bm.bmWidth) { + pwd->real_av_height = options.av_size; + pwd->real_av_width = (int)(options.av_size * (bm.bmWidth / (double)bm.bmHeight)); + } else { + pwd->real_av_height = (int)(options.av_size * (bm.bmHeight / (double)bm.bmWidth)); + pwd->real_av_width = options.av_size; + } + } + pwd->av_height = options.av_padding * 2 + pwd->real_av_height; + width += pwd->real_av_width + (2 * options.av_padding - options.padding); + } + } + + int i; + // text height + pwd->text_height = pwd->label_width = 0; + // iterate once to find max label width for items with label and value on same line, but don't consider width of labels on a new line + for(i = 0; i < pwd->row_count; i++) { + if(pwd->rows[i].swzLabel && pwd->rows[i].value_newline == false) { + if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels); + GetTextExtentPoint32(hdc, pwd->rows[i].swzLabel, _tcslen(pwd->rows[i].swzLabel), &size); + if(size.cx > pwd->label_width) + pwd->label_width = size.cx; + } + } + + for(i = 0; i < pwd->row_count; i++) { + if(hFontLabels) SelectObject(hdc, (HGDIOBJ)hFontLabels); + if(pwd->rows[i].swzLabel) + GetTextExtentPoint32(hdc, pwd->rows[i].swzLabel, _tcslen(pwd->rows[i].swzLabel), &size); + else + size.cy = size.cx = 0; + + // save so we don't have to recalculate + pwd->rows[i].label_height = size.cy; + + if(hFontValues) SelectObject(hdc, (HGDIOBJ)hFontValues); + RECT smr; + smr.top = smr.bottom = 0; + smr.left = r.left + options.padding + pwd->indent; + smr.right = r.right; + if(pwd->tb_height + pwd->text_height + options.text_padding < pwd->av_height) + smr.right -= pwd->real_av_width + 2 * options.av_padding; + else + smr.right -= options.padding; + if(!pwd->rows[i].value_newline) smr.right -= pwd->label_width + options.padding; + if(pwd->rows[i].swzValue) + DrawText(hdc, pwd->rows[i].swzValue, _tcslen(pwd->rows[i].swzValue), &smr, DT_CALCRECT | DT_VCENTER | DT_LEFT | DT_WORDBREAK | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX); + + // save so we don't have to recalculate + pwd->rows[i].value_height = smr.bottom; + + pwd->rows[i].total_height = (pwd->rows[i].line_above ? options.text_padding : 0); + if(pwd->rows[i].value_newline) { + if(size.cy) pwd->rows[i].total_height += size.cy + options.text_padding; + if(smr.bottom) pwd->rows[i].total_height += smr.bottom + options.text_padding; + } else { + int maxheight = max(size.cy, smr.bottom); + if(maxheight) pwd->rows[i].total_height += maxheight + options.text_padding; + } + + // only consider this item's width, and include it's height, if it doesn't make the window too big + if(max(pwd->tb_height + pwd->text_height + options.padding + pwd->rows[i].total_height, pwd->av_height) <= options.win_max_height) { + if(width < options.win_width) { + int wid = options.padding + pwd->indent + (pwd->rows[i].value_newline ? max(size.cx, smr.right - smr.left) : pwd->label_width + options.padding + (smr.right - smr.left)); + if(pwd->tb_height + pwd->text_height + options.text_padding < pwd->av_height) + width = max(width, wid + pwd->real_av_width + 2 * options.av_padding); + else + width = max(width, wid + options.padding); + } + + pwd->text_height += pwd->rows[i].total_height; + } + } + + SelectObject(hdc, hOldFont); + ReleaseDC(hwnd, hdc); + + int height = max(pwd->tb_height + pwd->text_height + options.padding, pwd->av_height); + + if(height < options.min_height) height = options.min_height; + // ignore minwidth for text tips + if((!pwd->text_tip) && width < options.min_width) width = options.min_width; + + if(height > options.win_max_height) height = options.win_max_height; + if(width > options.win_width) width = options.win_width; + + GetWindowRect(hwnd, &r); + if(r.right - r.left != width || r.bottom - r.top != height) { + + SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + SendMessage(hwnd, PUM_UPDATERGN, 0, 0); + + InvalidateRect(hwnd, 0, TRUE); + } + + if(pHeight) *pHeight = height; + } + return TRUE; + case PUM_UPDATERGN: + { + HRGN hRgn1; + RECT r; + + int v,h; + int w=11; + GetWindowRect(hwnd,&r); + r.right -= r.left; + r.left = 0; + r.bottom -= r.top; + r.top = 0; + + if(options.animate && pwd->anim_step < ANIM_STEPS) { + float frac = 1.0f - pwd->anim_step / (float)ANIM_STEPS; + int wi = r.right, hi = r.bottom; + + r.left += (int)(wi / 2.0f * frac + 0.5f); + r.right -= (int)(wi / 2.0f * frac + 0.5f); + r.top += (int)(hi / 2.0f * frac + 0.5f); + r.bottom -= (int)(hi / 2.0f * frac + 0.5f); + } + + // round corners + if(options.round) { + h=(r.right-r.left)>(w*2)?w:(r.right-r.left); + v=(r.bottom-r.top)>(w*2)?w:(r.bottom-r.top); + h=(hclcit.ptCursor, MONITOR_DEFAULTTONEAREST); + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + + wa_rect = mi.rcWork; + + GetWindowRect(hwnd, &r); + + CURSORINFO ci = {sizeof(CURSORINFO)}; + GetCursorInfo(&ci); + + + + int x = 0, y = 0, width = (r.right - r.left), height = (r.bottom - r.top); + + switch(options.pos) { + case PP_BOTTOMRIGHT: + x = pwd->clcit.ptCursor.x + GetSystemMetrics(SM_CXSMICON); // cursor size is too large - use small icon size + y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON); + break; + case PP_BOTTOMLEFT: + x = pwd->clcit.ptCursor.x - width - GetSystemMetrics(SM_CXSMICON); + y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON); + break; + case PP_TOPRIGHT: + x = pwd->clcit.ptCursor.x + GetSystemMetrics(SM_CXSMICON); + y = pwd->clcit.ptCursor.y - height - GetSystemMetrics(SM_CYSMICON); + break; + case PP_TOPLEFT: + x = pwd->clcit.ptCursor.x - width - GetSystemMetrics(SM_CXSMICON); + y = pwd->clcit.ptCursor.y - height - GetSystemMetrics(SM_CYSMICON); + break; + } + + if(x + width + 8 > wa_rect.right) + x = wa_rect.right - width - 8; + if(y + height > wa_rect.bottom) + y = pwd->clcit.ptCursor.y - height - 8; + if(x - 8 < wa_rect.left) + x = wa_rect.left + 8; + if(y - 8 < wa_rect.top) + y = pwd->clcit.ptCursor.y + GetSystemMetrics(SM_CYSMICON); + + SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + } + return TRUE; + } + + + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +int AvatarChanged(WPARAM wParam, LPARAM lParam) { + HANDLE hContact = (HANDLE)wParam; + PostMPMessage(MUM_GOTAVATAR, (WPARAM)hContact, 0); + return 0; +} + + diff --git a/tipper/tipper.cpp b/tipper/tipper.cpp index b12fd4a..15acb3d 100644 --- a/tipper/tipper.cpp +++ b/tipper/tipper.cpp @@ -359,8 +359,8 @@ int ModulesLoaded(WPARAM wParam, LPARAM lParam) { hAvChangeEvent = HookEvent(ME_AV_AVATARCHANGED, AvatarChanged); hAvContactChangeEvent = HookEvent(ME_AV_CONTACTAVATARCHANGED, AvatarChanged); - hShowTipEvent = HookEvent(ME_CLC_SHOWINFOTIP, ShowTip); - hHideTipEvent = HookEvent(ME_CLC_HIDEINFOTIP, HideTip); + hShowTipEvent = HookEvent(ME_CLC_SHOWINFOTIP, ShowTipHook); + hHideTipEvent = HookEvent(ME_CLC_HIDEINFOTIP, HideTipHook); hAckEvent = HookEvent(ME_PROTO_ACK, ProtoAck); hFramesSBShow = HookEvent(ME_CLIST_FRAMES_SB_SHOW_TOOLTIP, FramesShowSBTip); diff --git a/tipper/tipper.dsp b/tipper/tipper.dsp index 871236b..007b117 100644 --- a/tipper/tipper.dsp +++ b/tipper/tipper.dsp @@ -101,7 +101,7 @@ LINK32=link.exe # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /Zi /O1 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NO_GZIP" /D "PNG_NO_STDIO" /D "PNG_NO_CONSOLE_IO" /FD /c # SUBTRACT BASE CPP /YX -# ADD CPP /nologo /MD /W3 /GX /Zi /O1 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /Yu"common.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /Zi /O1 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /Yu"common.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -130,7 +130,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NO_GZIP" /D "PNG_NO_STDIO" /D "PNG_NO_CONSOLE_IO" /FR /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR /Yu"common.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "TIPPER_EXPORTS" /FR /Yu"common.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" diff --git a/tipper/tipper_8.vcproj b/tipper/tipper_8.vcproj index 4b62963..a323ea0 100644 --- a/tipper/tipper_8.vcproj +++ b/tipper/tipper_8.vcproj @@ -121,7 +121,7 @@ Name="VCCLCompilerTool" Optimization="1" FavorSizeOrSpeed="2" - AdditionalIncludeDirectories="../../include" + AdditionalIncludeDirectories="../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1" RuntimeLibrary="0" UsePrecompiledHeader="2" diff --git a/tipper/tipper_9.sln b/tipper/tipper_9.sln new file mode 100644 index 0000000..6a4b68c --- /dev/null +++ b/tipper/tipper_9.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tipper", "tipper_9.vcproj", "{2C818919-A38F-44FF-BD91-A6A204AC592A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug Unicode|Win32 = Debug Unicode|Win32 + Debug Unicode|x64 = Debug Unicode|x64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release Unicode|Win32 = Release Unicode|Win32 + Release Unicode|x64 = Release Unicode|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug Unicode|x64.ActiveCfg = Debug Unicode|x64 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug Unicode|x64.Build.0 = Debug Unicode|x64 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug|Win32.ActiveCfg = Debug|Win32 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug|Win32.Build.0 = Debug|Win32 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug|x64.ActiveCfg = Debug|x64 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Debug|x64.Build.0 = Debug|x64 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release Unicode|Win32.Build.0 = Release Unicode|Win32 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release Unicode|x64.ActiveCfg = Release Unicode|x64 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release Unicode|x64.Build.0 = Release Unicode|x64 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release|Win32.ActiveCfg = Release|Win32 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release|Win32.Build.0 = Release|Win32 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release|x64.ActiveCfg = Release|x64 + {2C818919-A38F-44FF-BD91-A6A204AC592A}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tipper/tipper_9.vcproj b/tipper/tipper_9.vcproj index f92e908..7b2ade7 100644 --- a/tipper/tipper_9.vcproj +++ b/tipper/tipper_9.vcproj @@ -1,7 +1,7 @@ + @@ -119,12 +122,17 @@ Name="VCCLCompilerTool" Optimization="3" InlineFunctionExpansion="1" - EnableIntrinsicFunctions="false" + EnableIntrinsicFunctions="true" FavorSizeOrSpeed="2" WholeProgramOptimization="true" AdditionalIncludeDirectories="../../include" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1" + StringPooling="true" + ExceptionHandling="0" RuntimeLibrary="2" + BufferSecurityCheck="false" + FloatingPointModel="2" + RuntimeTypeInfo="false" PrecompiledHeaderThrough="common.h" WarningLevel="3" DebugInformationFormat="3" @@ -279,13 +287,18 @@ Name="VCCLCompilerTool" Optimization="3" InlineFunctionExpansion="1" + EnableIntrinsicFunctions="true" FavorSizeOrSpeed="2" WholeProgramOptimization="true" AdditionalIncludeDirectories="../../include" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TIPPER_EXPORTS;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1" StringPooling="true" + ExceptionHandling="0" RuntimeLibrary="2" + BufferSecurityCheck="false" EnableFunctionLevelLinking="true" + FloatingPointModel="2" + RuntimeTypeInfo="false" PrecompiledHeaderThrough="common.h" WarningLevel="3" DebugInformationFormat="3" @@ -337,6 +350,341 @@ Name="VCPostBuildEventTool" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -401,6 +749,38 @@ UsePrecompiledHeader="1" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tipper/translations.cpp b/tipper/translations.cpp index 3e0a1ee..66f5514 100644 --- a/tipper/translations.cpp +++ b/tipper/translations.cpp @@ -1,533 +1,533 @@ -#include "common.h" -#include "translations.h" -#include -#include -#include "str_utils.h" - -int num_tfuncs = 0; -DBVTranslation *translations = 0; - -DWORD next_func_id; - -HANDLE hServiceAdd; - -void AddTranslation(DBVTranslation *new_trans) { - num_tfuncs++; - - translations = (DBVTranslation *)realloc(translations, sizeof(DBVTranslation) * num_tfuncs); - translations[num_tfuncs - 1] = *new_trans; - - char setting[256]; -#ifdef _UNICODE - WideCharToMultiByte(code_page, 0, new_trans->name, -1, setting, 256, 0, 0); -#else - strncpy(setting, new_trans->name, 256); -#endif - - if(_tcscmp(new_trans->name, _T("[No translation]")) == 0) - translations[num_tfuncs - 1].id = 0; - else { - DWORD id = DBGetContactSettingDword(0, MODULE, setting, 0); - if(id != 0) { - translations[num_tfuncs - 1].id = id; - if(next_func_id <= id) next_func_id = id + 1; - } else { - translations[num_tfuncs - 1].id = next_func_id++; - DBWriteContactSettingDword(0, MODULE, setting, translations[num_tfuncs - 1].id); - } - - DBWriteContactSettingDword(0, MODULE, "NextFuncId", next_func_id); - } -} - -TCHAR *null_translation(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - DBVARIANT dbv = {0}; - buff[0] = 0; - if(ServiceExists(MS_DB_CONTACT_GETSETTING_STR)) { - if(DBGetContactSettingStringUtf(hContact, module_name, setting_name, &dbv)) - return 0; - } else { - if(DBGetContactSetting(hContact, module_name, setting_name, &dbv)) - return 0; - } - - switch(dbv.type) { - case DBVT_DELETED: - DBFreeVariant(&dbv); - return 0; - case DBVT_BYTE: - _itot(dbv.bVal, buff, 10); - break; - case DBVT_WORD: - _ltot(dbv.wVal, buff, 10); - break; - case DBVT_DWORD: - _ltot(dbv.dVal, buff, 10); - break; - case DBVT_ASCIIZ: - a2t(dbv.pszVal, buff, bufflen); - buff[bufflen - 1] = 0; - break; - case DBVT_UTF8: - u2t(dbv.pszVal, buff, bufflen); - buff[bufflen - 1] = 0; - break; - //case DBVT_WCHAR: - //wcsncpy(buff, dbv.pwszVal, 1024); - //buff[bufflen - 1] = 0; - //break; - case DBVT_BLOB: - default: - DBFreeVariant(&dbv); - return 0; - - - } - DBFreeVariant(&dbv); - - if(_tcslen(buff) == 0) - return 0; - return buff; -} - -TCHAR *timestamp_to_short_date(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); - if(ts == 0) return 0; - - if(unicode_system) { - DBTIMETOSTRINGT dbt = {0}; - dbt.cbDest = bufflen; - dbt.szDest = buff; - dbt.szFormat = _T("d"); - CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt); - } else { - char buffA[1024]; - DBTIMETOSTRING dbt = {0}; - dbt.cbDest = sizeof(buffA); - dbt.szDest = buffA; - dbt.szFormat = "d"; - CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ts, (LPARAM)&dbt); - a2t(buffA, buff, bufflen); - } - - buff[bufflen - 1] = 0; - return buff; -} - -TCHAR *timestamp_to_long_date(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); - if(ts == 0) return 0; - - if(unicode_system) { - DBTIMETOSTRINGT dbt = {0}; - dbt.cbDest = bufflen; - dbt.szDest = buff; - dbt.szFormat = _T("D"); - CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt); - } else { - char buffA[1024]; - DBTIMETOSTRING dbt = {0}; - dbt.cbDest = sizeof(buffA); - dbt.szDest = buffA; - dbt.szFormat = "D"; - CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ts, (LPARAM)&dbt); - a2t(buffA, buff, bufflen); - } - - buff[bufflen - 1] = 0; - return buff; -} - -TCHAR *timestamp_to_time(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); - if(ts == 0) return 0; - - if(unicode_system) { - DBTIMETOSTRINGT dbt = {0}; - dbt.cbDest = bufflen; - dbt.szDest = buff; - dbt.szFormat = _T("s"); - CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt); - } else { - char buffA[1024]; - DBTIMETOSTRING dbt = {0}; - dbt.cbDest = sizeof(buffA); - dbt.szDest = buffA; - dbt.szFormat = "s"; - CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ts, (LPARAM)&dbt); - a2t(buffA, buff, bufflen); - } - - buff[bufflen - 1] = 0; - return buff; -} - -TCHAR *timestamp_to_time_no_secs(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); - if(ts == 0) return 0; - - if(unicode_system) { - DBTIMETOSTRINGT dbt = {0}; - dbt.cbDest = bufflen; - dbt.szDest = buff; - dbt.szFormat = _T("t"); - CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt); - } else { - char buffA[1024]; - DBTIMETOSTRING dbt = {0}; - dbt.cbDest = sizeof(buffA); - dbt.szDest = buffA; - dbt.szFormat = "t"; - CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ts, (LPARAM)&dbt); - a2t(buffA, buff, bufflen); - } - - return buff; -} - -TCHAR *timestamp_to_time_difference(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); - DWORD t = (DWORD)time(0); - if(ts == 0) return 0; - - DWORD diff = (t - ts); - int d = (diff / 60 / 60 / 24); - int h = (diff - d * 60 * 60 * 24) / 60 / 60; - int m = (diff - d * 60 * 60 * 24 - h * 60 * 60) / 60; - if(d > 0) - mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m); - else if(h > 0) - mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m); - else - mir_sntprintf(buff, bufflen, TranslateT("%dm"), m); - - return buff; -} - -TCHAR *seconds_to_time_difference(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - - DWORD diff = DBGetContactSettingDword(hContact, module_name, setting_name, 0); - int d = (diff / 60 / 60 / 24); - int h = (diff - d * 60 * 60 * 24) / 60 / 60; - int m = (diff - d * 60 * 60 * 24 - h * 60 * 60) / 60; - if(d > 0) - mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m); - else if(h > 0) - mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m); - else - mir_sntprintf(buff, bufflen, TranslateT("%dm"), m); - - return buff; -} - -TCHAR *word_to_status_desc(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - int status = DBGetContactSettingWord(hContact, module_name, setting_name, ID_STATUS_OFFLINE); - char *strptr = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, (LPARAM)0); - a2t(strptr, buff, bufflen); - buff[bufflen - 1] = 0; - return buff; -} - -TCHAR *byte_to_yesno(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - DBVARIANT dbv; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(dbv.type == DBVT_BYTE) { - if(dbv.bVal != 0) - _tcsncpy(buff, _T("Yes"), bufflen); - else - _tcsncpy(buff, _T("No"), bufflen); - buff[bufflen - 1] = 0; - DBFreeVariant(&dbv); - return buff; - } - DBFreeVariant(&dbv); - } - return 0; -} - -TCHAR *byte_to_mf(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - BYTE val = (BYTE)DBGetContactSettingByte(hContact, module_name, setting_name, 0); - if(val == 'F') - _tcsncpy(buff, TranslateT("Female"), bufflen); - else if(val == 'M') - _tcsncpy(buff, TranslateT("Male"), bufflen); - else - return 0; - - buff[bufflen - 1] = 0; - return buff; -} - -TCHAR *word_to_country(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - char *cname = 0; - WORD cid = (WORD)DBGetContactSettingWord(hContact, module_name, setting_name, (WORD)-1); - if(cid != (WORD)-1 && ServiceExists(MS_UTILS_GETCOUNTRYBYNUMBER) && (cname = (char *)CallService(MS_UTILS_GETCOUNTRYBYNUMBER, cid, 0)) != 0) { - if(strcmp(cname, "Unknown") == 0) - return 0; - a2t(cname, buff, bufflen); - buff[bufflen - 1] = 0; - return buff; - } - return 0; -} - -TCHAR *dword_to_ip(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { - DWORD ip = DBGetContactSettingDword(hContact, module_name, setting_name, (WORD)0); - if(ip) { - in_addr in; - in.S_un.S_addr = htonl(ip); - a2t(inet_ntoa(in), buff, bufflen); - buff[bufflen - 1] = 0; - return buff; - } - return 0; -} - -bool GetInt(const DBVARIANT &dbv, int *val) { - if(!val) return false; - - switch(dbv.type) { - case DBVT_BYTE: - if(val) *val = (int)dbv.bVal; - return true; - case DBVT_WORD: - if(val) *val = (int)dbv.wVal; - return true; - case DBVT_DWORD: - if(val) *val = (int)dbv.dVal; - return true; - } - return false; -} - -TCHAR *day_month_year_to_date(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { - DBVARIANT dbv; - char setting_name[256]; - mir_snprintf(setting_name, 256, "%sDay", prefix); - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - int day = 0; - if(GetInt(dbv, &day)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sMonth", prefix); - int month = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &month)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sYear", prefix); - int year = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &year)) { - DBFreeVariant(&dbv); - - SYSTEMTIME st = {0}; - st.wDay = day; - st.wMonth = month; - st.wYear = year; - - GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buff, bufflen); - return buff; - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - return 0; -} - -TCHAR *day_month_year_to_age(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { - DBVARIANT dbv; - char setting_name[256]; - mir_snprintf(setting_name, 256, "%sDay", prefix); - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - int day = 0; - if(GetInt(dbv, &day)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sMonth", prefix); - int month = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &month)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sYear", prefix); - int year = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &year)) { - DBFreeVariant(&dbv); - - SYSTEMTIME now; - GetLocalTime(&now); - - int age = now.wYear - year; - if(now.wMonth < month || (now.wMonth == month && now.wDay < day)) - age--; - mir_sntprintf(buff, bufflen, _T("%d"), age); - return buff; - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - return 0; -} - -TCHAR *hours_minutes_seconds_to_time(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { - DBVARIANT dbv; - char setting_name[256]; - mir_snprintf(setting_name, 256, "%sHours", prefix); - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - int hours = 0; - if(GetInt(dbv, &hours)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sMinutes", prefix); - int minutes = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &minutes)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sSeconds", prefix); - int seconds = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - GetInt(dbv, &seconds); - DBFreeVariant(&dbv); - } - - SYSTEMTIME st = {0}; - st.wHour = hours; - st.wMinute = minutes; - st.wSecond = seconds; - - GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buff, bufflen); - return buff; - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - return 0; -} - -TCHAR *hours_minutes_to_time(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { - DBVARIANT dbv; - char setting_name[256]; - mir_snprintf(setting_name, 256, "%sHours", prefix); - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - int hours = 0; - if(GetInt(dbv, &hours)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sMinutes", prefix); - int minutes = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &minutes)) { - DBFreeVariant(&dbv); - - SYSTEMTIME st = {0}; - st.wHour = hours; - st.wMinute = minutes; - - GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, 0, buff, bufflen); - return buff; - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - return 0; -} - -TCHAR *day_month_year_hours_minutes_seconds_to_time_difference(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { - DBVARIANT dbv; - char setting_name[256]; - mir_snprintf(setting_name, 256, "%sDay", prefix); - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - int day = 0; - if(GetInt(dbv, &day)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sMonth", prefix); - int month = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &month)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sYear", prefix); - int year = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &year)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sHours", prefix); - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - int hours = 0; - if(GetInt(dbv, &hours)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sMinutes", prefix); - int minutes = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - if(GetInt(dbv, &minutes)) { - DBFreeVariant(&dbv); - mir_snprintf(setting_name, 256, "%sSeconds", prefix); - int seconds = 0; - if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { - GetInt(dbv, &seconds); - DBFreeVariant(&dbv); - } - - SYSTEMTIME st = {0}, st_now; - st.wDay = day; - st.wMonth = month; - st.wYear = year; - st.wHour = hours; - st.wMinute = minutes; - st.wSecond = seconds; - GetLocalTime(&st_now); - - FILETIME ft, ft_now; - SystemTimeToFileTime(&st, &ft); - SystemTimeToFileTime(&st_now, &ft_now); - - LARGE_INTEGER li, li_now; - li.HighPart = ft.dwHighDateTime; li.LowPart = ft.dwLowDateTime; - li_now.HighPart = ft_now.dwHighDateTime; li_now.LowPart = ft_now.dwLowDateTime; - - long diff = (long)((li_now.QuadPart - li.QuadPart) / (LONGLONG)10000000L); - int y = diff / 60 / 60 / 24 / 365; - int d = (diff - y * 60 * 60 * 24 * 365) / 60 / 60 / 24; - int h = (diff - y * 60 * 60 * 24 * 365 - d * 60 * 60 * 24) / 60 / 60; - int m = (diff - y * 60 * 60 * 24 * 365 - d * 60 * 60 * 24 - h * 60 * 60) / 60; - if(y != 0) - mir_sntprintf(buff, bufflen, TranslateT("%dy %dd %dh %dm"), y, d, h, m); - else if(d != 0) - mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m); - else if(h != 0) - mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m); - else - mir_sntprintf(buff, bufflen, TranslateT("%dm"), m); - - return buff; - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - } else - DBFreeVariant(&dbv); - } - return 0; -} - -TCHAR *empty_xStatus_name_to_default_name(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { +#include "common.h" +#include "translations.h" +#include +#include +#include "str_utils.h" + +int num_tfuncs = 0; +DBVTranslation *translations = 0; + +DWORD next_func_id; + +HANDLE hServiceAdd; + +void AddTranslation(DBVTranslation *new_trans) { + num_tfuncs++; + + translations = (DBVTranslation *)realloc(translations, sizeof(DBVTranslation) * num_tfuncs); + translations[num_tfuncs - 1] = *new_trans; + + char setting[256]; +#ifdef _UNICODE + WideCharToMultiByte(code_page, 0, new_trans->name, -1, setting, 256, 0, 0); +#else + strncpy(setting, new_trans->name, 256); +#endif + + if(_tcscmp(new_trans->name, _T("[No translation]")) == 0) + translations[num_tfuncs - 1].id = 0; + else { + DWORD id = DBGetContactSettingDword(0, MODULE, setting, 0); + if(id != 0) { + translations[num_tfuncs - 1].id = id; + if(next_func_id <= id) next_func_id = id + 1; + } else { + translations[num_tfuncs - 1].id = next_func_id++; + DBWriteContactSettingDword(0, MODULE, setting, translations[num_tfuncs - 1].id); + } + + DBWriteContactSettingDword(0, MODULE, "NextFuncId", next_func_id); + } +} + +TCHAR *null_translation(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + DBVARIANT dbv = {0}; + buff[0] = 0; + if(ServiceExists(MS_DB_CONTACT_GETSETTING_STR)) { + if(DBGetContactSettingStringUtf(hContact, module_name, setting_name, &dbv)) + return 0; + } else { + if(DBGetContactSetting(hContact, module_name, setting_name, &dbv)) + return 0; + } + + switch(dbv.type) { + case DBVT_DELETED: + DBFreeVariant(&dbv); + return 0; + case DBVT_BYTE: + _itot(dbv.bVal, buff, 10); + break; + case DBVT_WORD: + _ltot(dbv.wVal, buff, 10); + break; + case DBVT_DWORD: + _ltot(dbv.dVal, buff, 10); + break; + case DBVT_ASCIIZ: + a2t(dbv.pszVal, buff, bufflen); + buff[bufflen - 1] = 0; + break; + case DBVT_UTF8: + u2t(dbv.pszVal, buff, bufflen); + buff[bufflen - 1] = 0; + break; + //case DBVT_WCHAR: + //wcsncpy(buff, dbv.pwszVal, 1024); + //buff[bufflen - 1] = 0; + //break; + case DBVT_BLOB: + default: + DBFreeVariant(&dbv); + return 0; + + + } + DBFreeVariant(&dbv); + + if(_tcslen(buff) == 0) + return 0; + return buff; +} + +TCHAR *timestamp_to_short_date(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); + if(ts == 0) return 0; + + if(unicode_system) { + DBTIMETOSTRINGT dbt = {0}; + dbt.cbDest = bufflen; + dbt.szDest = buff; + dbt.szFormat = _T("d"); + CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt); + } else { + char buffA[1024]; + DBTIMETOSTRING dbt = {0}; + dbt.cbDest = sizeof(buffA); + dbt.szDest = buffA; + dbt.szFormat = "d"; + CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ts, (LPARAM)&dbt); + a2t(buffA, buff, bufflen); + } + + buff[bufflen - 1] = 0; + return buff; +} + +TCHAR *timestamp_to_long_date(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); + if(ts == 0) return 0; + + if(unicode_system) { + DBTIMETOSTRINGT dbt = {0}; + dbt.cbDest = bufflen; + dbt.szDest = buff; + dbt.szFormat = _T("D"); + CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt); + } else { + char buffA[1024]; + DBTIMETOSTRING dbt = {0}; + dbt.cbDest = sizeof(buffA); + dbt.szDest = buffA; + dbt.szFormat = "D"; + CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ts, (LPARAM)&dbt); + a2t(buffA, buff, bufflen); + } + + buff[bufflen - 1] = 0; + return buff; +} + +TCHAR *timestamp_to_time(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); + if(ts == 0) return 0; + + if(unicode_system) { + DBTIMETOSTRINGT dbt = {0}; + dbt.cbDest = bufflen; + dbt.szDest = buff; + dbt.szFormat = _T("s"); + CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt); + } else { + char buffA[1024]; + DBTIMETOSTRING dbt = {0}; + dbt.cbDest = sizeof(buffA); + dbt.szDest = buffA; + dbt.szFormat = "s"; + CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ts, (LPARAM)&dbt); + a2t(buffA, buff, bufflen); + } + + buff[bufflen - 1] = 0; + return buff; +} + +TCHAR *timestamp_to_time_no_secs(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); + if(ts == 0) return 0; + + if(unicode_system) { + DBTIMETOSTRINGT dbt = {0}; + dbt.cbDest = bufflen; + dbt.szDest = buff; + dbt.szFormat = _T("t"); + CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM)ts, (LPARAM)&dbt); + } else { + char buffA[1024]; + DBTIMETOSTRING dbt = {0}; + dbt.cbDest = sizeof(buffA); + dbt.szDest = buffA; + dbt.szFormat = "t"; + CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)ts, (LPARAM)&dbt); + a2t(buffA, buff, bufflen); + } + + return buff; +} + +TCHAR *timestamp_to_time_difference(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + DWORD ts = DBGetContactSettingDword(hContact, module_name, setting_name, 0); + DWORD t = (DWORD)time(0); + if(ts == 0) return 0; + + DWORD diff = (t - ts); + int d = (diff / 60 / 60 / 24); + int h = (diff - d * 60 * 60 * 24) / 60 / 60; + int m = (diff - d * 60 * 60 * 24 - h * 60 * 60) / 60; + if(d > 0) + mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m); + else if(h > 0) + mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m); + else + mir_sntprintf(buff, bufflen, TranslateT("%dm"), m); + + return buff; +} + +TCHAR *seconds_to_time_difference(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + + DWORD diff = DBGetContactSettingDword(hContact, module_name, setting_name, 0); + int d = (diff / 60 / 60 / 24); + int h = (diff - d * 60 * 60 * 24) / 60 / 60; + int m = (diff - d * 60 * 60 * 24 - h * 60 * 60) / 60; + if(d > 0) + mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m); + else if(h > 0) + mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m); + else + mir_sntprintf(buff, bufflen, TranslateT("%dm"), m); + + return buff; +} + +TCHAR *word_to_status_desc(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + int status = DBGetContactSettingWord(hContact, module_name, setting_name, ID_STATUS_OFFLINE); + char *strptr = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, (LPARAM)0); + a2t(strptr, buff, bufflen); + buff[bufflen - 1] = 0; + return buff; +} + +TCHAR *byte_to_yesno(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + DBVARIANT dbv; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(dbv.type == DBVT_BYTE) { + if(dbv.bVal != 0) + _tcsncpy(buff, _T("Yes"), bufflen); + else + _tcsncpy(buff, _T("No"), bufflen); + buff[bufflen - 1] = 0; + DBFreeVariant(&dbv); + return buff; + } + DBFreeVariant(&dbv); + } + return 0; +} + +TCHAR *byte_to_mf(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + BYTE val = (BYTE)DBGetContactSettingByte(hContact, module_name, setting_name, 0); + if(val == 'F') + _tcsncpy(buff, TranslateT("Female"), bufflen); + else if(val == 'M') + _tcsncpy(buff, TranslateT("Male"), bufflen); + else + return 0; + + buff[bufflen - 1] = 0; + return buff; +} + +TCHAR *word_to_country(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + char *cname = 0; + WORD cid = (WORD)DBGetContactSettingWord(hContact, module_name, setting_name, (WORD)-1); + if(cid != (WORD)-1 && ServiceExists(MS_UTILS_GETCOUNTRYBYNUMBER) && (cname = (char *)CallService(MS_UTILS_GETCOUNTRYBYNUMBER, cid, 0)) != 0) { + if(strcmp(cname, "Unknown") == 0) + return 0; + a2t(cname, buff, bufflen); + buff[bufflen - 1] = 0; + return buff; + } + return 0; +} + +TCHAR *dword_to_ip(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { + DWORD ip = DBGetContactSettingDword(hContact, module_name, setting_name, (WORD)0); + if(ip) { + in_addr in; + in.S_un.S_addr = htonl(ip); + a2t(inet_ntoa(in), buff, bufflen); + buff[bufflen - 1] = 0; + return buff; + } + return 0; +} + +bool GetInt(const DBVARIANT &dbv, int *val) { + if(!val) return false; + + switch(dbv.type) { + case DBVT_BYTE: + if(val) *val = (int)dbv.bVal; + return true; + case DBVT_WORD: + if(val) *val = (int)dbv.wVal; + return true; + case DBVT_DWORD: + if(val) *val = (int)dbv.dVal; + return true; + } + return false; +} + +TCHAR *day_month_year_to_date(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { + DBVARIANT dbv; + char setting_name[256]; + mir_snprintf(setting_name, 256, "%sDay", prefix); + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + int day = 0; + if(GetInt(dbv, &day)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sMonth", prefix); + int month = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &month)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sYear", prefix); + int year = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &year)) { + DBFreeVariant(&dbv); + + SYSTEMTIME st = {0}; + st.wDay = day; + st.wMonth = month; + st.wYear = year; + + GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buff, bufflen); + return buff; + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + return 0; +} + +TCHAR *day_month_year_to_age(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { + DBVARIANT dbv; + char setting_name[256]; + mir_snprintf(setting_name, 256, "%sDay", prefix); + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + int day = 0; + if(GetInt(dbv, &day)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sMonth", prefix); + int month = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &month)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sYear", prefix); + int year = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &year)) { + DBFreeVariant(&dbv); + + SYSTEMTIME now; + GetLocalTime(&now); + + int age = now.wYear - year; + if(now.wMonth < month || (now.wMonth == month && now.wDay < day)) + age--; + mir_sntprintf(buff, bufflen, _T("%d"), age); + return buff; + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + return 0; +} + +TCHAR *hours_minutes_seconds_to_time(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { + DBVARIANT dbv; + char setting_name[256]; + mir_snprintf(setting_name, 256, "%sHours", prefix); + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + int hours = 0; + if(GetInt(dbv, &hours)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sMinutes", prefix); + int minutes = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &minutes)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sSeconds", prefix); + int seconds = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + GetInt(dbv, &seconds); + DBFreeVariant(&dbv); + } + + SYSTEMTIME st = {0}; + st.wHour = hours; + st.wMinute = minutes; + st.wSecond = seconds; + + GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buff, bufflen); + return buff; + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + return 0; +} + +TCHAR *hours_minutes_to_time(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { + DBVARIANT dbv; + char setting_name[256]; + mir_snprintf(setting_name, 256, "%sHours", prefix); + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + int hours = 0; + if(GetInt(dbv, &hours)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sMinutes", prefix); + int minutes = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &minutes)) { + DBFreeVariant(&dbv); + + SYSTEMTIME st = {0}; + st.wHour = hours; + st.wMinute = minutes; + + GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, 0, buff, bufflen); + return buff; + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + return 0; +} + +TCHAR *day_month_year_hours_minutes_seconds_to_time_difference(HANDLE hContact, const char *module_name, const char *prefix, TCHAR *buff, int bufflen) { + DBVARIANT dbv; + char setting_name[256]; + mir_snprintf(setting_name, 256, "%sDay", prefix); + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + int day = 0; + if(GetInt(dbv, &day)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sMonth", prefix); + int month = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &month)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sYear", prefix); + int year = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &year)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sHours", prefix); + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + int hours = 0; + if(GetInt(dbv, &hours)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sMinutes", prefix); + int minutes = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + if(GetInt(dbv, &minutes)) { + DBFreeVariant(&dbv); + mir_snprintf(setting_name, 256, "%sSeconds", prefix); + int seconds = 0; + if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) { + GetInt(dbv, &seconds); + DBFreeVariant(&dbv); + } + + SYSTEMTIME st = {0}, st_now; + st.wDay = day; + st.wMonth = month; + st.wYear = year; + st.wHour = hours; + st.wMinute = minutes; + st.wSecond = seconds; + GetLocalTime(&st_now); + + FILETIME ft, ft_now; + SystemTimeToFileTime(&st, &ft); + SystemTimeToFileTime(&st_now, &ft_now); + + LARGE_INTEGER li, li_now; + li.HighPart = ft.dwHighDateTime; li.LowPart = ft.dwLowDateTime; + li_now.HighPart = ft_now.dwHighDateTime; li_now.LowPart = ft_now.dwLowDateTime; + + long diff = (long)((li_now.QuadPart - li.QuadPart) / (LONGLONG)10000000L); + int y = diff / 60 / 60 / 24 / 365; + int d = (diff - y * 60 * 60 * 24 * 365) / 60 / 60 / 24; + int h = (diff - y * 60 * 60 * 24 * 365 - d * 60 * 60 * 24) / 60 / 60; + int m = (diff - y * 60 * 60 * 24 * 365 - d * 60 * 60 * 24 - h * 60 * 60) / 60; + if(y != 0) + mir_sntprintf(buff, bufflen, TranslateT("%dy %dd %dh %dm"), y, d, h, m); + else if(d != 0) + mir_sntprintf(buff, bufflen, TranslateT("%dd %dh %dm"), d, h, m); + else if(h != 0) + mir_sntprintf(buff, bufflen, TranslateT("%dh %dm"), h, m); + else + mir_sntprintf(buff, bufflen, TranslateT("%dm"), m); + + return buff; + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + } else + DBFreeVariant(&dbv); + } + return 0; +} + +TCHAR *empty_xStatus_name_to_default_name(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { TCHAR szDefaultName[1024]; ICQ_CUSTOM_STATUS xstatus={0}; @@ -548,9 +548,9 @@ TCHAR *empty_xStatus_name_to_default_name(HANDLE hContact, const char *module_na buff[bufflen - 1] = 0; return buff; -} - -TCHAR *timezone_to_time(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { +} + +TCHAR *timezone_to_time(HANDLE hContact, const char *module_name, const char *setting_name, TCHAR *buff, int bufflen) { int timezone = DBGetContactSettingByte(hContact,module_name,setting_name,256); if(timezone==256 || (char)timezone==-100) { return 0; @@ -572,108 +572,108 @@ TCHAR *timezone_to_time(HANDLE hContact, const char *module_name, const char *se FileTimeToSystemTime(&ft, &st); GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff, bufflen); - return buff; -} - -int ServiceAddTranslation(WPARAM wParam, LPARAM lParam) { - if(!lParam) return 1; - - DBVTranslation *trans = (DBVTranslation *)lParam; - AddTranslation(trans); - - return 0; -} - -void InitTranslations() { - next_func_id = DBGetContactSettingDword(0, MODULE, "NextFuncId", 1); - -#define INT_TRANS_COUNT 19 - DBVTranslation internal_translations[INT_TRANS_COUNT] = { - { - (TranslateFunc*)null_translation, - _T("[No translation]"), - }, - { - (TranslateFunc*)word_to_status_desc, - _T("WORD to status description") - }, - { - (TranslateFunc*)timestamp_to_time, - _T("DWORD timestamp to time") - }, - { - (TranslateFunc*)timestamp_to_time_difference, - _T("DWORD timestamp to time difference") - }, - { - (TranslateFunc*)byte_to_yesno, - _T("BYTE to Yes/No") - }, - { - (TranslateFunc*)byte_to_mf, - _T("BYTE to Male/Female (ICQ)") - }, - { - (TranslateFunc*)word_to_country, - _T("WORD to country name") - }, - { - (TranslateFunc*)dword_to_ip, - _T("DWORD to ip address") - }, - { - (TranslateFunc*)day_month_year_to_date, - _T("Day|Month|Year to date") - }, - { - (TranslateFunc*)day_month_year_to_age, - _T("Day|Month|Year to age") - }, - { - (TranslateFunc*)hours_minutes_seconds_to_time, - _T("Hours|Minutes|Seconds to time") - }, - { - (TranslateFunc*)day_month_year_hours_minutes_seconds_to_time_difference, - _T("Day|Month|Year|Hours|Minutes|Seconds to time difference") - }, - { - (TranslateFunc*)timestamp_to_time_no_secs, - _T("DWORD timestamp to time (no seconds)") - }, - { - (TranslateFunc*)hours_minutes_to_time, - _T("Hours|Minutes to time") - }, - { - (TranslateFunc*)timestamp_to_short_date, - _T("DWORD timestamp to date (short)") - }, - { - (TranslateFunc*)timestamp_to_long_date, - _T("DWORD timestamp to date (long)") - }, - { - (TranslateFunc*)empty_xStatus_name_to_default_name, - _T("xStatus: empty xStatus name to default name") - }, - { - (TranslateFunc*)seconds_to_time_difference, - _T("DWORD seconds to time difference") - }, - { - (TranslateFunc*)timezone_to_time, - _T("BYTE timezone to time") - } - }; - - for(int i = 0; i < INT_TRANS_COUNT; i++) AddTranslation(&internal_translations[i]); - - hServiceAdd = CreateServiceFunction(MS_TIPPER_ADDTRANSLATION, ServiceAddTranslation); -} - -void DeinitTranslations() { - DestroyServiceFunction(hServiceAdd); - free(translations); -} - + return buff; +} + +INT_PTR ServiceAddTranslation(WPARAM wParam, LPARAM lParam) { + if(!lParam) return 1; + + DBVTranslation *trans = (DBVTranslation *)lParam; + AddTranslation(trans); + + return 0; +} + +void InitTranslations() { + next_func_id = DBGetContactSettingDword(0, MODULE, "NextFuncId", 1); + +#define INT_TRANS_COUNT 19 + DBVTranslation internal_translations[INT_TRANS_COUNT] = { + { + (TranslateFunc*)null_translation, + _T("[No translation]"), + }, + { + (TranslateFunc*)word_to_status_desc, + _T("WORD to status description") + }, + { + (TranslateFunc*)timestamp_to_time, + _T("DWORD timestamp to time") + }, + { + (TranslateFunc*)timestamp_to_time_difference, + _T("DWORD timestamp to time difference") + }, + { + (TranslateFunc*)byte_to_yesno, + _T("BYTE to Yes/No") + }, + { + (TranslateFunc*)byte_to_mf, + _T("BYTE to Male/Female (ICQ)") + }, + { + (TranslateFunc*)word_to_country, + _T("WORD to country name") + }, + { + (TranslateFunc*)dword_to_ip, + _T("DWORD to ip address") + }, + { + (TranslateFunc*)day_month_year_to_date, + _T("Day|Month|Year to date") + }, + { + (TranslateFunc*)day_month_year_to_age, + _T("Day|Month|Year to age") + }, + { + (TranslateFunc*)hours_minutes_seconds_to_time, + _T("Hours|Minutes|Seconds to time") + }, + { + (TranslateFunc*)day_month_year_hours_minutes_seconds_to_time_difference, + _T("Day|Month|Year|Hours|Minutes|Seconds to time difference") + }, + { + (TranslateFunc*)timestamp_to_time_no_secs, + _T("DWORD timestamp to time (no seconds)") + }, + { + (TranslateFunc*)hours_minutes_to_time, + _T("Hours|Minutes to time") + }, + { + (TranslateFunc*)timestamp_to_short_date, + _T("DWORD timestamp to date (short)") + }, + { + (TranslateFunc*)timestamp_to_long_date, + _T("DWORD timestamp to date (long)") + }, + { + (TranslateFunc*)empty_xStatus_name_to_default_name, + _T("xStatus: empty xStatus name to default name") + }, + { + (TranslateFunc*)seconds_to_time_difference, + _T("DWORD seconds to time difference") + }, + { + (TranslateFunc*)timezone_to_time, + _T("BYTE timezone to time") + } + }; + + for(int i = 0; i < INT_TRANS_COUNT; i++) AddTranslation(&internal_translations[i]); + + hServiceAdd = CreateServiceFunction(MS_TIPPER_ADDTRANSLATION, ServiceAddTranslation); +} + +void DeinitTranslations() { + DestroyServiceFunction(hServiceAdd); + free(translations); +} + -- cgit v1.2.3