C/C++ Plugin Overview


When making a Rainmeter plugin there are a some basic functions that your code must export, as well as several optional ones you may want to export.

A copy of the API with some examples can be found here as well as the basics of each function listed below:

Required functions

Initialize void Initialize(void** data, void* rm)

Called when a measure is created (i.e. when a skin is loaded or when a skin is refreshed). Create your measure object here. Any other initialization or code that only needs to happen once should be placed here.

  • data : You may allocate and store measure specific data to this variable. The object you save here will be passed to other functions below.
  • rm : Internal pointer that is passed to most API functions. If needed, you may save this value for later use (like for logging functions).

Example:

PLUGIN_EXPORT void Initialize(void** data, void* rm)
{
Measure* measure = new Measure;
*data = measure;
// Do any initialization here, saving any values you want to into data for later
}
Reload void Reload(void* data, void* rm, double* maxValue)

Called by Rainmeter when the measure settings are to be read directly after Initialize. If DynamicVariables=1 is set on the measure, this function is called just before every call to the Update function during the update cycle.

  • data : Pointer to the data set in Initialize.
  • rm : Internal pointer that is passed to most API functions.
  • maxValue : Pointer to a double that can be assigned to the default maximum value for this measure. A value of 0.0 will make it based on the highest value returned from the Update function. Do not set maxValue unless necessary.

Example:

PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
{
Measure* measure = (Measure*)data;
// Read measures values from the measure (see API functions)

// The expected value returned in the Update function will not exceed 100.0
*maxValue = 100.0;
}
Update double Update(void* data)

Called by Rainmeter when a measure value is to be updated (i.e. on each update cycle). The number returned represents the number value of the measure.

Returns: The number value of the measure (as a double). This value will be used as the string value of the measure if the GetString function is not used or returns a nullptr.

Example:

PLUGIN_EXPORT double Update(void* data)
{
Measure* measure = (Measure*)data;
// Any processing that needs to happen during the update cycle should happen here
return 0.0; // Return the number value of the measure
}
Finalize void Finalize(void* data)

Called by Rainmeter when a measure is about to be destroyed. Perform cleanup here.

Example:

PLUGIN_EXPORT void Finalize(void* data)
{
Measure* measure = (Measure*)data;
// Do any cleanup here
delete measure;
}

Optional functions

GetString LPCWSTR GetString(void* data)

Optional function that returns the string value of the measure. Since this function is called 'on-demand' and may be called multiple times during the update cycle, do not process any data or consume CPU in this function. Do as minimal processing as possible to return the desired string. It is recommended to do all processing during the Update function and set a string variable there and retrieve that string variable in this function.

Returns: The string value for the measure (as a LPCWSTR). If you want the number value (returned from Update) to be used as the measures value, return nullptr instead.

Example:

PLUGIN_EXPORT LPCWSTR GetString(void* data)
{
Measure* measure = (Measure*)data;
if (something)
{
// Return a string value to use for this measure
return L"SomeValue";
}

//Return nullptr when you want to use the number
// value for this measure (the value returned from the Update function)
return nullptr;
}
ExecuteBang void ExecuteBang(void* data, LPCWSTR args)

Optional function that will process a custom bang when called from !CommandMeasure. This can be used to change some data within the measure, or to interact with another application.

  • data : Pointer to the data set in Initialize.
  • args : String that contains any arguments to parse.

Example:

PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args)
{
Measure* measure = (Measure*)data;
// !CommandMeasure was used on this measure...any arguments will be in args
}
Custom function LPCWSTR func(void* data, const int argc, const WCHAR* argv[])

You can define a custom function to be used in a section variable. The name of the function is the name to be used in the skin file as a section variable. The function must be exported and the function prototype must be: LPCWSTR func(void*data, const int argc, const WCHAR* argv[]).

The function name can be anything except the following: Initialize, Reload, Update, Finialize, GetString, ExecuteBang, Update2, GetPluginAuthor, and GetPluginVersion.

The skin will call this function (as a section variable) like this: [PluginMeasure:func(someArg1, someArg2)].

  • data : Pointer to the data set in Initialize.
  • argc : Number of arguments passed to the function.
  • argv : Arguments passed to the function as an array of strings.

Returns: A string to replace the section variable with (as a LPCWSTR). If a nullptr is returned, the variable will not be replaced and remain unchanged.

Example:

PLUGIN_EXPORT LPCWSTR SomeFunction(void* data, const int argc, const WCHAR* argv[])
{
Measure* measure = (Measure*)data;
if (argc > 0)
{
// Do something and return a value to replace variable with
return doSomething(argv);
}

return nullptr; // Do not replace the variable
}