summaryrefslogtreecommitdiff
path: root/plugins/BASS_interface/src/Main.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-05 13:40:33 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-05 13:40:33 +0000
commit3625defe533b307b8e52c926129f7f7f50a67962 (patch)
tree67221d478f70c9dd7ad73f9f4c59c435246c1182 /plugins/BASS_interface/src/Main.cpp
parenta819777ad787b9a5b96fcd567d531fbec98ad5f7 (diff)
bass_interface: folder structure change
git-svn-id: http://svn.miranda-ng.org/main/trunk@775 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/BASS_interface/src/Main.cpp')
-rw-r--r--plugins/BASS_interface/src/Main.cpp500
1 files changed, 500 insertions, 0 deletions
diff --git a/plugins/BASS_interface/src/Main.cpp b/plugins/BASS_interface/src/Main.cpp
new file mode 100644
index 0000000000..46e1b050e9
--- /dev/null
+++ b/plugins/BASS_interface/src/Main.cpp
@@ -0,0 +1,500 @@
+/*
+Copyright (C) 2010, 2011 tico-tico
+*/
+
+#include "bass_interface.h"
+
+HINSTANCE hInst;
+int hLangpack;
+
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+ __PLUGIN_NAME,
+ PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
+ __DESCRIPTION,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ MIID_BASSINT
+};
+
+
+static HANDLE hHooks[5] = {0};
+static HANDLE hService;
+static HINSTANCE hBass = NULL;
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ return &pluginInfo;
+}
+
+#define MAXCHAN 5
+static TCHAR CurrBassPath[MAX_PATH], tmp[MAX_PATH];
+static int sndNSnd = 0, sndLimSnd;
+static HSTREAM sndSSnd[MAXCHAN] = {0};
+
+static WORD TimeWrd1, TimeWrd2, StatMask;
+static BOOL QuietTime, Preview, EnPreview;
+static int Volume;
+static int device = -1;
+static int newBass = 0;
+static HWND ClistHWND;
+
+static int OnPlaySnd(WPARAM wParam, LPARAM lParam)
+{
+ TCHAR* ptszFile = (TCHAR*) lParam; SYSTEMTIME systime; WORD currtime, currstat; BOOL doPlay = TRUE;
+
+ GetLocalTime(&systime);
+ currtime = MAKEWORD(systime.wMinute, systime.wHour);
+
+ currstat = 1;
+ switch (CallService(MS_CLIST_GETSTATUSMODE, 0, 0))
+ {
+ case ID_STATUS_OUTTOLUNCH: currstat <<= 1;
+ case ID_STATUS_ONTHEPHONE: currstat <<= 1;
+ case ID_STATUS_INVISIBLE: currstat <<= 1;
+ case ID_STATUS_FREECHAT: currstat <<= 1;
+ case ID_STATUS_DND: currstat <<= 1;
+ case ID_STATUS_OCCUPIED: currstat <<= 1;
+ case ID_STATUS_NA: currstat <<= 1;
+ case ID_STATUS_AWAY: currstat <<= 1;
+ case ID_STATUS_ONLINE: currstat <<= 1;
+ }
+
+ if ( !DBGetContactSettingByte(NULL,"Skin","UseSound",0)) doPlay = FALSE;
+
+ if ( QuietTime )
+ if (
+ ((TimeWrd1 < TimeWrd2) && (TimeWrd1 <= currtime && currtime < TimeWrd2)) ||
+ ((TimeWrd2 < TimeWrd1) && (TimeWrd1 <= currtime || currtime < TimeWrd2))
+ ) doPlay = FALSE;
+
+ if ( !(currstat & StatMask)) doPlay = FALSE;
+
+ if ( Preview || (int)wParam==1 ) doPlay = TRUE;
+
+ if ( !ptszFile ) doPlay = FALSE;
+
+ if ( doPlay )
+ {
+ BASS_StreamFree(sndSSnd[sndNSnd]);
+ sndSSnd[sndNSnd] = BASS_StreamCreateFile(FALSE, ptszFile, 0, 0, BASS_TCHAR | BASS_STREAM_AUTOFREE);
+ BASS_ChannelPlay(sndSSnd[sndNSnd], FALSE);
+ sndNSnd = (sndNSnd+1)%sndLimSnd;
+ }
+
+ Preview = FALSE;
+
+ return 0;
+}
+
+#define SLIDER_MIN 0
+#define SLIDER_MAX 100
+
+INT_PTR CALLBACK OptionsProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ int i; SYSTEMTIME systime = {0};
+
+ TranslateDialogDefault(hwndDlg);
+
+ SendDlgItemMessage(hwndDlg, IDC_MAXCHANNEL, CB_RESETCONTENT, 0, 0);
+ for(i=1; i<=MAXCHAN; i++)
+ SendDlgItemMessage(hwndDlg, IDC_MAXCHANNEL, CB_ADDSTRING, 0, (LPARAM)_itot(i, tmp, 10));
+
+ SendDlgItemMessage(hwndDlg, IDC_MAXCHANNEL, CB_SETCURSEL, sndLimSnd - 1, 0);
+
+ SendDlgItemMessage(hwndDlg, IDC_CURRPATH, WM_SETTEXT, 0, (LPARAM)CurrBassPath);
+
+ SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_SETRANGE, FALSE, MAKELONG(SLIDER_MIN,SLIDER_MAX));
+ SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_SETPOS, TRUE, Volume);
+ SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_SETPAGESIZE, 0, 5);
+
+ systime.wHour = HIBYTE(TimeWrd1);
+ systime.wMinute = LOBYTE(TimeWrd1);
+ systime.wYear = 2000;
+ systime.wMonth = 1;
+ systime.wDay = 1;
+ SendDlgItemMessage(hwndDlg, IDC_TIME1, DTM_SETFORMAT, 0, (LPARAM)_T("HH:mm"));
+ SendDlgItemMessage(hwndDlg, IDC_TIME1, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&systime);
+ systime.wHour = HIBYTE(TimeWrd2);
+ systime.wMinute = LOBYTE(TimeWrd2);
+ SendDlgItemMessage(hwndDlg, IDC_TIME2, DTM_SETFORMAT, 0, (LPARAM)_T("HH:mm"));
+ SendDlgItemMessage(hwndDlg, IDC_TIME2, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&systime);
+
+ CheckDlgButton(hwndDlg, IDC_PREVIEW, EnPreview ? BST_CHECKED : BST_UNCHECKED);
+
+ for(i = IDC_CHECKBOX1; i < IDC_CHECKBOX10+1; i++)
+ {
+ if (StatMask & (1 << (i-IDC_CHECKBOX1)))
+ CheckDlgButton(hwndDlg, i, BST_CHECKED);
+ }
+
+ if (QuietTime)
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_TIME1), TRUE);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_TIME2), TRUE);
+ CheckDlgButton(hwndDlg, IDC_QUIETTIME, BST_CHECKED);
+ }
+ if (hBass == NULL)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VOLUME), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_MAXCHANNEL), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OUTDEVICE), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_QUIETTIME), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PREVIEW), FALSE);
+
+ for(i = IDC_CHECKBOX1; i < IDC_CHECKBOX10+1; i++)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, i), FALSE);
+ }
+ }
+ else
+ {
+ DBVARIANT dbv = {0}; BASS_DEVICEINFO info; DWORD bassver = BASS_GetVersion();
+
+ mir_sntprintf(tmp, SIZEOF(tmp), TranslateT("un4seen's bass version: %d.%d.%d.%d"), bassver >> 24, (bassver >> 16) & 0xff, (bassver >> 8) & 0xff, bassver & 0xff);
+ SendDlgItemMessage(hwndDlg, IDC_BASSVERSION, WM_SETTEXT, 0, (LPARAM)tmp);
+
+ SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_ADDSTRING, 0, (LPARAM)TranslateT("--default device--"));
+ SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_SETCURSEL, 0, 0);
+ DBGetContactSettingString(NULL, ModuleName, OPT_OUTDEVICE, &dbv);
+ for (i=1; BASS_GetDeviceInfo(i+newBass, &info); i++)
+ {
+ SendDlgItemMessageA(hwndDlg, IDC_OUTDEVICE, CB_ADDSTRING, 0, (LPARAM)info.name);
+ if (!lstrcmpA(dbv.pszVal, info.name))
+ SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_SETCURSEL, i, 0);
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ return 1;
+ }
+
+ case WM_HSCROLL:
+ if (hBass != NULL)
+ if (LOWORD(wParam) == SB_ENDSCROLL || LOWORD(wParam) == SB_THUMBTRACK)
+ {
+ BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_GETPOS, 0, 0) * 100);
+ Preview = TRUE;
+ if (EnPreview) SkinPlaySound("AlertMsg");
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ if (hBass != NULL)
+ {
+ int i; SYSTEMTIME systime;
+
+ SendDlgItemMessageA(hwndDlg, IDC_OUTDEVICE, WM_GETTEXT, sizeof(tmp), (LPARAM)tmp);
+ DBWriteContactSettingString(NULL, ModuleName, OPT_OUTDEVICE, (char *)tmp);
+
+ Volume = (DWORD)SendDlgItemMessage(hwndDlg, IDC_VOLUME, TBM_GETPOS, 0, 0);
+ DBWriteContactSettingByte(NULL, ModuleName, OPT_VOLUME, Volume);
+
+ sndLimSnd = SendDlgItemMessage(hwndDlg, IDC_MAXCHANNEL, CB_GETCURSEL, 0, 0) + 1;
+ if ( sndLimSnd > MAXCHAN ) sndLimSnd = MAXCHAN;
+ DBWriteContactSettingByte(NULL, ModuleName, OPT_MAXCHAN, sndLimSnd);
+
+ QuietTime = IsDlgButtonChecked(hwndDlg, IDC_QUIETTIME) == BST_CHECKED;
+ DBWriteContactSettingByte(NULL, ModuleName, OPT_QUIETTIME, QuietTime);
+
+ SendDlgItemMessage(hwndDlg, IDC_TIME1, DTM_GETSYSTEMTIME, 0, (LPARAM)&systime);
+ TimeWrd1 = MAKEWORD(systime.wMinute, systime.wHour);
+ DBWriteContactSettingWord(NULL, ModuleName, OPT_TIME1, TimeWrd1);
+
+ SendDlgItemMessage(hwndDlg, IDC_TIME2, DTM_GETSYSTEMTIME, 0, (LPARAM)&systime);
+ TimeWrd2 = MAKEWORD(systime.wMinute, systime.wHour);
+ DBWriteContactSettingWord(NULL, ModuleName, OPT_TIME2, TimeWrd2);
+
+ EnPreview = IsDlgButtonChecked(hwndDlg, IDC_PREVIEW) == BST_CHECKED;
+ DBWriteContactSettingByte(NULL, ModuleName, OPT_PREVIEW, EnPreview);
+
+ StatMask = 0;
+ for(i = IDC_CHECKBOX10; i > IDC_CHECKBOX1-1; i--)
+ {
+ StatMask <<= 1;
+ if(IsDlgButtonChecked(hwndDlg, i) == BST_CHECKED)
+ StatMask |= 1;
+ }
+
+ DBWriteContactSettingWord(NULL, ModuleName, OPT_STATUS, StatMask);
+
+ device = SendDlgItemMessage(hwndDlg, IDC_OUTDEVICE, CB_GETCURSEL, 0, 0);
+ if (device == 0) device = -1;
+ else device += newBass;
+ if (CallService(MS_TB_GETBUTTONSTATEBYID, (WPARAM)"BASSSoundOnOff", 0)==TBST_RELEASED)
+ {
+ BASS_Free();
+ BASS_Init(device, 44100, 0, ClistHWND, NULL);
+ BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume * 100 );
+ }
+ }
+ return 1;
+
+ case PSN_RESET:
+ if (hBass != NULL)
+ {
+ BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume * 100);
+ }
+ return 1;
+
+ case DTN_DATETIMECHANGE:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ return 1;
+ }
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case IDC_QUIETTIME:
+ {
+ BOOL b = IsDlgButtonChecked(hwndDlg, IDC_QUIETTIME) == BST_CHECKED;
+ EnableWindow(GetDlgItem(hwndDlg,IDC_TIME1), b);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_TIME2), b);
+ }
+ case IDC_MAXCHANNEL:
+ case IDC_OUTDEVICE:
+ case IDC_CHECKBOX1:
+ case IDC_CHECKBOX2:
+ case IDC_CHECKBOX3:
+ case IDC_CHECKBOX4:
+ case IDC_CHECKBOX5:
+ case IDC_CHECKBOX6:
+ case IDC_CHECKBOX7:
+ case IDC_CHECKBOX8:
+ case IDC_CHECKBOX9:
+ case IDC_CHECKBOX10:
+ case IDC_PREVIEW:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ case IDC_GETBASS:
+ CallService(MS_UTILS_OPENURL , 1, (LPARAM)"http://www.un4seen.com/");
+ break;
+ }
+ break;
+
+ //case WM_CLOSE:
+ // EndDialog(hwndDlg, 0);
+ }
+ return 0;
+}
+
+struct
+{
+ char* szDescr;
+ char* szName;
+ int defIconID;
+}
+static const iconList[] =
+{
+ { "Audio device is opened", "BASSSoundOnOffUp", IDI_BASSSoundOnOffUp },
+ { "Audio device is closed", "BASSSoundOnOffDown", IDI_BASSSoundOnOffDown }
+};
+
+static HANDLE hIconLibItem[SIZEOF(iconList)];
+
+void InitIcons(void)
+{
+ int i; char szSettingName[100]; SKINICONDESC sid = {0}; TCHAR szFile[MAX_PATH];
+
+ GetModuleFileName(hInst, szFile, SIZEOF(szFile));
+
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.ptszDefaultFile = szFile;
+ sid.cx = sid.cy = 16;
+ sid.pszName = szSettingName;
+ sid.pszSection = ModuleName;
+ sid.flags = SIDF_PATH_TCHAR;
+
+ for (i = 0; i < SIZEOF(iconList); i++)
+ {
+ mir_snprintf(szSettingName, SIZEOF(szSettingName), "%s_%s", ModuleName, iconList[i].szName);
+
+ sid.pszDescription = (char*)iconList[i].szDescr;
+ sid.iDefaultIndex = -iconList[i].defIconID;
+ hIconLibItem[i] = Skin_AddIcon(&sid);
+ }
+}
+
+int OptionsInit(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = {0};
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
+ odp.pszTitle = LPGEN(ModuleName);
+ odp.pfnDlgProc = OptionsProc;
+ odp.pszGroup = LPGEN("Customize");
+ odp.flags = ODPF_BOLDGROUPS;
+
+ Options_AddPage(wParam, &odp);
+ return 0;
+}
+
+INT_PTR BASSSoundOnOff(WPARAM wParam, LPARAM lParam)
+{
+ if (hBass != NULL)
+ {
+ BOOL opened = CallService(MS_TB_GETBUTTONSTATEBYID, (WPARAM)"BASSSoundOnOff", 0) == TBST_RELEASED;
+
+ if ( opened )
+ {
+ BASS_Free(); // Close Device
+ }
+ else
+ {
+ BASS_Init(device, 44100, 0, ClistHWND, NULL);
+ BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume * 100 );
+ }
+
+ CallService(MS_TB_SETBUTTONSTATEBYID, (WPARAM)"BASSSoundOnOff", opened ? TBST_PUSHED : TBST_RELEASED);
+ DBWriteContactSettingByte(NULL, ModuleName, OPT_DEVOPEN, !opened);
+ }
+ return 0;
+}
+
+int OnToolbarLoaded(WPARAM wParam, LPARAM lParam)
+{
+ TBButton tbb = {0};
+ tbb.cbSize = sizeof(TBButton);
+ tbb.pszButtonID = "BASSSoundOnOff";
+ tbb.pszButtonName = Translate("Open/close audio device");
+ tbb.pszServiceName = "BASSinterface/BASSSoundOnOff";
+ tbb.pszTooltipUp = Translate("Audio device is opened");
+ tbb.pszTooltipDn = Translate("Audio device is closed");
+ tbb.hPrimaryIconHandle = hIconLibItem[0];
+ tbb.hSecondaryIconHandle = hIconLibItem[1];
+ tbb.tbbFlags = TBBF_SHOWTOOLTIP;
+ tbb.defPos = 1000;
+
+ CallService(MS_TB_ADDBUTTON, 0, (LPARAM)&tbb);
+
+ return 0;
+}
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ DBVARIANT dbv = {0};
+
+ if (DBGetContactSettingTString(NULL, ModuleName, OPT_BASSPATH, &dbv))
+ {
+ DBWriteContactSettingTString(NULL, ModuleName, OPT_BASSPATH, _T("Plugins\\Bass\\Bass.dll"));
+ lstrcpy(tmp, _T("Plugins\\Bass\\Bass.dll"));
+ }
+ else
+ {
+ lstrcpy(tmp, dbv.ptszVal);
+ }
+
+ DBFreeVariant(&dbv);
+
+ CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)tmp, (LPARAM)CurrBassPath);
+ hBass = LoadLibrary(CurrBassPath);
+
+ if (hBass != NULL)
+ {
+ if (LOADBASSFUNCTION(BASS_Init) != NULL && LOADBASSFUNCTION(BASS_SetConfig) != NULL &&
+ LOADBASSFUNCTION(BASS_ChannelPlay) != NULL && LOADBASSFUNCTION(BASS_StreamCreateFile) != NULL &&
+ LOADBASSFUNCTION(BASS_GetVersion) != NULL && LOADBASSFUNCTION(BASS_StreamFree) != NULL &&
+ LOADBASSFUNCTION(BASS_GetDeviceInfo) != NULL && LOADBASSFUNCTION(BASS_Free))
+ {
+ int i; BASS_DEVICEINFO info;
+
+ newBass = (BASS_SetConfig(BASS_CONFIG_DEV_DEFAULT, TRUE) != 0); // will use new "Default" device
+
+ if (!DBGetContactSettingString(NULL, ModuleName, OPT_OUTDEVICE, &dbv))
+ {
+ for (i=1; BASS_GetDeviceInfo(i, &info); i++)
+ if (!lstrcmpA(dbv.pszVal, info.name))
+ device = i;
+ }
+ DBFreeVariant(&dbv);
+
+ sndLimSnd = DBGetContactSettingByte(NULL, ModuleName, OPT_MAXCHAN, MAXCHAN);
+ if ( sndLimSnd > MAXCHAN ) sndLimSnd = MAXCHAN;
+ TimeWrd1 = DBGetContactSettingWord(NULL, ModuleName, OPT_TIME1, 0);
+ TimeWrd2 = DBGetContactSettingWord(NULL, ModuleName, OPT_TIME2, 0);
+ QuietTime = DBGetContactSettingByte(NULL, ModuleName, OPT_QUIETTIME, 0);
+ EnPreview = DBGetContactSettingByte(NULL, ModuleName, OPT_PREVIEW, 0);
+
+ StatMask = DBGetContactSettingWord(NULL, ModuleName, OPT_STATUS, 0x3ff);
+
+ ClistHWND = (HWND)CallService("CLUI/GetHwnd", 0, 0);
+ if (DBGetContactSettingByte(NULL, ModuleName, OPT_DEVOPEN, 1))
+ BASS_Init(device, 44100, 0, ClistHWND, NULL);
+ else
+ CallService(MS_TB_SETBUTTONSTATEBYID, (WPARAM)"BASSSoundOnOff", TBST_PUSHED);
+
+ Volume = DBGetContactSettingByte(NULL, ModuleName, OPT_VOLUME, 33);
+ BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume * 100 );
+ hHooks[3] = HookEvent(ME_SKIN_PLAYINGSOUND, OnPlaySnd);
+ }
+ else
+ {
+ FreeLibrary(hBass);
+ hBass = NULL;
+ }
+ }
+
+ hHooks[4] = HookEvent(ME_OPT_INITIALISE, OptionsInit);
+
+ return 0;
+}
+
+int OnShutdown(WPARAM wParam, LPARAM lParam)
+{
+ if(hBass != NULL)
+ {
+ BASS_Free();
+ FreeLibrary(hBass);
+ }
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Load(void)
+{
+ mir_getLP(&pluginInfo);
+
+ hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+ hHooks[1] = HookEvent(ME_SYSTEM_SHUTDOWN, OnShutdown);
+ hHooks[2] = HookEvent(ME_TB_MODULELOADED, OnToolbarLoaded);
+
+ hService = CreateServiceFunction("BASSinterface/BASSSoundOnOff", BASSSoundOnOff);
+
+ InitIcons();
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ int i;
+ for (i = 0; i < SIZEOF(hHooks); i++)
+ {
+ if (hHooks[i])
+ UnhookEvent(hHooks[i]);
+ }
+
+ DestroyServiceFunction(hService);
+
+ return 0;
+} \ No newline at end of file