diff options
author | dartraiden <wowemuh@gmail.com> | 2023-01-14 01:30:59 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2023-01-14 01:30:59 +0300 |
commit | de40f3be3f08487937525c2ef096dad665dda61d (patch) | |
tree | eb1205f8dca7c30b561a2776f9527072bd92eaf1 /include | |
parent | dd743899a769120ba2321230afddd6e4f1271872 (diff) |
Convert sources to CR+LF
Diffstat (limited to 'include')
-rw-r--r-- | include/m_database.h | 1598 | ||||
-rw-r--r-- | include/m_db_int.h | 814 | ||||
-rw-r--r-- | include/m_gui.h | 3212 |
3 files changed, 2812 insertions, 2812 deletions
diff --git a/include/m_database.h b/include/m_database.h index fda99b4b2f..ad0e16e60b 100644 --- a/include/m_database.h +++ b/include/m_database.h @@ -1,799 +1,799 @@ -///////////////////////////////////////////////////////////////////////////////////////// -// Miranda NG: the free IM client for Microsoft* Windows* -// -// Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org) -// Copyright (c) 2000-08 Miranda ICQ/IM project, -// all portions of this codebase are copyrighted to the people -// listed in contributors.txt. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef M_DATABASE_H__ -#define M_DATABASE_H__ 1 - -///////////////////////////////////////////////////////////////////////////////////////// -// GENERALLY USEFUL STUFF - -#if !defined(M_SYSTEM_H__) - #include "m_system.h" -#endif - -#if !defined(M_UTILS_H__) - #include "m_utils.h" -#endif - -#ifdef _MSC_VER - #pragma warning(disable:4201 4204) -#endif - -///////////////////////////////////////////////////////////////////////////////////////// -// database functions - -// Switches safety settings on or off -// newSetting is TRUE initially. -// Miranda's database is normally protected against corruption by agressively -// flushing data to the disk on writes. If you're doing a lot of writes (eg in -// an import plugin) it can sometimes be desirable to switch this feature off to -// speed up the process. If you do switch it off, you must remember that crashes -// are far more likely to be catastrophic, so switch it back on at the earliest -// possible opportunity. -// Note that if you're doing a lot of setting writes, the flush is already delayed -// so you need not use this service for that purpose. - -EXTERN_C MIR_CORE_DLL(void) db_set_safety_mode(BOOL bNewMode); - -// Gets the number of contacts in the database, which does not count the user -// Returns the number of contacts. They can be retrieved using contact/findfirst and contact/findnext - -EXTERN_C MIR_CORE_DLL(int) db_get_contact_count(void); - -// Checks if a module doesn't contain any settings (for the contact given) - -MIR_CORE_DLL(bool) db_is_module_empty(MCONTACT hContact, const char *module); - -// Copies a module to another module for the contact given (0 by default) - -EXTERN_C MIR_CORE_DLL(int) db_copy_module(const char *szModule, const char *szNewModule, MCONTACT hContact = 0); - -// Removes all settings for the specified module. -// hContact is 0 for global settings or matches the concrete contact - -EXTERN_C MIR_CORE_DLL(int) db_delete_module(MCONTACT hContact, const char *szModuleName); - -///////////////////////////////////////////////////////////////////////////////////////// -// contact functions - -// Adds a new contact to the database. New contacts initially have no settings -// whatsoever, they must all be added with db/contacts/writesetting. -// Returns a handle to the newly created contact on success, or NULL otherwise. -// Triggers a db/contact/added event just before it returns. - -EXTERN_C MIR_CORE_DLL(MCONTACT) db_add_contact(void); - -// Deletes the contact hContact from the database and all events and settings associated with it. -// Returns 0 on success or nonzero if hContact was invalid -// Please don't try to delete the user contact (hContact = NULL) -// Triggers a db/contact/deleted event just *before* it removes anything -// Because all events are deleted, lots of people may end up with invalid event -// handles from this operation, which they should be prepared for. - -EXTERN_C MIR_CORE_DLL(int) db_delete_contact(MCONTACT hContact); - -// Checks if a given value is a valid contact handle, note that due -// to the nature of multiple threading, a valid contact can still become -// invalid after a call to this service. -// Returns 1 if the contact is a contact, or 0 if the contact is not valid. - -EXTERN_C MIR_CORE_DLL(int) db_is_contact(MCONTACT hContact); - -///////////////////////////////////////////////////////////////////////////////////////// -// enumerators - -// Enumerates the names of all modules that have stored or requested information from the database. -// Returns the value returned by the last call to dbmep -// This service is only really useful for debugging, in conjunction with db/contact/enumsettings -// dbmep should return 0 to continue enumeration, or nonzero to stop. -// -// Modules names will be enumerated in no particular order -// Writing to the database while module names are being enumerated will cause -// unpredictable results in the enumeration, but the write will work. -// szModuleName is only guaranteed to be valid for the duration of the callback. -// If you want to keep it for longer you must allocation your own storage. - -typedef int(*DBMODULEENUMPROC)(const char *szModuleName, void *param); - -EXTERN_C MIR_CORE_DLL(int) db_enum_modules(DBMODULEENUMPROC dbmep, void *param = nullptr); - -// Lists all resident settings - -EXTERN_C MIR_CORE_DLL(int) db_enum_residents(DBMODULEENUMPROC pFunc, void *param = nullptr); - -// Lists all the settings a specific modules has stored in the database for a specific contact. -// Returns the return value of the last call to pfnEnumProc, or -1 if there are -// no settings for that module/contact pair -// Writing to or deleting from the database while enumerating will have -// unpredictable results for the enumeration, but the write will succeed. -// Use db/modules/enum to get a complete list of module names -// szSetting is only guaranteed to be valid for the duration of the callback. If -// you want to keep it for longer you must allocation your own storage. - -typedef int (*DBSETTINGENUMPROC)(const char *szSetting, void *param); - -EXTERN_C MIR_CORE_DLL(int) db_enum_settings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, void *param = nullptr); - -///////////////////////////////////////////////////////////////////////////////////////// -// DBVARIANT: used by db/contact/getsetting and db/contact/writesetting - -#define DBVT_DELETED 0 // this setting just got deleted, no other values are valid -#define DBVT_BYTE 1 // bVal and cVal are valid -#define DBVT_WORD 2 // wVal and sVal are valid -#define DBVT_DWORD 4 // dVal and lVal are valid -#define DBVT_ASCIIZ 255 // pszVal is valid -#define DBVT_BLOB 254 // cpbVal and pbVal are valid -#define DBVT_UTF8 253 // pszVal is valid -#define DBVT_WCHAR 252 // pwszVal is valid -#define DBVT_ENCRYPTED 250 // blob of encrypted bytesw - - -#define DBVTF_VARIABLELENGTH 0x80 - -struct DBVARIANT -{ - uint8_t type; - union { - uint8_t bVal; char cVal; - uint16_t wVal; short sVal; - uint32_t dVal; long lVal; - struct { - union { - char *pszVal; - wchar_t *pwszVal; - }; - uint16_t cchVal; //only used for db/contact/getsettingstatic - }; - struct { - uint16_t cpbVal; - uint8_t *pbVal; - }; - }; -}; - -#define DBEF_TEMPORARY 0x0001 // disable notifications about temporary database events -#define DBEF_SENT 0x0002 // this event was sent by the user. If not set this event was received. -#define DBEF_READ 0x0004 // event has been read by the user. It does not need to be processed any more except for history. -#define DBEF_RTL 0x0008 // event contains the right-to-left aligned text -#define DBEF_UTF 0x0010 // event contains a text in utf-8 -#define DBEF_ENCRYPTED 0x0020 // event is encrypted (never reported outside a driver) -#define DBEF_HAS_ID 0x0040 // event has unique server id - -struct DBEVENTINFO -{ - const char *szModule; // pointer to name of the module that 'owns' this event - uint32_t timestamp; // seconds since 00:00, 01/01/1970. Gives us times until 2106 - // unless you use the standard C library which is - // signed and can only do until 2038. In GMT. - uint32_t flags; // combination of DBEF_* flags - uint16_t eventType; // module-defined event type field - int cbBlob; // size of pBlob in bytes - uint8_t *pBlob; // pointer to buffer containing module-defined event data - const char *szId; // server id - - bool __forceinline markedRead() const { - return (flags & (DBEF_SENT | DBEF_READ)) != 0; - } - - wchar_t* getString(const char *str) const { - return (flags & DBEF_UTF) ? mir_utf8decodeW(str) : mir_a2u(str); - } - - bool __forceinline operator==(const DBEVENTINFO &e) { - return (timestamp == e.timestamp && eventType == e.eventType && cbBlob == e.cbBlob && (flags & DBEF_SENT) == (e.flags & DBEF_SENT)); - } -}; - -EXTERN_C MIR_CORE_DLL(INT_PTR) db_free(DBVARIANT *dbv); - -///////////////////////////////////////////////////////////////////////////////////////// -// Database contacts - -// Gets the handle of the first contact in the database. This handle can be used -// with loads of functions. It does not need to be closed. -// You can specify szProto to find only its contacts -// Returns a handle to the first contact in the db on success, or NULL if there -// are no contacts in the db. - -EXTERN_C MIR_CORE_DLL(MCONTACT) db_find_first(const char *szProto = nullptr); - -// Gets the handle of the next contact after hContact in the database. This handle -// can be used with loads of functions. It does not need to be closed. -// You can specify szProto to find only its contacts -// Returns a handle to the contact after hContact in the db on success or NULL if -// hContact was the last contact in the db or hContact was invalid. - -EXTERN_C MIR_CORE_DLL(MCONTACT) db_find_next(MCONTACT hContact, const char *szProto = nullptr); - -class Contacts -{ - const char *m_szModule; - -public: - Contacts(const char *m = nullptr) : - m_szModule(m) - {} - - class iterator - { - MCONTACT hContact; - const char *m_szModule; - - public: - __inline iterator(const char *_m, MCONTACT _h) : - hContact(_h), - m_szModule(_m) - {} - - __inline iterator operator++() { hContact = ::db_find_next(hContact, m_szModule); return *this; } - __inline bool operator!=(const iterator &p) { return hContact != p.hContact; } - __inline operator const MCONTACT*() const { return &hContact; } - }; - - __inline iterator begin() const { return iterator(m_szModule, ::db_find_first(m_szModule)); } - __inline iterator end() const { return iterator(m_szModule, 0); } -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Database events - -// Adds a new event to a contact's event list -// Returns a handle to the newly added event, or NULL on failure -// Triggers a db/event/added event just before it returns. -// Events are sorted chronologically as they are entered, so you cannot guarantee -// that the new hEvent is the last event in the chain, however if a new event is -// added that has a timestamp less than 90 seconds *before* the event that should -// be after it, it will be added afterwards, to allow for protocols that only -// store times to the nearest minute, and slight delays in transports. -// There are a few predefined eventTypes below for easier compatibility, but -// modules are free to define their own, beginning at 2000 -// DBEVENTINFO.timestamp is in GMT, as returned by time(). There are services -// db/time/x below with useful stuff for dealing with it. - -#define EVENTTYPE_MESSAGE 0 -#define EVENTTYPE_CONTACTS 2 //v0.1.2.2+ -#define EVENTTYPE_ADDED 1000 //v0.1.1.0+: these used to be module- -#define EVENTTYPE_AUTHREQUEST 1001 //specific codes, hence the module- -#define EVENTTYPE_FILE 1002 //specific limit has been raised to 2000 - -EXTERN_C MIR_CORE_DLL(MEVENT) db_event_add(MCONTACT hContact, const DBEVENTINFO *dbei); - -// Gets the number of events in the chain belonging to a contact in the database. -// Returns the number of events in the chain owned by hContact or -1 if hContact -// is invalid. They can be retrieved using the db_event_first/last() services. - -EXTERN_C MIR_CORE_DLL(int) db_event_count(MCONTACT hContact); - -// Removes a single event from the database -// hDbEvent should have been returned by db_event_add/first/last/next/prev() -// Returns 0 on success, or nonzero if hDbEvent was invalid -// Triggers a db/event/deleted event just *before* the event is deleted - -EXTERN_C MIR_CORE_DLL(int) db_event_delete(MEVENT hDbEvent); - -// Edits an event in the database -// Returns 0 on success, or nonzero on error - -EXTERN_C MIR_CORE_DLL(int) db_event_edit(MCONTACT hContact, MEVENT hDbEvent, const DBEVENTINFO *dbei); - -// Tries to find an event by its id if present -// if an event is found, it's edited, otherwise a new event is added - -EXTERN_C MIR_CORE_DLL(MEVENT) db_event_replace(MCONTACT hContact, const DBEVENTINFO *dbei); - -// Retrieves a handle to the first event in the chain for hContact -// Returns the handle, or NULL if hContact is invalid or has no events -// Events in a chain are sorted chronologically automatically - -EXTERN_C MIR_CORE_DLL(MEVENT) db_event_first(MCONTACT hContact); - -// Retrieves a handle to the first unread event in the chain for hContact -// Returns the handle, or NULL if hContact is invalid or all its events have been read - -EXTERN_C MIR_CORE_DLL(MEVENT) db_event_firstUnread(MCONTACT hContact); - -// Retrieves all the information stored in hDbEvent -// hDbEvent should have been returned by db_event_add/first/last/next/prev() -// Returns 0 on success or nonzero if hDbEvent is invalid -// Don't forget to set dbe.cbSize, dbe.pBlob and dbe.cbBlob before calling this function -// The correct value dbe.cbBlob can be got using db_event_getBlobSize -// If successful, all the fields of dbe are filled. dbe.cbBlob is set to the -// actual number of bytes retrieved and put in dbe.pBlob -// If dbe.cbBlob is too small, dbe.pBlob is filled up to the size of dbe.cbBlob -// and then dbe.cbBlob is set to the required size of data to go in dbe.pBlob -// On return, dbe.szModule is a pointer to the database module's own internal list -// of modules. Look but don't touch. - -EXTERN_C MIR_CORE_DLL(int) db_event_get(MEVENT hDbEvent, DBEVENTINFO *dbei); - -// Retrieves the space in bytes required to store the blob in hDbEvent -// hDbEvent should have been returned by db_event_add/first/last/next/prev() -// Returns the space required in bytes, or -1 if hDbEvent is invalid - -EXTERN_C MIR_CORE_DLL(int) db_event_getBlobSize(MEVENT hDbEvent); - -// Retrieves a handle to the contact that owns hDbEvent. -// hDbEvent should have been returned by db_event_add/first/last/next/prev() -// NULL is a valid return value, meaning, as usual, the user. -// Returns INVALID_CONTACT_ID if hDbEvent is invalid, or the handle to the contact on success - -EXTERN_C MIR_CORE_DLL(MCONTACT) db_event_getContact(MEVENT hDbEvent); - -// Retrieves a handle to the last event in the chain for hContact -// Returns the handle, or NULL if hContact is invalid or has no events -// Events in a chain are sorted chronologically automatically - -EXTERN_C MIR_CORE_DLL(MEVENT) db_event_last(MCONTACT hContact); - -// Changes the flags for an event to mark it as read. -// hDbEvent should have been returned by db_event_add/first/last/next/prev() -// Returns the entire flag uint32_t for the event after the change, or -1 if hDbEvent is invalid. -// This is the one database write operation that does not trigger an event. -// Modules should not save flags states for any length of time. - -EXTERN_C MIR_CORE_DLL(int) db_event_markRead(MCONTACT hContact, MEVENT hDbEvent); - -// Retrieves a handle to the next event in a chain after hDbEvent -// Returns the handle, or NULL if hDbEvent is invalid or is the last event -// Events in a chain are sorted chronologically automatically - -EXTERN_C MIR_CORE_DLL(MEVENT) db_event_next(MCONTACT hContact, MEVENT hDbEvent); - -// Retrieves a handle to the previous event in a chain before hDbEvent -// Returns the handle, or NULL if hDbEvent is invalid or is the first event -// Events in a chain are sorted chronologically automatically - -EXTERN_C MIR_CORE_DLL(MEVENT) db_event_prev(MCONTACT hContact, MEVENT hDbEvent); - -// Retrieves a handle to the event identified by its module and unique identifier - -EXTERN_C MIR_CORE_DLL(MEVENT) db_event_getById(const char *szModule, const char *szId); - -// Updates the server ID associated with an event -// Returns 0 on success or a failure otherwise - -EXTERN_C MIR_CORE_DLL(int) db_event_updateId(MEVENT hDbEvent, const char *szId); - -///////////////////////////////////////////////////////////////////////////////////////// -// Database settings - -EXTERN_C MIR_CORE_DLL(INT_PTR) db_get(MCONTACT hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv); - -EXTERN_C MIR_CORE_DLL(int) db_get_b(MCONTACT hContact, const char *szModule, const char *szSetting, int errorValue = 0); -EXTERN_C MIR_CORE_DLL(int) db_get_w(MCONTACT hContact, const char *szModule, const char *szSetting, int errorValue = 0); -EXTERN_C MIR_CORE_DLL(uint32_t) db_get_dw(MCONTACT hContact, const char *szModule, const char *szSetting, uint32_t errorValue = 0); - -EXTERN_C MIR_CORE_DLL(char*) db_get_sa(MCONTACT hContact, const char *szModule, const char *szSetting, const char *szValue = nullptr); -EXTERN_C MIR_CORE_DLL(char*) db_get_utfa(MCONTACT hContact, const char *szModule, const char *szSetting, const char *szValue = nullptr); -EXTERN_C MIR_CORE_DLL(wchar_t*) db_get_wsa(MCONTACT hContact, const char *szModule, const char *szSetting, const wchar_t *szValue = nullptr); - -MIR_CORE_DLL(CMStringA) db_get_sm(MCONTACT hContact, const char *szModule, const char *szSetting, const char *szValue = nullptr); -MIR_CORE_DLL(CMStringW) db_get_wsm(MCONTACT hContact, const char *szModule, const char *szSetting, const wchar_t *szValue = nullptr); - -EXTERN_C MIR_CORE_DLL(int) db_get_static(MCONTACT hContact, const char *szModule, const char *szSetting, char *pDest, int cbDest); -EXTERN_C MIR_CORE_DLL(int) db_get_static_utf(MCONTACT hContact, const char *szModule, const char *szSetting, char *pDest, int cbDest); -EXTERN_C MIR_CORE_DLL(int) db_get_wstatic(MCONTACT hContact, const char *szModule, const char *szSetting, wchar_t *pDest, int cbDest); - -EXTERN_C MIR_CORE_DLL(INT_PTR) db_set(MCONTACT hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv); -EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_b(MCONTACT hContact, const char *szModule, const char *szSetting, uint8_t val); -EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_w(MCONTACT hContact, const char *szModule, const char *szSetting, uint16_t val); -EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_dw(MCONTACT hContact, const char *szModule, const char *szSetting, uint32_t val); -EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_s(MCONTACT hContact, const char *szModule, const char *szSetting, const char *val); -EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_ws(MCONTACT hContact, const char *szModule, const char *szSetting, const wchar_t *val); -EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_utf(MCONTACT hContact, const char *szModule, const char *szSetting, const char *val); -EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_blob(MCONTACT hContact, const char *szModule, const char *szSetting, const void *val, unsigned len); - -EXTERN_C MIR_CORE_DLL(INT_PTR) db_unset(MCONTACT hContact, const char *szModule, const char *szSetting); - -EXTERN_C MIR_CORE_DLL(BOOL) db_set_resident(const char *szModule, const char *szService, BOOL bEnable = true); - -EXTERN_C MIR_CORE_DLL(INT_PTR) db_get_s(MCONTACT hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv, const int nType = DBVT_ASCIIZ); -#define db_get_ws(a,b,c,d) db_get_s(a,b,c,d,DBVT_WCHAR) -#define db_get_utf(a,b,c,d) db_get_s(a,b,c,d,DBVT_UTF8) - -///////////////////////////////////////////////////////////////////////////////////////// -// Profile services - -// Gets the name of the profile currently being used by the database module. -// This is the same as the filename of the database -// Returns 0 on success or nonzero otherwise - -EXTERN_C MIR_APP_DLL(int) Profile_GetNameA(size_t cbLen, char *pszDest); -EXTERN_C MIR_APP_DLL(int) Profile_GetNameW(size_t cbLen, wchar_t *pwszDest); - -// Get the path of the base folder where Miranda will store all individual profiles -// The returned path does NOT include a trailing backslash. -// Essentially this is what has been set in mirandaboot.ini as ProfileDir. -// For more options to retrieve profile paths check MS_UTILS_REPLACEVARS -// Returns 0 on success or nonzero otherwise - -EXTERN_C MIR_APP_DLL(int) Profile_GetPathA(size_t cbLen, char *pszDest); -EXTERN_C MIR_APP_DLL(int) Profile_GetPathW(size_t cbLen, wchar_t *pwszDest); - -// Sets the default profile name programmatically -// Analog of Database/DefaultProfile in mirandaboot.ini -EXTERN_C MIR_APP_DLL(void) Profile_SetDefault(const wchar_t *pwszPath); - -// Checks if a profile is opened -EXTERN_C MIR_APP_DLL(bool) Profile_CheckOpened(const wchar_t *pwszProfileName); - -// Read an option from mirandaboot.ini -EXTERN_C MIR_APP_DLL(int) Profile_GetSettingInt(const wchar_t *pwszSetting, int iDefault = 0); -EXTERN_C MIR_APP_DLL(bool) Profile_GetSetting(const wchar_t *pwszSetting, wchar_t *pwszBuf, size_t cbLen, const wchar_t *pwszDefault = nullptr); - -template <size_t _Size> -bool Profile_GetSetting(const wchar_t *pwszSetting, wchar_t(&pwszBuf)[_Size], const wchar_t *pwszDefault = nullptr) -{ - return Profile_GetSetting(pwszSetting, pwszBuf, _Size, pwszDefault); -} - -// Checks the specified profile like dbtool did. -// Implemented in the dbchecker plugins, thus it might not exist -// wParam = (WPARAM)(wchar_t*)ptszProfileName -// lParam = (BOOL)bConversionMode - -#define MS_DB_CHECKPROFILE "DB/CheckProfile" - -///////////////////////////////////////////////////////////////////////////////////////// -// Contact services - -struct DBCONTACTWRITESETTING -{ - const char *szModule; // pointer to name of the module that wrote the setting to get - const char *szSetting; // pointer to name of the setting to get - DBVARIANT value; // variant containing the value to set -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Event services - -// Registers the specified database event type, with module, id & description. -// When someone needs to retrieve an event's text, a service named Module/GetEventText<id> -// will be called. For example, for module named 'foo' and event id 2000 a service -// foo/GetEventText2000 should be defined to process this request. That handler should -// decode a blob and return the event text in the required format, its prototype is identical -// to a call of DbEvent_GetText (see below) -// -// Returns -1 on error (e.g., event type already registred), 0 on success - -struct DBEVENTTYPEDESCR -{ - LPSTR module; // event module name - uint32_t flags; // flags, combination of the DETF_* - int eventType; // event id, unique for this module - LPSTR descr; // event type description (i.e. "File Transfer") - LPSTR textService; // service name for MS_DB_EVENT_GETTEXT (0.8+, default Module+'/GetEventText'+EvtID) - LPSTR iconService; // service name for MS_DB_EVENT_GETICON (0.8+, default Module+'/GetEventIcon'+EvtID) - HANDLE eventIcon; // icolib handle to eventicon (0.8+, default 'eventicon_'+Module+EvtID) -}; - -// constants for default event behaviour -#define DETF_HISTORY 1 // show event in history -#define DETF_MSGWINDOW 2 // show event in message window -#define DETF_NONOTIFY 4 // block event notify (e.g. Popups) - -EXTERN_C MIR_APP_DLL(int) DbEvent_RegisterType(DBEVENTTYPEDESCR*); - -///////////////////////////////////////////////////////////////////////////////////////// -// Retrieves the previously registered database event type, by module & id. -// Returns DBEVENTTYPEDESCR* or NULL, if an event isn't found. - -EXTERN_C MIR_APP_DLL(DBEVENTTYPEDESCR*) DbEvent_GetType(const char *szModule, int eventType); - -///////////////////////////////////////////////////////////////////////////////////////// -// macro to extract MCONTACT from the auth blob - -__forceinline MCONTACT DbGetAuthEventContact(DBEVENTINFO *dbei) -{ - return (MCONTACT)(*(uint32_t*)&dbei->pBlob[sizeof(uint32_t)]); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Retrieves the event's text -// * dbei should be the valid database event read via db_event_get() -// * codepage is any valid codepage, CP_ACP by default. -// -// Function returns a pointer to a string in the required format. -// This string should be freed by a call of mir_free - -EXTERN_C MIR_APP_DLL(char*) DbEvent_GetTextA(DBEVENTINFO *dbei, int codepage); -EXTERN_C MIR_APP_DLL(wchar_t*) DbEvent_GetTextW(DBEVENTINFO *dbei, int codepage); - -///////////////////////////////////////////////////////////////////////////////////////// -// Retrieves the event's icon -// * use LR_SHARED in flags for shared HICON -// dbei should be a valid database event read via db_event_get() -// -// Function returns HICON (use DestroyIcon to release resources if not LR_SHARED) -// -// A plugin can register the standard event icon in IcoLib named -// 'eventicon_'+Module+EvtID, like eventicon_ICQ2001. Otherwise, to declare an icon -// with the non-standard name, you can declare the special service, Module/GetEventIcon<id>, -// which will retrieve the custom icon handle (HICON). This service function has the -// same parameters MS_DB_EVENT_GETICON does. - -EXTERN_C MIR_APP_DLL(HICON) DbEvent_GetIcon(DBEVENTINFO *dbei, int flags); - -///////////////////////////////////////////////////////////////////////////////////////// -// Converts the event's string to wchar_t* depending on the event's format -// returns wchar_t* - the converted string -// Caller must free the result using mir_free - -EXTERN_C MIR_APP_DLL(wchar_t*) DbEvent_GetString(DBEVENTINFO *dbei, const char *str); - -///////////////////////////////////////////////////////////////////////////////////////// -// Database events - -///////////////////////////////////////////////////////////////////////////////////////// -// DB/Event/Added event -// Called when a new event has been added to the event chain for a contact -// wParam = (MCONTACT)hContact -// lParam = (LPARAM)(HANDLE)hDbEvent -// hDbEvent is a valid handle to the event. hContact is a valid handle to the -// contact to which hDbEvent refers. -// Since events are sorted chronologically, you cannot guarantee that hDbEvent is -// at any particular position in the chain. - -#define ME_DB_EVENT_ADDED "DB/Event/Added" - -///////////////////////////////////////////////////////////////////////////////////////// -// DB/Event/Edited event -// Called when the existing event was changed -// wParam = (MCONTACT)hContact -// lParam = (LPARAM)(HANDLE)hDbEvent -// hDbEvent is a valid handle to the event. hContact is a valid handle to the -// contact to which hDbEvent refers. - -#define ME_DB_EVENT_EDITED "DB/Event/Edited" - -///////////////////////////////////////////////////////////////////////////////////////// -// DB/Event/FilterAdd (NOTE: Added during 0.3.3+ development!) -// Called **before** a new event is made of a DBEVENTINFO structure, this -// hook is not SAFE unless you know what you're doing with it, the arguments -// are passed as-is (with errors, pointer problems, if any) from any arguments -// passed to db_event_add. - -// The point of this hook is to stop any unwanted database events, to stop -// an event being added, return 1, to allow the event to pass through return 0. -// wParam = (MCONTACT)hContact -// lParam = (LPARAM)&DBEVENTINFO -// -// Any changed made to the said DBEVENTINFO are also passed along to the database, -// therefore it is possible to shape the data, however DO NOT DO THIS. - -#define ME_DB_EVENT_FILTER_ADD "DB/Event/FilterAdd" - -///////////////////////////////////////////////////////////////////////////////////////// -// DB/Event/Marked/Read event -// Called when an event is marked read -// wParam = (MCONTACT)hContact -// lParam = (LPARAM)(HANDLE)hDbEvent -// hDbEvent is a valid handle to the event. -// hContact is a valid handle to the contact to which hDbEvent refers, and will remain valid. - -#define ME_DB_EVENT_MARKED_READ "DB/Event/Marked/Read" - -///////////////////////////////////////////////////////////////////////////////////////// -// DB/Event/Deleted event -// Called when an event is about to be deleted from the event chain for a contact -// wParam = (MCONTACT)hContact -// lParam = (LPARAM)(HANDLE)hDbEvent -// hDbEvent is a valid handle to the event which is about to be deleted, but it -// won't be once your hook has returned. -// hContact is a valid handle to the contact to which hDbEvent refers, and will -// remain valid. -// Returning nonzero from your hook will not stop the deletion, but it will, as -// usual, stop other hooks from being called. - -#define ME_DB_EVENT_DELETED "DB/Event/Deleted" - -///////////////////////////////////////////////////////////////////////////////////////// -// DB/Contact/Added event -// Called when a new contact has been added to the database -// wParam = (MCONTACT)hContact -// lParam = 0 -// hContact is a valid handle to the new contact. -// Contacts are initially created without any settings, so if you hook this event -// you will almost certainly also want to hook db/contact/settingchanged as well. - -#define ME_DB_CONTACT_ADDED "DB/Contact/Added" - -///////////////////////////////////////////////////////////////////////////////////////// -// DB/Contact/Deleted event -// Called when an contact is about to be deleted -// wParam = (MCONTACT)hContact -// lParam = 0 -// hContact is a valid handle to the contact which is about to be deleted, but it -// won't be once your hook has returned. -// Returning nonzero from your hook will not stop the deletion, but it will, as -// usual, stop other hooks from being called. -// Deleting a contact invalidates all events in its chain. - -#define ME_DB_CONTACT_DELETED "DB/Contact/Deleted" - -///////////////////////////////////////////////////////////////////////////////////////// -// DB/Contact/SettingChanged event -// Called when a contact has had one of its settings changed -// wParam = (MCONTACT)hContact -// lParam = (LPARAM)(DBCONTACTWRITESETTING*)&dbcws -// hContact is a valid handle to the contact that has changed. -// This event will be triggered many times rapidly when a whole bunch of values are set. -// Modules which hook this should be aware of this fact and quickly return if they -// are not interested in the value that has been changed. -// Careful not to get into infinite loops with this event. -// The structure dbcws is the same one as is passed to the original service, so -// don't change any of the members. - -#define ME_DB_CONTACT_SETTINGCHANGED "DB/Contact/SettingChanged" - -///////////////////////////////////////////////////////////////////////////////////////// -// Settings helper functions - -#ifndef DB_NOHELPERFUNCTIONS - -///////////////////////////////////////////////////////////////////////////////////////// inlined range tolerate versions */ - -__inline uint8_t DBGetContactSettingRangedByte(MCONTACT hContact, const char *szModule, const char *szSetting, uint8_t errorValue, uint8_t minValue, uint8_t maxValue) -{ - uint8_t bVal = db_get_b(hContact, szModule, szSetting, errorValue); - return (bVal < minValue || bVal > maxValue) ? errorValue : bVal; -} - -__inline uint16_t DBGetContactSettingRangedWord(MCONTACT hContact, const char *szModule, const char *szSetting, uint16_t errorValue, uint16_t minValue, uint16_t maxValue) -{ - uint16_t wVal = db_get_w(hContact, szModule, szSetting, errorValue); - return (wVal < minValue || wVal > maxValue) ? errorValue : wVal; -} - -__inline uint32_t DBGetContactSettingRangedDword(MCONTACT hContact, const char *szModule, const char *szSetting, uint32_t errorValue, uint32_t minValue, uint32_t maxValue) -{ - uint32_t dwVal = db_get_dw(hContact, szModule, szSetting, errorValue); - return (dwVal < minValue || dwVal > maxValue) ? errorValue : dwVal; -} - -#endif - -namespace DB -{ - MIR_APP_DLL(bool) IsDuplicateEvent(MCONTACT hContact, DBEVENTINFO &dbei); - - ///////////////////////////////////////////////////////////////////////////////////////// - // Helper to free event contents automatically - - struct EventInfo : public DBEVENTINFO - { - __forceinline explicit EventInfo() - { - memset(this, 0, sizeof(*this)); - } - - __forceinline ~EventInfo() - { - mir_free(pBlob); - } - }; - - ///////////////////////////////////////////////////////////////////////////////////////// - // Helper to process the auth req body - // blob is: 0(uint32_t), hContact(uint32_t), nick(UTF8), firstName(UTF8), lastName(UTF8), email(UTF8), reason(UTF8) - - #pragma warning(disable : 4251) - - class MIR_APP_EXPORT AUTH_BLOB - { - MCONTACT m_hContact; - uint32_t m_dwUin; - ptrA m_szNick, m_szFirstName, m_szLastName, m_szEmail, m_szReason; - uint32_t m_size; - - uint8_t* makeBlob(); - - public: - explicit AUTH_BLOB(MCONTACT hContact, const char *nick, const char *fname, const char *lname, const char *id, const char *reason); - explicit AUTH_BLOB(uint8_t *blob); - ~AUTH_BLOB(); - - __forceinline operator char*() { return (char*)makeBlob(); } - __forceinline operator uint8_t*() { return makeBlob(); } - - __forceinline uint32_t size() const { return m_size; } - - __forceinline MCONTACT get_contact() const { return m_hContact; } - __forceinline const char* get_nick() const { return m_szNick; } - __forceinline const char* get_firstName() const { return m_szFirstName; } - __forceinline const char* get_lastName() const { return m_szLastName; } - __forceinline const char* get_email() const { return m_szEmail; } - __forceinline const char* get_reason() const { return m_szReason; } - - __forceinline uint32_t get_uin() const { return m_dwUin; } - __forceinline void set_uin(uint32_t dwValue) { m_dwUin = dwValue; } - }; - - ///////////////////////////////////////////////////////////////////////////////////////// - // Event cursors - - class MIR_CORE_EXPORT EventCursor : public MZeroedObject - { - friend class EventIterator; - - protected: - MCONTACT hContact; - - public: - EventCursor(MCONTACT _1) : - hContact(_1) - { } - - virtual ~EventCursor(); - virtual MEVENT FetchNext() = 0; - - __forceinline MEVENT begin() { - return FetchNext(); - } - - __forceinline MEVENT end() { - return 0; - } - }; - - class MIR_CORE_EXPORT ECPTR : public MNonCopyable - { - EventCursor *m_cursor; - MEVENT m_prevFetched, m_currEvent; - - public: - ECPTR(EventCursor *_1); - ~ECPTR(); - - void DeleteEvent(); - MEVENT FetchNext(); - }; - - class EventIterator - { - EventCursor *cursor; - MEVENT hCurr = 0; - - public: - EventIterator(EventCursor *_1) : - cursor(_1) - {} - - EventIterator operator++() { - hCurr = cursor->FetchNext(); - return *this; - } - - bool operator!=(const EventIterator &p) { - return hCurr != p.hCurr; - } - - operator MEVENT() const { - return hCurr; - } - }; - - MIR_CORE_DLL(EventCursor*) Events(MCONTACT, MEVENT iStartEvent = 0); - MIR_CORE_DLL(EventCursor*) EventsRev(MCONTACT, MEVENT iStartEvent = 0); -}; - -#endif // M_DATABASE_H__ +/////////////////////////////////////////////////////////////////////////////////////////
+// Miranda NG: the free IM client for Microsoft* Windows*
+//
+// Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+// Copyright (c) 2000-08 Miranda ICQ/IM project,
+// all portions of this codebase are copyrighted to the people
+// listed in contributors.txt.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef M_DATABASE_H__
+#define M_DATABASE_H__ 1
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// GENERALLY USEFUL STUFF
+
+#if !defined(M_SYSTEM_H__)
+ #include "m_system.h"
+#endif
+
+#if !defined(M_UTILS_H__)
+ #include "m_utils.h"
+#endif
+
+#ifdef _MSC_VER
+ #pragma warning(disable:4201 4204)
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// database functions
+
+// Switches safety settings on or off
+// newSetting is TRUE initially.
+// Miranda's database is normally protected against corruption by agressively
+// flushing data to the disk on writes. If you're doing a lot of writes (eg in
+// an import plugin) it can sometimes be desirable to switch this feature off to
+// speed up the process. If you do switch it off, you must remember that crashes
+// are far more likely to be catastrophic, so switch it back on at the earliest
+// possible opportunity.
+// Note that if you're doing a lot of setting writes, the flush is already delayed
+// so you need not use this service for that purpose.
+
+EXTERN_C MIR_CORE_DLL(void) db_set_safety_mode(BOOL bNewMode);
+
+// Gets the number of contacts in the database, which does not count the user
+// Returns the number of contacts. They can be retrieved using contact/findfirst and contact/findnext
+
+EXTERN_C MIR_CORE_DLL(int) db_get_contact_count(void);
+
+// Checks if a module doesn't contain any settings (for the contact given)
+
+MIR_CORE_DLL(bool) db_is_module_empty(MCONTACT hContact, const char *module);
+
+// Copies a module to another module for the contact given (0 by default)
+
+EXTERN_C MIR_CORE_DLL(int) db_copy_module(const char *szModule, const char *szNewModule, MCONTACT hContact = 0);
+
+// Removes all settings for the specified module.
+// hContact is 0 for global settings or matches the concrete contact
+
+EXTERN_C MIR_CORE_DLL(int) db_delete_module(MCONTACT hContact, const char *szModuleName);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// contact functions
+
+// Adds a new contact to the database. New contacts initially have no settings
+// whatsoever, they must all be added with db/contacts/writesetting.
+// Returns a handle to the newly created contact on success, or NULL otherwise.
+// Triggers a db/contact/added event just before it returns.
+
+EXTERN_C MIR_CORE_DLL(MCONTACT) db_add_contact(void);
+
+// Deletes the contact hContact from the database and all events and settings associated with it.
+// Returns 0 on success or nonzero if hContact was invalid
+// Please don't try to delete the user contact (hContact = NULL)
+// Triggers a db/contact/deleted event just *before* it removes anything
+// Because all events are deleted, lots of people may end up with invalid event
+// handles from this operation, which they should be prepared for.
+
+EXTERN_C MIR_CORE_DLL(int) db_delete_contact(MCONTACT hContact);
+
+// Checks if a given value is a valid contact handle, note that due
+// to the nature of multiple threading, a valid contact can still become
+// invalid after a call to this service.
+// Returns 1 if the contact is a contact, or 0 if the contact is not valid.
+
+EXTERN_C MIR_CORE_DLL(int) db_is_contact(MCONTACT hContact);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// enumerators
+
+// Enumerates the names of all modules that have stored or requested information from the database.
+// Returns the value returned by the last call to dbmep
+// This service is only really useful for debugging, in conjunction with db/contact/enumsettings
+// dbmep should return 0 to continue enumeration, or nonzero to stop.
+//
+// Modules names will be enumerated in no particular order
+// Writing to the database while module names are being enumerated will cause
+// unpredictable results in the enumeration, but the write will work.
+// szModuleName is only guaranteed to be valid for the duration of the callback.
+// If you want to keep it for longer you must allocation your own storage.
+
+typedef int(*DBMODULEENUMPROC)(const char *szModuleName, void *param);
+
+EXTERN_C MIR_CORE_DLL(int) db_enum_modules(DBMODULEENUMPROC dbmep, void *param = nullptr);
+
+// Lists all resident settings
+
+EXTERN_C MIR_CORE_DLL(int) db_enum_residents(DBMODULEENUMPROC pFunc, void *param = nullptr);
+
+// Lists all the settings a specific modules has stored in the database for a specific contact.
+// Returns the return value of the last call to pfnEnumProc, or -1 if there are
+// no settings for that module/contact pair
+// Writing to or deleting from the database while enumerating will have
+// unpredictable results for the enumeration, but the write will succeed.
+// Use db/modules/enum to get a complete list of module names
+// szSetting is only guaranteed to be valid for the duration of the callback. If
+// you want to keep it for longer you must allocation your own storage.
+
+typedef int (*DBSETTINGENUMPROC)(const char *szSetting, void *param);
+
+EXTERN_C MIR_CORE_DLL(int) db_enum_settings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, void *param = nullptr);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DBVARIANT: used by db/contact/getsetting and db/contact/writesetting
+
+#define DBVT_DELETED 0 // this setting just got deleted, no other values are valid
+#define DBVT_BYTE 1 // bVal and cVal are valid
+#define DBVT_WORD 2 // wVal and sVal are valid
+#define DBVT_DWORD 4 // dVal and lVal are valid
+#define DBVT_ASCIIZ 255 // pszVal is valid
+#define DBVT_BLOB 254 // cpbVal and pbVal are valid
+#define DBVT_UTF8 253 // pszVal is valid
+#define DBVT_WCHAR 252 // pwszVal is valid
+#define DBVT_ENCRYPTED 250 // blob of encrypted bytesw
+
+
+#define DBVTF_VARIABLELENGTH 0x80
+
+struct DBVARIANT
+{
+ uint8_t type;
+ union {
+ uint8_t bVal; char cVal;
+ uint16_t wVal; short sVal;
+ uint32_t dVal; long lVal;
+ struct {
+ union {
+ char *pszVal;
+ wchar_t *pwszVal;
+ };
+ uint16_t cchVal; //only used for db/contact/getsettingstatic
+ };
+ struct {
+ uint16_t cpbVal;
+ uint8_t *pbVal;
+ };
+ };
+};
+
+#define DBEF_TEMPORARY 0x0001 // disable notifications about temporary database events
+#define DBEF_SENT 0x0002 // this event was sent by the user. If not set this event was received.
+#define DBEF_READ 0x0004 // event has been read by the user. It does not need to be processed any more except for history.
+#define DBEF_RTL 0x0008 // event contains the right-to-left aligned text
+#define DBEF_UTF 0x0010 // event contains a text in utf-8
+#define DBEF_ENCRYPTED 0x0020 // event is encrypted (never reported outside a driver)
+#define DBEF_HAS_ID 0x0040 // event has unique server id
+
+struct DBEVENTINFO
+{
+ const char *szModule; // pointer to name of the module that 'owns' this event
+ uint32_t timestamp; // seconds since 00:00, 01/01/1970. Gives us times until 2106
+ // unless you use the standard C library which is
+ // signed and can only do until 2038. In GMT.
+ uint32_t flags; // combination of DBEF_* flags
+ uint16_t eventType; // module-defined event type field
+ int cbBlob; // size of pBlob in bytes
+ uint8_t *pBlob; // pointer to buffer containing module-defined event data
+ const char *szId; // server id
+
+ bool __forceinline markedRead() const {
+ return (flags & (DBEF_SENT | DBEF_READ)) != 0;
+ }
+
+ wchar_t* getString(const char *str) const {
+ return (flags & DBEF_UTF) ? mir_utf8decodeW(str) : mir_a2u(str);
+ }
+
+ bool __forceinline operator==(const DBEVENTINFO &e) {
+ return (timestamp == e.timestamp && eventType == e.eventType && cbBlob == e.cbBlob && (flags & DBEF_SENT) == (e.flags & DBEF_SENT));
+ }
+};
+
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_free(DBVARIANT *dbv);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Database contacts
+
+// Gets the handle of the first contact in the database. This handle can be used
+// with loads of functions. It does not need to be closed.
+// You can specify szProto to find only its contacts
+// Returns a handle to the first contact in the db on success, or NULL if there
+// are no contacts in the db.
+
+EXTERN_C MIR_CORE_DLL(MCONTACT) db_find_first(const char *szProto = nullptr);
+
+// Gets the handle of the next contact after hContact in the database. This handle
+// can be used with loads of functions. It does not need to be closed.
+// You can specify szProto to find only its contacts
+// Returns a handle to the contact after hContact in the db on success or NULL if
+// hContact was the last contact in the db or hContact was invalid.
+
+EXTERN_C MIR_CORE_DLL(MCONTACT) db_find_next(MCONTACT hContact, const char *szProto = nullptr);
+
+class Contacts
+{
+ const char *m_szModule;
+
+public:
+ Contacts(const char *m = nullptr) :
+ m_szModule(m)
+ {}
+
+ class iterator
+ {
+ MCONTACT hContact;
+ const char *m_szModule;
+
+ public:
+ __inline iterator(const char *_m, MCONTACT _h) :
+ hContact(_h),
+ m_szModule(_m)
+ {}
+
+ __inline iterator operator++() { hContact = ::db_find_next(hContact, m_szModule); return *this; }
+ __inline bool operator!=(const iterator &p) { return hContact != p.hContact; }
+ __inline operator const MCONTACT*() const { return &hContact; }
+ };
+
+ __inline iterator begin() const { return iterator(m_szModule, ::db_find_first(m_szModule)); }
+ __inline iterator end() const { return iterator(m_szModule, 0); }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Database events
+
+// Adds a new event to a contact's event list
+// Returns a handle to the newly added event, or NULL on failure
+// Triggers a db/event/added event just before it returns.
+// Events are sorted chronologically as they are entered, so you cannot guarantee
+// that the new hEvent is the last event in the chain, however if a new event is
+// added that has a timestamp less than 90 seconds *before* the event that should
+// be after it, it will be added afterwards, to allow for protocols that only
+// store times to the nearest minute, and slight delays in transports.
+// There are a few predefined eventTypes below for easier compatibility, but
+// modules are free to define their own, beginning at 2000
+// DBEVENTINFO.timestamp is in GMT, as returned by time(). There are services
+// db/time/x below with useful stuff for dealing with it.
+
+#define EVENTTYPE_MESSAGE 0
+#define EVENTTYPE_CONTACTS 2 //v0.1.2.2+
+#define EVENTTYPE_ADDED 1000 //v0.1.1.0+: these used to be module-
+#define EVENTTYPE_AUTHREQUEST 1001 //specific codes, hence the module-
+#define EVENTTYPE_FILE 1002 //specific limit has been raised to 2000
+
+EXTERN_C MIR_CORE_DLL(MEVENT) db_event_add(MCONTACT hContact, const DBEVENTINFO *dbei);
+
+// Gets the number of events in the chain belonging to a contact in the database.
+// Returns the number of events in the chain owned by hContact or -1 if hContact
+// is invalid. They can be retrieved using the db_event_first/last() services.
+
+EXTERN_C MIR_CORE_DLL(int) db_event_count(MCONTACT hContact);
+
+// Removes a single event from the database
+// hDbEvent should have been returned by db_event_add/first/last/next/prev()
+// Returns 0 on success, or nonzero if hDbEvent was invalid
+// Triggers a db/event/deleted event just *before* the event is deleted
+
+EXTERN_C MIR_CORE_DLL(int) db_event_delete(MEVENT hDbEvent);
+
+// Edits an event in the database
+// Returns 0 on success, or nonzero on error
+
+EXTERN_C MIR_CORE_DLL(int) db_event_edit(MCONTACT hContact, MEVENT hDbEvent, const DBEVENTINFO *dbei);
+
+// Tries to find an event by its id if present
+// if an event is found, it's edited, otherwise a new event is added
+
+EXTERN_C MIR_CORE_DLL(MEVENT) db_event_replace(MCONTACT hContact, const DBEVENTINFO *dbei);
+
+// Retrieves a handle to the first event in the chain for hContact
+// Returns the handle, or NULL if hContact is invalid or has no events
+// Events in a chain are sorted chronologically automatically
+
+EXTERN_C MIR_CORE_DLL(MEVENT) db_event_first(MCONTACT hContact);
+
+// Retrieves a handle to the first unread event in the chain for hContact
+// Returns the handle, or NULL if hContact is invalid or all its events have been read
+
+EXTERN_C MIR_CORE_DLL(MEVENT) db_event_firstUnread(MCONTACT hContact);
+
+// Retrieves all the information stored in hDbEvent
+// hDbEvent should have been returned by db_event_add/first/last/next/prev()
+// Returns 0 on success or nonzero if hDbEvent is invalid
+// Don't forget to set dbe.cbSize, dbe.pBlob and dbe.cbBlob before calling this function
+// The correct value dbe.cbBlob can be got using db_event_getBlobSize
+// If successful, all the fields of dbe are filled. dbe.cbBlob is set to the
+// actual number of bytes retrieved and put in dbe.pBlob
+// If dbe.cbBlob is too small, dbe.pBlob is filled up to the size of dbe.cbBlob
+// and then dbe.cbBlob is set to the required size of data to go in dbe.pBlob
+// On return, dbe.szModule is a pointer to the database module's own internal list
+// of modules. Look but don't touch.
+
+EXTERN_C MIR_CORE_DLL(int) db_event_get(MEVENT hDbEvent, DBEVENTINFO *dbei);
+
+// Retrieves the space in bytes required to store the blob in hDbEvent
+// hDbEvent should have been returned by db_event_add/first/last/next/prev()
+// Returns the space required in bytes, or -1 if hDbEvent is invalid
+
+EXTERN_C MIR_CORE_DLL(int) db_event_getBlobSize(MEVENT hDbEvent);
+
+// Retrieves a handle to the contact that owns hDbEvent.
+// hDbEvent should have been returned by db_event_add/first/last/next/prev()
+// NULL is a valid return value, meaning, as usual, the user.
+// Returns INVALID_CONTACT_ID if hDbEvent is invalid, or the handle to the contact on success
+
+EXTERN_C MIR_CORE_DLL(MCONTACT) db_event_getContact(MEVENT hDbEvent);
+
+// Retrieves a handle to the last event in the chain for hContact
+// Returns the handle, or NULL if hContact is invalid or has no events
+// Events in a chain are sorted chronologically automatically
+
+EXTERN_C MIR_CORE_DLL(MEVENT) db_event_last(MCONTACT hContact);
+
+// Changes the flags for an event to mark it as read.
+// hDbEvent should have been returned by db_event_add/first/last/next/prev()
+// Returns the entire flag uint32_t for the event after the change, or -1 if hDbEvent is invalid.
+// This is the one database write operation that does not trigger an event.
+// Modules should not save flags states for any length of time.
+
+EXTERN_C MIR_CORE_DLL(int) db_event_markRead(MCONTACT hContact, MEVENT hDbEvent);
+
+// Retrieves a handle to the next event in a chain after hDbEvent
+// Returns the handle, or NULL if hDbEvent is invalid or is the last event
+// Events in a chain are sorted chronologically automatically
+
+EXTERN_C MIR_CORE_DLL(MEVENT) db_event_next(MCONTACT hContact, MEVENT hDbEvent);
+
+// Retrieves a handle to the previous event in a chain before hDbEvent
+// Returns the handle, or NULL if hDbEvent is invalid or is the first event
+// Events in a chain are sorted chronologically automatically
+
+EXTERN_C MIR_CORE_DLL(MEVENT) db_event_prev(MCONTACT hContact, MEVENT hDbEvent);
+
+// Retrieves a handle to the event identified by its module and unique identifier
+
+EXTERN_C MIR_CORE_DLL(MEVENT) db_event_getById(const char *szModule, const char *szId);
+
+// Updates the server ID associated with an event
+// Returns 0 on success or a failure otherwise
+
+EXTERN_C MIR_CORE_DLL(int) db_event_updateId(MEVENT hDbEvent, const char *szId);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Database settings
+
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_get(MCONTACT hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv);
+
+EXTERN_C MIR_CORE_DLL(int) db_get_b(MCONTACT hContact, const char *szModule, const char *szSetting, int errorValue = 0);
+EXTERN_C MIR_CORE_DLL(int) db_get_w(MCONTACT hContact, const char *szModule, const char *szSetting, int errorValue = 0);
+EXTERN_C MIR_CORE_DLL(uint32_t) db_get_dw(MCONTACT hContact, const char *szModule, const char *szSetting, uint32_t errorValue = 0);
+
+EXTERN_C MIR_CORE_DLL(char*) db_get_sa(MCONTACT hContact, const char *szModule, const char *szSetting, const char *szValue = nullptr);
+EXTERN_C MIR_CORE_DLL(char*) db_get_utfa(MCONTACT hContact, const char *szModule, const char *szSetting, const char *szValue = nullptr);
+EXTERN_C MIR_CORE_DLL(wchar_t*) db_get_wsa(MCONTACT hContact, const char *szModule, const char *szSetting, const wchar_t *szValue = nullptr);
+
+MIR_CORE_DLL(CMStringA) db_get_sm(MCONTACT hContact, const char *szModule, const char *szSetting, const char *szValue = nullptr);
+MIR_CORE_DLL(CMStringW) db_get_wsm(MCONTACT hContact, const char *szModule, const char *szSetting, const wchar_t *szValue = nullptr);
+
+EXTERN_C MIR_CORE_DLL(int) db_get_static(MCONTACT hContact, const char *szModule, const char *szSetting, char *pDest, int cbDest);
+EXTERN_C MIR_CORE_DLL(int) db_get_static_utf(MCONTACT hContact, const char *szModule, const char *szSetting, char *pDest, int cbDest);
+EXTERN_C MIR_CORE_DLL(int) db_get_wstatic(MCONTACT hContact, const char *szModule, const char *szSetting, wchar_t *pDest, int cbDest);
+
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_set(MCONTACT hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv);
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_b(MCONTACT hContact, const char *szModule, const char *szSetting, uint8_t val);
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_w(MCONTACT hContact, const char *szModule, const char *szSetting, uint16_t val);
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_dw(MCONTACT hContact, const char *szModule, const char *szSetting, uint32_t val);
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_s(MCONTACT hContact, const char *szModule, const char *szSetting, const char *val);
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_ws(MCONTACT hContact, const char *szModule, const char *szSetting, const wchar_t *val);
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_utf(MCONTACT hContact, const char *szModule, const char *szSetting, const char *val);
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_set_blob(MCONTACT hContact, const char *szModule, const char *szSetting, const void *val, unsigned len);
+
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_unset(MCONTACT hContact, const char *szModule, const char *szSetting);
+
+EXTERN_C MIR_CORE_DLL(BOOL) db_set_resident(const char *szModule, const char *szService, BOOL bEnable = true);
+
+EXTERN_C MIR_CORE_DLL(INT_PTR) db_get_s(MCONTACT hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv, const int nType = DBVT_ASCIIZ);
+#define db_get_ws(a,b,c,d) db_get_s(a,b,c,d,DBVT_WCHAR)
+#define db_get_utf(a,b,c,d) db_get_s(a,b,c,d,DBVT_UTF8)
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Profile services
+
+// Gets the name of the profile currently being used by the database module.
+// This is the same as the filename of the database
+// Returns 0 on success or nonzero otherwise
+
+EXTERN_C MIR_APP_DLL(int) Profile_GetNameA(size_t cbLen, char *pszDest);
+EXTERN_C MIR_APP_DLL(int) Profile_GetNameW(size_t cbLen, wchar_t *pwszDest);
+
+// Get the path of the base folder where Miranda will store all individual profiles
+// The returned path does NOT include a trailing backslash.
+// Essentially this is what has been set in mirandaboot.ini as ProfileDir.
+// For more options to retrieve profile paths check MS_UTILS_REPLACEVARS
+// Returns 0 on success or nonzero otherwise
+
+EXTERN_C MIR_APP_DLL(int) Profile_GetPathA(size_t cbLen, char *pszDest);
+EXTERN_C MIR_APP_DLL(int) Profile_GetPathW(size_t cbLen, wchar_t *pwszDest);
+
+// Sets the default profile name programmatically
+// Analog of Database/DefaultProfile in mirandaboot.ini
+EXTERN_C MIR_APP_DLL(void) Profile_SetDefault(const wchar_t *pwszPath);
+
+// Checks if a profile is opened
+EXTERN_C MIR_APP_DLL(bool) Profile_CheckOpened(const wchar_t *pwszProfileName);
+
+// Read an option from mirandaboot.ini
+EXTERN_C MIR_APP_DLL(int) Profile_GetSettingInt(const wchar_t *pwszSetting, int iDefault = 0);
+EXTERN_C MIR_APP_DLL(bool) Profile_GetSetting(const wchar_t *pwszSetting, wchar_t *pwszBuf, size_t cbLen, const wchar_t *pwszDefault = nullptr);
+
+template <size_t _Size>
+bool Profile_GetSetting(const wchar_t *pwszSetting, wchar_t(&pwszBuf)[_Size], const wchar_t *pwszDefault = nullptr)
+{
+ return Profile_GetSetting(pwszSetting, pwszBuf, _Size, pwszDefault);
+}
+
+// Checks the specified profile like dbtool did.
+// Implemented in the dbchecker plugins, thus it might not exist
+// wParam = (WPARAM)(wchar_t*)ptszProfileName
+// lParam = (BOOL)bConversionMode
+
+#define MS_DB_CHECKPROFILE "DB/CheckProfile"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Contact services
+
+struct DBCONTACTWRITESETTING
+{
+ const char *szModule; // pointer to name of the module that wrote the setting to get
+ const char *szSetting; // pointer to name of the setting to get
+ DBVARIANT value; // variant containing the value to set
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Event services
+
+// Registers the specified database event type, with module, id & description.
+// When someone needs to retrieve an event's text, a service named Module/GetEventText<id>
+// will be called. For example, for module named 'foo' and event id 2000 a service
+// foo/GetEventText2000 should be defined to process this request. That handler should
+// decode a blob and return the event text in the required format, its prototype is identical
+// to a call of DbEvent_GetText (see below)
+//
+// Returns -1 on error (e.g., event type already registred), 0 on success
+
+struct DBEVENTTYPEDESCR
+{
+ LPSTR module; // event module name
+ uint32_t flags; // flags, combination of the DETF_*
+ int eventType; // event id, unique for this module
+ LPSTR descr; // event type description (i.e. "File Transfer")
+ LPSTR textService; // service name for MS_DB_EVENT_GETTEXT (0.8+, default Module+'/GetEventText'+EvtID)
+ LPSTR iconService; // service name for MS_DB_EVENT_GETICON (0.8+, default Module+'/GetEventIcon'+EvtID)
+ HANDLE eventIcon; // icolib handle to eventicon (0.8+, default 'eventicon_'+Module+EvtID)
+};
+
+// constants for default event behaviour
+#define DETF_HISTORY 1 // show event in history
+#define DETF_MSGWINDOW 2 // show event in message window
+#define DETF_NONOTIFY 4 // block event notify (e.g. Popups)
+
+EXTERN_C MIR_APP_DLL(int) DbEvent_RegisterType(DBEVENTTYPEDESCR*);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Retrieves the previously registered database event type, by module & id.
+// Returns DBEVENTTYPEDESCR* or NULL, if an event isn't found.
+
+EXTERN_C MIR_APP_DLL(DBEVENTTYPEDESCR*) DbEvent_GetType(const char *szModule, int eventType);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// macro to extract MCONTACT from the auth blob
+
+__forceinline MCONTACT DbGetAuthEventContact(DBEVENTINFO *dbei)
+{
+ return (MCONTACT)(*(uint32_t*)&dbei->pBlob[sizeof(uint32_t)]);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Retrieves the event's text
+// * dbei should be the valid database event read via db_event_get()
+// * codepage is any valid codepage, CP_ACP by default.
+//
+// Function returns a pointer to a string in the required format.
+// This string should be freed by a call of mir_free
+
+EXTERN_C MIR_APP_DLL(char*) DbEvent_GetTextA(DBEVENTINFO *dbei, int codepage);
+EXTERN_C MIR_APP_DLL(wchar_t*) DbEvent_GetTextW(DBEVENTINFO *dbei, int codepage);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Retrieves the event's icon
+// * use LR_SHARED in flags for shared HICON
+// dbei should be a valid database event read via db_event_get()
+//
+// Function returns HICON (use DestroyIcon to release resources if not LR_SHARED)
+//
+// A plugin can register the standard event icon in IcoLib named
+// 'eventicon_'+Module+EvtID, like eventicon_ICQ2001. Otherwise, to declare an icon
+// with the non-standard name, you can declare the special service, Module/GetEventIcon<id>,
+// which will retrieve the custom icon handle (HICON). This service function has the
+// same parameters MS_DB_EVENT_GETICON does.
+
+EXTERN_C MIR_APP_DLL(HICON) DbEvent_GetIcon(DBEVENTINFO *dbei, int flags);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Converts the event's string to wchar_t* depending on the event's format
+// returns wchar_t* - the converted string
+// Caller must free the result using mir_free
+
+EXTERN_C MIR_APP_DLL(wchar_t*) DbEvent_GetString(DBEVENTINFO *dbei, const char *str);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Database events
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DB/Event/Added event
+// Called when a new event has been added to the event chain for a contact
+// wParam = (MCONTACT)hContact
+// lParam = (LPARAM)(HANDLE)hDbEvent
+// hDbEvent is a valid handle to the event. hContact is a valid handle to the
+// contact to which hDbEvent refers.
+// Since events are sorted chronologically, you cannot guarantee that hDbEvent is
+// at any particular position in the chain.
+
+#define ME_DB_EVENT_ADDED "DB/Event/Added"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DB/Event/Edited event
+// Called when the existing event was changed
+// wParam = (MCONTACT)hContact
+// lParam = (LPARAM)(HANDLE)hDbEvent
+// hDbEvent is a valid handle to the event. hContact is a valid handle to the
+// contact to which hDbEvent refers.
+
+#define ME_DB_EVENT_EDITED "DB/Event/Edited"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DB/Event/FilterAdd (NOTE: Added during 0.3.3+ development!)
+// Called **before** a new event is made of a DBEVENTINFO structure, this
+// hook is not SAFE unless you know what you're doing with it, the arguments
+// are passed as-is (with errors, pointer problems, if any) from any arguments
+// passed to db_event_add.
+
+// The point of this hook is to stop any unwanted database events, to stop
+// an event being added, return 1, to allow the event to pass through return 0.
+// wParam = (MCONTACT)hContact
+// lParam = (LPARAM)&DBEVENTINFO
+//
+// Any changed made to the said DBEVENTINFO are also passed along to the database,
+// therefore it is possible to shape the data, however DO NOT DO THIS.
+
+#define ME_DB_EVENT_FILTER_ADD "DB/Event/FilterAdd"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DB/Event/Marked/Read event
+// Called when an event is marked read
+// wParam = (MCONTACT)hContact
+// lParam = (LPARAM)(HANDLE)hDbEvent
+// hDbEvent is a valid handle to the event.
+// hContact is a valid handle to the contact to which hDbEvent refers, and will remain valid.
+
+#define ME_DB_EVENT_MARKED_READ "DB/Event/Marked/Read"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DB/Event/Deleted event
+// Called when an event is about to be deleted from the event chain for a contact
+// wParam = (MCONTACT)hContact
+// lParam = (LPARAM)(HANDLE)hDbEvent
+// hDbEvent is a valid handle to the event which is about to be deleted, but it
+// won't be once your hook has returned.
+// hContact is a valid handle to the contact to which hDbEvent refers, and will
+// remain valid.
+// Returning nonzero from your hook will not stop the deletion, but it will, as
+// usual, stop other hooks from being called.
+
+#define ME_DB_EVENT_DELETED "DB/Event/Deleted"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DB/Contact/Added event
+// Called when a new contact has been added to the database
+// wParam = (MCONTACT)hContact
+// lParam = 0
+// hContact is a valid handle to the new contact.
+// Contacts are initially created without any settings, so if you hook this event
+// you will almost certainly also want to hook db/contact/settingchanged as well.
+
+#define ME_DB_CONTACT_ADDED "DB/Contact/Added"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DB/Contact/Deleted event
+// Called when an contact is about to be deleted
+// wParam = (MCONTACT)hContact
+// lParam = 0
+// hContact is a valid handle to the contact which is about to be deleted, but it
+// won't be once your hook has returned.
+// Returning nonzero from your hook will not stop the deletion, but it will, as
+// usual, stop other hooks from being called.
+// Deleting a contact invalidates all events in its chain.
+
+#define ME_DB_CONTACT_DELETED "DB/Contact/Deleted"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// DB/Contact/SettingChanged event
+// Called when a contact has had one of its settings changed
+// wParam = (MCONTACT)hContact
+// lParam = (LPARAM)(DBCONTACTWRITESETTING*)&dbcws
+// hContact is a valid handle to the contact that has changed.
+// This event will be triggered many times rapidly when a whole bunch of values are set.
+// Modules which hook this should be aware of this fact and quickly return if they
+// are not interested in the value that has been changed.
+// Careful not to get into infinite loops with this event.
+// The structure dbcws is the same one as is passed to the original service, so
+// don't change any of the members.
+
+#define ME_DB_CONTACT_SETTINGCHANGED "DB/Contact/SettingChanged"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Settings helper functions
+
+#ifndef DB_NOHELPERFUNCTIONS
+
+///////////////////////////////////////////////////////////////////////////////////////// inlined range tolerate versions */
+
+__inline uint8_t DBGetContactSettingRangedByte(MCONTACT hContact, const char *szModule, const char *szSetting, uint8_t errorValue, uint8_t minValue, uint8_t maxValue)
+{
+ uint8_t bVal = db_get_b(hContact, szModule, szSetting, errorValue);
+ return (bVal < minValue || bVal > maxValue) ? errorValue : bVal;
+}
+
+__inline uint16_t DBGetContactSettingRangedWord(MCONTACT hContact, const char *szModule, const char *szSetting, uint16_t errorValue, uint16_t minValue, uint16_t maxValue)
+{
+ uint16_t wVal = db_get_w(hContact, szModule, szSetting, errorValue);
+ return (wVal < minValue || wVal > maxValue) ? errorValue : wVal;
+}
+
+__inline uint32_t DBGetContactSettingRangedDword(MCONTACT hContact, const char *szModule, const char *szSetting, uint32_t errorValue, uint32_t minValue, uint32_t maxValue)
+{
+ uint32_t dwVal = db_get_dw(hContact, szModule, szSetting, errorValue);
+ return (dwVal < minValue || dwVal > maxValue) ? errorValue : dwVal;
+}
+
+#endif
+
+namespace DB
+{
+ MIR_APP_DLL(bool) IsDuplicateEvent(MCONTACT hContact, DBEVENTINFO &dbei);
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Helper to free event contents automatically
+
+ struct EventInfo : public DBEVENTINFO
+ {
+ __forceinline explicit EventInfo()
+ {
+ memset(this, 0, sizeof(*this));
+ }
+
+ __forceinline ~EventInfo()
+ {
+ mir_free(pBlob);
+ }
+ };
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Helper to process the auth req body
+ // blob is: 0(uint32_t), hContact(uint32_t), nick(UTF8), firstName(UTF8), lastName(UTF8), email(UTF8), reason(UTF8)
+
+ #pragma warning(disable : 4251)
+
+ class MIR_APP_EXPORT AUTH_BLOB
+ {
+ MCONTACT m_hContact;
+ uint32_t m_dwUin;
+ ptrA m_szNick, m_szFirstName, m_szLastName, m_szEmail, m_szReason;
+ uint32_t m_size;
+
+ uint8_t* makeBlob();
+
+ public:
+ explicit AUTH_BLOB(MCONTACT hContact, const char *nick, const char *fname, const char *lname, const char *id, const char *reason);
+ explicit AUTH_BLOB(uint8_t *blob);
+ ~AUTH_BLOB();
+
+ __forceinline operator char*() { return (char*)makeBlob(); }
+ __forceinline operator uint8_t*() { return makeBlob(); }
+
+ __forceinline uint32_t size() const { return m_size; }
+
+ __forceinline MCONTACT get_contact() const { return m_hContact; }
+ __forceinline const char* get_nick() const { return m_szNick; }
+ __forceinline const char* get_firstName() const { return m_szFirstName; }
+ __forceinline const char* get_lastName() const { return m_szLastName; }
+ __forceinline const char* get_email() const { return m_szEmail; }
+ __forceinline const char* get_reason() const { return m_szReason; }
+
+ __forceinline uint32_t get_uin() const { return m_dwUin; }
+ __forceinline void set_uin(uint32_t dwValue) { m_dwUin = dwValue; }
+ };
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Event cursors
+
+ class MIR_CORE_EXPORT EventCursor : public MZeroedObject
+ {
+ friend class EventIterator;
+
+ protected:
+ MCONTACT hContact;
+
+ public:
+ EventCursor(MCONTACT _1) :
+ hContact(_1)
+ { }
+
+ virtual ~EventCursor();
+ virtual MEVENT FetchNext() = 0;
+
+ __forceinline MEVENT begin() {
+ return FetchNext();
+ }
+
+ __forceinline MEVENT end() {
+ return 0;
+ }
+ };
+
+ class MIR_CORE_EXPORT ECPTR : public MNonCopyable
+ {
+ EventCursor *m_cursor;
+ MEVENT m_prevFetched, m_currEvent;
+
+ public:
+ ECPTR(EventCursor *_1);
+ ~ECPTR();
+
+ void DeleteEvent();
+ MEVENT FetchNext();
+ };
+
+ class EventIterator
+ {
+ EventCursor *cursor;
+ MEVENT hCurr = 0;
+
+ public:
+ EventIterator(EventCursor *_1) :
+ cursor(_1)
+ {}
+
+ EventIterator operator++() {
+ hCurr = cursor->FetchNext();
+ return *this;
+ }
+
+ bool operator!=(const EventIterator &p) {
+ return hCurr != p.hCurr;
+ }
+
+ operator MEVENT() const {
+ return hCurr;
+ }
+ };
+
+ MIR_CORE_DLL(EventCursor*) Events(MCONTACT, MEVENT iStartEvent = 0);
+ MIR_CORE_DLL(EventCursor*) EventsRev(MCONTACT, MEVENT iStartEvent = 0);
+};
+
+#endif // M_DATABASE_H__
diff --git a/include/m_db_int.h b/include/m_db_int.h index 2516208764..661ad565f4 100644 --- a/include/m_db_int.h +++ b/include/m_db_int.h @@ -1,407 +1,407 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org) -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -aint with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_DB_INT_H__ -#define M_DB_INT_H__ 1 - -#ifndef M_CORE_H__ - #include <m_core.h> -#endif - -/////////////////////////////////////////////////////////////////////////////// -// basic database checker interface - -#define STATUS_MESSAGE 0 -#define STATUS_WARNING 1 -#define STATUS_ERROR 2 -#define STATUS_FATAL 3 -#define STATUS_SUCCESS 4 - -struct DATABASELINK; - -struct DBCHeckCallback -{ - uint32_t spaceProcessed, spaceUsed; - - void (*pfnAddLogMessage)(int type, const wchar_t *ptszFormat, ...); -}; - -interface MIDatabaseChecker -{ - STDMETHOD_(BOOL, Start)(DBCHeckCallback *callback) PURE; - STDMETHOD_(BOOL, CheckDb)(int phase) PURE; - STDMETHOD_(void, Destroy)() PURE; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// basic database interface - -struct DBCachedGlobalValue -{ - char *name; - DBVARIANT value; -}; - -struct DBCachedContactValue -{ - char *name; - DBVARIANT value; - DBCachedContactValue *next; -}; - -struct DBCachedContactBase -{ - MCONTACT contactID; - char *szProto; - DBCachedContactValue *first, *last; - - // metacontacts - int nSubs; // == -1 -> not a metacontact - MCONTACT *pSubs; - MCONTACT parentID; // == 0 -> not a subcontact - int nDefault; // default sub number - - __forceinline bool IsMeta() const { return nSubs != -1; } - __forceinline bool IsSub() const { return parentID != 0; } -}; - -#ifndef OWN_CACHED_CONTACT -struct DBCachedContact : public DBCachedContactBase {}; -#else -struct DBCachedContact; -#endif - -interface MIDatabaseCache : public MZeroedObject -{ - STDMETHOD_(DBCachedContact*, AddContactToCache)(MCONTACT contactID) PURE; - STDMETHOD_(DBCachedContact*, GetCachedContact)(MCONTACT contactID) PURE; - STDMETHOD_(DBCachedContact*, GetFirstContact)(void) PURE; - STDMETHOD_(DBCachedContact*, GetNextContact)(MCONTACT contactID) PURE; - STDMETHOD_(void, FreeCachedContact)(MCONTACT contactID) PURE; - - STDMETHOD_(char*, InsertCachedSetting)(const char *szName, size_t) PURE; - STDMETHOD_(char*, GetCachedSetting)(const char *szModuleName, const char *szSettingName, size_t, size_t) PURE; - STDMETHOD_(void, SetCachedVariant)(DBVARIANT *s, DBVARIANT *d) PURE; - STDMETHOD_(DBVARIANT*, GetCachedValuePtr)(MCONTACT contactID, char *szSetting, int bAllocate) PURE; -}; - -interface MIR_APP_EXPORT MIDatabase -{ - STDMETHOD_(BOOL, IsRelational)(void) PURE; - STDMETHOD_(void, SetCacheSafetyMode)(BOOL) PURE; - - STDMETHOD_(int, GetContactCount)(void) PURE; - STDMETHOD_(MCONTACT, FindFirstContact)(const char *szProto = nullptr) PURE; - STDMETHOD_(MCONTACT, FindNextContact)(MCONTACT contactID, const char *szProto = nullptr) PURE; - - STDMETHOD_(int, DeleteContact)(MCONTACT contactID) PURE; - STDMETHOD_(MCONTACT, AddContact)(void) PURE; - STDMETHOD_(BOOL, IsDbContact)(MCONTACT contactID) PURE; - STDMETHOD_(int, GetContactSize)(void) PURE; - - STDMETHOD_(int, GetEventCount)(MCONTACT contactID) PURE; - STDMETHOD_(MEVENT, AddEvent)(MCONTACT contactID, const DBEVENTINFO *dbe) PURE; - STDMETHOD_(BOOL, DeleteEvent)(MEVENT hDbEvent) PURE; - STDMETHOD_(BOOL, EditEvent)(MCONTACT contactID, MEVENT hDbEvent, const DBEVENTINFO *dbe) PURE; - STDMETHOD_(int, GetBlobSize)(MEVENT hDbEvent) PURE; - STDMETHOD_(BOOL, GetEvent)(MEVENT hDbEvent, DBEVENTINFO *dbe) PURE; - STDMETHOD_(BOOL, MarkEventRead)(MCONTACT contactID, MEVENT hDbEvent) PURE; - STDMETHOD_(MCONTACT, GetEventContact)(MEVENT hDbEvent) PURE; - STDMETHOD_(MEVENT, FindFirstEvent)(MCONTACT contactID) PURE; - STDMETHOD_(MEVENT, FindFirstUnreadEvent)(MCONTACT contactID) PURE; - STDMETHOD_(MEVENT, FindLastEvent)(MCONTACT contactID) PURE; - STDMETHOD_(MEVENT, FindNextEvent)(MCONTACT contactID, MEVENT hDbEvent) PURE; - STDMETHOD_(MEVENT, FindPrevEvent)(MCONTACT contactID, MEVENT hDbEvent) PURE; - - STDMETHOD_(BOOL, DeleteModule)(MCONTACT contactID, LPCSTR szModule) PURE; - STDMETHOD_(BOOL, EnumModuleNames)(DBMODULEENUMPROC pFunc, void *pParam) PURE; - - STDMETHOD_(BOOL, GetContactSetting)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) PURE; - STDMETHOD_(BOOL, GetContactSettingStr)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) PURE; - STDMETHOD_(BOOL, GetContactSettingStatic)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) PURE; - STDMETHOD_(BOOL, FreeVariant)(DBVARIANT *dbv) PURE; - STDMETHOD_(BOOL, WriteContactSetting)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) PURE; - STDMETHOD_(BOOL, DeleteContactSetting)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting) PURE; - STDMETHOD_(BOOL, EnumContactSettings)(MCONTACT contactID, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, void *param) PURE; - STDMETHOD_(BOOL, SetSettingResident)(BOOL bIsResident, const char *pszSettingName) PURE; - STDMETHOD_(BOOL, EnumResidentSettings)(DBMODULEENUMPROC pFunc, void *pParam) PURE; - STDMETHOD_(BOOL, IsSettingEncrypted)(LPCSTR szModule, LPCSTR szSetting) PURE; - - STDMETHOD_(BOOL, MetaDetouchSub)(DBCachedContact*, int nSub) PURE; - STDMETHOD_(BOOL, MetaSetDefault)(DBCachedContact*) PURE; - STDMETHOD_(BOOL, MetaMergeHistory)(DBCachedContact *ccMeta, DBCachedContact *ccSub) PURE; - STDMETHOD_(BOOL, MetaSplitHistory)(DBCachedContact *ccMeta, DBCachedContact *ccSub) PURE; - STDMETHOD_(BOOL, MetaRemoveSubHistory)(DBCachedContact *ccSub) PURE; - - STDMETHOD_(BOOL, Compact)(void) PURE; - STDMETHOD_(BOOL, Backup)(LPCWSTR) PURE; - STDMETHOD_(BOOL, Flush)(void) PURE; - - STDMETHOD_(MIDatabaseChecker*, GetChecker)(void) PURE; - STDMETHOD_(DATABASELINK*, GetDriver)(void) PURE; - - STDMETHOD_(MEVENT, GetEventById)(LPCSTR szModule, LPCSTR szId) PURE; - STDMETHOD_(int, UpdateEventId)(MEVENT hDbEvent, const char *szId) PURE; - - STDMETHOD_(DB::EventCursor*, EventCursor)(MCONTACT hContact, MEVENT hDbEvent) PURE; - STDMETHOD_(DB::EventCursor*, EventCursorRev)(MCONTACT hContact, MEVENT hDbEvent) PURE; -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -#pragma warning(push) -#pragma warning(disable:4275) - -struct MICryptoEngine; -struct CRYPTO_PROVIDER; - -class MIR_APP_EXPORT MDatabaseCommon : public MIDatabase, public MNonCopyable -{ - HANDLE m_hLock = nullptr; - -protected: - bool m_bEncrypted = false, m_bUsesPassword = false; - int m_codePage; - - mir_cs m_csDbAccess; - LIST<char> m_lResidentSettings; - MIDatabaseCache* m_cache; - MICryptoEngine *m_crypto = nullptr; - -protected: - int CheckProto(DBCachedContact *cc, const char *proto); - void FillContactSettings(); - bool LockName(const wchar_t *pwszProfileName); - void UnlockName(); - - STDMETHOD_(BOOL, GetContactSettingWorker)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic); - STDMETHOD_(BOOL, WriteContactSettingWorker)(MCONTACT contactID, DBCONTACTWRITESETTING &dbcws) PURE; - -public: - MDatabaseCommon(); - virtual ~MDatabaseCommon(); - - __forceinline bool isEncrypted() const { return m_bEncrypted; } - __forceinline MICryptoEngine* getCrypt() const { return m_crypto; } - __forceinline MIDatabaseCache* getCache() const { return m_cache; } - __forceinline bool usesPassword() const { return m_bUsesPassword; } - - void SetPassword(const wchar_t *ptszPassword); - - STDMETHODIMP_(BOOL) DeleteModule(MCONTACT contactID, LPCSTR szModule) override; - - STDMETHODIMP_(MCONTACT) FindFirstContact(const char *szProto = nullptr) override; - STDMETHODIMP_(MCONTACT) FindNextContact(MCONTACT contactID, const char *szProto = nullptr) override; - - STDMETHODIMP_(BOOL) MetaDetouchSub(DBCachedContact *cc, int nSub) override; - STDMETHODIMP_(BOOL) MetaSetDefault(DBCachedContact *cc) override; - STDMETHODIMP_(BOOL) MetaRemoveSubHistory(DBCachedContact *ccSub) override; - - STDMETHODIMP_(BOOL) IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting) override; - STDMETHODIMP_(BOOL) GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override; - STDMETHODIMP_(BOOL) GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override; - STDMETHODIMP_(BOOL) GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override; - STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv); - STDMETHODIMP_(BOOL) WriteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override; - - STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam) override; - STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName) override; - - STDMETHODIMP_(BOOL) Compact(void) override; - STDMETHODIMP_(BOOL) Backup(LPCWSTR) override; - STDMETHODIMP_(BOOL) Flush(void) override; - - STDMETHODIMP_(MIDatabaseChecker*) GetChecker(void) override; - - STDMETHODIMP_(DB::EventCursor*) EventCursor(MCONTACT hContact, MEVENT hDbEvent) override; - STDMETHODIMP_(DB::EventCursor*) EventCursorRev(MCONTACT hContact, MEVENT hDbEvent) override; - - //////////////////////////////////////////////////////////////////////////////////////// - // encryption support - - int InitCrypt(); - - CRYPTO_PROVIDER* SelectProvider(); - STDMETHOD_(CRYPTO_PROVIDER*, ReadProvider)() PURE; - STDMETHOD_(BOOL, StoreProvider)(CRYPTO_PROVIDER*) PURE; - - STDMETHOD_(BOOL, ReadCryptoKey)(MBinBuffer&) PURE; - STDMETHOD_(BOOL, StoreCryptoKey)() PURE; - - STDMETHOD_(BOOL, EnableEncryption)(BOOL) PURE; - STDMETHOD_(BOOL, ReadEncryption)() PURE; -}; - -#pragma warning(pop) - -///////////////////////////////////////////////////////////////////////////////////////// -// Read-only database, that cannot add/modify information in a profile - -class MIR_APP_EXPORT MDatabaseReadonly : public MDatabaseCommon -{ -public: - MDatabaseReadonly(); - - STDMETHODIMP_(BOOL) IsRelational(void) override; - - STDMETHODIMP_(void) SetCacheSafetyMode(BOOL) override; - - STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC, void*) override; - - STDMETHODIMP_(CRYPTO_PROVIDER*) ReadProvider() override; - STDMETHODIMP_(BOOL) StoreProvider(CRYPTO_PROVIDER*) override; - STDMETHODIMP_(BOOL) ReadCryptoKey(MBinBuffer&) override; - STDMETHODIMP_(BOOL) StoreCryptoKey() override; - STDMETHODIMP_(BOOL) EnableEncryption(BOOL) override; - STDMETHODIMP_(BOOL) ReadEncryption() override; - - //////////////////////////////////////////////////////////////////////////////////////// - STDMETHODIMP_(MCONTACT) AddContact(void) override; - STDMETHODIMP_(int) DeleteContact(MCONTACT) override; - STDMETHODIMP_(BOOL) IsDbContact(MCONTACT contactID) override; - STDMETHODIMP_(int) GetContactSize(void) override; - - //////////////////////////////////////////////////////////////////////////////////////// - STDMETHODIMP_(MEVENT) AddEvent(MCONTACT, const DBEVENTINFO*) override; - STDMETHODIMP_(BOOL) DeleteEvent(MEVENT) override; - STDMETHODIMP_(BOOL) EditEvent(MCONTACT contactID, MEVENT hDbEvent, const DBEVENTINFO *dbe) override; - STDMETHODIMP_(int) GetBlobSize(MEVENT) override; - STDMETHODIMP_(BOOL) MarkEventRead(MCONTACT, MEVENT) override; - STDMETHODIMP_(MCONTACT) GetEventContact(MEVENT) override; - STDMETHODIMP_(MEVENT) FindFirstUnreadEvent(MCONTACT) override; - - //////////////////////////////////////////////////////////////////////////////////////// - STDMETHODIMP_(BOOL) GetContactSettingWorker(MCONTACT, LPCSTR, LPCSTR, DBVARIANT*, int) override; - STDMETHODIMP_(BOOL) WriteContactSettingWorker(MCONTACT, DBCONTACTWRITESETTING&) override; - STDMETHODIMP_(BOOL) DeleteContactSetting(MCONTACT, LPCSTR, LPCSTR) override; - STDMETHODIMP_(BOOL) EnumContactSettings(MCONTACT, DBSETTINGENUMPROC, const char*, void*) override; - - //////////////////////////////////////////////////////////////////////////////////////// - STDMETHODIMP_(BOOL) MetaMergeHistory(DBCachedContact*, DBCachedContact*) override; - STDMETHODIMP_(BOOL) MetaSplitHistory(DBCachedContact*, DBCachedContact*) override; - STDMETHODIMP_(BOOL) MetaRemoveSubHistory(DBCachedContact*) override; - - //////////////////////////////////////////////////////////////////////////////////////// - STDMETHODIMP_(MEVENT) GetEventById(LPCSTR szModule, LPCSTR szId) override; - STDMETHODIMP_(int) UpdateEventId(MEVENT hDbEvent, const char *szId) override; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Each database plugin should register itself using this structure - -// Codes for DATABASELINK functions - -// grokHeader() error codes -#define EGROKPRF_NOERROR 0 -#define EGROKPRF_CANTREAD 1 // can't open the profile for reading -#define EGROKPRF_UNKHEADER 2 // header not supported, not a supported profile -#define EGROKPRF_VERNEWER 3 // header correct, version in profile newer than reader/writer -#define EGROKPRF_DAMAGED 4 // header/version fine, other internal data missing, damaged. -#define EGROKPRF_OBSOLETE 5 // obsolete database version detected, requiring conversion - -// makeDatabase() error codes -#define EMKPRF_CREATEFAILED 1 // for some reason CreateFile() didnt like something - -#define MDB_CAPS_CREATE 0x0001 // new database can be created -#define MDB_CAPS_COMPACT 0x0002 // database can be compacted -#define MDB_CAPS_CHECK 0x0004 // database can be checked - - -struct DATABASELINK -{ - int capabilities; - char* szShortName; // uniqie short database name - wchar_t* szFullName; // in English, auto-translated by the core - - /* - profile: pointer to a string which contains full path + name - Affect: The database plugin should create the profile, the filepath will not exist at - the time of this call, profile will be C:\..\<name>.dat - Returns: 0 on success, non zero on failure - error contains extended error information, see EMKPRF_* - */ - int (*makeDatabase)(const wchar_t *profile); - - /* - profile: [in] a null terminated string to file path of selected profile - error: [in/out] pointer to an int to set with error if any - Affect: Ask the database plugin if it supports the given profile, if it does it will - return 0, if it doesnt return 1, with the error set in error -- EGROKPRF_* can be valid error - condition, most common error would be [EGROKPRF_UNKHEADER] - Note: Just because 1 is returned, doesnt mean the profile is not supported, the profile might be damaged - etc. - Returns: 0 on success, non zero on failure - */ - int (*grokHeader)(const wchar_t *profile); - - /* - Affect: Tell the database to create all services/hooks that a 3.xx legacy database might support into link, - which is a PLUGINLINK structure - Returns: 0 on success, nonzero on failure - */ - MDatabaseCommon* (*Load)(const wchar_t *profile, BOOL bReadOnly); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// global database event handles - -EXTERN_C MIR_APP_EXPORT HANDLE - g_hevContactDeleted, // ME_DB_CONTACT_DELETED - g_hevContactAdded, // ME_DB_CONTACT_ADDED - g_hevSettingChanged, // ME_DB_CONTACT_SETTINGCHANGED - g_hevMarkedRead, // ME_DB_EVENT_MARKED_READ - g_hevEventAdded, // ME_DB_EVENT_ADDED - g_hevEventEdited, // ME_DB_EVENT_EDITED - g_hevEventDeleted, // ME_DB_EVENT_DELETED - g_hevEventFiltered; // ME_DB_EVENT_FILTER_ADD - -///////////////////////////////////////////////////////////////////////////////////////// -// cache access function - -EXTERN_C MIR_CORE_DLL(DBCachedContact*) db_get_contact(MCONTACT); - -///////////////////////////////////////////////////////////////////////////////////////// -// database list's functions - -EXTERN_C MIR_CORE_DLL(MDatabaseCommon*) db_get_current(void); -EXTERN_C MIR_CORE_DLL(void) db_setCurrent(MDatabaseCommon *_db); - -// registers a database plugin -EXTERN_C MIR_APP_DLL(void) RegisterDatabasePlugin(DATABASELINK *pDescr); - -// looks for a database plugin by its short name -// returns DATABASELINK* of the required plugin or nullptr on error -EXTERN_C MIR_APP_DLL(DATABASELINK*) GetDatabasePlugin(const char *pszDriverName); - -// looks for a database plugin suitable to open this file -// returns DATABASELINK* of the required plugin or nullptr on error -EXTERN_C MIR_APP_DLL(DATABASELINK*) FindDatabasePlugin(const wchar_t *ptszFileName); - -///////////////////////////////////////////////////////////////////////////////////////// -// database upgrader - -namespace DB -{ - MIR_APP_DLL(MDatabaseCommon *) Upgrade(const wchar_t *profile); -} - -#endif // M_DB_INT_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+aint with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_DB_INT_H__
+#define M_DB_INT_H__ 1
+
+#ifndef M_CORE_H__
+ #include <m_core.h>
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// basic database checker interface
+
+#define STATUS_MESSAGE 0
+#define STATUS_WARNING 1
+#define STATUS_ERROR 2
+#define STATUS_FATAL 3
+#define STATUS_SUCCESS 4
+
+struct DATABASELINK;
+
+struct DBCHeckCallback
+{
+ uint32_t spaceProcessed, spaceUsed;
+
+ void (*pfnAddLogMessage)(int type, const wchar_t *ptszFormat, ...);
+};
+
+interface MIDatabaseChecker
+{
+ STDMETHOD_(BOOL, Start)(DBCHeckCallback *callback) PURE;
+ STDMETHOD_(BOOL, CheckDb)(int phase) PURE;
+ STDMETHOD_(void, Destroy)() PURE;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// basic database interface
+
+struct DBCachedGlobalValue
+{
+ char *name;
+ DBVARIANT value;
+};
+
+struct DBCachedContactValue
+{
+ char *name;
+ DBVARIANT value;
+ DBCachedContactValue *next;
+};
+
+struct DBCachedContactBase
+{
+ MCONTACT contactID;
+ char *szProto;
+ DBCachedContactValue *first, *last;
+
+ // metacontacts
+ int nSubs; // == -1 -> not a metacontact
+ MCONTACT *pSubs;
+ MCONTACT parentID; // == 0 -> not a subcontact
+ int nDefault; // default sub number
+
+ __forceinline bool IsMeta() const { return nSubs != -1; }
+ __forceinline bool IsSub() const { return parentID != 0; }
+};
+
+#ifndef OWN_CACHED_CONTACT
+struct DBCachedContact : public DBCachedContactBase {};
+#else
+struct DBCachedContact;
+#endif
+
+interface MIDatabaseCache : public MZeroedObject
+{
+ STDMETHOD_(DBCachedContact*, AddContactToCache)(MCONTACT contactID) PURE;
+ STDMETHOD_(DBCachedContact*, GetCachedContact)(MCONTACT contactID) PURE;
+ STDMETHOD_(DBCachedContact*, GetFirstContact)(void) PURE;
+ STDMETHOD_(DBCachedContact*, GetNextContact)(MCONTACT contactID) PURE;
+ STDMETHOD_(void, FreeCachedContact)(MCONTACT contactID) PURE;
+
+ STDMETHOD_(char*, InsertCachedSetting)(const char *szName, size_t) PURE;
+ STDMETHOD_(char*, GetCachedSetting)(const char *szModuleName, const char *szSettingName, size_t, size_t) PURE;
+ STDMETHOD_(void, SetCachedVariant)(DBVARIANT *s, DBVARIANT *d) PURE;
+ STDMETHOD_(DBVARIANT*, GetCachedValuePtr)(MCONTACT contactID, char *szSetting, int bAllocate) PURE;
+};
+
+interface MIR_APP_EXPORT MIDatabase
+{
+ STDMETHOD_(BOOL, IsRelational)(void) PURE;
+ STDMETHOD_(void, SetCacheSafetyMode)(BOOL) PURE;
+
+ STDMETHOD_(int, GetContactCount)(void) PURE;
+ STDMETHOD_(MCONTACT, FindFirstContact)(const char *szProto = nullptr) PURE;
+ STDMETHOD_(MCONTACT, FindNextContact)(MCONTACT contactID, const char *szProto = nullptr) PURE;
+
+ STDMETHOD_(int, DeleteContact)(MCONTACT contactID) PURE;
+ STDMETHOD_(MCONTACT, AddContact)(void) PURE;
+ STDMETHOD_(BOOL, IsDbContact)(MCONTACT contactID) PURE;
+ STDMETHOD_(int, GetContactSize)(void) PURE;
+
+ STDMETHOD_(int, GetEventCount)(MCONTACT contactID) PURE;
+ STDMETHOD_(MEVENT, AddEvent)(MCONTACT contactID, const DBEVENTINFO *dbe) PURE;
+ STDMETHOD_(BOOL, DeleteEvent)(MEVENT hDbEvent) PURE;
+ STDMETHOD_(BOOL, EditEvent)(MCONTACT contactID, MEVENT hDbEvent, const DBEVENTINFO *dbe) PURE;
+ STDMETHOD_(int, GetBlobSize)(MEVENT hDbEvent) PURE;
+ STDMETHOD_(BOOL, GetEvent)(MEVENT hDbEvent, DBEVENTINFO *dbe) PURE;
+ STDMETHOD_(BOOL, MarkEventRead)(MCONTACT contactID, MEVENT hDbEvent) PURE;
+ STDMETHOD_(MCONTACT, GetEventContact)(MEVENT hDbEvent) PURE;
+ STDMETHOD_(MEVENT, FindFirstEvent)(MCONTACT contactID) PURE;
+ STDMETHOD_(MEVENT, FindFirstUnreadEvent)(MCONTACT contactID) PURE;
+ STDMETHOD_(MEVENT, FindLastEvent)(MCONTACT contactID) PURE;
+ STDMETHOD_(MEVENT, FindNextEvent)(MCONTACT contactID, MEVENT hDbEvent) PURE;
+ STDMETHOD_(MEVENT, FindPrevEvent)(MCONTACT contactID, MEVENT hDbEvent) PURE;
+
+ STDMETHOD_(BOOL, DeleteModule)(MCONTACT contactID, LPCSTR szModule) PURE;
+ STDMETHOD_(BOOL, EnumModuleNames)(DBMODULEENUMPROC pFunc, void *pParam) PURE;
+
+ STDMETHOD_(BOOL, GetContactSetting)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) PURE;
+ STDMETHOD_(BOOL, GetContactSettingStr)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) PURE;
+ STDMETHOD_(BOOL, GetContactSettingStatic)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) PURE;
+ STDMETHOD_(BOOL, FreeVariant)(DBVARIANT *dbv) PURE;
+ STDMETHOD_(BOOL, WriteContactSetting)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) PURE;
+ STDMETHOD_(BOOL, DeleteContactSetting)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting) PURE;
+ STDMETHOD_(BOOL, EnumContactSettings)(MCONTACT contactID, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, void *param) PURE;
+ STDMETHOD_(BOOL, SetSettingResident)(BOOL bIsResident, const char *pszSettingName) PURE;
+ STDMETHOD_(BOOL, EnumResidentSettings)(DBMODULEENUMPROC pFunc, void *pParam) PURE;
+ STDMETHOD_(BOOL, IsSettingEncrypted)(LPCSTR szModule, LPCSTR szSetting) PURE;
+
+ STDMETHOD_(BOOL, MetaDetouchSub)(DBCachedContact*, int nSub) PURE;
+ STDMETHOD_(BOOL, MetaSetDefault)(DBCachedContact*) PURE;
+ STDMETHOD_(BOOL, MetaMergeHistory)(DBCachedContact *ccMeta, DBCachedContact *ccSub) PURE;
+ STDMETHOD_(BOOL, MetaSplitHistory)(DBCachedContact *ccMeta, DBCachedContact *ccSub) PURE;
+ STDMETHOD_(BOOL, MetaRemoveSubHistory)(DBCachedContact *ccSub) PURE;
+
+ STDMETHOD_(BOOL, Compact)(void) PURE;
+ STDMETHOD_(BOOL, Backup)(LPCWSTR) PURE;
+ STDMETHOD_(BOOL, Flush)(void) PURE;
+
+ STDMETHOD_(MIDatabaseChecker*, GetChecker)(void) PURE;
+ STDMETHOD_(DATABASELINK*, GetDriver)(void) PURE;
+
+ STDMETHOD_(MEVENT, GetEventById)(LPCSTR szModule, LPCSTR szId) PURE;
+ STDMETHOD_(int, UpdateEventId)(MEVENT hDbEvent, const char *szId) PURE;
+
+ STDMETHOD_(DB::EventCursor*, EventCursor)(MCONTACT hContact, MEVENT hDbEvent) PURE;
+ STDMETHOD_(DB::EventCursor*, EventCursorRev)(MCONTACT hContact, MEVENT hDbEvent) PURE;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#pragma warning(push)
+#pragma warning(disable:4275)
+
+struct MICryptoEngine;
+struct CRYPTO_PROVIDER;
+
+class MIR_APP_EXPORT MDatabaseCommon : public MIDatabase, public MNonCopyable
+{
+ HANDLE m_hLock = nullptr;
+
+protected:
+ bool m_bEncrypted = false, m_bUsesPassword = false;
+ int m_codePage;
+
+ mir_cs m_csDbAccess;
+ LIST<char> m_lResidentSettings;
+ MIDatabaseCache* m_cache;
+ MICryptoEngine *m_crypto = nullptr;
+
+protected:
+ int CheckProto(DBCachedContact *cc, const char *proto);
+ void FillContactSettings();
+ bool LockName(const wchar_t *pwszProfileName);
+ void UnlockName();
+
+ STDMETHOD_(BOOL, GetContactSettingWorker)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic);
+ STDMETHOD_(BOOL, WriteContactSettingWorker)(MCONTACT contactID, DBCONTACTWRITESETTING &dbcws) PURE;
+
+public:
+ MDatabaseCommon();
+ virtual ~MDatabaseCommon();
+
+ __forceinline bool isEncrypted() const { return m_bEncrypted; }
+ __forceinline MICryptoEngine* getCrypt() const { return m_crypto; }
+ __forceinline MIDatabaseCache* getCache() const { return m_cache; }
+ __forceinline bool usesPassword() const { return m_bUsesPassword; }
+
+ void SetPassword(const wchar_t *ptszPassword);
+
+ STDMETHODIMP_(BOOL) DeleteModule(MCONTACT contactID, LPCSTR szModule) override;
+
+ STDMETHODIMP_(MCONTACT) FindFirstContact(const char *szProto = nullptr) override;
+ STDMETHODIMP_(MCONTACT) FindNextContact(MCONTACT contactID, const char *szProto = nullptr) override;
+
+ STDMETHODIMP_(BOOL) MetaDetouchSub(DBCachedContact *cc, int nSub) override;
+ STDMETHODIMP_(BOOL) MetaSetDefault(DBCachedContact *cc) override;
+ STDMETHODIMP_(BOOL) MetaRemoveSubHistory(DBCachedContact *ccSub) override;
+
+ STDMETHODIMP_(BOOL) IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting) override;
+ STDMETHODIMP_(BOOL) GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override;
+ STDMETHODIMP_(BOOL) GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override;
+ STDMETHODIMP_(BOOL) GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override;
+ STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv);
+ STDMETHODIMP_(BOOL) WriteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override;
+
+ STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam) override;
+ STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName) override;
+
+ STDMETHODIMP_(BOOL) Compact(void) override;
+ STDMETHODIMP_(BOOL) Backup(LPCWSTR) override;
+ STDMETHODIMP_(BOOL) Flush(void) override;
+
+ STDMETHODIMP_(MIDatabaseChecker*) GetChecker(void) override;
+
+ STDMETHODIMP_(DB::EventCursor*) EventCursor(MCONTACT hContact, MEVENT hDbEvent) override;
+ STDMETHODIMP_(DB::EventCursor*) EventCursorRev(MCONTACT hContact, MEVENT hDbEvent) override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // encryption support
+
+ int InitCrypt();
+
+ CRYPTO_PROVIDER* SelectProvider();
+ STDMETHOD_(CRYPTO_PROVIDER*, ReadProvider)() PURE;
+ STDMETHOD_(BOOL, StoreProvider)(CRYPTO_PROVIDER*) PURE;
+
+ STDMETHOD_(BOOL, ReadCryptoKey)(MBinBuffer&) PURE;
+ STDMETHOD_(BOOL, StoreCryptoKey)() PURE;
+
+ STDMETHOD_(BOOL, EnableEncryption)(BOOL) PURE;
+ STDMETHOD_(BOOL, ReadEncryption)() PURE;
+};
+
+#pragma warning(pop)
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Read-only database, that cannot add/modify information in a profile
+
+class MIR_APP_EXPORT MDatabaseReadonly : public MDatabaseCommon
+{
+public:
+ MDatabaseReadonly();
+
+ STDMETHODIMP_(BOOL) IsRelational(void) override;
+
+ STDMETHODIMP_(void) SetCacheSafetyMode(BOOL) override;
+
+ STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC, void*) override;
+
+ STDMETHODIMP_(CRYPTO_PROVIDER*) ReadProvider() override;
+ STDMETHODIMP_(BOOL) StoreProvider(CRYPTO_PROVIDER*) override;
+ STDMETHODIMP_(BOOL) ReadCryptoKey(MBinBuffer&) override;
+ STDMETHODIMP_(BOOL) StoreCryptoKey() override;
+ STDMETHODIMP_(BOOL) EnableEncryption(BOOL) override;
+ STDMETHODIMP_(BOOL) ReadEncryption() override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ STDMETHODIMP_(MCONTACT) AddContact(void) override;
+ STDMETHODIMP_(int) DeleteContact(MCONTACT) override;
+ STDMETHODIMP_(BOOL) IsDbContact(MCONTACT contactID) override;
+ STDMETHODIMP_(int) GetContactSize(void) override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ STDMETHODIMP_(MEVENT) AddEvent(MCONTACT, const DBEVENTINFO*) override;
+ STDMETHODIMP_(BOOL) DeleteEvent(MEVENT) override;
+ STDMETHODIMP_(BOOL) EditEvent(MCONTACT contactID, MEVENT hDbEvent, const DBEVENTINFO *dbe) override;
+ STDMETHODIMP_(int) GetBlobSize(MEVENT) override;
+ STDMETHODIMP_(BOOL) MarkEventRead(MCONTACT, MEVENT) override;
+ STDMETHODIMP_(MCONTACT) GetEventContact(MEVENT) override;
+ STDMETHODIMP_(MEVENT) FindFirstUnreadEvent(MCONTACT) override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ STDMETHODIMP_(BOOL) GetContactSettingWorker(MCONTACT, LPCSTR, LPCSTR, DBVARIANT*, int) override;
+ STDMETHODIMP_(BOOL) WriteContactSettingWorker(MCONTACT, DBCONTACTWRITESETTING&) override;
+ STDMETHODIMP_(BOOL) DeleteContactSetting(MCONTACT, LPCSTR, LPCSTR) override;
+ STDMETHODIMP_(BOOL) EnumContactSettings(MCONTACT, DBSETTINGENUMPROC, const char*, void*) override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ STDMETHODIMP_(BOOL) MetaMergeHistory(DBCachedContact*, DBCachedContact*) override;
+ STDMETHODIMP_(BOOL) MetaSplitHistory(DBCachedContact*, DBCachedContact*) override;
+ STDMETHODIMP_(BOOL) MetaRemoveSubHistory(DBCachedContact*) override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ STDMETHODIMP_(MEVENT) GetEventById(LPCSTR szModule, LPCSTR szId) override;
+ STDMETHODIMP_(int) UpdateEventId(MEVENT hDbEvent, const char *szId) override;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Each database plugin should register itself using this structure
+
+// Codes for DATABASELINK functions
+
+// grokHeader() error codes
+#define EGROKPRF_NOERROR 0
+#define EGROKPRF_CANTREAD 1 // can't open the profile for reading
+#define EGROKPRF_UNKHEADER 2 // header not supported, not a supported profile
+#define EGROKPRF_VERNEWER 3 // header correct, version in profile newer than reader/writer
+#define EGROKPRF_DAMAGED 4 // header/version fine, other internal data missing, damaged.
+#define EGROKPRF_OBSOLETE 5 // obsolete database version detected, requiring conversion
+
+// makeDatabase() error codes
+#define EMKPRF_CREATEFAILED 1 // for some reason CreateFile() didnt like something
+
+#define MDB_CAPS_CREATE 0x0001 // new database can be created
+#define MDB_CAPS_COMPACT 0x0002 // database can be compacted
+#define MDB_CAPS_CHECK 0x0004 // database can be checked
+
+
+struct DATABASELINK
+{
+ int capabilities;
+ char* szShortName; // uniqie short database name
+ wchar_t* szFullName; // in English, auto-translated by the core
+
+ /*
+ profile: pointer to a string which contains full path + name
+ Affect: The database plugin should create the profile, the filepath will not exist at
+ the time of this call, profile will be C:\..\<name>.dat
+ Returns: 0 on success, non zero on failure - error contains extended error information, see EMKPRF_*
+ */
+ int (*makeDatabase)(const wchar_t *profile);
+
+ /*
+ profile: [in] a null terminated string to file path of selected profile
+ error: [in/out] pointer to an int to set with error if any
+ Affect: Ask the database plugin if it supports the given profile, if it does it will
+ return 0, if it doesnt return 1, with the error set in error -- EGROKPRF_* can be valid error
+ condition, most common error would be [EGROKPRF_UNKHEADER]
+ Note: Just because 1 is returned, doesnt mean the profile is not supported, the profile might be damaged
+ etc.
+ Returns: 0 on success, non zero on failure
+ */
+ int (*grokHeader)(const wchar_t *profile);
+
+ /*
+ Affect: Tell the database to create all services/hooks that a 3.xx legacy database might support into link,
+ which is a PLUGINLINK structure
+ Returns: 0 on success, nonzero on failure
+ */
+ MDatabaseCommon* (*Load)(const wchar_t *profile, BOOL bReadOnly);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// global database event handles
+
+EXTERN_C MIR_APP_EXPORT HANDLE
+ g_hevContactDeleted, // ME_DB_CONTACT_DELETED
+ g_hevContactAdded, // ME_DB_CONTACT_ADDED
+ g_hevSettingChanged, // ME_DB_CONTACT_SETTINGCHANGED
+ g_hevMarkedRead, // ME_DB_EVENT_MARKED_READ
+ g_hevEventAdded, // ME_DB_EVENT_ADDED
+ g_hevEventEdited, // ME_DB_EVENT_EDITED
+ g_hevEventDeleted, // ME_DB_EVENT_DELETED
+ g_hevEventFiltered; // ME_DB_EVENT_FILTER_ADD
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// cache access function
+
+EXTERN_C MIR_CORE_DLL(DBCachedContact*) db_get_contact(MCONTACT);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// database list's functions
+
+EXTERN_C MIR_CORE_DLL(MDatabaseCommon*) db_get_current(void);
+EXTERN_C MIR_CORE_DLL(void) db_setCurrent(MDatabaseCommon *_db);
+
+// registers a database plugin
+EXTERN_C MIR_APP_DLL(void) RegisterDatabasePlugin(DATABASELINK *pDescr);
+
+// looks for a database plugin by its short name
+// returns DATABASELINK* of the required plugin or nullptr on error
+EXTERN_C MIR_APP_DLL(DATABASELINK*) GetDatabasePlugin(const char *pszDriverName);
+
+// looks for a database plugin suitable to open this file
+// returns DATABASELINK* of the required plugin or nullptr on error
+EXTERN_C MIR_APP_DLL(DATABASELINK*) FindDatabasePlugin(const wchar_t *ptszFileName);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// database upgrader
+
+namespace DB
+{
+ MIR_APP_DLL(MDatabaseCommon *) Upgrade(const wchar_t *profile);
+}
+
+#endif // M_DB_INT_H__
diff --git a/include/m_gui.h b/include/m_gui.h index 48041ff696..60d4dc2933 100644 --- a/include/m_gui.h +++ b/include/m_gui.h @@ -1,1606 +1,1606 @@ -/* - -Jabber Protocol Plugin for Miranda NG - -Copyright (c) 2002-04 Santithorn Bunchua -Copyright (c) 2005-12 George Hazan -Copyright (c) 2007-09 Maxim Mluhov -Copyright (c) 2007-09 Victor Pavlychko -Copyright (C) 2012-23 Miranda NG team - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#pragma once - -#ifndef __M_GUI_H -#define __M_GUI_H - -#ifdef _MSC_VER - #include <CommCtrl.h> -#endif // _WINDOWS - -#include <m_system.h> -#include <m_protoint.h> -#include <m_clc.h> - -#pragma warning(disable:4355 4251 4481) - -///////////////////////////////////////////////////////////////////////////////////////// -// helpers for the option's visualization - -template<int Size> -struct CMDBTraits -{ -}; - -template<> -struct CMDBTraits<1> -{ - typedef uint8_t DBType; - enum { DBTypeId = DBVT_BYTE }; - static __forceinline DBType Get(const char *szModule, const char *szSetting, DBType value) - { - return db_get_b(0, szModule, szSetting, value); - } - static __forceinline void Set(const char *szModule, const char *szSetting, DBType value) - { - db_set_b(0, szModule, szSetting, value); - } -}; - -template<> -struct CMDBTraits<2> -{ - typedef uint16_t DBType; - enum { DBTypeId = DBVT_WORD }; - static __forceinline DBType Get(const char *szModule, const char *szSetting, DBType value) - { - return db_get_w(0, szModule, szSetting, value); - } - static __forceinline void Set(const char *szModule, const char *szSetting, DBType value) - { - db_set_w(0, szModule, szSetting, value); - } -}; - -template<> -struct CMDBTraits<4> -{ - typedef uint32_t DBType; - enum { DBTypeId = DBVT_DWORD }; - static __forceinline DBType Get(const char *szModule, const char *szSetting, DBType value) - { - return db_get_dw(0, szModule, szSetting, value); - } - static __forceinline void Set(const char *szModule, const char *szSetting, DBType value) - { - db_set_dw(0, szModule, szSetting, value); - } -}; - -template<> -struct CMDBTraits<8> -{ - typedef uint32_t DBType; - enum { DBTypeId = DBVT_DWORD }; - static __forceinline DBType Get(const char *szModule, const char *szSetting, DBType value) - { - return db_get_dw(0, szModule, szSetting, value); - } - static __forceinline void Set(const char *szModule, const char *szSetting, DBType value) - { - db_set_dw(0, szModule, szSetting, value); - } -}; - -class CMOptionBase : public MNonCopyable -{ -public: - __forceinline const char* GetDBModuleName() const { return m_szModuleName; } - __forceinline const char* GetDBSettingName() const { return m_szSetting; } - - __forceinline void Delete() const - { db_unset(0, m_szModuleName, m_szSetting); - } - -protected: - __forceinline CMOptionBase(PROTO_INTERFACE *proto, const char *szSetting) : - m_szModuleName(proto->m_szModuleName), m_szSetting(szSetting) - {} - - __forceinline CMOptionBase(const char *module, const char *szSetting) : - m_szModuleName(module), m_szSetting(szSetting) - {} - - const char *m_szModuleName; - const char *m_szSetting; -}; - -template<class T> -class CMOption : public CMOptionBase -{ -public: - typedef T Type; - - __forceinline CMOption(PROTO_INTERFACE *proto, const char *szSetting, Type defValue) : - CMOptionBase(proto, szSetting), m_default(defValue) - {} - - __forceinline CMOption(const char *szModule, const char *szSetting, Type defValue) : - CMOptionBase(szModule, szSetting), m_default(defValue) - {} - - __forceinline Type Default() const - { - return m_default; - } - - __forceinline operator Type() - { - return (Type)CMDBTraits<sizeof(Type)>::Get(m_szModuleName, m_szSetting, m_default); - } - - __forceinline Type operator= (Type value) - { - #ifdef _MSC_VER - CMDBTraits<sizeof(Type)>::Set(m_szModuleName, m_szSetting, (CMDBTraits<sizeof(Type)>::DBType)value); - #else - CMDBTraits<sizeof(Type)>::Set(m_szModuleName, m_szSetting, value); - #endif - return value; - } - -private: - Type m_default; -}; - -template<> -class CMOption<char*> : public CMOptionBase -{ -public: - - typedef char Type; - - __forceinline CMOption(PROTO_INTERFACE *proto, const char *szSetting, const Type *defValue = nullptr) : - CMOptionBase(proto, szSetting), m_default(defValue) - {} - - __forceinline CMOption(const char *szModule, const char *szSetting, const Type *defValue = nullptr) : - CMOptionBase(szModule, szSetting), m_default(defValue) - {} - - __forceinline const Type* Default() const - { - return m_default; - } - - __forceinline operator Type*() - { - m_value = db_get_sa(0, m_szModuleName, m_szSetting); - if (!m_value) m_value = mir_strdup(m_default); - return m_value; - } - - __forceinline Type* operator= (Type *value) - { - db_set_s(0, m_szModuleName, m_szSetting, value); - return value; - } - -private: - const Type *m_default; - mir_ptr<Type> m_value; -}; - -template<> -class CMOption<wchar_t*> : public CMOptionBase -{ -public: - - typedef wchar_t Type; - - __forceinline CMOption(PROTO_INTERFACE *proto, const char *szSetting, const Type *defValue = nullptr) : - CMOptionBase(proto, szSetting), m_default(defValue) - {} - - __forceinline CMOption(const char *szModule, const char *szSetting, const Type *defValue = nullptr) : - CMOptionBase(szModule, szSetting), m_default(defValue) - {} - - __forceinline const Type* Default() const - { - return m_default; - } - - __forceinline operator Type*() - { - m_value = db_get_wsa(0, m_szModuleName, m_szSetting); - if (!m_value) m_value = mir_wstrdup(m_default); - return m_value; - } - - __forceinline const Type* operator= (const Type *value) - { - db_set_ws(0, m_szModuleName, m_szSetting, value); - return value; - } - -private: - const Type *m_default; - mir_ptr<Type> m_value; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CDbLink - -class MIR_CORE_EXPORT CDataLink -{ -protected: - uint8_t m_type; - -public: - __inline CDataLink(uint8_t type) : m_type(type) {} - virtual ~CDataLink() {} - - __inline uint8_t GetDataType() const { return m_type; } - - virtual uint32_t LoadInt() = 0; - virtual void SaveInt(uint32_t value) = 0; - - virtual wchar_t* LoadText() = 0; - virtual void SaveText(wchar_t *value) = 0; -}; - -class MIR_CORE_EXPORT CDbLink : public CDataLink -{ - char *m_szModule; - char *m_szSetting; - - uint32_t m_iDefault; - wchar_t *m_szDefault; - - DBVARIANT dbv; - -public: - CDbLink(const char *szModule, const char *szSetting, uint8_t type, uint32_t iValue); - CDbLink(const char *szModule, const char *szSetting, uint8_t type, wchar_t *szValue); - ~CDbLink(); - - uint32_t LoadInt() override; - void SaveInt(uint32_t value) override; - - wchar_t* LoadText() override; - void SaveText(wchar_t *value) override; -}; - -template<class T> -class CMOptionLink : public CDataLink -{ -private: - CMOption<T> *m_option; - -public: - __forceinline CMOptionLink(CMOption<T> &option) : - CDataLink(CMDBTraits<sizeof(T)>::DBTypeId), m_option(&option) - {} - - __forceinline uint32_t LoadInt() override { return (uint32_t)(T)*m_option; } - __forceinline void SaveInt(uint32_t value) override { *m_option = (T)value; } - - __forceinline wchar_t* LoadText() override { return nullptr; } - __forceinline void SaveText(wchar_t*) override {} -}; - -template<> -class CMOptionLink<wchar_t*> : public CDataLink -{ -private: - typedef wchar_t *T; - CMOption<T> *m_option; - -public: - __forceinline CMOptionLink(CMOption<T> &option) : - CDataLink(DBVT_WCHAR), m_option(&option) - {} - - __forceinline uint32_t LoadInt() override { return 0; } - __forceinline void SaveInt(uint32_t) override { } - - __forceinline wchar_t* LoadText() override { return *m_option; } - __forceinline void SaveText(wchar_t *value) override { *m_option = value; } -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlBase - -struct CContextMenuPos -{ - const class CCtrlBase *pCtrl; - POINT pt; - union { - int iCurr; // int for list boxes - HTREEITEM hItem; - }; -}; - -class MIR_CORE_EXPORT CCtrlBase -{ - friend class CDlgBase; - - __forceinline CCtrlBase(const CCtrlBase&) = delete; - __forceinline CCtrlBase& operator=(const CCtrlBase&) = delete; - -public: - CCtrlBase(CDlgBase *wnd, int idCtrl); - virtual ~CCtrlBase(); - - __forceinline MWindow GetHwnd() const { return m_hwnd; } - __forceinline int GetCtrlId() const { return m_idCtrl; } - __forceinline CDlgBase *GetParent() const { return m_parentWnd; } - __forceinline bool IsChanged() const { return m_bChanged; } - __forceinline void SetSilent(bool bSilent = true) { m_bSilent = bSilent; } - __forceinline void UseSystemColors() { m_bUseSystemColors = true; } - - void Show(bool bShow = true); - __forceinline void Hide() { Show(false); } - - void Enable(bool bIsEnable = true); - __forceinline void Disable() { Enable(false); } - bool Enabled(void) const; - - void NotifyChange(); - void SetDraw(bool bEnable); - - LRESULT SendMsg(UINT Msg, WPARAM wParam, LPARAM lParam) const; - - void SetText(const wchar_t *text); - void SetTextA(const char *text); - void SetInt(int value); - - wchar_t* GetText() const; - char* GetTextA() const; - char* GetTextU() const; - - wchar_t* GetText(wchar_t *buf, size_t size) const; - char* GetTextA(char *buf, size_t size) const; - char* GetTextU(char *buf, size_t size) const; - - int GetInt() const; - - virtual BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t /*idCode*/) { return FALSE; } - virtual BOOL OnNotify(int /*idCtrl*/, NMHDR* /*pnmh*/) { return FALSE; } - - virtual BOOL OnMeasureItem(MEASUREITEMSTRUCT*) { return FALSE; } - virtual BOOL OnDrawItem(DRAWITEMSTRUCT*) { return FALSE; } - virtual BOOL OnDeleteItem(DELETEITEMSTRUCT*) { return FALSE; } - - virtual void OnInit(); - virtual void OnDestroy(); - - virtual bool OnApply(); - virtual void OnReset(); - -protected: - MWindow m_hwnd = nullptr; // must be the first data item - int m_idCtrl; - bool m_bChanged = false, m_bSilent = false, m_bUseSystemColors = false, m_bNotifiable = false; - CDlgBase *m_parentWnd; - -public: - CCallback<CCtrlBase> OnChange; - CCallback<CContextMenuPos> OnBuildMenu; - -protected: - virtual void GetCaretPos(CContextMenuPos&) const; - virtual LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam); - - void Subclass(); - void Unsubclass(); - -private: - static LRESULT CALLBACK GlobalSubclassWndProc(MWindow hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlData - data access controls base class - -class MIR_CORE_EXPORT CCtrlData : public CCtrlBase -{ - typedef CCtrlBase CSuper; - -public: - CCtrlData(CDlgBase *dlg, int ctrlId); - ~CCtrlData(); - - void CreateDbLink(const char* szModuleName, const char* szSetting, uint8_t type, uint32_t iValue); - void CreateDbLink(const char* szModuleName, const char* szSetting, wchar_t* szValue); - void CreateDbLink(CDataLink *link) { m_dbLink = link; } - - void OnInit() override; - -protected: - CDataLink *m_dbLink; - - __inline uint8_t GetDataType() { return m_dbLink ? m_dbLink->GetDataType() : DBVT_DELETED; } - __inline uint32_t LoadInt() { return m_dbLink ? m_dbLink->LoadInt() : 0; } - __inline void SaveInt(uint32_t value) { if (m_dbLink) m_dbLink->SaveInt(value); } - __inline const wchar_t *LoadText() { return m_dbLink ? m_dbLink->LoadText() : L""; } - __inline void SaveText(wchar_t *value) { if (m_dbLink) m_dbLink->SaveText(value); } -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CDlgBase - base dialog class - -class MIR_CORE_EXPORT CDlgBase -{ - friend class CTimer; - friend class CCtrlBase; - friend class CCtrlData; - -public: - CDlgBase(class CMPluginBase &pPlug, int idDialog); - virtual ~CDlgBase(); - - // general utilities - void Close(); - void Resize(); - void Create(); - void Show(int nCmdShow = SW_SHOW); - int DoModal(); - void EndModal(INT_PTR nResult); - - class CCtrlBase* FindControl(int idCtrl); - class CCtrlBase* FindControl(MWindow hwnd); - - void SetCaption(const wchar_t *ptszCaption); - void SetDraw(bool bEnable); - void NotifyChange(void); // sends a notification to a parent window - - HINSTANCE GetInst() const; - - __forceinline MWindow GetHwnd() const { return m_hwnd; } - __forceinline void Hide() { Show(SW_HIDE); } - __forceinline bool IsInitialized() const { return m_bInitialized; } - __forceinline void SetMinSize(int x, int y) { m_iMinWidth = x, m_iMinHeight = y; } - __forceinline void SetParent(MWindow hwnd) { m_hwndParent = hwnd; } - - __forceinline CCtrlBase* operator[](int iControlId) { return FindControl(iControlId); } - - static CDlgBase* Find(MWindow hwnd); - -protected: - MWindow m_hwnd = nullptr; // must be the first data item - MWindow m_hwndParent = nullptr; - int m_idDialog; - - bool m_isModal = false; - bool m_bInitialized = false; - bool m_forceResizable = false; - bool m_bFixedSize; - bool m_bSucceeded = false; // was IDOK pressed or not - bool m_bExiting = false; // window received WM_CLOSE and gonna die soon - - enum { CLOSE_ON_OK = 0x1, CLOSE_ON_CANCEL = 0x2 }; - uint8_t m_autoClose; // automatically close dialog on IDOK/CANCEL commands. default: CLOSE_ON_OK|CLOSE_ON_CANCEL - - CMPluginBase &m_pPlugin; - - // override this handlers to provide custom functionality - // general messages - virtual bool OnInitDialog(); - virtual bool OnApply(); - virtual bool OnClose(); - virtual void OnDestroy(); - - virtual void OnTimer(class CTimer*); - - // miranda-related stuff - virtual int Resizer(UTILRESIZECONTROL *urc); - virtual void OnResize(); - virtual void OnReset(); - virtual void OnChange(); - - // main dialog procedure - virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam); - - CCallback<void> m_OnFinishWizard; - - // register controls - void AddControl(CCtrlBase *ctrl); - void RemoveControl(CCtrlBase *ctrl); - - // timers - void AddTimer(CTimer *timer); - void RemoveTimer(UINT_PTR idEvent); - - // options support - void CreateLink(class CCtrlData& ctrl, const char *szSetting, uint8_t type, uint32_t iValue); - void CreateLink(class CCtrlData& ctrl, const char *szSetting, wchar_t *szValue); - - template<class T> - __inline void CreateLink(CCtrlData& ctrl, CMOption<T> &option) - { - ctrl.CreateDbLink(new CMOptionLink<T>(option)); - } - - // win32 stuff - void ThemeDialogBackground(BOOL tabbed); - -private: - LIST<CTimer> m_timers; - LIST<CCtrlBase> m_controls; - - void NotifyControls(void (CCtrlBase::*fn)()); - bool VerifyControls(bool (CCtrlBase::*fn)()); - - CTimer* FindTimer(int idEvent); - int m_iMinWidth = -1, m_iMinHeight = -1; - - static BOOL CALLBACK GlobalFieldEnum(MWindow hwnd, LPARAM lParam); - static INT_PTR CALLBACK GlobalDlgProc(MWindow hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - static int GlobalDlgResizer(MWindow hwnd, LPARAM lParam, UTILRESIZECONTROL *urc); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CTimer - -class MIR_CORE_EXPORT CTimer -{ - friend class CDlgBase; - -public: - CTimer(CDlgBase* wnd, UINT_PTR idEvent); - ~CTimer(); - - __forceinline UINT_PTR GetEventId() const { return m_idEvent; } - __forceinline MWindow GetHwnd() const { return m_wnd->GetHwnd(); } - - virtual BOOL OnTimer(); - - void Start(int elapse); - bool Stop(); // returns true if timer was active - - void StartSafe(int elapse); - void StopSafe(); - - CCallback<CTimer> OnEvent; - -protected: - UINT_PTR m_idEvent; - CDlgBase* m_wnd; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlLabel - -class MIR_CORE_EXPORT CCtrlLabel : public CCtrlBase -{ - typedef CCtrlBase CSuper; - -public: - CCtrlLabel(CDlgBase *dlg, int ctrlId); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlButton - -class MIR_CORE_EXPORT CCtrlButton : public CCtrlBase -{ - typedef CCtrlBase CSuper; - -public: - CCtrlButton(CDlgBase *dlg, int ctrlId); - - BOOL OnCommand(MWindow hwndCtrl, uint16_t idCtrl, uint16_t idCode) override; - - CCallback<CCtrlButton> OnClick; - - void Click(); - bool IsPushed() const; - void Push(bool bPushed); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlMButton - -class MIR_CORE_EXPORT CCtrlMButton : public CCtrlButton -{ - typedef CCtrlButton CSuper; - -public: - CCtrlMButton(CDlgBase *dlg, int ctrlId, HICON hIcon, const char* tooltip); - CCtrlMButton(CDlgBase *dlg, int ctrlId, int iCoreIcon, const char* tooltip); - ~CCtrlMButton(); - - void MakeFlat(); - void MakePush(); - - void OnInit() override; - -protected: - HICON m_hIcon; - const char* m_toolTip; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CSplitter - -class MIR_CORE_EXPORT CSplitter : public CCtrlBase -{ - typedef CCtrlBase CSuper; - -public: - CSplitter(CDlgBase *dlg, int ctrlId); - - __forceinline int GetPos() const { return m_iPosition; } - -protected: - LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) override; - void OnInit() override; - - int m_iPosition; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlHyperlink - -class MIR_CORE_EXPORT CCtrlHyperlink : public CCtrlBase -{ - typedef CCtrlBase CSuper; - -public: - CCtrlHyperlink(CDlgBase *dlg, int ctrlId, const char* url = nullptr); - - BOOL OnCommand(MWindow hwndCtrl, uint16_t idCtrl, uint16_t idCode) override; - - CCallback<CCtrlHyperlink> OnClick; - - void SetUrl(const char *url); - const char *GetUrl(); - -protected: - const char* m_url; - - void Default_OnClick(CCtrlHyperlink*); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CProgress - -class MIR_CORE_EXPORT CCtrlProgress : public CCtrlBase -{ -public: - CCtrlProgress(CDlgBase *dlg, int ctrlId); - - void SetRange(uint16_t max, uint16_t min = 0); - void SetPosition(uint16_t value); - void SetStep(uint16_t value); - uint16_t Move(uint16_t delta = 0); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlClc - -#if !defined(MGROUP) - typedef int MGROUP; -#endif - -class MIR_CORE_EXPORT CCtrlClc : public CCtrlBase -{ - typedef CCtrlBase CSuper; - -public: - CCtrlClc(CDlgBase *dlg, int ctrlId); - - void AddContact(MCONTACT hContact); - void AddGroup(HANDLE hGroup); - HANDLE AddInfoItem(CLCINFOITEM *cii); - void AutoRebuild(); - void DeleteItem(HANDLE hItem); - void EditLabel(HANDLE hItem); - void EndEditLabel(bool save); - void EnsureVisible(HANDLE hItem, bool partialOk); - void Expand(HANDLE hItem, uint32_t flags); - HANDLE FindContact(MCONTACT hContact); - HANDLE FindGroup(MGROUP hGroup); - COLORREF GetBkColor() const; - bool GetCheck(HANDLE hItem) const; - int GetCount() const; - MWindow GetEditControl() const; - uint32_t GetExStyle() const; - uint32_t GetExpand(HANDLE hItem) const; - int GetExtraColumns() const; - uint8_t GetExtraImage(HANDLE hItem, int iColumn) const; - HIMAGELIST GetExtraImageList() const; - HFONT GetFont(int iFontId) const; - bool GetHideOfflineRoot() const; - int GetItemType(HANDLE hItem) const; - HANDLE GetNextItem(HANDLE hItem, uint32_t flags) const; - HANDLE GetSelection() const; - HANDLE HitTest(int x, int y, uint32_t *hitTest) const; - void SelectItem(HANDLE hItem); - void SetBkColor(COLORREF clBack); - void SetCheck(HANDLE hItem, bool check); - void SetExStyle(uint32_t exStyle); - void SetExtraColumns(int iColumns); - void SetExtraImage(HANDLE hItem, int iColumn, int iImage); - void SetExtraImageList(HIMAGELIST hImgList); - void SetFont(int iFontId, HANDLE hFont, bool bRedraw); - void SetItemText(HANDLE hItem, char *szText); - void SetHideEmptyGroups(bool state); - void SetHideOfflineRoot(bool state); - void SetOfflineModes(uint32_t modes); - void SetUseGroups(bool state); - - struct TEventInfo - { - CCtrlClc *ctrl; - NMCLISTCONTROL *info; - }; - - CCallback<TEventInfo> OnExpanded; - CCallback<TEventInfo> OnListRebuilt; - CCallback<TEventInfo> OnItemChecked; - CCallback<TEventInfo> OnDragging; - CCallback<TEventInfo> OnDropped; - CCallback<TEventInfo> OnListSizeChange; - CCallback<TEventInfo> OnOptionsChanged; - CCallback<TEventInfo> OnDragStop; - CCallback<TEventInfo> OnNewContact; - CCallback<TEventInfo> OnContactMoved; - CCallback<TEventInfo> OnCheckChanged; - CCallback<TEventInfo> OnClick; - -protected: - BOOL OnNotify(int idCtrl, NMHDR *pnmh) override; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlCheck - -class MIR_CORE_EXPORT CCtrlCheck : public CCtrlData -{ - typedef CCtrlData CSuper; - -public: - CCtrlCheck(CDlgBase *dlg, int ctrlId); - BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t /*idCode*/) override; - - bool OnApply() override; - void OnReset() override; - - int GetState() const; - void SetState(int state); - - bool IsChecked(); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlColor - color picker - -class MIR_CORE_EXPORT CCtrlColor : public CCtrlData -{ - typedef CCtrlData CSuper; - -public: - CCtrlColor(CDlgBase *dlg, int ctrlId); - BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t /*idCode*/) override; - - bool OnApply() override; - void OnReset() override; - - uint32_t GetColor(); - void SetColor(uint32_t dwValue); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlDate - date & time picker - -class MIR_CORE_EXPORT CCtrlDate : public CCtrlData -{ - typedef CCtrlData CSuper; - - BOOL OnNotify(int, NMHDR*) override; - -public: - CCtrlDate(CDlgBase *dlg, int ctrlId); - - void GetTime(SYSTEMTIME*); - void SetTime(SYSTEMTIME*); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlEdit - -class MIR_CORE_EXPORT CCtrlEdit : public CCtrlData -{ - typedef CCtrlData CSuper; - -public: - CCtrlEdit(CDlgBase *dlg, int ctrlId); - BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t idCode) override; - - bool OnApply() override; - void OnReset() override; - - void SetMaxLength(unsigned int len); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlRichEdit - -class MIR_CORE_EXPORT CCtrlRichEdit : public CCtrlEdit -{ - typedef CCtrlEdit CSuper; - -public: - CCtrlRichEdit(CDlgBase *dlg, int ctrlId); - - // returns text length in bytes if a parameter is omitted or in symbols, if not - int GetRichTextLength(int iCodePage = CP_ACP) const; - - // returns a buffer that should be freed using mir_free() or ptrA/ptrW - char* GetRichTextRtf(bool bText = false, bool bSelection = false) const; // returns text with formatting - wchar_t* GetRichText() const; // returns only text in ucs2 - - // these methods return text length in Unicode chars - int SetRichText(const wchar_t *text); - int SetRichTextRtf(const char *text); - - // enables or disables content editing - void SetReadOnly(bool bReadOnly); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlSlider - -class MIR_CORE_EXPORT CCtrlSlider : public CCtrlData -{ - typedef CCtrlData CSuper; - - int m_wMin, m_wMax; - -protected: - BOOL OnCommand(MWindow hwndCtrl, uint16_t idCtrl, uint16_t idCode) override; - -public: - CCtrlSlider(CDlgBase *dlg, int ctrlId, int max = 100, int min = 0); - - bool OnApply() override; - void OnReset() override; - - int GetPosition() const; - void SetPosition(int pos); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlSpin - -class MIR_CORE_EXPORT CCtrlSpin : public CCtrlData -{ - typedef CCtrlData CSuper; - - int16_t m_wMin, m_wMax, m_wCurr; - - BOOL OnNotify(int, NMHDR*) override; - -public: - CCtrlSpin(CDlgBase *dlg, int ctrlId, int16_t max = 100, int16_t min = 0); - - bool OnApply() override; - void OnReset() override; - - int16_t GetPosition(); - void SetPosition(int16_t pos); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlListBox - -class MIR_CORE_EXPORT CCtrlListBox : public CCtrlBase -{ - typedef CCtrlBase CSuper; - -public: - CCtrlListBox(CDlgBase *dlg, int ctrlId); - - int AddString(const wchar_t *text, LPARAM data=0); - void DeleteString(int index); - int FindString(const wchar_t *str, int index = -1, bool exact = false); - int GetCount() const; - int GetCurSel() const; - LPARAM GetItemData(int index) const; - int GetItemRect(int index, RECT *pResult) const; - wchar_t* GetItemText(int index) const; - wchar_t* GetItemText(int index, wchar_t *buf, int size) const; - bool GetSel(int index) const; - int GetSelCount() const; - int* GetSelItems(int *items, int count) const; - int* GetSelItems() const; - int InsertString(const wchar_t *text, int pos, LPARAM data=0); - void ResetContent(); - int SelectString(const wchar_t *str); - int SetCurSel(int index); - void SetItemData(int index, LPARAM data); - void SetItemHeight(int index, int iHeight); - void SetSel(int index, bool sel = true); - - // Events - CCallback<CCtrlListBox> OnDblClick; - CCallback<CCtrlListBox> OnSelCancel; - CCallback<CCtrlListBox> OnSelChange; - -protected: - BOOL OnCommand(MWindow hwndCtrl, uint16_t idCtrl, uint16_t idCode) override; - void GetCaretPos(CContextMenuPos&) const override; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlCombo - -class MIR_CORE_EXPORT CCtrlCombo : public CCtrlData -{ - typedef CCtrlData CSuper; - -public: - CCtrlCombo(CDlgBase *dlg, int ctrlId); - - BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t idCode) override; - void OnInit() override; - bool OnApply() override; - void OnReset() override; - - // returns item data associated with the selected item or -1 - LPARAM GetCurData() const; - - // selects line with userdata passed. returns index of this line or -1 - int SelectData(LPARAM data); - - // Control interface - int AddString(const wchar_t *text, LPARAM data = 0); - int AddStringA(const char *text, LPARAM data = 0); - void DeleteString(int index); - int FindString(const wchar_t *str, int index = -1, bool exact = false); - int FindStringA(const char *str, int index = -1, bool exact = false); - int GetCount() const; - int GetCurSel() const; - bool GetDroppedState() const; - LPARAM GetItemData(int index) const; - wchar_t* GetItemText(int index) const; - wchar_t* GetItemText(int index, wchar_t *buf, int size) const; - int InsertString(const wchar_t *text, int pos, LPARAM data=0); - void ResetContent(); - int SelectString(const wchar_t *str); - int SetCurSel(int index); - void SetItemData(int index, LPARAM data); - void ShowDropdown(bool show = true); - - // Events - CCallback<CCtrlCombo> OnCloseup; - CCallback<CCtrlCombo> OnDropdown; - CCallback<CCtrlCombo> OnKillFocus; - CCallback<CCtrlCombo> OnSelChanged; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlListView - -class MIR_CORE_EXPORT CCtrlListView : public CCtrlBase -{ - typedef CCtrlBase CSuper; - -public: - CCtrlListView(CDlgBase *dlg, int ctrlId); - - // direction = -1 or 1. returns new item index - int MoveItem(int idx, int direction); - - void SetCurSel(int idx); - - // Classic LV interface - uint32_t ApproximateViewRect(int cx, int cy, int iCount); - void Arrange(UINT code); - void CancelEditLabel(); - HIMAGELIST CreateDragImage(int iItem, POINT *lpptUpLeft); - void DeleteAllItems(); - void DeleteColumn(int iCol); - void DeleteItem(int iItem); - MWindow EditLabel(int iItem); - int EnableGroupView(BOOL fEnable); - BOOL EnsureVisible(int i, BOOL fPartialOK); - int FindItem(int iStart, const LVFINDINFO *plvfi); - COLORREF GetBkColor() const; - void GetBkImage(LVBKIMAGE *plvbki) const; - UINT GetCallbackMask() const; - BOOL GetCheckState(UINT iIndex) const; - void GetColumn(int iCol, LVCOLUMN *pcol) const; - void GetColumnOrderArray(int iCount, int *lpiArray) const; - int GetColumnWidth(int iCol) const; - int GetCountPerPage() const; - MWindow GetEditControl() const; - uint32_t GetExtendedListViewStyle() const; - int GetFocusedGroup() const; - int GetGroupCount() const; - void GetGroupInfo(int iGroupId, LVGROUP *pgrp) const; - void GetGroupInfoByIndex(int iIndex, LVGROUP *pgrp) const; - void GetGroupMetrics(LVGROUPMETRICS *pGroupMetrics) const; - UINT GetGroupState(UINT dwGroupId, UINT dwMask) const; - MWindow GetHeader() const; - HCURSOR GetHotCursor() const; - int GetHotItem() const; - uint32_t GetHoverTime() const; - HIMAGELIST GetImageList(int iImageList) const; - BOOL GetInsertMark(LVINSERTMARK *plvim) const; - COLORREF GetInsertMarkColor() const; - int GetInsertMarkRect(RECT *prc) const; - BOOL GetISearchString(LPSTR lpsz) const; - bool GetItem(LVITEM *pitem) const; - int GetItemCount() const; - void GetItemPosition(int i, POINT *ppt) const; - void GetItemRect(int i, RECT *prc, int code) const; - uint32_t GetItemSpacing(BOOL fSmall) const; - UINT GetItemState(int i, UINT mask) const; - void GetItemText(int iItem, int iSubItem, LPTSTR pszText, int cchTextMax) const; - int GetNextItem(int iStart, UINT flags) const; - BOOL GetNumberOfWorkAreas(UINT *lpuWorkAreas) const; - BOOL GetOrigin(POINT *lpptOrg) const; - COLORREF GetOutlineColor() const; - UINT GetSelectedColumn() const; - UINT GetSelectedCount() const; - int GetSelectionMark() const; - int GetStringWidth(LPCSTR psz) const; - BOOL GetSubItemRect(int iItem, int iSubItem, int code, RECT *lpRect) const; - COLORREF GetTextBkColor() const; - COLORREF GetTextColor() const; - void GetTileInfo(LVTILEINFO *plvtinfo) const; - void GetTileViewInfo(LVTILEVIEWINFO *plvtvinfo) const; - MWindow GetToolTips() const; - int GetTopIndex() const; - BOOL GetUnicodeFormat() const; - uint32_t GetView() const; - BOOL GetViewRect(RECT *prc) const; - void GetWorkAreas(int nWorkAreas, RECT *lprc) const; - BOOL HasGroup(int dwGroupId); - int HitTest(LVHITTESTINFO *pinfo) const; - int HitTestEx(LVHITTESTINFO *pinfo); - int InsertColumn(int iCol, const LVCOLUMN *pcol); - int InsertGroup(int index, LVGROUP *pgrp); - void InsertGroupSorted(LVINSERTGROUPSORTED *structInsert); - int InsertItem(const LVITEM *pitem); - BOOL InsertMarkHitTest(POINT *point, LVINSERTMARK *plvim); - BOOL IsGroupViewEnabled(); - UINT IsItemVisible(UINT index); - UINT MapIDToIndex(UINT id); - UINT MapIndexToID(UINT index); - BOOL RedrawItems(int iFirst, int iLast); - void RemoveAllGroups(); - int RemoveGroup(int iGroupId); - BOOL Scroll(int dx, int dy); - BOOL SetBkColor(COLORREF clrBk); - BOOL SetBkImage(LVBKIMAGE *plvbki); - BOOL SetCallbackMask(UINT mask); - void SetCheckState(UINT iIndex, BOOL fCheck); - BOOL SetColumn(int iCol, LVCOLUMN *pcol); - BOOL SetColumnOrderArray(int iCount, int *lpiArray); - BOOL SetColumnWidth(int iCol, int cx); - void SetExtendedListViewStyle(uint32_t dwExStyle); - void SetExtendedListViewStyleEx(uint32_t dwExMask, uint32_t dwExStyle); - int SetGroupInfo(int iGroupId, LVGROUP *pgrp); - void SetGroupMetrics(LVGROUPMETRICS *pGroupMetrics); - void SetGroupState(UINT dwGroupId, UINT dwMask, UINT dwState); - HCURSOR SetHotCursor(HCURSOR hCursor); - int SetHotItem(int iIndex); - void SetHoverTime(uint32_t dwHoverTime); - uint32_t SetIconSpacing(int cx, int cy); - HIMAGELIST SetImageList(HIMAGELIST himl, int iImageList); - BOOL SetInfoTip(LVSETINFOTIP *plvSetInfoTip); - BOOL SetInsertMark(LVINSERTMARK *plvim); - COLORREF SetInsertMarkColor(COLORREF color); - BOOL SetItem(const LVITEM *pitem); - void SetItemCount(int cItems); - void SetItemCountEx(int cItems, uint32_t dwFlags); - BOOL SetItemPosition(int i, int x, int y); - void SetItemPosition32(int iItem, int x, int y); - void SetItemState(int i, UINT state, UINT mask); - void SetItemText(int i, int iSubItem, const wchar_t *pszText); - COLORREF SetOutlineColor(COLORREF color); - void SetSelectedColumn(int iCol); - int SetSelectionMark(int iIndex); - BOOL SetTextBkColor(COLORREF clrText); - BOOL SetTextColor(COLORREF clrText); - BOOL SetTileInfo(LVTILEINFO *plvtinfo); - BOOL SetTileViewInfo(LVTILEVIEWINFO *plvtvinfo); - MWindow SetToolTips(MWindow ToolTip); - BOOL SetUnicodeFormat(BOOL fUnicode); - int SetView(uint32_t iView); - void SetWorkAreas(int nWorkAreas, RECT *lprc); - int SubItemHitTest(LVHITTESTINFO *pInfo) const; - int SubItemHitTestEx(LVHITTESTINFO *plvhti); - BOOL Update(int iItem); - - #ifdef _MSC_VER - int SortGroups(PFNLVGROUPCOMPARE pfnGroupCompare, LPVOID plv); - BOOL SortItems(PFNLVCOMPARE pfnCompare, LPARAM lParamSort); - BOOL SortItemsEx(PFNLVCOMPARE pfnCompare, LPARAM lParamSort); - #endif // _MSC_VER - - // Additional APIs - HIMAGELIST CreateImageList(int iImageList); - void AddColumn(int iSubItem, const wchar_t *name, int cx); - void AddGroup(int iGroupId, const wchar_t *name); - int AddItem(const wchar_t *text, int iIcon, LPARAM lParam = 0, int iGroupId = -1); - void SetItem(int iItem, int iSubItem, const wchar_t *text, int iIcon = -1); - LPARAM GetItemData(int iItem) const; - - // Events - struct TEventInfo { - CCtrlListView *treeviewctrl; - union { - NMHDR *nmhdr; - NMLISTVIEW *nmlv; - NMLVDISPINFO *nmlvdi; - NMLVSCROLL *nmlvscr; - NMLVGETINFOTIP *nmlvit; - NMLVFINDITEM *nmlvfi; - NMITEMACTIVATE *nmlvia; - NMLVKEYDOWN *nmlvkey; - NMLVCUSTOMDRAW *nmcd; - }; - }; - - CCallback<TEventInfo> OnBeginDrag; - CCallback<TEventInfo> OnBeginLabelEdit; - CCallback<TEventInfo> OnBeginRDrag; - CCallback<TEventInfo> OnBeginScroll; - CCallback<TEventInfo> OnColumnClick; - CCallback<TEventInfo> OnCustomDraw; - CCallback<TEventInfo> OnDeleteAllItems; - CCallback<TEventInfo> OnDeleteItem; - CCallback<TEventInfo> OnClick; - CCallback<TEventInfo> OnDoubleClick; - CCallback<TEventInfo> OnEndLabelEdit; - CCallback<TEventInfo> OnEndScroll; - CCallback<TEventInfo> OnGetDispInfo; - CCallback<TEventInfo> OnGetInfoTip; - CCallback<TEventInfo> OnHotTrack; - CCallback<TEventInfo> OnIncrementalSearch; - CCallback<TEventInfo> OnInsertItem; - CCallback<TEventInfo> OnItemActivate; - CCallback<TEventInfo> OnItemChanged; - CCallback<TEventInfo> OnItemChanging; - CCallback<TEventInfo> OnKeyDown; - CCallback<TEventInfo> OnMarqueeBegin; - CCallback<TEventInfo> OnSetDispInfo; - -protected: - BOOL OnNotify(int idCtrl, NMHDR *pnmh) override; - void GetCaretPos(CContextMenuPos&) const override; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlTreeView - -#undef GetNextSibling -#undef GetPrevSibling - -#define MTREE_CHECKBOX 0x0001 -#define MTREE_DND 0x0002 -#define MTREE_MULTISELECT 0x0004 - -class MIR_CORE_EXPORT CCtrlTreeView : public CCtrlBase -{ - typedef CCtrlBase CSuper; - - HTREEITEM MoveItemAbove(HTREEITEM hItem, HTREEITEM hInsertAfter, HTREEITEM hParent); - -public: - CCtrlTreeView(CDlgBase *dlg, int ctrlId); - - void SetFlags(uint32_t dwFlags); // MTREE_* combination - - // Classic TV interface - HIMAGELIST CreateDragImage(HTREEITEM hItem); - void DeleteAllItems(); - void DeleteItem(HTREEITEM hItem); - MWindow EditLabel(HTREEITEM hItem); - void EndEditLabelNow(BOOL cancel); - void EnsureVisible(HTREEITEM hItem); - void Expand(HTREEITEM hItem, uint32_t flag); - COLORREF GetBkColor() const; - uint32_t GetCheckState(HTREEITEM hItem) const; - HTREEITEM GetChild(HTREEITEM hItem) const; - int GetCount() const; - HTREEITEM GetDropHilight() const; - MWindow GetEditControl() const; - HTREEITEM GetFirstVisible() const; - HIMAGELIST GetImageList(int iImage) const; - int GetIndent() const; - COLORREF GetInsertMarkColor() const; - bool GetItem(TVITEMEX *tvi) const; - int GetItemHeight() const; - void GetItemRect(HTREEITEM hItem, RECT *rcItem, BOOL fItemRect) const; - uint32_t GetItemState(HTREEITEM hItem, uint32_t stateMask) const; - HTREEITEM GetLastVisible() const; - COLORREF GetLineColor() const; - HTREEITEM GetNextItem(HTREEITEM hItem, uint32_t flag) const; - HTREEITEM GetNextSibling(HTREEITEM hItem) const; - HTREEITEM GetNextVisible(HTREEITEM hItem) const; - HTREEITEM GetParent(HTREEITEM hItem) const; - HTREEITEM GetPrevSibling(HTREEITEM hItem) const; - HTREEITEM GetPrevVisible(HTREEITEM hItem) const; - HTREEITEM GetRoot() const; - uint32_t GetScrollTime() const; - HTREEITEM GetSelection() const; - COLORREF GetTextColor() const; - MWindow GetToolTips() const; - BOOL GetUnicodeFormat() const; - unsigned GetVisibleCount() const; - HTREEITEM HitTest(TVHITTESTINFO *hti) const; - HTREEITEM InsertItem(TVINSERTSTRUCT *tvis); - void Select(HTREEITEM hItem, uint32_t flag); - void SelectDropTarget(HTREEITEM hItem); - void SelectItem(HTREEITEM hItem); - void SelectSetFirstVisible(HTREEITEM hItem); - COLORREF SetBkColor(COLORREF clBack); - void SetCheckState(HTREEITEM hItem, uint32_t state); - HIMAGELIST SetImageList(HIMAGELIST hIml, int iImage); - void SetIndent(int iIndent); - void SetInsertMark(HTREEITEM hItem, BOOL fAfter); - COLORREF SetInsertMarkColor(COLORREF clMark); - void SetItem(TVITEMEX *tvi); - void SetItemHeight(short cyItem); - void SetItemState(HTREEITEM hItem, uint32_t state, uint32_t stateMask); - COLORREF SetLineColor(COLORREF clLine); - void SetScrollTime(UINT uMaxScrollTime); - COLORREF SetTextColor(COLORREF clText); - MWindow SetToolTips(MWindow hwndToolTips); - BOOL SetUnicodeFormat(BOOL fUnicode); - void SortChildren(HTREEITEM hItem, BOOL fRecurse); - void SortChildrenCB(TVSORTCB *cb, BOOL fRecurse); - - // Additional stuff - void TranslateItem(HTREEITEM hItem); - void TranslateTree(); - HTREEITEM FindNamedItem(HTREEITEM hItem, const wchar_t *name); - void GetItem(HTREEITEM hItem, TVITEMEX *tvi) const; - void GetItem(HTREEITEM hItem, TVITEMEX *tvi, wchar_t *szText, int iTextLength) const; - void InvertCheck(HTREEITEM hItem); - - bool IsSelected(HTREEITEM hItem); - int GetNumSelected(); - void GetSelected(LIST<_TREEITEM> &selected); - - void Select(HTREEITEM hItem); - void Select(LIST<_TREEITEM> &selected); - void SelectAll(); - void SelectRange(HTREEITEM hStart, HTREEITEM hEnd); - - void Unselect(HTREEITEM hItem); - void UnselectAll(); - - void DropHilite(HTREEITEM hItem); - void DropUnhilite(HTREEITEM hItem); - - // Events - struct TEventInfo { - CCtrlTreeView *treeviewctrl; - union { - NMHDR *nmhdr; - NMTREEVIEW *nmtv; - NMTVKEYDOWN *nmtvkey; - NMTVDISPINFO *nmtvdi; - NMTVGETINFOTIP *nmtvit; - NMTVCUSTOMDRAW *nmcd; - HTREEITEM hItem; // for OnItemChanged - }; - }; - - CCallback<TEventInfo> OnBeginDrag; - CCallback<TEventInfo> OnBeginLabelEdit; - CCallback<TEventInfo> OnBeginRDrag; - CCallback<TEventInfo> OnCustomDraw; - CCallback<TEventInfo> OnDeleteItem; - CCallback<TEventInfo> OnEndLabelEdit; - CCallback<TEventInfo> OnGetDispInfo; - CCallback<TEventInfo> OnGetInfoTip; - CCallback<TEventInfo> OnItemChanged; - CCallback<TEventInfo> OnItemExpanded; - CCallback<TEventInfo> OnItemExpanding; - CCallback<TEventInfo> OnKeyDown; - CCallback<TEventInfo> OnRightClick; - CCallback<TEventInfo> OnSelChanged; - CCallback<TEventInfo> OnSelChanging; - CCallback<TEventInfo> OnSetDispInfo; - CCallback<TEventInfo> OnSingleExpand; - -protected: - void OnInit() override; - BOOL OnNotify(int idCtrl, NMHDR *pnmh) override; - - void GetCaretPos(CContextMenuPos&) const override; - LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) override; - - union { - uint32_t m_dwFlags; - struct { - bool m_bDndEnabled : 1; - bool m_bDragging : 1; - bool m_bCheckBox : 1; - bool m_bMultiSelect : 1; - }; - }; - HTREEITEM m_hDragItem; // valid if m_bDragging == true -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlTreeOpts - array of options with sections - -class MIR_CORE_EXPORT CCtrlTreeOpts : public CCtrlTreeView -{ - typedef CCtrlTreeView CSuper; - -public: - CCtrlTreeOpts(CDlgBase *dlg, int ctrlId); - ~CCtrlTreeOpts(); - - void AddOption(const wchar_t *pwszSection, const wchar_t *pwszName, CMOption<bool> &option); - void AddOption(const wchar_t *pwszSection, const wchar_t *pwszName, bool &option); - void AddOption(const wchar_t *pwszSection, const wchar_t *pwszName, uint32_t &option, uint32_t mask); - - BOOL OnNotify(int idCtrl, NMHDR *pnmh) override; - void OnDestroy() override; - void OnInit() override; - bool OnApply() override; - -protected: - struct COptionsItem - { - const wchar_t *m_pwszSection, *m_pwszName; - - union - { - CMOption<bool> *m_option; - bool *m_pBool; - struct - { - uint32_t *m_pDword; - uint32_t m_mask; - }; - }; - - HTREEITEM m_hItem = nullptr; - enum OptionItemType { CMOPTION = 1, BOOL = 2, MASK = 3 }; - OptionItemType m_type; - - COptionsItem(const wchar_t *pwszSection, const wchar_t *pwszName, OptionItemType type) : - m_pwszSection(pwszSection), - m_pwszName(pwszName), - m_type(type) - {} - }; - - OBJLIST<COptionsItem> m_options; - - void ProcessItemClick(HTREEITEM hti); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CCtrlPages - -#define PSN_INFOCHANGED 1 - -// force-send a PSN_INFOCHANGED to all pages -#define PSM_FORCECHANGED (WM_USER+100) - -class MIR_CORE_EXPORT CCtrlPages : public CCtrlBase -{ - typedef CCtrlBase CSuper; - - HIMAGELIST m_hIml; - CDlgBase *m_pActivePage; - int m_numRows = 1; - - struct TPageInfo; - void InsertPage(TPageInfo *pPage); - void ShowPage(CDlgBase *pDlg); - - void CheckRowCount(); - TPageInfo* GetCurrPage(); - TPageInfo* GetItemPage(int iPage); - LIST<TPageInfo> m_pages; - -public: - CCtrlPages(CDlgBase *dlg, int ctrlId); - - void AddPage(const wchar_t *ptszName, HICON hIcon, CDlgBase *pDlg); - void ActivatePage(int iPage); - int GetCount(void); - int GetDlgIndex(CDlgBase*); - void RemovePage(int iPage); - void SwapPages(int idx1, int idx2); - - CDlgBase* GetNthPage(int iPage); - - __forceinline CDlgBase* GetActivePage() const - { return m_pActivePage; - } - -protected: - BOOL OnNotify(int idCtrl, NMHDR *pnmh) override; - - void OnInit() override; - void OnDestroy() override; - - bool OnApply() override; - void OnReset() override; - - LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) override; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// CProtoDlgBase - -#define WM_PROTO_REFRESH (WM_USER + 100) -#define WM_PROTO_CHECK_ONLINE (WM_USER + 101) -#define WM_PROTO_ACTIVATE (WM_USER + 102) -#define WM_PROTO_LAST (WM_USER + 200) - -struct PROTO_INTERFACE; - -class MIR_APP_EXPORT CProtoIntDlgBase : public CDlgBase -{ - typedef CDlgBase CSuper; - -public: - CProtoIntDlgBase(PROTO_INTERFACE *proto, int idDialog); - - void CreateLink(CCtrlData &ctrl, const char *szSetting, uint8_t type, uint32_t iValue); - void CreateLink(CCtrlData &ctrl, const char *szSetting, wchar_t *szValue); - - template<class T> - __inline void CreateLink(CCtrlData &ctrl, CMOption<T> &option) - { - ctrl.CreateDbLink(new CMOptionLink<T>(option)); - } - - __inline PROTO_INTERFACE *GetProtoInterface() { return m_proto_interface; } - - void SetStatusText(const wchar_t *statusText); - -protected: - PROTO_INTERFACE *m_proto_interface; - MWindow m_hwndStatus = nullptr; - - INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override; - - virtual void OnProtoRefresh(WPARAM, LPARAM); - virtual void OnProtoActivate(WPARAM, LPARAM); - virtual void OnProtoCheckOnline(WPARAM, LPARAM); - -private: - void UpdateStatusBar(); -}; - -template<typename TProto> -class CProtoDlgBase : public CProtoIntDlgBase -{ - typedef CProtoIntDlgBase CSuper; - -public: - __inline CProtoDlgBase<TProto>(TProto *proto, int idDialog) : - CProtoIntDlgBase(proto, idDialog), - m_proto(proto) - { - } - - __inline TProto *GetProto() { return m_proto; } - -protected: - TProto* m_proto; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Safe open/close dialogs -#define UI_SAFE_OPEN(dlgClass, dlgPtr) \ - { \ - if (dlgPtr) \ - { \ - SetForegroundWindow((dlgPtr)->GetHwnd()); \ - } else \ - { \ - (dlgPtr) = new dlgClass(this); \ - (dlgPtr)->Show(); \ - } \ - } - -#define UI_SAFE_OPEN_EX(dlgClass, dlgPtr, dlgLocal) \ - if (dlgPtr) \ - { \ - ::SetForegroundWindow((dlgPtr)->GetHwnd()); \ - } else \ - { \ - (dlgPtr) = new dlgClass(this); \ - (dlgPtr)->Show(); \ - } \ - dlgClass *dlgLocal = (dlgClass *)(dlgPtr); - -#define UI_SAFE_CLOSE(dlg) \ - { \ - if (dlg) { \ - (dlg)->Close(); \ - (dlg) = NULL; \ - } \ - } - -#define UI_SAFE_CLOSE_HWND(hwnd) \ - { \ - if (hwnd) { \ - ::SendMessage((hwnd), WM_CLOSE, 0, 0); \ - (hwnd) = NULL; \ - } \ - } - -///////////////////////////////////////////////////////////////////////////////////////// -// NULL-Safe dialog notifications -#define UI_SAFE_NOTIFY(dlg, msg) \ - { \ - if (dlg) \ - ::SendMessage((dlg)->GetHwnd(), msg, 0, 0); \ - } - -#define UI_SAFE_NOTIFY_HWND(hwnd, msg) \ - { \ - if (hwnd) \ - ::SendMessage((hwnd), msg, 0, 0); \ - } - -///////////////////////////////////////////////////////////////////////////////////////// -// Define message maps -#define UI_MESSAGE_MAP(dlgClass, baseDlgClass) \ - typedef baseDlgClass CMessageMapSuperClass; \ - virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) \ - { \ - switch (msg) \ - { \ - case 0: \ - break /* just to handle ";" symbol after macro */ - -#define UI_MESSAGE(msg, proc) \ - case msg: \ - proc(msg, wParam, lParam); \ - break - -#define UI_MESSAGE_EX(msg, func) \ - case msg: \ - return func(msg, wParam, lParam) - -#define UI_POSTPROCESS_MESSAGE(msg, proc) \ - case msg: \ - CMessageMapSuperClass::DlgProc(msg, wParam, lParam); \ - return FALSE - -#define UI_POSTPROCESS_MESSAGE_EX(msg, func) \ - case msg: \ - CMessageMapSuperClass::DlgProc(msg, wParam, lParam); \ - return func(msg, wParam, lParam) - -#define UI_MESSAGE_MAP_END() \ - } \ - return CMessageMapSuperClass::DlgProc(msg, wParam, lParam); \ - } - -#endif // __M_GUI_H +/*
+
+Jabber Protocol Plugin for Miranda NG
+
+Copyright (c) 2002-04 Santithorn Bunchua
+Copyright (c) 2005-12 George Hazan
+Copyright (c) 2007-09 Maxim Mluhov
+Copyright (c) 2007-09 Victor Pavlychko
+Copyright (C) 2012-23 Miranda NG team
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#ifndef __M_GUI_H
+#define __M_GUI_H
+
+#ifdef _MSC_VER
+ #include <CommCtrl.h>
+#endif // _WINDOWS
+
+#include <m_system.h>
+#include <m_protoint.h>
+#include <m_clc.h>
+
+#pragma warning(disable:4355 4251 4481)
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// helpers for the option's visualization
+
+template<int Size>
+struct CMDBTraits
+{
+};
+
+template<>
+struct CMDBTraits<1>
+{
+ typedef uint8_t DBType;
+ enum { DBTypeId = DBVT_BYTE };
+ static __forceinline DBType Get(const char *szModule, const char *szSetting, DBType value)
+ {
+ return db_get_b(0, szModule, szSetting, value);
+ }
+ static __forceinline void Set(const char *szModule, const char *szSetting, DBType value)
+ {
+ db_set_b(0, szModule, szSetting, value);
+ }
+};
+
+template<>
+struct CMDBTraits<2>
+{
+ typedef uint16_t DBType;
+ enum { DBTypeId = DBVT_WORD };
+ static __forceinline DBType Get(const char *szModule, const char *szSetting, DBType value)
+ {
+ return db_get_w(0, szModule, szSetting, value);
+ }
+ static __forceinline void Set(const char *szModule, const char *szSetting, DBType value)
+ {
+ db_set_w(0, szModule, szSetting, value);
+ }
+};
+
+template<>
+struct CMDBTraits<4>
+{
+ typedef uint32_t DBType;
+ enum { DBTypeId = DBVT_DWORD };
+ static __forceinline DBType Get(const char *szModule, const char *szSetting, DBType value)
+ {
+ return db_get_dw(0, szModule, szSetting, value);
+ }
+ static __forceinline void Set(const char *szModule, const char *szSetting, DBType value)
+ {
+ db_set_dw(0, szModule, szSetting, value);
+ }
+};
+
+template<>
+struct CMDBTraits<8>
+{
+ typedef uint32_t DBType;
+ enum { DBTypeId = DBVT_DWORD };
+ static __forceinline DBType Get(const char *szModule, const char *szSetting, DBType value)
+ {
+ return db_get_dw(0, szModule, szSetting, value);
+ }
+ static __forceinline void Set(const char *szModule, const char *szSetting, DBType value)
+ {
+ db_set_dw(0, szModule, szSetting, value);
+ }
+};
+
+class CMOptionBase : public MNonCopyable
+{
+public:
+ __forceinline const char* GetDBModuleName() const { return m_szModuleName; }
+ __forceinline const char* GetDBSettingName() const { return m_szSetting; }
+
+ __forceinline void Delete() const
+ { db_unset(0, m_szModuleName, m_szSetting);
+ }
+
+protected:
+ __forceinline CMOptionBase(PROTO_INTERFACE *proto, const char *szSetting) :
+ m_szModuleName(proto->m_szModuleName), m_szSetting(szSetting)
+ {}
+
+ __forceinline CMOptionBase(const char *module, const char *szSetting) :
+ m_szModuleName(module), m_szSetting(szSetting)
+ {}
+
+ const char *m_szModuleName;
+ const char *m_szSetting;
+};
+
+template<class T>
+class CMOption : public CMOptionBase
+{
+public:
+ typedef T Type;
+
+ __forceinline CMOption(PROTO_INTERFACE *proto, const char *szSetting, Type defValue) :
+ CMOptionBase(proto, szSetting), m_default(defValue)
+ {}
+
+ __forceinline CMOption(const char *szModule, const char *szSetting, Type defValue) :
+ CMOptionBase(szModule, szSetting), m_default(defValue)
+ {}
+
+ __forceinline Type Default() const
+ {
+ return m_default;
+ }
+
+ __forceinline operator Type()
+ {
+ return (Type)CMDBTraits<sizeof(Type)>::Get(m_szModuleName, m_szSetting, m_default);
+ }
+
+ __forceinline Type operator= (Type value)
+ {
+ #ifdef _MSC_VER
+ CMDBTraits<sizeof(Type)>::Set(m_szModuleName, m_szSetting, (CMDBTraits<sizeof(Type)>::DBType)value);
+ #else
+ CMDBTraits<sizeof(Type)>::Set(m_szModuleName, m_szSetting, value);
+ #endif
+ return value;
+ }
+
+private:
+ Type m_default;
+};
+
+template<>
+class CMOption<char*> : public CMOptionBase
+{
+public:
+
+ typedef char Type;
+
+ __forceinline CMOption(PROTO_INTERFACE *proto, const char *szSetting, const Type *defValue = nullptr) :
+ CMOptionBase(proto, szSetting), m_default(defValue)
+ {}
+
+ __forceinline CMOption(const char *szModule, const char *szSetting, const Type *defValue = nullptr) :
+ CMOptionBase(szModule, szSetting), m_default(defValue)
+ {}
+
+ __forceinline const Type* Default() const
+ {
+ return m_default;
+ }
+
+ __forceinline operator Type*()
+ {
+ m_value = db_get_sa(0, m_szModuleName, m_szSetting);
+ if (!m_value) m_value = mir_strdup(m_default);
+ return m_value;
+ }
+
+ __forceinline Type* operator= (Type *value)
+ {
+ db_set_s(0, m_szModuleName, m_szSetting, value);
+ return value;
+ }
+
+private:
+ const Type *m_default;
+ mir_ptr<Type> m_value;
+};
+
+template<>
+class CMOption<wchar_t*> : public CMOptionBase
+{
+public:
+
+ typedef wchar_t Type;
+
+ __forceinline CMOption(PROTO_INTERFACE *proto, const char *szSetting, const Type *defValue = nullptr) :
+ CMOptionBase(proto, szSetting), m_default(defValue)
+ {}
+
+ __forceinline CMOption(const char *szModule, const char *szSetting, const Type *defValue = nullptr) :
+ CMOptionBase(szModule, szSetting), m_default(defValue)
+ {}
+
+ __forceinline const Type* Default() const
+ {
+ return m_default;
+ }
+
+ __forceinline operator Type*()
+ {
+ m_value = db_get_wsa(0, m_szModuleName, m_szSetting);
+ if (!m_value) m_value = mir_wstrdup(m_default);
+ return m_value;
+ }
+
+ __forceinline const Type* operator= (const Type *value)
+ {
+ db_set_ws(0, m_szModuleName, m_szSetting, value);
+ return value;
+ }
+
+private:
+ const Type *m_default;
+ mir_ptr<Type> m_value;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CDbLink
+
+class MIR_CORE_EXPORT CDataLink
+{
+protected:
+ uint8_t m_type;
+
+public:
+ __inline CDataLink(uint8_t type) : m_type(type) {}
+ virtual ~CDataLink() {}
+
+ __inline uint8_t GetDataType() const { return m_type; }
+
+ virtual uint32_t LoadInt() = 0;
+ virtual void SaveInt(uint32_t value) = 0;
+
+ virtual wchar_t* LoadText() = 0;
+ virtual void SaveText(wchar_t *value) = 0;
+};
+
+class MIR_CORE_EXPORT CDbLink : public CDataLink
+{
+ char *m_szModule;
+ char *m_szSetting;
+
+ uint32_t m_iDefault;
+ wchar_t *m_szDefault;
+
+ DBVARIANT dbv;
+
+public:
+ CDbLink(const char *szModule, const char *szSetting, uint8_t type, uint32_t iValue);
+ CDbLink(const char *szModule, const char *szSetting, uint8_t type, wchar_t *szValue);
+ ~CDbLink();
+
+ uint32_t LoadInt() override;
+ void SaveInt(uint32_t value) override;
+
+ wchar_t* LoadText() override;
+ void SaveText(wchar_t *value) override;
+};
+
+template<class T>
+class CMOptionLink : public CDataLink
+{
+private:
+ CMOption<T> *m_option;
+
+public:
+ __forceinline CMOptionLink(CMOption<T> &option) :
+ CDataLink(CMDBTraits<sizeof(T)>::DBTypeId), m_option(&option)
+ {}
+
+ __forceinline uint32_t LoadInt() override { return (uint32_t)(T)*m_option; }
+ __forceinline void SaveInt(uint32_t value) override { *m_option = (T)value; }
+
+ __forceinline wchar_t* LoadText() override { return nullptr; }
+ __forceinline void SaveText(wchar_t*) override {}
+};
+
+template<>
+class CMOptionLink<wchar_t*> : public CDataLink
+{
+private:
+ typedef wchar_t *T;
+ CMOption<T> *m_option;
+
+public:
+ __forceinline CMOptionLink(CMOption<T> &option) :
+ CDataLink(DBVT_WCHAR), m_option(&option)
+ {}
+
+ __forceinline uint32_t LoadInt() override { return 0; }
+ __forceinline void SaveInt(uint32_t) override { }
+
+ __forceinline wchar_t* LoadText() override { return *m_option; }
+ __forceinline void SaveText(wchar_t *value) override { *m_option = value; }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlBase
+
+struct CContextMenuPos
+{
+ const class CCtrlBase *pCtrl;
+ POINT pt;
+ union {
+ int iCurr; // int for list boxes
+ HTREEITEM hItem;
+ };
+};
+
+class MIR_CORE_EXPORT CCtrlBase
+{
+ friend class CDlgBase;
+
+ __forceinline CCtrlBase(const CCtrlBase&) = delete;
+ __forceinline CCtrlBase& operator=(const CCtrlBase&) = delete;
+
+public:
+ CCtrlBase(CDlgBase *wnd, int idCtrl);
+ virtual ~CCtrlBase();
+
+ __forceinline MWindow GetHwnd() const { return m_hwnd; }
+ __forceinline int GetCtrlId() const { return m_idCtrl; }
+ __forceinline CDlgBase *GetParent() const { return m_parentWnd; }
+ __forceinline bool IsChanged() const { return m_bChanged; }
+ __forceinline void SetSilent(bool bSilent = true) { m_bSilent = bSilent; }
+ __forceinline void UseSystemColors() { m_bUseSystemColors = true; }
+
+ void Show(bool bShow = true);
+ __forceinline void Hide() { Show(false); }
+
+ void Enable(bool bIsEnable = true);
+ __forceinline void Disable() { Enable(false); }
+ bool Enabled(void) const;
+
+ void NotifyChange();
+ void SetDraw(bool bEnable);
+
+ LRESULT SendMsg(UINT Msg, WPARAM wParam, LPARAM lParam) const;
+
+ void SetText(const wchar_t *text);
+ void SetTextA(const char *text);
+ void SetInt(int value);
+
+ wchar_t* GetText() const;
+ char* GetTextA() const;
+ char* GetTextU() const;
+
+ wchar_t* GetText(wchar_t *buf, size_t size) const;
+ char* GetTextA(char *buf, size_t size) const;
+ char* GetTextU(char *buf, size_t size) const;
+
+ int GetInt() const;
+
+ virtual BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t /*idCode*/) { return FALSE; }
+ virtual BOOL OnNotify(int /*idCtrl*/, NMHDR* /*pnmh*/) { return FALSE; }
+
+ virtual BOOL OnMeasureItem(MEASUREITEMSTRUCT*) { return FALSE; }
+ virtual BOOL OnDrawItem(DRAWITEMSTRUCT*) { return FALSE; }
+ virtual BOOL OnDeleteItem(DELETEITEMSTRUCT*) { return FALSE; }
+
+ virtual void OnInit();
+ virtual void OnDestroy();
+
+ virtual bool OnApply();
+ virtual void OnReset();
+
+protected:
+ MWindow m_hwnd = nullptr; // must be the first data item
+ int m_idCtrl;
+ bool m_bChanged = false, m_bSilent = false, m_bUseSystemColors = false, m_bNotifiable = false;
+ CDlgBase *m_parentWnd;
+
+public:
+ CCallback<CCtrlBase> OnChange;
+ CCallback<CContextMenuPos> OnBuildMenu;
+
+protected:
+ virtual void GetCaretPos(CContextMenuPos&) const;
+ virtual LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam);
+
+ void Subclass();
+ void Unsubclass();
+
+private:
+ static LRESULT CALLBACK GlobalSubclassWndProc(MWindow hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlData - data access controls base class
+
+class MIR_CORE_EXPORT CCtrlData : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+public:
+ CCtrlData(CDlgBase *dlg, int ctrlId);
+ ~CCtrlData();
+
+ void CreateDbLink(const char* szModuleName, const char* szSetting, uint8_t type, uint32_t iValue);
+ void CreateDbLink(const char* szModuleName, const char* szSetting, wchar_t* szValue);
+ void CreateDbLink(CDataLink *link) { m_dbLink = link; }
+
+ void OnInit() override;
+
+protected:
+ CDataLink *m_dbLink;
+
+ __inline uint8_t GetDataType() { return m_dbLink ? m_dbLink->GetDataType() : DBVT_DELETED; }
+ __inline uint32_t LoadInt() { return m_dbLink ? m_dbLink->LoadInt() : 0; }
+ __inline void SaveInt(uint32_t value) { if (m_dbLink) m_dbLink->SaveInt(value); }
+ __inline const wchar_t *LoadText() { return m_dbLink ? m_dbLink->LoadText() : L""; }
+ __inline void SaveText(wchar_t *value) { if (m_dbLink) m_dbLink->SaveText(value); }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CDlgBase - base dialog class
+
+class MIR_CORE_EXPORT CDlgBase
+{
+ friend class CTimer;
+ friend class CCtrlBase;
+ friend class CCtrlData;
+
+public:
+ CDlgBase(class CMPluginBase &pPlug, int idDialog);
+ virtual ~CDlgBase();
+
+ // general utilities
+ void Close();
+ void Resize();
+ void Create();
+ void Show(int nCmdShow = SW_SHOW);
+ int DoModal();
+ void EndModal(INT_PTR nResult);
+
+ class CCtrlBase* FindControl(int idCtrl);
+ class CCtrlBase* FindControl(MWindow hwnd);
+
+ void SetCaption(const wchar_t *ptszCaption);
+ void SetDraw(bool bEnable);
+ void NotifyChange(void); // sends a notification to a parent window
+
+ HINSTANCE GetInst() const;
+
+ __forceinline MWindow GetHwnd() const { return m_hwnd; }
+ __forceinline void Hide() { Show(SW_HIDE); }
+ __forceinline bool IsInitialized() const { return m_bInitialized; }
+ __forceinline void SetMinSize(int x, int y) { m_iMinWidth = x, m_iMinHeight = y; }
+ __forceinline void SetParent(MWindow hwnd) { m_hwndParent = hwnd; }
+
+ __forceinline CCtrlBase* operator[](int iControlId) { return FindControl(iControlId); }
+
+ static CDlgBase* Find(MWindow hwnd);
+
+protected:
+ MWindow m_hwnd = nullptr; // must be the first data item
+ MWindow m_hwndParent = nullptr;
+ int m_idDialog;
+
+ bool m_isModal = false;
+ bool m_bInitialized = false;
+ bool m_forceResizable = false;
+ bool m_bFixedSize;
+ bool m_bSucceeded = false; // was IDOK pressed or not
+ bool m_bExiting = false; // window received WM_CLOSE and gonna die soon
+
+ enum { CLOSE_ON_OK = 0x1, CLOSE_ON_CANCEL = 0x2 };
+ uint8_t m_autoClose; // automatically close dialog on IDOK/CANCEL commands. default: CLOSE_ON_OK|CLOSE_ON_CANCEL
+
+ CMPluginBase &m_pPlugin;
+
+ // override this handlers to provide custom functionality
+ // general messages
+ virtual bool OnInitDialog();
+ virtual bool OnApply();
+ virtual bool OnClose();
+ virtual void OnDestroy();
+
+ virtual void OnTimer(class CTimer*);
+
+ // miranda-related stuff
+ virtual int Resizer(UTILRESIZECONTROL *urc);
+ virtual void OnResize();
+ virtual void OnReset();
+ virtual void OnChange();
+
+ // main dialog procedure
+ virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam);
+
+ CCallback<void> m_OnFinishWizard;
+
+ // register controls
+ void AddControl(CCtrlBase *ctrl);
+ void RemoveControl(CCtrlBase *ctrl);
+
+ // timers
+ void AddTimer(CTimer *timer);
+ void RemoveTimer(UINT_PTR idEvent);
+
+ // options support
+ void CreateLink(class CCtrlData& ctrl, const char *szSetting, uint8_t type, uint32_t iValue);
+ void CreateLink(class CCtrlData& ctrl, const char *szSetting, wchar_t *szValue);
+
+ template<class T>
+ __inline void CreateLink(CCtrlData& ctrl, CMOption<T> &option)
+ {
+ ctrl.CreateDbLink(new CMOptionLink<T>(option));
+ }
+
+ // win32 stuff
+ void ThemeDialogBackground(BOOL tabbed);
+
+private:
+ LIST<CTimer> m_timers;
+ LIST<CCtrlBase> m_controls;
+
+ void NotifyControls(void (CCtrlBase::*fn)());
+ bool VerifyControls(bool (CCtrlBase::*fn)());
+
+ CTimer* FindTimer(int idEvent);
+ int m_iMinWidth = -1, m_iMinHeight = -1;
+
+ static BOOL CALLBACK GlobalFieldEnum(MWindow hwnd, LPARAM lParam);
+ static INT_PTR CALLBACK GlobalDlgProc(MWindow hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+ static int GlobalDlgResizer(MWindow hwnd, LPARAM lParam, UTILRESIZECONTROL *urc);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CTimer
+
+class MIR_CORE_EXPORT CTimer
+{
+ friend class CDlgBase;
+
+public:
+ CTimer(CDlgBase* wnd, UINT_PTR idEvent);
+ ~CTimer();
+
+ __forceinline UINT_PTR GetEventId() const { return m_idEvent; }
+ __forceinline MWindow GetHwnd() const { return m_wnd->GetHwnd(); }
+
+ virtual BOOL OnTimer();
+
+ void Start(int elapse);
+ bool Stop(); // returns true if timer was active
+
+ void StartSafe(int elapse);
+ void StopSafe();
+
+ CCallback<CTimer> OnEvent;
+
+protected:
+ UINT_PTR m_idEvent;
+ CDlgBase* m_wnd;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlLabel
+
+class MIR_CORE_EXPORT CCtrlLabel : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+public:
+ CCtrlLabel(CDlgBase *dlg, int ctrlId);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlButton
+
+class MIR_CORE_EXPORT CCtrlButton : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+public:
+ CCtrlButton(CDlgBase *dlg, int ctrlId);
+
+ BOOL OnCommand(MWindow hwndCtrl, uint16_t idCtrl, uint16_t idCode) override;
+
+ CCallback<CCtrlButton> OnClick;
+
+ void Click();
+ bool IsPushed() const;
+ void Push(bool bPushed);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlMButton
+
+class MIR_CORE_EXPORT CCtrlMButton : public CCtrlButton
+{
+ typedef CCtrlButton CSuper;
+
+public:
+ CCtrlMButton(CDlgBase *dlg, int ctrlId, HICON hIcon, const char* tooltip);
+ CCtrlMButton(CDlgBase *dlg, int ctrlId, int iCoreIcon, const char* tooltip);
+ ~CCtrlMButton();
+
+ void MakeFlat();
+ void MakePush();
+
+ void OnInit() override;
+
+protected:
+ HICON m_hIcon;
+ const char* m_toolTip;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CSplitter
+
+class MIR_CORE_EXPORT CSplitter : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+public:
+ CSplitter(CDlgBase *dlg, int ctrlId);
+
+ __forceinline int GetPos() const { return m_iPosition; }
+
+protected:
+ LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ void OnInit() override;
+
+ int m_iPosition;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlHyperlink
+
+class MIR_CORE_EXPORT CCtrlHyperlink : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+public:
+ CCtrlHyperlink(CDlgBase *dlg, int ctrlId, const char* url = nullptr);
+
+ BOOL OnCommand(MWindow hwndCtrl, uint16_t idCtrl, uint16_t idCode) override;
+
+ CCallback<CCtrlHyperlink> OnClick;
+
+ void SetUrl(const char *url);
+ const char *GetUrl();
+
+protected:
+ const char* m_url;
+
+ void Default_OnClick(CCtrlHyperlink*);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CProgress
+
+class MIR_CORE_EXPORT CCtrlProgress : public CCtrlBase
+{
+public:
+ CCtrlProgress(CDlgBase *dlg, int ctrlId);
+
+ void SetRange(uint16_t max, uint16_t min = 0);
+ void SetPosition(uint16_t value);
+ void SetStep(uint16_t value);
+ uint16_t Move(uint16_t delta = 0);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlClc
+
+#if !defined(MGROUP)
+ typedef int MGROUP;
+#endif
+
+class MIR_CORE_EXPORT CCtrlClc : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+public:
+ CCtrlClc(CDlgBase *dlg, int ctrlId);
+
+ void AddContact(MCONTACT hContact);
+ void AddGroup(HANDLE hGroup);
+ HANDLE AddInfoItem(CLCINFOITEM *cii);
+ void AutoRebuild();
+ void DeleteItem(HANDLE hItem);
+ void EditLabel(HANDLE hItem);
+ void EndEditLabel(bool save);
+ void EnsureVisible(HANDLE hItem, bool partialOk);
+ void Expand(HANDLE hItem, uint32_t flags);
+ HANDLE FindContact(MCONTACT hContact);
+ HANDLE FindGroup(MGROUP hGroup);
+ COLORREF GetBkColor() const;
+ bool GetCheck(HANDLE hItem) const;
+ int GetCount() const;
+ MWindow GetEditControl() const;
+ uint32_t GetExStyle() const;
+ uint32_t GetExpand(HANDLE hItem) const;
+ int GetExtraColumns() const;
+ uint8_t GetExtraImage(HANDLE hItem, int iColumn) const;
+ HIMAGELIST GetExtraImageList() const;
+ HFONT GetFont(int iFontId) const;
+ bool GetHideOfflineRoot() const;
+ int GetItemType(HANDLE hItem) const;
+ HANDLE GetNextItem(HANDLE hItem, uint32_t flags) const;
+ HANDLE GetSelection() const;
+ HANDLE HitTest(int x, int y, uint32_t *hitTest) const;
+ void SelectItem(HANDLE hItem);
+ void SetBkColor(COLORREF clBack);
+ void SetCheck(HANDLE hItem, bool check);
+ void SetExStyle(uint32_t exStyle);
+ void SetExtraColumns(int iColumns);
+ void SetExtraImage(HANDLE hItem, int iColumn, int iImage);
+ void SetExtraImageList(HIMAGELIST hImgList);
+ void SetFont(int iFontId, HANDLE hFont, bool bRedraw);
+ void SetItemText(HANDLE hItem, char *szText);
+ void SetHideEmptyGroups(bool state);
+ void SetHideOfflineRoot(bool state);
+ void SetOfflineModes(uint32_t modes);
+ void SetUseGroups(bool state);
+
+ struct TEventInfo
+ {
+ CCtrlClc *ctrl;
+ NMCLISTCONTROL *info;
+ };
+
+ CCallback<TEventInfo> OnExpanded;
+ CCallback<TEventInfo> OnListRebuilt;
+ CCallback<TEventInfo> OnItemChecked;
+ CCallback<TEventInfo> OnDragging;
+ CCallback<TEventInfo> OnDropped;
+ CCallback<TEventInfo> OnListSizeChange;
+ CCallback<TEventInfo> OnOptionsChanged;
+ CCallback<TEventInfo> OnDragStop;
+ CCallback<TEventInfo> OnNewContact;
+ CCallback<TEventInfo> OnContactMoved;
+ CCallback<TEventInfo> OnCheckChanged;
+ CCallback<TEventInfo> OnClick;
+
+protected:
+ BOOL OnNotify(int idCtrl, NMHDR *pnmh) override;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlCheck
+
+class MIR_CORE_EXPORT CCtrlCheck : public CCtrlData
+{
+ typedef CCtrlData CSuper;
+
+public:
+ CCtrlCheck(CDlgBase *dlg, int ctrlId);
+ BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t /*idCode*/) override;
+
+ bool OnApply() override;
+ void OnReset() override;
+
+ int GetState() const;
+ void SetState(int state);
+
+ bool IsChecked();
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlColor - color picker
+
+class MIR_CORE_EXPORT CCtrlColor : public CCtrlData
+{
+ typedef CCtrlData CSuper;
+
+public:
+ CCtrlColor(CDlgBase *dlg, int ctrlId);
+ BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t /*idCode*/) override;
+
+ bool OnApply() override;
+ void OnReset() override;
+
+ uint32_t GetColor();
+ void SetColor(uint32_t dwValue);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlDate - date & time picker
+
+class MIR_CORE_EXPORT CCtrlDate : public CCtrlData
+{
+ typedef CCtrlData CSuper;
+
+ BOOL OnNotify(int, NMHDR*) override;
+
+public:
+ CCtrlDate(CDlgBase *dlg, int ctrlId);
+
+ void GetTime(SYSTEMTIME*);
+ void SetTime(SYSTEMTIME*);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlEdit
+
+class MIR_CORE_EXPORT CCtrlEdit : public CCtrlData
+{
+ typedef CCtrlData CSuper;
+
+public:
+ CCtrlEdit(CDlgBase *dlg, int ctrlId);
+ BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t idCode) override;
+
+ bool OnApply() override;
+ void OnReset() override;
+
+ void SetMaxLength(unsigned int len);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlRichEdit
+
+class MIR_CORE_EXPORT CCtrlRichEdit : public CCtrlEdit
+{
+ typedef CCtrlEdit CSuper;
+
+public:
+ CCtrlRichEdit(CDlgBase *dlg, int ctrlId);
+
+ // returns text length in bytes if a parameter is omitted or in symbols, if not
+ int GetRichTextLength(int iCodePage = CP_ACP) const;
+
+ // returns a buffer that should be freed using mir_free() or ptrA/ptrW
+ char* GetRichTextRtf(bool bText = false, bool bSelection = false) const; // returns text with formatting
+ wchar_t* GetRichText() const; // returns only text in ucs2
+
+ // these methods return text length in Unicode chars
+ int SetRichText(const wchar_t *text);
+ int SetRichTextRtf(const char *text);
+
+ // enables or disables content editing
+ void SetReadOnly(bool bReadOnly);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlSlider
+
+class MIR_CORE_EXPORT CCtrlSlider : public CCtrlData
+{
+ typedef CCtrlData CSuper;
+
+ int m_wMin, m_wMax;
+
+protected:
+ BOOL OnCommand(MWindow hwndCtrl, uint16_t idCtrl, uint16_t idCode) override;
+
+public:
+ CCtrlSlider(CDlgBase *dlg, int ctrlId, int max = 100, int min = 0);
+
+ bool OnApply() override;
+ void OnReset() override;
+
+ int GetPosition() const;
+ void SetPosition(int pos);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlSpin
+
+class MIR_CORE_EXPORT CCtrlSpin : public CCtrlData
+{
+ typedef CCtrlData CSuper;
+
+ int16_t m_wMin, m_wMax, m_wCurr;
+
+ BOOL OnNotify(int, NMHDR*) override;
+
+public:
+ CCtrlSpin(CDlgBase *dlg, int ctrlId, int16_t max = 100, int16_t min = 0);
+
+ bool OnApply() override;
+ void OnReset() override;
+
+ int16_t GetPosition();
+ void SetPosition(int16_t pos);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlListBox
+
+class MIR_CORE_EXPORT CCtrlListBox : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+public:
+ CCtrlListBox(CDlgBase *dlg, int ctrlId);
+
+ int AddString(const wchar_t *text, LPARAM data=0);
+ void DeleteString(int index);
+ int FindString(const wchar_t *str, int index = -1, bool exact = false);
+ int GetCount() const;
+ int GetCurSel() const;
+ LPARAM GetItemData(int index) const;
+ int GetItemRect(int index, RECT *pResult) const;
+ wchar_t* GetItemText(int index) const;
+ wchar_t* GetItemText(int index, wchar_t *buf, int size) const;
+ bool GetSel(int index) const;
+ int GetSelCount() const;
+ int* GetSelItems(int *items, int count) const;
+ int* GetSelItems() const;
+ int InsertString(const wchar_t *text, int pos, LPARAM data=0);
+ void ResetContent();
+ int SelectString(const wchar_t *str);
+ int SetCurSel(int index);
+ void SetItemData(int index, LPARAM data);
+ void SetItemHeight(int index, int iHeight);
+ void SetSel(int index, bool sel = true);
+
+ // Events
+ CCallback<CCtrlListBox> OnDblClick;
+ CCallback<CCtrlListBox> OnSelCancel;
+ CCallback<CCtrlListBox> OnSelChange;
+
+protected:
+ BOOL OnCommand(MWindow hwndCtrl, uint16_t idCtrl, uint16_t idCode) override;
+ void GetCaretPos(CContextMenuPos&) const override;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlCombo
+
+class MIR_CORE_EXPORT CCtrlCombo : public CCtrlData
+{
+ typedef CCtrlData CSuper;
+
+public:
+ CCtrlCombo(CDlgBase *dlg, int ctrlId);
+
+ BOOL OnCommand(MWindow /*hwndCtrl*/, uint16_t /*idCtrl*/, uint16_t idCode) override;
+ void OnInit() override;
+ bool OnApply() override;
+ void OnReset() override;
+
+ // returns item data associated with the selected item or -1
+ LPARAM GetCurData() const;
+
+ // selects line with userdata passed. returns index of this line or -1
+ int SelectData(LPARAM data);
+
+ // Control interface
+ int AddString(const wchar_t *text, LPARAM data = 0);
+ int AddStringA(const char *text, LPARAM data = 0);
+ void DeleteString(int index);
+ int FindString(const wchar_t *str, int index = -1, bool exact = false);
+ int FindStringA(const char *str, int index = -1, bool exact = false);
+ int GetCount() const;
+ int GetCurSel() const;
+ bool GetDroppedState() const;
+ LPARAM GetItemData(int index) const;
+ wchar_t* GetItemText(int index) const;
+ wchar_t* GetItemText(int index, wchar_t *buf, int size) const;
+ int InsertString(const wchar_t *text, int pos, LPARAM data=0);
+ void ResetContent();
+ int SelectString(const wchar_t *str);
+ int SetCurSel(int index);
+ void SetItemData(int index, LPARAM data);
+ void ShowDropdown(bool show = true);
+
+ // Events
+ CCallback<CCtrlCombo> OnCloseup;
+ CCallback<CCtrlCombo> OnDropdown;
+ CCallback<CCtrlCombo> OnKillFocus;
+ CCallback<CCtrlCombo> OnSelChanged;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlListView
+
+class MIR_CORE_EXPORT CCtrlListView : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+public:
+ CCtrlListView(CDlgBase *dlg, int ctrlId);
+
+ // direction = -1 or 1. returns new item index
+ int MoveItem(int idx, int direction);
+
+ void SetCurSel(int idx);
+
+ // Classic LV interface
+ uint32_t ApproximateViewRect(int cx, int cy, int iCount);
+ void Arrange(UINT code);
+ void CancelEditLabel();
+ HIMAGELIST CreateDragImage(int iItem, POINT *lpptUpLeft);
+ void DeleteAllItems();
+ void DeleteColumn(int iCol);
+ void DeleteItem(int iItem);
+ MWindow EditLabel(int iItem);
+ int EnableGroupView(BOOL fEnable);
+ BOOL EnsureVisible(int i, BOOL fPartialOK);
+ int FindItem(int iStart, const LVFINDINFO *plvfi);
+ COLORREF GetBkColor() const;
+ void GetBkImage(LVBKIMAGE *plvbki) const;
+ UINT GetCallbackMask() const;
+ BOOL GetCheckState(UINT iIndex) const;
+ void GetColumn(int iCol, LVCOLUMN *pcol) const;
+ void GetColumnOrderArray(int iCount, int *lpiArray) const;
+ int GetColumnWidth(int iCol) const;
+ int GetCountPerPage() const;
+ MWindow GetEditControl() const;
+ uint32_t GetExtendedListViewStyle() const;
+ int GetFocusedGroup() const;
+ int GetGroupCount() const;
+ void GetGroupInfo(int iGroupId, LVGROUP *pgrp) const;
+ void GetGroupInfoByIndex(int iIndex, LVGROUP *pgrp) const;
+ void GetGroupMetrics(LVGROUPMETRICS *pGroupMetrics) const;
+ UINT GetGroupState(UINT dwGroupId, UINT dwMask) const;
+ MWindow GetHeader() const;
+ HCURSOR GetHotCursor() const;
+ int GetHotItem() const;
+ uint32_t GetHoverTime() const;
+ HIMAGELIST GetImageList(int iImageList) const;
+ BOOL GetInsertMark(LVINSERTMARK *plvim) const;
+ COLORREF GetInsertMarkColor() const;
+ int GetInsertMarkRect(RECT *prc) const;
+ BOOL GetISearchString(LPSTR lpsz) const;
+ bool GetItem(LVITEM *pitem) const;
+ int GetItemCount() const;
+ void GetItemPosition(int i, POINT *ppt) const;
+ void GetItemRect(int i, RECT *prc, int code) const;
+ uint32_t GetItemSpacing(BOOL fSmall) const;
+ UINT GetItemState(int i, UINT mask) const;
+ void GetItemText(int iItem, int iSubItem, LPTSTR pszText, int cchTextMax) const;
+ int GetNextItem(int iStart, UINT flags) const;
+ BOOL GetNumberOfWorkAreas(UINT *lpuWorkAreas) const;
+ BOOL GetOrigin(POINT *lpptOrg) const;
+ COLORREF GetOutlineColor() const;
+ UINT GetSelectedColumn() const;
+ UINT GetSelectedCount() const;
+ int GetSelectionMark() const;
+ int GetStringWidth(LPCSTR psz) const;
+ BOOL GetSubItemRect(int iItem, int iSubItem, int code, RECT *lpRect) const;
+ COLORREF GetTextBkColor() const;
+ COLORREF GetTextColor() const;
+ void GetTileInfo(LVTILEINFO *plvtinfo) const;
+ void GetTileViewInfo(LVTILEVIEWINFO *plvtvinfo) const;
+ MWindow GetToolTips() const;
+ int GetTopIndex() const;
+ BOOL GetUnicodeFormat() const;
+ uint32_t GetView() const;
+ BOOL GetViewRect(RECT *prc) const;
+ void GetWorkAreas(int nWorkAreas, RECT *lprc) const;
+ BOOL HasGroup(int dwGroupId);
+ int HitTest(LVHITTESTINFO *pinfo) const;
+ int HitTestEx(LVHITTESTINFO *pinfo);
+ int InsertColumn(int iCol, const LVCOLUMN *pcol);
+ int InsertGroup(int index, LVGROUP *pgrp);
+ void InsertGroupSorted(LVINSERTGROUPSORTED *structInsert);
+ int InsertItem(const LVITEM *pitem);
+ BOOL InsertMarkHitTest(POINT *point, LVINSERTMARK *plvim);
+ BOOL IsGroupViewEnabled();
+ UINT IsItemVisible(UINT index);
+ UINT MapIDToIndex(UINT id);
+ UINT MapIndexToID(UINT index);
+ BOOL RedrawItems(int iFirst, int iLast);
+ void RemoveAllGroups();
+ int RemoveGroup(int iGroupId);
+ BOOL Scroll(int dx, int dy);
+ BOOL SetBkColor(COLORREF clrBk);
+ BOOL SetBkImage(LVBKIMAGE *plvbki);
+ BOOL SetCallbackMask(UINT mask);
+ void SetCheckState(UINT iIndex, BOOL fCheck);
+ BOOL SetColumn(int iCol, LVCOLUMN *pcol);
+ BOOL SetColumnOrderArray(int iCount, int *lpiArray);
+ BOOL SetColumnWidth(int iCol, int cx);
+ void SetExtendedListViewStyle(uint32_t dwExStyle);
+ void SetExtendedListViewStyleEx(uint32_t dwExMask, uint32_t dwExStyle);
+ int SetGroupInfo(int iGroupId, LVGROUP *pgrp);
+ void SetGroupMetrics(LVGROUPMETRICS *pGroupMetrics);
+ void SetGroupState(UINT dwGroupId, UINT dwMask, UINT dwState);
+ HCURSOR SetHotCursor(HCURSOR hCursor);
+ int SetHotItem(int iIndex);
+ void SetHoverTime(uint32_t dwHoverTime);
+ uint32_t SetIconSpacing(int cx, int cy);
+ HIMAGELIST SetImageList(HIMAGELIST himl, int iImageList);
+ BOOL SetInfoTip(LVSETINFOTIP *plvSetInfoTip);
+ BOOL SetInsertMark(LVINSERTMARK *plvim);
+ COLORREF SetInsertMarkColor(COLORREF color);
+ BOOL SetItem(const LVITEM *pitem);
+ void SetItemCount(int cItems);
+ void SetItemCountEx(int cItems, uint32_t dwFlags);
+ BOOL SetItemPosition(int i, int x, int y);
+ void SetItemPosition32(int iItem, int x, int y);
+ void SetItemState(int i, UINT state, UINT mask);
+ void SetItemText(int i, int iSubItem, const wchar_t *pszText);
+ COLORREF SetOutlineColor(COLORREF color);
+ void SetSelectedColumn(int iCol);
+ int SetSelectionMark(int iIndex);
+ BOOL SetTextBkColor(COLORREF clrText);
+ BOOL SetTextColor(COLORREF clrText);
+ BOOL SetTileInfo(LVTILEINFO *plvtinfo);
+ BOOL SetTileViewInfo(LVTILEVIEWINFO *plvtvinfo);
+ MWindow SetToolTips(MWindow ToolTip);
+ BOOL SetUnicodeFormat(BOOL fUnicode);
+ int SetView(uint32_t iView);
+ void SetWorkAreas(int nWorkAreas, RECT *lprc);
+ int SubItemHitTest(LVHITTESTINFO *pInfo) const;
+ int SubItemHitTestEx(LVHITTESTINFO *plvhti);
+ BOOL Update(int iItem);
+
+ #ifdef _MSC_VER
+ int SortGroups(PFNLVGROUPCOMPARE pfnGroupCompare, LPVOID plv);
+ BOOL SortItems(PFNLVCOMPARE pfnCompare, LPARAM lParamSort);
+ BOOL SortItemsEx(PFNLVCOMPARE pfnCompare, LPARAM lParamSort);
+ #endif // _MSC_VER
+
+ // Additional APIs
+ HIMAGELIST CreateImageList(int iImageList);
+ void AddColumn(int iSubItem, const wchar_t *name, int cx);
+ void AddGroup(int iGroupId, const wchar_t *name);
+ int AddItem(const wchar_t *text, int iIcon, LPARAM lParam = 0, int iGroupId = -1);
+ void SetItem(int iItem, int iSubItem, const wchar_t *text, int iIcon = -1);
+ LPARAM GetItemData(int iItem) const;
+
+ // Events
+ struct TEventInfo {
+ CCtrlListView *treeviewctrl;
+ union {
+ NMHDR *nmhdr;
+ NMLISTVIEW *nmlv;
+ NMLVDISPINFO *nmlvdi;
+ NMLVSCROLL *nmlvscr;
+ NMLVGETINFOTIP *nmlvit;
+ NMLVFINDITEM *nmlvfi;
+ NMITEMACTIVATE *nmlvia;
+ NMLVKEYDOWN *nmlvkey;
+ NMLVCUSTOMDRAW *nmcd;
+ };
+ };
+
+ CCallback<TEventInfo> OnBeginDrag;
+ CCallback<TEventInfo> OnBeginLabelEdit;
+ CCallback<TEventInfo> OnBeginRDrag;
+ CCallback<TEventInfo> OnBeginScroll;
+ CCallback<TEventInfo> OnColumnClick;
+ CCallback<TEventInfo> OnCustomDraw;
+ CCallback<TEventInfo> OnDeleteAllItems;
+ CCallback<TEventInfo> OnDeleteItem;
+ CCallback<TEventInfo> OnClick;
+ CCallback<TEventInfo> OnDoubleClick;
+ CCallback<TEventInfo> OnEndLabelEdit;
+ CCallback<TEventInfo> OnEndScroll;
+ CCallback<TEventInfo> OnGetDispInfo;
+ CCallback<TEventInfo> OnGetInfoTip;
+ CCallback<TEventInfo> OnHotTrack;
+ CCallback<TEventInfo> OnIncrementalSearch;
+ CCallback<TEventInfo> OnInsertItem;
+ CCallback<TEventInfo> OnItemActivate;
+ CCallback<TEventInfo> OnItemChanged;
+ CCallback<TEventInfo> OnItemChanging;
+ CCallback<TEventInfo> OnKeyDown;
+ CCallback<TEventInfo> OnMarqueeBegin;
+ CCallback<TEventInfo> OnSetDispInfo;
+
+protected:
+ BOOL OnNotify(int idCtrl, NMHDR *pnmh) override;
+ void GetCaretPos(CContextMenuPos&) const override;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlTreeView
+
+#undef GetNextSibling
+#undef GetPrevSibling
+
+#define MTREE_CHECKBOX 0x0001
+#define MTREE_DND 0x0002
+#define MTREE_MULTISELECT 0x0004
+
+class MIR_CORE_EXPORT CCtrlTreeView : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+ HTREEITEM MoveItemAbove(HTREEITEM hItem, HTREEITEM hInsertAfter, HTREEITEM hParent);
+
+public:
+ CCtrlTreeView(CDlgBase *dlg, int ctrlId);
+
+ void SetFlags(uint32_t dwFlags); // MTREE_* combination
+
+ // Classic TV interface
+ HIMAGELIST CreateDragImage(HTREEITEM hItem);
+ void DeleteAllItems();
+ void DeleteItem(HTREEITEM hItem);
+ MWindow EditLabel(HTREEITEM hItem);
+ void EndEditLabelNow(BOOL cancel);
+ void EnsureVisible(HTREEITEM hItem);
+ void Expand(HTREEITEM hItem, uint32_t flag);
+ COLORREF GetBkColor() const;
+ uint32_t GetCheckState(HTREEITEM hItem) const;
+ HTREEITEM GetChild(HTREEITEM hItem) const;
+ int GetCount() const;
+ HTREEITEM GetDropHilight() const;
+ MWindow GetEditControl() const;
+ HTREEITEM GetFirstVisible() const;
+ HIMAGELIST GetImageList(int iImage) const;
+ int GetIndent() const;
+ COLORREF GetInsertMarkColor() const;
+ bool GetItem(TVITEMEX *tvi) const;
+ int GetItemHeight() const;
+ void GetItemRect(HTREEITEM hItem, RECT *rcItem, BOOL fItemRect) const;
+ uint32_t GetItemState(HTREEITEM hItem, uint32_t stateMask) const;
+ HTREEITEM GetLastVisible() const;
+ COLORREF GetLineColor() const;
+ HTREEITEM GetNextItem(HTREEITEM hItem, uint32_t flag) const;
+ HTREEITEM GetNextSibling(HTREEITEM hItem) const;
+ HTREEITEM GetNextVisible(HTREEITEM hItem) const;
+ HTREEITEM GetParent(HTREEITEM hItem) const;
+ HTREEITEM GetPrevSibling(HTREEITEM hItem) const;
+ HTREEITEM GetPrevVisible(HTREEITEM hItem) const;
+ HTREEITEM GetRoot() const;
+ uint32_t GetScrollTime() const;
+ HTREEITEM GetSelection() const;
+ COLORREF GetTextColor() const;
+ MWindow GetToolTips() const;
+ BOOL GetUnicodeFormat() const;
+ unsigned GetVisibleCount() const;
+ HTREEITEM HitTest(TVHITTESTINFO *hti) const;
+ HTREEITEM InsertItem(TVINSERTSTRUCT *tvis);
+ void Select(HTREEITEM hItem, uint32_t flag);
+ void SelectDropTarget(HTREEITEM hItem);
+ void SelectItem(HTREEITEM hItem);
+ void SelectSetFirstVisible(HTREEITEM hItem);
+ COLORREF SetBkColor(COLORREF clBack);
+ void SetCheckState(HTREEITEM hItem, uint32_t state);
+ HIMAGELIST SetImageList(HIMAGELIST hIml, int iImage);
+ void SetIndent(int iIndent);
+ void SetInsertMark(HTREEITEM hItem, BOOL fAfter);
+ COLORREF SetInsertMarkColor(COLORREF clMark);
+ void SetItem(TVITEMEX *tvi);
+ void SetItemHeight(short cyItem);
+ void SetItemState(HTREEITEM hItem, uint32_t state, uint32_t stateMask);
+ COLORREF SetLineColor(COLORREF clLine);
+ void SetScrollTime(UINT uMaxScrollTime);
+ COLORREF SetTextColor(COLORREF clText);
+ MWindow SetToolTips(MWindow hwndToolTips);
+ BOOL SetUnicodeFormat(BOOL fUnicode);
+ void SortChildren(HTREEITEM hItem, BOOL fRecurse);
+ void SortChildrenCB(TVSORTCB *cb, BOOL fRecurse);
+
+ // Additional stuff
+ void TranslateItem(HTREEITEM hItem);
+ void TranslateTree();
+ HTREEITEM FindNamedItem(HTREEITEM hItem, const wchar_t *name);
+ void GetItem(HTREEITEM hItem, TVITEMEX *tvi) const;
+ void GetItem(HTREEITEM hItem, TVITEMEX *tvi, wchar_t *szText, int iTextLength) const;
+ void InvertCheck(HTREEITEM hItem);
+
+ bool IsSelected(HTREEITEM hItem);
+ int GetNumSelected();
+ void GetSelected(LIST<_TREEITEM> &selected);
+
+ void Select(HTREEITEM hItem);
+ void Select(LIST<_TREEITEM> &selected);
+ void SelectAll();
+ void SelectRange(HTREEITEM hStart, HTREEITEM hEnd);
+
+ void Unselect(HTREEITEM hItem);
+ void UnselectAll();
+
+ void DropHilite(HTREEITEM hItem);
+ void DropUnhilite(HTREEITEM hItem);
+
+ // Events
+ struct TEventInfo {
+ CCtrlTreeView *treeviewctrl;
+ union {
+ NMHDR *nmhdr;
+ NMTREEVIEW *nmtv;
+ NMTVKEYDOWN *nmtvkey;
+ NMTVDISPINFO *nmtvdi;
+ NMTVGETINFOTIP *nmtvit;
+ NMTVCUSTOMDRAW *nmcd;
+ HTREEITEM hItem; // for OnItemChanged
+ };
+ };
+
+ CCallback<TEventInfo> OnBeginDrag;
+ CCallback<TEventInfo> OnBeginLabelEdit;
+ CCallback<TEventInfo> OnBeginRDrag;
+ CCallback<TEventInfo> OnCustomDraw;
+ CCallback<TEventInfo> OnDeleteItem;
+ CCallback<TEventInfo> OnEndLabelEdit;
+ CCallback<TEventInfo> OnGetDispInfo;
+ CCallback<TEventInfo> OnGetInfoTip;
+ CCallback<TEventInfo> OnItemChanged;
+ CCallback<TEventInfo> OnItemExpanded;
+ CCallback<TEventInfo> OnItemExpanding;
+ CCallback<TEventInfo> OnKeyDown;
+ CCallback<TEventInfo> OnRightClick;
+ CCallback<TEventInfo> OnSelChanged;
+ CCallback<TEventInfo> OnSelChanging;
+ CCallback<TEventInfo> OnSetDispInfo;
+ CCallback<TEventInfo> OnSingleExpand;
+
+protected:
+ void OnInit() override;
+ BOOL OnNotify(int idCtrl, NMHDR *pnmh) override;
+
+ void GetCaretPos(CContextMenuPos&) const override;
+ LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+
+ union {
+ uint32_t m_dwFlags;
+ struct {
+ bool m_bDndEnabled : 1;
+ bool m_bDragging : 1;
+ bool m_bCheckBox : 1;
+ bool m_bMultiSelect : 1;
+ };
+ };
+ HTREEITEM m_hDragItem; // valid if m_bDragging == true
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlTreeOpts - array of options with sections
+
+class MIR_CORE_EXPORT CCtrlTreeOpts : public CCtrlTreeView
+{
+ typedef CCtrlTreeView CSuper;
+
+public:
+ CCtrlTreeOpts(CDlgBase *dlg, int ctrlId);
+ ~CCtrlTreeOpts();
+
+ void AddOption(const wchar_t *pwszSection, const wchar_t *pwszName, CMOption<bool> &option);
+ void AddOption(const wchar_t *pwszSection, const wchar_t *pwszName, bool &option);
+ void AddOption(const wchar_t *pwszSection, const wchar_t *pwszName, uint32_t &option, uint32_t mask);
+
+ BOOL OnNotify(int idCtrl, NMHDR *pnmh) override;
+ void OnDestroy() override;
+ void OnInit() override;
+ bool OnApply() override;
+
+protected:
+ struct COptionsItem
+ {
+ const wchar_t *m_pwszSection, *m_pwszName;
+
+ union
+ {
+ CMOption<bool> *m_option;
+ bool *m_pBool;
+ struct
+ {
+ uint32_t *m_pDword;
+ uint32_t m_mask;
+ };
+ };
+
+ HTREEITEM m_hItem = nullptr;
+ enum OptionItemType { CMOPTION = 1, BOOL = 2, MASK = 3 };
+ OptionItemType m_type;
+
+ COptionsItem(const wchar_t *pwszSection, const wchar_t *pwszName, OptionItemType type) :
+ m_pwszSection(pwszSection),
+ m_pwszName(pwszName),
+ m_type(type)
+ {}
+ };
+
+ OBJLIST<COptionsItem> m_options;
+
+ void ProcessItemClick(HTREEITEM hti);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CCtrlPages
+
+#define PSN_INFOCHANGED 1
+
+// force-send a PSN_INFOCHANGED to all pages
+#define PSM_FORCECHANGED (WM_USER+100)
+
+class MIR_CORE_EXPORT CCtrlPages : public CCtrlBase
+{
+ typedef CCtrlBase CSuper;
+
+ HIMAGELIST m_hIml;
+ CDlgBase *m_pActivePage;
+ int m_numRows = 1;
+
+ struct TPageInfo;
+ void InsertPage(TPageInfo *pPage);
+ void ShowPage(CDlgBase *pDlg);
+
+ void CheckRowCount();
+ TPageInfo* GetCurrPage();
+ TPageInfo* GetItemPage(int iPage);
+ LIST<TPageInfo> m_pages;
+
+public:
+ CCtrlPages(CDlgBase *dlg, int ctrlId);
+
+ void AddPage(const wchar_t *ptszName, HICON hIcon, CDlgBase *pDlg);
+ void ActivatePage(int iPage);
+ int GetCount(void);
+ int GetDlgIndex(CDlgBase*);
+ void RemovePage(int iPage);
+ void SwapPages(int idx1, int idx2);
+
+ CDlgBase* GetNthPage(int iPage);
+
+ __forceinline CDlgBase* GetActivePage() const
+ { return m_pActivePage;
+ }
+
+protected:
+ BOOL OnNotify(int idCtrl, NMHDR *pnmh) override;
+
+ void OnInit() override;
+ void OnDestroy() override;
+
+ bool OnApply() override;
+ void OnReset() override;
+
+ LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// CProtoDlgBase
+
+#define WM_PROTO_REFRESH (WM_USER + 100)
+#define WM_PROTO_CHECK_ONLINE (WM_USER + 101)
+#define WM_PROTO_ACTIVATE (WM_USER + 102)
+#define WM_PROTO_LAST (WM_USER + 200)
+
+struct PROTO_INTERFACE;
+
+class MIR_APP_EXPORT CProtoIntDlgBase : public CDlgBase
+{
+ typedef CDlgBase CSuper;
+
+public:
+ CProtoIntDlgBase(PROTO_INTERFACE *proto, int idDialog);
+
+ void CreateLink(CCtrlData &ctrl, const char *szSetting, uint8_t type, uint32_t iValue);
+ void CreateLink(CCtrlData &ctrl, const char *szSetting, wchar_t *szValue);
+
+ template<class T>
+ __inline void CreateLink(CCtrlData &ctrl, CMOption<T> &option)
+ {
+ ctrl.CreateDbLink(new CMOptionLink<T>(option));
+ }
+
+ __inline PROTO_INTERFACE *GetProtoInterface() { return m_proto_interface; }
+
+ void SetStatusText(const wchar_t *statusText);
+
+protected:
+ PROTO_INTERFACE *m_proto_interface;
+ MWindow m_hwndStatus = nullptr;
+
+ INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+
+ virtual void OnProtoRefresh(WPARAM, LPARAM);
+ virtual void OnProtoActivate(WPARAM, LPARAM);
+ virtual void OnProtoCheckOnline(WPARAM, LPARAM);
+
+private:
+ void UpdateStatusBar();
+};
+
+template<typename TProto>
+class CProtoDlgBase : public CProtoIntDlgBase
+{
+ typedef CProtoIntDlgBase CSuper;
+
+public:
+ __inline CProtoDlgBase<TProto>(TProto *proto, int idDialog) :
+ CProtoIntDlgBase(proto, idDialog),
+ m_proto(proto)
+ {
+ }
+
+ __inline TProto *GetProto() { return m_proto; }
+
+protected:
+ TProto* m_proto;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Safe open/close dialogs
+#define UI_SAFE_OPEN(dlgClass, dlgPtr) \
+ { \
+ if (dlgPtr) \
+ { \
+ SetForegroundWindow((dlgPtr)->GetHwnd()); \
+ } else \
+ { \
+ (dlgPtr) = new dlgClass(this); \
+ (dlgPtr)->Show(); \
+ } \
+ }
+
+#define UI_SAFE_OPEN_EX(dlgClass, dlgPtr, dlgLocal) \
+ if (dlgPtr) \
+ { \
+ ::SetForegroundWindow((dlgPtr)->GetHwnd()); \
+ } else \
+ { \
+ (dlgPtr) = new dlgClass(this); \
+ (dlgPtr)->Show(); \
+ } \
+ dlgClass *dlgLocal = (dlgClass *)(dlgPtr);
+
+#define UI_SAFE_CLOSE(dlg) \
+ { \
+ if (dlg) { \
+ (dlg)->Close(); \
+ (dlg) = NULL; \
+ } \
+ }
+
+#define UI_SAFE_CLOSE_HWND(hwnd) \
+ { \
+ if (hwnd) { \
+ ::SendMessage((hwnd), WM_CLOSE, 0, 0); \
+ (hwnd) = NULL; \
+ } \
+ }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// NULL-Safe dialog notifications
+#define UI_SAFE_NOTIFY(dlg, msg) \
+ { \
+ if (dlg) \
+ ::SendMessage((dlg)->GetHwnd(), msg, 0, 0); \
+ }
+
+#define UI_SAFE_NOTIFY_HWND(hwnd, msg) \
+ { \
+ if (hwnd) \
+ ::SendMessage((hwnd), msg, 0, 0); \
+ }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Define message maps
+#define UI_MESSAGE_MAP(dlgClass, baseDlgClass) \
+ typedef baseDlgClass CMessageMapSuperClass; \
+ virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) \
+ { \
+ switch (msg) \
+ { \
+ case 0: \
+ break /* just to handle ";" symbol after macro */
+
+#define UI_MESSAGE(msg, proc) \
+ case msg: \
+ proc(msg, wParam, lParam); \
+ break
+
+#define UI_MESSAGE_EX(msg, func) \
+ case msg: \
+ return func(msg, wParam, lParam)
+
+#define UI_POSTPROCESS_MESSAGE(msg, proc) \
+ case msg: \
+ CMessageMapSuperClass::DlgProc(msg, wParam, lParam); \
+ return FALSE
+
+#define UI_POSTPROCESS_MESSAGE_EX(msg, func) \
+ case msg: \
+ CMessageMapSuperClass::DlgProc(msg, wParam, lParam); \
+ return func(msg, wParam, lParam)
+
+#define UI_MESSAGE_MAP_END() \
+ } \
+ return CMessageMapSuperClass::DlgProc(msg, wParam, lParam); \
+ }
+
+#endif // __M_GUI_H
|