/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2008 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ //include #include "hdr/modern_commonheaders.h" #include "hdr/modern_commonprototypes.h" #include "version.h" #include "hdr/modern_clui.h" #include "hdr/modern_clcpaint.h" //definitions #define CHECKRES(sub) if (sub!=S_OK) return S_FALSE; HINSTANCE g_hInst = 0; PLUGINLINK * pluginLink=NULL; CLIST_INTERFACE *pcli=NULL; CLIST_INTERFACE corecli={0}; CLUIDATA g_CluiData={0}; int hLangpack; MM_INTERFACE mmi; LIST_INTERFACE li; UTF8_INTERFACE utfi; TIME_API tmi; pfnTryEnterCriticalSection fnTryEnterCriticalSection; pfnGetAncestor fnGetAncestor; pfnGetMenuBarInfo fnGetMenuBarInfo; pfnGetScrollBarInfo fnGetScrollBarInfo; pfnMsgWaitForMultipleObjectsEx fnMsgWaitForMultipleObjectsEx; static HRESULT SubclassClistInterface(); static HRESULT CreateHookableEvents(); int EventArea_UnloadModule(); PLUGININFOEX pluginInfo = { sizeof(PLUGININFOEX), DEBUG_AWARE_STR "Modern Contact List '09", 0, //will initialized later in MirandaPluginInfoEx "Display contacts, event notifications, protocol status with advantage visual modifications. Supported MW modifications, enchanced metacontact cooperation.", "Artem Shpynov, Ricardo Pescuma Domenecci and Anton Senko based on clist_mw by Bethoven", "ashpynov@gmail.com" , "Copyright 2000-2010 Miranda-IM project ["__DATE__" "__TIME__"]", "http://miranda-im.org/development", UNICODE_AWARE, DEFMOD_CLISTALL, #ifdef UNICODE {0x43909b6, 0xaad8, 0x4d82, { 0x8e, 0xb5, 0x9f, 0x64, 0xcf, 0xe8, 0x67, 0xcd }} //{043909B6-AAD8-4d82-8EB5-9F64CFE867CD} #else {0xf6588c56, 0x15dc, 0x4cd7, { 0x8c, 0xf9, 0x48, 0xab, 0x6c, 0x5f, 0xd2, 0xf }} //{F6588C56-15DC-4cd7-8CF9-48AB6C5FD20F} #endif }; static const MUUID interfaces[] = {MIID_CLIST, MIID_LAST}; PLUGININTERFACE const MUUID * MirandaPluginInterfaces(void) { return interfaces; } BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved) { g_hInst = hInstDLL; DisableThreadLibraryCalls(g_hInst); return TRUE; } inline int MakeVer(int a, int b, int c, int d) { return PLUGIN_MAKE_VERSION(a,b,c,d); } PLUGININTERFACE PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { if ( mirandaVersion < MINIMAL_COREVERSION_NUM ) return NULL; pluginInfo.version=MakeVer(PRODUCT_VERSION); return &pluginInfo; } PLUGININTERFACE int CListInitialise(PLUGINLINK * link) { pluginLink=link; /* #ifdef _DEBUG _CrtSetBreakAlloc(11166); #endif */ HMODULE hKernel = GetModuleHandleA( "kernel32.dll" ); fnTryEnterCriticalSection = ( pfnTryEnterCriticalSection )GetProcAddress( hKernel, "TryEnterCriticalSection" ); HMODULE hUser = GetModuleHandleA( "user32.dll" ); fnGetMenuBarInfo = ( pfnGetMenuBarInfo )GetProcAddress( hUser, "GetMenuBarInfo" ); fnGetScrollBarInfo = ( pfnGetScrollBarInfo )GetProcAddress( hUser, "GetScrollBarInfo" ); fnMsgWaitForMultipleObjectsEx = ( pfnMsgWaitForMultipleObjectsEx )GetProcAddress( hUser, "MsgWaitForMultipleObjectsEx" ); if (( fnGetAncestor = ( pfnGetAncestor )GetProcAddress( hUser, "GetAncestor" )) == NULL ) fnGetAncestor = MyGetAncestor; g_dwMainThreadID = GetCurrentThreadId(); DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),&g_hMainThread,0,FALSE,DUPLICATE_SAME_ACCESS); mir_getMMI(&mmi); mir_getUTFI(&utfi); mir_getLI(&li); mir_getTMI(&tmi); mir_getLP( &pluginInfo ); CHECKRES ( PreLoadContactListModule ( ) ); CHECKRES ( SubclassClistInterface ( ) ); CHECKRES ( CreateHookableEvents ( ) ); CHECKRES ( XPThemesLoadModule ( ) ); CHECKRES ( SkinEngineLoadModule ( ) ); CHECKRES ( BackgroundsLoadModule ( ) ); CHECKRES ( CluiLoadModule ( ) ); CHECKRES ( ClcLoadModule ( ) ); CHECKRES ( ToolbarButtonLoadModule( ) ); CHECKRES ( ToolbarLoadModule() ); TRACE( "CListInitialise Modern Contact List ... Done\r\n" ); return S_OK; } // never called by a newer plugin loader. PLUGININTERFACE int Load(PLUGINLINK * link) { MessageBoxA(0,"You Running Old Miranda, use " MINIMAL_COREVERSION_STR " version!","Modern Clist",0); return 1; } PLUGININTERFACE int Unload(void) { TRACE("Unloading Clist Modern\r\n"); if (IsWindow(pcli->hwndContactList)) DestroyWindow(pcli->hwndContactList); pcli->hwndContactList=NULL; UnhookAll(); BackgroundsUnloadModule(); SkinEngineUnloadModule(); XPThemesUnloadModule(); UnloadAvatarOverlayIcon(); UninitSkinHotKeys(); FreeRowCell(); EventArea_UnloadModule(); TRACE("Unloading Clist Modern COMPLETE\r\n"); return 0; } static HRESULT SubclassClistInterface() { // get the contact list interface pcli = ( CLIST_INTERFACE* )CallService(MS_CLIST_RETRIEVE_INTERFACE, 0, (LPARAM)g_hInst); if ( (INT_PTR)pcli == CALLSERVICE_NOTFOUND || pcli->version < 6 ) { MessageBoxA( NULL, "This version of plugin requires Miranda IM " MINIMAL_COREVERSION_STR " or later", "Fatal error", MB_OK ); return TRUE; } // OVERLOAD CLIST INTERFACE FUNCTIONS // // Naming convention is: // 'cli*' - new handler without default core service calling // 'save*' - pointer to stored default parent handle // 'cli_*' - new handler with default core service calling corecli=*pcli; pcli->bDisplayLocked = TRUE; pcli->pfnCheckCacheItem = (void (*)(ClcCacheEntryBase*)) cliCheckCacheItem; pcli->pfnFreeCacheItem = (void(*)(ClcCacheEntryBase*)) cliFreeCacheItem; pcli->pfnInvalidateDisplayNameCacheEntry = cliInvalidateDisplayNameCacheEntry; pcli->pfnTrayIconUpdateBase = cliTrayIconUpdateBase; pcli->pfnCluiProtocolStatusChanged = cliCluiProtocolStatusChanged; pcli->pfnBeginRenameSelection = cliBeginRenameSelection; pcli->pfnCreateClcContact = cliCreateClcContact; pcli->pfnCreateCacheItem = cliCreateCacheItem; pcli->pfnGetRowBottomY = cliGetRowBottomY; pcli->pfnGetRowHeight = cliGetRowHeight; pcli->pfnGetRowTopY = cliGetRowTopY; pcli->pfnGetRowTotalHeight = cliGetRowTotalHeight; pcli->pfnInvalidateRect = CLUI__cliInvalidateRect; pcli->pfnGetCacheEntry = cliGetCacheEntry; pcli->pfnOnCreateClc = CLUI::cliOnCreateClc; pcli->pfnPaintClc = CLCPaint::cliPaintClc; pcli->pfnRebuildEntireList = cliRebuildEntireList; pcli->pfnRecalcScrollBar = cliRecalcScrollBar; pcli->pfnRowHitTest = cliRowHitTest; pcli->pfnScrollTo = cliScrollTo; pcli->pfnShowHide = cliShowHide; pcli->pfnHitTest = cliHitTest; pcli->pfnCompareContacts = cliCompareContacts; pcli->pfnBuildGroupPopupMenu= cliBuildGroupPopupMenu; pcli->pfnGetIconFromStatusMode = cliGetIconFromStatusMode; pcli->pfnFindItem = cliFindItem; pcli->pfnGetRowByIndex = cliGetRowByIndex; pcli->pfnGetRowsPriorTo = cliGetRowsPriorTo; pcli->pfnGetGroupContentsCount =cliGetGroupContentsCount; pcli->pfnCreateEvent = cliCreateEvent; pcli->pfnFindRowByText = cliFindRowByText; //partialy overloaded - call default handlers from inside pcli->pfnIconFromStatusMode = cli_IconFromStatusMode; pcli->pfnLoadCluiGlobalOpts = CLUI_cli_LoadCluiGlobalOpts; pcli->pfnSortCLC = cli_SortCLC; pcli->pfnAddGroup = cli_AddGroup; pcli->pfnGetGroupCountsText = cli_GetGroupCountsText; pcli->pfnAddContactToTree = cli_AddContactToTree; pcli->pfnAddInfoItemToGroup = cli_AddInfoItemToGroup; pcli->pfnAddItemToGroup = cli_AddItemToGroup; pcli->pfnContactListWndProc = CLUI::cli_ContactListWndProc; pcli->pfnDeleteItemFromTree = cli_DeleteItemFromTree; pcli->pfnFreeContact = cli_FreeContact; pcli->pfnFreeGroup = cli_FreeGroup; pcli->pfnChangeContactIcon = cli_ChangeContactIcon; pcli->pfnTrayIconProcessMessage = cli_TrayIconProcessMessage; pcli->pfnSaveStateAndRebuildList= cli_SaveStateAndRebuildList; pcli->pfnContactListControlWndProc = cli_ContactListControlWndProc; pcli->pfnProcessExternalMessages = cli_ProcessExternalMessages; pcli->pfnAddEvent = cli_AddEvent; pcli->pfnRemoveEvent = cli_RemoveEvent; pcli->pfnDocking_ProcessWindowMessage = Docking_ProcessWindowMessage; return S_OK; } static HRESULT CreateHookableEvents() { g_CluiData.hEventExtraImageListRebuilding = CreateHookableEvent(ME_CLIST_EXTRA_LIST_REBUILD); g_CluiData.hEventExtraImageApplying = CreateHookableEvent(ME_CLIST_EXTRA_IMAGE_APPLY); g_CluiData.hEventExtraClick = CreateHookableEvent(ME_CLIST_EXTRA_CLICK); g_CluiData.hEventBkgrChanged = CreateHookableEvent(ME_BACKGROUNDCONFIG_CHANGED); g_CluiData.hEventPreBuildTrayMenu = CreateHookableEvent(ME_CLIST_PREBUILDTRAYMENU); g_CluiData.hEventPreBuildFrameMenu = CreateHookableEvent(ME_CLIST_PREBUILDFRAMEMENU); g_CluiData.hEventPreBuildGroupMenu = CreateHookableEvent(ME_CLIST_PREBUILDGROUPMENU); g_CluiData.hEventPreBuildSubGroupMenu = CreateHookableEvent(ME_CLIST_PREBUILDSUBGROUPMENU); g_CluiData.hEventStatusBarShowToolTip = CreateHookableEvent(ME_CLIST_FRAMES_SB_SHOW_TOOLTIP); g_CluiData.hEventStatusBarHideToolTip = CreateHookableEvent(ME_CLIST_FRAMES_SB_HIDE_TOOLTIP); g_CluiData.hEventToolBarModuleLoaded = CreateHookableEvent(ME_TB_MODULELOADED); g_CluiData.hEventSkinServicesCreated = CreateHookableEvent(ME_SKIN_SERVICESCREATED); return S_OK; }