summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/ExternalAPI/m_weather.h65
-rw-r--r--protocols/Weather/res/resource.rc6
-rw-r--r--protocols/Weather/src/proto.h218
-rw-r--r--protocols/Weather/src/resource.h1
-rw-r--r--protocols/Weather/src/stdafx.h189
-rw-r--r--protocols/Weather/src/weather.cpp82
-rw-r--r--protocols/Weather/src/weather_addstn.cpp160
-rw-r--r--protocols/Weather/src/weather_contacts.cpp586
-rw-r--r--protocols/Weather/src/weather_conv.cpp54
-rw-r--r--protocols/Weather/src/weather_data.cpp68
-rw-r--r--protocols/Weather/src/weather_http.cpp22
-rw-r--r--protocols/Weather/src/weather_ini.cpp3
-rw-r--r--protocols/Weather/src/weather_mwin.cpp22
-rw-r--r--protocols/Weather/src/weather_opt.cpp603
-rw-r--r--protocols/Weather/src/weather_popup.cpp469
-rw-r--r--protocols/Weather/src/weather_proto.cpp116
-rw-r--r--protocols/Weather/src/weather_svcs.cpp128
-rw-r--r--protocols/Weather/src/weather_update.cpp121
-rw-r--r--protocols/Weather/src/weather_userinfo.cpp311
-rw-r--r--protocols/Weather/weather.vcxproj2
-rw-r--r--protocols/Weather/weather.vcxproj.filters6
21 files changed, 1588 insertions, 1644 deletions
diff --git a/plugins/ExternalAPI/m_weather.h b/plugins/ExternalAPI/m_weather.h
index eb9e89f84d..83793cc651 100644
--- a/plugins/ExternalAPI/m_weather.h
+++ b/plugins/ExternalAPI/m_weather.h
@@ -59,74 +59,9 @@ struct WEATHERINFO
// WPARAM = LPARAM = NULL
#define MS_WEATHER_REFRESHALL "Weather/RefreshAll"
-// Below are the service functions for weather contacts
-// The plugin does NOT verify that they are used in weather contact,
-// so bad call on these function may cause crashes.
-
-// Update a single station
-// WPARAM = (HANDLE)hContact
-// LPARAM = NULL
-#define MS_WEATHER_UPDATE "Weather/Update"
-
-// Update a single station + delete old settings
-// WPARAM = (HANDLE)hContact
-// LPARAM = NULL
-#define MS_WEATHER_REFRESH "Weather/Refresh"
-
-// View the brief info of a contact
-// WPARAM = (HANDLE)hContact
-// LPARAM = NULL
-#define MS_WEATHER_BRIEF "Weather/Brief"
-
-// Use default browser to open the complete forecast on web
-// WPARAM = (HANDLE)hContact
-// LPARAM = NULL
-#define MS_WEATHER_COMPLETE "Weather/CompleteForecast"
-
-// Use default browser to open the weather map defined for the contact
-// WPARAM = (HANDLE)hContact
-// LPARAM = NULL
-#define MS_WEATHER_MAP "Weather/Map"
-
-// Open the external log of the weather contact
-// WPARAM = (HANDLE)hContact
-// LPARAM = NULL
-#define MS_WEATHER_LOG "Weather/Log"
-
-// Edit weather contact setting
-// WPARAM = (HANDLE)hContact
-// LPARAM = NULL
-#define MS_WEATHER_EDIT "Weather/Edit"
-
// parse the string to turn it to weather display
// WPARAM = (WEATHERINFO*)hContact
// LPARAM = (char*)display_str
#define MS_WEATHER_GETDISPLAY "Weather/GetDisplay"
-// =============== WEATHER EVENTS ================
-
-/*
-HANDLE hContact = (HANDLE)wParam;
-BOOL Condition_Changed = (BOOL)lParam;
-
-hContact is the handle of updated contact
-If the weather condition is differ from the last update (either temperature/condition,
-or the last update time, depend what the user choose in the options), then
-Condition_Changed is true; otherwise is false.
-*/
-#define ME_WEATHER_UPDATED "Miranda/Weather/Updated"
-
-/*
-Shows a warning message for Weather Popup.
-wParam = (char*) lpzMessage
-lParam = Type
-Type can either be SM_WARNING, SM_NOTIFY, or SM_WEATHERALERT
-
-This event is used to avoid the error popup to occurs within a thread, so the "Use
-multiply thread" fuction don't have to be enabled for weather popups to work.
-*/
-#define SM_WEATHERALERT 16
-#define ME_WEATHER_ERROR "Miranda/Weather/Error"
-
-
#endif //M_WEATHER_H__
diff --git a/protocols/Weather/res/resource.rc b/protocols/Weather/res/resource.rc
index 34e5f32c83..36e656b8f7 100644
--- a/protocols/Weather/res/resource.rc
+++ b/protocols/Weather/res/resource.rc
@@ -54,10 +54,8 @@ BEGIN
CONTROL "Remove old data when updating",IDC_REMOVEOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,45,286,8
CONTROL "Make the contact italic when weather alert is issued",IDC_MAKEI,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,56,286,8
- GROUPBOX "Modes",IDC_STATIC,3,70,300,37
- CONTROL "Use weather condition as protocol status",IDC_PROTOCOND,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,81,278,8
- CONTROL "Avatar only mode",IDC_DISCONDICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,91,278,8
+ GROUPBOX "Modes",IDC_STATIC,3,70,300,27
+ CONTROL "Avatar only mode",IDC_DISCONDICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,81,278,8
GROUPBOX "Units",IDC_STATIC,3,107,299,80,WS_GROUP
LTEXT "Temperature",IDC_STATIC,8,116,53,8
CONTROL "Celsius",IDC_T1,"Button",BS_AUTORADIOBUTTON,65,116,40,8
diff --git a/protocols/Weather/src/proto.h b/protocols/Weather/src/proto.h
new file mode 100644
index 0000000000..6e1747b8c2
--- /dev/null
+++ b/protocols/Weather/src/proto.h
@@ -0,0 +1,218 @@
+#pragma once
+
+struct MYOPTIONS
+{
+ // main options
+ uint8_t AutoUpdate;
+ uint8_t CAutoUpdate;
+ uint8_t StartupUpdate;
+ uint8_t UpdateOnlyConditionChanged;
+ uint8_t RemoveOldData;
+ uint8_t MakeItalic;
+
+ uint16_t UpdateTime;
+ uint16_t AvatarSize;
+
+ // units
+ uint16_t tUnit;
+ uint16_t wUnit;
+ uint16_t vUnit;
+ uint16_t pUnit;
+ uint16_t dUnit;
+ uint16_t eUnit;
+ wchar_t DegreeSign[4];
+ uint8_t DoNotAppendUnit;
+ uint8_t NoFrac;
+
+ // advanced
+ uint8_t DisCondIcon;
+
+ // popup options
+ uint8_t UpdatePopup;
+ uint8_t AlertPopup;
+ uint8_t PopupOnChange;
+ uint8_t ShowWarnings;
+
+ // popup colors
+ uint8_t UseWinColors;
+ COLORREF BGColour;
+ COLORREF TextColour;
+
+ // popup actions
+ uint32_t LeftClickAction;
+ uint32_t RightClickAction;
+
+ // popup delay
+ uint32_t pDelay;
+
+ // other misc stuff
+ wchar_t Default[64];
+ MCONTACT DefStn;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Protocol class
+
+class CWeatherProto : public PROTO<CWeatherProto>
+{
+ friend class CEditDlg;
+ friend class COptionsDlg;
+ friend class CPopupOptsDlg;
+ friend class CBriefInfoDlg;
+ friend class COptionsTextDlg;
+
+ class CProtoImpl
+ {
+ friend class CWeatherProto;
+ CWeatherProto &m_proto;
+
+ CTimer m_start, m_update;
+
+ void OnStart(CTimer *pTimer)
+ {
+ pTimer->Stop();
+ m_proto.StartUpdate();
+ }
+
+ void OnUpdate(CTimer *)
+ {
+ m_proto.DoUpdate();
+ }
+
+ CProtoImpl(CWeatherProto &pro) :
+ m_proto(pro),
+ m_start(Miranda_GetSystemWindow(), UINT_PTR(this) + 1),
+ m_update(Miranda_GetSystemWindow(), UINT_PTR(this) + 2)
+ {
+ m_start.OnEvent = Callback(this, &CProtoImpl::OnStart);
+ m_update.OnEvent = Callback(this, &CProtoImpl::OnUpdate);
+ }
+ }
+ m_impl;
+
+ void DoUpdate();
+ void StartUpdate();
+
+ // contacts
+ INT_PTR __cdecl ViewLog(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl LoadForecast(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl WeatherMap(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl EditSettings(WPARAM wParam, LPARAM lParam);
+
+ int __cdecl BriefInfoEvt(WPARAM wParam, LPARAM lParam);
+
+ bool IsMyContact(MCONTACT hContact);
+
+ // conversions
+ void numToStr(double num, wchar_t *str, size_t strSize);
+
+ void GetTemp(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
+ void GetSpeed(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
+ void GetPressure(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
+ void GetDist(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
+ void GetElev(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
+
+ // data
+ void ConvertDataValue(struct WIDATAITEM *UpdateData, wchar_t *Data);
+ void EraseAllInfo(void);
+ void GetDataValue(WIDATAITEM *UpdateData, wchar_t *Data, wchar_t **szData);
+
+ // http
+ int InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **szData);
+
+ // menu items
+ void InitMenuItems();
+ void UpdateMenu(BOOL State);
+
+ INT_PTR __cdecl EnableDisableCmd(WPARAM wParam, LPARAM lParam);
+
+ // mwin
+ void InitMwin(void);
+ void DestroyMwin(void);
+
+ int __cdecl BuildContactMenu(WPARAM wparam, LPARAM lparam);
+
+ // options
+ void LoadOptions();
+ void SaveOptions();
+ void RestartTimer();
+ void InitPopupOptions(WPARAM);
+
+ int __cdecl OptInit(WPARAM wParam, LPARAM lParam);
+
+ CMStringW GetTextValue(int c);
+
+ // popups
+ int WPShowMessage(const wchar_t *lpzText, int kind);
+ int WeatherPopup(MCONTACT hContact, bool bNew);
+
+ // search
+ int IDSearch(wchar_t *id, const int searchId);
+ int IDSearchProc(wchar_t *sID, const int searchId, struct WIIDSEARCH *sData, wchar_t *svc, wchar_t *svcname);
+
+ int NameSearch(wchar_t *name, const int searchId);
+ int NameSearchProc(wchar_t *name, const int searchId, struct WINAMESEARCH *sData, wchar_t *svc, wchar_t *svcname);
+
+ void __cdecl NameSearchThread(void *);
+ void __cdecl BasicSearchThread(void *);
+
+ // update weather
+ HANDLE hUpdateMutex;
+
+ int GetWeatherData(MCONTACT hContact);
+ int UpdateWeather(MCONTACT hContact);
+ void UpdateListAdd(MCONTACT hContact);
+ MCONTACT UpdateGetFirst();
+ void DestroyUpdateList(void);
+
+ void __cdecl UpdateThread(void *);
+ void UpdateAll(BOOL AutoUpdate, BOOL RemoveOld);
+
+ INT_PTR __cdecl UpdateSingleStation(WPARAM, LPARAM);
+ INT_PTR __cdecl UpdateSingleRemove(WPARAM, LPARAM);
+
+ INT_PTR __cdecl UpdateAllInfo(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl UpdateAllRemove(WPARAM wParam, LPARAM lParam);
+
+ // user info
+ int __cdecl UserInfoInit(WPARAM, LPARAM);
+
+public:
+ CWeatherProto(const char *protoName, const wchar_t *userName);
+ ~CWeatherProto();
+
+ MYOPTIONS opt;
+
+ INT_PTR __cdecl BriefInfo(WPARAM, LPARAM);
+
+ static LRESULT CALLBACK CWeatherProto::PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ // PROTO_INTERFACE
+ MCONTACT AddToList(int flags, PROTOSEARCHRESULT *psr) override;
+ HANDLE SearchBasic(const wchar_t *id) override;
+ HANDLE SearchAdvanced(MWindow owner) override;
+ MWindow CreateExtendedSearchUI(MWindow owner) override;
+
+ INT_PTR GetCaps(int type, MCONTACT hContact) override;
+ int SetStatus(int iNewStatus) override;
+
+ bool OnContactDeleted(MCONTACT, uint32_t flags) override;
+ void OnModulesLoaded() override;
+ void OnShutdown() override;
+};
+
+typedef CProtoDlgBase<CWeatherProto> CWeatherDlgBase;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Plugin class
+
+struct CMPlugin : public ACCPROTOPLUGIN<CWeatherProto>
+{
+ CMPlugin();
+
+ HINSTANCE hIconsDll = nullptr;
+ CMOption<bool> bPopups;
+
+ int Load() override;
+ int Unload() override;
+};
diff --git a/protocols/Weather/src/resource.h b/protocols/Weather/src/resource.h
index 67e9006fb3..28b2aa9163 100644
--- a/protocols/Weather/src/resource.h
+++ b/protocols/Weather/src/resource.h
@@ -58,7 +58,6 @@
#define IDC_DAutoUpdate 2030
#define IDC_IURL 2032
#define IDC_MURL 2033
-#define IDC_PROTOCOND 2034
#define IDC_Overwrite 2035
#define IDC_UPDCONDCHG 2036
#define IDC_REMOVEOLD 2037
diff --git a/protocols/Weather/src/stdafx.h b/protocols/Weather/src/stdafx.h
index e3df248c79..59f2e4fa38 100644
--- a/protocols/Weather/src/stdafx.h
+++ b/protocols/Weather/src/stdafx.h
@@ -62,6 +62,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "resource.h"
#include "version.h"
+#include "proto.h"
//============ CONSTANTS ============
@@ -86,9 +87,6 @@ enum EWeatherCondition
MAX_COND
};
-// status
-#define NOSTATUSDATA 1
-
// limits
#define MAX_TEXT_SIZE 4096
#define MAX_DATA_LEN 1024
@@ -105,73 +103,22 @@ enum EWeatherCondition
#define UM_SETCONTACT 40000
// weather update error codes
-#define INVALID_ID_FORMAT 10
-#define INVALID_SVC 11
-#define INVALID_ID 12
-#define SVC_NOT_FOUND 20
-#define NETLIB_ERROR 30
-#define DATA_EMPTY 40
-#define DOC_NOT_FOUND 42
-#define DOC_TOO_SHORT 43
-#define UNKNOWN_ERROR 99
+#define INVALID_ID_FORMAT 10
+#define INVALID_SVC 11
+#define INVALID_ID 12
+#define SVC_NOT_FOUND 20
+#define NETLIB_ERROR 30
+#define DATA_EMPTY 40
+#define DOC_NOT_FOUND 42
+#define DOC_TOO_SHORT 43
+#define UNKNOWN_ERROR 99
+
+#define SM_WEATHERALERT 16
+#define WM_UPDATEDATA (WM_USER + 2687)
// defaults constants
#define VAR_LIST_OPT TranslateT("%c\tcurrent condition\n%d\tcurrent date\n%e\tdewpoint\n%f\tfeel-like temp\n%h\ttoday's high\n%i\twind direction\n%l\ttoday's low\n%m\thumidity\n%n\tstation name\n%p\tpressure\n%r\tsunrise time\n%s\tstation ID\n%t\ttemperature\n%u\tupdate time\n%v\tvisibility\n%w\twind speed\n%y\tsun set\n----------\n\\n\tnew line")
-//============ OPTION STRUCT ============
-
-// option struct
-struct MYOPTIONS
-{
- // main options
- uint8_t AutoUpdate;
- uint8_t CAutoUpdate;
- uint8_t StartupUpdate;
- uint8_t NoProtoCondition;
- uint8_t UpdateOnlyConditionChanged;
- uint8_t RemoveOldData;
- uint8_t MakeItalic;
-
- uint16_t UpdateTime;
- uint16_t AvatarSize;
-
- // units
- uint16_t tUnit;
- uint16_t wUnit;
- uint16_t vUnit;
- uint16_t pUnit;
- uint16_t dUnit;
- uint16_t eUnit;
- wchar_t DegreeSign[4];
- uint8_t DoNotAppendUnit;
- uint8_t NoFrac;
-
- // advanced
- uint8_t DisCondIcon;
-
- // popup options
- uint8_t UpdatePopup;
- uint8_t AlertPopup;
- uint8_t PopupOnChange;
- uint8_t ShowWarnings;
-
- // popup colors
- uint8_t UseWinColors;
- COLORREF BGColour;
- COLORREF TextColour;
-
- // popup actions
- uint32_t LeftClickAction;
- uint32_t RightClickAction;
-
- // popup delay
- uint32_t pDelay;
-
- // other misc stuff
- wchar_t Default[64];
- MCONTACT DefStn;
-};
-
//============ STRUCT USED TO MAKE AN UPDATE LIST ============
struct WCONTACTLIST {
MCONTACT hContact;
@@ -182,8 +129,6 @@ typedef struct WCONTACTLIST UPDATELIST;
extern UPDATELIST *UpdateListHead, *UpdateListTail;
-void DestroyUpdateList(void);
-
//============ DATA FORMAT STRUCT ============
#define WID_NORMAL 0
@@ -298,15 +243,9 @@ extern WIDATALIST *WIHead, *WITail;
extern HWND hPopupWindow, hWndSetup;
-extern MYOPTIONS opt;
-
-extern unsigned status, old_status;
-
extern MWindowList hDataWindowList, hWindowList;
-extern HNETLIBUSER hNetlibUser;
-extern HANDLE hHookWeatherUpdated, hHookWeatherError, hTBButton, hUpdateMutex;
-extern UINT_PTR timerId;
+extern HANDLE hTBButton;
extern HGENMENU hMwinMenu;
@@ -317,35 +256,9 @@ extern bool g_bIsUtf;
//============ FUNCTION PRIMITIVES ============
// functions in weather_addstn.c
-INT_PTR WeatherAddToList(WPARAM wParam,LPARAM lParam);
BOOL CheckSearch();
-int IDSearch(wchar_t *id, const int searchId);
-int NameSearch(wchar_t *name, const int searchId);
-
-INT_PTR WeatherBasicSearch(WPARAM wParam,LPARAM lParam);
-INT_PTR WeatherCreateAdvancedSearchUI(WPARAM wParam, LPARAM lParam);
-INT_PTR WeatherAdvancedSearch(WPARAM wParam, LPARAM lParam);
-
-int WeatherAdd(WPARAM wParam, LPARAM lParam);
-
-// functions used in weather_contacts.c
-INT_PTR ViewLog(WPARAM wParam,LPARAM lParam);
-INT_PTR LoadForecast(WPARAM wParam,LPARAM lParam);
-INT_PTR WeatherMap(WPARAM wParam,LPARAM lParam);
-INT_PTR EditSettings(WPARAM wParam,LPARAM lParam);
-
-int ContactDeleted(WPARAM wParam,LPARAM lParam);
-
-BOOL IsMyContact(MCONTACT hContact);
-
// functions in weather_conv.c
-void GetTemp(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
-void GetSpeed(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
-void GetPressure(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
-void GetDist(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
-void GetElev(wchar_t *tempchar, wchar_t *unit, wchar_t *str);
-
void ClearStatusIcons();
int MapCondToStatus(MCONTACT hContact);
HICON GetStatusIcon(MCONTACT hContact);
@@ -371,10 +284,6 @@ void GetStationID(MCONTACT hContact, wchar_t* id, int idlen);
WEATHERINFO LoadWeatherInfo(MCONTACT Change);
int DBGetData(MCONTACT hContact, char *setting, DBVARIANT *dbv);
-void EraseAllInfo(void);
-
-void GetDataValue(WIDATAITEM *UpdateData, wchar_t *Data, wchar_t** szInfo);
-void ConvertDataValue(WIDATAITEM *UpdateData, wchar_t *Data);
void wSetData(char *&Data, const char *Value);
void wSetData(wchar_t *&Data, const char *Value);
void wSetData(wchar_t *&Data, const wchar_t *Value);
@@ -383,10 +292,6 @@ void wfree(wchar_t *&Data);
void DBDataManage(MCONTACT hContact, uint16_t Mode, WPARAM wParam, LPARAM lParam);
-// functions in weather_http.c
-int InternetDownloadFile (char *szUrl, char *cookie, char *userAgent, wchar_t** szData);
-void NetlibInit();
-
// functions in weather_ini.c
WIDATA* GetWIData(wchar_t *pszServ);
@@ -395,74 +300,26 @@ bool IsContainedInCondList(const wchar_t *pszStr, WICONDLIST *List);
void DestroyWIList();
bool LoadWIData(bool dial);
-INT_PTR CALLBACK DlgPopupOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-
// functions in weather_info.c
void GetINIInfo(wchar_t *pszSvc);
wchar_t* GetINIVersionNum(int iVersion);
+const wchar_t *GetDefaultText(int c);
void MoreVarList();
-// functions in weather_opt.c
-void LoadOptions();
-void SaveOptions();
-
-int OptInit(WPARAM wParam,LPARAM lParam);
-
-CMStringW GetTextValue(int c);
-const wchar_t* GetDefaultText(int c);
-
-// functions in weather_popup.c
-int WeatherPopup(WPARAM wParam, LPARAM lParam);
-int WeatherError(WPARAM wParam, LPARAM lParam);
-int WPShowMessage(const wchar_t* lpzText, uint16_t kind);
-
-LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
// functions in weather_svcs.c
void InitServices(void);
-INT_PTR WeatherSetStatus(WPARAM new_status, LPARAM lParam);
-INT_PTR WeatherGetCaps(WPARAM wParam, LPARAM lParam);
-INT_PTR WeatherGetName(WPARAM wParam, LPARAM lParam);
-INT_PTR WeatherGetStatus(WPARAM wParam, LPARAM lParam);
INT_PTR WeatherLoadIcon(WPARAM wParam, LPARAM lParam);
-void UpdateMenu(BOOL State);
-void UpdatePopupMenu(BOOL State);
-void AddMenuItems();
void AvatarDownloaded(MCONTACT hContact);
-// functions in weather_update.c
-int UpdateWeather(MCONTACT hContact);
-
-void UpdateAll(BOOL AutoUpdate, BOOL RemoveOld);
-INT_PTR UpdateSingleStation(WPARAM wParam,LPARAM lParam);
-INT_PTR UpdateAllInfo(WPARAM wParam,LPARAM lParam);
-INT_PTR UpdateSingleRemove(WPARAM wParam,LPARAM lParam);
-INT_PTR UpdateAllRemove(WPARAM wParam,LPARAM lParam);
-
-int GetWeatherData(MCONTACT hContact);
-
-void CALLBACK timerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
-void CALLBACK timerProc2(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
-
// function from multiwin module
-void InitMwin(void);
-void DestroyMwin(void);
INT_PTR Mwin_MenuClicked(WPARAM wParam, LPARAM lParam);
-int BuildContactMenu(WPARAM wparam, LPARAM lparam);
void UpdateMwinData(MCONTACT hContact);
void removeWindow(MCONTACT hContact);
-// functions in weather_userinfo.c
-int UserInfoInit(WPARAM wParam, LPARAM lParam);
-
-#define WM_UPDATEDATA WM_USER + 2687
-
-int BriefInfo(WPARAM wParam, LPARAM lParam);
-
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
// UI Classes
class WeatherMyDetailsDlg : public CUserInfoPageDlg
@@ -476,17 +333,3 @@ public:
void onClick_Reload(CCtrlButton *);
};
-
-//============ Plugin Class ============
-
-struct CMPlugin : public PLUGIN<CMPlugin>
-{
- CMPlugin();
-
- HINSTANCE hIconsDll = nullptr;
- CMOption<bool> bPopups;
-
- int Load() override;
- int Unload() override;
-};
-
diff --git a/protocols/Weather/src/weather.cpp b/protocols/Weather/src/weather.cpp
index f5e6bb2e7b..f84a009ff8 100644
--- a/protocols/Weather/src/weather.cpp
+++ b/protocols/Weather/src/weather.cpp
@@ -33,18 +33,8 @@ 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;
@@ -77,11 +67,9 @@ static const PLUGININFOEX pluginInfoEx =
};
CMPlugin::CMPlugin() :
- PLUGIN<CMPlugin>(MODULENAME, pluginInfoEx),
+ ACCPROTOPLUGIN<CWeatherProto>(MODULENAME, pluginInfoEx),
bPopups(MODULENAME, "UsePopup", true)
{
- opt.NoProtoCondition = g_plugin.getByte("NoStatus", true);
- RegisterProtocol((opt.NoProtoCondition) ? PROTOTYPE_VIRTUAL : PROTOTYPE_PROTOCOL);
SetUniqueId("ID");
}
@@ -91,21 +79,7 @@ extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOC
/////////////////////////////////////////////////////////////////////////////////////////
-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)
+static int OnToolbarLoaded(WPARAM, LPARAM)
{
TTBButton ttb = {};
ttb.name = LPGEN("Enable/disable auto update");
@@ -119,23 +93,8 @@ int OnToolbarLoaded(WPARAM, LPARAM)
return 0;
}
-// weather protocol initialization function
-// run after the event ME_SYSTEM_MODULESLOADED occurs
-int WeatherInit(WPARAM, LPARAM)
+static int OnModulesLoaded(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;
}
@@ -162,37 +121,15 @@ int CMPlugin::Load()
// 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);
+ HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
hDataWindowList = WindowList_Create();
hWindowList = WindowList_Create();
- hUpdateMutex = CreateMutex(nullptr, FALSE, nullptr);
-
// initialize weather protocol services
InitServices();
@@ -208,7 +145,7 @@ int CMPlugin::Load()
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);
+ SetWindowLongPtr(hPopupWindow, GWLP_WNDPROC, (LONG_PTR)&CWeatherProto::PopupWndProc);
return 0;
}
@@ -220,20 +157,11 @@ 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;
}
diff --git a/protocols/Weather/src/weather_addstn.cpp b/protocols/Weather/src/weather_addstn.cpp
index eb2a85b9fb..3704dc68c4 100644
--- a/protocols/Weather/src/weather_addstn.cpp
+++ b/protocols/Weather/src/weather_addstn.cpp
@@ -28,18 +28,16 @@ to the contact list. Contain code for both name and ID search.
static int sttSearchId = -1;
static wchar_t name1[256];
-// ============ ADDING NEW STATION ============
-
+/////////////////////////////////////////////////////////////////////////////////////////
// protocol service function for adding a new contact onto contact list
-// lParam = PROTOSEARCHRESULT
-INT_PTR WeatherAddToList(WPARAM, LPARAM lParam)
+
+MCONTACT CWeatherProto::AddToList(int, PROTOSEARCHRESULT *psr)
{
- PROTOSEARCHRESULT *psr = (PROTOSEARCHRESULT*)lParam;
if (!psr || !psr->email.w)
return 0;
// search for existing contact
- for (auto &hContact : Contacts(MODULENAME)) {
+ for (auto &hContact : AccContacts()) {
DBVARIANT dbv;
// check ID to see if the contact already exist in the database
if (!g_plugin.getWString(hContact, "ID", &dbv)) {
@@ -74,54 +72,55 @@ INT_PTR WeatherAddToList(WPARAM, LPARAM lParam)
// set settings by obtaining the default for the service
if (psr->lastName.w[0] != 0) {
WIDATA *sData = GetWIData(svc);
- g_plugin.setWString(hContact, "MapURL", sData->DefaultMap);
- g_plugin.setString(hContact, "InfoURL", sData->DefaultURL);
+ setWString(hContact, "MapURL", sData->DefaultMap);
+ setString(hContact, "InfoURL", sData->DefaultURL);
}
else { // if no valid service is found, create empty strings for MapURL and InfoURL
- g_plugin.setString(hContact, "MapURL", "");
- g_plugin.setString(hContact, "InfoURL", "");
+ setString(hContact, "MapURL", "");
+ setString(hContact, "InfoURL", "");
}
// write the other info and settings to the database
- g_plugin.setWString(hContact, "ID", psr->email.w);
- g_plugin.setWString(hContact, "Nick", psr->nick.w);
- g_plugin.setWord(hContact, "Status", ID_STATUS_OFFLINE);
+ setWString(hContact, "ID", psr->email.w);
+ setWString(hContact, "Nick", psr->nick.w);
+ setWord(hContact, "Status", ID_STATUS_OFFLINE);
AvatarDownloaded(hContact);
wchar_t str[256];
mir_snwprintf(str, TranslateT("Current weather information for %s."), psr->nick.w);
- g_plugin.setWString(hContact, "About", str);
+ setWString(hContact, "About", str);
// make the last update tags to something invalid
- g_plugin.setString(hContact, "LastLog", "never");
- g_plugin.setString(hContact, "LastCondition", "None");
- g_plugin.setString(hContact, "LastTemperature", "None");
+ setString(hContact, "LastLog", "never");
+ setString(hContact, "LastCondition", "None");
+ setString(hContact, "LastTemperature", "None");
// ignore status change
db_set_dw(hContact, "Ignore", "Mask", 8);
// if no default station is found, set the new contact as default station
if (opt.Default[0] == 0) {
- DBVARIANT dbv;
GetStationID(hContact, opt.Default, _countof(opt.Default));
opt.DefStn = hContact;
- if (!g_plugin.getWString(hContact, "Nick", &dbv)) {
+ ptrW wszNick(g_plugin.getWStringA(hContact, "Nick"));
+ if (mir_wstrlen(wszNick)) {
// notification message box
- mir_snwprintf(str, TranslateT("%s is now the default weather station"), dbv.pwszVal);
- db_free(&dbv);
+ mir_snwprintf(str, TranslateT("%s is now the default weather station"), wszNick);
MessageBox(nullptr, str, TranslateT("Weather Protocol"), MB_OK | MB_ICONINFORMATION);
}
+
g_plugin.setWString("Default", opt.Default);
}
+
// display the Edit Settings dialog box
EditSettings(hContact, 0);
- return (INT_PTR)hContact;
+ return hContact;
}
-// ============ WARNING DIALOG ============
+/////////////////////////////////////////////////////////////////////////////////////////
+// shows a message box and cancel search if update is in process
-// show a message box and cancel search if update is in process
BOOL CheckSearch()
{
if (UpdateListHead != nullptr) {
@@ -131,53 +130,36 @@ BOOL CheckSearch()
return TRUE;
}
-// ============ BASIC ID SEARCH ============
-
+/////////////////////////////////////////////////////////////////////////////////////////
// A timer process for the ID search (threaded)
-static void __cdecl BasicSearchTimerProc(void *pParam)
+
+void __cdecl CWeatherProto::BasicSearchThread(void *pParam)
{
ptrW sID((wchar_t *)pParam);
- int result;
// search only when it's not current updating weather.
if (CheckSearch())
- result = IDSearch(sID, sttSearchId);
+ IDSearch(sID, sttSearchId);
// broadcast the search result
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)sttSearchId);
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)sttSearchId);
// exit the search
sttSearchId = -1;
}
-// the service function for ID search
-// lParam = ID search string
-INT_PTR WeatherBasicSearch(WPARAM, LPARAM lParam)
+HANDLE CWeatherProto::SearchBasic(const wchar_t *id)
{
if (sttSearchId != -1)
return 0; // only one search at a time
sttSearchId = 1;
- mir_forkthread(BasicSearchTimerProc, mir_a2u((char *)lParam)); // create a thread for the ID search
- return sttSearchId;
+ ForkThread(&CWeatherProto::BasicSearchThread, mir_wstrdup(id));
+ return (HANDLE)sttSearchId;
}
-// ============ NAME SEARCH ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// name search timer process (threaded)
-static void __cdecl NameSearchTimerProc(LPVOID)
-{
- // search only when it's not current updating weather.
- if (CheckSearch())
- if (name1[0] != 0)
- NameSearch(name1, sttSearchId); // search nickname field
-
- // broadcast the result
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)sttSearchId);
-
- // exit the search
- sttSearchId = -1;
-}
static INT_PTR CALLBACK WeatherSearchAdvancedDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM)
{
@@ -194,36 +176,52 @@ static INT_PTR CALLBACK WeatherSearchAdvancedDlgProc(HWND hwndDlg, UINT msg, WPA
return FALSE;
}
-INT_PTR WeatherCreateAdvancedSearchUI(WPARAM, LPARAM lParam)
+MWindow CWeatherProto::CreateExtendedSearchUI(MWindow hwndOwner)
{
- HWND parent = (HWND)lParam;
- if (parent)
- return (INT_PTR)CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SEARCHCITY), parent, WeatherSearchAdvancedDlgProc, 0);
+ if (hwndOwner)
+ return CreateDialogParamW(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SEARCHCITY), hwndOwner, WeatherSearchAdvancedDlgProc, 0);
return 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// service function for name search
-INT_PTR WeatherAdvancedSearch(WPARAM, LPARAM lParam)
+
+void __cdecl CWeatherProto::NameSearchThread(void *)
{
- if (sttSearchId != -1) return 0; //only one search at a time
+ // search only when it's not current updating weather.
+ if (CheckSearch())
+ if (name1[0] != 0)
+ NameSearch(name1, sttSearchId); // search nickname field
+
+ // broadcast the result
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)sttSearchId);
+
+ // exit the search
+ sttSearchId = -1;
+}
+
+HANDLE CWeatherProto::SearchAdvanced(MWindow hwndOwner)
+{
+ if (sttSearchId != -1)
+ return 0; //only one search at a time
sttSearchId = 1;
- GetDlgItemText((HWND)lParam, IDC_SEARCHCITY, name1, _countof(name1));
+ GetDlgItemText(hwndOwner, IDC_SEARCHCITY, name1, _countof(name1));
// search for the weather station using a thread
- mir_forkthread(NameSearchTimerProc);
- return sttSearchId;
+ ForkThread(&CWeatherProto::NameSearchThread);
+ return (HANDLE)sttSearchId;
}
-// ============ SEARCH FOR A WEATHER STATION USING ID ============
-
-// Seaching station ID from a single weather service (Threaded)
+/////////////////////////////////////////////////////////////////////////////////////////
+// Seaching station ID from a single weather service
// sID = search string for the station ID
// searchId = -1
// sData = the ID search data for that particular weather service
// svcname = the name of the weather service that is currently searching (ie. Yahoo Weather)
-int IDSearchProc(wchar_t *sID, const int searchId, WIIDSEARCH *sData, wchar_t *svc, wchar_t *svcname)
+
+int CWeatherProto::IDSearchProc(wchar_t *sID, const int searchId, WIIDSEARCH *sData, wchar_t *svc, wchar_t *svcname)
{
wchar_t str[MAX_DATA_LEN], newID[MAX_DATA_LEN];
@@ -259,16 +257,12 @@ int IDSearchProc(wchar_t *sID, const int searchId, WIIDSEARCH *sData, wchar_t *s
psr.firstName.w = L" ";
psr.lastName.w = svcname;
psr.email.w = newID;
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
return 0;
}
-// ID search (Threaded)
-// sID: the ID to search for
-// searchId: don't change
-// return 0 if no error
-int IDSearch(wchar_t *sID, const int searchId)
+int CWeatherProto::IDSearch(wchar_t *sID, const int searchId)
{
// for a normal ID search (ID != #)
if (mir_wstrcmp(sID, L"#")) {
@@ -289,20 +283,20 @@ int IDSearch(wchar_t *sID, const int searchId)
psr.firstName.w = L" ";
psr.lastName.w = L"";
psr.email.w = TranslateT("<Enter station ID here>"); // to be entered
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
}
return 0;
}
-// ============ SEARCH FOR A WEATHER STATION BY NAME ============
-
+/////////////////////////////////////////////////////////////////////////////////////////
// Seaching station name from a single weather service (Threaded)
// name = the name of the weather station to be searched
// searchId = -1
// sData = the name search data for that particular weather service
// svcname = the name of the weather service that is currently searching (ie. Yahoo Weather)
-int NameSearchProc(wchar_t *name, const int searchId, WINAMESEARCH *sData, wchar_t *svc, wchar_t *svcname)
+
+int CWeatherProto::NameSearchProc(wchar_t *name, const int searchId, WINAMESEARCH *sData, wchar_t *svc, wchar_t *svcname)
{
wchar_t Name[MAX_DATA_LEN], str[MAX_DATA_LEN], sID[MAX_DATA_LEN], *szData = nullptr, *search;
@@ -352,7 +346,7 @@ int NameSearchProc(wchar_t *name, const int searchId, WINAMESEARCH *sData, wchar
psr.lastName.w = svcname;
psr.email.w = sID;
psr.id.w = sID;
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
mir_free(szData);
return 0;
}
@@ -390,7 +384,7 @@ int NameSearchProc(wchar_t *name, const int searchId, WINAMESEARCH *sData, wchar
psr.lastName.w = svcname;
psr.email.w = sID;
psr.id.w = sID;
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)searchId, (LPARAM)&psr);
}
}
}
@@ -403,11 +397,7 @@ int NameSearchProc(wchar_t *name, const int searchId, WINAMESEARCH *sData, wchar
return 1;
}
-// name search (Threaded)
-// name: the station name to search for
-// searchId: don't change
-// return 0 if no error
-int NameSearch(wchar_t *name, const int searchId)
+int CWeatherProto::NameSearch(wchar_t *name, const int searchId)
{
// search every weather service using the search station name
WIDATALIST *Item = WIHead;
@@ -419,13 +409,3 @@ int NameSearch(wchar_t *name, const int searchId)
return 0;
}
-
-// ======================MENU ITEM FUNCTION ============
-
-// add a new weather station via find/add dialog
-int WeatherAdd(WPARAM, LPARAM)
-{
- db_set_s(0, "FindAdd", "LastSearched", "Weather");
- CallService(MS_FINDADD_FINDADD, 0, 0);
- return 0;
-}
diff --git a/protocols/Weather/src/weather_contacts.cpp b/protocols/Weather/src/weather_contacts.cpp
index 2833521275..8db99359c0 100644
--- a/protocols/Weather/src/weather_contacts.cpp
+++ b/protocols/Weather/src/weather_contacts.cpp
@@ -33,11 +33,16 @@ static void OpenUrl(wchar_t *format, wchar_t *id)
Utils_OpenUrlW(loc);
}
-//============ BASIC CONTACTS FUNCTIONS AND LINKS ============
+bool CWeatherProto::IsMyContact(MCONTACT hContact)
+{
+ return !mir_strcmp(m_szModuleName, Proto_GetBaseAccountName(hContact));
+}
+/////////////////////////////////////////////////////////////////////////////////////////
// view weather log for the contact
// wParam = current contact
-INT_PTR ViewLog(WPARAM wParam, LPARAM lParam)
+
+INT_PTR CWeatherProto::ViewLog(WPARAM wParam, LPARAM lParam)
{
// see if the log path is set
DBVARIANT dbv;
@@ -52,9 +57,11 @@ INT_PTR ViewLog(WPARAM wParam, LPARAM lParam)
return 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// read complete forecast
// wParam = current contact
-INT_PTR LoadForecast(WPARAM wParam, LPARAM)
+
+INT_PTR CWeatherProto::LoadForecast(WPARAM wParam, LPARAM)
{
wchar_t id[256], loc2[256];
GetStationID(wParam, id, _countof(id));
@@ -70,9 +77,11 @@ INT_PTR LoadForecast(WPARAM wParam, LPARAM)
return 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// load weather map
// wParam = current contact
-INT_PTR WeatherMap(WPARAM wParam, LPARAM)
+
+INT_PTR CWeatherProto::WeatherMap(WPARAM wParam, LPARAM)
{
wchar_t id[256], loc2[256];
GetStationID(wParam, id, _countof(id));
@@ -90,314 +99,331 @@ INT_PTR WeatherMap(WPARAM wParam, LPARAM)
return 0;
}
-//============ EDIT SETTINGS ============
+/////////////////////////////////////////////////////////////////////////////////////////
+// edit weather settings
+// lParam = current contact
-typedef struct
+class CEditDlg : public CWeatherDlgBase
{
MCONTACT hContact;
HICON hRename;
HICON hUserDetail;
HICON hFile;
HICON hSrchAll;
-} CntSetWndDataType;
-// edit weather settings
-// lParam = current contact
-static INT_PTR CALLBACK DlgProcChange(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- DBVARIANT dbv;
+ CCtrlEdit edtID, edtName;
+ CCtrlButton btnGetName, btnExternal, btnBrowse, btnView1, btnView2, btnReset1, btnReset2, btnSvcInfo, btnChange;
+
wchar_t str[MAX_DATA_LEN], str2[256], city[256], filter[256], *chop;
char loc[512];
OPENFILENAME ofn; // common dialog box structure
- MCONTACT hContact;
WIDATA *sData;
- CntSetWndDataType *wndData = nullptr;
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- wndData = (CntSetWndDataType*)mir_alloc(sizeof(CntSetWndDataType));
- wndData->hContact = hContact = lParam;
- wndData->hRename = Skin_LoadIcon(SKINICON_OTHER_RENAME);
- wndData->hUserDetail = Skin_LoadIcon(SKINICON_OTHER_USERDETAILS);
- wndData->hFile = Skin_LoadIcon(SKINICON_EVENT_FILE);
- wndData->hSrchAll = Skin_LoadIcon(SKINICON_OTHER_SEARCHALL);
+public:
+ CEditDlg(CWeatherProto *ppro, MCONTACT _1) :
+ CWeatherDlgBase(ppro, IDD_EDIT),
+ hContact(_1),
+ edtID(this, IDC_ID),
+ edtName(this, IDC_NAME),
+ btnView1(this, IDC_VIEW1),
+ btnView2(this, IDC_VIEW2),
+ btnReset1(this, IDC_RESET1),
+ btnReset2(this, IDC_RESET2),
+ btnBrowse(this, IDC_BROWSE),
+ btnChange(this, IDC_CHANGE),
+ btnGetName(this, IDC_GETNAME),
+ btnSvcInfo(this, IDC_SVCINFO),
+ btnExternal(this, IDC_External)
+ {
+ edtID.OnChange = Callback(this, &CEditDlg::onChanged_ID);
+ edtName.OnChange = Callback(this, &CEditDlg::onChanged_Name);
+
+ btnView1.OnClick = Callback(this, &CEditDlg::onClick_View1);
+ btnView2.OnClick = Callback(this, &CEditDlg::onClick_View2);
+ btnReset1.OnClick = Callback(this, &CEditDlg::onClick_Reset1);
+ btnReset2.OnClick = Callback(this, &CEditDlg::onClick_Reset2);
+ btnBrowse.OnClick = Callback(this, &CEditDlg::onClick_Browse);
+ btnChange.OnClick = Callback(this, &CEditDlg::onClick_Change);
+ btnGetName.OnClick = Callback(this, &CEditDlg::onClick_GetName);
+ btnSvcInfo.OnClick = Callback(this, &CEditDlg::onClick_SvcInfo);
+ btnExternal.OnClick = Callback(this, &CEditDlg::onClick_External);
+ }
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)wndData);
+ bool OnInitDialog() override
+ {
+ hRename = Skin_LoadIcon(SKINICON_OTHER_RENAME);
+ hUserDetail = Skin_LoadIcon(SKINICON_OTHER_USERDETAILS);
+ hFile = Skin_LoadIcon(SKINICON_EVENT_FILE);
+ hSrchAll = Skin_LoadIcon(SKINICON_OTHER_SEARCHALL);
// set button images
- SendDlgItemMessage(hwndDlg, IDC_GETNAME, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hRename);
- SendDlgItemMessage(hwndDlg, IDC_SVCINFO, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hUserDetail);
- SendDlgItemMessage(hwndDlg, IDC_BROWSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hFile);
- SendDlgItemMessage(hwndDlg, IDC_VIEW1, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hSrchAll);
- SendDlgItemMessage(hwndDlg, IDC_RESET1, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hRename);
- SendDlgItemMessage(hwndDlg, IDC_VIEW2, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hSrchAll);
- SendDlgItemMessage(hwndDlg, IDC_RESET2, BM_SETIMAGE, IMAGE_ICON, (LPARAM)wndData->hRename);
+ SendDlgItemMessage(m_hwnd, IDC_GETNAME, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hRename);
+ SendDlgItemMessage(m_hwnd, IDC_SVCINFO, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hUserDetail);
+ SendDlgItemMessage(m_hwnd, IDC_BROWSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hFile);
+ SendDlgItemMessage(m_hwnd, IDC_VIEW1, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hSrchAll);
+ SendDlgItemMessage(m_hwnd, IDC_RESET1, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hRename);
+ SendDlgItemMessage(m_hwnd, IDC_VIEW2, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hSrchAll);
+ SendDlgItemMessage(m_hwnd, IDC_RESET2, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hRename);
// make all buttons flat
- SendDlgItemMessage(hwndDlg, IDC_GETNAME, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_SVCINFO, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_BROWSE, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_VIEW1, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_RESET1, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_VIEW2, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_RESET2, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_GETNAME, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_SVCINFO, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_BROWSE, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_VIEW1, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_RESET1, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_VIEW2, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_RESET2, BUTTONSETASFLATBTN, TRUE, 0);
// set tooltip for the buttons
- SendDlgItemMessage(hwndDlg, IDC_GETNAME, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Get city name from ID"), BATF_UNICODE);
- SendDlgItemMessage(hwndDlg, IDC_SVCINFO, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Weather INI information"), BATF_UNICODE);
- SendDlgItemMessage(hwndDlg, IDC_BROWSE, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Browse"), BATF_UNICODE);
- SendDlgItemMessage(hwndDlg, IDC_VIEW1, BUTTONADDTOOLTIP, (WPARAM)LPGENW("View webpage"), BATF_UNICODE);
- SendDlgItemMessage(hwndDlg, IDC_RESET1, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Reset to default"), BATF_UNICODE);
- SendDlgItemMessage(hwndDlg, IDC_VIEW2, BUTTONADDTOOLTIP, (WPARAM)LPGENW("View webpage"), BATF_UNICODE);
- SendDlgItemMessage(hwndDlg, IDC_RESET2, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Reset to default"), BATF_UNICODE);
+ SendDlgItemMessage(m_hwnd, IDC_GETNAME, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Get city name from ID"), BATF_UNICODE);
+ SendDlgItemMessage(m_hwnd, IDC_SVCINFO, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Weather INI information"), BATF_UNICODE);
+ SendDlgItemMessage(m_hwnd, IDC_BROWSE, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Browse"), BATF_UNICODE);
+ SendDlgItemMessage(m_hwnd, IDC_VIEW1, BUTTONADDTOOLTIP, (WPARAM)LPGENW("View webpage"), BATF_UNICODE);
+ SendDlgItemMessage(m_hwnd, IDC_RESET1, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Reset to default"), BATF_UNICODE);
+ SendDlgItemMessage(m_hwnd, IDC_VIEW2, BUTTONADDTOOLTIP, (WPARAM)LPGENW("View webpage"), BATF_UNICODE);
+ SendDlgItemMessage(m_hwnd, IDC_RESET2, BUTTONADDTOOLTIP, (WPARAM)LPGENW("Reset to default"), BATF_UNICODE);
// save the handle for the contact
- WindowList_Add(hWindowList, hwndDlg, hContact);
+ WindowList_Add(hWindowList, m_hwnd, hContact);
// start to get the settings
// if the setting not exist, leave the dialog box blank
- if (!g_plugin.getWString(hContact, "ID", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_ID, dbv.pwszVal);
+ DBVARIANT dbv;
+ if (!m_proto->getWString(hContact, "ID", &dbv)) {
+ SetDlgItemText(m_hwnd, IDC_ID, dbv.pwszVal);
// check if the station is a default station
- CheckDlgButton(hwndDlg, IDC_DEFA, mir_wstrcmp(dbv.pwszVal, opt.Default) != 0 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_DEFA, mir_wstrcmp(dbv.pwszVal, m_proto->opt.Default) != 0 ? BST_CHECKED : BST_UNCHECKED);
db_free(&dbv);
}
- if (!g_plugin.getWString(hContact, "Nick", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_NAME, dbv.pwszVal);
+ if (!m_proto->getWString(hContact, "Nick", &dbv)) {
+ SetDlgItemText(m_hwnd, IDC_NAME, dbv.pwszVal);
db_free(&dbv);
}
- if (!g_plugin.getWString(hContact, "Log", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_LOG, dbv.pwszVal);
+ if (!m_proto->getWString(hContact, "Log", &dbv)) {
+ SetDlgItemText(m_hwnd, IDC_LOG, dbv.pwszVal);
// if the log path is not empty, check the checkbox for external log
- if (dbv.pwszVal[0]) CheckDlgButton(hwndDlg, IDC_External, BST_CHECKED);
+ if (dbv.pwszVal[0]) CheckDlgButton(m_hwnd, IDC_External, BST_CHECKED);
db_free(&dbv);
}
// enable/disable the browse button depending on the value of external log checkbox
- EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE), (uint8_t)IsDlgButtonChecked(hwndDlg, IDC_External));
+ EnableWindow(GetDlgItem(m_hwnd, IDC_BROWSE), (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_External));
// other checkbox options
- CheckDlgButton(hwndDlg, IDC_DPop, g_plugin.getByte(hContact, "DPopUp", FALSE) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_DAutoUpdate, g_plugin.getByte(hContact, "DAutoUpdate", FALSE) ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_Internal, g_plugin.getByte(hContact, "History", 0) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_DPop, m_proto->getByte(hContact, "DPopUp", FALSE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_DAutoUpdate, m_proto->getByte(hContact, "DAutoUpdate", FALSE) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_Internal, m_proto->getByte(hContact, "History", 0) ? BST_CHECKED : BST_UNCHECKED);
- if (!g_plugin.getWString(hContact, "InfoURL", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_IURL, dbv.pwszVal);
+ if (!m_proto->getWString(hContact, "InfoURL", &dbv)) {
+ SetDlgItemText(m_hwnd, IDC_IURL, dbv.pwszVal);
db_free(&dbv);
}
- if (!g_plugin.getWString(hContact, "MapURL", &dbv)) {
- SetDlgItemText(hwndDlg, IDC_MURL, dbv.pwszVal);
+ if (!m_proto->getWString(hContact, "MapURL", &dbv)) {
+ SetDlgItemText(m_hwnd, IDC_MURL, dbv.pwszVal);
db_free(&dbv);
}
// display the dialog box and free memory
- Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, MODULENAME, "EditSetting_");
- ShowWindow(hwndDlg, SW_SHOW);
- break;
-
- case WM_COMMAND:
- wndData = (CntSetWndDataType*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- hContact = wndData ? wndData->hContact : NULL;
-
- switch (LOWORD(wParam)) {
- case IDC_ID:
- // check if there are 2 parts in the ID (svc/id) seperated by "/"
- // if not, don't let user change the setting
- GetDlgItemText(hwndDlg, IDC_ID, str, _countof(str));
- chop = wcschr(str, '/');
- if (chop == nullptr)
- EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGE), FALSE);
- else
- EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGE), TRUE);
- break;
-
- case IDC_NAME:
- // check if station name is entered
- // if not, don't let user change the setting
- GetDlgItemText(hwndDlg, IDC_NAME, str, _countof(str));
- EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGE), str[0] != 0);
- break;
-
- case IDC_GETNAME:
- // the button for getting station name from the internet
- // this function uses the ID search for add/find weather station
- if (!CheckSearch())
- return TRUE; // don't download if update is in progress
-
- // get the weather update data using the string in the ID field
- GetDlgItemText(hwndDlg, IDC_ID, str, _countof(str));
- GetSvc(str);
- sData = GetWIData(str);
- GetDlgItemText(hwndDlg, IDC_ID, str, _countof(str));
- GetID(str);
- // if ID search is available, do it
- if (sData->IDSearch.Available) {
- // load the page
- mir_snprintf(loc, sData->IDSearch.SearchURL, str);
- str[0] = 0;
- wchar_t *pData = nullptr;
- if (InternetDownloadFile(loc, nullptr, sData->UserAgent, &pData) == 0) {
- wchar_t *szInfo = pData;
- wchar_t *search = wcsstr(szInfo, sData->IDSearch.NotFoundStr);
-
- // if the page is found (ie. valid ID), get the name of the city
- if (search == nullptr)
- GetDataValue(&sData->IDSearch.Name, str, &szInfo);
- }
- // free memory
- mir_free(pData);
+ Utils_RestoreWindowPositionNoMove(m_hwnd, NULL, MODULENAME, "EditSetting_");
+ ShowWindow(m_hwnd, SW_SHOW);
+ return true;
+ }
+
+ void OnDestroy() override
+ {
+ IcoLib_ReleaseIcon(hFile);
+ IcoLib_ReleaseIcon(hRename);
+ IcoLib_ReleaseIcon(hSrchAll);
+ IcoLib_ReleaseIcon(hUserDetail);
+ SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
+
+ WindowList_Remove(hWindowList, m_hwnd);
+ Utils_SaveWindowPosition(m_hwnd, NULL, MODULENAME, "EditSetting_");
+ }
+
+ void onChanged_ID(CCtrlEdit *)
+ {
+ // check if there are 2 parts in the ID (svc/id) seperated by "/"
+ // if not, don't let user change the setting
+ GetDlgItemText(m_hwnd, IDC_ID, str, _countof(str));
+ chop = wcschr(str, '/');
+ if (chop == nullptr)
+ EnableWindow(GetDlgItem(m_hwnd, IDC_CHANGE), FALSE);
+ else
+ EnableWindow(GetDlgItem(m_hwnd, IDC_CHANGE), TRUE);
+ }
+
+ void onChanged_Name(CCtrlEdit *)
+ {
+ // check if station name is entered
+ // if not, don't let user change the setting
+ GetDlgItemText(m_hwnd, IDC_NAME, str, _countof(str));
+ EnableWindow(GetDlgItem(m_hwnd, IDC_CHANGE), str[0] != 0);
+ }
+
+ void onClick_GetName(CCtrlButton *)
+ {
+ // the button for getting station name from the internet
+ // this function uses the ID search for add/find weather station
+ if (!CheckSearch())
+ return; // don't download if update is in progress
+
+ // get the weather update data using the string in the ID field
+ GetDlgItemText(m_hwnd, IDC_ID, str, _countof(str));
+ GetSvc(str);
+ sData = GetWIData(str);
+ GetDlgItemText(m_hwnd, IDC_ID, str, _countof(str));
+ GetID(str);
+
+ // if ID search is available, do it
+ if (sData->IDSearch.Available) {
+ // load the page
+ mir_snprintf(loc, sData->IDSearch.SearchURL, str);
+ str[0] = 0;
+ wchar_t *pData = nullptr;
+ if (m_proto->InternetDownloadFile(loc, nullptr, sData->UserAgent, &pData) == 0) {
+ wchar_t *szInfo = pData;
+ wchar_t *search = wcsstr(szInfo, sData->IDSearch.NotFoundStr);
+
+ // if the page is found (ie. valid ID), get the name of the city
+ if (search == nullptr)
+ m_proto->GetDataValue(&sData->IDSearch.Name, str, &szInfo);
}
+ // free memory
+ mir_free(pData);
+ }
+
+ // give no station name but only ID if the search is unavailable
+ if (str[0] != 0)
+ SetDlgItemText(m_hwnd, IDC_NAME, str);
+ }
+
+ void onClick_External(CCtrlButton *)
+ {
+ // enable/disable the borwse button depending if the external log is enabled
+ EnableWindow(GetDlgItem(m_hwnd, IDC_BROWSE), (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_External));
+ if (!(uint8_t)IsDlgButtonChecked(m_hwnd, IDC_External))
+ return;
- // give no station name but only ID if the search is unavailable
- if (str[0] != 0)
- SetDlgItemText(hwndDlg, IDC_NAME, str);
- break;
-
- case IDC_External:
- // enable/disable the borwse button depending if the external log is enabled
- EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSE), (uint8_t)IsDlgButtonChecked(hwndDlg, IDC_External));
- if (!(uint8_t)IsDlgButtonChecked(hwndDlg, IDC_External))
- return TRUE;
- __fallthrough;
-
- case IDC_BROWSE:
- // browse for the external log file
- GetDlgItemText(hwndDlg, IDC_LOG, str, _countof(str));
- // Initialize OPENFILENAME
- memset(&ofn, 0, sizeof(OPENFILENAME));
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = hwndDlg;
- ofn.lpstrFile = str;
- ofn.nMaxFile = _countof(str);
-
- // set filters
- mir_snwprintf(filter, L"%s (*.txt)%c*.txt%c%s (*.*)%c*.*%c%c", TranslateT("Text Files"), 0, 0, TranslateT("All Files"), 0, 0, 0);
- ofn.lpstrFilter = filter;
- ofn.nFilterIndex = 1;
- ofn.lpstrFileTitle = nullptr;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = nullptr;
- ofn.Flags = OFN_PATHMUSTEXIST;
-
- // Display a Open dialog box and put the file name on the dialog
- if (GetOpenFileName(&ofn))
- SetDlgItemText(hwndDlg, IDC_LOG, ofn.lpstrFile);
- // if there is no log file specified, disable external logging
- EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGE), ofn.lpstrFile[0] != 0);
- break;
-
- case IDC_VIEW1:
- // view the page for more info
- GetDlgItemText(hwndDlg, IDC_IURL, str, _countof(str));
- if (str[0] == 0)
- return TRUE;
- GetDlgItemText(hwndDlg, IDC_ID, str2, _countof(str2));
+ onClick_Browse(0);
+ }
+
+ void onClick_Browse(CCtrlButton *)
+ {
+ // browse for the external log file
+ GetDlgItemText(m_hwnd, IDC_LOG, str, _countof(str));
+
+ // Initialize OPENFILENAME
+ memset(&ofn, 0, sizeof(OPENFILENAME));
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = m_hwnd;
+ ofn.lpstrFile = str;
+ ofn.nMaxFile = _countof(str);
+
+ // set filters
+ mir_snwprintf(filter, L"%s (*.txt)%c*.txt%c%s (*.*)%c*.*%c%c", TranslateT("Text Files"), 0, 0, TranslateT("All Files"), 0, 0, 0);
+ ofn.lpstrFilter = filter;
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = nullptr;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = nullptr;
+ ofn.Flags = OFN_PATHMUSTEXIST;
+
+ // Display a Open dialog box and put the file name on the dialog
+ if (GetOpenFileName(&ofn))
+ SetDlgItemText(m_hwnd, IDC_LOG, ofn.lpstrFile);
+
+ // if there is no log file specified, disable external logging
+ EnableWindow(GetDlgItem(m_hwnd, IDC_CHANGE), ofn.lpstrFile[0] != 0);
+ }
+
+ void onClick_View1(CCtrlButton *)
+ {
+ // view the page for more info
+ GetDlgItemText(m_hwnd, IDC_IURL, str, _countof(str));
+ if (str[0]) {
+ GetDlgItemText(m_hwnd, IDC_ID, str2, _countof(str2));
OpenUrl(str, str2);
- break;
-
- case IDC_VIEW2:
- // view the page for weather map
- GetDlgItemText(hwndDlg, IDC_MURL, str, _countof(str));
- if (str[0] == 0)
- return TRUE;
- GetDlgItemText(hwndDlg, IDC_ID, str2, _countof(str2));
+ }
+ }
+
+ void onClick_View2(CCtrlButton *)
+ {
+ // view the page for weather map
+ GetDlgItemText(m_hwnd, IDC_MURL, str, _countof(str));
+ if (str[0]) {
+ GetDlgItemText(m_hwnd, IDC_ID, str2, _countof(str2));
OpenUrl(str, str2);
- break;
-
- case IDC_RESET1:
- // reset the more info url to service default
- GetDlgItemText(hwndDlg, IDC_ID, str, _countof(str));
- GetSvc(str);
- sData = GetWIData(str);
- SetDlgItemTextA(hwndDlg, IDC_IURL, sData->DefaultURL);
- break;
-
- case IDC_RESET2:
- // reset the weathe map url to service default
- GetDlgItemText(hwndDlg, IDC_ID, str, _countof(str));
- GetSvc(str);
- sData = GetWIData(str);
- SetDlgItemText(hwndDlg, IDC_MURL, sData->DefaultMap);
- break;
-
- case IDC_SVCINFO:
- // display the information of the ini file used by the weather station
- GetDlgItemText(hwndDlg, IDC_ID, str, _countof(str));
- GetSvc(str);
- GetINIInfo(str);
- break;
-
- case IDC_CHANGE:
- // temporary disable the protocol while applying the change
- // start writing the new settings to database
- GetDlgItemText(hwndDlg, IDC_ID, str, _countof(str));
- g_plugin.setWString(hContact, "ID", str);
- if ((uint8_t)IsDlgButtonChecked(hwndDlg, IDC_DEFA)) { // if default station is set
- mir_wstrcpy(opt.Default, str);
- opt.DefStn = hContact;
- g_plugin.setWString("Default", opt.Default);
- }
- GetDlgItemText(hwndDlg, IDC_NAME, city, _countof(city));
- g_plugin.setWString(hContact, "Nick", city);
- mir_snwprintf(str2, TranslateT("Current weather information for %s."), city);
- if ((uint8_t)IsDlgButtonChecked(hwndDlg, IDC_External)) {
- GetDlgItemText(hwndDlg, IDC_LOG, str, _countof(str));
- g_plugin.setWString(hContact, "Log", str);
- }
- else g_plugin.delSetting(hContact, "Log");
-
- GetDlgItemText(hwndDlg, IDC_IURL, str, _countof(str));
- g_plugin.setWString(hContact, "InfoURL", str);
-
- GetDlgItemText(hwndDlg, IDC_MURL, str, _countof(str));
- g_plugin.setWString(hContact, "MapURL", str);
- g_plugin.setWord(hContact, "Status", ID_STATUS_OFFLINE);
- g_plugin.setWord(hContact, "StatusIcon", -1);
- AvatarDownloaded(hContact);
- g_plugin.setWString(hContact, "About", str2);
- g_plugin.setByte(hContact, "History", (uint8_t)IsDlgButtonChecked(hwndDlg, IDC_Internal));
- g_plugin.setByte(hContact, "Overwrite", (uint8_t)IsDlgButtonChecked(hwndDlg, IDC_Overwrite));
- g_plugin.setByte(hContact, "File", (uint8_t)IsDlgButtonChecked(hwndDlg, IDC_External));
- g_plugin.setByte(hContact, "DPopUp", (uint8_t)IsDlgButtonChecked(hwndDlg, IDC_DPop));
- g_plugin.setByte(hContact, "DAutoUpdate", (uint8_t)IsDlgButtonChecked(hwndDlg, IDC_DAutoUpdate));
-
- // re-enable the protocol and update the data for the station
- g_plugin.setString(hContact, "LastCondition", "None");
- UpdateSingleStation(hContact, 0);
- __fallthrough;
-
- case IDCANCEL:
- // remove the dialog from window list and close it
- DestroyWindow(hwndDlg);
- break;
}
- break;
-
- case WM_CLOSE:
- // remove the dialog from window list and close it
- DestroyWindow(hwndDlg);
- break;
-
- case WM_DESTROY:
- wndData = (CntSetWndDataType*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- IcoLib_ReleaseIcon(wndData->hFile);
- IcoLib_ReleaseIcon(wndData->hRename);
- IcoLib_ReleaseIcon(wndData->hSrchAll);
- IcoLib_ReleaseIcon(wndData->hUserDetail);
- mir_free(wndData);
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
-
- WindowList_Remove(hWindowList, hwndDlg);
- Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, "EditSetting_");
- break;
}
- return FALSE;
-}
-// show edit settings dialog
-// wParam = current contact
-INT_PTR EditSettings(WPARAM wParam, LPARAM)
+ void onClick_Reset1(CCtrlButton *)
+ {
+ // reset the more info url to service default
+ GetDlgItemText(m_hwnd, IDC_ID, str, _countof(str));
+ GetSvc(str);
+ sData = GetWIData(str);
+ SetDlgItemTextA(m_hwnd, IDC_IURL, sData->DefaultURL);
+ }
+
+ void onClick_Reset2(CCtrlButton *)
+ {
+ // reset the weathe map url to service default
+ GetDlgItemText(m_hwnd, IDC_ID, str, _countof(str));
+ GetSvc(str);
+ sData = GetWIData(str);
+ SetDlgItemText(m_hwnd, IDC_MURL, sData->DefaultMap);
+ }
+
+ void onClick_SvcInfo(CCtrlButton *)
+ {
+ // display the information of the ini file used by the weather station
+ GetDlgItemText(m_hwnd, IDC_ID, str, _countof(str));
+ GetSvc(str);
+ GetINIInfo(str);
+ }
+
+ void onClick_Change(CCtrlButton *)
+ {
+ // temporary disable the protocol while applying the change
+ // start writing the new settings to database
+ GetDlgItemText(m_hwnd, IDC_ID, str, _countof(str));
+ g_plugin.setWString(hContact, "ID", str);
+ if ((uint8_t)IsDlgButtonChecked(m_hwnd, IDC_DEFA)) { // if default station is set
+ mir_wstrcpy(m_proto->opt.Default, str);
+ m_proto->opt.DefStn = hContact;
+ g_plugin.setWString("Default", m_proto->opt.Default);
+ }
+ GetDlgItemText(m_hwnd, IDC_NAME, city, _countof(city));
+ g_plugin.setWString(hContact, "Nick", city);
+ mir_snwprintf(str2, TranslateT("Current weather information for %s."), city);
+ if ((uint8_t)IsDlgButtonChecked(m_hwnd, IDC_External)) {
+ GetDlgItemText(m_hwnd, IDC_LOG, str, _countof(str));
+ m_proto->setWString(hContact, "Log", str);
+ }
+ else m_proto->delSetting(hContact, "Log");
+
+ GetDlgItemText(m_hwnd, IDC_IURL, str, _countof(str));
+ m_proto->setWString(hContact, "InfoURL", str);
+
+ GetDlgItemText(m_hwnd, IDC_MURL, str, _countof(str));
+ m_proto->setWString(hContact, "MapURL", str);
+ m_proto->setWord(hContact, "Status", ID_STATUS_OFFLINE);
+ m_proto->setWord(hContact, "StatusIcon", -1);
+ AvatarDownloaded(hContact);
+ m_proto->setWString(hContact, "About", str2);
+ m_proto->setByte(hContact, "History", (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_Internal));
+ m_proto->setByte(hContact, "Overwrite", (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_Overwrite));
+ m_proto->setByte(hContact, "File", (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_External));
+ m_proto->setByte(hContact, "DPopUp", (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_DPop));
+ m_proto->setByte(hContact, "DAutoUpdate", (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_DAutoUpdate));
+
+ // re-enable the protocol and update the data for the station
+ g_plugin.setString(hContact, "LastCondition", "None");
+ m_proto->UpdateSingleStation(hContact, 0);
+ }
+};
+
+INT_PTR CWeatherProto::EditSettings(WPARAM wParam, LPARAM)
{
HWND hEditDlg = WindowList_Find(hWindowList, wParam);
@@ -410,34 +436,30 @@ INT_PTR EditSettings(WPARAM wParam, LPARAM)
else {
// if the dialog box is not opened, open a new one
if (IsMyContact(wParam))
- CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_EDIT), nullptr, DlgProcChange, (LPARAM)wParam);
+ (new CEditDlg(this, wParam))->Create();
}
return 0;
}
-//============ CONTACT DELETION ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// when a contact is deleted, make sure some other contact take over the default station
-// wParam = deleted contact
-int ContactDeleted(WPARAM wParam, LPARAM)
-{
- if (!IsMyContact(wParam))
- return 0;
- removeWindow(wParam);
+bool CWeatherProto::OnContactDeleted(MCONTACT hContact, uint32_t)
+{
+ removeWindow(hContact);
// exit this function if it is not default station
- ptrW tszID(g_plugin.getWStringA(wParam, "ID"));
+ ptrW tszID(getWStringA(hContact, "ID"));
if (tszID != NULL)
if (mir_wstrcmp(tszID, opt.Default))
- return 0;
+ return false;
// now the default station is deleted, try to get a new one
// start looking for other weather stations
- for (auto &hContact : Contacts(MODULENAME)) {
- tszID = g_plugin.getWStringA(hContact, "ID");
+ for (auto &cc: AccContacts()) {
+ tszID = getWStringA(cc, "ID");
if (tszID == NULL)
continue;
@@ -445,15 +467,15 @@ int ContactDeleted(WPARAM wParam, LPARAM)
// this is the first weather station encountered from the search
if (mir_wstrcmp(opt.Default, tszID)) {
wcsncpy_s(opt.Default, tszID, _TRUNCATE);
- opt.DefStn = hContact;
- ptrW tszNick(g_plugin.getWStringA(hContact, "Nick"));
+ opt.DefStn = cc;
+ ptrW tszNick(g_plugin.getWStringA(cc, "Nick"));
if (tszNick != NULL) {
wchar_t str[255];
mir_snwprintf(str, TranslateT("%s is now the default weather station"), (wchar_t*)tszNick);
MessageBox(nullptr, str, TranslateT("Weather Protocol"), MB_OK | MB_ICONINFORMATION);
}
g_plugin.setWString("Default", opt.Default);
- return 0; // exit this function quickly
+ return true;
}
}
@@ -461,11 +483,5 @@ int ContactDeleted(WPARAM wParam, LPARAM)
opt.Default[0] = 0; // no default station
opt.DefStn = NULL;
g_plugin.setWString("Default", opt.Default);
- return 0;
-}
-
-BOOL IsMyContact(MCONTACT hContact)
-{
- const char *szProto = Proto_GetBaseAccountName(hContact);
- return szProto != nullptr && mir_strcmp(MODULENAME, szProto) == 0;
+ return true;
}
diff --git a/protocols/Weather/src/weather_conv.cpp b/protocols/Weather/src/weather_conv.cpp
index f2d18dc240..7b1897834e 100644
--- a/protocols/Weather/src/weather_conv.cpp
+++ b/protocols/Weather/src/weather_conv.cpp
@@ -25,11 +25,11 @@ string conversions, display text parsing, etc
#include "stdafx.h"
-//============ SOME HELPER FUNCTIONS ============
-
+/////////////////////////////////////////////////////////////////////////////////////////
// see if a string is a number
// s = the string to be determined
// return value = true if the string is a number, false if it isn't
+
BOOL is_number(wchar_t *s)
{
BOOL tag = FALSE;
@@ -47,7 +47,7 @@ BOOL is_number(wchar_t *s)
return FALSE;
}
-static void numToStr(double num, wchar_t *str, size_t strSize)
+void CWeatherProto::numToStr(double num, wchar_t *str, size_t strSize)
{
int i = (int)(num * (opt.NoFrac ? 10 : 100));
int u = abs(i);
@@ -69,13 +69,13 @@ static void numToStr(double num, wchar_t *str, size_t strSize)
mir_snwprintf(str, strSize, L"%i", w);
}
-//============ UNIT CONVERSIONS ============
-
+/////////////////////////////////////////////////////////////////////////////////////////
// temperature conversion
// tempchar = the string containing the temperature value
// unit = the unit for temperature
// return value = the converted temperature with degree sign and unit; if fails, return N/A
-void GetTemp(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
+
+void CWeatherProto::GetTemp(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
{
// unit can be C, F
double temp;
@@ -123,11 +123,13 @@ void GetTemp(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
}
}
+/////////////////////////////////////////////////////////////////////////////////////////
// temperature conversion
// tempchar = the string containing the pressure value
// unit = the unit for pressure
// return value = the converted pressure with unit; if fail, return the original string
-void GetPressure(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
+
+void CWeatherProto::GetPressure(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
{
// unit can be kPa, hPa, mb, in, mm, torr
double tempunit = 0, output;
@@ -180,11 +182,13 @@ void GetPressure(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
}
}
+/////////////////////////////////////////////////////////////////////////////////////////
// speed conversion
// tempchar = the string containing the speed value
// unit = the unit for speed
// return value = the converted speed with unit; if fail, return _T(""
-void GetSpeed(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
+
+void CWeatherProto::GetSpeed(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
{
// unit can be km/h, mph, m/s, knots
double tempunit;
@@ -229,11 +233,13 @@ void GetSpeed(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
}
}
+/////////////////////////////////////////////////////////////////////////////////////////
// distance conversion
// tempchar = the string containing the distance value
// unit = the unit for distance
// return value = the converted distance with unit; if fail, return original string
-void GetDist(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
+
+void CWeatherProto::GetDist(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
{
// unit can be km, miles
double tempunit = 0, output;
@@ -269,11 +275,13 @@ void GetDist(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
}
}
+/////////////////////////////////////////////////////////////////////////////////////////
// elevation conversion
// tempchar = the string containing the elevation value
// unit = the unit for elevation
// return value = the converted elevation with unit; if fail, return original string
-void GetElev(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
+
+void CWeatherProto::GetElev(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
{
// unit can be ft, m
double tempunit = 0, output;
@@ -309,8 +317,7 @@ void GetElev(wchar_t *tempchar, wchar_t *unit, wchar_t *str)
}
}
-//============ CONDITION ICON ASSIGNMENT ============
-
+/////////////////////////////////////////////////////////////////////////////////////////
// assign the contact icon (status) from the condition string
// the description may be different between different sources
// cond = the string for weather condition
@@ -373,9 +380,9 @@ uint16_t GetIcon(const wchar_t *cond, WIDATA *Data)
return NA;
}
-//============ STRING CONVERSIONS ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// this function convert the string to the format with 1 upper case followed by lower case char
+
void CaseConv(wchar_t *str)
{
bool nextUp = true;
@@ -391,9 +398,10 @@ void CaseConv(wchar_t *str)
}
}
+/////////////////////////////////////////////////////////////////////////////////////////
// the next 2 functions are copied from miranda source
// str = the string to modify
-//
+
void TrimString(char *str)
{
size_t len, start;
@@ -414,7 +422,9 @@ void TrimString(wchar_t *str)
memmove(str, str + start, (len - start + 1) * sizeof(wchar_t));
}
+/////////////////////////////////////////////////////////////////////////////////////////
// convert \t to tab and \n to linefeed
+
void ConvertBackslashes(char *str)
{
for (char *pstr = str; *pstr; pstr = CharNextA(pstr)) {
@@ -429,9 +439,11 @@ void ConvertBackslashes(char *str)
}
}
+/////////////////////////////////////////////////////////////////////////////////////////
// replace spaces with _T("%20"
// dis = original string
// return value = the modified string with space -> _T("%20"
+
char *GetSearchStr(char *dis)
{
char *pstr = dis;
@@ -448,12 +460,12 @@ char *GetSearchStr(char *dis)
return dis;
}
-//============ ICON ASSIGNMENT ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// make display and history strings
// w = WEATHERINFO data to be parsed
// dis = the string to parse
// return value = the parsed string
+
wchar_t *GetDisplay(WEATHERINFO *w, const wchar_t *dis, wchar_t *str)
{
wchar_t lpzDate[32], chr;
@@ -542,11 +554,11 @@ INT_PTR GetDisplaySvcFunc(WPARAM wParam, LPARAM lParam)
return (INT_PTR)GetDisplay(&winfo, (wchar_t*)lParam, svcReturnText);
}
-//============ ID MANAGEMENT ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// get service data module internal name
// mod/id <- the mod part
// pszID = original 2-part id, return the service internal name
+
void GetSvc(wchar_t *pszID)
{
wchar_t *chop = wcschr(pszID, '/');
@@ -556,9 +568,11 @@ void GetSvc(wchar_t *pszID)
pszID[0] = 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// get the id use for update without the service internal name
// mod/id <- the id part
// pszID = original 2-part id, return the single part id
+
void GetID(wchar_t *pszID)
{
wchar_t *chop = wcschr(pszID, '/');
@@ -568,7 +582,7 @@ void GetID(wchar_t *pszID)
pszID[0] = 0;
}
-//============ WEATHER ERROR CODE ============
+/////////////////////////////////////////////////////////////////////////////////////////
// Get the text when an error code is specified
// code = the error code obtained when updating weather
// str = the string for the error
diff --git a/protocols/Weather/src/weather_data.cpp b/protocols/Weather/src/weather_data.cpp
index 0f3cf9ccc9..2ee99cda25 100644
--- a/protocols/Weather/src/weather_data.cpp
+++ b/protocols/Weather/src/weather_data.cpp
@@ -25,11 +25,11 @@ saving individual weather data for a weather contact.
#include "stdafx.h"
-//============ LOAD WEATHER INFO FROM A CONTACT ============
+/////////////////////////////////////////////////////////////////////////////////////////
// get station ID from DB
// hContact = the current contact handle
// return value = the string for station ID
-//
+
void GetStationID(MCONTACT hContact, wchar_t *id, int idlen)
{
// accessing the database
@@ -37,9 +37,11 @@ void GetStationID(MCONTACT hContact, wchar_t *id, int idlen)
id[0] = 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// initialize weather info by loading values from database
// hContact = current contact handle
// return value = the current weather information in WEATHERINFO struct
+
WEATHERINFO LoadWeatherInfo(MCONTACT hContact)
{
// obtaining values from the DB
@@ -82,8 +84,10 @@ WEATHERINFO LoadWeatherInfo(MCONTACT hContact)
return winfo;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// getting weather setting from database
// return 0 on success
+
int DBGetData(MCONTACT hContact, char *setting, DBVARIANT *dbv)
{
if (db_get_ws(hContact, WEATHERCONDITION, setting, dbv)) {
@@ -99,47 +103,47 @@ int DBGetData(MCONTACT hContact, char *setting, DBVARIANT *dbv)
}
-//============ ERASE OLD SETTINGS ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// erase all current weather information from database
// lastver = the last used version number in dword (using PLUGIN_MAKE_VERSION)
-void EraseAllInfo()
+
+void CWeatherProto::EraseAllInfo()
{
wchar_t str[255];
int ContactCount = 0;
MCONTACT LastContact = NULL;
DBVARIANT dbv;
// loop through all contacts
- for (auto &hContact : Contacts(MODULENAME)) {
- g_plugin.setWord(hContact, "Status", ID_STATUS_OFFLINE);
- g_plugin.setWord(hContact, "StatusIcon", -1);
+ for (auto &hContact : AccContacts()) {
+ setWord(hContact, "Status", ID_STATUS_OFFLINE);
+ setWord(hContact, "StatusIcon", -1);
db_unset(hContact, "CList", "MyHandle");
// clear all data
- if (g_plugin.getWString(hContact, "Nick", &dbv)) {
- g_plugin.setWString(hContact, "Nick", TranslateT("<Enter city name here>"));
- g_plugin.setString(hContact, "LastLog", "never");
- g_plugin.setString(hContact, "LastCondition", "None");
- g_plugin.setString(hContact, "LastTemperature", "None");
+ if (getWString(hContact, "Nick", &dbv)) {
+ setWString(hContact, "Nick", TranslateT("<Enter city name here>"));
+ setString(hContact, "LastLog", "never");
+ setString(hContact, "LastCondition", "None");
+ setString(hContact, "LastTemperature", "None");
}
else db_free(&dbv);
DBDataManage(hContact, WDBM_REMOVE, 0, 0);
db_set_s(hContact, "UserInfo", "MyNotes", "");
// reset update tag
- g_plugin.setByte(hContact, "IsUpdated", FALSE);
+ setByte(hContact, "IsUpdated", FALSE);
// reset logging settings
- if (!g_plugin.getWString(hContact, "Log", &dbv)) {
- g_plugin.setByte(hContact, "File", (uint8_t)(dbv.pwszVal[0] != 0));
+ if (!getWString(hContact, "Log", &dbv)) {
+ setByte(hContact, "File", (uint8_t)(dbv.pwszVal[0] != 0));
db_free(&dbv);
}
- else g_plugin.setByte(hContact, "File", FALSE);
+ else setByte(hContact, "File", FALSE);
// if no default station find, assign a new one
if (opt.Default[0] == 0) {
GetStationID(hContact, opt.Default, _countof(opt.Default));
opt.DefStn = hContact;
- if (!g_plugin.getWString(hContact, "Nick", &dbv)) {
+ if (!getWString(hContact, "Nick", &dbv)) {
mir_snwprintf(str, TranslateT("%s is now the default weather station"), dbv.pwszVal);
db_free(&dbv);
MessageBox(nullptr, str, TranslateT("Weather Protocol"), MB_OK | MB_ICONINFORMATION);
@@ -147,7 +151,7 @@ void EraseAllInfo()
}
// get the handle of the default station
if (opt.DefStn == NULL) {
- if (!g_plugin.getWString(hContact, "ID", &dbv)) {
+ if (!getWString(hContact, "ID", &dbv)) {
if (!mir_wstrcmp(dbv.pwszVal, opt.Default))
opt.DefStn = hContact;
db_free(&dbv);
@@ -161,22 +165,24 @@ void EraseAllInfo()
// if (ContactCount != 0) status = ONLINE;
// in case where the default station is missing
if (opt.DefStn == NULL && ContactCount != 0) {
- if (!g_plugin.getWString(LastContact, "ID", &dbv)) {
+ if (!getWString(LastContact, "ID", &dbv)) {
wcsncpy(opt.Default, dbv.pwszVal, _countof(opt.Default) - 1);
db_free(&dbv);
}
opt.DefStn = LastContact;
- if (!g_plugin.getWString(LastContact, "Nick", &dbv)) {
+ if (!getWString(LastContact, "Nick", &dbv)) {
mir_snwprintf(str, TranslateT("%s is now the default weather station"), dbv.pwszVal);
db_free(&dbv);
MessageBox(nullptr, str, TranslateT("Weather Protocol"), MB_OK | MB_ICONINFORMATION);
}
}
// save option in case of default station changed
- g_plugin.setWString("Default", opt.Default);
+ setWString("Default", opt.Default);
}
-void ConvertDataValue(WIDATAITEM *UpdateData, wchar_t *Data)
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CWeatherProto::ConvertDataValue(WIDATAITEM *UpdateData, wchar_t *Data)
{
wchar_t str[MAX_DATA_LEN];
@@ -236,14 +242,13 @@ void ConvertDataValue(WIDATAITEM *UpdateData, wchar_t *Data)
}
}
-//============ GET THE VALUE OF A DATAITEM ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// get the value of the data using the start, end strings
// UpdateData = the WIDATAITEM struct containing start, end, unit
// Data = the string containing weather data obtained from UpdateData
// global var. used: szInfo = the downloaded string
-//
-void GetDataValue(WIDATAITEM *UpdateData, wchar_t *Data, wchar_t **szData)
+
+void CWeatherProto::GetDataValue(WIDATAITEM *UpdateData, wchar_t *Data, wchar_t **szData)
{
wchar_t last = 0, current, *start, *end;
unsigned startloc = 0, endloc = 0, respos = 0;
@@ -340,8 +345,7 @@ void GetDataValue(WIDATAITEM *UpdateData, wchar_t *Data, wchar_t **szData)
*szData = szInfo;
}
-//============ ALLOCATE SPACE AND COPY STRING ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// copy a string into a new memory location
// Data = the field the data is copied to
// Value = the original string, the string where data is copied from
@@ -388,10 +392,11 @@ void wfree(wchar_t *&Data)
Data = nullptr;
}
-//============ MANAGE THE ITEMS STORED IN DB ============
+/////////////////////////////////////////////////////////////////////////////////////////
// get single setting that is found
// szSetting = the setting name
// lparam = the counter
+
int GetWeatherDataFromDB(const char *szSetting, void *lparam)
{
LIST<char> *pList = (LIST<char>*)lparam;
@@ -399,9 +404,10 @@ int GetWeatherDataFromDB(const char *szSetting, void *lparam)
return 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// remove or display the weather information for a contact
// hContact - the contact in which the info is going to be removed
-//
+
void DBDataManage(MCONTACT hContact, uint16_t Mode, WPARAM wParam, LPARAM)
{
// get all the settings and store them in a temporary list
diff --git a/protocols/Weather/src/weather_http.cpp b/protocols/Weather/src/weather_http.cpp
index bfbcadc589..91ae9b911c 100644
--- a/protocols/Weather/src/weather_http.cpp
+++ b/protocols/Weather/src/weather_http.cpp
@@ -25,15 +25,13 @@ from the web using netlib
#include "stdafx.h"
-HNETLIBUSER hNetlibUser;
-
-//============ DOWNLOAD NEW WEATHER ============
+/////////////////////////////////////////////////////////////////////////////////////////
// function to download webpage from the internet
// szUrl = URL of the webpage to be retrieved
// return value = 0 for success, 1 or HTTP error code for failure
// global var used: szData, szInfo = containing the retrieved data
-//
-int InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **szData)
+
+int CWeatherProto::InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **szData)
{
if (userAgent == nullptr || userAgent[0] == 0)
userAgent = NETLIB_USER_AGENT;
@@ -50,7 +48,7 @@ int InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **s
nlhr.AddHeader("Cookie", cookie);
// download the page
- NLHR_PTR nlhrReply(Netlib_HttpTransaction(hNetlibUser, &nlhr));
+ NLHR_PTR nlhrReply(Netlib_HttpTransaction(m_hNetlibUser, &nlhr));
if (nlhrReply == nullptr) {
// if the data does not downloaded successfully (ie. disconnected), then return 1000 as error code
*szData = (wchar_t*)mir_alloc(512);
@@ -117,15 +115,3 @@ int InternetDownloadFile(char *szUrl, char *cookie, char *userAgent, wchar_t **s
// make a copy of the retrieved data, then free the memory of the http reply
return result;
}
-
-//============ NETLIB INITIALIZATION ============
-//
-// initialize netlib support for weather protocol
-void NetlibInit(void)
-{
- NETLIBUSER nlu = {};
- nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION;
- nlu.szSettingsModule = MODULENAME;
- nlu.szDescriptiveName.a = MODULENAME;
- hNetlibUser = Netlib_RegisterUser(&nlu);
-}
diff --git a/protocols/Weather/src/weather_ini.cpp b/protocols/Weather/src/weather_ini.cpp
index 0929b06c1e..0296e0a7d8 100644
--- a/protocols/Weather/src/weather_ini.cpp
+++ b/protocols/Weather/src/weather_ini.cpp
@@ -198,7 +198,8 @@ static INT_PTR CALLBACK DlgProcSetup(HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
break;
case IDC_STEP4:
- WeatherAdd(0, 0);
+ db_set_s(0, "FindAdd", "LastSearched", "Weather");
+ CallService(MS_FINDADD_FINDADD, 0, 0);
__fallthrough;
case IDCANCEL:
diff --git a/protocols/Weather/src/weather_mwin.cpp b/protocols/Weather/src/weather_mwin.cpp
index da08be4ce1..d6ae726046 100644
--- a/protocols/Weather/src/weather_mwin.cpp
+++ b/protocols/Weather/src/weather_mwin.cpp
@@ -27,6 +27,7 @@ HGENMENU hMwinMenu;
struct MWinDataType
{
+ CWeatherProto *ppro;
MCONTACT hContact;
HWND hAvt;
BOOL haveAvatar;
@@ -44,7 +45,8 @@ static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)data);
data->hContact = (DWORD_PTR)((LPCREATESTRUCT)lParam)->lpCreateParams;
- data->hAvt = CreateWindow(AVATAR_CONTROL_CLASS, TEXT(""), WS_CHILD, 0, 0, opt.AvatarSize, opt.AvatarSize, hwnd, 0, g_plugin.getInst(), 0);
+ data->ppro = (CWeatherProto *)Proto_GetContactInstance(data->hContact);
+ data->hAvt = CreateWindow(AVATAR_CONTROL_CLASS, TEXT(""), WS_CHILD, 0, 0, data->ppro->opt.AvatarSize, data->ppro->opt.AvatarSize, hwnd, 0, g_plugin.getInst(), 0);
if (data->hAvt)
SendMessage(data->hAvt, AVATAR_SETCONTACT, 0, (LPARAM)data->hContact);
break;
@@ -97,7 +99,7 @@ static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
break;
case WM_LBUTTONDBLCLK:
- BriefInfo(data->hContact, 0);
+ data->ppro->BriefInfo(data->hContact, 0);
break;
case WM_COMMAND: //Needed by the contact's context menu
@@ -124,7 +126,7 @@ static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
break;
case WM_REDRAWWIN:
- if (data->hAvt != nullptr) MoveWindow(data->hAvt, 0, 0, opt.AvatarSize, opt.AvatarSize, TRUE);
+ if (data->hAvt != nullptr) MoveWindow(data->hAvt, 0, 0, data->ppro->opt.AvatarSize, data->ppro->opt.AvatarSize, TRUE);
RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
break;
@@ -133,7 +135,7 @@ static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
RECT r, rc;
if (GetUpdateRect(hwnd, &r, FALSE)) {
- int picSize = opt.AvatarSize;
+ int picSize = data->ppro->opt.AvatarSize;
HICON hIcon = nullptr;
if (!data->haveAvatar) {
@@ -274,9 +276,9 @@ INT_PTR Mwin_MenuClicked(WPARAM wParam, LPARAM)
return 0;
}
-int BuildContactMenu(WPARAM wparam, LPARAM)
+int CWeatherProto::BuildContactMenu(WPARAM wparam, LPARAM)
{
- int flags = g_plugin.getDword(wparam, "mwin") ? CMIF_CHECKED : 0;
+ int flags = getDword(wparam, "mwin") ? CMIF_CHECKED : 0;
Menu_ModifyItem(hMwinMenu, nullptr, INVALID_HANDLE_VALUE, flags);
return 0;
}
@@ -287,7 +289,7 @@ int RedrawFrame(WPARAM, LPARAM)
return 0;
}
-void InitMwin(void)
+void CWeatherProto::InitMwin(void)
{
if (!ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
return;
@@ -337,16 +339,16 @@ void InitMwin(void)
mir_strcpy(fontid.setting, "fnt1");
g_plugin.addFont(&fontid);
- for (auto &hContact : Contacts(MODULENAME))
+ for (auto &hContact : AccContacts())
if (g_plugin.getDword(hContact, "mwin"))
addWindow(hContact);
hFontHook = HookEvent(ME_FONT_RELOAD, RedrawFrame);
}
-void DestroyMwin(void)
+void CWeatherProto::DestroyMwin(void)
{
- for (auto &hContact : Contacts(MODULENAME)) {
+ for (auto &hContact : AccContacts()) {
uint32_t frameId = g_plugin.getDword(hContact, "mwin");
if (frameId)
CallService(MS_CLIST_FRAMES_REMOVEFRAME, frameId, 0);
diff --git a/protocols/Weather/src/weather_opt.cpp b/protocols/Weather/src/weather_opt.cpp
index 1d92f20191..5ee7e3353d 100644
--- a/protocols/Weather/src/weather_opt.cpp
+++ b/protocols/Weather/src/weather_opt.cpp
@@ -24,7 +24,6 @@ contain code for saving/loading options from the database.
#include "stdafx.h"
-static BOOL opt_startup;
int RedrawFrame(WPARAM wParam, LPARAM lParam);
//============ LOADING AND SAVING OPTIONS ===========
@@ -54,21 +53,21 @@ const wchar_t* GetDefaultText(int c)
return L"";
}
-CMStringW GetTextValue(int c)
+CMStringW CWeatherProto::GetTextValue(int c)
{
CMStringW ret;
switch (c) {
- case 'C': ret = g_plugin.getMStringW("DisplayText"); break;
- case 'b': ret = g_plugin.getMStringW("BriefTextTitle"); break;
- case 'B': ret = g_plugin.getMStringW("BriefText"); break;
- case 'N': ret = g_plugin.getMStringW("NoteText"); break;
- case 'E': ret = g_plugin.getMStringW("ExtText"); break;
- case 'H': ret = g_plugin.getMStringW("HistoryText"); break;
- case 'X': ret = g_plugin.getMStringW("ExtraText"); break;
- case 'S': ret = g_plugin.getMStringW("StatusText"); break;
- case 'P': ret = g_plugin.getMStringW("PopupTitle"); break;
- case 'p': ret = g_plugin.getMStringW("PopupText"); break;
+ case 'C': ret = getMStringW("DisplayText"); break;
+ case 'b': ret = getMStringW("BriefTextTitle"); break;
+ case 'B': ret = getMStringW("BriefText"); break;
+ case 'N': ret = getMStringW("NoteText"); break;
+ case 'E': ret = getMStringW("ExtText"); break;
+ case 'H': ret = getMStringW("HistoryText"); break;
+ case 'X': ret = getMStringW("ExtraText"); break;
+ case 'S': ret = getMStringW("StatusText"); break;
+ case 'P': ret = getMStringW("PopupTitle"); break;
+ case 'p': ret = getMStringW("PopupText"); break;
}
return (ret.IsEmpty()) ? GetDefaultText(c) : ret;
@@ -76,248 +75,228 @@ CMStringW GetTextValue(int c)
// load options from database + set default if the setting does not exist
-void LoadOptions(void)
+void CWeatherProto::LoadOptions(void)
{
memset(&opt, 0, sizeof(opt));
// main options
- opt.StartupUpdate = g_plugin.getByte("StartupUpdate", true);
- opt.AutoUpdate = g_plugin.getByte("AutoUpdate", true);
- opt.UpdateTime = g_plugin.getWord("UpdateTime", 30);
- opt.NoProtoCondition = g_plugin.getByte("NoStatus", true);
- opt.UpdateOnlyConditionChanged = g_plugin.getByte("CondChangeAsUpdate", true);
- opt.RemoveOldData = g_plugin.getByte("RemoveOld", false);
- opt.MakeItalic = g_plugin.getByte("MakeItalic", true);
- opt.AvatarSize = g_plugin.getByte("AvatarSize", 128);
+ opt.StartupUpdate = getByte("StartupUpdate", true);
+ opt.AutoUpdate = getByte("AutoUpdate", true);
+ opt.UpdateTime = getWord("UpdateTime", 30);
+ opt.UpdateOnlyConditionChanged = getByte("CondChangeAsUpdate", true);
+ opt.RemoveOldData = getByte("RemoveOld", false);
+ opt.MakeItalic = getByte("MakeItalic", true);
+ opt.AvatarSize = getByte("AvatarSize", 128);
// units
- opt.tUnit = g_plugin.getWord("tUnit", 1);
- opt.wUnit = g_plugin.getWord("wUnit", 2);
- opt.vUnit = g_plugin.getWord("vUnit", 1);
- opt.pUnit = g_plugin.getWord("pUnit", 4);
- opt.dUnit = g_plugin.getWord("dUnit", 1);
- opt.eUnit = g_plugin.getWord("eUnit", 2);
-
- ptrW szValue(g_plugin.getWStringA("DegreeSign"));
+ opt.tUnit = getWord("tUnit", 1);
+ opt.wUnit = getWord("wUnit", 2);
+ opt.vUnit = getWord("vUnit", 1);
+ opt.pUnit = getWord("pUnit", 4);
+ opt.dUnit = getWord("dUnit", 1);
+ opt.eUnit = getWord("eUnit", 2);
+
+ ptrW szValue(getWStringA("DegreeSign"));
wcsncpy_s(opt.DegreeSign, (szValue == NULL) ? L"" : szValue, _TRUNCATE);
- opt.DoNotAppendUnit = g_plugin.getByte("DoNotAppendUnit", 0);
- opt.NoFrac = g_plugin.getByte("NoFractions", 0);
+ opt.DoNotAppendUnit = getByte("DoNotAppendUnit", 0);
+ opt.NoFrac = getByte("NoFractions", 0);
// advanced
- opt.DisCondIcon = g_plugin.getByte("DisableConditionIcon", false);
+ opt.DisCondIcon = getByte("DisableConditionIcon", false);
// popup options
- opt.UpdatePopup = g_plugin.getByte("UpdatePopup", true);
- opt.AlertPopup = g_plugin.getByte("AlertPopup", true);
- opt.PopupOnChange = g_plugin.getByte("PopUpOnChange", true);
- opt.ShowWarnings = g_plugin.getByte("ShowWarnings", true);
+ opt.UpdatePopup = getByte("UpdatePopup", true);
+ opt.AlertPopup = getByte("AlertPopup", true);
+ opt.PopupOnChange = getByte("PopUpOnChange", true);
+ opt.ShowWarnings = getByte("ShowWarnings", true);
// popup colors
- opt.BGColour = g_plugin.getDword("BackgroundColour", GetSysColor(COLOR_BTNFACE));
- opt.TextColour = g_plugin.getDword("TextColour", GetSysColor(COLOR_WINDOWTEXT));
- opt.UseWinColors = g_plugin.getByte("UseWinColors", false);
+ opt.BGColour = getDword("BackgroundColour", GetSysColor(COLOR_BTNFACE));
+ opt.TextColour = getDword("TextColour", GetSysColor(COLOR_WINDOWTEXT));
+ opt.UseWinColors = getByte("UseWinColors", false);
// popup actions
- opt.LeftClickAction = g_plugin.getDword("LeftClickAction", IDM_M2);
- opt.RightClickAction = g_plugin.getDword("RightClickAction", IDM_M1);
+ opt.LeftClickAction = getDword("LeftClickAction", IDM_M2);
+ opt.RightClickAction = getDword("RightClickAction", IDM_M1);
// popup delay
- opt.pDelay = g_plugin.getDword("PopupDelay", 0);
+ opt.pDelay = getDword("PopupDelay", 0);
// misc
- if (szValue = g_plugin.getWStringA("Default"))
+ if (szValue = getWStringA("Default"))
wcsncpy_s(opt.Default, szValue, _TRUNCATE);
else
opt.Default[0] = 0;
}
// save the options to database
-void SaveOptions(void)
+void CWeatherProto::SaveOptions(void)
{
// main options
- g_plugin.setByte("StartupUpdate", (uint8_t)opt.StartupUpdate);
- g_plugin.setByte("AutoUpdate", (uint8_t)opt.AutoUpdate);
- g_plugin.setWord("UpdateTime", opt.UpdateTime);
- g_plugin.setByte("NoStatus", (uint8_t)opt.NoProtoCondition);
- g_plugin.setByte("CondChangeAsUpdate", (uint8_t)opt.UpdateOnlyConditionChanged);
- g_plugin.setByte("RemoveOld", (uint8_t)opt.RemoveOldData);
- g_plugin.setByte("MakeItalic", (uint8_t)opt.MakeItalic);
- g_plugin.setByte("AvatarSize", (uint8_t)opt.AvatarSize);
+ setByte("StartupUpdate", (uint8_t)opt.StartupUpdate);
+ setByte("AutoUpdate", (uint8_t)opt.AutoUpdate);
+ setWord("UpdateTime", opt.UpdateTime);
+ setByte("CondChangeAsUpdate", (uint8_t)opt.UpdateOnlyConditionChanged);
+ setByte("RemoveOld", (uint8_t)opt.RemoveOldData);
+ setByte("MakeItalic", (uint8_t)opt.MakeItalic);
+ setByte("AvatarSize", (uint8_t)opt.AvatarSize);
// units
- g_plugin.setWord("tUnit", opt.tUnit);
- g_plugin.setWord("wUnit", opt.wUnit);
- g_plugin.setWord("vUnit", opt.vUnit);
- g_plugin.setWord("pUnit", opt.pUnit);
- g_plugin.setWord("dUnit", opt.dUnit);
- g_plugin.setWord("eUnit", opt.eUnit);
- g_plugin.setWString("DegreeSign", opt.DegreeSign);
- g_plugin.setByte("DoNotAppendUnit", (uint8_t)opt.DoNotAppendUnit);
- g_plugin.setByte("NoFractions", (uint8_t)opt.NoFrac);
+ setWord("tUnit", opt.tUnit);
+ setWord("wUnit", opt.wUnit);
+ setWord("vUnit", opt.vUnit);
+ setWord("pUnit", opt.pUnit);
+ setWord("dUnit", opt.dUnit);
+ setWord("eUnit", opt.eUnit);
+ setWString("DegreeSign", opt.DegreeSign);
+ setByte("DoNotAppendUnit", (uint8_t)opt.DoNotAppendUnit);
+ setByte("NoFractions", (uint8_t)opt.NoFrac);
// advanced
- g_plugin.setByte("DisableConditionIcon", (uint8_t)opt.DisCondIcon);
+ setByte("DisableConditionIcon", (uint8_t)opt.DisCondIcon);
// popup options
- g_plugin.setByte("UpdatePopup", (uint8_t)opt.UpdatePopup);
- g_plugin.setByte("AlertPopup", (uint8_t)opt.AlertPopup);
- g_plugin.setByte("PopUpOnChange", (uint8_t)opt.PopupOnChange);
- g_plugin.setByte("ShowWarnings", (uint8_t)opt.ShowWarnings);
+ setByte("UpdatePopup", (uint8_t)opt.UpdatePopup);
+ setByte("AlertPopup", (uint8_t)opt.AlertPopup);
+ setByte("PopUpOnChange", (uint8_t)opt.PopupOnChange);
+ setByte("ShowWarnings", (uint8_t)opt.ShowWarnings);
// popup colors
- g_plugin.setDword("BackgroundColour", opt.BGColour);
- g_plugin.setDword("TextColour", opt.TextColour);
- g_plugin.setByte("UseWinColors", (uint8_t)opt.UseWinColors);
+ setDword("BackgroundColour", opt.BGColour);
+ setDword("TextColour", opt.TextColour);
+ setByte("UseWinColors", (uint8_t)opt.UseWinColors);
// popup actions
- g_plugin.setDword("LeftClickAction", opt.LeftClickAction);
- g_plugin.setDword("RightClickAction", opt.RightClickAction);
+ setDword("LeftClickAction", opt.LeftClickAction);
+ setDword("RightClickAction", opt.RightClickAction);
// popup delay
- g_plugin.setDword("PopupDelay", opt.pDelay);
+ setDword("PopupDelay", opt.pDelay);
// misc stuff
- g_plugin.setWString("Default", opt.Default);
+ setWString("Default", opt.Default);
}
-//============ MAIN OPTIONS ============
+/////////////////////////////////////////////////////////////////////////////////////////
// weather options
-static INT_PTR CALLBACK OptionsProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
+class COptionsDlg : public CWeatherDlgBase
{
- wchar_t str[512];
+public:
+ COptionsDlg(CWeatherProto *ppro) :
+ CWeatherDlgBase(ppro, IDD_OPTIONS)
+ {}
+
+ bool OnInitDialog() override
+ {
+ wchar_t str[512];
+ auto &opt = m_proto->opt;
- switch (msg) {
- case WM_INITDIALOG:
- opt_startup = TRUE;
- TranslateDialogDefault(hdlg);
- // load settings
_ltow(opt.UpdateTime, str, 10);
- SetDlgItemText(hdlg, IDC_UPDATETIME, str);
- SetDlgItemText(hdlg, IDC_DEGREE, opt.DegreeSign);
-
- SendDlgItemMessage(hdlg, IDC_AVATARSPIN, UDM_SETRANGE32, 0, 999);
- SendDlgItemMessage(hdlg, IDC_AVATARSPIN, UDM_SETPOS, 0, opt.AvatarSize);
- SendDlgItemMessage(hdlg, IDC_AVATARSIZE, EM_LIMITTEXT, 3, 0);
-
- CheckDlgButton(hdlg, IDC_STARTUPUPD, opt.StartupUpdate ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_UPDATE, opt.AutoUpdate ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_PROTOCOND, !opt.NoProtoCondition ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_UPDCONDCHG, opt.UpdateOnlyConditionChanged ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_REMOVEOLD, opt.RemoveOldData ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_MAKEI, opt.MakeItalic ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_DISCONDICON, opt.DisCondIcon ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_DONOTAPPUNITS, opt.DoNotAppendUnit ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_NOFRAC, opt.NoFrac ? BST_CHECKED : BST_UNCHECKED);
+ SetDlgItemText(m_hwnd, IDC_UPDATETIME, str);
+ SetDlgItemText(m_hwnd, IDC_DEGREE, opt.DegreeSign);
+
+ SendDlgItemMessage(m_hwnd, IDC_AVATARSPIN, UDM_SETRANGE32, 0, 999);
+ SendDlgItemMessage(m_hwnd, IDC_AVATARSPIN, UDM_SETPOS, 0, opt.AvatarSize);
+ SendDlgItemMessage(m_hwnd, IDC_AVATARSIZE, EM_LIMITTEXT, 3, 0);
+
+ CheckDlgButton(m_hwnd, IDC_STARTUPUPD, opt.StartupUpdate ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_UPDATE, opt.AutoUpdate ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_UPDCONDCHG, opt.UpdateOnlyConditionChanged ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_REMOVEOLD, opt.RemoveOldData ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_MAKEI, opt.MakeItalic ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_DISCONDICON, opt.DisCondIcon ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_DONOTAPPUNITS, opt.DoNotAppendUnit ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_NOFRAC, opt.NoFrac ? BST_CHECKED : BST_UNCHECKED);
// load units
switch (opt.tUnit) { // temperature
- case 1: CheckRadioButton(hdlg, IDC_T1, IDC_T2, IDC_T1); break;
- case 2: CheckRadioButton(hdlg, IDC_T1, IDC_T2, IDC_T2); break;
+ case 1: CheckRadioButton(m_hwnd, IDC_T1, IDC_T2, IDC_T1); break;
+ case 2: CheckRadioButton(m_hwnd, IDC_T1, IDC_T2, IDC_T2); break;
}
switch (opt.wUnit) { // wind
- case 1: CheckRadioButton(hdlg, IDC_W1, IDC_W4, IDC_W1); break;
- case 2: CheckRadioButton(hdlg, IDC_W1, IDC_W4, IDC_W2); break;
- case 3: CheckRadioButton(hdlg, IDC_W1, IDC_W4, IDC_W3); break;
- case 4: CheckRadioButton(hdlg, IDC_W1, IDC_W4, IDC_W4); break;
+ case 1: CheckRadioButton(m_hwnd, IDC_W1, IDC_W4, IDC_W1); break;
+ case 2: CheckRadioButton(m_hwnd, IDC_W1, IDC_W4, IDC_W2); break;
+ case 3: CheckRadioButton(m_hwnd, IDC_W1, IDC_W4, IDC_W3); break;
+ case 4: CheckRadioButton(m_hwnd, IDC_W1, IDC_W4, IDC_W4); break;
}
switch (opt.vUnit) { // visibility
- case 1: CheckRadioButton(hdlg, IDC_V1, IDC_V2, IDC_V1); break;
- case 2: CheckRadioButton(hdlg, IDC_V1, IDC_V2, IDC_V2); break;
+ case 1: CheckRadioButton(m_hwnd, IDC_V1, IDC_V2, IDC_V1); break;
+ case 2: CheckRadioButton(m_hwnd, IDC_V1, IDC_V2, IDC_V2); break;
}
switch (opt.pUnit) { // pressure
- case 1: CheckRadioButton(hdlg, IDC_P1, IDC_P4, IDC_P1); break;
- case 2: CheckRadioButton(hdlg, IDC_P1, IDC_P4, IDC_P2); break;
- case 3: CheckRadioButton(hdlg, IDC_P1, IDC_P4, IDC_P3); break;
- case 4: CheckRadioButton(hdlg, IDC_P1, IDC_P4, IDC_P4); break;
+ case 1: CheckRadioButton(m_hwnd, IDC_P1, IDC_P4, IDC_P1); break;
+ case 2: CheckRadioButton(m_hwnd, IDC_P1, IDC_P4, IDC_P2); break;
+ case 3: CheckRadioButton(m_hwnd, IDC_P1, IDC_P4, IDC_P3); break;
+ case 4: CheckRadioButton(m_hwnd, IDC_P1, IDC_P4, IDC_P4); break;
}
switch (opt.dUnit) { // pressure
- case 1: CheckRadioButton(hdlg, IDC_D1, IDC_D3, IDC_D1); break;
- case 2: CheckRadioButton(hdlg, IDC_D1, IDC_D3, IDC_D2); break;
- case 3: CheckRadioButton(hdlg, IDC_D1, IDC_D3, IDC_D3); break;
+ case 1: CheckRadioButton(m_hwnd, IDC_D1, IDC_D3, IDC_D1); break;
+ case 2: CheckRadioButton(m_hwnd, IDC_D1, IDC_D3, IDC_D2); break;
+ case 3: CheckRadioButton(m_hwnd, IDC_D1, IDC_D3, IDC_D3); break;
}
switch (opt.eUnit) { // elev
- case 1: CheckRadioButton(hdlg, IDC_E1, IDC_E2, IDC_E1); break;
- case 2: CheckRadioButton(hdlg, IDC_E1, IDC_E2, IDC_E2); break;
+ case 1: CheckRadioButton(m_hwnd, IDC_E1, IDC_E2, IDC_E1); break;
+ case 2: CheckRadioButton(m_hwnd, IDC_E1, IDC_E2, IDC_E2); break;
}
- opt_startup = FALSE;
- return 0;
-
- case WM_COMMAND:
- if (HIWORD(wparam) == BN_CLICKED && GetFocus() == (HWND)lparam)
- if (!opt_startup) SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
- if (!((LOWORD(wparam) == IDC_UPDATE || LOWORD(wparam) == IDC_DEGREE) &&
- (HIWORD(wparam) != EN_CHANGE || (HWND)lparam != GetFocus())))
- if (!opt_startup) SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
- return 0;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lparam)->code) {
- case PSN_APPLY:
- // change the status for weather protocol
- if (IsDlgButtonChecked(hdlg, IDC_PROTOCOND) && opt.DefStn != NULL) {
- old_status = status;
- status = MapCondToStatus(opt.DefStn);
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status);
- }
-
- // get update time and remove the old timer
- GetDlgItemText(hdlg, IDC_UPDATETIME, str, _countof(str));
- opt.UpdateTime = (uint16_t)_wtoi(str);
- if (opt.UpdateTime < 1) opt.UpdateTime = 1;
- KillTimer(nullptr, timerId);
- timerId = SetTimer(nullptr, 0, opt.UpdateTime * 60000, timerProc);
-
- // other general options
- GetDlgItemText(hdlg, IDC_DEGREE, opt.DegreeSign, _countof(opt.DegreeSign));
- opt.StartupUpdate = IsDlgButtonChecked(hdlg, IDC_STARTUPUPD);
- opt.AutoUpdate = IsDlgButtonChecked(hdlg, IDC_UPDATE);
- opt.NoProtoCondition = BST_UNCHECKED == IsDlgButtonChecked(hdlg, IDC_PROTOCOND);
- opt.DisCondIcon = IsDlgButtonChecked(hdlg, IDC_DISCONDICON);
- opt.UpdateOnlyConditionChanged = (uint8_t)IsDlgButtonChecked(hdlg, IDC_UPDCONDCHG);
- opt.RemoveOldData = IsDlgButtonChecked(hdlg, IDC_REMOVEOLD);
- opt.MakeItalic = IsDlgButtonChecked(hdlg, IDC_MAKEI);
- opt.AvatarSize = GetDlgItemInt(hdlg, IDC_AVATARSIZE, nullptr, FALSE);
- opt.DoNotAppendUnit = IsDlgButtonChecked(hdlg, IDC_DONOTAPPUNITS);
- opt.NoFrac = IsDlgButtonChecked(hdlg, IDC_NOFRAC);
- UpdateMenu(opt.AutoUpdate);
-
- // save the units
- if (IsDlgButtonChecked(hdlg, IDC_T1)) opt.tUnit = 1;
- if (IsDlgButtonChecked(hdlg, IDC_T2)) opt.tUnit = 2;
- if (IsDlgButtonChecked(hdlg, IDC_W1)) opt.wUnit = 1;
- if (IsDlgButtonChecked(hdlg, IDC_W2)) opt.wUnit = 2;
- if (IsDlgButtonChecked(hdlg, IDC_W3)) opt.wUnit = 3;
- if (IsDlgButtonChecked(hdlg, IDC_W4)) opt.wUnit = 4;
- if (IsDlgButtonChecked(hdlg, IDC_V1)) opt.vUnit = 1;
- if (IsDlgButtonChecked(hdlg, IDC_V2)) opt.vUnit = 2;
- if (IsDlgButtonChecked(hdlg, IDC_P1)) opt.pUnit = 1;
- if (IsDlgButtonChecked(hdlg, IDC_P2)) opt.pUnit = 2;
- if (IsDlgButtonChecked(hdlg, IDC_P3)) opt.pUnit = 3;
- if (IsDlgButtonChecked(hdlg, IDC_P4)) opt.pUnit = 4;
- if (IsDlgButtonChecked(hdlg, IDC_D1)) opt.dUnit = 1;
- if (IsDlgButtonChecked(hdlg, IDC_D2)) opt.dUnit = 2;
- if (IsDlgButtonChecked(hdlg, IDC_D3)) opt.dUnit = 3;
- if (IsDlgButtonChecked(hdlg, IDC_E1)) opt.eUnit = 1;
- if (IsDlgButtonChecked(hdlg, IDC_E2)) opt.eUnit = 2;
-
- // save the new weather options
- SaveOptions();
-
- RedrawFrame(0, 0);
-
- return 1;
- }
- break;
+ return true;
}
- return 0;
-}
-//============ TEXT OPTION DIALOG ============
+ bool OnApply() override
+ {
+ wchar_t str[512];
+ auto &opt = m_proto->opt;
+
+ // get update time and remove the old timer
+ GetDlgItemText(m_hwnd, IDC_UPDATETIME, str, _countof(str));
+ opt.UpdateTime = (uint16_t)_wtoi(str);
+ if (opt.UpdateTime < 1) opt.UpdateTime = 1;
+ m_proto->RestartTimer();
+
+ // other general options
+ GetDlgItemText(m_hwnd, IDC_DEGREE, opt.DegreeSign, _countof(opt.DegreeSign));
+ opt.StartupUpdate = IsDlgButtonChecked(m_hwnd, IDC_STARTUPUPD);
+ opt.AutoUpdate = IsDlgButtonChecked(m_hwnd, IDC_UPDATE);
+ opt.DisCondIcon = IsDlgButtonChecked(m_hwnd, IDC_DISCONDICON);
+ opt.UpdateOnlyConditionChanged = (uint8_t)IsDlgButtonChecked(m_hwnd, IDC_UPDCONDCHG);
+ opt.RemoveOldData = IsDlgButtonChecked(m_hwnd, IDC_REMOVEOLD);
+ opt.MakeItalic = IsDlgButtonChecked(m_hwnd, IDC_MAKEI);
+ opt.AvatarSize = GetDlgItemInt(m_hwnd, IDC_AVATARSIZE, nullptr, FALSE);
+ opt.DoNotAppendUnit = IsDlgButtonChecked(m_hwnd, IDC_DONOTAPPUNITS);
+ opt.NoFrac = IsDlgButtonChecked(m_hwnd, IDC_NOFRAC);
+ m_proto->UpdateMenu(opt.AutoUpdate);
+
+ // save the units
+ if (IsDlgButtonChecked(m_hwnd, IDC_T1)) opt.tUnit = 1;
+ if (IsDlgButtonChecked(m_hwnd, IDC_T2)) opt.tUnit = 2;
+ if (IsDlgButtonChecked(m_hwnd, IDC_W1)) opt.wUnit = 1;
+ if (IsDlgButtonChecked(m_hwnd, IDC_W2)) opt.wUnit = 2;
+ if (IsDlgButtonChecked(m_hwnd, IDC_W3)) opt.wUnit = 3;
+ if (IsDlgButtonChecked(m_hwnd, IDC_W4)) opt.wUnit = 4;
+ if (IsDlgButtonChecked(m_hwnd, IDC_V1)) opt.vUnit = 1;
+ if (IsDlgButtonChecked(m_hwnd, IDC_V2)) opt.vUnit = 2;
+ if (IsDlgButtonChecked(m_hwnd, IDC_P1)) opt.pUnit = 1;
+ if (IsDlgButtonChecked(m_hwnd, IDC_P2)) opt.pUnit = 2;
+ if (IsDlgButtonChecked(m_hwnd, IDC_P3)) opt.pUnit = 3;
+ if (IsDlgButtonChecked(m_hwnd, IDC_P4)) opt.pUnit = 4;
+ if (IsDlgButtonChecked(m_hwnd, IDC_D1)) opt.dUnit = 1;
+ if (IsDlgButtonChecked(m_hwnd, IDC_D2)) opt.dUnit = 2;
+ if (IsDlgButtonChecked(m_hwnd, IDC_D3)) opt.dUnit = 3;
+ if (IsDlgButtonChecked(m_hwnd, IDC_E1)) opt.eUnit = 1;
+ if (IsDlgButtonChecked(m_hwnd, IDC_E2)) opt.eUnit = 2;
+
+ // save the new weather options
+ m_proto->SaveOptions();
+
+ RedrawFrame(0, 0);
+ return true;
+ }
+};
+/////////////////////////////////////////////////////////////////////////////////////////
// text option dialog
struct
@@ -338,172 +317,156 @@ static controls[] =
{ 'S', IDC_BTITLE2, "StatusText" },
};
-static INT_PTR CALLBACK DlgProcText(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
+class COptionsTextDlg : public CWeatherDlgBase
{
- RECT rc, pos;
- HWND button;
- HMENU hMenu, hMenu1;
- switch (msg) {
- case WM_INITDIALOG:
- opt_startup = TRUE;
+ CCtrlMButton btnMore, btnReset, tm1, tm2, tm3, tm4, tm5, tm6, tm7, tm8;
+
+public:
+ COptionsTextDlg(CWeatherProto *ppro) :
+ CWeatherDlgBase(ppro, IDD_TEXTOPT),
+ btnMore(this, IDC_MORE, 0, 0),
+ btnReset(this, IDC_RESET, 0, 0),
+ tm1(this, IDC_TM1, 0, 0),
+ tm2(this, IDC_TM2, 0, 0),
+ tm3(this, IDC_TM3, 0, 0),
+ tm4(this, IDC_TM4, 0, 0),
+ tm5(this, IDC_TM5, 0, 0),
+ tm6(this, IDC_TM6, 0, 0),
+ tm7(this, IDC_TM7, 0, 0),
+ tm8(this, IDC_TM8, 0, 0)
+ {
+ btnMore.OnClick = Callback(this, &COptionsTextDlg::onClick_More);
+ btnReset.OnClick = Callback(this, &COptionsTextDlg::onClick_Reset);
+
+ tm1.OnClick = tm2.OnClick = tm3.OnClick = tm4.OnClick = tm5.OnClick = tm6.OnClick = tm7.OnClick = tm8.OnClick =
+ Callback(this, &COptionsTextDlg::onClick_TM);
+ }
+
+ bool OnInitDialog() override
+ {
// set windows position, make it top-most
- GetWindowRect(hdlg, &rc);
- SetWindowPos(hdlg, HWND_TOPMOST, rc.left, rc.top, 0, 0, SWP_NOSIZE);
- TranslateDialogDefault(hdlg);
+ RECT rc;
+ GetWindowRect(m_hwnd, &rc);
+ SetWindowPos(m_hwnd, HWND_TOPMOST, rc.left, rc.top, 0, 0, SWP_NOSIZE);
// generate the display text for variable list
- SetDlgItemText(hdlg, IDC_VARLIST, VAR_LIST_OPT);
+ SetDlgItemText(m_hwnd, IDC_VARLIST, VAR_LIST_OPT);
for (auto &it : controls)
- SetDlgItemText(hdlg, it.id, GetTextValue(it.c));
+ SetDlgItemText(m_hwnd, it.id, m_proto->GetTextValue(it.c));
// make the more variable and other buttons flat
- SendDlgItemMessage(hdlg, IDC_MORE, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_TM1, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_TM2, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_TM3, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_TM4, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_TM5, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_TM6, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_TM7, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_TM8, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_RESET, BUTTONSETASFLATBTN, TRUE, 0);
-
- // load the settings
- opt_startup = FALSE;
- return TRUE;
-
- case WM_COMMAND:
- if (opt_startup) return TRUE;
- switch (LOWORD(wParam)) {
- case IDC_CTEXT:
- case IDC_BTITLE:
- case IDC_BTEXT:
- case IDC_NTEXT:
- case IDC_XTEXT:
- case IDC_ETEXT:
- case IDC_HTEXT:
- case IDC_BTITLE2:
- if (HIWORD(wParam) == EN_CHANGE)
- SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
- break;
+ tm1.MakeFlat();
+ tm2.MakeFlat();
+ tm3.MakeFlat();
+ tm4.MakeFlat();
+ tm5.MakeFlat();
+ tm6.MakeFlat();
+ tm7.MakeFlat();
+ tm8.MakeFlat();
+ btnMore.MakeFlat();
+ btnReset.MakeFlat();
+ return true;
+ }
- case IDC_MORE:
- // display custom variables list
- MoreVarList();
- break;
+ bool OnApply() override
+ {
+ // save the option
+ wchar_t textstr[MAX_TEXT_SIZE];
+ for (auto &it : controls) {
+ GetDlgItemText(m_hwnd, it.id, textstr, _countof(textstr));
+ if (!mir_wstrcmpi(textstr, GetDefaultText(it.c)))
+ g_plugin.delSetting(it.setting);
+ else
+ g_plugin.setWString(it.setting, textstr);
+ }
- case IDC_TM1:
- case IDC_TM2:
- case IDC_TM3:
- case IDC_TM4:
- case IDC_TM5:
- case IDC_TM6:
- case IDC_TM7:
- case IDC_TM8:
- // display the menu
- button = GetDlgItem(hdlg, LOWORD(wParam));
- GetWindowRect(button, &pos);
- hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_TMMENU));
- hMenu1 = GetSubMenu(hMenu, 0);
- TranslateMenu(hMenu1);
- {
- auto &var = controls[int(LOWORD(wParam)) - IDC_TM1];
-
- switch (TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, nullptr)) {
- case ID_MPREVIEW:
- {
- // show the preview in a message box, using the weather data from the default station
- WEATHERINFO winfo = LoadWeatherInfo(opt.DefStn);
- wchar_t buf[2] = { var.c, 0 }, str[4096];
- GetDisplay(&winfo, buf, str);
- MessageBox(nullptr, str, TranslateT("Weather Protocol Text Preview"), MB_OK | MB_TOPMOST);
- }
- break;
-
- case ID_MRESET:
- SetDlgItemText(hdlg, var.id, GetDefaultText(var.c));
- break;
- }
- DestroyMenu(hMenu);
- }
- break;
+ m_proto->SaveOptions();
+ m_proto->UpdateAllInfo(0, 0);
+ return true;
+ }
- case IDC_RESET:
- // left click action selection menu
- button = GetDlgItem(hdlg, IDC_RESET);
- GetWindowRect(button, &pos);
- hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_TMENU));
- hMenu1 = GetSubMenu(hMenu, 0);
- TranslateMenu(hMenu1);
- switch (TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, nullptr)) {
- case ID_T1:
- // reset to the strings in memory, discard all changes
- for (auto &it : controls)
- SetDlgItemText(hdlg, it.id, GetTextValue(it.c));
+ void onClick_More(CCtrlButton *)
+ {
+ MoreVarList();
+ }
+
+ void onClick_TM(CCtrlButton *pButton)
+ {
+ // display the menu
+ RECT pos;
+ GetWindowRect(pButton->GetHwnd(), &pos);
+ HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_TMMENU));
+ HMENU hMenu1 = GetSubMenu(hMenu, 0);
+ TranslateMenu(hMenu1);
+ {
+ auto &var = controls[pButton->GetCtrlId() - IDC_TM1];
+
+ switch (TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, m_hwnd, nullptr)) {
+ case ID_MPREVIEW:
+ {
+ // show the preview in a message box, using the weather data from the default station
+ WEATHERINFO winfo = LoadWeatherInfo(m_proto->opt.DefStn);
+ wchar_t buf[2] = { var.c, 0 }, str[4096];
+ GetDisplay(&winfo, buf, str);
+ MessageBox(nullptr, str, TranslateT("Weather Protocol Text Preview"), MB_OK | MB_TOPMOST);
+ }
break;
- case ID_T2:
- // reset to the default setting
- for (auto &it : controls)
- SetDlgItemText(hdlg, it.id, GetDefaultText(it.c));
+ case ID_MRESET:
+ SetDlgItemText(m_hwnd, var.id, GetDefaultText(var.c));
break;
}
DestroyMenu(hMenu);
- break;
}
- return TRUE;
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- // save the option
- wchar_t textstr[MAX_TEXT_SIZE];
- for (auto &it : controls) {
- GetDlgItemText(hdlg, it.id, textstr, _countof(textstr));
- if (!mir_wstrcmpi(textstr, GetDefaultText(it.c)))
- g_plugin.delSetting(it.setting);
- else
- g_plugin.setWString(it.setting, textstr);
- }
+ }
+
+ void onClick_Reset(CCtrlButton *)
+ {
+ // left click action selection menu
+ RECT pos;
+ GetWindowRect(btnReset.GetHwnd(), &pos);
+ HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_TMENU));
+ HMENU hMenu1 = GetSubMenu(hMenu, 0);
+ TranslateMenu(hMenu1);
+ switch (TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, m_hwnd, nullptr)) {
+ case ID_T1:
+ // reset to the strings in memory, discard all changes
+ for (auto &it : controls)
+ SetDlgItemText(m_hwnd, it.id, m_proto->GetTextValue(it.c));
+ break;
- SaveOptions();
- UpdateAllInfo(0, 0);
+ case ID_T2:
+ // reset to the default setting
+ for (auto &it : controls)
+ SetDlgItemText(m_hwnd, it.id, GetDefaultText(it.c));
break;
}
- break;
+ DestroyMenu(hMenu);
}
- return FALSE;
-}
-
-
-//============ OPTION INITIALIZATION ============
+};
+/////////////////////////////////////////////////////////////////////////////////////////
// register the weather option pages
-int OptInit(WPARAM wParam, LPARAM)
+
+int CWeatherProto::OptInit(WPARAM wParam, LPARAM)
{
- // plugin options
OPTIONSDIALOGPAGE odp = {};
+ odp.szGroup.w = LPGENW("Network");
+ odp.szTitle.w = m_tszUserName;
odp.position = 95600;
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
- odp.pfnDlgProc = OptionsProc;
- odp.szGroup.a = LPGEN("Network");
- odp.szTitle.a = MODULENAME;
+ odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE;
+
+ // plugin options
+ odp.pDialog = new COptionsDlg(this);
odp.szTab.a = LPGEN("General");
- odp.flags = ODPF_BOLDGROUPS;
g_plugin.addOptions(wParam, &odp);
// text options
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_TEXTOPT);
- odp.pfnDlgProc = DlgProcText;
+ odp.pDialog = new COptionsTextDlg(this);
odp.szTab.a = LPGEN("Display");
g_plugin.addOptions(wParam, &odp);
- // if popup service exists, load the weather popup options
- odp.position = 100000000;
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_POPUP);
- odp.szGroup.a = LPGEN("Popups");
- odp.szTab.a = nullptr;
- odp.pfnDlgProc = DlgPopupOpts;
- g_plugin.addOptions(wParam, &odp);
+ InitPopupOptions(wParam);
return 0;
}
diff --git a/protocols/Weather/src/weather_popup.cpp b/protocols/Weather/src/weather_popup.cpp
index 992db0a69a..e9fa6bd427 100644
--- a/protocols/Weather/src/weather_popup.cpp
+++ b/protocols/Weather/src/weather_popup.cpp
@@ -27,37 +27,33 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// variables for weather_popup.c
static MCONTACT hPopupContact;
-//============ SHOW WEATHER POPUPS ============
-
-//============ WEATHER ERROR POPUPS ============
+/////////////////////////////////////////////////////////////////////////////////////////
+// wrapper function for displaying weather warning popup by triggering an event (threaded)
+// lpzText = error text
+// kind = display type (see m_popup.h)
-// display weather error or notices (not threaded)
-// wParam = error text
-// lParam = display type
-// Type can either be SM_WARNING, SM_NOTIFY, or SM_WEATHERALERT
-int WeatherError(WPARAM wParam, LPARAM lParam)
+int CWeatherProto::WPShowMessage(const wchar_t *lpzText, int kind)
{
if (!g_plugin.bPopups)
return 0;
- wchar_t* tszMsg = (wchar_t*)wParam;
-
- if ((uint32_t)lParam == SM_WARNING)
- PUShowMessageW(tszMsg, SM_WARNING);
- else if ((uint32_t)lParam == SM_NOTIFY)
- PUShowMessageW(tszMsg, SM_NOTIFY);
- else if ((uint32_t)lParam == SM_WEATHERALERT) {
+ if (kind == SM_WARNING)
+ PUShowMessageW(lpzText, SM_WARNING);
+ else if (kind == SM_NOTIFY)
+ PUShowMessageW(lpzText, SM_NOTIFY);
+ else if (kind == SM_WEATHERALERT) {
POPUPDATAW ppd;
wchar_t str1[512], str2[512];
// get the 2 strings
- wcsncpy(str1, tszMsg, _countof(str1) - 1);
- wcsncpy(str2, tszMsg, _countof(str2) - 1);
+ wcsncpy(str1, lpzText, _countof(str1) - 1);
+ wcsncpy(str2, lpzText, _countof(str2) - 1);
wchar_t *chop = wcschr(str1, 255);
if (chop != nullptr)
*chop = '\0';
else
str1[0] = 0;
+
chop = wcschr(str2, 255);
if (chop != nullptr)
wcsncpy(str2, chop + 1, _countof(str2) - 1);
@@ -77,38 +73,28 @@ int WeatherError(WPARAM wParam, LPARAM lParam)
return 0;
}
-// wrapper function for displaying weather warning popup by triggering an event
-// (threaded)
-// lpzText = error text
-// kind = display type (see m_popup.h)
-int WPShowMessage(const wchar_t* lpzText, uint16_t kind)
-{
- NotifyEventHooks(hHookWeatherError, (WPARAM)lpzText, (LPARAM)kind);
- return 0;
-}
-
-//============ WEATHER POPUP PROCESSES ============
-
+/////////////////////////////////////////////////////////////////////////////////////////
// popup dialog pocess
// for selecting actions when click on the popup window
// use for displaying contact menu
+
static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
- uint32_t ID = 0;
- MCONTACT hContact;
- hContact = PUGetContact(hWnd);
+ uint32_t ID;
+ MCONTACT hContact = PUGetContact(hWnd);
+ auto *ppro = (CWeatherProto*)Proto_GetContactInstance(hContact);
switch (message) {
case WM_COMMAND:
- ID = opt.LeftClickAction;
+ ID = (ppro) ? ppro->opt.LeftClickAction : 0;
if (ID != IDM_M7) PUDeletePopup(hWnd);
- SendMessage(hPopupWindow, ID, hContact, 0);
+ SendMessage(hPopupWindow, ID, hContact, LPARAM(ppro));
return TRUE;
case WM_CONTEXTMENU:
- ID = opt.RightClickAction;
+ ID = (ppro) ? ppro->opt.RightClickAction : IDM_M7;
if (ID != IDM_M7) PUDeletePopup(hWnd);
- SendMessage(hPopupWindow, ID, hContact, 0);
+ SendMessage(hPopupWindow, ID, hContact, LPARAM(ppro));
return TRUE;
case UM_FREEPLUGINDATA:
@@ -119,13 +105,15 @@ static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPA
return DefWindowProc(hWnd, message, wParam, lParam);
}
+/////////////////////////////////////////////////////////////////////////////////////////
// display weather popups
// wParam = the contact to display popup
// lParam = whether the weather data is changed or not
-int WeatherPopup(WPARAM hContact, LPARAM lParam)
+
+int CWeatherProto::WeatherPopup(MCONTACT hContact, bool bAlways)
{
// determine if the popup should display or not
- if (g_plugin.bPopups && opt.UpdatePopup && (!opt.PopupOnChange || (BOOL)lParam) && !g_plugin.getByte(hContact, "DPopUp")) {
+ if (g_plugin.bPopups && opt.UpdatePopup && (!opt.PopupOnChange || bAlways) && !g_plugin.getByte(hContact, "DPopUp")) {
WEATHERINFO winfo = LoadWeatherInfo(hContact);
// setup the popup
@@ -143,24 +131,27 @@ int WeatherPopup(WPARAM hContact, LPARAM lParam)
return 0;
}
-
+/////////////////////////////////////////////////////////////////////////////////////////
// process for the popup window
// containing the code for popup actions
-LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+
+LRESULT CALLBACK CWeatherProto::PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
POINT pt;
HMENU hMenu;
+ auto *ppro = (CWeatherProto *)lParam;
+
switch (uMsg) {
case IDM_M2: // brief info
- BriefInfo(wParam, 0);
+ ppro->BriefInfo(wParam, 0);
break;
case IDM_M3: // read complete forecast
- LoadForecast(wParam, 0);
+ ppro->LoadForecast(wParam, 0);
break;
case IDM_M4: // display weather map
- WeatherMap(wParam, 0);
+ ppro->WeatherMap(wParam, 0);
break;
case IDM_M5: // open history window
@@ -168,7 +159,7 @@ LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
break;
case IDM_M6: // open external log
- ViewLog(wParam, 0);
+ ppro->ViewLog(wParam, 0);
break;
case IDM_M7: // display contact menu
@@ -197,7 +188,7 @@ LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
return DefWindowProc(hWnd, uMsg, wParam, lParam);//FALSE;
}
-//============ POPUP OPTIONS ============
+/////////////////////////////////////////////////////////////////////////////////////////
struct
{
@@ -218,225 +209,245 @@ static void SelectMenuItem(HMENU hMenu, int Check)
CheckMenuItem(hMenu, i, MF_BYPOSITION | ((int)GetMenuItemID(hMenu, i) == Check) * 8);
}
-// temporary read the current option to memory
-// but does not write to the database
-void ReadPopupOpt(HWND hdlg)
+class CPopupOptsDlg : public CWeatherDlgBase
{
- wchar_t str[512];
-
- // popup colour
- opt.TextColour = SendDlgItemMessage(hdlg, IDC_TEXTCOLOUR, CPM_GETCOLOUR, 0, 0);
- opt.BGColour = SendDlgItemMessage(hdlg, IDC_BGCOLOUR, CPM_GETCOLOUR, 0, 0);
-
- // get delay time
- GetDlgItemText(hdlg, IDC_DELAY, str, _countof(str));
- int num = _wtoi(str);
- opt.pDelay = num;
-
- // other options
- opt.UseWinColors = (uint8_t)IsDlgButtonChecked(hdlg, IDC_USEWINCOLORS);
- opt.UpdatePopup = (uint8_t)IsDlgButtonChecked(hdlg, IDC_POP1);
- opt.AlertPopup = (uint8_t)IsDlgButtonChecked(hdlg, IDC_POP2);
- opt.PopupOnChange = (uint8_t)IsDlgButtonChecked(hdlg, IDC_CH);
- opt.ShowWarnings = (uint8_t)IsDlgButtonChecked(hdlg, IDC_W);
-}
+ CCtrlEdit edtDelay;
+ CCtrlCheck chkUseWin;
+ CCtrlButton btnLeft, btnRight, btnPD1, btnPD2, btnPdef, btnVars, btnPreview;
+
+ // temporary read the current option to memory
+ // but does not write to the database
+ void ReadPopupOpt(HWND hdlg)
+ {
+ wchar_t str[512];
+ auto &opt = m_proto->opt;
-// copied and modified from NewStatusNotify
-INT_PTR CALLBACK DlgPopupOpts(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- int ID;
- HMENU hMenu, hMenu1;
- RECT pos;
- HWND button;
- MCONTACT hContact;
+ // popup colour
+ opt.TextColour = SendDlgItemMessage(hdlg, IDC_TEXTCOLOUR, CPM_GETCOLOUR, 0, 0);
+ opt.BGColour = SendDlgItemMessage(hdlg, IDC_BGCOLOUR, CPM_GETCOLOUR, 0, 0);
+
+ // get delay time
+ GetDlgItemText(hdlg, IDC_DELAY, str, _countof(str));
+ int num = _wtoi(str);
+ opt.pDelay = num;
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hdlg);
- SaveOptions();
+ // other options
+ opt.UseWinColors = (uint8_t)IsDlgButtonChecked(hdlg, IDC_USEWINCOLORS);
+ opt.UpdatePopup = (uint8_t)IsDlgButtonChecked(hdlg, IDC_POP1);
+ opt.AlertPopup = (uint8_t)IsDlgButtonChecked(hdlg, IDC_POP2);
+ opt.PopupOnChange = (uint8_t)IsDlgButtonChecked(hdlg, IDC_CH);
+ opt.ShowWarnings = (uint8_t)IsDlgButtonChecked(hdlg, IDC_W);
+ }
+
+public:
+ CPopupOptsDlg(CWeatherProto *ppro) :
+ CWeatherDlgBase(ppro, IDD_POPUP),
+ btnPD1(this, IDC_PD1),
+ btnPD2(this, IDC_PD2),
+ btnPdef(this, IDC_PDEF),
+ btnVars(this, IDC_VAR3),
+ btnLeft(this, IDC_LeftClick),
+ btnRight(this, IDC_RightClick),
+ btnPreview(this, IDC_PREVIEW),
+ edtDelay(this, IDC_DELAY),
+ chkUseWin(this, IDC_USEWINCOLORS)
+ {
+ edtDelay.OnChange = Callback(this, &CPopupOptsDlg::onChanged_Delay);
+ chkUseWin.OnChange = Callback(this, &CPopupOptsDlg::onChanged_UseWin);
+
+ btnPD1.OnClick = Callback(this, &CPopupOptsDlg::onClick_PD1);
+ btnPD2.OnClick = Callback(this, &CPopupOptsDlg::onClick_PD2);
+ btnPdef.OnClick = Callback(this, &CPopupOptsDlg::onClick_Pdef);
+ btnVars.OnClick = Callback(this, &CPopupOptsDlg::onClick_Vars);
+ btnLeft.OnClick = Callback(this, &CPopupOptsDlg::onClick_Left);
+ btnRight.OnClick = Callback(this, &CPopupOptsDlg::onClick_Right);
+ btnPreview.OnClick = Callback(this, &CPopupOptsDlg::onClick_Preview);
+ }
+
+ bool OnInitDialog() override
+ {
+ m_proto->SaveOptions();
// click actions
- hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
- hMenu1 = GetSubMenu(hMenu, 0);
+ HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
+ HMENU hMenu1 = GetSubMenu(hMenu, 0);
wchar_t str[512];
- GetMenuString(hMenu1, opt.LeftClickAction, str, _countof(str), MF_BYCOMMAND);
- SetDlgItemText(hdlg, IDC_LeftClick, TranslateW(str));
- GetMenuString(hMenu1, opt.RightClickAction, str, _countof(str), MF_BYCOMMAND);
- SetDlgItemText(hdlg, IDC_RightClick, TranslateW(str));
+ auto &opt = m_proto->opt;
+ GetMenuStringW(hMenu1, opt.LeftClickAction, str, _countof(str), MF_BYCOMMAND);
+ SetDlgItemTextW(m_hwnd, IDC_LeftClick, TranslateW(str));
+ GetMenuStringW(hMenu1, opt.RightClickAction, str, _countof(str), MF_BYCOMMAND);
+ SetDlgItemTextW(m_hwnd, IDC_RightClick, TranslateW(str));
DestroyMenu(hMenu);
// other options
- CheckDlgButton(hdlg, IDC_E, g_plugin.bPopups ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_POP2, opt.AlertPopup ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_POP1, opt.UpdatePopup ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_CH, opt.PopupOnChange ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hdlg, IDC_W, opt.ShowWarnings ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_E, g_plugin.bPopups ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_POP2, opt.AlertPopup ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_POP1, opt.UpdatePopup ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_CH, opt.PopupOnChange ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(m_hwnd, IDC_W, opt.ShowWarnings ? BST_CHECKED : BST_UNCHECKED);
for (auto &it : controls)
- SetDlgItemText(hdlg, it.id, GetTextValue(it.c));
+ SetDlgItemText(m_hwnd, it.id, m_proto->GetTextValue(it.c));
// setting popup delay option
_ltow(opt.pDelay, str, 10);
- SetDlgItemText(hdlg, IDC_DELAY, str);
+ SetDlgItemText(m_hwnd, IDC_DELAY, str);
if (opt.pDelay == -1)
- CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD2);
+ CheckRadioButton(m_hwnd, IDC_PD1, IDC_PD3, IDC_PD2);
else if (opt.pDelay == 0)
- CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD1);
+ CheckRadioButton(m_hwnd, IDC_PD1, IDC_PD3, IDC_PD1);
else
- CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD3);
+ CheckRadioButton(m_hwnd, IDC_PD1, IDC_PD3, IDC_PD3);
// Colours. First step is configuring the colours.
- SendDlgItemMessage(hdlg, IDC_BGCOLOUR, CPM_SETCOLOUR, 0, opt.BGColour);
- SendDlgItemMessage(hdlg, IDC_TEXTCOLOUR, CPM_SETCOLOUR, 0, opt.TextColour);
+ SendDlgItemMessage(m_hwnd, IDC_BGCOLOUR, CPM_SETCOLOUR, 0, opt.BGColour);
+ SendDlgItemMessage(m_hwnd, IDC_TEXTCOLOUR, CPM_SETCOLOUR, 0, opt.TextColour);
// Second step is disabling them if we want to use default Windows ones.
- CheckDlgButton(hdlg, IDC_USEWINCOLORS, opt.UseWinColors ? BST_CHECKED : BST_UNCHECKED);
- EnableWindow(GetDlgItem(hdlg, IDC_BGCOLOUR), !opt.UseWinColors);
- EnableWindow(GetDlgItem(hdlg, IDC_TEXTCOLOUR), !opt.UseWinColors);
+ CheckDlgButton(m_hwnd, IDC_USEWINCOLORS, opt.UseWinColors ? BST_CHECKED : BST_UNCHECKED);
+ EnableWindow(GetDlgItem(m_hwnd, IDC_BGCOLOUR), !opt.UseWinColors);
+ EnableWindow(GetDlgItem(m_hwnd, IDC_TEXTCOLOUR), !opt.UseWinColors);
// buttons
- SendDlgItemMessage(hdlg, IDC_PREVIEW, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_PDEF, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_LeftClick, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_RightClick, BUTTONSETASFLATBTN, TRUE, 0);
- SendDlgItemMessage(hdlg, IDC_VAR3, BUTTONSETASFLATBTN, TRUE, 0);
- return TRUE;
+ SendDlgItemMessage(m_hwnd, IDC_PREVIEW, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_PDEF, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_LeftClick, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_RightClick, BUTTONSETASFLATBTN, TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_VAR3, BUTTONSETASFLATBTN, TRUE, 0);
+ return true;
+ }
- case WM_COMMAND:
- // enable the "apply" button
- if (HIWORD(wParam) == BN_CLICKED && GetFocus() == (HWND)lParam)
- SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
- if (!((LOWORD(wParam) == IDC_UPDATE || LOWORD(wParam) == IDC_DEGREE) &&
- (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())))
- SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
- //These are simple clicks: we don't save, but we tell the Options Page to enable the "Apply" button.
- switch (LOWORD(wParam)) {
- case IDC_BGCOLOUR: //Fall through
- case IDC_TEXTCOLOUR:
- // select new colors
- if (HIWORD(wParam) == CPN_COLOURCHANGED)
- SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
- break;
+ bool OnApply() override
+ {
+ ReadPopupOpt(m_hwnd);
+
+ wchar_t textstr[MAX_TEXT_SIZE];
+ for (auto &it : controls) {
+ GetDlgItemText(m_hwnd, it.id, textstr, _countof(textstr));
+ if (!mir_wstrcmpi(textstr, GetDefaultText(it.c)))
+ g_plugin.delSetting(it.setting);
+ else
+ g_plugin.setWString(it.setting, textstr);
+ }
- case IDC_USEWINCOLORS:
- // use window color - enable/disable color selection controls
- EnableWindow(GetDlgItem(hdlg, IDC_BGCOLOUR), !(opt.UseWinColors));
- EnableWindow(GetDlgItem(hdlg, IDC_TEXTCOLOUR), !(opt.UseWinColors));
- SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
- break;
+ // save the options, and update main menu
+ m_proto->SaveOptions();
+ return true;
+ }
- case IDC_E:
- case IDC_CH:
- SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
- break;
+ void onChanged_UseWin(CCtrlCheck *)
+ {
+ // use window color - enable/disable color selection controls
+ EnableWindow(GetDlgItem(m_hwnd, IDC_BGCOLOUR), !(m_proto->opt.UseWinColors));
+ EnableWindow(GetDlgItem(m_hwnd, IDC_TEXTCOLOUR), !(m_proto->opt.UseWinColors));
+ }
- case IDC_RightClick:
- // right click action selection menu
- button = GetDlgItem(hdlg, IDC_RightClick);
- GetWindowRect(button, &pos);
-
- hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
- hMenu1 = GetSubMenu(hMenu, 0);
- TranslateMenu(hMenu1);
- SelectMenuItem(hMenu1, opt.RightClickAction);
- ID = TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, nullptr);
- if (ID)
- opt.RightClickAction = ID;
- DestroyMenu(hMenu);
-
- hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
- hMenu1 = GetSubMenu(hMenu, 0);
- GetMenuString(hMenu1, opt.RightClickAction, str, _countof(str), MF_BYCOMMAND);
- SetDlgItemText(hdlg, IDC_RightClick, TranslateW(str));
- DestroyMenu(hMenu);
- break;
+ void onClick_Right(CCtrlButton *)
+ {
+ // right click action selection menu
+ RECT pos;
+ GetWindowRect(GetDlgItem(m_hwnd, IDC_RightClick), &pos);
+
+ HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
+ HMENU hMenu1 = GetSubMenu(hMenu, 0);
+ TranslateMenu(hMenu1);
+ SelectMenuItem(hMenu1, m_proto->opt.RightClickAction);
+ int ID = TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, m_hwnd, nullptr);
+ if (ID)
+ m_proto->opt.RightClickAction = ID;
+ DestroyMenu(hMenu);
- case IDC_LeftClick:
- // left click action selection menu
- button = GetDlgItem(hdlg, IDC_LeftClick);
- GetWindowRect(button, &pos);
-
- hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
- hMenu1 = GetSubMenu(hMenu, 0);
- TranslateMenu(hMenu1);
- SelectMenuItem(hMenu1, opt.LeftClickAction);
- ID = TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, hdlg, nullptr);
- if (ID) opt.LeftClickAction = ID;
- DestroyMenu(hMenu);
-
- hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
- hMenu1 = GetSubMenu(hMenu, 0);
- GetMenuString(hMenu1, opt.LeftClickAction, str, _countof(str), MF_BYCOMMAND);
- SetDlgItemText(hdlg, IDC_LeftClick, TranslateW(str));
- DestroyMenu(hMenu);
- break;
+ hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
- case IDC_PD1:
- // Popup delay setting from popup plugin
- SetDlgItemText(hdlg, IDC_DELAY, L"0");
- CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD1);
- break;
+ wchar_t str[512];
+ GetMenuString(hMenu1, m_proto->opt.RightClickAction, str, _countof(str), MF_BYCOMMAND);
+ SetDlgItemText(m_hwnd, IDC_RightClick, TranslateW(str));
+ DestroyMenu(hMenu);
+ }
- case IDC_PD2:
- // Popup delay = permanent
- SetDlgItemText(hdlg, IDC_DELAY, L"-1");
- CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD2);
- break;
+ void onClick_Left(CCtrlButton *)
+ {
+ // left click action selection menu
+ RECT pos;
+ GetWindowRect(GetDlgItem(m_hwnd, IDC_LeftClick), &pos);
+
+ HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
+ HMENU hMenu1 = GetSubMenu(hMenu, 0);
+ TranslateMenu(hMenu1);
+ SelectMenuItem(hMenu1, m_proto->opt.LeftClickAction);
+ int ID = TrackPopupMenu(hMenu1, TPM_LEFTBUTTON | TPM_RETURNCMD, pos.left, pos.bottom, 0, m_hwnd, nullptr);
+ if (ID)
+ m_proto->opt.LeftClickAction = ID;
+ DestroyMenu(hMenu);
- case IDC_DELAY:
- // if text is edited
- CheckRadioButton(hdlg, IDC_PD1, IDC_PD3, IDC_PD3);
- break;
+ hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_PMENU));
+ hMenu1 = GetSubMenu(hMenu, 0);
- case IDC_PDEF:
- // set the default value for popup texts
- for (auto &it : controls)
- SetDlgItemText(hdlg, it.id, GetDefaultText(it.c));
- break;
+ wchar_t str[512];
+ GetMenuString(hMenu1, m_proto->opt.LeftClickAction, str, _countof(str), MF_BYCOMMAND);
+ SetDlgItemText(m_hwnd, IDC_LeftClick, TranslateW(str));
+ DestroyMenu(hMenu);
+ }
- case IDC_VAR3:
- // display variable list
- {
- CMStringW wszText;
- wszText += L" \n"; // to make the message box wider
- wszText += TranslateT("%c\tcurrent condition\n%d\tcurrent date\n%e\tdewpoint\n%f\tfeel-like temperature\n%h\ttoday's high\n%i\twind direction\n%l\ttoday's low\n%m\thumidity\n%n\tstation name\n%p\tpressure\n%r\tsunrise time\n%s\tstation ID\n%t\ttemperature\n%u\tupdate time\n%v\tvisibility\n%w\twind speed\n%y\tsun set");
- wszText += L"\n";
- wszText += TranslateT("%[..]\tcustom variables");
- MessageBox(nullptr, wszText, TranslateT("Variable List"), MB_OK | MB_ICONASTERISK | MB_TOPMOST);
- }
- break;
+ void onClick_PD1(CCtrlButton *)
+ {
+ // Popup delay setting from popup plugin
+ SetDlgItemText(m_hwnd, IDC_DELAY, L"0");
+ CheckRadioButton(m_hwnd, IDC_PD1, IDC_PD3, IDC_PD1);
+ }
- case IDC_PREVIEW:
- // popup preview
- hContact = opt.DefStn;
- ReadPopupOpt(hdlg); // read new options to memory
- WeatherPopup((WPARAM)opt.DefStn, (BOOL)TRUE); // display popup using new opt
- LoadOptions(); // restore old option in memory
- opt.DefStn = hContact;
- break;
- }
- break;
+ void onClick_PD2(CCtrlButton *)
+ {
+ // Popup delay = permanent
+ SetDlgItemText(m_hwnd, IDC_DELAY, L"-1");
+ CheckRadioButton(m_hwnd, IDC_PD1, IDC_PD3, IDC_PD2);
+ }
- case WM_NOTIFY: //Here we have pressed either the OK or the APPLY button.
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- ReadPopupOpt(hdlg);
-
- wchar_t textstr[MAX_TEXT_SIZE];
- for (auto &it : controls) {
- GetDlgItemText(hdlg, it.id, textstr, _countof(textstr));
- if (!mir_wstrcmpi(textstr, GetDefaultText(it.c)))
- g_plugin.delSetting(it.setting);
- else
- g_plugin.setWString(it.setting, textstr);
- }
-
- // save the options, and update main menu
- SaveOptions();
- return TRUE;
- }
- break;
+ void onChanged_Delay(CCtrlEdit *)
+ {
+ // if text is edited
+ CheckRadioButton(m_hwnd, IDC_PD1, IDC_PD3, IDC_PD3);
}
- return FALSE;
+
+ void onClick_Pdef(CCtrlButton *)
+ {
+ // set the default value for popup texts
+ for (auto &it : controls)
+ SetDlgItemText(m_hwnd, it.id, GetDefaultText(it.c));
+ }
+
+ void onClick_Vars(CCtrlButton *)
+ {
+ // display variable list
+ CMStringW wszText;
+ wszText += L" \n"; // to make the message box wider
+ wszText += TranslateT("%c\tcurrent condition\n%d\tcurrent date\n%e\tdewpoint\n%f\tfeel-like temperature\n%h\ttoday's high\n%i\twind direction\n%l\ttoday's low\n%m\thumidity\n%n\tstation name\n%p\tpressure\n%r\tsunrise time\n%s\tstation ID\n%t\ttemperature\n%u\tupdate time\n%v\tvisibility\n%w\twind speed\n%y\tsun set");
+ wszText += L"\n";
+ wszText += TranslateT("%[..]\tcustom variables");
+ MessageBox(nullptr, wszText, TranslateT("Variable List"), MB_OK | MB_ICONASTERISK | MB_TOPMOST);
+ }
+
+ void onClick_Preview(CCtrlButton *)
+ {
+ // popup preview
+ MCONTACT hContact = m_proto->opt.DefStn;
+ ReadPopupOpt(m_hwnd); // read new options to memory
+ m_proto->WeatherPopup(m_proto->opt.DefStn, true); // display popup using new opt
+ m_proto->LoadOptions(); // restore old option in memory
+ m_proto->opt.DefStn = hContact;
+ }
+};
+
+void CWeatherProto::InitPopupOptions(WPARAM wParam)
+{
+ // if popup service exists, load the weather popup options
+ OPTIONSDIALOGPAGE odp = {};
+ odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE;
+ odp.position = 100000000;
+ odp.szGroup.w = LPGENW("Popups");
+ odp.szTitle.w = m_tszUserName;
+ odp.pDialog = new CPopupOptsDlg(this);
+ g_plugin.addOptions(wParam, &odp);
}
diff --git a/protocols/Weather/src/weather_proto.cpp b/protocols/Weather/src/weather_proto.cpp
new file mode 100644
index 0000000000..235f62294e
--- /dev/null
+++ b/protocols/Weather/src/weather_proto.cpp
@@ -0,0 +1,116 @@
+/*
+Copyright (C) 2012-25 Miranda NG team (https://miranda-ng.org)
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+CWeatherProto::CWeatherProto(const char *protoName, const wchar_t *userName) :
+ PROTO<CWeatherProto>(protoName, userName),
+ m_impl(*this),
+ hUpdateMutex(CreateMutex(nullptr, FALSE, nullptr))
+{
+ HookProtoEvent(ME_OPT_INITIALISE, &CWeatherProto::OptInit);
+ HookProtoEvent(ME_CLIST_DOUBLECLICKED, &CWeatherProto::BriefInfoEvt);
+ HookProtoEvent(ME_CLIST_PREBUILDCONTACTMENU, &CWeatherProto::BuildContactMenu);
+
+ InitMwin();
+
+ // reset the weather data at startup for individual contacts
+ EraseAllInfo();
+
+ // load options and set defaults
+ LoadOptions();
+
+ // menu items
+ InitMenuItems();
+
+ // netlib
+ NETLIBUSER nlu = {};
+ nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_UNICODE;
+ nlu.szSettingsModule = m_szModuleName;
+ nlu.szDescriptiveName.w = m_tszUserName;
+ m_hNetlibUser = Netlib_RegisterUser(&nlu);
+}
+
+CWeatherProto::~CWeatherProto()
+{
+ DestroyMwin();
+ DestroyUpdateList();
+
+ CloseHandle(hUpdateMutex);
+}
+
+void CWeatherProto::OnModulesLoaded()
+{
+ // timer for the first update
+ m_impl.m_start.Start(5000); // first update is 5 sec after load
+
+ // weather user detail
+ HookProtoEvent(ME_USERINFO_INITIALISE, &CWeatherProto::UserInfoInit);
+}
+
+void CWeatherProto::OnShutdown()
+{
+ m_impl.m_update.Stop();
+
+ SaveOptions(); // save options once more
+
+ WindowList_Broadcast(hWindowList, WM_CLOSE, 0, 0);
+ WindowList_Broadcast(hDataWindowList, WM_CLOSE, 0, 0);
+ SendMessage(hWndSetup, WM_CLOSE, 0, 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CWeatherProto::SetStatus(int new_status)
+{
+ // if we don't want to show status for default station
+ if (m_iStatus != new_status) {
+ int old_status = m_iStatus;
+ m_iStatus = new_status != ID_STATUS_OFFLINE ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
+
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+
+ UpdateMenu(m_iStatus != ID_STATUS_OFFLINE);
+ if (m_iStatus != ID_STATUS_OFFLINE)
+ UpdateAll(FALSE, FALSE);
+ }
+
+ return 0;
+}
+
+// get capabilities protocol service function
+INT_PTR CWeatherProto::GetCaps(int type, MCONTACT)
+{
+ switch (type) {
+ case PFLAGNUM_1:
+ // support search and visible list
+ return PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_EXTSEARCH | PF1_MODEMSGRECV;
+
+ case PFLAGNUM_2:
+ return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT;
+
+ case PFLAGNUM_4:
+ return PF4_AVATARS | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_FORCEAUTH;
+
+ case PFLAGNUM_5: /* this is PFLAGNUM_5 change when alpha SDK is released */
+ return PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT;
+
+ case PFLAG_UNIQUEIDTEXT:
+ return (INT_PTR)TranslateT("Station ID");
+ }
+ return 0;
+}
diff --git a/protocols/Weather/src/weather_svcs.cpp b/protocols/Weather/src/weather_svcs.cpp
index daeb7f8bd1..9c87328209 100644
--- a/protocols/Weather/src/weather_svcs.cpp
+++ b/protocols/Weather/src/weather_svcs.cpp
@@ -32,62 +32,6 @@ extern VARSW g_pwszIconsName;
//============ MIRANDA PROTOCOL SERVICES ============
-// protocol service function for setting weather protocol status
-INT_PTR WeatherSetStatus(WPARAM new_status, LPARAM)
-{
- // if we don't want to show status for default station
- if (status != new_status) {
- old_status = status;
- status = new_status = new_status != ID_STATUS_OFFLINE ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
-
- if (!opt.NoProtoCondition) {
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status);
-
- UpdateMenu(new_status != ID_STATUS_OFFLINE);
- if (new_status != ID_STATUS_OFFLINE)
- UpdateAll(FALSE, FALSE);
- }
- }
-
- return 0;
-}
-
-// get capabilities protocol service function
-INT_PTR WeatherGetCaps(WPARAM wParam, LPARAM)
-{
- INT_PTR ret = 0;
-
- switch (wParam) {
- case PFLAGNUM_1:
- // support search and visible list
- ret = PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_EXTSEARCH | PF1_MODEMSGRECV;
- break;
-
- case PFLAGNUM_2:
- ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT;
- break;
-
- case PFLAGNUM_4:
- ret = PF4_AVATARS | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_FORCEAUTH;
- break;
-
- case PFLAGNUM_5: /* this is PFLAGNUM_5 change when alpha SDK is released */
- ret = PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT;
- break;
-
- case PFLAG_UNIQUEIDTEXT:
- ret = (INT_PTR)TranslateT("Station ID");
- break;
- }
- return ret;
-}
-
-// protocol service function to get the current status of the protocol
-INT_PTR WeatherGetStatus(WPARAM, LPARAM)
-{
- return status;
-}
-
// protocol service function to get the icon of the protocol
INT_PTR WeatherLoadIcon(WPARAM wParam, LPARAM)
{
@@ -256,18 +200,10 @@ static INT_PTR WeatherAdvancedStatusIcon(WPARAM hContact, LPARAM)
// protocol services
void InitServices(void)
{
- CreateProtoServiceFunction(MODULENAME, PS_GETCAPS, WeatherGetCaps);
CreateProtoServiceFunction(MODULENAME, PS_LOADICON, WeatherLoadIcon);
- CreateProtoServiceFunction(MODULENAME, PS_SETSTATUS, WeatherSetStatus);
- CreateProtoServiceFunction(MODULENAME, PS_GETSTATUS, WeatherGetStatus);
- CreateProtoServiceFunction(MODULENAME, PS_BASICSEARCH, WeatherBasicSearch);
- CreateProtoServiceFunction(MODULENAME, PS_SEARCHBYEMAIL, WeatherBasicSearch);
- CreateProtoServiceFunction(MODULENAME, PS_ADDTOLIST, WeatherAddToList);
CreateProtoServiceFunction(MODULENAME, PS_GETINFO, WeatherGetInfo);
CreateProtoServiceFunction(MODULENAME, PS_GETAVATARINFO, WeatherGetAvatarInfo);
CreateProtoServiceFunction(MODULENAME, PS_GETAWAYMSG, WeatherGetAwayMsg);
- CreateProtoServiceFunction(MODULENAME, PS_CREATEADVSEARCHUI, WeatherCreateAdvancedSearchUI);
- CreateProtoServiceFunction(MODULENAME, PS_SEARCHBYADVANCED, WeatherAdvancedSearch);
CreateProtoServiceFunction(MODULENAME, PS_GETADVANCEDSTATUSICON, WeatherAdvancedStatusIcon);
CreateProtoServiceFunction(MODULENAME, MS_WEATHER_GETDISPLAY, GetDisplaySvcFunc);
@@ -275,11 +211,11 @@ void InitServices(void)
//============ MENU INITIALIZATION ============
-void UpdateMenu(BOOL State)
+void CWeatherProto::UpdateMenu(BOOL State)
{
// update option setting
opt.CAutoUpdate = State;
- g_plugin.setByte("AutoUpdate", (uint8_t)State);
+ setByte("AutoUpdate", (uint8_t)State);
if (State) { // to enable auto-update
Menu_ModifyItem(hEnableDisableMenu, LPGENW("Auto Update Enabled"), g_plugin.getIconHandle(IDI_ICON));
@@ -294,87 +230,81 @@ void UpdateMenu(BOOL State)
}
// update the weather auto-update menu item when click on it
-static INT_PTR EnableDisableCmd(WPARAM wParam, LPARAM lParam)
+INT_PTR CWeatherProto::EnableDisableCmd(WPARAM wParam, LPARAM lParam)
{
UpdateMenu(wParam == TRUE ? (BOOL)lParam : !opt.CAutoUpdate);
return 0;
}
-// displays contact info dialog
-static INT_PTR BriefInfoSvc(WPARAM wParam, LPARAM lParam)
-{
- return BriefInfo(wParam, lParam);
-}
-
// adding weather contact menus
// copied and modified form "modified MSN Protocol"
-void AddMenuItems(void)
+void CWeatherProto::InitMenuItems()
{
CMenuItem mi(&g_plugin);
// contact menu
SET_UID(mi, 0x266ef52b, 0x869a, 0x4cac, 0xa9, 0xf8, 0xea, 0x5b, 0xb8, 0xab, 0xe0, 0x24);
- CreateServiceFunction(MS_WEATHER_UPDATE, UpdateSingleStation);
mi.position = -0x7FFFFFFA;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_UPDATE);
mi.name.a = LPGEN("Update Weather");
- mi.pszService = MS_WEATHER_UPDATE;
- Menu_AddContactMenuItem(&mi, MODULENAME);
+ mi.pszService = "/Update";
+ Menu_AddContactMenuItem(&mi, m_szModuleName);
+ CreateProtoService(mi.pszService, &CWeatherProto::UpdateSingleStation);
SET_UID(mi, 0x45361b4, 0x8de, 0x44b4, 0x8f, 0x11, 0x9b, 0xe9, 0x6e, 0xa8, 0x83, 0x54);
- CreateServiceFunction(MS_WEATHER_REFRESH, UpdateSingleRemove);
mi.position = -0x7FFFFFF9;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_UPDATE2);
mi.name.a = LPGEN("Remove Old Data then Update");
- mi.pszService = MS_WEATHER_REFRESH;
- Menu_AddContactMenuItem(&mi, MODULENAME);
+ mi.pszService = "/Refresh";
+ Menu_AddContactMenuItem(&mi, m_szModuleName);
+ CreateProtoService(mi.pszService, &CWeatherProto::UpdateSingleRemove);
SET_UID(mi, 0x4232975e, 0xb181, 0x46a5, 0xb7, 0x6e, 0xd2, 0x5f, 0xef, 0xb8, 0xc4, 0x4d);
- CreateServiceFunction(MS_WEATHER_BRIEF, BriefInfoSvc);
mi.position = -0x7FFFFFF8;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_S);
mi.name.a = LPGEN("Brief Information");
- mi.pszService = MS_WEATHER_BRIEF;
- Menu_AddContactMenuItem(&mi, MODULENAME);
+ mi.pszService = "/Brief";
+ Menu_AddContactMenuItem(&mi, m_szModuleName);
+ CreateProtoService(mi.pszService, &CWeatherProto::BriefInfo);
SET_UID(mi, 0x3d6ed729, 0xd49a, 0x4ae9, 0x8e, 0x2, 0x9f, 0xe0, 0xf0, 0x2c, 0xcc, 0xb1);
- CreateServiceFunction(MS_WEATHER_COMPLETE, LoadForecast);
mi.position = -0x7FFFFFF7;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_READ);
mi.name.a = LPGEN("Read Complete Forecast");
- mi.pszService = MS_WEATHER_COMPLETE;
- Menu_AddContactMenuItem(&mi, MODULENAME);
+ mi.pszService = "/CompleteForecast";
+ Menu_AddContactMenuItem(&mi, m_szModuleName);
+ CreateProtoService(mi.pszService, &CWeatherProto::LoadForecast);
SET_UID(mi, 0xc4b6c5e0, 0x13c3, 0x4e02, 0x8a, 0xeb, 0xeb, 0x8a, 0xe2, 0x66, 0x40, 0xd4);
- CreateServiceFunction(MS_WEATHER_MAP, WeatherMap);
mi.position = -0x7FFFFFF6;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_MAP);
mi.name.a = LPGEN("Weather Map");
- mi.pszService = MS_WEATHER_MAP;
- Menu_AddContactMenuItem(&mi, MODULENAME);
+ mi.pszService = "/Map";
+ Menu_AddContactMenuItem(&mi, m_szModuleName);
+ CreateProtoService(mi.pszService, &CWeatherProto::WeatherMap);
SET_UID(mi, 0xee3ad7f4, 0x3377, 0x4e4c, 0x8f, 0x3c, 0x3b, 0xf5, 0xd4, 0x86, 0x28, 0x25);
- CreateServiceFunction(MS_WEATHER_LOG, ViewLog);
mi.position = -0x7FFFFFF5;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_LOG);
mi.name.a = LPGEN("View Log");
- mi.pszService = MS_WEATHER_LOG;
- Menu_AddContactMenuItem(&mi, MODULENAME);
+ mi.pszService = "/Log";
+ Menu_AddContactMenuItem(&mi, m_szModuleName);
+ CreateProtoService(mi.pszService, &CWeatherProto::ViewLog);
SET_UID(mi, 0x1b01cd6a, 0xe5ee, 0x42b4, 0xa1, 0x6d, 0x43, 0xb9, 0x4, 0x58, 0x43, 0x2e);
- CreateServiceFunction(MS_WEATHER_EDIT, EditSettings);
mi.position = -0x7FFFFFF4;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_EDIT);
mi.name.a = LPGEN("Edit Settings");
- mi.pszService = MS_WEATHER_EDIT;
- Menu_AddContactMenuItem(&mi, MODULENAME);
+ mi.pszService = "/Edit";
+ Menu_AddContactMenuItem(&mi, m_szModuleName);
+ CreateProtoService(mi.pszService, &CWeatherProto::EditSettings);
// adding main menu items
mi.root = g_plugin.addRootMenu(MO_MAIN, LPGENW("Weather"), 500099000);
Menu_ConfigureItem(mi.root, MCI_OPT_UID, "82809D2F-2CF0-4E15-9350-D257A7748552");
SET_UID(mi, 0x5ad16188, 0xe0a0, 0x4c31, 0x85, 0xc3, 0xe4, 0x85, 0x79, 0x7e, 0x4b, 0x9c);
- CreateServiceFunction(MS_WEATHER_ENABLED, EnableDisableCmd);
+ CreateProtoService(MS_WEATHER_ENABLED, &CWeatherProto::EnableDisableCmd);
mi.name.a = LPGEN("Enable/Disable Weather Update");
mi.hIcolibItem = g_plugin.getIconHandle(IDI_ICON);
mi.position = 10100001;
@@ -383,7 +313,7 @@ void AddMenuItems(void)
UpdateMenu(opt.AutoUpdate);
SET_UID(mi, 0x2b1c2054, 0x2991, 0x4025, 0x87, 0x73, 0xb6, 0xf7, 0x85, 0xac, 0xc7, 0x37);
- CreateServiceFunction(MS_WEATHER_UPDATEALL, UpdateAllInfo);
+ CreateProtoService(MS_WEATHER_UPDATEALL, &CWeatherProto::UpdateAllInfo);
mi.position = 20100001;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_UPDATE);
mi.name.a = LPGEN("Update All Weather");
@@ -391,7 +321,7 @@ void AddMenuItems(void)
Menu_AddMainMenuItem(&mi);
SET_UID(mi, 0x8234c00e, 0x788e, 0x424f, 0xbc, 0xc4, 0x2, 0xfd, 0x67, 0x58, 0x2d, 0x19);
- CreateServiceFunction(MS_WEATHER_REFRESHALL, UpdateAllRemove);
+ CreateProtoService(MS_WEATHER_REFRESHALL, &CWeatherProto::UpdateAllRemove);
mi.position = 20100002;
mi.hIcolibItem = g_plugin.getIconHandle(IDI_UPDATE2);
mi.name.a = LPGEN("Remove Old Data then Update All");
@@ -406,6 +336,6 @@ void AddMenuItems(void)
mi.hIcolibItem = nullptr;
mi.root = nullptr;
mi.name.a = LPGEN("Display in a frame");
- hMwinMenu = Menu_AddContactMenuItem(&mi, MODULENAME);
+ hMwinMenu = Menu_AddContactMenuItem(&mi, m_szModuleName);
}
}
diff --git a/protocols/Weather/src/weather_update.cpp b/protocols/Weather/src/weather_update.cpp
index f872d2031f..54bf94c994 100644
--- a/protocols/Weather/src/weather_update.cpp
+++ b/protocols/Weather/src/weather_update.cpp
@@ -29,10 +29,10 @@ menu items).
UPDATELIST *UpdateListHead = nullptr, *UpdateListTail = nullptr;
//============ RETRIEVE NEW WEATHER ============
-//
// retrieve weather info and display / log them
// hContact = current contact
-int UpdateWeather(MCONTACT hContact)
+
+int CWeatherProto::UpdateWeather(MCONTACT hContact)
{
wchar_t str2[MAX_TEXT_SIZE];
DBVARIANT dbv;
@@ -44,10 +44,10 @@ int UpdateWeather(MCONTACT hContact)
dbv.pszVal = "";
// log to netlib log for debug purpose
- Netlib_LogfW(hNetlibUser, L"************************************************************************");
+ Netlib_LogfW(m_hNetlibUser, L"************************************************************************");
int dbres = g_plugin.getWString(hContact, "Nick", &dbv);
- Netlib_LogfW(hNetlibUser, L"<-- Start update for station -->");
+ Netlib_LogfW(m_hNetlibUser, L"<-- Start update for station -->");
// download the info and parse it
// result are stored in database
@@ -62,12 +62,15 @@ int UpdateWeather(MCONTACT hContact)
WPShowMessage(str, SM_WARNING);
}
// log to netlib
- Netlib_LogfW(hNetlibUser, L"Error! Update cannot continue... Start to free memory");
- Netlib_LogfW(hNetlibUser, L"<-- Error occurs while updating station: %s -->", dbv.pwszVal);
- if (!dbres) db_free(&dbv);
+ Netlib_LogfW(m_hNetlibUser, L"Error! Update cannot continue... Start to free memory");
+ Netlib_LogfW(m_hNetlibUser, L"<-- Error occurs while updating station: %s -->", dbv.pwszVal);
+ if (!dbres)
+ db_free(&dbv);
return 1;
}
- if (!dbres) db_free(&dbv);
+
+ if (!dbres)
+ db_free(&dbv);
// initialize, load new weather Data
WEATHERINFO winfo = LoadWeatherInfo(hContact);
@@ -136,7 +139,7 @@ int UpdateWeather(MCONTACT hContact)
else
db_unset(hContact, "CList", "StatusMsg");
- ProtoBroadcastAck(MODULENAME, hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, nullptr, (LPARAM)(str2[0] ? str2 : nullptr));
+ ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, nullptr, (LPARAM)(str2[0] ? str2 : nullptr));
// save descriptions in MyNotes
GetDisplay(&winfo, GetTextValue('N'), str2);
@@ -147,15 +150,14 @@ int UpdateWeather(MCONTACT hContact)
// set the update tag
g_plugin.setByte(hContact, "IsUpdated", TRUE);
- // save info for default weather condition
- if (!mir_wstrcmp(winfo.id, opt.Default) && !opt.NoProtoCondition) {
- // save current condition for default station to be displayed after the update
- old_status = status;
- status = iStatus;
- // a workaround for a default station that currently have an n/a icon assigned
- if (status == ID_STATUS_OFFLINE) status = NOSTATUSDATA;
- ProtoBroadcastAck(MODULENAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, status);
- }
+ // save current condition for default station to be displayed after the update
+ int old_status = m_iStatus;
+ m_iStatus = iStatus;
+
+ // a workaround for a default station that currently have an n/a icon assigned
+ if (m_iStatus == ID_STATUS_OFFLINE)
+ m_iStatus = ID_STATUS_CONNECTING;
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
// logging
if (Ch) {
@@ -198,11 +200,11 @@ int UpdateWeather(MCONTACT hContact)
}
// show the popup
- NotifyEventHooks(hHookWeatherUpdated, hContact, (LPARAM)Ch);
+ WeatherPopup(hContact, Ch);
}
- Netlib_LogfW(hNetlibUser, L"Update Completed - Start to free memory");
- Netlib_LogfW(hNetlibUser, L"<-- Update successful for station -->");
+ Netlib_LogfW(m_hNetlibUser, L"Update Completed - Start to free memory");
+ Netlib_LogfW(m_hNetlibUser, L"<-- Update successful for station -->");
// Update frame data
UpdateMwinData(hContact);
@@ -214,12 +216,12 @@ int UpdateWeather(MCONTACT hContact)
return 0;
}
-//============ UPDATE LIST ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// a linked list queue for updating weather station
// this function add a weather contact to the end of queue for update
// hContact = current contact
-void UpdateListAdd(MCONTACT hContact)
+
+void CWeatherProto::UpdateListAdd(MCONTACT hContact)
{
UPDATELIST *newItem = (UPDATELIST*)mir_alloc(sizeof(UPDATELIST));
newItem->hContact = hContact;
@@ -236,7 +238,7 @@ void UpdateListAdd(MCONTACT hContact)
// get the first item from the update queue and remove it from the queue
// return value = the contact for next update
-MCONTACT UpdateGetFirst()
+MCONTACT CWeatherProto::UpdateGetFirst()
{
MCONTACT hContact = NULL;
@@ -258,7 +260,7 @@ MCONTACT UpdateGetFirst()
return hContact;
}
-void DestroyUpdateList(void)
+void CWeatherProto::DestroyUpdateList(void)
{
WaitForSingleObject(hUpdateMutex, INFINITE);
@@ -275,9 +277,11 @@ void DestroyUpdateList(void)
ReleaseMutex(hUpdateMutex);
}
+/////////////////////////////////////////////////////////////////////////////////////////
// update all weather thread
// this thread update each weather station from the queue
-static void UpdateThreadProc(void *)
+
+void CWeatherProto::UpdateThread(void *)
{
WaitForSingleObject(hUpdateMutex, INFINITE);
if (ThreadRunning) {
@@ -295,15 +299,15 @@ static void UpdateThreadProc(void *)
ThreadRunning = FALSE;
}
-//============ UPDATE WEATHER ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// update all weather station
// AutoUpdate = true if it is from automatic update using timer
// false if it is from update by clicking the main menu
-void UpdateAll(BOOL AutoUpdate, BOOL RemoveData)
+
+void CWeatherProto::UpdateAll(BOOL AutoUpdate, BOOL RemoveData)
{
// add all weather contact to the update queue list
- for (auto &hContact : Contacts(MODULENAME))
+ for (auto &hContact : AccContacts())
if (!g_plugin.getByte(hContact, "AutoUpdate") || !AutoUpdate) {
if (RemoveData)
DBDataManage(hContact, WDBM_REMOVE, 0, 0);
@@ -313,12 +317,14 @@ void UpdateAll(BOOL AutoUpdate, BOOL RemoveData)
// if it is not updating, then start the update thread process
// if it is updating, the stations just added to the queue will get updated by the already-running process
if (!ThreadRunning)
- mir_forkthread(UpdateThreadProc);
+ ForkThread(&CWeatherProto::UpdateThread);
}
+/////////////////////////////////////////////////////////////////////////////////////////
// update a single station
// wParam = handle for the weather station that is going to be updated
-INT_PTR UpdateSingleStation(WPARAM wParam, LPARAM)
+
+INT_PTR CWeatherProto::UpdateSingleStation(WPARAM wParam, LPARAM)
{
if (IsMyContact(wParam)) {
// add the station to the end of the update queue
@@ -328,15 +334,17 @@ INT_PTR UpdateSingleStation(WPARAM wParam, LPARAM)
// if it is updating, the stations just added to the queue will get
// updated by the already-running process
if (!ThreadRunning)
- mir_forkthread(UpdateThreadProc);
+ ForkThread(&CWeatherProto::UpdateThread);
}
return 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// update a single station with removing the old data
// wParam = handle for the weather station that is going to be updated
-INT_PTR UpdateSingleRemove(WPARAM wParam, LPARAM)
+
+INT_PTR CWeatherProto::UpdateSingleRemove(WPARAM wParam, LPARAM)
{
if (IsMyContact(wParam)) {
// add the station to the end of the update queue, and also remove old data
@@ -346,33 +354,37 @@ INT_PTR UpdateSingleRemove(WPARAM wParam, LPARAM)
// if it is not updating, then start the update thread process
// if it is updating, the stations just added to the queue will get updated by the already-running process
if (!ThreadRunning)
- mir_forkthread(UpdateThreadProc);
+ ForkThread(&CWeatherProto::UpdateThread);
}
return 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// the "Update All" menu item in main menu
-INT_PTR UpdateAllInfo(WPARAM, LPARAM)
+
+INT_PTR CWeatherProto::UpdateAllInfo(WPARAM, LPARAM)
{
if (!ThreadRunning)
UpdateAll(FALSE, FALSE);
return 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// the "Update All" menu item in main menu and remove the old data
-INT_PTR UpdateAllRemove(WPARAM, LPARAM)
+
+INT_PTR CWeatherProto::UpdateAllRemove(WPARAM, LPARAM)
{
if (!ThreadRunning)
UpdateAll(FALSE, TRUE);
return 0;
}
-//============ GETTING WEATHER DATA ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// getting weather data and save them into the database
// hContact = the contact to get the data
-int GetWeatherData(MCONTACT hContact)
+
+int CWeatherProto::GetWeatherData(MCONTACT hContact)
{
// get each part of the id's
wchar_t id[256];
@@ -577,28 +589,29 @@ int GetWeatherData(MCONTACT hContact)
return 0;
}
-//============ UPDATE TIMERS ============
-//
+/////////////////////////////////////////////////////////////////////////////////////////
// main auto-update timer
-void CALLBACK timerProc(HWND, UINT, UINT_PTR, DWORD)
+
+void CWeatherProto::DoUpdate()
{
// only run if it is not current updating and the auto update option is enabled
- if (!ThreadRunning && opt.CAutoUpdate && !Miranda_IsTerminated() && (opt.NoProtoCondition || status == ID_STATUS_ONLINE))
+ if (!ThreadRunning && opt.CAutoUpdate && !Miranda_IsTerminated() && m_iStatus == ID_STATUS_ONLINE)
UpdateAll(TRUE, FALSE);
}
-
// temporary timer for first run
// when this is run, it kill the old startup timer and create the permenant one above
-void CALLBACK timerProc2(HWND, UINT, UINT_PTR, DWORD)
+
+void CWeatherProto::StartUpdate()
{
- KillTimer(nullptr, timerId);
- ThreadRunning = FALSE;
+ ThreadRunning = false;
- if (Miranda_IsTerminated())
- return;
+ if (!Miranda_IsTerminated())
+ m_impl.m_update.Start(opt.UpdateTime * 60000);
+}
- if (opt.StartupUpdate && opt.NoProtoCondition)
- UpdateAll(FALSE, FALSE);
- timerId = SetTimer(nullptr, 0, ((int)opt.UpdateTime) * 60000, timerProc);
+void CWeatherProto::RestartTimer()
+{
+ m_impl.m_update.Stop();
+ m_impl.m_update.Start(opt.UpdateTime * 60000);
}
diff --git a/protocols/Weather/src/weather_userinfo.cpp b/protocols/Weather/src/weather_userinfo.cpp
index ecee919ce5..d8e06bbde9 100644
--- a/protocols/Weather/src/weather_userinfo.cpp
+++ b/protocols/Weather/src/weather_userinfo.cpp
@@ -27,73 +27,47 @@ information
#include "stdafx.h"
-//============ BRIEF INFORMATION ============
-//
-static int BriefDlgResizer(HWND, LPARAM, UTILRESIZECONTROL *urc)
-{
- switch (urc->wId) {
- case IDC_HEADERBAR:
- return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH;
-
- case IDC_MTEXT:
- case IDC_DATALIST:
- return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
-
- case IDC_MUPDATE:
- return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM;
-
- case IDC_MTOGGLE:
- case IDC_MWEBPAGE:
- case IDCANCEL:
- return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
- }
- return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
-}
+/////////////////////////////////////////////////////////////////////////////////////////
+// dialog process for more data in the user info window
+// lParam = contact handle
-// set the title of the dialog and on the which rectangle
-// also load brief info into message box
-static void LoadBriefInfoText(HWND hwndDlg, MCONTACT hContact)
+class CBriefInfoDlg : public CWeatherDlgBase
{
- wchar_t str[4096];
+ static const unsigned tabstops = 48;
+ MCONTACT hContact;
- // load weather information from the contact into the WEATHERINFO struct
- WEATHERINFO winfo = LoadWeatherInfo(hContact);
- // check if data exist. If not, display error message box
- if (!g_plugin.getByte(hContact, "IsUpdated"))
- SetDlgItemTextW(hwndDlg, IDC_MTEXT, TranslateT("No information available.\r\nPlease update weather condition first."));
- else {
- // set the display text and show the message box
- GetDisplay(&winfo, GetTextValue('B'), str);
- SetDlgItemTextW(hwndDlg, IDC_MTEXT, str);
- }
+ UI_MESSAGE_MAP(CBriefInfoDlg, CWeatherDlgBase);
+ UI_MESSAGE(WM_UPDATEDATA, OnUpdate);
+ UI_MESSAGE_MAP_END();
- GetDisplay(&winfo, L"%c, %t", str);
- SetWindowTextW(hwndDlg, winfo.city);
- SetDlgItemTextW(hwndDlg, IDC_HEADERBAR, str);
-}
+ CCtrlButton btnUpdate, btnWebpage, btnToggle;
-// dialog process for more data in the user info window
-// lParam = contact handle
-static INT_PTR CALLBACK DlgProcMoreData(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- static const unsigned tabstops = 48;
- MCONTACT hContact = (MCONTACT)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+public:
+ CBriefInfoDlg(CWeatherProto *ppro, MCONTACT _1) :
+ CWeatherDlgBase(ppro, IDD_BRIEF),
+ hContact(_1),
+ btnToggle(this, IDC_MTOGGLE),
+ btnUpdate(this, IDC_MUPDATE),
+ btnWebpage(this, IDC_MWEBPAGE)
+ {
+ SetMinSize(350, 300);
- switch (msg) {
- case WM_INITDIALOG:
- // save the contact handle for later use
- hContact = lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)hContact);
+ btnToggle.OnClick = Callback(this, &CBriefInfoDlg::onClick_Toggle);
+ btnUpdate.OnClick = Callback(this, &CBriefInfoDlg::onClick_Update);
+ btnWebpage.OnClick = Callback(this, &CBriefInfoDlg::onClick_Webpage);
+ }
- SendDlgItemMessage(hwndDlg, IDC_MTEXT, EM_AUTOURLDETECT, (WPARAM)TRUE, 0);
- SendDlgItemMessage(hwndDlg, IDC_MTEXT, EM_SETEVENTMASK, 0, ENM_LINK);
- SendDlgItemMessage(hwndDlg, IDC_MTEXT, EM_SETMARGINS, EC_LEFTMARGIN, 5);
- SendDlgItemMessage(hwndDlg, IDC_MTEXT, EM_SETTABSTOPS, 1, (LPARAM)&tabstops);
+ bool OnInitDialog() override
+ {
+ SendDlgItemMessage(m_hwnd, IDC_MTEXT, EM_AUTOURLDETECT, (WPARAM)TRUE, 0);
+ SendDlgItemMessage(m_hwnd, IDC_MTEXT, EM_SETEVENTMASK, 0, ENM_LINK);
+ SendDlgItemMessage(m_hwnd, IDC_MTEXT, EM_SETMARGINS, EC_LEFTMARGIN, 5);
+ SendDlgItemMessage(m_hwnd, IDC_MTEXT, EM_SETTABSTOPS, 1, (LPARAM)&tabstops);
// get the list to display
{
LV_COLUMN lvc = {};
- HWND hList = GetDlgItem(hwndDlg, IDC_DATALIST);
+ HWND hList = GetDlgItem(m_hwnd, IDC_DATALIST);
RECT aRect = {};
GetClientRect(hList, &aRect);
@@ -113,146 +87,140 @@ static INT_PTR CALLBACK DlgProcMoreData(HWND hwndDlg, UINT msg, WPARAM wParam, L
ListView_InsertColumn(hList, 1, &lvc);
// inserting data
- SendMessage(hwndDlg, WM_UPDATEDATA, 0, 0);
+ SendMessage(m_hwnd, WM_UPDATEDATA, 0, 0);
}
- TranslateDialogDefault(hwndDlg);
+ TranslateDialogDefault(m_hwnd);
// prevent dups of the window
- WindowList_Add(hDataWindowList, hwndDlg, hContact);
+ WindowList_Add(hDataWindowList, m_hwnd, hContact);
// restore window position
- Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, MODULENAME, "BriefInfo_");
- return TRUE;
-
- case WM_UPDATEDATA:
- ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_DATALIST));
- LoadBriefInfoText(hwndDlg, hContact);
- DBDataManage(hContact, WDBM_DETAILDISPLAY, (WPARAM)hwndDlg, 0);
-
- // set icons
- {
- HICON hIcon = GetStatusIconBig(hContact);
- DestroyIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, LPARAM(hIcon)));
- DestroyIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, LPARAM(hIcon)));
- }
-
- RedrawWindow(GetDlgItem(hwndDlg, IDC_HEADERBAR), nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
- break;
-
- case WM_SIZE:
- {
- RECT rc;
- HWND hList = GetDlgItem(hwndDlg, IDC_DATALIST);
- GetWindowRect(hList, &rc);
- ListView_SetColumnWidth(hList, 1, ListView_GetColumnWidth(hList, 1) + (int)LOWORD(lParam) - (rc.right - rc.left));
+ Utils_RestoreWindowPositionNoMove(m_hwnd, NULL, MODULENAME, "BriefInfo_");
+ return true;
+ }
- Utils_ResizeDialog(hwndDlg, g_plugin.getInst(), MAKEINTRESOURCEA(IDD_BRIEF), BriefDlgResizer);
- }
- break;
+ void OnDestroy() override
+ {
+ DestroyIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_BIG, 0));
+ DestroyIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_SMALL, 0));
- case WM_GETMINMAXINFO:
- {
- LPMINMAXINFO mmi = (LPMINMAXINFO)lParam;
+ Utils_SaveWindowPosition(m_hwnd, NULL, MODULENAME, "BriefInfo_");
+ WindowList_Remove(hDataWindowList, m_hwnd);
+ }
- // The minimum width in points
- mmi->ptMinTrackSize.x = 350;
- // The minimum height in points
- mmi->ptMinTrackSize.y = 300;
- }
- break;
+ int Resizer(UTILRESIZECONTROL *urc) override
+ {
+ switch (urc->wId) {
+ case IDC_HEADERBAR:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDCANCEL:
- // close the info window
- DestroyWindow(hwndDlg);
- break;
+ case IDC_MTEXT:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
- case IDC_MUPDATE:
+ case IDC_DATALIST:
{
- HWND hList = GetDlgItem(hwndDlg, IDC_DATALIST);
-
- // update current data
- // set the text to "updating"
- SetDlgItemText(hwndDlg, IDC_MTEXT, TranslateT("Retrieving new data, please wait..."));
- ListView_DeleteAllItems(hList);
-
- LV_ITEM lvi = {};
- lvi.mask = LVIF_TEXT | LVIF_PARAM;
- lvi.lParam = 1;
- lvi.pszText = L"";
- lvi.iItem = ListView_InsertItem(hList, &lvi);
- lvi.pszText = TranslateT("Retrieving new data, please wait...");
- ListView_SetItemText(hList, lvi.iItem, 1, lvi.pszText);
- UpdateSingleStation(hContact, 0);
- break;
+ HWND hList = GetDlgItem(m_hwnd, IDC_DATALIST);
+ RECT rc;
+ GetWindowRect(hList, &rc);
+ ListView_SetColumnWidth(hList, 1, ListView_GetColumnWidth(hList, 1) + urc->dlgNewSize.cx - (rc.right - rc.left));
}
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
- case IDC_MWEBPAGE:
- LoadForecast(hContact, 0); // read complete forecast
- break;
+ case IDC_MUPDATE:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM;
case IDC_MTOGGLE:
- if (IsWindowVisible(GetDlgItem(hwndDlg, IDC_DATALIST)))
- SetDlgItemText(hwndDlg, IDC_MTOGGLE, TranslateT("More Info"));
- else
- SetDlgItemText(hwndDlg, IDC_MTOGGLE, TranslateT("Brief Info"));
- ShowWindow(GetDlgItem(hwndDlg, IDC_DATALIST), (int)!IsWindowVisible(
- GetDlgItem(hwndDlg, IDC_DATALIST)));
- ShowWindow(GetDlgItem(hwndDlg, IDC_MTEXT), (int)!IsWindowVisible(GetDlgItem(hwndDlg, IDC_MTEXT)));
- break;
+ case IDC_MWEBPAGE:
+ case IDCANCEL:
+ return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
}
- break;
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
+ }
- case WM_NOTIFY:
- {
- LPNMHDR pNmhdr = (LPNMHDR)lParam;
- if (pNmhdr->idFrom == IDC_MTEXT && pNmhdr->code == EN_LINK) {
- ENLINK *enlink = (ENLINK *)lParam;
- switch (enlink->msg) {
- case WM_LBUTTONUP:
- TEXTRANGE tr;
- tr.chrg = enlink->chrg;
- tr.lpstrText = (wchar_t*)mir_alloc(sizeof(wchar_t)*(tr.chrg.cpMax - tr.chrg.cpMin + 8));
- SendMessage(pNmhdr->hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
- Utils_OpenUrlW(tr.lpstrText);
- mir_free(tr.lpstrText);
- break;
- }
- }
+ INT_PTR OnUpdate(UINT, WPARAM, LPARAM)
+ {
+ ListView_DeleteAllItems(GetDlgItem(m_hwnd, IDC_DATALIST));
+
+ wchar_t str[4096];
+
+ // load weather information from the contact into the WEATHERINFO struct
+ WEATHERINFO winfo = LoadWeatherInfo(hContact);
+ // check if data exist. If not, display error message box
+ if (!g_plugin.getByte(hContact, "IsUpdated"))
+ SetDlgItemTextW(m_hwnd, IDC_MTEXT, TranslateT("No information available.\r\nPlease update weather condition first."));
+ else {
+ // set the display text and show the message box
+ GetDisplay(&winfo, m_proto->GetTextValue('B'), str);
+ SetDlgItemTextW(m_hwnd, IDC_MTEXT, str);
}
- break;
- case WM_CLOSE:
- DestroyWindow(hwndDlg);
- break;
+ GetDisplay(&winfo, L"%c, %t", str);
+ SetWindowTextW(m_hwnd, winfo.city);
+ SetDlgItemTextW(m_hwnd, IDC_HEADERBAR, str);
+
+ DBDataManage(hContact, WDBM_DETAILDISPLAY, (WPARAM)m_hwnd, 0);
+
+ // set icons
+ HICON hIcon = GetStatusIconBig(hContact);
+ DestroyIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_BIG, LPARAM(hIcon)));
+ DestroyIcon((HICON)SendMessage(m_hwnd, WM_SETICON, ICON_SMALL, LPARAM(hIcon)));
- case WM_DESTROY:
- DestroyIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0));
- DestroyIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, 0));
+ RedrawWindow(GetDlgItem(m_hwnd, IDC_HEADERBAR), nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
+ return 0;
+ }
- Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, "BriefInfo_");
- WindowList_Remove(hDataWindowList, hwndDlg);
- break;
+ void onClick_Update(CCtrlButton *)
+ {
+ HWND hList = GetDlgItem(m_hwnd, IDC_DATALIST);
+
+ // update current data
+ // set the text to "updating"
+ SetDlgItemText(m_hwnd, IDC_MTEXT, TranslateT("Retrieving new data, please wait..."));
+ ListView_DeleteAllItems(hList);
+
+ LV_ITEM lvi = {};
+ lvi.mask = LVIF_TEXT | LVIF_PARAM;
+ lvi.lParam = 1;
+ lvi.pszText = L"";
+ lvi.iItem = ListView_InsertItem(hList, &lvi);
+ lvi.pszText = TranslateT("Retrieving new data, please wait...");
+ ListView_SetItemText(hList, lvi.iItem, 1, lvi.pszText);
+ m_proto->UpdateSingleStation(hContact, 0);
}
- return FALSE;
-}
+ void onClick_Webpage(CCtrlButton *)
+ {
+ m_proto->LoadForecast(hContact, 0); // read complete forecast
+ }
-// show brief information dialog
-// wParam = current contact
-int BriefInfo(WPARAM wParam, LPARAM)
+ void onClick_Toggle(CCtrlButton *)
+ {
+ if (IsWindowVisible(GetDlgItem(m_hwnd, IDC_DATALIST)))
+ SetDlgItemText(m_hwnd, IDC_MTOGGLE, TranslateT("More Info"));
+ else
+ SetDlgItemText(m_hwnd, IDC_MTOGGLE, TranslateT("Brief Info"));
+ ShowWindow(GetDlgItem(m_hwnd, IDC_DATALIST), (int)!IsWindowVisible(
+ GetDlgItem(m_hwnd, IDC_DATALIST)));
+ ShowWindow(GetDlgItem(m_hwnd, IDC_MTEXT), (int)!IsWindowVisible(GetDlgItem(m_hwnd, IDC_MTEXT)));
+ }
+};
+
+INT_PTR CWeatherProto::BriefInfo(WPARAM hContact, LPARAM)
{
// make sure that the contact is actually a weather one
- if (!IsMyContact(wParam))
+ if (!IsMyContact(hContact))
return 0;
- HWND hMoreDataDlg = WindowList_Find(hDataWindowList, wParam);
+ HWND hMoreDataDlg = WindowList_Find(hDataWindowList, hContact);
if (hMoreDataDlg != nullptr) {
SetForegroundWindow(hMoreDataDlg);
SetFocus(hMoreDataDlg);
}
- else hMoreDataDlg = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_BRIEF), nullptr, DlgProcMoreData, (LPARAM)wParam);
+ else {
+ auto *pDlg = new CBriefInfoDlg(this, hContact);
+ pDlg->Create();
+ hMoreDataDlg = pDlg->GetHwnd();
+ }
ShowWindow(GetDlgItem(hMoreDataDlg, IDC_DATALIST), 0);
ShowWindow(GetDlgItem(hMoreDataDlg, IDC_MTEXT), 1);
@@ -260,6 +228,11 @@ int BriefInfo(WPARAM wParam, LPARAM)
return 1;
}
+int CWeatherProto::BriefInfoEvt(WPARAM wParam, LPARAM)
+{
+ return BriefInfo(wParam, 0);
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
// User info dialog
@@ -323,8 +296,12 @@ public:
void onClick_Detail(CCtrlButton *)
{
HWND hMoreDataDlg = WindowList_Find(hDataWindowList, m_hContact);
- if (hMoreDataDlg == nullptr)
- hMoreDataDlg = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_BRIEF), nullptr, DlgProcMoreData, m_hContact);
+ if (hMoreDataDlg == nullptr) {
+ auto *ppro = (CWeatherProto*)Proto_GetContactInstance(m_hContact);
+ auto *pDlg = new CBriefInfoDlg(ppro, m_hContact);
+ pDlg->Create();
+ hMoreDataDlg = pDlg->GetHwnd();
+ }
else {
SetForegroundWindow(hMoreDataDlg);
SetFocus(hMoreDataDlg);
@@ -334,7 +311,7 @@ public:
}
};
-int UserInfoInit(WPARAM wParam, LPARAM hContact)
+int CWeatherProto::UserInfoInit(WPARAM wParam, LPARAM hContact)
{
USERINFOPAGE uip = {};
uip.szTitle.a = MODULENAME;
diff --git a/protocols/Weather/weather.vcxproj b/protocols/Weather/weather.vcxproj
index 35e9cf3032..938d3773d0 100644
--- a/protocols/Weather/weather.vcxproj
+++ b/protocols/Weather/weather.vcxproj
@@ -40,9 +40,11 @@
<ClCompile Include="src\weather_mwin.cpp" />
<ClCompile Include="src\weather_opt.cpp" />
<ClCompile Include="src\weather_popup.cpp" />
+ <ClCompile Include="src\weather_proto.cpp" />
<ClCompile Include="src\weather_svcs.cpp" />
<ClCompile Include="src\weather_update.cpp" />
<ClCompile Include="src\weather_userinfo.cpp" />
+ <ClInclude Include="src\proto.h" />
<ClInclude Include="src\resource.h" />
<ClInclude Include="src\stdafx.h" />
<ClInclude Include="src\version.h" />
diff --git a/protocols/Weather/weather.vcxproj.filters b/protocols/Weather/weather.vcxproj.filters
index a8fbc7147e..07d844fda7 100644
--- a/protocols/Weather/weather.vcxproj.filters
+++ b/protocols/Weather/weather.vcxproj.filters
@@ -47,6 +47,9 @@
<ClCompile Include="src\weather_userinfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\weather_proto.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\resource.h">
@@ -58,6 +61,9 @@
<ClInclude Include="src\version.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\proto.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\resource.rc">