For the next Avedesk version I'm wanting to be able to show previews of what a desklet looks like beforing adding it.
By default, AveDesk will try to use icon.png as the small preview icon, and largeicon.png as the real-sized preview.
However, this would only work for desklets that included these files. For older desklets, it won't work obviously. To be kinda backward compatible, avedesk searches for a combination of images:
TRYIMAGE(L"icon.png")
TRYIMAGE(L"bg.png")
TRYIMAGE(L"preview.png")
TRYIMAGE(L"screenshot.png")
TRYIMAGE(L"preview.png")
TRYIMAGE(L"screenshot.jpg")
TRYIMAGE(L"preview.jpg")
TRYIMAGE(L"normal.png")
TRYIMAGE(L"default.png")
TRYIMAGE(L"images/bg.png")
TRYIMAGE(L"images/icon.png")
TRYIMAGE(L"images/normal.png")
TRYIMAGE(L"images/default.png")
TRYIMAGE() will search on the filename in,
a) the desklets directory
the skins directory, tried to beextracted from the skin information (e.g., name, key).
For most desklets, this results in a succesfull hit. However, since SysStats has a better seperation of code and contents, it's hard to get a preview image (where to look?) - currently, avedesk will for every SysStats config use the same screenhot.jpg in SysStats folder, as you can see in the following image:

I have a couple of things so that SysStats (and other desklets) would show the correct image.
The first one would simply be a function to be implemented by SysStats to get an image for a skin. AveDesk will make sure this function is called on a non-blocking worker-thread, so SysStats can even load the config offscreen and render it to a bitmap.
Because this process can be time-consuming, caching should be an option:
struct IconData
{
DWORD dwSize;
DWORD flags; // caller: WANTS_SMALLICON, WANTS_BIGICON, NOT_IN_CACHE, callee: SMALL_AND_BIG_ARE_THE_SAME
HBITMAP hBmp; // preview bitmap to be filled out by the callee
SIZE size; // caller: requesting size, callee: bitmap size
WCHAR cacheID[MAX_PATH+20]; // callee: fill with an id to find this entry back
TIMESTAMP timeStamp; // timeStamp of cache-entry
};
const int ICON_SUCCESS = 0;
const int ICON_ERROR = 1;
const int ICON_LOOK_IN_THE_CACHE = 2;
int OnGetSkinIcon(ENUMERATOR_DATA* lpEnumData lPData, const SkinInfo* skinInfo, IconData* iconData)
{
wcscpy_s(iconData->cacheID, MAX_PATH, skinInfo->key);
wcscat_s(iconData->cacheID, MAX_PATH+20, iconData->flags & WANTS_SMALLICON ? L"SMALL" : L"LARGE");
if(iconData->flags & NOT_IN_CACHE || GenerateTimeStamp() > iconData->timeStamp)
{
// generate bitmap
iconData->hBmp = GeneratePreview(...);
iconData->size = ...
iconData->timeStamp = ...
return ICON_SUCCESS;
}
else
{
return ICON_LOOK_IN_THE_CACHE;
}
}
However, suppose the user is doing an action that would make obtaining the preview icon useless, there needs to be a way to cancel it. The above function would not be good enough.
Something along the lines of:
// creating icon
TOKEN token = OnStartCreatingPreviewIcon(...., iconIsReadyCallback);
// canceling
OnStopCreatingPreviewIcon(...., token);
AveDesk will ask SysStats to start creating the preview icon [sysStats is now responsible for creating a worker-thread itself], and gives a callback function pointer SysStats can call when the icon is ready. SysStats gives back a token which can be used to cancel the operation.
This makes stuff more complex - caching not included yet.
Any idea? What would be the easiest from a SysStats point-of-view?
Aqua-Soft Forums