/* Weather Protocol plugin for Miranda IM Copyright (c) 2012 Miranda NG team Copyright (c) 2005-2011 Boris Krasnovskiy All Rights Reserved Copyright (c) 2002-2005 Calvin Che This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Main file for the Weather Protocol, includes loading, unloading, upgrading, support for plugin uninsaller, and anything that doesn't belong to any other file. */ #include "stdafx.h" //============ GLOBAL VARIABLES ============ WIDATALIST *WIHead; WIDATALIST *WITail; HWND hPopupWindow; HANDLE hHookWeatherUpdated; HANDLE hHookWeatherError; MWindowList hDataWindowList, hWindowList; HANDLE hUpdateMutex; unsigned status; unsigned old_status; UINT_PTR timerId = 0; CMPlugin g_plugin; MYOPTIONS opt; // check if weather is currently updating BOOL ThreadRunning; // variable to determine if module loaded BOOL ModuleLoaded = FALSE; VARSW g_pwszIconsName(L"%miranda_path%\\Icons\\proto_Weather.dll"); HANDLE hTBButton = nullptr; ///////////////////////////////////////////////////////////////////////////////////////// // plugin info static const PLUGININFOEX pluginInfoEx = { sizeof(PLUGININFOEX), __PLUGIN_NAME, PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), __DESCRIPTION, __AUTHOR, __COPYRIGHT, __AUTHORWEB, UNICODE_AWARE, // {6B612A34-DCF2-4E32-85CF-B6FD006B745E} {0x6b612a34, 0xdcf2, 0x4e32, {0x85, 0xcf, 0xb6, 0xfd, 0x0, 0x6b, 0x74, 0x5e}} }; CMPlugin::CMPlugin() : PLUGIN(MODULENAME, pluginInfoEx), bPopups(MODULENAME, "UsePopup", true) { opt.NoProtoCondition = g_plugin.getByte("NoStatus", true); RegisterProtocol((opt.NoProtoCondition) ? PROTOTYPE_VIRTUAL : PROTOTYPE_PROTOCOL); SetUniqueId("ID"); } ///////////////////////////////////////////////////////////////////////////////////////// extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOCOL, MIID_LAST }; ///////////////////////////////////////////////////////////////////////////////////////// int WeatherShutdown(WPARAM, LPARAM) { KillTimer(nullptr, timerId); // kill update timer SaveOptions(); // save options once more status = ID_STATUS_OFFLINE; // set status to offline WindowList_Broadcast(hWindowList, WM_CLOSE, 0, 0); WindowList_Broadcast(hDataWindowList, WM_CLOSE, 0, 0); SendMessage(hWndSetup, WM_CLOSE, 0, 0); return 0; } int OnToolbarLoaded(WPARAM, LPARAM) { TTBButton ttb = {}; ttb.name = LPGEN("Enable/disable auto update"); ttb.pszService = MS_WEATHER_ENABLED; ttb.pszTooltipUp = LPGEN("Auto Update Enabled"); ttb.pszTooltipDn = LPGEN("Auto Update Disabled"); ttb.hIconHandleUp = g_plugin.getIconHandle(IDI_ICON); ttb.hIconHandleDn = g_plugin.getIconHandle(IDI_DISABLED); ttb.dwFlags = (g_plugin.getByte("AutoUpdate", 1) ? 0 : TTBBF_PUSHED) | TTBBF_ASPUSHBUTTON | TTBBF_VISIBLE; hTBButton = g_plugin.addTTB(&ttb); return 0; } // weather protocol initialization function // run after the event ME_SYSTEM_MODULESLOADED occurs int WeatherInit(WPARAM, LPARAM) { // initialize netlib NetlibInit(); InitMwin(); // load weather menu items AddMenuItems(); // timer for the first update timerId = SetTimer(nullptr, 0, 5000, timerProc2); // first update is 5 sec after load // weather user detail HookEvent(ME_USERINFO_INITIALISE, UserInfoInit); HookEvent(ME_TTB_MODULELOADED, OnToolbarLoaded); return 0; } //============ MISC FUNCTIONS ============ static IconItem iconList[] = { { LPGEN("Protocol icon"), "main", IDI_ICON }, { LPGEN("Update Disabled"), "disabled", IDI_DISABLED }, { LPGEN("View Log"), "log", IDI_LOG }, { LPGEN("Update with Clear"), "update2", IDI_UPDATE2 }, { LPGEN("View Brief"), "brief", IDI_S }, { LPGEN("View Complete"), "read", IDI_READ }, { LPGEN("Weather Update"), "update", IDI_UPDATE }, { LPGEN("Weather Map"), "map", IDI_MAP }, { LPGEN("Edit Settings"), "edit", IDI_EDIT }, }; int CMPlugin::Load() { g_plugin.registerIcon(MODULENAME, iconList, MODULENAME); // load dll with icons hIconsDll = LoadLibraryW(g_pwszIconsName); // load options and set defaults LoadOptions(); // reset the weather data at startup for individual contacts EraseAllInfo(); // load weather update data LoadWIData(true); // set status to online if "Do not display weather condition as protocol status" is enabled old_status = status = ID_STATUS_OFFLINE; // add an event on weather update and error hHookWeatherUpdated = CreateHookableEvent(ME_WEATHER_UPDATED); hHookWeatherError = CreateHookableEvent(ME_WEATHER_ERROR); // initialize options and network HookEvent(ME_OPT_INITIALISE, OptInit); HookEvent(ME_SYSTEM_MODULESLOADED, WeatherInit); HookEvent(ME_DB_CONTACT_DELETED, ContactDeleted); HookEvent(ME_CLIST_DOUBLECLICKED, BriefInfo); HookEvent(ME_WEATHER_UPDATED, WeatherPopup); HookEvent(ME_WEATHER_ERROR, WeatherError); HookEvent(ME_SYSTEM_PRESHUTDOWN, WeatherShutdown); HookEvent(ME_CLIST_PREBUILDCONTACTMENU, BuildContactMenu); hDataWindowList = WindowList_Create(); hWindowList = WindowList_Create(); hUpdateMutex = CreateMutex(nullptr, FALSE, nullptr); // initialize weather protocol services InitServices(); // add sound event addSound("weatherupdated", _A2W(MODULENAME), LPGENW("Condition Changed")); addSound("weatheralert", _A2W(MODULENAME), LPGENW("Alert Issued")); // popup initialization addPopupOption(LPGEN("Weather notifications"), bPopups); // window needed for popup commands wchar_t SvcFunc[100]; mir_snwprintf(SvcFunc, L"%s__PopupWindow", _A2W(MODULENAME)); hPopupWindow = CreateWindowEx(WS_EX_TOOLWINDOW, L"static", SvcFunc, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, nullptr, g_plugin.getInst(), nullptr); SetWindowLongPtr(hPopupWindow, GWLP_WNDPROC, (LONG_PTR)PopupWndProc); return 0; } ///////////////////////////////////////////////////////////////////////////////////////// // unload function int CMPlugin::Unload() { if (hIconsDll) FreeModule(hIconsDll); DestroyMwin(); DestroyWindow(hPopupWindow); DestroyHookableEvent(hHookWeatherUpdated); DestroyHookableEvent(hHookWeatherError); Netlib_CloseHandle(hNetlibUser); DestroyUpdateList(); DestroyWIList(); // unload all ini data from memory WindowList_Destroy(hDataWindowList); WindowList_Destroy(hWindowList); CloseHandle(hUpdateMutex); return 0; }