From da1c34bde32e040a0a431ffb809c3b1e425dc558 Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Tue, 22 Nov 2011 17:35:02 +0000 Subject: added FortuneAwayMsg git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@196 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- ExternalAPI/m_fortunemsg.h | 71 ++++++ FortuneAwayMsg/AggressiveOptimize.h | 165 ++++++++++++++ FortuneAwayMsg/fortune.c | 246 +++++++++++++++++++++ FortuneAwayMsg/fortune.h | 41 ++++ FortuneAwayMsg/fortuneawaymsg.dsp | 130 +++++++++++ FortuneAwayMsg/fortuneawaymsg.dsw | 29 +++ FortuneAwayMsg/main.c | 280 +++++++++++++++++++++++ FortuneAwayMsg/options.c | 429 ++++++++++++++++++++++++++++++++++++ FortuneAwayMsg/resource.h | 99 +++++++++ FortuneAwayMsg/resource.rc | 123 +++++++++++ 10 files changed, 1613 insertions(+) create mode 100644 ExternalAPI/m_fortunemsg.h create mode 100644 FortuneAwayMsg/AggressiveOptimize.h create mode 100644 FortuneAwayMsg/fortune.c create mode 100644 FortuneAwayMsg/fortune.h create mode 100644 FortuneAwayMsg/fortuneawaymsg.dsp create mode 100644 FortuneAwayMsg/fortuneawaymsg.dsw create mode 100644 FortuneAwayMsg/main.c create mode 100644 FortuneAwayMsg/options.c create mode 100644 FortuneAwayMsg/resource.h create mode 100644 FortuneAwayMsg/resource.rc diff --git a/ExternalAPI/m_fortunemsg.h b/ExternalAPI/m_fortunemsg.h new file mode 100644 index 0000000..bf13dc4 --- /dev/null +++ b/ExternalAPI/m_fortunemsg.h @@ -0,0 +1,71 @@ +/* + +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. + +*/ + +#ifndef _FORTUNEMSG_ +#define _FORTUNEMSG_ + +#define MIN_FORTUNEMSG 10 +#define MAX_FORTUNEMSG 1024 +#define FORTUNE_BUFSIZE (MAX_FORTUNEMSG + 1) + +//returns the fortune message (from a random file) +//wParam=0 +//lParam=(char *)buffer or 0 +//returns (char *)status msg (buffer if specified), or 0 on failure +//If lParam != 0 then the fortune msg is to be stored there, make sure +//its length is at least equal to FORTUNE_BUFSIZE. If lParam == 0, then +//the plugin will allocate the memory, but don't forget to free it (the +//return value) using MS_FORTUNEMSG_FREEMEMORY (but only if you specify lParam=0!!!) +#define MS_FORTUNEMSG_GETMESSAGE "FortuneMsg/GetMessage" + +//returns the fortune message for a protocol +//wParam=(char*)szProtoName +//lParam=(char *)buffer or 0 +//returns (char *)status msg (buffer if specified), or 0 on failure +//If lParam != 0 then the fortune msg is to be stored there, make sure +//its length is at least equal to FORTUNE_BUFSIZE. If lParam == 0, then +//the plugin will allocate the memory, but don't forget to free it (the +//return value) using MS_FORTUNEMSG_FREEMEMORY (but only if you specify lParam=0!!!) +#define MS_FORTUNEMSG_GETPROTOMSG "FortuneMsg/GetProtoMessage" + +//returns the fortune status message for a status +//wParam=(int)status +//lParam=(char *)buffer or 0 +//returns (char *)status msg (buffer if specified), or 0 on failure +//If lParam != 0 then the fortune msg is to be stored there, make sure +//its length is at least equal to FORTUNE_BUFSIZE. If lParam == 0, then +//the plugin will allocate the memory, but don't forget to free it (the +//return value) using MS_FORTUNEMSG_FREEMEMORY (but only if you specify lParam=0!!!) +#define MS_FORTUNEMSG_GETSTATUSMSG "FortuneMsg/GetStatusMessage" + +//frees the memory allocated by one of the other three services +//wParam=0 +//lParam=(void *)pointer to the memory to be freed +//(the returned value from one of the other three services if called with lParam=0) +//return value: 0 on success, -1 on failure (argument was NULL) +#define MS_FORTUNEMSG_FREEMEMORY "FortuneMsg/FreeMemory" + + +//this service was created for being used by Variables plugin +//wParam=0 +//lParam=(ARGUMENTSINFO *) see m_variables.h for description of the structure +//returns (char *)status msg, or 0 on failure +#define MS_FORTUNEMSG_FROMVARIABLES "FortuneMsg/FromVariables" + + +#endif diff --git a/FortuneAwayMsg/AggressiveOptimize.h b/FortuneAwayMsg/AggressiveOptimize.h new file mode 100644 index 0000000..34c6074 --- /dev/null +++ b/FortuneAwayMsg/AggressiveOptimize.h @@ -0,0 +1,165 @@ +////////////////////////////// +// Version 1.40 +// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support! +// Version 1.30 +// Nov 24th, 2000 +// Version 1.20 +// Jun 9th, 2000 +// Version 1.10 +// Jan 23rd, 2000 +// Version 1.00 +// May 20th, 1999 +// Todd C. Wilson, Fresh Ground Software +// (todd@nopcode.com) +// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) +// result in smaller exe's. +// The "trick" is to tell the compiler to not pad out the function calls; this is done +// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads +// out each and every function call. In one single 500k dll, I managed to cut out 120k +// by this alone! +// The other two "tricks" are telling the Linker to merge all data-type segments together +// in the exe file. The relocation, read-only (constants) data, and code section (.text) +// sections can almost always be merged. Each section merged can save 4k in exe space, +// since each section is padded out to 4k chunks. This is very noticeable with smaller +// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of +// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger +// programs, this is less overall, but can save at least 4k. +// Note that if you're using MFC static or some other 3rd party libs, you may get poor +// results with merging the readonly (.rdata) section - the exe may grow larger. +// To use this feature, define _MERGE_RDATA_ in your project or before this header is used. +// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results +// in a small exe. Under VC6, the program instead uses 4k, which is the same as the +// section size. The reason (from what I understand) is that 4k is the chunk size of +// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) +// will re-align the programs on this boundary. The problem with this is that all of +// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious +// exe bloat. This is very noticeable for smaller programs. +// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the +// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% +// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is* +// a previously documented switch, but was left out of the docs for some reason in VC6 and +// all of the current MSDN's - see KB:Q235956 for more information. +// Microsoft does say that using the 4k alignment will "speed up process loading", +// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe. +// Please note, however, that this will probably not change the size of the COMPRESSED +// file (either in a .zip file or in an install archive), since this 4k is all zeroes and +// gets compressed away. +// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the +// default setting for this switch. Apparently this sets the same values as the above two +// switches do. We do not use this in this header, since it smacks of a bug and not a feature. +// Thanks to Michael Geary for some additional tips! +// +// Notes about using this header in .NET +// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no +// honest or good reason why Microsoft decided to make this change, it just doesn't. +// So that is why there are a lot of <1300 #if's in the header. +// If you want to take full advantage of the VC7 linker options, you will need to do it on a +// PER PROJECT BASIS; you can no longer use a global header file like this to make it better. +// Items I strongly suggest putting in all your VC7 project linker options command line settings: +// /ignore:4078 /RELEASE +// Compiler options: +// /GL (Whole Program Optimization) +// If you're making an .EXE and not a .DLL, consider adding in: +// /GA (Optimize for Windows Application) +// Some items to consider using in your VC7 projects (not VC6): +// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings. +// /LTCG:NOSTATUS +// The classic no-padding and no-bloat compiler C/C++ switch: +// /opt:nowin98 +// +// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files) +// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS) +// +// Now, notes on using these options in VC7 vs VC6. +// VC6 consistently, for me, produces smaller code from C++ the exact same sources, +// with or without this header. On average, VC6 produces 5% smaller binaries compared +// to VC7 compiling the exact same project, *without* this header. With this header, VC6 +// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and +// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting +// in the way of code generation. However, template support is better, so there. +// Both VC6 and VC7 show the same end kind of end result savings - larger binary output +// will shave about 2% off, where as smaller projects (support DLL's, cpl's, +// activex controls, ATL libs, etc) get the best result, since the padding is usually +// more than the actual usable code. But again, VC7 does not compile down as small as VC6. +// +// The argument can be made that doing this is a waste of time, since the "zero bytes" +// will be compressed out in a zip file or install archive. Not really - it doesn't matter +// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes +// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to +// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the +// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're +// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with +// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all +// worthy developers have (all six of us), so they will need any space and LOADING TIME +// savings they will need; taking an extra 32k or more out of your end user's 64megs of +// ram on Windows 98 is Not a Good Thing. +// +// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data +// pragma will cause the output file to be un-disassembleable! (is that a word?) At least, +// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the +// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code! +// Thanks to Gëzim Pani for discovering this gem - for a full writeup on +// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize +// article. + +#ifndef _AGGRESSIVEOPTIMIZE_H_ +#define _AGGRESSIVEOPTIMIZE_H_ + +#pragma warning(disable:4711) + +#ifdef NDEBUG +// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) +#pragma optimize("gsy",on) + +#if (_MSC_VER<1300) + #pragma comment(linker,"/RELEASE") +#endif + +// Note that merging the .rdata section will result in LARGER exe's if you using +// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. +//#ifdef _MERGE_RDATA_ +//#pragma comment(linker,"/merge:.rdata=.data") +//#endif // _MERGE_RDATA_ + +//#pragma comment(linker,"/merge:.text=.data") +//#if (_MSC_VER<1300) + // In VC7, this causes problems with the relocation and data tables, so best to not merge them +// #pragma comment(linker,"/merge:.reloc=.data") +//#endif + +// Merging sections with different attributes causes a linker warning, so +// turn off the warning. From Michael Geary. Undocumented, as usual! +#if (_MSC_VER<1300) + // In VC7, you will need to put this in your project settings + #pragma comment(linker,"/ignore:4078") +#endif + +// With Visual C++ 5, you already get the 512-byte alignment, so you will only need +// it for VC6, and maybe later. +#if _MSC_VER >= 1000 + +// Option #1: use /filealign +// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. +// Either leave at 0x200 or 0x1000 +//#pragma comment(linker,"/FILEALIGN:0x200") + +// Option #2: use /opt:nowin98 +// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one. +// This is our currently preferred option, since it is fully documented and unlikely +// to break in service packs and updates. +#if (_MSC_VER<1300) + // In VC7, you will need to put this in your project settings + #pragma comment(linker,"/opt:nowin98") +#else + +// Option #3: use /align:4096 +// A side effect of using the default align value is that it turns on the above switch. +// Does nothing under Vc7 that /opt:nowin98 doesn't already give you +// #pragma comment(linker,"/ALIGN:512") +#endif + +#endif // _MSC_VER >= 1000 + +#endif // NDEBUG + +#endif // _AGGRESSIVEOPTIMIZE_H_ diff --git a/FortuneAwayMsg/fortune.c b/FortuneAwayMsg/fortune.c new file mode 100644 index 0000000..6bfebeb --- /dev/null +++ b/FortuneAwayMsg/fortune.c @@ -0,0 +1,246 @@ +/* + +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. + +*/ + +// System includes +#include +#include +#include +#include +#include + +// Miranda Includes +#include +#include +#include + +// Fortune include +#include "fortune.h" +#include "m_fortunemsg.h" + +void bigEndian2littleEndian(void *, size_t); +unsigned int random(unsigned int); +size_t readFortuneItem(char *, unsigned int, FILE *, FILE *, unsigned char, unsigned int); +void normalizeMsg(char *); +void trimFortune(char *); +void addCRBeforeLF(char *, unsigned int); + +#define isSpace(a) (a == ' ' || a == '\t' || a == '\r' || a == '\n') + +BOOL readFortune(const char *dbSetting, char *messageBuf, unsigned int maxFortuneMsg) +{ + DBVARIANT dbv; + char datFilename[MAX_PATH+1], fortuneFilename[MAX_PATH+1]; + FILE *fDatfile, *fFortunefile; + DATFILEHEADER datHeader; + int rCountdown; + + if (DBGetContactSetting(NULL, MODULE_NAME, dbSetting, &dbv)) + return FALSE; + makeAbsolute(datFilename, dbv.pszVal); + DBFreeVariant(&dbv); + + if (strlen(datFilename) < 5) + return FALSE; + if (!(fDatfile=fopen(datFilename, "rb"))) + return FALSE; + if (fread(&datHeader, sizeof(DATFILEHEADER), 1, fDatfile) < 1) + return FALSE; + bigEndian2littleEndian(&(datHeader.dat_version), sizeof(unsigned int)); + bigEndian2littleEndian(&(datHeader.dat_numstr), sizeof(unsigned int)); + bigEndian2littleEndian(&(datHeader.dat_longlen), sizeof(unsigned int)); + bigEndian2littleEndian(&(datHeader.dat_shortlen), sizeof(unsigned int)); + bigEndian2littleEndian(&(datHeader.dat_flags), sizeof(unsigned int)); + + if (datHeader.dat_shortlen > maxFortuneMsg) + return FALSE; + + strcpy(fortuneFilename, datFilename); + fortuneFilename[strlen(fortuneFilename) - 4] = '\0'; + + if (!(fFortunefile=fopen(fortuneFilename, "rt"))) + return FALSE; + + for(rCountdown=MAX_RETRIES; rCountdown && readFortuneItem(messageBuf, random(datHeader.dat_numstr), fDatfile, fFortunefile, datHeader.DELIM, maxFortuneMsg) == -1; rCountdown--); + + fclose(fDatfile); + fclose(fFortunefile); + return !!rCountdown; +} + +void bigEndian2littleEndian(void *convField, size_t fieldSize) +{ + size_t i; + char aux[128]; + + memcpy(aux, convField, fieldSize); + for (i=0; i < (fieldSize / 2); i++) { + char aux2; + int j = fieldSize - i - 1; + + aux2 = aux[i]; + aux[i] = aux[j]; + aux[j] = aux2; + } + memcpy(convField, aux, fieldSize); +} + +unsigned int random(unsigned int maxNumber) +{ + static time_t seed = 0; + + if (seed == 0) { + (void)time(&seed); + srand((unsigned int)seed); + } + + return (unsigned int)(rand() % maxNumber); +} + +size_t readFortuneItem(char *fortuneMsg, unsigned int nroItem, FILE *fDatfile, FILE *fFortunefile, unsigned char delimiter, unsigned int maxFortuneMsg) +{ + size_t countBytes = 0; + f_offset fortuneOffset; + char buffer[2*FORTUNE_BUFSIZE], messageBuf[2*FORTUNE_BUFSIZE]; + + messageBuf[0] = fortuneMsg[0] = '\0'; + if (fseek(fDatfile, (long)(sizeof(DATFILEHEADER) + nroItem * sizeof(f_offset)), SEEK_SET)) + return 0; + if (fread(&fortuneOffset, sizeof(f_offset), 1, fDatfile) < 1) + return 0; + bigEndian2littleEndian(&fortuneOffset, sizeof(f_offset)); + + if (fseek(fFortunefile, (long)fortuneOffset, SEEK_SET)) + return 0; + while(fgets(buffer, 2*FORTUNE_BUFSIZE, fFortunefile) != NULL && !(buffer[0] == delimiter && buffer[1] == '\n')) { + if ((countBytes += strlen(buffer)) > (2*FORTUNE_BUFSIZE-1)) + return -1; + strcat(messageBuf, buffer); + } + + if (DBGetContactSettingByte(NULL, MODULE_NAME, "OneLine", 0)) + normalizeMsg(messageBuf); + else { + trimFortune(messageBuf); + if (!DBGetContactSettingByte(NULL, MODULE_NAME, "RemoveCR", 0)) + addCRBeforeLF(messageBuf, maxFortuneMsg); + } + + if ((countBytes = strlen(messageBuf)) > maxFortuneMsg) + return -1; + strcpy(fortuneMsg, messageBuf); + return countBytes; +} + +void normalizeMsg(char *fortuneMsg) +{ + char buffer[2*FORTUNE_BUFSIZE], *str; + + strcpy(buffer, fortuneMsg); + + if (!(str=strtok(buffer, " \t\r\n"))) + fortuneMsg[0] = '\0'; + else { + strcpy(fortuneMsg, str); + while(str = strtok(NULL, " \t\r\n")) { + strcat(fortuneMsg, " "); + strcat(fortuneMsg, str); + } + } +} + +void trimFortune(char *fortuneMsg) +{ + int i; + + for (i=strlen(fortuneMsg)-1; i >= 0 && isSpace(fortuneMsg[i]); i--) + fortuneMsg[i] = '\0'; +} + +void addCRBeforeLF(char *fortuneMsg, unsigned int maxFortuneMsg) +{ + int i, j, empty; + char buffer[2*FORTUNE_BUFSIZE]; + + if ((empty = maxFortuneMsg - strlen(fortuneMsg)) < 0) return; + + strcpy(buffer, fortuneMsg); + + for (i=j=0; buffer[i]; i++) { + if (empty && buffer[i] == '\n') { + empty--; + fortuneMsg[j++] = '\r'; + } + fortuneMsg[j++] = buffer[i]; + } + fortuneMsg[j] = '\0'; +} + +BOOL selectRandomFile(char *datFilename) +{ + DBVARIANT dbv; + char szDir[MAX_PATH+1], szMask[MAX_PATH+1]; + WIN32_FIND_DATA FileData; + HANDLE hSearch; + int count = 0; + + datFilename[0] = '\0'; + + if (DBGetContactSetting(NULL, MODULE_NAME, "FortuneDir", &dbv)) return FALSE; + + strcpy(szDir, dbv.pszVal); + DBFreeVariant(&dbv); + makeAbsolute(szMask, szDir); + strcat(szMask, "\\*.dat"); + + if ((hSearch=FindFirstFile(szMask, &FileData)) == INVALID_HANDLE_VALUE) return FALSE; + do { + count++; + } while (FindNextFile(hSearch, &FileData)); + + count = random(count); + + if ((hSearch=FindFirstFile(szMask, &FileData)) == INVALID_HANDLE_VALUE) return FALSE; + do { + if(count-- == 0) { + strcpy(datFilename, szDir); + strcat(datFilename, "\\"); + strcat(datFilename, FileData.cFileName); + return TRUE; + } + } while (FindNextFile(hSearch, &FileData)); + + return FALSE; +} + +char *makeRelative(char *returnPath, const char *path) +{ + strcpy(returnPath, path); + if (ServiceExists(MS_UTILS_PATHTORELATIVE)) + CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)path, (LPARAM)returnPath); + + return returnPath; +} + +char *makeAbsolute(char *returnPath, const char *path) +{ + strcpy(returnPath, path); + if (ServiceExists(MS_UTILS_PATHTOABSOLUTE)) + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)path, (LPARAM)returnPath); + + return returnPath; +} diff --git a/FortuneAwayMsg/fortune.h b/FortuneAwayMsg/fortune.h new file mode 100644 index 0000000..e9c7563 --- /dev/null +++ b/FortuneAwayMsg/fortune.h @@ -0,0 +1,41 @@ +/* + +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 "AggressiveOptimize.h" + +typedef struct { /* .dat file header */ + unsigned int dat_version; /* version number */ + unsigned int dat_numstr; /* # of strings in the file */ + unsigned int dat_longlen; /* length of longest string */ + unsigned int dat_shortlen; /* length of shortest string */ + unsigned int dat_flags; /* bit field for flags */ + unsigned char filler[15]; /* rest of the .dat header */ +} DATFILEHEADER; + +typedef unsigned int f_offset; + +// fortune.c defines +#define DELIM filler[0] /* delimiting character */ +#define MODULE_NAME "FortuneAwayMsg" +#define MAX_RETRIES 15 +#define datfileSize(header) (sizeof(DATFILEHEADER) + header.dat_numstr * sizeof(f_ offset)) + +BOOL selectRandomFile(char *); +BOOL readFortune(const char *, char *, unsigned int); +char *makeRelative(char*, const char *); +char *makeAbsolute(char *, const char *); diff --git a/FortuneAwayMsg/fortuneawaymsg.dsp b/FortuneAwayMsg/fortuneawaymsg.dsp new file mode 100644 index 0000000..48ba4d5 --- /dev/null +++ b/FortuneAwayMsg/fortuneawaymsg.dsp @@ -0,0 +1,130 @@ +# Microsoft Developer Studio Project File - Name="fortuneawaymsg" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=fortuneawaymsg - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fortuneawaymsg.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fortuneawaymsg.mak" CFG="fortuneawaymsg - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fortuneawaymsg - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "fortuneawaymsg - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fortuneawaymsg - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FORTUNEAWAYMSG_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FORTUNEAWAYMSG_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc0c /d "NDEBUG" +# ADD RSC /l 0xc0c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msvcrt.lib /nologo /dll /machine:I386 /nodefaultlib + +!ELSEIF "$(CFG)" == "fortuneawaymsg - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FORTUNEAWAYMSG_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FORTUNEAWAYMSG_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc0c /d "_DEBUG" +# ADD RSC /l 0xc0c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "fortuneawaymsg - Win32 Release" +# Name "fortuneawaymsg - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\fortune.c +# End Source File +# Begin Source File + +SOURCE=.\main.c +# End Source File +# Begin Source File + +SOURCE=.\options.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\fortune.h +# End Source File +# Begin Source File + +SOURCE=.\m_fortunemsg.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Group +# End Target +# End Project diff --git a/FortuneAwayMsg/fortuneawaymsg.dsw b/FortuneAwayMsg/fortuneawaymsg.dsw new file mode 100644 index 0000000..00db4c0 --- /dev/null +++ b/FortuneAwayMsg/fortuneawaymsg.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "fortuneawaymsg"=".\fortuneawaymsg.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/FortuneAwayMsg/main.c b/FortuneAwayMsg/main.c new file mode 100644 index 0000000..77d2931 --- /dev/null +++ b/FortuneAwayMsg/main.c @@ -0,0 +1,280 @@ +/* + +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. + + +Description +----------- +This plugin for Miranda-IM doesn't add any functionality on itself. It +provides basically three services for retrieving: a) a BSD Fortune message +from a random file, b) a BSD Fortune message from a protocol-defined file, +and c) a BSD Fortune message from a status-defined file. So, hopefully, +the only thing plugin developers will have to do is define three variables +like %fortunemsg%, %protofortunemsg% and %statusfortunemsg% and call the +corresponding service in this plugin in order to retrieve the fortune msgs. + +Options +------- +Options page Options->Status->Fortune Messages. + +Thanks +------ +- UnregistereD for help, ideas and support in variables plugin +- Leecher for encouraging and providing with the necessary tools +- Blabla for kindly sending me the sources of the original fortune plugin (from which I took completely the random file selection code) +- Harven for discussion and support to this plugin +- JDGordon/Targaff for helping with the Endianism thing +- Amp from the forums who provided a patched version compatible with latest Variables +- simpleaway, ieview, messagesound and skype plugins' authors for part of their code I use in the Options page +- Miranda IM developers for this amazing program +- all other people from Miranda community + + +*/ + +// System includes +#include +#include +#include +#include + +// Miranda Includes +#include +#include +#include +#include +#include +#include +#include "m_variables.h" +#include "m_updater.h" + +// Fortune include +#include "fortune.h" +#include "m_fortunemsg.h" + +// Prototypes +static int ModulesLoaded(WPARAM, LPARAM); +static int GetFortune(WPARAM, LPARAM); +static int GetProtoFortune(WPARAM, LPARAM); +static int GetStatusFortune(WPARAM, LPARAM); +static int FreeAllocatedMemory(WPARAM, LPARAM); +static int CalledFromVariables(WPARAM, LPARAM); +char *StatusModeToDbSetting(int, const char *); +extern int InitOptions(WPARAM, LPARAM); + + +// Program globals +HINSTANCE hInst; +PLUGINLINK *pluginLink; +HANDLE hModulesLoaded, hInitOptions, hGetFortune, hGetProtoFortune, hGetStatusFortune, hFreeAllocatedMemory, hCalledFromVariables; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFO), + "FortuneAwayMsg", + PLUGIN_MAKE_VERSION(0,0,0,10), + "Fortune Messages for the AwayMessages", + "tioduke", + "tioduke@yahoo.ca", + "© 2005-2008 TioDuke", + "http://addons.miranda-im.org/details.php?action=viewfile&id=1933", + 0, + 0, + {0x9c00ab77, 0x41ce, 0x4e93, {0x9a, 0x83, 0xf9, 0xa8, 0x20, 0x5c, 0xa9, 0x1b}} //{9c00ab77-41ce-4e93-9a83-f9a8205ca91b} +}; + +// DLL Stuff // + +__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) +{ + pluginInfo.cbSize = sizeof(PLUGININFO); + return (PLUGININFO*)&pluginInfo; +} + +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + pluginInfo.cbSize = sizeof(PLUGININFOEX); + return &pluginInfo; +} + +#define MIID_FORTUNEAWAYMSG {0x9c00ab77, 0x41ce, 0x4e93, {0x9a, 0x83, 0xf9, 0xa8, 0x20, 0x5c, 0xa9, 0x1b}} +static const MUUID interfaces[] = {MIID_FORTUNEAWAYMSG, MIID_LAST}; +__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst=hinstDLL; + DisableThreadLibraryCalls(hInst); + return TRUE; +} + +int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink=link; + + hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); + return 0; +} + +int __declspec(dllexport) Unload(void) +{ + UnhookEvent(hModulesLoaded); + UnhookEvent(hInitOptions); + DestroyServiceFunction(hGetFortune); + DestroyServiceFunction(hGetProtoFortune); + DestroyServiceFunction(hGetStatusFortune); + DestroyServiceFunction(hFreeAllocatedMemory); + DestroyServiceFunction(hCalledFromVariables); + return 0; +} + +// Hooked events + +static int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + hInitOptions = HookEvent(ME_OPT_INITIALISE, InitOptions); + hGetFortune = CreateServiceFunction(MS_FORTUNEMSG_GETMESSAGE, GetFortune); + hGetProtoFortune = CreateServiceFunction(MS_FORTUNEMSG_GETPROTOMSG, GetProtoFortune); + hGetStatusFortune = CreateServiceFunction(MS_FORTUNEMSG_GETSTATUSMSG, GetStatusFortune); + hFreeAllocatedMemory = CreateServiceFunction(MS_FORTUNEMSG_FREEMEMORY, FreeAllocatedMemory); + hCalledFromVariables = CreateServiceFunction(MS_FORTUNEMSG_FROMVARIABLES, CalledFromVariables); + + if (ServiceExists(MS_VARS_REGISTERTOKEN)) { + TOKENREGISTER vr; + ZeroMemory(&vr, sizeof(vr)); + vr.cbSize = sizeof(TOKENREGISTER); + vr.szTokenString = "fortunemsg"; + vr.szService = MS_FORTUNEMSG_FROMVARIABLES; + vr.szCleanupService = MS_FORTUNEMSG_FREEMEMORY; + vr.szHelpText = "retrieves a random fortune string"; + vr.memType = TR_MEM_OWNER; + vr.flags = TRF_CLEANUP; + CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM)&vr); + } + + if (ServiceExists("DBEditorpp/RegisterSingleModule")) + CallService("DBEditorpp/RegisterSingleModule", (WPARAM)MODULE_NAME, 0); + if (ServiceExists(MS_UPDATE_REGISTERFL)) + CallService(MS_UPDATE_REGISTERFL, (WPARAM)1933, (LPARAM)&pluginInfo); + + + return 0; +} + +// Services + +static int GetFortune(WPARAM wParam, LPARAM lParam) +{ + char datFilename[MAX_PATH+1], fortuneMsg[FORTUNE_BUFSIZE]; + char *returnMsg = (char *)lParam; + + if (selectRandomFile(datFilename)) + DBWriteContactSettingString(NULL, MODULE_NAME, "RandomFile", datFilename); + + if (!readFortune("RandomFile", fortuneMsg, MAX_FORTUNEMSG)) return 0; + + if (!returnMsg) + if (!(returnMsg = malloc(strlen(fortuneMsg)+1))) + return 0; + strcpy(returnMsg, fortuneMsg); + + return (int)returnMsg; +} + +static int GetProtoFortune(WPARAM wParam, LPARAM lParam) +{ + unsigned int maxFortuneMsg; + char dbSetting[MAX_PATH+1], fortuneMsg[FORTUNE_BUFSIZE]; + char *protoName = (char *)wParam; + char *returnMsg = (char *)lParam; + + if (!protoName) //Harven asked me for this, as sometimes SimpleAway doesn't know which protocol + return CallService(MS_FORTUNEMSG_GETMESSAGE, 0, 0); + + _snprintf(dbSetting, MAX_PATH, "%sLength", protoName); + maxFortuneMsg = (unsigned int) DBGetContactSettingWord(NULL, MODULE_NAME, dbSetting, MAX_FORTUNEMSG); + if (maxFortuneMsg > MAX_FORTUNEMSG) maxFortuneMsg = MAX_FORTUNEMSG; + + _snprintf(dbSetting, MAX_PATH, "%sFile", protoName); + + if (!readFortune(dbSetting, fortuneMsg, maxFortuneMsg)) return 0; + + if (!returnMsg) + if (!(returnMsg = malloc(strlen(fortuneMsg)+1))) + return 0; + strcpy(returnMsg, fortuneMsg); + + return (int)returnMsg; +} + +static int GetStatusFortune(WPARAM wParam, LPARAM lParam) +{ + char fortuneMsg[FORTUNE_BUFSIZE]; + int status = (int)wParam; + char *returnMsg = (char *)lParam; + + if (status < ID_STATUS_OFFLINE || status > ID_STATUS_OUTTOLUNCH) return 0; + + if (!readFortune(StatusModeToDbSetting(status, "File"), fortuneMsg, MAX_FORTUNEMSG)) return 0; + + if (!returnMsg) + if (!(returnMsg = malloc(strlen(fortuneMsg)+1))) + return 0; + strcpy(returnMsg, fortuneMsg); + + return (int)returnMsg; +} + +static int FreeAllocatedMemory(WPARAM wParam, LPARAM lParam) +{ + void *lPtr = (void *)lParam; + + if (!lPtr) + return -1; + + free(lPtr); + return 0; +} + +static int CalledFromVariables(WPARAM wParam, LPARAM lParam) +{ + return CallService(MS_FORTUNEMSG_GETMESSAGE, 0, 0); +} + + +// helpers from awaymsg.c +char *StatusModeToDbSetting(int status, const char *suffix) +{ + char *prefix; + static char str[MAX_PATH+1]; + + switch(status) { + case ID_STATUS_OFFLINE: prefix="Off"; break; + case ID_STATUS_ONLINE: prefix="On"; break; + case ID_STATUS_AWAY: prefix="Away"; break; + case ID_STATUS_NA: prefix="Na"; break; + case ID_STATUS_OCCUPIED: prefix="Occupied"; break; + case ID_STATUS_DND: prefix="Dnd"; break; + case ID_STATUS_FREECHAT: prefix="FreeChat"; break; + case ID_STATUS_INVISIBLE: prefix="Inv"; break; + case ID_STATUS_ONTHEPHONE: prefix="Otp"; break; + case ID_STATUS_OUTTOLUNCH: prefix="Otl"; break; + default: return NULL; + } + strcpy(str, prefix); strcat(str, suffix); + return str; +} diff --git a/FortuneAwayMsg/options.c b/FortuneAwayMsg/options.c new file mode 100644 index 0000000..803414b --- /dev/null +++ b/FortuneAwayMsg/options.c @@ -0,0 +1,429 @@ +/* + +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. + +*/ + + +// System includes +#include +#include +#include +#include + +// Miranda Includes +#include +#include +#include +#include +#include +#include +#include + +// Fortune include +#include "fortune.h" +#include "resource.h" +#include "m_fortunemsg.h" + +#ifndef BIF_NEWDIALOGSTYLE +#define BIF_NEWDIALOGSTYLE 0x0040 +#endif + +// Prototypes +int InitOptions(WPARAM, LPARAM); +INT_PTR CALLBACK DlgOptionsProc(HWND, UINT, WPARAM, LPARAM); +int CALLBACK prcHookBrowseForFolder(HWND, UINT, LPARAM, LPARAM); +extern char *StatusModeToDbSetting(int, const char *); + + +// Program globals +extern HINSTANCE hInst; + +struct OptDlgData +{ + BOOL oneLine; + BOOL removeCR; + char fortuneDir[MAX_PATH+1]; + char statusFile[9][MAX_PATH+1]; + int protoCount; + char **protoName; + char **protoFile; + int *protoLength; +}; + +int InitOptions(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp; + + ZeroMemory(&odp, sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONDLG); + odp.pszTitle = Translate("Fortune Messages"); + odp.pszGroup = Translate("Status"); + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = DlgOptionsProc; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + return 0; +} + +INT_PTR CALLBACK DlgOptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + struct OptDlgData *data; + static BOOL initDlg=FALSE; + + data = (struct OptDlgData *)GetWindowLong(hwndDlg, GWL_USERDATA); + + switch (uMsg) { + case WM_INITDIALOG: + { + PROTOCOLDESCRIPTOR **proto; + DBVARIANT dbv; + DWORD protoStatusFlags, auxStatusFlags; + int i, protoCount, index; + + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + data = (struct OptDlgData *)malloc(sizeof(struct OptDlgData)); + SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)data); + + SendDlgItemMessage(hwndDlg, IDC_FORTUNEDIR, EM_LIMITTEXT, MAX_PATH, 0); + SendDlgItemMessage(hwndDlg, IDC_PROTOFILE, EM_LIMITTEXT, MAX_PATH, 0); + SendDlgItemMessage(hwndDlg, IDC_STATUSFILE, EM_LIMITTEXT, MAX_PATH, 0); + + SendDlgItemMessage(hwndDlg, IDC_EMAXLEN, EM_LIMITTEXT, 4, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_SMAXLEN), UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_EMAXLEN), 0); + SendMessage(GetDlgItem(hwndDlg, IDC_SMAXLEN), UDM_SETRANGE32, (WPARAM)MIN_FORTUNEMSG, (LPARAM)MAX_FORTUNEMSG); + + if(!DBGetContactSetting(NULL, MODULE_NAME, "FortuneDir", &dbv)) { + makeAbsolute(data->fortuneDir, dbv.pszVal); + DBFreeVariant(&dbv); + } else + data->fortuneDir[0] = '\0'; + EnableWindow(GetDlgItem(hwndDlg, IDC_FORTUNEDIR), TRUE); + SetDlgItemText(hwndDlg, IDC_FORTUNEDIR, data->fortuneDir); + + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protoCount,(LPARAM)&proto); + data->protoName = (char **)malloc(protoCount * sizeof(char *)); + data->protoFile = (char **)malloc(protoCount * sizeof(char *)); + data->protoLength = (int *)malloc(protoCount * sizeof(int)); + if (!data->protoName || !data->protoFile || !data->protoLength) { + data->protoCount = 0; + EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOFILE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOBROWSE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EMAXLEN), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SMAXLEN), FALSE); + } else { + char setting[MAX_PATH+1]; + + data->protoCount = protoCount; + for(i=0; i < protoCount; i++) { + char protoLabel[MAXMODULELABELLENGTH+1]; + data->protoName[i] = NULL; + data->protoFile[i] = NULL; + if (proto[i]->type != PROTOTYPE_PROTOCOL) + continue; + if (!(auxStatusFlags = CallProtoService(proto[i]->szName, PS_GETCAPS,PFLAGNUM_3, 0))) + continue; + protoStatusFlags |= auxStatusFlags; + if (!(data->protoName[i] = (char *)malloc(strlen(proto[i]->szName)+1))) + continue; + if (!(data->protoFile[i] = (char *)malloc(MAX_PATH+1))) + continue; + CallProtoService(proto[i]->szName, PS_GETNAME, MAXMODULELABELLENGTH, (LPARAM)protoLabel); + index = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_ADDSTRING, 0, (LPARAM)protoLabel); + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETITEMDATA, index, (LPARAM)i); + if (index != CB_ERR && index != CB_ERRSPACE) { + strcpy(data->protoName[i], proto[i]->szName); + _snprintf(setting, sizeof(setting), "%sFile", proto[i]->szName); + if(!DBGetContactSetting(NULL, MODULE_NAME, setting, &dbv)) { + makeAbsolute(data->protoFile[i], dbv.pszVal); + DBFreeVariant(&dbv); + } else + data->protoFile[i][0] = '\0'; + _snprintf(setting, sizeof(setting), "%sLength", proto[i]->szName); + data->protoLength[i] = DBGetContactSettingWord(NULL, MODULE_NAME, setting, MAX_FORTUNEMSG); + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + } + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETCURSEL, (WPARAM)0, 0); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CBOPTPROTO, CBN_SELCHANGE), (LPARAM)GetDlgItem(hwndDlg, IDC_CBOPTPROTO)); + } + + for (i=ID_STATUS_ONLINE; i <= ID_STATUS_OUTTOLUNCH; i++) + if (protoStatusFlags & Proto_Status2Flag(i)) { + index = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_INSERTSTRING, (WPARAM)-1, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, i, 0)); + if (index != CB_ERR && index != CB_ERRSPACE) { + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_SETITEMDATA, (WPARAM)index, (LPARAM)i-ID_STATUS_ONLINE); + if(!DBGetContactSetting(NULL, MODULE_NAME, StatusModeToDbSetting(i, "File"), &dbv)) { + makeAbsolute(data->statusFile[i-ID_STATUS_ONLINE], dbv.pszVal); + DBFreeVariant(&dbv); + } else + data->statusFile[i-ID_STATUS_ONLINE][0] = '\0'; + } + } + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_SETCURSEL, (WPARAM)0, 0); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CBOPTSTATUS, CBN_SELCHANGE),(LPARAM)GetDlgItem(hwndDlg, IDC_CBOPTSTATUS)); + + if (data->oneLine = DBGetContactSettingByte(NULL, MODULE_NAME, "OneLine", 0)) { + CheckDlgButton(hwndDlg, IDC_CCHECKONELINE, BST_CHECKED); + data->removeCR = TRUE; + CheckDlgButton(hwndDlg, IDC_CCHECKREMOVECR, BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_CCHECKREMOVECR), FALSE); + } else { + CheckDlgButton(hwndDlg, IDC_CCHECKONELINE, BST_UNCHECKED); + if (data->removeCR = DBGetContactSettingByte(NULL, MODULE_NAME, "RemoveCR", 0)) + CheckDlgButton(hwndDlg, IDC_CCHECKREMOVECR, BST_CHECKED); + else + CheckDlgButton(hwndDlg, IDC_CCHECKREMOVECR, BST_UNCHECKED); + } + + initDlg=FALSE; + return TRUE; + } + case WM_COMMAND: + { + BOOL sthChanged = FALSE; + switch (LOWORD(wParam)) { + case IDC_FORTUNEDIR: + if(HIWORD(wParam) == EN_CHANGE) { + char path[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_FORTUNEDIR, path, sizeof(path)); + strcpy(data->fortuneDir, path); + sthChanged = TRUE; + } + break; + case IDC_DIRBROWSE: + { + char path[MAX_PATH+1]; + LPMALLOC psMalloc; + BROWSEINFOA bi; + LPITEMIDLIST pidl; + +#ifdef __WINE__ + path[0] = '\0'; +#else + GetDlgItemTextA(hwndDlg, IDC_FORTUNEDIR, path, sizeof(path)); +#endif + if(SUCCEEDED(CoGetMalloc(1, &psMalloc))) { + ZeroMemory(&bi, sizeof(bi)); + bi.hwndOwner = hwndDlg; + bi.pszDisplayName = path; + bi.lpszTitle = Translate("Select Fortune Folder"); + bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX | BIF_RETURNONLYFSDIRS; + bi.lpfn = prcHookBrowseForFolder; + bi.lParam = (LPARAM)path; + if (pidl = SHBrowseForFolderA(&bi)) { + if (SHGetPathFromIDListA(pidl, path)) + SetDlgItemTextA(hwndDlg, IDC_FORTUNEDIR, path); + psMalloc->lpVtbl->Free(psMalloc, pidl); + } + psMalloc->lpVtbl->Release(psMalloc); + } + break; + } + case IDC_CBOPTPROTO: + if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_SELENDOK) { + int i = SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0); + + EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOFILE), TRUE); + SetDlgItemText(hwndDlg, IDC_PROTOFILE, data->protoFile[i]); + SetDlgItemInt(hwndDlg, IDC_EMAXLEN, data->protoLength[i], FALSE); + } + break; + case IDC_PROTOFILE: + if(HIWORD(wParam) == EN_CHANGE) { + char path[MAX_PATH+1]; + int i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + + GetDlgItemText(hwndDlg, IDC_PROTOFILE, path, sizeof(path)); + strcpy(data->protoFile[i], path); + sthChanged = TRUE; + } + break; + case IDC_PROTOBROWSE: + { + char path[MAX_PATH+1]; + OPENFILENAME ofn={0}; + + GetDlgItemText(hwndDlg, IDC_PROTOFILE, path, sizeof(path)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndDlg; + ofn.hInstance = NULL; + ofn.lpstrFilter = "Fortune header file (*.dat)\0*.dat\0\0"; + ofn.lpstrFile = path; + ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; + ofn.nMaxFile = sizeof(path); + ofn.nMaxFileTitle = MAX_PATH; + ofn.lpstrDefExt = "dat"; + if(GetOpenFileName(&ofn)) + SetDlgItemText(hwndDlg, IDC_PROTOFILE, path); + break; + } + case IDC_EMAXLEN: + if(HIWORD(wParam) == EN_CHANGE) { + BOOL translated; + int val = GetDlgItemInt(hwndDlg, IDC_EMAXLEN, &translated, FALSE); + + if (translated) { + int i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + + data->protoLength[i] = val; + if (data->protoLength[i] < MIN_FORTUNEMSG) data->protoLength[i] = MIN_FORTUNEMSG; + if (data->protoLength[i] > MAX_FORTUNEMSG) data->protoLength[i] = MAX_FORTUNEMSG; + sthChanged = TRUE; + } + } + break; + case IDC_CBOPTSTATUS: + if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_SELENDOK) { + int i = SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0); + + EnableWindow(GetDlgItem(hwndDlg, IDC_STATUSFILE), TRUE); + SetDlgItemText(hwndDlg, IDC_STATUSFILE, data->statusFile[i]); + } + break; + case IDC_STATUSFILE: + if(HIWORD(wParam) == EN_CHANGE) { + char path[MAX_PATH+1]; + int i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETCURSEL, 0, 0), 0); + + GetDlgItemText(hwndDlg, IDC_STATUSFILE, path, sizeof(path)); + strcpy(data->statusFile[i], path); + sthChanged = TRUE; + } + break; + case IDC_STATUSBROWSE: + { + char path[MAX_PATH+1]; + OPENFILENAME ofn={0}; + + GetDlgItemText(hwndDlg, IDC_STATUSFILE, path, sizeof(path)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndDlg; + ofn.hInstance = NULL; + ofn.lpstrFilter = "Fortune header file (*.dat)\0*.dat\0\0"; + ofn.lpstrFile = path; + ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; + ofn.nMaxFile = sizeof(path); + ofn.nMaxFileTitle = MAX_PATH; + ofn.lpstrDefExt = "dat"; + if(GetOpenFileName(&ofn)) + SetDlgItemText(hwndDlg, IDC_STATUSFILE, path); + break; + } + case IDC_CCHECKONELINE: + if (HIWORD(wParam) == BN_CLICKED) { + if (IsDlgButtonChecked(hwndDlg, IDC_CCHECKONELINE) == BST_CHECKED) { + data->oneLine = TRUE; + data->removeCR = TRUE; + CheckDlgButton(hwndDlg, IDC_CCHECKREMOVECR, BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_CCHECKREMOVECR), FALSE); + } else { + data->oneLine = FALSE; + EnableWindow(GetDlgItem(hwndDlg, IDC_CCHECKREMOVECR), TRUE); + } + sthChanged = TRUE; + } + break; + case IDC_CCHECKREMOVECR: + if (HIWORD(wParam) == BN_CLICKED) { + if (IsDlgButtonChecked(hwndDlg, IDC_CCHECKREMOVECR) == BST_CHECKED) + data->removeCR = TRUE; + else + data->removeCR = FALSE; + sthChanged = TRUE; + } + break; + } + if (!initDlg && sthChanged) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + { + int i; + char auxPath[MAX_PATH+1]; + + DBWriteContactSettingString(NULL, MODULE_NAME, "FortuneDir", makeRelative(auxPath, data->fortuneDir)); + + for (i=0; i < data->protoCount; i++) { + char setting[MAX_PATH+1]; + if (data->protoName[i] && data->protoFile[i]) { + _snprintf(setting, sizeof(setting), "%sFile", data->protoName[i]); + DBWriteContactSettingString(NULL, MODULE_NAME, setting, makeRelative(auxPath, data->protoFile[i])); + _snprintf(setting, sizeof(setting), "%sLength", data->protoName[i]); + DBWriteContactSettingWord(NULL, MODULE_NAME, setting, (WORD)data->protoLength[i]); + } + } + + for (i=ID_STATUS_ONLINE; i <= ID_STATUS_OUTTOLUNCH; i++) + DBWriteContactSettingString(NULL, MODULE_NAME, StatusModeToDbSetting(i, "File"), makeRelative(auxPath, data->statusFile[i-ID_STATUS_ONLINE])); + + DBWriteContactSettingByte(NULL, MODULE_NAME, "OneLine", (BYTE)data->oneLine); + DBWriteContactSettingByte(NULL, MODULE_NAME, "RemoveCR", (BYTE)data->removeCR); + + return TRUE; + } + } + break; + } + break; + case WM_DESTROY: + { + int i; + + for (i=0; i < data->protoCount; i++) { + if (data->protoName[i]) + free(data->protoName[i]); + if (data->protoFile[i]) + free(data->protoFile[i]); + } + if (data->protoName) + free(data->protoName); + if (data->protoFile) + free(data->protoFile); + if (data->protoLength) + free(data->protoLength); + free(data); + break; + } + } + return FALSE; +} + +// Hook for SHBrowseForFolder() +// Sets the initial directory (a LPCSTR in lpData) +int CALLBACK prcHookBrowseForFolder(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + char szDir[MAX_PATH+1]; + switch(uMsg) { + case BFFM_INITIALIZED: + SendMessageA(hwnd, BFFM_SETSELECTION, TRUE, lpData); + break; + case BFFM_SELCHANGED: + if (SHGetPathFromIDListA((LPITEMIDLIST)lParam, szDir)) + SendMessageA(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)szDir); + break; + } + return 0; +} diff --git a/FortuneAwayMsg/resource.h b/FortuneAwayMsg/resource.h new file mode 100644 index 0000000..81fecfb --- /dev/null +++ b/FortuneAwayMsg/resource.h @@ -0,0 +1,99 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// +#define IDD_AWAYMSGBOX 102 +#define IDD_OPTIONDLG 103 +#define IDD_READAWAYMSG 104 +#define IDI_CROSS 104 +#define IDI_HISTORY 105 +#define IDI_MESSAGE 106 +#define IDI_PLUS 107 +#define IDI_CHIST 109 +#define IDB_MSGDN 118 +#define IDB_MSGUP 119 +#define IDI_COPY 120 +#define IDD_COPY 121 +#define IDB_BITMAP1 122 +#define IDC_TITLE_1 1000 +#define IDC_BUTTON1 1023 +#define IDC_BOPTHIST 1023 +#define IDC_OK 1024 +#define IDC_BOPDEF 1024 +#define IDC_EDIT1 1025 +#define IDC_CANCEL 1026 +#define IDC_ICON1 1032 +#define IDC_CCHECKONELINE 1032 +#define IDC_ICON2 1033 +#define IDC_CCHECKREMOVECR 1033 +#define IDC_ICON3 1034 +#define IDC_ICON4 1035 +#define IDC_ICON5 1036 +#define IDC_ICON6 1037 +#define IDC_ICON7 1038 +#define IDC_ICON8 1039 +#define IDC_ICON9 1040 +#define IDC_ICON10 1041 +#define IDC_CBMSG 1042 +#define IDC_RADIO1 1043 +#define IDC_ROPTMSG1 1043 +#define IDC_RADIO2 1044 +#define IDC_ROPTMSG2 1044 +#define IDC_RADIO3 1045 +#define IDC_ROPTMSG3 1045 +#define IDC_RADIO4 1046 +#define IDC_ROPTMSG4 1046 +#define IDC_RADIO5 1047 +#define IDC_ROPTMSG5 1047 +#define IDC_RADIO6 1048 +#define IDC_RADIO7 1049 +#define IDC_RADIO8 1050 +#define IDC_RADIO9 1051 +#define IDC_RADIO10 1052 +#define IDC_MSG 1053 +#define IDC_TEXT1 1053 +#define IDC_RETRIEVING 1054 +#define IDC_LENGTH 1054 +#define IDC_COPY 1055 +#define IDC_TLAYOUT 1061 +#define IDC_CSTATUSLIST 1062 +#define IDC_CICONS2 1063 +#define IDC_CICONS1 1064 +#define IDC_CBUTTONS 1065 +#define IDC_EMAXHIST 1071 +#define IDC_ETIMEOUT 1072 +#define IDC_ESECWINAMP 1073 +#define IDC_SMAXHIST 1074 +#define IDC_SMAXLEN 1074 +#define IDC_CCLOSEWND 1075 +#define IDC_STIMEOUT 1076 +#define IDC_CBOPTSTATUS 1077 +#define IDC_CCHECKWINAMP 1078 +#define IDC_COPTMSG1 1079 +#define IDC_SSECWINAMP 1080 +#define IDC_OPTEDIT2 1081 +#define IDC_OPTEDIT1 1082 +#define IDC_CBOPTPROTO 1083 +#define IDC_COPTPROTO1 1084 +#define IDC_COPTPROTO2 1085 +#define IDC_CREMOVECR 1086 +#define IDC_PROTOBROWSE 1184 +#define IDC_STATUSBROWSE 1185 +#define IDC_DIRBROWSE 1186 +#define IDC_PROTOFILE 1271 +#define IDC_STATUSFILE 1272 +#define IDC_FORTUNEDIR 1273 +#define IDC_PROTOLEN 1274 +#define IDC_PROTOLENGTH 1274 +#define IDC_EMAXLEN 1274 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 123 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1086 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/FortuneAwayMsg/resource.rc b/FortuneAwayMsg/resource.rc new file mode 100644 index 0000000..cf0f75a --- /dev/null +++ b/FortuneAwayMsg/resource.rc @@ -0,0 +1,123 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONDLG DIALOGEX 0, 0, 309, 252 +STYLE WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + GROUPBOX "Fortune Folder",IDC_STATIC,7,13,294,50 + EDITTEXT IDC_FORTUNEDIR,13,28,263,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_DIRBROWSE,281,29,15,11 + LTEXT "(Used for the %fortunemsg%-type variables)",IDC_STATIC, + 14,50,166,9 + GROUPBOX "Protocols",IDC_STATIC,7,71,294,62 + COMBOBOX IDC_CBOPTPROTO,13,86,97,97,CBS_DROPDOWNLIST | CBS_SORT | WS_TABSTOP + EDITTEXT IDC_PROTOFILE,117,86,159,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_PROTOBROWSE,281,87,15,11 + RTEXT "Maximum fortune length:",IDC_STATIC,119,104,122,9 + EDITTEXT IDC_EMAXLEN,245,102,31,12,ES_NUMBER | NOT WS_BORDER, + WS_EX_CLIENTEDGE + CONTROL "Spin2",IDC_SMAXLEN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,267,102, + 9,12 + LTEXT "(Used for the %protofortunemsg%-type variables)", + IDC_STATIC,14,120,166,9 + GROUPBOX "Statuses",IDC_STATIC,7,141,294,50 + COMBOBOX IDC_CBOPTSTATUS,13,156,97,97,CBS_DROPDOWNLIST | + WS_TABSTOP + EDITTEXT IDC_STATUSFILE,117,156,159,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_STATUSBROWSE,281,157,15,11 + LTEXT "(Used for the %statusfortunemsg%-type variables)", + IDC_STATIC,14,178,166,9 + CONTROL "Remove CR characters ('\\r')",IDC_CCHECKREMOVECR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,198,282,10 + CONTROL "One line fortunes (remove LFs '\\n', CRs '\\r', tabs '\\t' and cosecutive spaces)", + IDC_CCHECKONELINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 13,211,282,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_OPTIONDLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 301 + TOPMARGIN, 7 + BOTTOMMARGIN, 245 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + -- cgit v1.2.3