| Home | Products | Purchase | Download | Contact | Selteco Developer Network |
Developing Bannershop Extensions
|
| Frame 1 | ![]() | 2 sec |
| Effect Frame | ![]() | 0.1 sec |
| Effect Frame | ![]() | 0.1 sec |
| Break Frame | ![]() | 0.1 sec |
| Frame 2 | ![]() | 2 sec |
| Break Frame | ![]() | 0.1 sec |
| Effect Frame | ![]() | 0.1 sec |
| Effect Frame | ![]() | 0.1 sec |
| Effect Frame | ![]() | 0.1 sec |
| Effect Frame | ![]() | 0.1 sec |
| Frame 3 | ![]() | 2 sec |
Effect frames are not visible in the Bannershop's Frames list, and can not be modified. Effect frames are recreated every time the frame contents have been modified. This means the effect is "live" - a change of animated image is always automatically reflected in the effect animation.
Step 1
Bannershop loads extension DLL using standard Windows LoadLibrary function.
When loaded main DLL function is executed to perform library setup. No
specific action is required at this point, however some of the commercial
extensions may perform serial number checkup at this point and refuse load
is they are not registered or display serial number prompt. Typical DllMain function that does nothing looks like this:
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch( ul_reason_for_call ) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
;
};
return TRUE;
}
Step 2
Immediately after successful load Bannershop is looking for the function called B5XGetExtensions. Bannershop calls this function to retrieve
all effects supported by this extension.
DWORD * B5XGetExtensions();
B5XGetExtensions returns pointer to effect IDs table followed by 0 value. Effect ID is a unique DWORD value identifying single animation effect that can be performed by this extension. All further calls pass this unique effect ID as one of the parameters. This ensures that the extension always know which effect is currently referred by Bannershop. The extension may contain unlimited number of effects, each of them identified by unique ID.
Effect IDs table returned by B5XGetExtensions function may look like this:
| 0x0054 | 0x0059 | 0x0000 |
In the above example extension contains 2 effects identified by numbers 0x0054 and 0x0059. The last value is 0 indicating end of table.
Step 3
Now after Bannershop has preliminary list of effects it wants to find out more from the extension about these effects. For each effect Bannershop calls the function called
B5XGetInfo
BOOL B5XGetInfo(DWORD EffectID, B5XINFO * b5xinfo);
Extension must fill a structure called B5XINFO. Pointer to this structure is passed from Bannershop to extension procedure.
typedef struct B5XINFO
{
DWORD XType; // effect type: 1=intro, 2=outro
int MaxSpeed; // maximum speed of this effect (0-5)
int MinSpeed; // minimum speed of this effect (0-5)
LPSTR MenuName; // name of the effect displayed in "Bannershop" dialogs
} B5XINFO;
Extension must fill all members of the B5XINFO structure.
The meaning of speed values is as follows:
| Speed Value | Name in dialog | Number of effect frames |
| 0 | Ultra Fast | 1 |
| 1 | Very Fast | 2 |
| 2 | Fast | 4 |
| 3 | Medium | 8 |
| 4 | Slow | 16 |
| 5 | Very Slow | 32 |
Step 4
The last step of loading an extension is to find out more who did this great job. Bannershop
calls the function calls B5XVendorInfo
LPCSTR B5XVendorInfo(DWORD dwFlag);
The extension must return the text that will be displayed in the informative dialog of Bannershop. Usually it is information about the extension developer, its web site url etc. Simple function may look like this:
LPCSTR B5XVendorInfo(DWORD dwFlag)
{
if(dwFlag==0)
return "Sample Extension for Bannershop GIF Animator v1.0
\r\n(c) VendorName Inc, 2000\r\nhttp://www.myvendorname.com";
return NULL;
}
dwFlag value is reserved for future use. Extension should return NULL pointer if the dwFlag is not zero.
Bannershop creates animation frames by itself. It calls the extension functions only to retrieve transformed bitmaps of animated images.
Bannershop calls extension rendering functions for each animation step and for each animated item. Each document item is represented by a rectangular bitmap (called item bitmap). This bitmap is passed to extension and Bannershop expects the extension to return transformed bitmap for current animation step. Current step number is also passed to the rendering procedure and is usually the most important parameter for transforming animated item.
Bannershop calls the function called B5XPrepare to query the extension how the item should be transformed. Extension must return the information how it wants to render the item in current step.
int B5XPrepare(DWORD EffectID, struct XRENDERINFO * xRenderInfo, int Step);
XRENDERINFO structure is filled by Bannershop and contains all important information about animated item and its environment. Step parameter indicates current frame number in effect animation sequence. Step can be either positive or negative number. The value is negative for intro effects and positive for outro effects. Numbering of steps is illustrated below:
Frame 1 (outro animation effect, 2 steps) Effect Frame (step +1) Effect Frame (step +2) Break Frame Frame 2 (no effects) Break Frame Effect Frame (step -4) Effect Frame (step -3) Effect Frame (step -2) Effect Frame (step -1) Frame 3 (intro animation effect, 4 steps)
(Break frames are created by Bannershop and are not part of effect animation)
B5XPrepare may return the following values that indicate what the extension want to do with animated item in current step:
If the extension returned B5XPAINTRENDERED Bannershop prepares output buffer and calls the function B5XDoRender. This function must read input bitmap and write output pixels to the output buffer. Bannershop paints then output bitmap instead of original item. This feature is used for example in "fade in" effect.
int B5XDoRender(DWORD EffectID, struct XRENDERINFO * xRenderInfo, int Step);
typedef struct XRENDERINFO
{
RECT pBox;
RECT iBox;
RECT tBox;
int Kind;
int Steps;
int StepDelay;
int Option;
DWORD * lpBits;
DWORD * outBits;
} XRENDERINFO;
Variables filled by Bannershop before calling B5XPrepare
and B5XDoRender:
pBox contains bounding rectangle of visible (exportable) frame area
iBox contains bounding rectangle of item bitmap
Steps total number of steps in this effect
StepDelay current step duration in 1/100th of second, usually =10
lpBits pointer to animated bitmap pixels
outBits NULL for B5XPrepare, output buffer for B5XDoRender
Variables filled by Extension before returning from B5XPrepare:
tBox contains bounding rectangle of item bitmap after transformation
Variables filled by Extension before returning from B5XDoRender:
outBits extension writes rendered bitmap to this buffer
Variables not explained and not used in this SDK:
Kind specifies item type - image, shape or text
Option extension specific additional parameter
The reason why Bannershop calls B5XPrepare before B5XDoRender is that usually output bitmap does not match input bitmap in size. Before calling B5XDoRender Bannershop must allocate output buffer based on new bitmap dimensions returned in tBox rectangle, which is filled by B5XPrepare function.
tBox rectangle is very important here. Extension returns here both dimension of new bitmap and also its new position.
The following example illustrates 400 x 400 pixels workspace, with frame being white rectangle and sample animated item being yellow one:
Based on above picture pBox and iBox rectangles passed to
B5XPrepare and B5XDoRender functions would have following values:
// pBox is the frame rectangle pBox.left = 0; pBox.top = 0; pBox.right = 120; pBox.bottom = 80; // iBox is the item rectangle iBox.left = 40; iBox.top = 40; iBox.right = 100; iBox.bottom = 60;If the extensions wants the item to be moved in current step by 10 pixels right it sets the tBox.left and tBox.top values to new position in function B5XPrepare:
// tBox is transformation rectangle tBox.left = 40 + 10 = 50; tBox.top = 40;and returns B5XPAINTMOVED value. In this case Bannershop ignores tBox.right and tBox.bottom values.
If the extensions wants the item to be enlarged by 10 pixels each side it sets the tBox rectangle to new position and dimensions:
// tBox is transformation rectangle tBox.left = 40 - 10 = 30; tBox.top = 40 - 10 = 30; tBox.right = 100 + 10 = 110; tBox.bottom = 60 + 10 = 70;and returns B5XPAINTRESAMPLED value to inform Bannershop that it should resample the bitmap to new dimensions. tBox.left and tBox.top values specify new position of the bitmap.
The last example is the case where the extension wants to render the bitmap. Let's say the output bitmap will be 10 pixels smaller in width than the original and the bitmap should be aligned to frame's top-left corner. tBox rectangle will have following values:
// tBox is transformation rectangle tBox.left = 0; // aligned to frame's left border tBox.top = 0; // aligned to frame's top border tBox.right = 50; // original width - 10 = 60 - 10 = 50 pixels tBox.bottom = 20; // original height of 20 pixels matchedAfter setting tBox rectangle B5XPrepare function returns B5XPAINTRENDERED value. Bannershop will prepare output buffer of size 50 x 20 pixels and call B5XDoRender to retrieve rendered bitmap. Buffer address is passed in XRENDERINFO.outBits.
As you may already know Device Independent Bitmap is "upside down" bitmap. This means that 0,0 pixel is placed not in top-left corner but in bottom-left one. This also means that if you want to get to the pixel number x,y you can't just use simple y*width+x expression to index pixel table, but it's a bit more complex. For simplicity to access pixel x,y we use a macro called DIB32PIXEL. To find an index of pixel x,y we use the following expression:
DIB32PIXEL( x, y, bitmap_width, bitmap_height)
So for example retrieving pixel at coordinates 15,20 in 30 x 40 bitmap is as easy as:
mypixel = lpBits[ DIB32PIXEL( 15, 20, 30, 40) ];
Each pixel as a 32-bit DWORD value, with bytes distributed as TBGR (Transparency, Blue, Green, Red) called channel bytes. To retrieve channel bytes you can use the following macros:
DIBT( mypixel ) for Transparency value
DIBR( mypixel ) for Red value
DIBG( mypixel ) for Green value
DIBB( mypixel ) for Blue value
To pack 4 channel bytes into one DWORD pixel use the DIBCOLOR macro:
mypixel = DIBCOLOR( transparency, blue, green, red)
Watch the red and blue order, it's different than in regular RGB bitmaps!
Transparency byte equal 0 means the pixel is fully opaque. If the byte is equal 255 it means the pixel if fully transparent. Byte equal 128 means the pixel is 50% transparent and its color will be mixed with corresponding background pixel in appropriate proportions.
This extension shakes randomly animated item. In the example picture below, "shake" effect was applied individually to each star with different effect duration time for each of them.
My Shake extension illustrates usage of B5XPrepare function. Actual item bitmap remains unchanged - the item is only repositioned.
This sample extension provides animation effects that make the item appear or disappear not suddenly but in a smooth, fade way.
My Fade extension illustrates usage of both B5XPrepare and B5XDoRender functions. Actual item bitmap must be rendered in each step.
To see these extensions in action place MyShake.b5x and MyFade.b5x files in "extensions" folder of Bannershop GIF Animator. Effects provided by extensions are called "My Fade In", "My Fade Out" and "My Shake". Launch Bannershop GIF Animator and apply these effects to your images to see how they work.
Extension code is well commented. See .cpp files for details. If you are using Microsoft Visual C++ you can open extension project files (.mdp). If you are using different compiler create new DLL projects and import .cpp and .rc files.
Before releasing your extension send an email to tech@selteco.com to request unique IDs for effects in your extension. You may request a bigger pool for future use so you don't have to email us every time you create new extension.
If you want to be referenced from our site or if you want your extension to be listed on our pages send us your extension by email. We will evaluate it and include in our web site.
| © Copyright 1999, 2000 Selteco |