Effect DLL SDK
(Doesn't work with the Lite
version)
Requirements
Use the following information if you want to create your own DLL
containing effects for use with Wallpaper Cycler. You need
knowledge of programming DLLs in C++ to create your own
effects.
The first thing you have to do is to download the Effect
DLL SDK and the Anti-Grain Geometry (AGG) drawing
library from http://www.antigrain.com/.
The Effect SDK contains the following files:
- Effects Common.h: Containing some general
definitions.
- Effects.cpp: You should add your effects implementations
to this file.
- Effects.h: This file defines the effects in the
DLL.
The first file should not be altered. The two last files will be
explained in the following sections.
When you compile the DLL with your compiler, make sure that you
have set the preprocessor definition WPC_EFFECTS_EXPORTS.
Effects.h Structure
This section will explain the structure of the effect.h
file. The first few lines in the WPC_EFFECTS_DLL namespace allow
you to specify some general information about your DLL.
static const TCHAR* g_version = _T("3.0");
static const TCHAR* g_author = _T("NuonSoft (Marc Gregoire)");
static const TCHAR* g_email = _T("marc.gregoire@nuonsoft.com");
static const TCHAR* g_link = _T("http://www.nuonsoft.com/wallpapercycler");
static const TCHAR* g_description = _T("This Effect DLL contains the standard
effects that comes with Wallpaper Cycler.");
|
You should change the above strings to some appropriate values.
The next few lines define the following typedefs.
typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::pixfmt_gray8 pixfmtGray;
|
These typedefs are used in the implementation of your effect.
The following few lines in the effects.h file contain some inline
helper functions which you need to use in your implementation. The
function ColorrefToAgg will convert a COLORREF value into an
colorvalue for use by the AGG library. You have to use this inline
helper function to do the conversion to make sure the order of the
R, G, B and A values is correct. The function "ClampValue"
is used to clamp a value between a lower and an upper bound (see
example below).
The following section in the effects.h file is the most
important section. It defines your effects.
static const EFFECT_INFO g_effects[] = {
"ApplyTransparency",
_T("Transparency"),
_T("Make the image transparent by the given amount."),
_T("Transparency Percentage=INT=50|0|100=Transparency percentage (100 is
fully transparent).;"),
};
|
Each effect contains the following 4 strings in the g_effects
array:
- Name of the function of your effect.
- Name of your effect as will be shown in the GUI.
- A description of this effect.
- The parameters that your effect accepts (see below).
The first three strings are self-explanatory. The last string
contains your parameters and this string has the following well
defined syntax:
_T("name1=TYPE=DEFVALUE=DESCRIPTION;name2=TYPE=DEFVALUE=DESCRIPTION")
That string can contain as many parameters as you need. The
characters "=" and ";" (without the quotes) are not
allowed in the name, type, defvalue and description fields! The
different fields are explained below.
nameX is the name of that parameter and will be shown in
the GUI. Note: Please make
sure that all parameter names are different!
TYPE is the type of the parameter and can be any of the
following:
- STRING: The parameter is a string value. This type is
also used if you need a floating point parameter.
- CHOICE: This parameter will display a dropdown list to
the user containing the options you specify in the DEFVALUE field
(see below).
- INT: This parameter is an integer value. The DEFVALUE
field can be used to specify a lower- and upperbound for this
integer (see below).
- BOOL: This parameter will display a checkbox to the
user.
- COLOR: This parameter will display a color-selector to
the user.
- FILE: This parameter will allow the user to select a
file.
The DEFVALUE field is used to specify a default value for
a specific parameter. For example:
_T("aBoolean=BOOL=1=Parameter set to true by default.")
As you can see the DEFVALUE field is set to 1, which will cause
the checkbox to be checked by default. The DEFVALUE has a special
meaning for the CHOICE and INT types:
- For the CHOICE type, the default value is what should be
added to the dropdown list and the first item will be preselected.
The items should be separated with a |. What you get back as
parameter is the index of the selected item. For example, the
parameter string _T("aChoice=CHOICE=Value 1|Value 2=A choice
sample.") will display a dropdown list to user containing the
strings "Value 1" and "Value 2" and the first one will be selected
by default.
- For the INT type, the default value can be something
like:
x
where x is the default value, OR
x|a where x is the default value and a is the minimum
value, OR
x|a|b where x is the default value, a is the minimum
value and b the maximum value.
Note: These minimum and maximum
values are only used in the GUI to limit the range of the spinner
buttons that appear next to the integer entry box. You should still
do your own parameter checking when your effect function is called,
as will be explained later.
The DESCRIPTION field allows you to specify a little
description which will be shown in the GUI when that particular
parameter is selected by the user.
The following part of the effects.h file contains some functions
definitions that you should not touch.
The last part of the effects.h file is the definition of your
effect functions.
WPC_EFFECTS_API bool ApplyTransparency(agg::rendering_buffer& aggbuffBack,
agg::rendering_buffer& aggbuffFore, agg::rendering_buffer* pAggbuffMask,
const RECT& rect, const RECT& rectclip, const TCHAR* pszParams);
|
The meaning of all the parameters will be explained later, but
each of your effect functions should have the above signature.
Effects.cpp Structure
The effects.cpp file starts with some includes, the DllMain
function, some other functions and the macros
PARSE_PARAMETERS_START and PARSE_PARAMETERS_END. All of this
shouldn't be touched. After all this, you should implement your
effect functions. This is explained in more details in the
following example section.
Example
The following is an example of an effects function as
implemented in a DLL. This particular effect will make the
foreground transparent with a certain transparency value.
WPC_EFFECTS_API bool WPC_EFFECTS_DLL::ApplyTransparency(agg::rendering_buffer& aggbuffBack,
agg::rendering_buffer& aggbuffFore, agg::rendering_buffer* pAggbuffMask,
const RECT& rect, const RECT& rectclip, const TCHAR* pszParams)
{
// Create local variables for our effect-specific parameters
int iTransValue = 0;
// Parse our effect-specific parameters from pszParams
PARSE_PARAMETERS_START
if (!_tcsnicmp(_T("Transparency Percentage"), token, equalsign-token))
iTransValue = _ttoi(equalsign + 1);
PARSE_PARAMETERS_END
// Check parameter range!
ClampValue<int>(iTransValue, 0, 100);
// Attach AGG pixel formats to the AGG buffers
pixfmt pixfF(aggbuffFore);
pixfmt pixfB(aggbuffBack);
pixfmtGray pixfMask(*pAggbuffMask);
// Loop over all rows, keeping into account rectclip!
for (int y=rectclip.top; y<=rectclip.bottom; ++y)
{
// Loop over all columns, keeping into account rectclip!
for (int x=rectclip.left; x<=rectclip.right; ++x)
{
// Take masking into account
agg::gray8 m(0);
if (pAggbuffMask)
{
// A mask is supplied, check the mask value
m = pixfMask.pixel(x, y);
if (m.v == 255)
continue;
}
// Get the color of the pixel in the foreground
agg::rgba8 pf = pixfF.pixel(x, y);
// Get the color of the corresponding pixel in the background
agg::rgba8 pb = pixfB.pixel(x+rect.left, y+rect.top);
// Calculate new foreground color, based on transparency value
pf.r = int(((100-iTransValue)*pf.r + iTransValue*pb.r) / 100.0 + 0.5);
pf.g = int(((100-iTransValue)*pf.g + iTransValue*pb.g) / 100.0 + 0.5);
pf.b = int(((100-iTransValue)*pf.b + iTransValue*pb.b) / 100.0 + 0.5);
// Take masking into account
if (m.v != 0)
{
// A mask is supplied and the value is not 0, so
// apply mask to new foreground color
pf.r = int(((255-m.v)*pf.r + m.v*pb.r) / 255.0 + 0.5);
pf.g = int(((255-m.v)*pf.g + m.v*pb.g) / 255.0 + 0.5);
pf.b = int(((255-m.v)*pf.b + m.v*pb.b) / 255.0 + 0.5);
}
// Store new color in foreground buffer
pixfF.copy_pixel(x, y, pf);
}
}
return true;
}
|
Each effect function requires the following parameters:
- aggbuffBack: This is an AGG buffer containing the
background.
- aggbuffFore: This is the AGG buffer on which you need to
apply your effect.
- pAggbuffMask: This is a pointer to an AGG buffer
containing a mask. You should keep this mask into account when
applying your effect. (Note:
This can be a NULL-pointer, so check for NULL pointer!)
- rect: This is the rectangle that aggbuffFore occupies in
aggbuffBack.
- rectclip: This is the rectangle inside aggbuffFore to
which the effect should be applied. You should also keep the mask
into account.
- pszParams: This is a string containing specific
parameters for your effect.
The flow of the code is explained with comments in the above
piece of code. Don't forget to do parameter validation and
correction right after the
PARSE_PARAMETERS_START/PARSE_PARAMETERS_END block! In the example
above this is done with a simple call to ClampValue to make sure
that the iTransValue parameter is between 0 and 100 (0 and 100
inclusive).
Problems?
If you have any trouble with creating effects, ask your
questions either via the Wallpaper Cycler SDK sub-forum at
http://www.nuonsoft.com/forum/
or via email.
Back to
Top
|
Copyright © 2009 NuonSoft
All trademarks and trade names are properties of their respective
owners.
|
|