Title: The Bat! Common Plug-in Application Programming Interface (CP API) v1.12
Hello All,

Please find the updated The Bat! Common Plug-in Application Programming Interface (CP API) v1.12 document below. The document is also available at
https://www.ritlabs.com/download/files3/the_bat/doc/thebat-common-plugin-api-v1-12.rar


The Bat! Common Plug-in Application Programming Interface (CP API) v1.12
Copyright 2003-2017 Ritlabs, SRL. All rights reserved.
1. Abstract
Starting from version 2, The Bat! introduces possibility to expand its functionality by adding plug-in modules. This document describes the principles of how those modules are used and what functionality should/can be included in them.
2. Plug-in modules
A Plug-in module for The Bat! is a Win32 Dynamically Linked Library (DLL). The default file extension of general purpose Plug-in files is .TBP (TBP stands for The Bat! Plug-in).
Below is a set of functions that can be implemented in the Plug-in module (function names are case-sensitive):

TBP_Initialize
TBP_Finalize
TBP_GetName
TBP_GetVersion
TBP_GetStatus
TBP_GetInfo
TBP_NeedConfig
TBP_Setup
TBP_SetConfigData
TBP_GetConfigData
TBP_NeedCOM
TBP_GetSpamScore
TBP_FeedSpam
TBP_GetMacroList
TBP_ExecMacro
TBP_SetLibEntryPoints
TBP_NeedResave
TBP_SetCoreBridge

Minimum implementation level of a Plug-in includes the following functions:

TBP_GetName
TBP_GetStatus


3. Code conventions
3.1. Calling convention
All Plug-in functions must be implemented using standard Win32 API calling convention, which is defined as TBP_EXPORT in C and stdcall in Object Pascal
A code excerpt below defines TBP_Export for most popular C/C++ compilers:

// if we're in MS Visual C++
#ifdef _MSC_VER
#define TBP_EXPORT __stdcall
#endif

// if we're in Borland C++ Builder
#ifdef __BORLANDC__
#define TBP_EXPORT __stdcall
#endif

// if we're in Metrowerks CodeWarrior
#ifdef __MWERKS__
#define TBP_EXPORT __declspec(dllexport)
#endif

3.2. Thread safety
Any plug-in function can be called from different threads simultaneously, so all functions must be aware to multi-threaded model and provide appropriate level of protection of internal data. If a Plug-in author does not want to support full-blown multithreading, a simple workaround can be made by using critical sections (EnterCriticalSection at the start of a function and LeaveCriticalSection at the end, make sure the critical section is initialised at the DLL’s entry point or in the TBP_Initialize function and the code between EnterCriticalSection and LeaveCriticalSection is protected from exceptions).
The plug-in must not assume that the DllMain or TBP_Initialize or other functions will be called from the same thread or that these threads won’t be destroyed after calling these functions. The Bat! May call them from different threads and free the treads subsequently.
The Bat! version 5 and later supports TBP_MainWindowLoaded function to notify the plugin about the main thread. The only function that is called from the thread that The Bat! would not free while the program is running is TBP_MainWindowLoaded. This function is always called from the main thread (GUI thread) after the main window of The Bat! is loaded. The plugin must not assume that any of The Bat! windows or window handles exist prior to the TBP_MainWindowLoaded call.
3.3. Null-terminated strings
Unless it is explicitly specified, length of string buffers MUST NOT include the terminating null character and the terminating null character MUST NOT be added upon retrieval of any string data from Plug-ins.
3.4. “Buffer overrun” control
For safety sake, it is highly recommended not to use local array variables as buffers for retrieving data from objects provided by The Bat!  Buffers passed to Plug-in functions are dynamically allocated, but it is still highly recommended to pay special attention to the “buffer overrun” problem, so the program’s data stays safe.
3.5. String encoding
Since The Bat! version 7.4.16.17, encoding of all strings is UTF-8. Before that version, strings were encoded using the system-default codepage, configured via the “Language for non-Unicode programs” Windows Regional Settings option.
3.6. Data type sizes
The Bat! 32-bit version uses 32-bit plugins only, so is the 64-bit version of The Bat! – it can only use 64-bit versions of the plugins.
So, the size of the pointer types is 4 bytes under for The Bat! 32-bit and, respectively, 8 bytes for The Bat! 64-bit.
The size of integer types is always 4 bytes, regardless of the bitness of the plugin.
The size of char is always one byte, or 8 bits.
4. Programming languages
Any programming language can be used for creation of Plug-in modules as long as they can be used for creation of a Win32 DLL module, support name, call and thread safety conventions provided in this document.
This document provides function definitions in C/C++ and Object Pascal
5. Functions
5.1. General purpose functions.
Functions described in this section are common for all types of plug-ins. They are used for retrieving general information about a plug-in and providing a proper way to initialise, finalise and configure the plug-in.
5.1.1. TBP_Initialize
Syntax:

    C++:                     void WINAPI TBP_Initialize();

    Object Pascal:       procedure TBP_Initialize; stdcall;

Description:

This function is called upon initialization of the Plug-in. During The Bat! execution, it is called just once right after the Plug-in module is loaded. Use TBP_Initialize to initialize all internal data for proper functioning of the Plug-in.

Return values:

None. If an error occurs during a call to TBP_Initialize, and this error is critical to the Plug-in’s functionality, TBP_GetStatus must return an error code.


5.1.2. TBP_Finalize
Syntax:

    C++:                     void WINAPI TBP_Finalize();

    Object Pascal:       procedure TBP_Finalize; stdcall;

Description:

This function is called once before the Plug-in is unloaded from memory. Use TBP_Finalize for cleaning up memory, temporary files, etc.


Return values:

None.


5.1.3. TBP_GetName

Syntax:

   C++:                      int WINAPI TBP_GetName(char* ABuf, int ABufSize);

   Object Pascal:        function TBP_GetName(ABuf: PChar; ABufSize: Integer): Integer; stdcall;

Description:

This function is called in order to retrieve the name of the Plug-in.

Parameters:

ABuf
[out] Pointer to a string buffer that receives string specifying the name of the Plug-in. If ABuf is a null pointer, the function must return value is the required buffer size in bytes.
ABufSize
[in] Size of the string buffer identified by ABuf, in bytes. If the ABufSize is negative, the function must return value is the required buffer size in bytes.

Return values:

A positive value                     the number of bytes written in the ABuf or the required buffer size
Zero or a negative value         function is not supported


5.1.4. TBP_GetVersion

Syntax:

   C++:                      int WINAPI TBP_GetVersion(char* ABuf, int ABufSize);

   Object Pascal:        function TBP_GetVersion(ABuf: PChar; ABufSize: Integer): Integer; stdcall;

Description:

This function is called in order to retrieve the version name of the Plug-in. It is encouraged to add any valuable information about the current state of the Plug-in to the version name.

Parameters:

ABuf
[out] Pointer to a string buffer that receives the string specifying the version name of the Plug-in. If ABuf is a null pointer, the function must return value is the required buffer size in bytes.
ABufSize
[in] Size of the string buffer identified by ABuf, in bytes. If the ABufSize is negative, the function must return value is the required buffer size in bytes.

Return values:

A positive value                     the number of bytes written in the ABuf or the required buffer size
Zero or a negative value         function is not supported


5.1.5. TBP_GetStatus

Syntax:

   C++:                      int WINAPI TBP_GetStatus();

   Object Pascal:        function TBP_GetStatus: Integer; stdcall;

Description:

This function is called to determine whether the Plug-in is functioning properly.

Return values:

0                      the Plug-in is functioning properly
Non-zero         error code (will be logged)

5.1.6. TBP_GetInfo

Syntax:

   C++:                      int WINAPI TBP_GetInfo(char* ABuf, int ABufSize);

   Object Pascal:        function TBP_GetInfo(ABuf: PChar; ABufSize: Integer): Integer; stdcall;

Description:

This function is called in order to retrieve additional information about the Plug-in. This information will be displayed when a user clicks the “Information” button on the Plug-in configuration page.

Note: If the information text starts with the <HTML> tag, it is displayed as an HTML document.

Parameters:

ABuf
[out] Pointer to a string buffer that receives the string with information about the Plug-in. If ABuf is a null pointer, the function must return value is the required buffer size in bytes.
ABufSize
[in] Size of the string buffer identified by ABuf, in bytes. If the ABufSize is negative, the function must return value is the required buffer size in bytes.

Return values:

A positive value                     the number of bytes written in the ABuf or the required buffer size
Zero or a negative value         function is not supported


5.1.7. TBP_NeedConfig

Syntax:

   C++:                      int WINAPI TBP_NeedConfig();

   Object Pascal:        function TBP_NeedConfig: Integer; stdcall;

Description:

This function is called to determine whether the Plug-in can be configured within The Bat!  A user can configure Plug-ins by clicking the Configure button at the Plug-in configuration page.


Return values:

0                      the Plug-in cannot be configured within The Bat!
Non-zero         the Plug-in can be configured within The Bat!


5.1.8. TBP_Setup

Syntax:

   C++:                      int WINAPI TBP_Setup();

   Object Pascal:        function TBP_Setup: Integer; stdcall;

Description:

This function is called for configuring the Plug-in from The Bat! Plug-in configuration page by clicking the Configure button or right after installing the Plug-in. The TBP_Setup can be called by The Bat! only if the TBP_NeedConfig returned a non-zero value. The handle of the calling window can be retrieved by the GetActiveWindow Win32 API function.

Return values:

0                      the Plug-in was successfully configured
Non-zero         the Plug-in was not configured, possible error code (may be logged in future)


5.1.9. TBP_SetConfigData

Syntax:

   C++:                      int WINAPI TBP_SetConfigData(const void* ABuf, int ABufSize);

   Object Pascal:        function TBP_SetConfigData (const ABuf; ABufSize: Integer): Integer; stdcall;

Description:

This function is used for passing Plug-in configuration data stored in the Plug-in configuration file.

There are no any special requirements about the configuration data format; it is treated as a binary buffer that may contain any characters.

The TBP_SetConfigData is called when the Plug-in is loaded and initialised at the program’s start-up.

Parameters:

ABuf
[in] Pointer to a binary buffer that contains Plug-in configuration data.
ABufSize
[in] Size of the binary buffer identified by ABuf, in bytes.

Return values:

0                      function completed successfully
Non-zero         a failure occurred during execution of the function, error code (may be logged in future)


5.1.10. TBP_GetConfigData

Syntax:

   C++:                      int WINAPI TBP_GetConfigData(void* ABuf, int ABufSize);

   Object Pascal:        function TBP_GetConfigData (var ABuf; ABufSize: Integer): Integer; stdcall;

Description:


This function is used for retrieving Plug-in configuration data after the Plug-in is configured using the TBP_Setup function in order to store the data in the Plug-in configuration file.

There are no any special requirements about the configuration data format; it is treated as a binary buffer that may contain any characters.

The TBP_GetConfigData is called when the TBP_Setup function returns zero (i.e. when the plug-in was successfully configured).

Parameters:

ABuf
[out] Pointer to a binary buffer that receives configuration data from the Plug-in. If ABuf is a null pointer, the function must return value is the required buffer size in bytes.
ABufSize
[in] Size of the binary buffer identified by ABuf, in bytes. If the ABufSize is negative, the function must return value is the required buffer size in bytes.

Return values:

A positive value                     the number of bytes written in the ABuf or the required buffer size
Zero or a negative value         function is not supported


5.1.11. TBP_NeedCOM

Syntax:
fConfigNeeded
Description:

This function is called to determine whether the Plug-in requires COM subsystem initialisation, i.e. call to CoInitialize must be made before using functions of the Plug-in in a thread.

If the Plug-in implements functions working with the ITBPDataProvider interface, the return value of this function is ignored because it requires COM initialisation anyway.

Return values:

0                                  the Plug-in does not require COM
Any non-zero value    the Plug-in requires COM

5.1.12. TBP_SetCoreBridge
Syntax:

   C++:                       int WINAPI TBP_SetCoreBridge (ITBPCoreBridge* ABridge);

   Object Pascal:        function TBP_SetCoreBridge(ABridge: ITBPCoreBridge): Integer; stdcall;


Description:

ITBPCoreBridge is an interface that gives access to internal data of The Bat!. It gives access to mail items (mail accounts, folders, messages), windows (viewers, editors, address book),  and other data. It also allows you to call functionality of the S/MIME internal implementation of The Bat!, i.e. allows to sign, verify, encrypt and decrypt data).

This functionality is implemented since version 4.2.14 of The Bat!

The Bat! calls this function only once, during the startup of The Bat! The plugin should save the interface to call it later.

Detailed description of ITBPCoreBridge is given in a separate document.

Parameters:

ABridge
[in] The ITBPCoreBridge interface.

Return values:

The Bat! currently doesn’t check the return value of TBP_SetCoreBridge

5.1.13 TBP_MainWindowLoaded

Syntax:

   C++:                      int WINAPI TBP_ MainWindowLoaded();

   Object Pascal:        function TBP_ MainWindowLoaded: Integer; stdcall;

Description:

This function is called from the main thread (GUI thread) to notify the plugin that the main window of The Bat! is loaded.

This function is only supported from The Bat! version 5.


Return values:

The return value of this function is ignored.



5.2. Anti-spam

This section contains information about Anti-spam functions of Plug-ins.

5.2.1. TBP_GetSpamScore

Syntax:

   C++:                       int WINAPI TBP_GetSpamScore(int MsgID, TBPGetDataProc* GetData);

   Object Pascal:        function TBP_GetSpamScore(MsgID: Integer; GetData: TBPGetDataProc): Integer; stdcall;

Description:

This function calculates Spam Score of a message. TBP_GetSpamScore of each Plug-in is called when a message is about to be stored in the message base after it is received and the final score is calculated accordingly to the user settings. TBP_GetSpamScore must return a score out of 100 points assigned to the message by the Plug-in. Zero score means the message is considered as legitimate mail, 100 points means the message is surely spam. If the returned value is negative, The Bat! assumes that the message was not processed by the Plug-in and do not count the Plug-in in calculation of the final score for the given message (e.g. when two plug-ins are installed, if one of the Plug-ins returned -1 and the second one returned 80, the average score will be 80, if both Plug-ins returned -1, the average score is 0)

TBP_GetSpamScore can also be used for any preliminary processing of a message (for example, extracting some data from all incoming mail for storing into a database).

Parameters:

MsgID
          [in] the identifier of the message being processed. MsgID passed to the GetData function together with property identifier in order to retrieve required data from the message. This identifier is unique within The Bat! and cannot be reused after exit from TBP_GetSpamScore.
GetData
          [in] a pointer to the TBPGetDataProc function which is used for retrieving data from a message


Return values:

0-100                          Spam Score (out of 100) assigned to a message by the Plug-in
A negative value         the message was not processed

5.2.1. TBP_FeedSpam

Syntax:

   C++:                       int WINAPI TBP_FeedSpam(int MsgID, int IsSpam, TBPGetDataProc* GetData);

   Object Pascal:        function TBP_FeedSpam(MsgID, IsSpam: Integer; GetData: TBPGetDataProc): Integer; stdcall;

Description:

This function may be provided by the Plug-in in order to “educate” the Plug-in about spam and non-spam messages accordingly to the user’s preferences. TBP_FeedSpam is called when a user selects messages and uses the “Mark as Junk” or “Mark as not Junk” command.

Implementation of TBP_FeedSpam is optional and depends on algorithms used for detecting spam.

A plug-in must store collected data separately from its configuration data that can be received by TBP_GetConfigData

Parameters:

MsgID
          [in] the identifier of the message being processed. MsgID passed to the GetData function together with property identifier in order to retrieve required data from the message. This identifier is unique within The Bat! and cannot be reused after exit from TBP_FeedSpam.
IsSpam
          [in] if IsSpam is not zero, the message is considered as spam, otherwise the message is legitimate
GetData
          [in] a pointer to the TBPGetDataProc function which is used for retrieving data from a message


Return values:

0                      the Plug-in collected new data from the message
Non-zero         the message was not processed or no new data was collected from it


5.2.3. TBPGetDataProc callback function


Syntax:

   C++:                       typedef int (WINAPI TBPGetDataProc)(int MsgID, int DataID, char* ABuf, int ABufSize);

   Object Pascal:        TBPGetDataProc = function(MsgID, DataID: Integer; ABuf: PChar; ABufSize: Integer): Integer; stdcall;

Description:

A TBPGetDataProc callback function is passed as a parameter to TBP_GetSpamScore and
TBP_FeedSpam functions in order to provide access to data of the message being processed.
It is possible to get virtually all data from a message by calling this function without need to parse the “raw” message source.

The data returned by this function may be characterised as text (some parts may be encoded accordingly to various standards, though)

Parameters:

MsgID
          [in] the identifier of the message being processed.
DataID
          [in] the identifier of message property to be retrieved. See the table of possible property identifiers in p. 5.2.4
ABuf
          [out] a pointer to the string buffer that receives data of the item identified by DataID; if Buf is a null pointer, TBPGetDataProc returns the required buffer size.
ABufSize
          [in] size of the string buffer identified by ABuf, in bytes; if ABufSize is negative, TBPGetDataProc returns the required buffer size.

Return values:

0 or a positive value    the number of bytes written in the buffer identified by Buf or the requires buffer size
Negative value            the function failed or the item identified by DataID does not exist


5.2.4. Message Property Identifiers

The table below describes currently defined message property identifiers
                           
Name
Value
Used for retrieving…
mpidMessageHeader
100000
RFC 822 message header
mpidMessageBodyA
100001
Decoded message text converted into Windows local code page. This property is obsolete, please use mpidMessageBodyW.
mpidMessageAttachmentsA
100002
List of attachments separated by null character, converted into Windows local code page. The end of the list is determined by double null character. This property is obsolete, please use mpidMessageBodyW.
mpidMessageSenderA
100003
Decoded list of senders converted into Windows local code page. This property is obsolete, please use mpidMessageSenderW.
mpidMessageSubjectA
100004
Decoded message subject converted into Windows local code page. This property is obsolete, please use mpidMessageSubjectW.
mpidRawMessage
100005
The entire message source without any conversion made. This may be useful if the Plug-in parses messages by itself.
mpidReceivedDate
100006
The date and time when the message was received (stored to the message base). The format is Win32 SYSTEMTIME structure, given in local time.
mpidMessageAttachmentsW
100007
List of attachments separated by CR character. The end of the list is determined by double CR character. The string is in the UTF-16 encoding.
mpidMessageBodyW
100008
Decoded message text in the UTF-16 encoding.
mpidMessageSenderW
100009
Decoded list of senders in the UTF-16 encoding.
mpidMessageSubjectW
100010
Decoded message subject in UTF-16 encoding.


Other identifiers that can be used by the Plug-in (with self-descriptive names and values) are:

   midxSubject          1
   midxDate             2
   midxComment          3
   midxInReplyTo        4
   midxMessageID        5
   midxNewsgroups       6
   midxMailer           7
   midxContentType      8
   midxContentSubType   9
   midxExpireDate      10
   midxOrganization    11
   midxContentID       12
   midxContentMD5      13
   midxPriority        14
   midxImportance      15
   midxContentLocation 16
   midxEncoding        17
   midxCharset         18
   midxBoundary        19
   midxMsgEncoding     20
   midxC_Name          21
   midxCD_Name         22
   midxReportType      23
   midxReferences      24
   midxC_Description   25
   midxContentDisposition 26
   midxContentLanguage  27
   midxC_ID             29
   midxC_AccessType     30
   midxC_Expiration     31
   midxC_Size           32
   midxC_Permission     33
   midxC_Site           34
   midxC_Directory      35
   midxC_Mode           36
   midxC_Server         37
   midxC_Subject        38
   midxReturnPath       41
   midxFromName         42
   midxFromAddr         43
   midxReplyName        44
   midxReplyAddr        45
   midxToName           46
   midxToAddr           47
   midxServerID         48
   midxRRC              49
   midxRRQ              50
   midxFileSubst        51
   midxC_Number         52
   midxC_Total          53
   midxMDN_To           55
   midxMDN_Options      56
   midxRefList          57
   midxC_MICAlg         58
   midxC_SMIMEType      59
   midxC_Protocol       60
   midxC_ProtocolType   61
   midxC_ProtocolSubType 62
   midxMatter           63
   midxListHelp         64
   midxListUnsub        65
   midxListSub          66
   midxListPost         67
   midxListOwner        68
   midxListArchive      69
   midxDecodedFrom      70
   midxDecodedTo        71
   midxDecodedSubj      72
   midxDecodedToEtc     73
   midxFrom             74
   midxTo               75
   midxCC               76
   midxBCC              77
   midxReplyTo          78
   midxSender           79
   midxXSender          80
   midxImapURL          81
   midxMailChat         82
   midxMailingList      83
   midxC_Format         84
   midxC_Type           85
   midxC_Min            86
   midxC_Max            87
   midxC_Mandatory      88
   midxImapSize         89
   midxC_CrType         90
   midxExValName        91
   midxDefValue         92
   midxOrigRcpt         93
   midxCIntData         94
   midxCSpScope         95
   midxCLoadFrom        96
   midxCSaveTo          97
   midxSpScope          98
   midxLoadFrom         99
   midxSaveTo          100
   midxSendDelay       108 // See the %POSTPONE macro  
   midxSendDelayEvent  109
   midxTags            112
   midxRefferedMsgURL  113
   midxDecodedFromUTF8 114
   midxDecodedToUTF8   115
   midxDecodedSubjUTF8 116
   midxDecodedToEtcUTF8 117
   midxRSSFeedURL      118
   midxRSSItemLink     120

Note: “midxC_” identifiers are used for retrieving values of corresponding Content-Type parameters.

5.3. Custom macros

This sections describes functions for adding new macros to the existing set of template macros (see The Bat! Help to find out the list of built-in macros)
5.3.1. TBP_GetMacroList

Syntax:

   C++:                      int WINAPI TBP_GetMacroList(char* ABuf, int ABufSize);

   Object Pascal:        function TBP_GetMacroList(ABuf: PChar; ABufSize: Integer): Integer; stdcall;

Description:
This function is called in order to retrieve the CR LF – separated list of macros implemented in the Plug-in. This list is used by The Bat! Template Processor to find the plug-in that implements an unknown macro. Note that Plug-ins cannot overwrite any of built-in macros, so before giving macro a name, the implementer should make sure the names of new macros do not conflict with existing ones.
Name of macro may contain any number of characters; the set of allowed characters is restricted to Latin letters (A-Z), decimal digits (0-9) and the underscore character ( _ ). Macro names are case insensitive.
Parameters:
ABuf
[out] Pointer to a string buffer that receives the string containing list of macros implemented by the Plug-in separated by CR LF pair. If ABuf is a null pointer, the function must return value is the required buffer size in bytes.
ABufSize
[in] Size of the string buffer identified by ABuf, in bytes. If the ABufSize is negative, the function must return value is the required buffer size in bytes.

Return values:

A positive value                     the number of bytes written in the ABuf or the required buffer size
Zero or a negative value         function is not supported


5.3.2. TBP_ExecMacro

Syntax:

   C++:                       int WINAPI TBP_ExecMacro(char* AMacro, int MaxLen, ITBPDataProvider* Template, ITBPDataProvider* Params): Integer; stdcall;

   Object Pascal:        function TBP_ExecMacro(AMacro: PChar; MaxLen: Integer; Template, Params: ITBPDataProvider): Integer; stdcall;

Description:

This function is called each time the Template Processor executes a macro listed by the Plug-in.  The Plug-in should execute the macro accordingly to its rules and return either the index in the Template object where the replacing text should be taken from or negative value if macro is replaced by empty string.

Parameters:

AMacro
[in] Pointer to a string buffer that contains the null-terminated string specifying the name of the macro to be executed.
MaxLen
[in] Maximum length of the macro name located in AMacro.
Template
[in] Pointer to the Template Processor object; p. 5.3.3 specifies the list of property identifiers that could be used for setting and retrieving information. The Template.ExecuteMacro method can be used for execution of simple templates (this is especially useful for retrieving information from the address book using %ABnnnPPP macros, use of regular _expression_ macros, setting custom message header fields), the OutData object is used for passing back the result of template execution, the data index of the result is 0.
Params
[in] Pointer to the parameter list object. The Params.ItemCount method returns the number of parameters passed to the macro. To retrieve parameters, use call to Params.GetDataByID(Index,…), where Index specifies the zero-based index of a parameter. Note that parameters passed to the macro are templates themselves, they are executed once when and only if they are retrieved by using the Params.GetDataByID method.

Return values:

0 or positive value                  The index in the Template object where the resulting string should be taken from
Negative value                       Macro was executed but in should be replaced by empty string


5.3.3. TBP_SetLibEntryPoints

Syntax:

   C++:                       int WINAPI TBP_SetLibEntryPoints (void *AData, int ANumPoints);

   Object Pascal:        function TBP_SetLibEntryPoints(const AData: Pointer; const ANumPoints: Integer): Integer; stdcall;


Description:

Sometimes a plugin may need access to functions already implemented in The Bat!, e.g. memory-allocation routines, a library that implements Perl-Compatible Regular Expressions, etc.

This function is called before TBP_Initialize in order to pass entry points to the functions above mentioned to the plugin. The plugin should save entry points of the functions to call them later.
This function is called from The Bat! 3.60.04 and higher.

Please see the complete list of the functions that The Bat! provides to the plugin in the separate document “LibEntryPoints”.

Parameters:

AData
[in] Pointer to the array of pairs of entry point. Each pair consist of a 32-bit DWORD of the function ID and 32-bit or 64-bit pointer to the function entry point. This yields to 8 bytes for each pair for a 32-bit process and 12 bytes for a 64-bit process. Please see the complete list of the IDs of functions that The Bat! provides in the separate document “LibEntryPoints”.
ANumPoints
[in] Number of 8-byte (or 12-byte) pairs passed in AData.

Return values:

The Bat! currently doesn’t check the return value of TBP_SetLibEntryPoints

5.3.4. TBP_NeedResave

Syntax:

   C++:                       BOOL int WINAPI TBP_NeedResave (void);

   Object Pascal:        function TBP_NeedResave:BOOL; stdcall;

This function is called when the plug-in is just loaded, it should return TRUE when The Bat! should retrieve plug-in's configuration data and save it right away. This function is not called when the plug-in is added (TBP_NeedConfig is called instead), so this may be helpful sometimes for distinction of two ways of loading a plug-in.

The logic of this function is can be illustrated by the following code:

if (TBP_NeedResave)
{
TBP_GetConfigData();
TBPIni.WriteStr(....)
}

5.3.5. Template object index

Below is the list of indexes that can be used for setting and retrieving information of a Template object passed to TBP_ExecMacro . Index names are considered as self-explanatory.

String indexes (string data can be accessed by ITBPDataProvider::GetDataByID and ITBPDataProvider::SetDataByID):

tpxQuotePrefix        200  // Current quotation prefix as it appears in text
tpxCharset            211
tpxAccount            214
tpxFrom               215
tpxReplyTo            216
tpxReturnPath         217
tpxTo                 218
tpxCC                 219
tpxBCC                220
tpxOrg                221
tpxSubject            222
tpxFullSubject        223
tpxComment            224
tpxOldTo              225
tpxOldFrom            226
tpxOldReplyTo         227
tpxOldCC              228
tpxOldBCC             229
tpxOldSubject         230
tpxOldComment         231
tpxMatter             232
tpxOldMatter          233
tpxMsgID              234
tpxOldMsgID           235
tpxOldDate            236
tpxOldRcvDate         237
tpxOldReturn          238
tpxOldOrg             239
tpxOldText            240
tpxText               241  // Text of the original message (selected part when initiated by “Reply quoting selected text” command)
tpxHeaders            243
tpxAttachments        244
tpxOldAttachments     245
tpxOldCharset         247
tpxTracking           248  // Message tracking number
tpxQuoteStyle         249  // Defined quotation style, empty string
tpxRegExpPattern      251
tpxRegExpText         252
tpxFullText           254  // Full text of original message
tpxLastAddress        257
tpxCursorHeader       261
tpxReferences         265
tpxOldRefs            266
tpxIncludeMask        279
tpxEventText          281
tpxHtmlTextA          283
tpxHtmlCharsetA       284
tpxMemo               286
tpxDelay              290   // See the %POSTPONE macro  
tpxTags               300

Integer and Boolean indexes (32-bit integer data can be accessed by ITBPDataProvider::GetIntValue and ITBPDataProvider::SetIntValue). For Boolean data, 0 value mean False, any non-zero integer means True.

Index ID Type Meaning
tpxWrapJustify 201 Boolean If True, all subsequent calls to the %Wrapped macro will produce wrapped text aligned by both left and right edges
tpxClear 202 Boolean If True, the text produced by calling template will completely replace the text in the message editor
tpxIsSignature 203 Boolean If True, the text produced by calling template will replace the current signature in the message editor
tpxSignComplete 204 Integer < 0       Do not sign message on completion
0          Use default signing settings
> 0       Sign message on completion
tpxEncryptComplete 205 Integer < 0      Do not encrypt message on completion
0          Use default settings
> 0       Encrypt message on completion
tpxUseSMIME 206 Integer < 0       Do not to use S/MIME
0          Use default settings
> 0       Use S/MIME
tpxUsePGP 207 Integer < 0       Do not to use OpenPGP
0          Use default settings
> 0       Use OpenPGP
tpxRCR 208 Integer < 0       Do not request Reading Confirmation
0          Use default settings
> 0       Request Reading Confirmation
tpxRRQ 209 Integer < 0       Do not request Confirm Receipt
0          Use default settings
> 0       Request Confirm Receipt
tpxSplit 210 Integer < 0       Do not split large message
0          Use default settings
> 0       Split large message
tpxPriority 212 Integer < 0       Message priority is Low
0          Message priority is Normal
> 0       Message priority is High
tpxTotalPages 262 Integer (Printing  header/footer only) Total number of pages
tpxCurrentPage 263 Integer (Printing header/footer only) The current page number
tpxFullTextDifferent 259 Boolean True if data items identified by tpxText and tpxFullText are different, false otherwise.
tpxCursorBody 260 Intege 1 – cursor should be positioned in message body
100 – cursor was positioned, but not in the body
tpxEditorType 276 Integer See the %SETEDITOR macro
tpxIncludeOriginal 277 Integer See the %ATTACHORIGINAL macro
tpxOriginalNoAttach 278 Integer See the %NoOriginalAttachments macro
tpxIncludeOriginalHeader 280 Boolean See the %crcATTACHORIGINALHeader
tpxEventText 281

tpxTextSet 282

tpxHtmlTextA 283

tpxHtmlCharsetA 284

tpxPGPmode 285

tpxMemo 286

tpxBasePos 287

tpxHasAttachMacro 288

tpxIgnoreSeparator 289

tpxDelay 290
See the %POSTPONE macro
tpxTags 300

tpxOldTags 301


Note about using ITBPDataProvider::SetDataByID: try to use ITBPDataProvider::ExecuteMacro method for setting standard template properties wherever it is possible.


6. ITBPDataProvider – the universal interface for data exchange

ITBPDataProvider
is the universal interface for exchanging data and commands between The Bat! and Plug-ins. This interface is supported by all The Bat! objects that are or will be accessible by a Plug-in to maintain simplicity (and thus reliability) of communication with Plug-ins.

Syntax:

C++:
interface DECLSPEC_UUID("9DD91B89-A551-4180-8A81-2CCF584CD4BF") ITBPDataProvider : public IUnknown  
{
   virtual int WINAPI GetDataByID(int ID, char* ABuf, int ABufSize) = 0;
  virtual int WINAPI SetDataByID(int ID, char* ABuf, int ABufSize) = 0;
  virtual int WINAPI GetIntValue(int ID) = 0;
  virtual int WINAPI SetIntValue(int ID, int Value) = 0;
  virtual int WINAPI GetIDType(int ID) = 0;
  virtual int WINAPI ItemCount() = 0;
  virtual HRESULT WINAPI ExecuteMacro(char* AMacro, int MaxLen, ITBPDataProvider* InData, ITBPDataProvider* OutData) = 0;
}


Object Pascal:

ITBPDataProvider = interface ['{9DD91B89-A551-4180-8A81-2CCF584CD4BF}']
  function GetDataByID(ID: Integer; ABuf: PChar; ABufSize: Integer): Integer; stdcall;
  function SetDataByID(ID: Integer; ABuf: PChar; ABufSize: Integer): Integer; stdcall;
  function GetIntValue(ID: Integer): Integer; stdcall;
  function SetIntValue(ID, Value: Integer): Integer; stdcall;
  function GetIDType(ID: Integer): Integer; stdcall;
  function ItemCount: Integer; stdcall;
  function ExecuteMacro(AMacro: Pointer; MaxLen: Integer; InData, OutData: ITBPDataProvider): HResult; stdcall;
end;


6.1.  ITBPDataProvider::GetDataByID

Syntax:

C++:                virtual int WINAPI GetDataByID(int ID, char* ABuf, int ABufSize);

Object Pascal: function GetDataByID(ID: Integer; ABuf: PChar; ABufSize: Integer): Integer; stdcall;

Description:

This function is used for retrieving text data from the object. Each object’s readable property should be available at least for reading by using this function. Format of data being received is determined by the type returned by the GetIDType method and described in p. 6.5

Parameters:

ID
[in] Identifier of the property to be retrieved.
ABuf
[out] Pointer to a string buffer that receives property data. If ABuf is a null pointer, the function must return value is the required buffer size in bytes.
ABufSize
[in] Size of the string buffer identified by ABuf, in bytes. If the ABufSize is negative, the function must return value is the required buffer size in bytes.


Return values:

Zero or a positive value          the number of bytes written in the ABuf or the required buffer size
A negative value                    function is not supported


6.2. ITBPDataProvider::SetDataByID
Syntax:
C++:         virtual int WINAPI SetDataByID(int ID, char* ABuf, int ABufSize);

Object Pascal:  function SetDataByID(ID: Integer; ABuf: PChar; ABufSize: Integer): Integer; stdcall;

Description:

This function is used for assigning data to object properties. . Format of data that could be stored into the property is determined by the type returned by the GetIDType method.

Note: some objects many provide read-only access to their properties.

Parameters:

ID
[in] Identifier of the property to be changed.
ABuf
[in] Pointer to a memory buffer that contains property data.
ABufSize
[in] Size of the memory buffer identified by ABuf, in bytes.


Return values:

Zero or a positive value          the number of bytes written into the target property
A negative value                    function is not supported


6.3. ITBPDataProvider::GetIntValue

Syntax:

C++:         virtual int WINAPI GetIntValue(int ID);

Object Pascal: function GetIntValue(ID: Integer): Integer; stdcall;

Description:

This function returns integer value of a property. Even when a property is not numeric, it is encouraged that implementations tried to convert stored data into numeric format. For example if a string property is ‘1001’, the result of GetIntValue with the ID if this property should be 1001. Boolean data should be converted into integer values accordingly to common conventions (0 means False, non-zero value means True)

Parameters:

ID
[in] Identifier of the property to be retrieved.

Return values:

The function must always return the value corresponding to the property ID. For non-existing properties, zero (0) must be returned

6.4. ITBPDataProvider::SetIntValue

Syntax:

C++:         virtual int WINAPI SetIntValue(int ID, int Value);

Object Pascal: function SetIntValue(ID, Value: Integer): Integer; stdcall;

Description:

This function should be used for assigning 32-bit integer values wit the object’s property.

Note: some objects many provide read-only access to their properties.

Parameters:

ID
[in] Identifier of the property to be changed.
Value
[in] 32-bit integer value to be assigned to the property.

Return values:
         
0                      The integer data was assigned successfully.
Any other        Object cannot change the property with provided ID.

6.5. ITBPDataProvider::GetIDType

Syntax:

C++:         virtual int WINAPI GetIDType(int ID);

Object Pascal: function GetIDType(ID: Integer): Integer; stdcall;

Description:

This function returns type identifier of the property specified by ID;


Parameters:

ID
[in] Identifier of the target property


Return values:

Property type identifier

Below is the list of currently defined type identifiers:

Name Value Description GetDataByID / SetDataByID Conversion
dtcChar 0 String data As is
dtcInt 1 32-bit integer Text representation of the number
dtcInt64 2 64-bit integer Text representation of the number
dtcWChar 3 UTF-16-encoded text Text converted in the local code page
dtcBool 5 Boolean ‘0’ for False, ‘1’ for True
dtcBinary 6 Binary data Base64-encoded text
dtcFloat 7 Floating-point value that corresponds to “Double” data type in Delphi, the Double precision floating-point value (8 bytes) Text representation of the number

Negative value            Property is not defined yet


6.6. ITBPDataProvider::ItemCount

Syntax:

C++:         virtual int WINAPI ItemCount();
Object Pascal:      function ItemCount: Integer; stdcall;

Description:

This function returns the number of stored properties for numbered list objects (such as Params in TBP_ExecMacro)

Parameters:

None

Return values:

The number of counted properties.


6.7. ITBPDataProvider::ExecuteMacro

Syntax:

C++:         virtual HRESULT WINAPI ExecuteMacro(char* AMacro, int MaxLen, ITBPDataProvider* InData, ITBPDataProvider* OutData);
Object Pascal:      function ExecuteMacro(AMacro: PChar; MaxLen: Integer; InData, OutData: ITBPDataProvider): HResult; stdcall;

Description:

This function is designed to give extra access to facilities provided by an object. Each object that implements the ITBPDataProvider interface may have its own set of macros that is documented for that particular object.

Below is the list of objects with documented behaviour of ExecuteMacro method:

Object Where documented
Template Processor objects p.5.3.2

Parameters:

AMacro
[in] Pointer to a string buffer that contains the null-terminated string specifying the text of the macro to be executed.
MaxLen
[in] Maximum length of the macro text located in AMacro.

InData
[in] Pointer to the ITBPDataProvider object containing input data for macro execution, if required. Property indexes and meaning are to be documented for each implementation. For most cases, InData is a numbered list of parameters.
OutData
[out] Pointer to the ITBPDataProvider object containing output data of macro execution, if required. Property indexes and meaning are to be documented for each implementation.
For most cases, Property with zero index contains the result of execution of the Macro.


Return values:

To be documented for each implementation


7. History of changes
Version 1.0 (2003) – Initial document;
Version 1.9 (October 9th, 2009) clarifies the TBP_NeedResave and adds new values to the “Template object index”;
Version 1.10 (November 27th, 2009) adds a description for TBP_SetCoreBridge;
Version 1.11 (July 30th, 2010) clarifies thread safety and adds TBP_MainWindowLoaded;
Version 1.12 (June 8th, 2017) explains string encoding and data type sizes, adds new identifiers, replaces "UNICODE" to UTF-16, to be precise.



--
Maxim Masiutin
Director
Ritlabs, SRL
________________________________________________
http://www.silverstones.com/thebat/TBUDLInfo.html

Reply via email to