summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2023-01-14 01:30:59 +0300
committerdartraiden <wowemuh@gmail.com>2023-01-14 01:30:59 +0300
commitde40f3be3f08487937525c2ef096dad665dda61d (patch)
treeeb1205f8dca7c30b561a2776f9527072bd92eaf1 /include
parentdd743899a769120ba2321230afddd6e4f1271872 (diff)
Convert sources to CR+LF
Diffstat (limited to 'include')
-rw-r--r--include/m_database.h1598
-rw-r--r--include/m_db_int.h814
-rw-r--r--include/m_gui.h3212
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