// popups2.cpp : Defines the entry point for the DLL application. // #include "common.h" #include "tipper.h" #include "version.h" #include "message_pump.h" #include "options.h" #include "popwin.h" #include "str_utils.h" HMODULE hInst = 0; HANDLE mainThread = 0; bool unicode_system; FontID font_id_title = {0}, font_id_labels = {0}, font_id_values = {0}; ColourID colour_id_bg = {0}, colour_id_border = {0}, colour_id_divider = {0}, colour_id_sidebar = {0}; FontIDW font_id_titlew = {0}, font_id_labelsw = {0}, font_id_valuesw = {0}; ColourIDW colour_id_bgw = {0}, colour_id_borderw = {0}, colour_id_dividerw = {0}, colour_id_sidebarw = {0}; HFONT hFontTitle = 0, hFontLabels = 0, hFontValues = 0; // hooked here so it's in the main thread HANDLE hAvChangeEvent = 0, hAvContactChangeEvent = 0, hShowTipEvent = 0, hHideTipEvent = 0, hAckEvent = 0, hFramesSBShow = 0, hFramesSBHide = 0, hSettingChangedEvent = 0; HANDLE hShowTipService = 0, hShowTipWService = 0, hHideTipService = 0; struct MM_INTERFACE memoryManagerInterface = {0}; PLUGININFOEX pluginInfo={ sizeof(PLUGININFOEX), __PLUGIN_NAME, PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), __DESC, __AUTHOR, __AUTHOREMAIL, __COPYRIGHT, __AUTHORWEB, UNICODE_AWARE, //not transient 0, //doesn't replace anything built-in #ifndef _UNICODE { 0xedae7137, 0x1b6a, 0x4b8f, { 0xaa, 0xb0, 0x3b, 0x5a, 0x2f, 0x8, 0xf4, 0x62 } } // {EDAE7137-1B6A-4b8f-AAB0-3B5A2F08F462} #else { 0x785c25e3, 0xc906, 0x434b, { 0x97, 0x23, 0xe2, 0x44, 0xe1, 0xbe, 0xca, 0x2 } } // {785C25E3-C906-434b-9723-E244E1BECA02} #endif }; PLUGINLINK *pluginLink = 0; extern "C" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { hInst = hModule; DisableThreadLibraryCalls(hInst); return TRUE; } extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { return &pluginInfo; } extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) { pluginInfo.cbSize = sizeof(PLUGININFO); return (PLUGININFO*)&pluginInfo; } static const MUUID interfaces[] = {MIID_TOOLTIPS, MIID_LAST}; extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) { return interfaces; } int ReloadFont(WPARAM wParam, LPARAM lParam) { if(ServiceExists(MS_FONT_GETW)) { LOGFONTW log_font; if(hFontTitle) DeleteObject(hFontTitle); options.title_col = CallService(MS_FONT_GETW, (WPARAM)&font_id_titlew, (LPARAM)&log_font); hFontTitle = CreateFontIndirectW(&log_font); if(hFontLabels) DeleteObject(hFontLabels); options.label_col = CallService(MS_FONT_GETW, (WPARAM)&font_id_labelsw, (LPARAM)&log_font); hFontLabels = CreateFontIndirectW(&log_font); if(hFontValues) DeleteObject(hFontValues); options.value_col = CallService(MS_FONT_GETW, (WPARAM)&font_id_valuesw, (LPARAM)&log_font); hFontValues = CreateFontIndirectW(&log_font); options.bg_col = CallService(MS_COLOUR_GETW, (WPARAM)&colour_id_bgw, 0); options.border_col = CallService(MS_COLOUR_GETW, (WPARAM)&colour_id_borderw, 0); options.sidebar_col = CallService(MS_COLOUR_GETW, (WPARAM)&colour_id_sidebarw, 0); options.div_col = CallService(MS_COLOUR_GETW, (WPARAM)&colour_id_dividerw, 0); } else { LOGFONTA log_font; if(hFontTitle) DeleteObject(hFontTitle); options.title_col = CallService(MS_FONT_GET, (WPARAM)&font_id_title, (LPARAM)&log_font); hFontTitle = CreateFontIndirectA(&log_font); if(hFontLabels) DeleteObject(hFontLabels); options.label_col = CallService(MS_FONT_GET, (WPARAM)&font_id_labels, (LPARAM)&log_font); hFontLabels = CreateFontIndirectA(&log_font); if(hFontValues) DeleteObject(hFontValues); options.value_col = CallService(MS_FONT_GET, (WPARAM)&font_id_values, (LPARAM)&log_font); hFontValues = CreateFontIndirectA(&log_font); options.bg_col = CallService(MS_COLOUR_GET, (WPARAM)&colour_id_bg, 0); options.border_col = CallService(MS_COLOUR_GET, (WPARAM)&colour_id_border, 0); options.sidebar_col = CallService(MS_COLOUR_GET, (WPARAM)&colour_id_sidebar, 0); options.div_col = CallService(MS_COLOUR_GET, (WPARAM)&colour_id_divider, 0); } return 0; } // hack to hide tip when clist hides from timeout int SettingChanged(WPARAM wParam, LPARAM lParam) { DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam; if(strcmp(dcws->szModule, "CList") != 0 || strcmp(dcws->szSetting, "State") != 0) return 0; // clist hiding if(dcws->value.type == DBVT_BYTE && dcws->value.bVal == 0) { HideTip(0, 0); } return 0; } int ModulesLoaded(WPARAM wParam, LPARAM lParam) { if(ServiceExists(MS_UPDATE_REGISTER)) { // register with updater Update update = {0}; char szVersion[16]; update.cbSize = sizeof(Update); update.szComponentName = pluginInfo.shortName; update.pbVersion = (BYTE *)CreateVersionString(pluginInfo.version, szVersion); update.cpbVersion = strlen((char *)update.pbVersion); update.szBetaChangelogURL = "https://server.scottellis.com.au/wsvn/mim_plugs/tipper/?op=log&rev=0&sc=0&isdir=1"; update.szUpdateURL = UPDATER_AUTOREGISTER; // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) // before the version that we use to locate it on the page // (note that if the update URL and the version URL point to standard file listing entries, the backend xml // data will be used to check for updates rather than the actual web page - this is not true for beta urls) #ifdef _UNICODE update.szBetaUpdateURL = "http://www.scottellis.com.au/miranda_plugins/tipper.zip"; update.szBetaVersionURL = "http://www.scottellis.com.au/miranda_plugins/ver_tipper.html"; #else update.szBetaUpdateURL = "http://www.scottellis.com.au/miranda_plugins/tipper_ansi.zip"; update.szBetaVersionURL = "http://www.scottellis.com.au/miranda_plugins/ver_tipper_ansi.html"; #endif update.pbBetaVersionPrefix = (BYTE *)"Tipper version "; update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix); CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); } if(ServiceExists(MS_FONT_REGISTERW)) { font_id_titlew.cbSize = sizeof(FontIDW); font_id_titlew.flags = FIDF_ALLOWEFFECTS; t2w(TranslateT("Tooltips"), font_id_titlew.group, 64); t2w(TranslateT("Title"), font_id_titlew.name, 64); strcpy(font_id_titlew.dbSettingsGroup, MODULE); strcpy(font_id_titlew.prefix, "FontFirst"); font_id_titlew.order = 0; font_id_titlew.deffontsettings.charset = DEFAULT_CHARSET; font_id_titlew.deffontsettings.size = -14; font_id_titlew.deffontsettings.style = DBFONTF_BOLD; font_id_titlew.deffontsettings.colour = RGB(255, 0, 0); font_id_titlew.flags |= FIDF_DEFAULTVALID; font_id_labelsw.cbSize = sizeof(FontIDW); font_id_labelsw.flags = FIDF_ALLOWEFFECTS; t2w(TranslateT("Tooltips"), font_id_labelsw.group, 64); t2w(TranslateT("Labels"), font_id_labelsw.name, 64); strcpy(font_id_labelsw.dbSettingsGroup, MODULE); strcpy(font_id_labelsw.prefix, "FontLabels"); font_id_labelsw.order = 1; font_id_labelsw.deffontsettings.charset = DEFAULT_CHARSET; font_id_labelsw.deffontsettings.size = -12; font_id_labelsw.deffontsettings.style = DBFONTF_ITALIC; font_id_labelsw.deffontsettings.colour = RGB(128, 128, 128); font_id_labelsw.flags |= FIDF_DEFAULTVALID; font_id_valuesw.cbSize = sizeof(FontIDW); font_id_valuesw.flags = FIDF_ALLOWEFFECTS; t2w(TranslateT("Tooltips"), font_id_valuesw.group, 64); t2w(TranslateT("Values"), font_id_valuesw.name, 64); strcpy(font_id_valuesw.dbSettingsGroup, MODULE); strcpy(font_id_valuesw.prefix, "FontValues"); font_id_valuesw.order = 2; font_id_valuesw.deffontsettings.charset = DEFAULT_CHARSET; font_id_valuesw.deffontsettings.size = -12; font_id_valuesw.deffontsettings.style = 0; font_id_valuesw.deffontsettings.colour = RGB(0, 0, 0); font_id_valuesw.flags |= FIDF_DEFAULTVALID; CallService(MS_FONT_REGISTERW, (WPARAM)&font_id_titlew, 0); CallService(MS_FONT_REGISTERW, (WPARAM)&font_id_labelsw, 0); CallService(MS_FONT_REGISTERW, (WPARAM)&font_id_valuesw, 0); colour_id_bgw.cbSize = sizeof(ColourIDW); t2w(TranslateT("Tooltips"), colour_id_bgw.group, 64); t2w(TranslateT("Background"), colour_id_bgw.name, 64); strcpy(colour_id_bgw.dbSettingsGroup, MODULE); strcpy(colour_id_bgw.setting, "ColourBg"); colour_id_bgw.defcolour = RGB(219, 219, 219); colour_id_bgw.order = 0; colour_id_borderw.cbSize = sizeof(ColourIDW); t2w(TranslateT("Tooltips"), colour_id_borderw.group, 64); t2w(TranslateT("Border"), colour_id_borderw.name, 64); strcpy(colour_id_borderw.dbSettingsGroup, MODULE); strcpy(colour_id_borderw.setting, "BorderCol"); colour_id_borderw.defcolour = 0; colour_id_borderw.order = 0; colour_id_dividerw.cbSize = sizeof(ColourIDW); t2w(TranslateT("Tooltips"), colour_id_dividerw.group, 64); t2w(TranslateT("Dividers"), colour_id_dividerw.name, 64); strcpy(colour_id_dividerw.dbSettingsGroup, MODULE); strcpy(colour_id_dividerw.setting, "DividerCol"); colour_id_dividerw.defcolour = 0; colour_id_dividerw.order = 0; colour_id_sidebarw.cbSize = sizeof(ColourIDW); t2w(TranslateT("Tooltips"), colour_id_sidebarw.group, 64); t2w(TranslateT("Sidebar"), colour_id_sidebarw.name, 64); strcpy(colour_id_sidebarw.dbSettingsGroup, MODULE); strcpy(colour_id_sidebarw.setting, "SidebarCol"); colour_id_sidebarw.defcolour = RGB(192, 192, 192); colour_id_sidebarw.order = 0; CallService(MS_COLOUR_REGISTERW, (WPARAM)&colour_id_bgw, 0); CallService(MS_COLOUR_REGISTERW, (WPARAM)&colour_id_borderw, 0); CallService(MS_COLOUR_REGISTERW, (WPARAM)&colour_id_dividerw, 0); CallService(MS_COLOUR_REGISTERW, (WPARAM)&colour_id_sidebarw, 0); ReloadFont(0, 0); HookEvent(ME_FONT_RELOAD, ReloadFont); } else if(ServiceExists(MS_FONT_REGISTER)) { font_id_title.cbSize = sizeof(FontID); font_id_title.flags = FIDF_ALLOWEFFECTS; t2a(TranslateT("Tooltips"), font_id_title.group, 64); t2a(TranslateT("Title"), font_id_title.name, 64); strcpy(font_id_title.dbSettingsGroup, MODULE); strcpy(font_id_title.prefix, "FontFirst"); font_id_title.order = 0; font_id_title.deffontsettings.charset = DEFAULT_CHARSET; font_id_title.deffontsettings.size = -14; font_id_title.deffontsettings.style = DBFONTF_BOLD; font_id_title.deffontsettings.colour = RGB(255, 0, 0); font_id_title.flags |= FIDF_DEFAULTVALID; font_id_labels.cbSize = sizeof(FontID); font_id_labels.flags = FIDF_ALLOWEFFECTS; t2a(TranslateT("Tooltips"), font_id_labels.group, 64); t2a(TranslateT("Labels"), font_id_labels.name, 64); strcpy(font_id_labels.dbSettingsGroup, MODULE); strcpy(font_id_labels.prefix, "FontLabels"); font_id_labels.order = 1; font_id_labels.deffontsettings.charset = DEFAULT_CHARSET; font_id_labels.deffontsettings.size = -12; font_id_labels.deffontsettings.style = DBFONTF_ITALIC; font_id_labels.deffontsettings.colour = RGB(128, 128, 128); font_id_labels.flags |= FIDF_DEFAULTVALID; font_id_values.cbSize = sizeof(FontID); font_id_values.flags = FIDF_ALLOWEFFECTS; t2a(TranslateT("Tooltips"), font_id_values.group, 64); t2a(TranslateT("Values"), font_id_values.name, 64); strcpy(font_id_values.dbSettingsGroup, MODULE); strcpy(font_id_values.prefix, "FontValues"); font_id_values.order = 2; font_id_values.deffontsettings.charset = DEFAULT_CHARSET; font_id_values.deffontsettings.size = -12; font_id_values.deffontsettings.style = 0; font_id_values.deffontsettings.colour = RGB(0, 0, 0); font_id_values.flags |= FIDF_DEFAULTVALID; CallService(MS_FONT_REGISTER, (WPARAM)&font_id_title, 0); CallService(MS_FONT_REGISTER, (WPARAM)&font_id_labels, 0); CallService(MS_FONT_REGISTER, (WPARAM)&font_id_values, 0); colour_id_bg.cbSize = sizeof(ColourID); t2a(TranslateT("Tooltips"), colour_id_bg.group, 64); t2a(TranslateT("Background"), colour_id_bg.name, 64); strcpy(colour_id_bg.dbSettingsGroup, MODULE); strcpy(colour_id_bg.setting, "ColourBg"); colour_id_bg.defcolour = RGB(219, 219, 219); colour_id_bg.order = 0; colour_id_border.cbSize = sizeof(ColourID); t2a(TranslateT("Tooltips"), colour_id_border.group, 64); t2a(TranslateT("Border"), colour_id_border.name, 64); strcpy(colour_id_border.dbSettingsGroup, MODULE); strcpy(colour_id_border.setting, "BorderCol"); colour_id_border.defcolour = 0; colour_id_border.order = 0; colour_id_divider.cbSize = sizeof(ColourID); t2a(TranslateT("Tooltips"), colour_id_divider.group, 64); t2a(TranslateT("Dividers"), colour_id_divider.name, 64); strcpy(colour_id_divider.dbSettingsGroup, MODULE); strcpy(colour_id_divider.setting, "DividerCol"); colour_id_divider.defcolour = 0; colour_id_divider.order = 0; colour_id_sidebar.cbSize = sizeof(ColourID); t2a(TranslateT("Tooltips"), colour_id_sidebar.group, 64); t2a(TranslateT("Sidebar"), colour_id_sidebar.name, 64); strcpy(colour_id_sidebar.dbSettingsGroup, MODULE); strcpy(colour_id_sidebar.setting, "SidebarCol"); colour_id_sidebar.defcolour = RGB(192, 192, 192); colour_id_sidebar.order = 0; CallService(MS_COLOUR_REGISTER, (WPARAM)&colour_id_bg, 0); CallService(MS_COLOUR_REGISTER, (WPARAM)&colour_id_border, 0); CallService(MS_COLOUR_REGISTER, (WPARAM)&colour_id_divider, 0); CallService(MS_COLOUR_REGISTER, (WPARAM)&colour_id_sidebar, 0); ReloadFont(0, 0); HookEvent(ME_FONT_RELOAD, ReloadFont); } else { options.title_col = RGB(255, 0, 0); options.label_col = RGB(128, 128, 128), options.value_col = 0; options.bg_col = RGB(219, 219, 219); options.border_col = options.div_col = 0; options.sidebar_col = RGB(192, 192, 192); LOGFONT lf = {0}; lf.lfCharSet = DEFAULT_CHARSET; lf.lfHeight = -14; lf.lfWeight = FW_BOLD; hFontTitle = CreateFontIndirect(&lf); lf.lfHeight = -12; lf.lfWeight = 0; lf.lfItalic = TRUE; hFontLabels = CreateFontIndirect(&lf); lf.lfHeight = -12; lf.lfWeight = 0; lf.lfItalic = FALSE; hFontValues = CreateFontIndirect(&lf); } hAvChangeEvent = HookEvent(ME_AV_AVATARCHANGED, AvatarChanged); hAvContactChangeEvent = HookEvent(ME_AV_CONTACTAVATARCHANGED, AvatarChanged); 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); hFramesSBHide = HookEvent(ME_CLIST_FRAMES_SB_HIDE_TOOLTIP, FramesHideSBTip); LoadOptions(); // set 'time-in' CallService(MS_CLC_SETINFOTIPHOVERTIME, options.time_in, 0); return 0; } int Shutdown(WPARAM wParam, LPARAM lParam) { if(hFramesSBShow) UnhookEvent(hFramesSBShow); if(hFramesSBHide) UnhookEvent(hFramesSBHide); if(hAvChangeEvent) UnhookEvent(hAvChangeEvent); if(hAvContactChangeEvent) UnhookEvent(hAvContactChangeEvent); if(hShowTipEvent) UnhookEvent(hShowTipEvent); if(hHideTipEvent) UnhookEvent(hHideTipEvent); if(hAckEvent) UnhookEvent(hAckEvent); if(hShowTipService) DestroyServiceFunction(hShowTipService); if(hShowTipWService) DestroyServiceFunction(hShowTipWService); if(hHideTipService) DestroyServiceFunction(hHideTipService); DeinitMessagePump(); return 0; } HANDLE hEventPreShutdown, hEventModulesLoaded; extern "C" int TIPPER_API Load(PLUGINLINK *link) { pluginLink = link; DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &mainThread, THREAD_SET_CONTEXT, FALSE, 0); set_codepage(); char szVer[128]; unicode_system = (CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)sizeof(szVer), (LPARAM)szVer) == 0 && strstr(szVer, "Unicode")); // get the internal malloc/free() memoryManagerInterface.cbSize = sizeof(memoryManagerInterface); CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM)&memoryManagerInterface); // don't save status messages CallService(MS_DB_SETSETTINGRESIDENT, (WPARAM)TRUE, (LPARAM)MODULE "/TempStatusMsg"); // Ensure that the common control DLL is loaded (for listview) INITCOMMONCONTROLSEX icex; icex.dwSize = sizeof(INITCOMMONCONTROLSEX); icex.dwICC = ICC_LISTVIEW_CLASSES; InitCommonControlsEx(&icex); if(ServiceExists(MS_LANGPACK_GETCODEPAGE)) code_page = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0); InitTranslations(); InitMessagePump(); InitOptions(); // for compatibility with mToolTip status tooltips hShowTipService = CreateServiceFunction("mToolTip/ShowTip", ShowTip); hShowTipWService = CreateServiceFunction("mToolTip/ShowTipW", ShowTipW); hHideTipService = CreateServiceFunction("mToolTip/HideTip", HideTip); hEventPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, Shutdown); hEventModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); hSettingChangedEvent = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingChanged); return 0; } extern "C" int TIPPER_API Unload() { UnhookEvent(hSettingChangedEvent); UnhookEvent(hEventPreShutdown); UnhookEvent(hEventModulesLoaded); DeinitOptions(); if(ServiceExists(MS_FONT_REGISTERW)) { DeleteObject(hFontTitle); DeleteObject(hFontLabels); DeleteObject(hFontValues); } // otherwise, no need to delete the handle DeinitTranslations(); CloseHandle(mainThread); return 0; }