From cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 14:14:52 +0000 Subject: svn.miranda.im is moving to a new home! git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- splashscreen/src/main.cpp | 534 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 534 insertions(+) create mode 100644 splashscreen/src/main.cpp (limited to 'splashscreen/src/main.cpp') diff --git a/splashscreen/src/main.cpp b/splashscreen/src/main.cpp new file mode 100644 index 0000000..90f83b4 --- /dev/null +++ b/splashscreen/src/main.cpp @@ -0,0 +1,534 @@ +/* + Splash Screen Plugin for Miranda-IM (www.miranda-im.org) + (c) 2004-2007 nullbie, (c) 2005-2007 Thief + + 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 + + File name : $URL: http://svn.miranda.im/mainrepo/splashscreen/trunk/src/main.cpp $ + Revision : $Rev: 1586 $ + Last change on : $Date: 2010-04-09 12:34:01 +0300 (Пт, 09 апр 2010) $ + Last change by : $Author: Thief $ + +*/ + +#include "headers.h" + +HINSTANCE hInst = 0; +PLUGINLINK *pluginLink; + +static HMODULE hUserDll = NULL; +static HMODULE hAdvaimg = NULL; + +pfnConvertPng2dib png2dibConvertor = NULL; + +bool bstartup = true; // startup? +bool bserviceinvoked = false; +bool bmodulesloaded = false; // modules are loaded +bool png2dibavail = true; // can we use png2dib service? + +char *mirandaVerString; +char szPrefix[128]; +PVOID pVerInfo; + +// path to miranda's dir, config file path, splash path, sound path +char szMirDir[MAX_PATH], szIniFile[MAX_PATH], szDllName[MAX_PATH], szSplashFile[MAX_PATH], szSoundFile [MAX_PATH], szhAdvaimgPath [MAX_PATH]; +#ifdef _DEBUG +char szLogFile[MAX_PATH]; +#endif +static char inBuf[80]; + +SPLASHOPTS options; + +// Options handle. Declarated in options.cpp +extern BOOL CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +extern int OptInit(WPARAM wParam, LPARAM lParam); +extern bool ShowSplash(bool bpreview); +extern void ReadIniConfig(); + +HANDLE hShowSplashService, hTestService; +// Service functions declarated in service.cpp +extern int ShowSplashService(WPARAM wparam,LPARAM lparam); +#ifdef _DEBUG +extern int TestService(WPARAM wParam,LPARAM lParam); +#endif + +extern BOOL (WINAPI *MyUpdateLayeredWindow) + (HWND hwnd, HDC hdcDST, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, + COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags); +extern HWND hwndSplash; + +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + #ifndef _DEBUG + "Splash Screen", + #else + "Splash Screen (Debug)", + #endif + __VERSION_DWORD, + "Shows a splash at Miranda startup", + "nullbie, Thief", + "thief@miranda.im", + "2004-2007 Victor Pavlychko, 2005-2010 Alexander Turyak ["BuildDate"]", + "http://addons.miranda-im.org/details.php?id=2624", + 0, //not transient + 0, //doesn't replace anything built-in + {0xc64cc8e0, 0xcf03, 0x474a, {0x8b, 0x11, 0x8b, 0xd4, 0x56, 0x5c, 0xcf, 0x04}} /* C64CC8E0-CF03-474A-8B11-8BD4565CC */ +}; + +PLUGININFO oldpluginInfo={ + sizeof(PLUGININFO), + pluginInfo.shortName, + pluginInfo.version, + pluginInfo.description, + pluginInfo.author, + pluginInfo.authorEmail, + pluginInfo.copyright, + pluginInfo.homepage, + pluginInfo.flags, + pluginInfo.replacesDefaultModule +}; + +/* 91CB1E8D-C33C-43C0-BDD8-6725B070B3E0 */ +#define MIID_SPLASHSCREEN {0x91cb1e8d, 0xc33c, 0x43c0, {0xbd, 0xd8, 0x67, 0x25, 0xb0, 0x70, 0xb3, 0xe0}} + +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + static const MUUID interfaces[] = {MIID_SPLASHSCREEN, MIID_LAST}; + return interfaces; +} + +HANDLE hSplashThread, hModulesLoaded, hPlugDisableHook, hOptInit, hSystemOKToExit; +LRESULT CALLBACK SplashWindowProc(HWND, UINT, WPARAM, LPARAM); +int ModulesLoaded(WPARAM wParam,LPARAM lParam); +int PlugDisableHook(WPARAM wParam,LPARAM lParam); +int onSystemOKToExit(WPARAM wParam,LPARAM lParam); + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +void SplashMain() +{ +if (bstartup) +{ + DWORD unused; + DWORD verInfoSize; + UINT blockSize; + + // Retrive path to exe of current running Miranda is located + GetModuleFileName(GetModuleHandle(NULL), szMirDir, sizeof(szMirDir)); + + verInfoSize = GetFileVersionInfoSizeA(szMirDir,&unused); + pVerInfo = /*mir_*/malloc(verInfoSize); + GetFileVersionInfoA(szMirDir,0,verInfoSize,pVerInfo); + VerQueryValueA(pVerInfo,"\\StringFileInfo\\000004b0\\ProductVersion",(PVOID*)&mirandaVerString,&blockSize); + + // Remove 'miranda32.exe' from string + char *pos; + pos = strrchr(szMirDir, '\\'); + if(pos != NULL) *pos = 0; + lstrcat(szMirDir,"\\"); + + // Get the name string of plugin's dll name whatever it named + static char* sztmpstr; + GetModuleFileName(hInst, szDllName, sizeof(szDllName)); + sztmpstr = _strrev(szDllName); + pos = strchr(sztmpstr, '\\'); + if(pos != NULL) *pos = 0; + strcpy(szDllName, _strrev(sztmpstr)); + + static char szPath[MAX_PATH]; + + lstrcat(szPath,szMirDir); + lstrcat(szPath,"plugins\\splash.ini"); + lstrcat(szhAdvaimgPath,szMirDir); + lstrcat(szhAdvaimgPath,"plugins\\advaimg.dll"); + + #ifdef _DEBUG + lstrcat(szLogFile,szMirDir); + lstrcat(szLogFile,PlugName); + lstrcat(szLogFile,".log"); + #endif + + #ifdef _DEBUG + initLog(); + logTimeStamp(); + #endif + + #ifdef _DEBUG + logMessage("Miranda version", mirandaVerString); + #endif + + static char szMirandaBootIni[MAX_PATH]; + lstrcat(szMirandaBootIni,szMirDir); + lstrcat(szMirandaBootIni,"mirandaboot.ini"); + GetPrivateProfileString("Splash","Ini","",inBuf,sizeof(inBuf),szMirandaBootIni); + if (strlen(inBuf)) + { + char szExpandedIniPath[MAX_PATH]; + ExpandEnvironmentStringsA(inBuf, szExpandedIniPath,sizeof(szExpandedIniPath)); + lstrcat(szIniFile,szExpandedIniPath); + } + else + { + FILE *fp; + fp = fopen(szPath, "r"); + if (!fp) + { + #ifdef _DEBUG + logMessage("error! couldn't open", szPath); + #endif + + lstrcat(szIniFile,szMirDir); + lstrcat(szIniFile,"mirandaboot.ini"); + } + else + { + lstrcat(szIniFile,szPath); + fclose(fp); + } + } + + ReadIniConfig(); + + #ifdef _DEBUG + logMessage("Dll Name", szDllName); + logMessage("Ini path",szIniFile); + logMessage("Advaimg path", szhAdvaimgPath); + #endif +} + +if (bstartup & (options.active == 1)) { + + if (options.runonce) + { + WritePrivateProfileString("Splash","Active","0",szIniFile); + WritePrivateProfileString("Splash","DisableAfterStartup","0",szIniFile); + } + + if (hUserDll == NULL) + { + hUserDll = LoadLibrary("user32.dll"); + if (hUserDll) + { + MyUpdateLayeredWindow = (BOOL (WINAPI *)(HWND, HDC, POINT *, SIZE *, HDC, POINT *, COLORREF, BLENDFUNCTION *, DWORD))GetProcAddress(hUserDll, "UpdateLayeredWindow"); + } + } + + if (hAdvaimg == NULL) + { + hAdvaimg = LoadLibrary(szhAdvaimgPath); + if (hAdvaimg == NULL) + { + png2dibavail = false; + bstartup = false; + } + if (hAdvaimg) + { + png2dibConvertor = (pfnConvertPng2dib) GetProcAddress(hAdvaimg, "mempng2dib"); + if (png2dibConvertor == NULL) + { + FreeLibrary(hAdvaimg); hAdvaimg = NULL; + MessageBoxA(NULL, + "Your advaimg.dll is either obsolete or damaged. Get latest from Miranda alpha builds.", + "Error", + MB_OK | MB_ICONSTOP); + } + #ifdef _DEBUG + if (png2dibConvertor) logMessage("Loading advaimg","done"); + #endif + } + } + + //for 9x "alfa" testing + //MyUpdateLayeredWindow = 0; + + GetPrivateProfileString("Splash","VersionPrefix","",inBuf,sizeof(inBuf),szIniFile); + strcpy(szPrefix,inBuf); + + GetPrivateProfileString("Splash","Path","splash\\splash.png",inBuf,sizeof(inBuf),szIniFile); + + char szExpandedSplashFile[MAX_PATH]; + ExpandEnvironmentStringsA(inBuf, szExpandedSplashFile,sizeof(szExpandedSplashFile)); + lstrcpy(inBuf, szExpandedSplashFile); + + char *pos3 = 0; + pos3 = strrchr(inBuf, ':'); + if (pos3 == NULL) + { + lstrcpy(szSplashFile, szMirDir); + } + + lstrcat(szSplashFile, inBuf); + + GetPrivateProfileString("Splash","Sound","sounds\\startup.wav",inBuf,sizeof(inBuf),szIniFile); + + char szExpandedSoundFile[MAX_PATH]; + ExpandEnvironmentStringsA(inBuf, szExpandedSoundFile,sizeof(szExpandedSoundFile)); + lstrcpy(inBuf, szExpandedSoundFile); + + char *pos2; + pos2 = strchr(inBuf, ':'); + if (pos2 == NULL) + { + lstrcat(szSoundFile, szMirDir); + } + + lstrcat(szSoundFile, inBuf); + + #ifdef _DEBUG + logMessage("SoundFilePath",szSoundFile); + #endif + + char szOldPath[MAX_PATH] = {0}; + + if(options.random) // randomly select a splash file + { + int filescount = 0; + char szSplashDir[MAX_PATH] = {0}, szSearch[MAX_PATH] = {0}; + char* p = 0; + char files [255][50]; //TODO: make memory allocation dynamic + + lstrcpy(szSplashDir, szSplashFile); + lstrcpy(szOldPath, szSplashFile); + // find the last \ and null it out, this leaves no trailing slash + p = strrchr(szSplashDir, '\\'); + if (p) *p = 0; + // create the search filter + mir_snprintf(szSearch,sizeof(szSearch),"%s\\*.*", szSplashDir); + // FFFN will return filenames + HANDLE hFind = INVALID_HANDLE_VALUE; + WIN32_FIND_DATAA ffd; + hFind = FindFirstFileA(szSearch, &ffd); + if ( hFind != INVALID_HANDLE_VALUE ) + { + do + { + if (!(ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) + { + #ifdef _DEBUG + logMessage("Found file",ffd.cFileName); + #endif + //files = new char[strlen(ffd.cFileName)]; + //files[filescount] = new char[strlen(ffd.cFileName)]; + char ext[5]; + memcpy(ext,ffd.cFileName+(strlen(ffd.cFileName)-4),5); + + #ifdef _DEBUG + logMessage("Extention",ext); + #endif + + if (lstrcmpi(ext,".png") & lstrcmpi(ext,".bmp")) + continue; + + #ifdef _DEBUG + logMessage("File has valid ext",ext); + #endif + strcpy(files[filescount++],ffd.cFileName); + } //if + } while (FindNextFileA(hFind, &ffd)); + + srand((unsigned) time(NULL)); + int r = 0; + if (filescount) r = (rand() % filescount) + 1; + + ZeroMemory(&szSplashFile,sizeof(szSplashFile)); + lstrcpy(szSplashFile, szSplashDir); + lstrcat(szSplashFile,"\\"); + lstrcat(szSplashFile,files[r-1]); + + #ifdef _DEBUG + logMessage("final file",szSplashFile); + #endif + FindClose(hFind); + } //if + } + + // Call splash display routine + ShowSplash(false); + + if (options.random) + { + ZeroMemory(&szSplashFile,sizeof(szSplashFile)); + lstrcpy(szSplashFile, szOldPath); + } + + } + bstartup = false; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + SplashMain(); + return &pluginInfo; +} + +extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) +{ + SplashMain(); + return &oldpluginInfo; +} + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink = link; + + hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); + hSystemOKToExit = HookEvent(ME_SYSTEM_OKTOEXIT,onSystemOKToExit); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + free(pVerInfo); + + if (hSplashThread) CloseHandle(hSplashThread); + + UnregisterClass(SPLASH_CLASS, hInst); + + // Freeing loaded libraries + if (hUserDll) FreeLibrary(hUserDll); + if (hAdvaimg) FreeLibrary(hAdvaimg); + + #ifdef _DEBUG + logMessage("Unload","Job done"); + #endif + + return 0; +} + +int onSystemOKToExit(WPARAM wParam,LPARAM lParam) +{ + // Hooked events need to be unhooked + UnhookEvent(hModulesLoaded); + UnhookEvent(hSystemOKToExit); + UnhookEvent(hPlugDisableHook); + UnhookEvent(hOptInit); + + DestroyServiceFunction(hShowSplashService); + #ifdef _DEBUG + DestroyServiceFunction(hTestService); + #endif + + return 0; +} + +int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + bmodulesloaded = true; // all modules are loaded now, let other parts know about this fact + + if (hwndSplash) + { + if (PostMessage(hwndSplash, WM_LOADED, 0, 0)) + { + #ifdef _DEBUG + logMessage("Posted WM_LOADED message","done"); + #endif + } + } + + // Options initialize hook + hOptInit = HookEvent(ME_OPT_INITIALISE, OptInit); + + hPlugDisableHook = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, PlugDisableHook); + + // Service to call splash + hShowSplashService = CreateServiceFunction(MS_SHOWSPLASH, ShowSplashService); + + #ifdef _DEBUG + hTestService = CreateServiceFunction("Splash/Test",TestService); + CLISTMENUITEM mi; + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = 0; + mi.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + mi.hotKey = 0; + mi.position = -0x7FFFFFFF; + mi.pszName = "Call Splash Service"; + mi.pszService = "Splash/Test"; + + CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi); + #endif + + if (ServiceExists(MS_UPDATE_REGISTER)) + { + // register with updater + Update update = {0}; + char szVersion[16]; + + update.cbSize = sizeof(Update); + + update.szComponentName = pluginInfo.shortName; + update.pbVersion = (BYTE *)CreateVersionString(pluginInfo.version, szVersion); + update.cpbVersion = strlen((char *)update.pbVersion); + + update.szUpdateURL = UPDATER_AUTOREGISTER; + + // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) + // before the version that we use to locate it on the page + // (note that if the update URL and the version URL point to standard file listing entries, the backend xml + // data will be used to check for updates rather than the actual web page - this is not true for beta urls) + update.szBetaUpdateURL = "http://thief.miranda.im/advsplashscreen.zip"; + update.szBetaVersionURL = "http://thief.miranda.im/updater/splash_version.txt"; + update.szBetaChangelogURL = "http://thief.miranda.im"; + update.pbBetaVersionPrefix = (BYTE *)"Splash Screen "; + + update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix); + + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + } + + #ifdef _DEBUG + logMessage("Loading modules","done"); + #endif + + return 0; +} + +int PlugDisableHook(WPARAM wParam, LPARAM lParam) +{ + char buf [128]; + DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; + if(options.inheritGS) + if (!lstrcmp(cws->szModule,"Skin") & !lstrcmp(cws->szSetting,"UseSound")) + { + sprintf(buf,"%d",cws->value.bVal); + WritePrivateProfileString("Splash","PlaySound",buf,szIniFile); + #ifdef _DEBUG + cws->value.bVal ? _DebugPopup(NULL, "Sounds enabled.", "") : _DebugPopup(NULL, "Sounds disabled.", ""); + logMessage("Module",cws->szModule); + logMessage("Setting",cws->szSetting); + logMessage("Value",buf); + #endif + } + if (!lstrcmp(cws->szModule,"PluginDisable") & (!lstrcmp(cws->szSetting,szDllName))) + { + sprintf(buf,"%d",!cws->value.bVal); + WritePrivateProfileString("Splash","Active",buf,szIniFile); + + #ifdef _DEBUG + cws->value.bVal ? _DebugPopup(NULL, "Disabled.", "") : _DebugPopup(NULL, "Enabled.", ""); + logMessage("PlugDisableHook","Triggered"); + logMessage("Module",cws->szModule); + logMessage("Setting",cws->szSetting); + logMessage("Value",buf); + #endif + } + + return 0; +} -- cgit v1.2.3