//Start of header // Native include #include #include //required Miranda SDK (files are in include subfolder) #include "newpluginapi.h" #include "m_system.h" #include "m_cluiframes.h" #include "m_database.h" #include "m_utils.h" //required updater header (not in Miranda SDK) #include "m_updater.h" //required iconlib header (not in Miranda SDK) #include "m_icolib.h" //resource definition header #include "resource.h" //Fingerprint services definition header #include "m_fingerprint.h" //Definition from other Miranda IM SDK #define MS_CLUI_LISTBEGINREBUILD "CLUI/ListBeginRebuild" #define ME_OPT_INITIALISE "Opt/Initialise" #define MS_UTILS_PATHTORELATIVE "Utils/PathToRelative" #define MS_PROTO_GETCONTACTBASEPROTO "Proto/GetContactBaseProto" #define MS_LANGPACK_TRANSLATESTRING "LangPack/TranslateString" #define Translate(s) ((char*)CallService(MS_LANGPACK_TRANSLATESTRING,0,(LPARAM)(s))) #define IsWinVerXPPlus() (LOBYTE(LOWORD(GetVersion()))>=5 && LOWORD(GetVersion())!=5) #define _CRT_SECURE_NO_DEPRECATE // End of SDK headers include #if defined(__GNUC__) #define _alloca alloca //#define FASTCALL #else #define FASTCALL __fastcall #endif #define mir_strncpy(a,b,c) { strncpy(a,b,c)[c-1] = 0; } #define LIB_NONE 0 #define LIB_GET 1 #define LIB_REG 2 #define LIB_USE 3 HANDLE hExtraImageListRebuild; // hook event handle for ME_CLIST_EXTRA_LIST_REBUILD HANDLE hExtraImageApply; // hook event handle for ME_CLIST_EXTRA_IMAGE_APPLY HANDLE hContactSettingChanged; // hook event handle for ME_DB_CONTACT_SETTINGCHANGED HANDLE hOptInitialise; // hook event handle for ME_OPT_INITIALISE HANDLE hIconsChanged; // hook event handle for ME_SKIN2_ICONSCHANGED HANDLE hModulesLoaded; HANDLE hPreShutdown; // hook event handle for ME_SYSTEM_PRESHUTDOWN HANDLE compClientServ=NULL; HANDLE getClientIcon=NULL; BYTE bColumn = 0; int OnIconsChanged(WPARAM wParam, LPARAM lParam); int OnExtraIconListRebuild(WPARAM wParam, LPARAM lParam); int OnExtraImageApply(WPARAM wParam, LPARAM lParam); int OnContactSettingChanged(WPARAM wParam, LPARAM lParam); int OnOptInitialise(WPARAM wParam, LPARAM lParam); int OnModulesLoaded(WPARAM wParam, LPARAM lParam); int OnPreShutdown(WPARAM wParam, LPARAM lParam); int ServiceSameClients(WPARAM wParam, LPARAM lParam); int ServiceGetClientIcon(WPARAM wParam, LPARAM lParam); HICON FASTCALL CreateJoinedIcon(HICON hBottom, HICON hTop); HBITMAP FASTCALL CreateBitmap32(int cx, int cy); HBITMAP FASTCALL CreateBitmap32Point(int cx, int cy, void ** bits); BYTE FASTCALL GetIconIndexFromFI(short base, short overlay, short overlay2, short overlay3); void FASTCALL ClearFI(); int FASTCALL ApplyFingerprintImage(HANDLE hContact,char *MirVer); HICON FASTCALL LoadIconFromExternalFile(char *filename,int nLibrary,char *IconName,int flag,char *Description,int internalidx, BOOL * NeedFree); BOOL FASTCALL WildCompare(char * name, char * mask); BOOL __inline WildCompareProc(char * name, char * mask); int FASTCALL DBGetStaticString(HANDLE hContact, const char* moduleName, const char* valueName, char* dest, int dest_len); typedef struct { BYTE b; BYTE g; BYTE r; BYTE a; } RGBA; typedef struct _knfpMask { char *szIconName; char *szMask; char *szClientDescription; char *szIconFileName; int iIconIndex; BYTE registeredIndex; int SectionFlag; } KN_FP_MASK; typedef struct _foundInfo { DWORD array; BYTE registeredIndex; } FOUNDINFO; FOUNDINFO *fiList=NULL; int nFICount=0; //Including of fingerprint masks #include "fingerprints.h" //End of header HANDLE hHeap = NULL; BOOL SKIN2_RELEASEICON = FALSE; BOOL SKIN2_ADDICON = FALSE; char szPath[MAX_PATH],szMyPath[MAX_PATH]; HINSTANCE g_hInst; PLUGINLINK *pluginLink; // PluginInfo & PluginInfoEx + UUID #include "version.h" #if defined(FULL) || defined(STANDARD) || defined(LITE) #ifdef FULL #define FP_MODULENAME "Fingerprint Mod (full)" #define MIID_FINGERPRINT_MOD_TYPE MIID_FINGERPRINT_MOD_FULL #endif #ifdef STANDARD #define FP_MODULENAME "Fingerprint Mod (standard)" #define MIID_FINGERPRINT_MOD_TYPE MIID_FINGERPRINT_MOD_STANDARD #endif #ifdef LITE #define FP_MODULENAME "Fingerprint Mod (lite)" #define MIID_FINGERPRINT_MOD_TYPE MIID_FINGERPRINT_MOD_LITE #endif #else #define FP_MODULENAME "Fingerprint Mod (custom build)" #define MIID_FINGERPRINT_MOD_TYPE MIID_FINGERPRINT_MOD_CUSTOM #endif static PLUGININFOEX pluginInfoEx = { sizeof(PLUGININFOEX), FP_MODULENAME, __VERSION_DWORD, "Fingerprint Mod (client version) icons module set extra icon of your buddies according to their client version", "Artem Shpynov aka FYR, Bio, Faith Healer", "faith@inbox.ru", "© 2006-2007 Artem Shpynov aka FYR, Bio, Faith Healer", "http://Faith.MirandaIM.Ru", UNICODE_AWARE, 0, MIID_FINGERPRINT_MOD }; static PLUGININFO pluginInfo = { sizeof(PLUGININFO), FP_MODULENAME, __VERSION_DWORD, "Fingerprint Mod (client version) icons module set extra icon of your buddies according to their client version", "Artem Shpynov aka FYR, Bio, Faith Healer", "faith@inbox.ru", "© 2006-2007 Artem Shpynov aka FYR, Bio, Faith Healer", "http://Faith.MirandaIM.Ru", 0, 0 }; __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) {// Tell Miranda IM about plugin return &pluginInfoEx; } __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) {// Tell Miranda IM about plugin return &pluginInfo; } static const MUUID interfaces[] = {MIID_FINGERPRINT,MIID_FINGERPRINT_MOD,MIID_FINGERPRINT_MOD_TYPE, MIID_LAST}; __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) { return interfaces; } //End of PluginInfo & PluginInfoEx+ UUID block BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { g_hInst=hinstDLL; return TRUE; } int __declspec(dllexport) Load(PLUGINLINK *link) { pluginLink=link; hModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,OnModulesLoaded); hPreShutdown=HookEvent(ME_SYSTEM_PRESHUTDOWN,OnPreShutdown); compClientServ=CreateServiceFunction(MS_FP_SAMECLIENTS,ServiceSameClients); getClientIcon=CreateServiceFunction(MS_FP_GETCLIENTICON,ServiceGetClientIcon); hHeap=HeapCreate(HEAP_NO_SERIALIZE,0,0); return 0; } int __declspec(dllexport) Unload(void) { HeapDestroy(hHeap); ClearFI(); return 0; } void FASTCALL mir_strupr(char *string) { char *cp; for ( cp = string ; *cp ; ++cp ) if ( ('a' <= *cp) && (*cp <= 'z') ) *cp -= 'a' - 'A'; } /* * FreeIcon * for mode > 0 it releases icon from iconlib * for mode < 0 it destroys icon */ void FASTCALL FreeIcon(HICON hIcon, int mode) { if (!mode) return; if (mode > 0 && SKIN2_RELEASEICON) CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, (WPARAM)0); else DestroyIcon(hIcon); } /* * Prepare * prepares upperstring masks and registers them in IcoLib */ void FASTCALL Prepare(KN_FP_MASK *mask) { char *szNewMask; if (!mask->szMask) return; szNewMask = (char*)HeapAlloc(hHeap,HEAP_NO_SERIALIZE,strlen(mask->szMask)+1); strcpy(szNewMask,mask->szMask); mir_strupr(szNewMask); mask->szMask = szNewMask; if (SKIN2_ADDICON) LoadIconFromExternalFile(mask->szIconFileName,LIB_REG,mask->szIconName,mask->SectionFlag,mask->szClientDescription,mask->iIconIndex,NULL); } /* * OnModulesLoaded * Hook necessary events here */ int OnModulesLoaded(WPARAM wParam, LPARAM lParam) { int i; KN_FP_MASK *mask; bColumn = DBGetContactSettingByte(NULL,"Finger","ClientColumn",0); if (!bColumn || bColumn > EXTRA_ICON_COUNT) bColumn = EXTRA_ICON_CLIENT; #ifdef FULL // CallService("Update/RegisterFL", (WPARAM)2594, (LPARAM)&pluginInfo); #endif //Hook necessary events hIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, OnIconsChanged); // hOptInitialise = HookEvent(ME_OPT_INITIALISE, OnOptInitialise); hExtraImageListRebuild = HookEvent(ME_CLIST_EXTRA_LIST_REBUILD,OnExtraIconListRebuild); hExtraImageApply = HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, OnExtraImageApply); hContactSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnContactSettingChanged); SKIN2_ADDICON = ServiceExists(MS_SKIN2_ADDICON); SKIN2_RELEASEICON = ServiceExists(MS_SKIN2_RELEASEICON); GetModuleFileNameA(g_hInst, szMyPath, MAX_PATH); CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)szMyPath, (LPARAM)szPath); // prepare masks for (i=0;iszSetting && !strcmp(cws->szSetting,"MirVer")) { if (cws->value.type==DBVT_ASCIIZ) ApplyFingerprintImage((HANDLE)wParam,cws->value.pszVal); else if (cws->value.type==DBVT_UTF8 || cws->value.type==DBVT_WCHAR) ApplyFingerprintImage((HANDLE)wParam,cws->value.ptszVal); else ApplyFingerprintImage((HANDLE)wParam,NULL); } } return 0; } /* * LoadIconFromExternalFile * If iconlib module presents register icon there * Regiister and return icon within iconlib * or from resourse */ // TO DO: Extracting icons from clienticons.dll or other external files require futher // destroying of icon... need to add field to list, modify it and remove icon on unload // Otherwise it will cause gdi resources leaking. // So nowtime it is commented out HICON FASTCALL LoadIconFromExternalFile(char *filename, int nLibrary, char *IconName, int flag, char *Description, int internalidx, int *NeedFree) { HICON hIcon=NULL; if (IconName==NULL) return NULL; if (SKIN2_ADDICON && nLibrary) { if (nLibrary!=LIB_REG) hIcon=((HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IconName)); if (hIcon==NULL && (nLibrary&LIB_REG) && IconName!=NULL) { SKINICONDESC sid={0}; char *SectName=""; switch (flag) { #if defined(ICQ) || defined(JABBER) || defined(MSN) || defined(AIM) || defined(YAHOO) || defined(IRC) case 1: SectName="Fingerprint client icons/ MirandaIM clients"; break; case 2: SectName="Fingerprint client icons/ Multi-protocol clients"; break; #endif #ifdef ICQ #ifndef LITE case 3: SectName="Fingerprint client icons/ICQ clients/Official clients"; break; #else case 3: SectName="Fingerprint client icons/ICQ clients"; break; #endif case 4: SectName="Fingerprint client icons/ICQ clients"; break; #endif #ifdef JABBER case 5: SectName="Fingerprint client icons/Jabber clients"; break; #endif #ifdef MSN case 6: SectName="Fingerprint client icons/MSN clients"; break; #endif #ifdef AIM case 7: SectName="Fingerprint client icons/AIM clients"; break; #endif #ifdef YAHOO case 8: SectName="Fingerprint client icons/Yahoo clients"; break; #endif #ifdef IRC case 9: SectName="Fingerprint client icons/IRC clients"; break; #endif case 10: SectName="Fingerprint client icons/Jabber clients"; break; #ifdef SKYPE case 11: SectName="Fingerprint client icons/Skype clients"; break; #endif #ifdef GADU_GADU case 12: SectName="Fingerprint client icons/Gadu-Gadu clients"; break; #endif #if defined(MIR_PACKS) && defined(MIR_PACKS_OVERLAYS) case 13: SectName="Fingerprint client icons/ MirandaIM clients/packs overlays"; break; #elif defined(MIR_PACKS) && defined(MIR_PACKS_FULL) case 13: SectName="Fingerprint client icons/ MirandaIM clients/custom packs"; break; #endif #ifdef MAIL_RU case 14: SectName="Fingerprint client icons/Mail.Ru clients"; break; #endif #ifndef LITE case 15: SectName="Fingerprint client icons/ MirandaIM clients/overlays"; break; #else case 15: SectName="Fingerprint client icons/ MirandaIM overlays"; break; #endif #if defined(SUB_CLIENTS) || defined(OVERLAY_AS_DOT) || defined(LITE) case 16: SectName="Fingerprint client icons/ MirandaIM clients/sub-clients overlays"; break; #endif case 17: SectName="Fingerprint client icons/[ other clients ]"; break; /* case 18: SectName="Fingerprint client icons/[ other clients ]/overlay icons"; break; */ case 18: SectName="Fingerprint client icons/[ overlay icons ]"; break; default: SectName="Fingerprint client icons"; break; } sid.cbSize = sizeof(sid); sid.pszSection = Translate(SectName); sid.pszName=IconName; sid.pszDescription=Description; sid.pszDefaultFile=szPath; sid.iDefaultIndex=-internalidx; sid.cx=sid.cy=16; CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); if (nLibrary!=LIB_REG) hIcon=((HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IconName)); } } if (NeedFree) *NeedFree= (hIcon && SKIN2_RELEASEICON); if (!hIcon && nLibrary!=LIB_REG) { ExtractIconExA(szMyPath, -internalidx, NULL, &hIcon, 1); if (hIcon && NeedFree) *NeedFree=-1; } return hIcon; } /* * WildCompare * Compare 'name' string with 'mask' strings. * Masks can contain '*' or '?' wild symbols * Asterics '*' symbol covers 'empty' symbol too e.g WildCompare("Tst","T*st*"), returns TRUE * In order to handle situation 'at least one any sybol' use "?*" combination: * e.g WildCompare("Tst","T?*st*"), returns FALSE, but both WildCompare("Test","T?*st*") and * WildCompare("Teeest","T?*st*") return TRUE. * * Function is case sensitive! so convert input or modify func to use _qtoupper() * * Mask can contain several submasks. In this case each submask (including first) * should start from '|' e.g: "|first*submask|second*mask". * * Dec 25, 2006 by FYR: * Added Exception to masks: the mask "|^mask3|mask2|mask1" means: * if NOT according to mask 3 AND (mask1 OR mask2) * EXCEPTION should be BEFORE main mask: * IF Exception match - the comparing stops as FALSE * IF Exception does not match - comparing continue * IF Mask match - comparing stops as TRUE * IF Mask does not not match comparing continue */ BOOL FASTCALL WildCompare(char * name, char * mask) { if (*mask!='|') return WildCompareProc(name,mask); { int s=1,e=1; static char temp[100]; //lets made temp static local var - should be faster than dynamic // char * temp = _alloca(strlen(mask)); int bExcept; while (mask[e]!='\0') { s=e; while(mask[e]!='\0' && mask[e]!='|') e++; // exception mask bExcept= (*(mask+s)=='^'); if (bExcept) s++; memcpy(temp,mask+s,e-s); temp[e-s]='\0'; if (WildCompareProc(name,temp)) return !bExcept; if (mask[e]!='\0') e++; else return FALSE; } return FALSE; } } //#define _qtoupper(_c) (((_c)>='a' && (_c)<='z')?((_c)-'a'+'A'):(_c)) //#define _qtoupper(_c) (((_c)>='a' && (_c)<='z')?((_c)&0x5F):(_c)) BOOL __inline WildCompareProc(char * name, char * mask) { char * last='\0'; for(;; mask++, name++) { if(*mask != '?' && *mask != *name) break; if(*name == '\0') return ((BOOL)!*mask); } if(*mask != '*') return FALSE; for(;; mask++, name++) { while(*mask == '*') { last = mask++; if(*mask == '\0') return ((BOOL)!*mask); /* true */ } if(*name == '\0') return ((BOOL)!*mask); /* *mask == EOS */ if(*mask != '?' && *mask != *name) name -= (size_t)(mask - last) - 1, mask = last; } } /* * ServiceGetClientIcon * MS_FP_GETCLIENTICON service implementation. * wParam - char * MirVer value to get client for. * lParam - int noCopy - if wParam is equal to "1" will return icon handler without copiing icon. */ int ServiceGetClientIcon(WPARAM wParam, LPARAM lParam) { char *szMirVer=(char*)wParam; // MirVer value to get client for. /* static HICON hIcon=NULL; // returned HICON if (hIcon) { DestroyIcon(hIcon); hIcon=NULL; } */ if (!szMirVer) return 0; { HICON hIcon=NULL; // returned HICON int NoCopy=(int)lParam; // noCopy HICON icMain=NULL; HICON icOverlay=NULL; HICON icOverlay2=NULL; HICON icOverlay3=NULL; BOOL needFreeBase=FALSE; BOOL needFreeOverlay=FALSE; BOOL needFreeOverlay2=FALSE; BOOL needFreeOverlay3=FALSE; short base=-1, overlay=-1, overlay2=-1, overlay3=-1; BYTE Index=0xFF; short i=0; short j, k, l; char MirVer[256]; mir_strncpy(MirVer, szMirVer, sizeof(MirVer)); mir_strupr(MirVer); while (iszIconFileName,LIB_USE,mainMask->szIconName,mainMask->SectionFlag,mainMask->szClientDescription,mainMask->iIconIndex,&needFreeBase); if (icMain) { KN_FP_MASK * overlayMask=(overlay!=-1)?&(def_kn_fp_overlays_mask[overlay]):NULL; KN_FP_MASK * overlay2Mask=(overlay2!=-1)?&(def_kn_fp_overlays2_mask[overlay2]):NULL; KN_FP_MASK * overlay3Mask=(overlay3!=-1)?&(def_kn_fp_overlays3_mask[overlay3]):NULL; icOverlay=(overlayMask==NULL)?NULL:LoadIconFromExternalFile(overlayMask->szIconFileName,LIB_USE,overlayMask->szIconName,overlayMask->SectionFlag,overlayMask->szClientDescription,overlayMask->iIconIndex,&needFreeOverlay); icOverlay2=(overlay2Mask==NULL)?NULL:LoadIconFromExternalFile(overlay2Mask->szIconFileName,LIB_USE,overlay2Mask->szIconName,overlay2Mask->SectionFlag,overlay2Mask->szClientDescription,overlay2Mask->iIconIndex,&needFreeOverlay2); icOverlay3=(overlay3Mask==NULL)?NULL:LoadIconFromExternalFile(overlay3Mask->szIconFileName,LIB_USE,overlay3Mask->szIconName,overlay3Mask->SectionFlag,overlay3Mask->szClientDescription,overlay3Mask->iIconIndex,&needFreeOverlay3); hIcon=icMain; if (overlayMask) hIcon=CreateJoinedIcon(hIcon,icOverlay); if (overlay2Mask) { HICON hTmp = hIcon; hIcon=CreateJoinedIcon(hIcon,icOverlay2); if (overlayMask && hTmp) DestroyIcon(hTmp); } if (overlay3Mask) { HICON hTmp = hIcon; hIcon=CreateJoinedIcon(hIcon,icOverlay3); if (overlayMask && hTmp) DestroyIcon(hTmp); } } } if (hIcon==icMain) hIcon=CopyIcon(icMain); FreeIcon(icMain,needFreeBase); FreeIcon(icOverlay,needFreeOverlay); FreeIcon(icOverlay2,needFreeOverlay2); FreeIcon(icOverlay3,needFreeOverlay3); /* if (hIcon && !NoCopy) return (int)CopyIcon(hIcon); */ return (int)hIcon; } } /* * ServiceSameClient * MS_FP_SAMECLIENTS service implementation. * wParam - char * first MirVer value * lParam - char * second MirVer value * return pointer to char string - client desription (do not destroy) if clients are same */ int ServiceSameClients(WPARAM wParam, LPARAM lParam) { char * szMirVerFirst =(char*)wParam; // MirVer value to get client for. char * szMirVerSecond =(char*)lParam; // MirVer value to get client for. int firstIndex, secondIndex; BOOL Result=FALSE; firstIndex=secondIndex=0; if (!szMirVerFirst || !szMirVerSecond) return (int)NULL; //one of its is not null { char MirVerFirst[256], MirVerSecond[256]; mir_strncpy(MirVerFirst, szMirVerFirst, sizeof(MirVerFirst)); mir_strncpy(MirVerSecond, szMirVerSecond, sizeof(MirVerSecond)); mir_strupr(MirVerFirst); mir_strupr(MirVerSecond); while (firstIndex>3)))&(0x01<<(7-(x&0x07))))!=0; } /* * blend - alpha blend ARGB values of 2 pixels. X1 - underlaying, * X2 - overlaying points. */ DWORD FASTCALL blend(DWORD X1,DWORD X2) { RGBA *q1 = (RGBA*)&X1; RGBA *q2 = (RGBA*)&X2; BYTE a_1=~q1->a; BYTE a_2=~q2->a; WORD am=q1->a*a_2; WORD ar=q1->a+((a_1*q2->a)/255); // if a2 more than 0 than result should be more // or equal (if a1==0) to a2, else in combination // with mask we can get here black points ar=(q2->a > ar)?q2->a:ar; if (ar==0) return 0; { WORD arm=ar*255; WORD rr=((q1->r*am + q2->r*q2->a*255))/arm; WORD gr=((q1->g*am + q2->g*q2->a*255))/arm; WORD br=((q1->b*am + q2->b*q2->a*255))/arm; return (ar<<24)|(rr<<16)|(gr<<8)|br; } } /* * CreateJoinedIcon - creates new icon by drawing hTop over hBottom. */ HICON FASTCALL CreateJoinedIcon(HICON hBottom, HICON hTop) { BOOL drawn = 0; HDC tempDC, tempDC2, tempDC3; HICON res=NULL; HBITMAP oImage,nImage; HBITMAP nMask, hbm, obmp, obmp2; BITMAP bmp={0}; BYTE *ptPixels = NULL; ICONINFO iNew={0}; BYTE p[32] = {0}; tempDC=CreateCompatibleDC(NULL); nImage=CreateBitmap32Point(16,16,(void**)&ptPixels); oImage=SelectObject(tempDC,nImage); // if (ptPixels) memset(ptPixels,0,16*16*4); if (IsWinVerXPPlus()) { ICONINFO iciBottom={0}; ICONINFO iciTop={0}; BITMAP bmp_top={0}; BITMAP bmp_top_mask={0}; BITMAP bmp_bottom={0}; BITMAP bmp_bottom_mask={0}; GetIconInfo(hBottom,&iciBottom); GetObject(iciBottom.hbmColor,sizeof(BITMAP),&bmp_bottom); GetObject(iciBottom.hbmMask,sizeof(BITMAP),&bmp_bottom_mask); GetIconInfo(hTop,&iciTop); GetObject(iciTop.hbmColor,sizeof(BITMAP),&bmp_top); GetObject(iciTop.hbmMask,sizeof(BITMAP),&bmp_top_mask); if (bmp_bottom.bmBitsPixel==32 &&bmp_top.bmBitsPixel==32) { BYTE * BottomBuffer, * TopBuffer, * BottomMaskBuffer, * TopMaskBuffer; BYTE * bb, * tb, * bmb, * tmb; BYTE * db=ptPixels; int vstep_d=16*4; int vstep_b=bmp_bottom.bmWidthBytes; int vstep_t=bmp_top.bmWidthBytes; int vstep_bm=bmp_bottom_mask.bmWidthBytes; int vstep_tm=bmp_top_mask.bmWidthBytes; if (bmp_bottom.bmBits) bb=BottomBuffer=(BYTE*)bmp_bottom.bmBits; else { BottomBuffer=(BYTE*)_alloca(bmp_bottom.bmHeight*bmp_bottom.bmWidthBytes); GetBitmapBits(iciBottom.hbmColor,bmp_bottom.bmHeight*bmp_bottom.bmWidthBytes,BottomBuffer); bb=BottomBuffer+vstep_b*(bmp_bottom.bmHeight-1); vstep_b=-vstep_b; } if (bmp_top.bmBits) tb=TopBuffer=(BYTE*)bmp_top.bmBits; else { TopBuffer=(BYTE*)_alloca(bmp_top.bmHeight*bmp_top.bmWidthBytes); GetBitmapBits(iciTop.hbmColor,bmp_top.bmHeight*bmp_top.bmWidthBytes,TopBuffer); tb=TopBuffer+vstep_t*(bmp_top.bmHeight-1); vstep_t=-vstep_t; } if (bmp_bottom_mask.bmBits) bmb=BottomMaskBuffer=(BYTE*)bmp_bottom_mask.bmBits; else { BottomMaskBuffer=(BYTE*)_alloca(bmp_bottom_mask.bmHeight*bmp_bottom_mask.bmWidthBytes); GetBitmapBits(iciBottom.hbmMask,bmp_bottom_mask.bmHeight*bmp_bottom_mask.bmWidthBytes,BottomMaskBuffer); bmb=BottomMaskBuffer+vstep_bm*(bmp_bottom_mask.bmHeight-1); vstep_bm=-vstep_bm; } if (bmp_top_mask.bmBits) tmb=TopMaskBuffer=(BYTE*)bmp_top_mask.bmBits; else { TopMaskBuffer=(BYTE*)_alloca(bmp_top_mask.bmHeight*bmp_top_mask.bmWidthBytes); GetBitmapBits(iciTop.hbmMask,bmp_top_mask.bmHeight*bmp_top_mask.bmWidthBytes,TopMaskBuffer); tmb=TopMaskBuffer+vstep_tm*(bmp_top_mask.bmHeight-1); vstep_tm=-vstep_tm; } { int x; int y; BOOL topHasAlpha = checkHasAlfa(TopBuffer,bmp_top.bmWidthBytes,bmp_top.bmHeight); BOOL bottomHasAlpha = checkHasAlfa(BottomBuffer,bmp_bottom.bmWidthBytes,bmp_bottom.bmHeight); BOOL topHasMask = !topHasAlpha && checkHasMask(TopMaskBuffer); BOOL bottomHasMask = !bottomHasAlpha && checkHasMask(BottomMaskBuffer); for (y=0; y<16; y++) { for (x=0; x<16; x++) { DWORD bottom_d=((DWORD*)bb)[x]; DWORD top_d=((DWORD*)tb)[x]; if (topHasMask) { if (GetMaskBit(tmb,x)) top_d&=0xFFFFFF; else top_d|=0xFF000000; } if (bottomHasMask) { if (GetMaskBit(bmb,x)) bottom_d&=0xFFFFFF; else bottom_d|=0xFF000000; } ((DWORD*)db)[x]=blend(bottom_d,top_d); } bb+=vstep_b; tb+=vstep_t; bmb+=vstep_bm; tmb+=vstep_tm; db+=vstep_d; } } drawn = 1; } DeleteObject(iciBottom.hbmColor); DeleteObject(iciTop.hbmColor); DeleteObject(iciBottom.hbmMask); DeleteObject(iciTop.hbmMask); } if (!drawn) { DrawIconEx(tempDC,0,0,hBottom,16,16,0,NULL,DI_NORMAL); DrawIconEx(tempDC,0,0,hTop,16,16,0,NULL,DI_NORMAL); } nMask=CreateBitmap(16,16,1,1,(void*)&p); tempDC2=CreateCompatibleDC(NULL); tempDC3=CreateCompatibleDC(NULL); hbm=CreateCompatibleBitmap(tempDC3,16,16); obmp=SelectObject(tempDC2,nMask); obmp2=SelectObject(tempDC3,hbm); DrawIconEx(tempDC2,0,0,hBottom,16,16,0,NULL,DI_MASK); DrawIconEx(tempDC3,0,0,hTop,16,16,0,NULL,DI_MASK); BitBlt(tempDC2,0,0,16,16,tempDC3,0,0,SRCAND); GdiFlush(); SelectObject(tempDC2,obmp); DeleteDC(tempDC2); SelectObject(tempDC3,obmp2); DeleteDC(tempDC3); SelectObject(tempDC,oImage); DeleteDC(tempDC); DeleteObject(hbm); iNew.fIcon=TRUE; iNew.hbmColor=nImage; iNew.hbmMask=nMask; res=CreateIconIndirect(&iNew); DeleteObject(nImage); DeleteObject(nMask); return res; } BYTE FASTCALL GetIconIndexFromFI(short base, short overlay, short overlay2, short overlay3) { int i; DWORD val; BYTE found=0xFF; BOOL needFreeBase=FALSE, needFreeOverlay=FALSE, needFreeOverlay2=FALSE, needFreeOverlay3=FALSE; if (base==-1 || nFICount == 0xFF) return found; val = (base<<24)|((overlay&0xFF)<<16)|((overlay2&0xFF)<<8)|(overlay3&0xFF); for (i=0; iszIconFileName,LIB_USE,mainMask->szIconName,mainMask->SectionFlag,mainMask->szClientDescription,mainMask->iIconIndex,&needFreeBase); fiList=realloc(fiList,sizeof(FOUNDINFO)*(nFICount+1)); fiList[nFICount].array=val; if (icMain!=NULL) { KN_FP_MASK * overlayMask=(overlay!=-1)?&(def_kn_fp_overlays_mask[overlay]):NULL; KN_FP_MASK * overlay2Mask=(overlay2!=-1)?&(def_kn_fp_overlays2_mask[overlay2]):NULL; KN_FP_MASK * overlay3Mask=(overlay3!=-1)?&(def_kn_fp_overlays3_mask[overlay3]):NULL; HICON icOverlay=(overlayMask==NULL)?NULL:LoadIconFromExternalFile(overlayMask->szIconFileName,LIB_USE,overlayMask->szIconName,overlayMask->SectionFlag,overlayMask->szClientDescription,overlayMask->iIconIndex,&needFreeOverlay); HICON icOverlay2=(overlay2Mask==NULL)?NULL:LoadIconFromExternalFile(overlay2Mask->szIconFileName,LIB_USE,overlay2Mask->szIconName,overlay2Mask->SectionFlag,overlay2Mask->szClientDescription,overlay2Mask->iIconIndex,&needFreeOverlay2); HICON icOverlay3=(overlay3Mask==NULL)?NULL:LoadIconFromExternalFile(overlay3Mask->szIconFileName,LIB_USE,overlay3Mask->szIconName,overlay3Mask->SectionFlag,overlay3Mask->szClientDescription,overlay3Mask->iIconIndex,&needFreeOverlay3); HICON icRes=icMain; if (overlayMask) icRes = CreateJoinedIcon(icRes,icOverlay); if (overlay2Mask) { HICON hTmp = icRes; icRes=CreateJoinedIcon(icRes,icOverlay2); if (overlayMask && hTmp) DestroyIcon(hTmp); } if (overlay3Mask) { HICON hTmp = icRes; icRes=CreateJoinedIcon(icRes,icOverlay3); if (overlayMask && hTmp) DestroyIcon(hTmp); } fiList[nFICount].registeredIndex=(icRes)?CallService(MS_CLIST_EXTRA_ADD_ICON,(WPARAM)icRes,0):0xFF; found=fiList[nFICount].registeredIndex; if (icRes && icRes!=icMain) DestroyIcon(icRes); FreeIcon(icMain,needFreeBase); FreeIcon(icOverlay,needFreeOverlay); FreeIcon(icOverlay2,needFreeOverlay2); FreeIcon(icOverlay3,needFreeOverlay3); } else { fiList[nFICount].registeredIndex=0xFF; } nFICount++; } return found; } void FASTCALL ClearFI() { if (fiList!=NULL) free(fiList); fiList=NULL; nFICount=0; return; } // (c) by George Hazan int FASTCALL DBGetStaticString(HANDLE hContact, const char* moduleName, const char* valueName, char* dest, int dest_len) { DBVARIANT dbv; DBCONTACTGETSETTING sVal; dbv.pszVal = dest; dbv.cchVal = dest_len; dbv.type = DBVT_ASCIIZ; sVal.pValue = &dbv; sVal.szModule = moduleName; sVal.szSetting = valueName; if (CallService(MS_DB_CONTACT_GETSETTINGSTATIC, ( WPARAM )hContact, ( LPARAM )&sVal ) != 0) return 1; return (dbv.type != DBVT_ASCIIZ); }