using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Reflection; using System.Resources; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; using System.Collections.ObjectModel; using Virtuoso.Miranda.Plugins.Infrastructure; using Virtuoso.Miranda.Plugins.Native; //using xJuick.Core; //using xJuick.Fork; using Speak.Interop; using Speak.Structs; //using xJuick.UI; using Speak.Utils; using Speak.TTS; //using ISite = xJuick.Sites.ISite; namespace Speak.Opt { internal class Options { #region Menu Constants private const Int32 IDD_SPEAK_OPTIONS_DIALOG = 666; private const Int32 IDD_ANNOUNCE_OPTIONS_DIALOG = 667; private const Int32 IDD_ENGINE_OPTIONS_DIALOG = 668; private const Int32 IDC_SPEAK_LIST = 1079; private const Int32 IDC_SPEAK_VISIBLEICON = 1204; private const Int32 IDC_SPEAK_INVISIBLEICON = 1205; private const Int32 IDI_ANNOUNCE_OFFLINE = 1002; private const Int32 IDI_ANNOUNCE_ONLINE = 1025; private const Int32 IDI_ANNOUNCE_AWAY = 1024; private const Int32 IDI_ANNOUNCE_DND = 1019; private const Int32 IDI_ANNOUNCE_NA = 1026; private const Int32 IDI_ANNOUNCE_OCCUPIED = 1027; private const Int32 IDI_ANNOUNCE_FREEFORCHAT = 1028; private const Int32 IDI_ANNOUNCE_INVISIBLE = 1029; private const Int32 IDI_ANNOUNCE_CONNECT = 1030; private const Int32 IDI_ANNOUNCE_DISCONNECT = 1031; private const Int32 IDI_ANNOUNCE_SHUTDOWN = 1032; private const Int32 IDI_ANNOUNCE_ACTIVE = 1033; private const Int32 IDI_ANNOUNCE_ONOPEN = 1034; private const Int32 IDI_ANNOUNCE_ONFOCUS = 1035; private const Int32 IDI_ANNOUNCE_LENGTH = 1011; private const Int32 IDI_ENGINE_VOICES = 1001; private const Int32 IDI_ENGINE_VOLUME = 1000; private const Int32 IDI_ENGINE_RATE = 1002; private const Int32 IDI_ENGINE_PITCH = 1003; private const Int32 IDI_ENGINE_WELCOME = 1011; private const Int32 IDI_ENGINE_TEST = 1006; #endregion private bool initset = true; private Delegate dlgProcSpeak; private Delegate dlgProcAnnounce; private Delegate dlgProcEngine; private int hItemUnkSpeak; private static Win32ImageList imagelistSpeak; /// /// Enum of the Events /// public enum EventChanged { /// /// When A Usercontact has Changed /// Active, /// /// When the Global Settings Changed /// Announce, /// /// When the Engine Settings Changed /// Engine, /// /// No Events has Raised /// None } /// /// Delegate an Event of Changed /// /// Eventtype public delegate void ChangedEventHandler(EventChanged e); /// /// Raises When Settings was Changed /// public event ChangedEventHandler Changed; /// /// Internal Raising for Event /// /// protected virtual void OnChanged(EventChanged e) { if (Changed != null) Changed(e); } /// /// The Option Class that Handles the Optionsdialog /// public Options() { initImageLists(); } private void initImageLists() { imagelistSpeak = createImageList(new List() { StandartIcons.SKINICON_OTHER_SMALLDOT, StandartIcons.SKINICON_EVENT_MESSAGE, StandartIcons.ID_STATUS_ONLINE }); } private Win32ImageList createImageList(List list) { list.Sort(); Win32ImageList imageList = new Win32ImageList(); for (int i = 0, iconCount = list.Count; i < iconCount; i++) { imageList.AddIcon(list[i], IconTable.GetDefaultIcon(list[i])); } return imageList; } /// /// Here you Can Connect your Options /// /// Miranda Handle /// /// 0 public int Opts(UIntPtr wparam, IntPtr lparam) { initset = !initset; if (initset) return 0; #region Active Status Page dlgProcSpeak = new Win32WndProc(WndProcSpeak); OptionsDialogPage odpspeak = new OptionsDialogPage(); odpspeak.szTitle = Marshal.StringToHGlobalAnsi("Active Modes"); odpspeak.cbSize = Marshal.SizeOf(odpspeak); odpspeak.position = 0; odpspeak.pszTemplate = new IntPtr((UInt32)((short)IDD_SPEAK_OPTIONS_DIALOG)); odpspeak.pfnDlgProc = Marshal.GetFunctionPointerForDelegate(dlgProcSpeak); odpspeak.szGroup = Marshal.StringToHGlobalAnsi("Speak"); odpspeak.groupPosition = 100; odpspeak.hGroupIcon = IntPtr.Zero; odpspeak.flags = MainConstants.ODPF_BOLDGROUPS; odpspeak.hInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]); IntPtr cmdPtrSpeak = Marshal.AllocHGlobal(Marshal.SizeOf(odpspeak)); Marshal.StructureToPtr(odpspeak, cmdPtrSpeak, false); MirandaContext.Current.CallService(API.MS_OPT_ADDPAGE, wparam, cmdPtrSpeak); #endregion #region Announce Page dlgProcAnnounce = new Win32WndProc(WndProcAnnounce); OptionsDialogPage odpannounce = new OptionsDialogPage(); odpannounce.szTitle = Marshal.StringToHGlobalAnsi("Announce"); odpannounce.cbSize = Marshal.SizeOf(odpannounce); odpannounce.position = 0; odpannounce.pszTemplate = new IntPtr((UInt32)((short)IDD_ANNOUNCE_OPTIONS_DIALOG)); odpannounce.pfnDlgProc = Marshal.GetFunctionPointerForDelegate(dlgProcAnnounce); odpannounce.szGroup = Marshal.StringToHGlobalAnsi("Speak"); odpannounce.groupPosition = 101; odpannounce.hGroupIcon = IntPtr.Zero; odpannounce.flags = MainConstants.ODPF_BOLDGROUPS; odpannounce.hInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]); IntPtr cmdPtrAnnounce = Marshal.AllocHGlobal(Marshal.SizeOf(odpannounce)); Marshal.StructureToPtr(odpannounce, cmdPtrAnnounce, false); MirandaContext.Current.CallService(API.MS_OPT_ADDPAGE, wparam, cmdPtrAnnounce); #endregion #region Engine/Voice Page dlgProcEngine = new Win32WndProc(WndProcEngine); OptionsDialogPage odpengine = new OptionsDialogPage(); odpengine.szTitle = Marshal.StringToHGlobalAnsi("Engine/Voice"); odpengine.cbSize = Marshal.SizeOf(odpengine); odpengine.position = 0; odpengine.pszTemplate = new IntPtr((UInt32)((short)IDD_ENGINE_OPTIONS_DIALOG)); odpengine.pfnDlgProc = Marshal.GetFunctionPointerForDelegate(dlgProcEngine); odpengine.szGroup = Marshal.StringToHGlobalAnsi("Speak"); odpengine.groupPosition = 102; odpengine.hGroupIcon = IntPtr.Zero; odpengine.flags = MainConstants.ODPF_BOLDGROUPS; odpengine.hInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]); IntPtr cmdPtrEngine = Marshal.AllocHGlobal(Marshal.SizeOf(odpengine)); Marshal.StructureToPtr(odpengine, cmdPtrEngine, false); MirandaContext.Current.CallService(API.MS_OPT_ADDPAGE, wparam, cmdPtrEngine); #endregion return 0; } private int WndProcEngine(IntPtr hWnd, int Msg, int wParam, int lParam) { switch (Msg) { case WinApi.WM_INITDIALOG: InitEngine(hWnd); return 0; case WinApi.WM_COMMAND: return ProcessCommandEngine(hWnd, Util.LoWord(wParam), Util.HiWord(wParam), lParam); case WinApi.WM_NOTIFY: return NotifyEngine(hWnd, wParam, lParam); } return 0; } private int NotifyEngine(IntPtr hWnd, int wParam, int lParam) { NMHDR lParams; lParams = (NMHDR)Marshal.PtrToStructure((IntPtr)lParam, typeof(NMHDR)); switch (lParams.idFrom) { case IDI_ENGINE_VOLUME: case IDI_ENGINE_RATE: case IDI_ENGINE_PITCH: if (lParams.code == WinApi.WM_HSCROLL) { WinApi.SendMessage(WinApi.GetParent(hWnd), WinApi.PSM_CHANGED, 0, 0); return 0; } break; case 0: switch (lParams.code) { case WinApi.PSN_APPLY: { writeDBstring("engine", "speak_config", GetComboText(hWnd, IDI_ENGINE_VOICES)); writeDBlong("volume", "speak_config", (uint)GetSlider(hWnd, IDI_ENGINE_VOLUME)); writeDBlong("rate", "speak_config", (uint)GetSlider(hWnd, IDI_ENGINE_RATE)); writeDBlong("pitch", "speak_config", (uint)GetSlider(hWnd, IDI_ENGINE_PITCH)); writeDBstring("welcome_msg", "speak_config", GetText(hWnd, IDI_ENGINE_WELCOME)); OnChanged(EventChanged.Engine); return 1; } } break; } return 0; } private int ProcessCommandEngine(IntPtr hwndDlg, Int16 item, Int16 command, Int32 lParam) { switch (item) { case IDI_ENGINE_TEST: { if (command == WinApi.BN_CLICKED) { TextToSpeak s = TextToSpeak.getInstance(); s.setVoice(GetComboText(hwndDlg, IDI_ENGINE_VOICES)); s.setVolume(GetSlider(hwndDlg, IDI_ENGINE_VOLUME)); s.setRate(GetSlider(hwndDlg, IDI_ENGINE_RATE)); s.setPitch(GetSlider(hwndDlg, IDI_ENGINE_PITCH)); s.speak(GetText(hwndDlg, IDI_ENGINE_WELCOME), "test" + GetText(hwndDlg, IDI_ENGINE_WELCOME) + DateTime.Now); } } break; case IDI_ENGINE_VOICES: { if (command == WinApi.CBN_SELCHANGE) { WinApi.SendMessage(WinApi.GetParent(hwndDlg), WinApi.PSM_CHANGED, 0, 0); return 0; } } break; case IDI_ENGINE_WELCOME: if (command == WinApi.EN_CHANGE) { WinApi.SendMessage(WinApi.GetParent(hwndDlg), WinApi.PSM_CHANGED, 0, 0); } return 0; } return 0; } private int GetSlider(IntPtr hwndDlg, int ID) { return (int)WinApi.SendDlgItemMessage(hwndDlg, ID, WinApi.TBM_GETPOS, 0, 0); } private string GetComboText(IntPtr hWnd, Int32 ID) { int nIndex = WinApi.SendDlgItemMessage(hWnd, ID, WinApi.CB_GETCURSEL, 0, 0); if (nIndex == -1) return ""; int nStrLen = WinApi.SendDlgItemMessage(hWnd, ID, WinApi.CB_GETLBTEXTLEN, nIndex, 0); IntPtr strPtr = Marshal.AllocHGlobal(nStrLen); WinApi.SendDlgItemMessage(hWnd, ID, WinApi.CB_GETLBTEXT, nIndex, strPtr); return Util.GetNormalRussian(strPtr, (uint)nStrLen); ; } private void InitEngine(IntPtr hWnd) { ClearComboBox(hWnd, IDI_ENGINE_VOICES); SetVoices(hWnd, IDI_ENGINE_VOICES, TextToSpeak.getVoices(), readDBString("engine", "speak_config")); SetRateSlider(hWnd, IDI_ENGINE_VOLUME, readDBLong("volume", "speak_config")); SetRateSlider(hWnd, IDI_ENGINE_RATE, readDBLong("rate", "speak_config")); SetRateSlider(hWnd, IDI_ENGINE_PITCH, readDBLong("pitch", "speak_config")); SetText(hWnd, IDI_ENGINE_WELCOME, readDBString("welcome_msg", "speak_config")); } private void SetRateSlider(IntPtr hWnd, int ID, long pos) { WinApi.SendDlgItemMessage(hWnd, ID, WinApi.TBM_SETRANGE, 1, WinApi.MakeLParam(1,100)); WinApi.SendDlgItemMessage(hWnd, ID, WinApi.TBM_SETPOS, 1, int.Parse(pos.ToString())); } private void SetVoices(IntPtr hWnd, int ID, List list, string standart) { int i = 0; int def = -1; foreach (string item in list) { if (item == standart) def = i; AddComboText(hWnd, ID, item); i++; } WinApi.SendDlgItemMessage(hWnd, ID, WinApi.CB_SETCURSEL, def, 0); } private void AddComboText(IntPtr hWnd, Int32 ID, string text) { int length; IntPtr str = Util.GetStringPtr(text, out length); WinApi.SendDlgItemMessage(hWnd, ID, WinApi.CB_ADDSTRING, 0, str); if (str != IntPtr.Zero) Marshal.FreeHGlobal(str); } private void ClearComboBox(IntPtr hWnd, Int32 ID) { WinApi.SendDlgItemMessage(hWnd, ID, WinApi.CB_RESETCONTENT, 0, 0); } private int WndProcAnnounce(IntPtr hWnd, int Msg, int wParam, int lParam) { switch (Msg) { case WinApi.WM_INITDIALOG: InitAnnounce(hWnd); return 0; case WinApi.WM_COMMAND: return ProcessCommandAnnounce(hWnd, Util.LoWord(wParam), Util.HiWord(wParam), lParam); case WinApi.WM_NOTIFY: return NotifyAnnounce(hWnd, wParam, lParam); } return 0; } private int NotifyAnnounce(IntPtr hwndDlg, int wParam, int lParam) { NMHDR lParams; lParams = (NMHDR)Marshal.PtrToStructure((IntPtr)lParam, typeof(NMHDR)); switch (lParams.idFrom) { case 0: switch (lParams.code) { case WinApi.PSN_APPLY: { writeDBBool("status_" + (int)StatusModes.Offline, "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_OFFLINE)); writeDBBool("status_" + (int)StatusModes.Online, "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_ONLINE)); writeDBBool("status_" + (int)StatusModes.Away, "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_AWAY)); writeDBBool("status_" + (int)StatusModes.DND, "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_DND)); writeDBBool("status_" + (int)StatusModes.NA, "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_NA)); writeDBBool("status_" + (int)StatusModes.Occupied, "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_OCCUPIED)); writeDBBool("status_" + (int)StatusModes.FreeForChat, "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_FREEFORCHAT)); writeDBBool("status_" + (int)StatusModes.Invisible, "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_INVISIBLE)); writeDBBool("active_connect", "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_CONNECT)); writeDBBool("active_disconnect", "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_DISCONNECT)); writeDBBool("active_shutdown", "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_SHUTDOWN)); writeDBBool("active", "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_ACTIVE)); writeDBBool("ignore_onopen", "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_ONOPEN)); writeDBBool("ignore_onfocus", "speak_config", IsBtnChecked(hwndDlg, IDI_ANNOUNCE_ONFOCUS)); writeDBlong("max_msg_size", "speak_config", UInt32.Parse(GetText(hwndDlg, IDI_ANNOUNCE_LENGTH))); OnChanged(EventChanged.Announce); return 1; } } break; } return 0; } private string GetText(IntPtr hwndDlg, int ID) { int nStrLen = WinApi.SendDlgItemMessage(hwndDlg, ID, WinApi.WM_GETTEXTLENGTH, 0, 0); IntPtr strPtr = Marshal.AllocHGlobal(nStrLen + 1); WinApi.SendDlgItemMessage(hwndDlg, ID, WinApi.WM_GETTEXT, nStrLen + 1, strPtr); return Marshal.PtrToStringAnsi(strPtr, nStrLen); } private bool IsBtnChecked(IntPtr hwndDlg, Int32 ID) { return WinApi.SendDlgItemMessage(hwndDlg, ID, WinApi.BM_GETCHECK, 0, 0) == WinApi.BST_CHECKED; } private int ProcessCommandAnnounce(IntPtr hwndDlg, Int16 item, Int16 command, Int32 lParam) { switch (item) { case IDI_ANNOUNCE_OFFLINE: case IDI_ANNOUNCE_ONLINE: case IDI_ANNOUNCE_AWAY: case IDI_ANNOUNCE_DND: case IDI_ANNOUNCE_NA: case IDI_ANNOUNCE_OCCUPIED: case IDI_ANNOUNCE_FREEFORCHAT: case IDI_ANNOUNCE_INVISIBLE: case IDI_ANNOUNCE_CONNECT: case IDI_ANNOUNCE_DISCONNECT: case IDI_ANNOUNCE_SHUTDOWN: case IDI_ANNOUNCE_ACTIVE: case IDI_ANNOUNCE_ONOPEN: case IDI_ANNOUNCE_ONFOCUS: WinApi.SendMessage(WinApi.GetParent(hwndDlg), WinApi.PSM_CHANGED, 0, 0); return 0; case IDI_ANNOUNCE_LENGTH: if (command == WinApi.EN_CHANGE) { WinApi.SendMessage(WinApi.GetParent(hwndDlg), WinApi.PSM_CHANGED, 0, 0); } return 0; } return 0; } private void InitAnnounce(IntPtr hWnd) { SetCheckState(hWnd, IDI_ANNOUNCE_OFFLINE, readDBBool("status_" + (int)StatusModes.Offline, "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_ONLINE, readDBBool("status_" + (int)StatusModes.Online, "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_AWAY, readDBBool("status_" + (int)StatusModes.Away, "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_DND, readDBBool("status_" + (int)StatusModes.DND, "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_NA, readDBBool("status_" + (int)StatusModes.NA, "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_OCCUPIED, readDBBool("status_" + (int)StatusModes.Occupied, "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_FREEFORCHAT, readDBBool("status_" + (int)StatusModes.FreeForChat, "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_INVISIBLE, readDBBool("status_" + (int)StatusModes.Invisible, "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_CONNECT, readDBBool("active_connect", "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_DISCONNECT, readDBBool("active_disconnect", "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_SHUTDOWN, readDBBool("active_shutdown", "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_ACTIVE, readDBBool("active", "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_ONOPEN, readDBBool("ignore_onopen", "speak_config")); SetCheckState(hWnd, IDI_ANNOUNCE_ONFOCUS, readDBBool("ignore_onfocus", "speak_config")); SetText(hWnd, IDI_ANNOUNCE_LENGTH, readDBLong("max_msg_size","speak_config").ToString()); } private void SetText(IntPtr hWnd, Int32 ID, string text) { int length; IntPtr str = Util.GetStringPtr(text, out length); WinApi.SendDlgItemMessage(hWnd, ID, WinApi.WM_SETTEXT, 0, Marshal.StringToHGlobalAnsi(text)); if (str != IntPtr.Zero) Marshal.FreeHGlobal(str); } private void SetCheckState(IntPtr hWnd, Int32 ID, bool isChecked) { WinApi.SendDlgItemMessage(hWnd, ID, WinApi.BM_SETCHECK, isChecked ? WinApi.BST_CHECKED : WinApi.BST_UNCHECKED, 0); } private int WndProcSpeak(IntPtr hWnd, int Msg, int wParam, int lParam) { switch (Msg) { case WinApi.WM_INITDIALOG: initImageLists(); InitSpeakList(hWnd); return 0; case WinApi.WM_SETFOCUS: WinApi.SetFocus(WinApi.GetDlgItem(hWnd, IDC_SPEAK_LIST)); break; case WinApi.WM_NOTIFY: return NotifySpeak(hWnd, wParam, lParam); case WinApi.WM_DESTROY: DestroySpeak(hWnd); break; } return 0; } private int NotifySpeak(IntPtr hwndDlg, int wParam, int lParam) { NMHDR lParams; lParams = (NMHDR)Marshal.PtrToStructure((IntPtr)lParam, typeof(NMHDR)); switch (lParams.idFrom) { case IDC_SPEAK_LIST: switch (lParams.code) { case ContactListConstants.CLN_NEWCONTACT: case ContactListConstants.CLN_LISTREBUILT: WinApi.SendMessage(WinApi.GetDlgItem(hwndDlg, IDC_SPEAK_LIST), ContactListConstants.CLM_AUTOREBUILD, 0, 0); SetAllContactIcons(WinApi.GetDlgItem(hwndDlg, IDC_SPEAK_LIST), imagelistSpeak); SetListGroupIcons(WinApi.GetDlgItem(hwndDlg, IDC_SPEAK_LIST), WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_ROOT, 0), 0, imagelistSpeak, null); break; case ContactListConstants.CLN_OPTIONSCHANGED: SetListGroupIcons(WinApi.GetDlgItem(hwndDlg, IDC_SPEAK_LIST), WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_ROOT, 0), 0, imagelistSpeak, null); break; case WinApi.NM_CLICK: { int hItem; NMCLISTCONTROL nm; nm = (NMCLISTCONTROL)Marshal.PtrToStructure((IntPtr)lParam, typeof(NMCLISTCONTROL)); int iImage; int itemType; // Make sure we have an extra column if (nm.iColumn == -1) break; // Find clicked item hItem = WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_HITTEST, 0, WinApi.MakeLParam(nm.pt.X, nm.pt.Y)); // Nothing was clicked if (hItem == 0) break; // Get image in clicked column (2=none, 1=online, 0=message) iImage = WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_GETEXTRAIMAGE, hItem, WinApi.MakeLParam(nm.iColumn, 0)); if (iImage == imagelistSpeak[StandartIcons.SKINICON_OTHER_SMALLDOT]) { iImage = (nm.iColumn == 0) ? imagelistSpeak[StandartIcons.ID_STATUS_ONLINE] : imagelistSpeak[StandartIcons.SKINICON_EVENT_MESSAGE]; } else { if (iImage == imagelistSpeak[StandartIcons.ID_STATUS_ONLINE] || iImage == imagelistSpeak[StandartIcons.SKINICON_EVENT_MESSAGE]) { iImage = imagelistSpeak[StandartIcons.SKINICON_OTHER_SMALLDOT]; } } itemType = WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_GETITEMTYPE, hItem, 0); if (itemType == ContactListConstants.CLCIT_CONTACT) { // A contact WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_SETEXTRAIMAGE, hItem, WinApi.MakeLParam(nm.iColumn, iImage)); } else if (itemType == ContactListConstants.CLCIT_INFO) { WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_SETEXTRAIMAGE, hItem, WinApi.MakeLParam(nm.iColumn, iImage)); } // Update the all/none icons SetListGroupIcons(WinApi.GetDlgItem(hwndDlg, IDC_SPEAK_LIST), WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_ROOT, 0), 0, imagelistSpeak, null); // Activate Apply button WinApi.SendMessage(WinApi.GetParent(hwndDlg), WinApi.PSM_CHANGED, 0, 0); } break; } break; case 0: switch (lParams.code) { case WinApi.PSN_APPLY: { int hContact = MirandaContext.Current.CallService(API.MS_DB_CONTACT_FINDFIRST, IntPtr.Zero, IntPtr.Zero); do { int hItem = WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_FINDCONTACT, hContact, 0); if (hItem != 0) { for (int i = 0; i < 2; i++) { int iImage = WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_GETEXTRAIMAGE, hItem, WinApi.MakeLParam(i, 0)); if (i == 0) { if (iImage == imagelistSpeak[StandartIcons.ID_STATUS_ONLINE]) { writeDBBool("status", "speak_config", false, (IntPtr)hContact); } else { writeDBBool("status", "speak_config", true, (IntPtr)hContact); } } if (i == 1) { if (iImage == imagelistSpeak[StandartIcons.SKINICON_EVENT_MESSAGE]) { writeDBBool("message", "speak_config", false, (IntPtr)hContact); } else { writeDBBool("message", "speak_config", true, (IntPtr)hContact); } } } } } while ((hContact = MirandaContext.Current.CallService(API.MS_DB_CONTACT_FINDNEXT, (IntPtr)hContact, IntPtr.Zero)) != 0); for (int i = 0; i < 2; i++) { int iImageu = WinApi.SendDlgItemMessage(hwndDlg, IDC_SPEAK_LIST, ContactListConstants.CLM_GETEXTRAIMAGE, hItemUnkSpeak, WinApi.MakeLParam(i, 0)); if (i == 0) { if (iImageu == imagelistSpeak[StandartIcons.ID_STATUS_ONLINE]) { writeDBBool("status_u", "speak_config", false); } else { writeDBBool("status_u", "speak_config", true); } } if (i == 1) { if (iImageu == imagelistSpeak[StandartIcons.SKINICON_EVENT_MESSAGE]) { writeDBBool("message_u", "speak_config", false); } else { writeDBBool("message_u", "speak_config", true); } } } OnChanged(EventChanged.Active); return 1; } } break; } return 0; } private void DestroySpeak(IntPtr hWnd) { WinApi.DestroyIcon(imagelistSpeak.GetIcon(StandartIcons.SKINICON_EVENT_MESSAGE)); WinApi.DestroyIcon(imagelistSpeak.GetIcon(StandartIcons.ID_STATUS_ONLINE)); { int hIml = WinApi.SendDlgItemMessage(hWnd, IDC_SPEAK_LIST, ContactListConstants.CLM_GETEXTRAIMAGELIST, 0, 0); WinApi.ImageList_Destroy(hIml); } } private void InitSpeakList(IntPtr handle) { setIcons(handle, IDC_SPEAK_LIST, imagelistSpeak); setIcons(imagelistSpeak, StandartIcons.SKINICON_EVENT_MESSAGE, IDC_SPEAK_VISIBLEICON, handle); setIcons(imagelistSpeak, StandartIcons.ID_STATUS_ONLINE, IDC_SPEAK_INVISIBLEICON, handle); ResetListOptions(WinApi.GetDlgItem(handle, IDC_SPEAK_LIST)); WinApi.SendDlgItemMessage(handle, IDC_SPEAK_LIST, ContactListConstants.CLM_SETEXTRACOLUMNS, 2, 0); hItemUnkSpeak = addStringCList(IDC_SPEAK_LIST, "** Unknown contacts **", handle); SetUnknownIcons(WinApi.GetDlgItem(handle, IDC_SPEAK_LIST), hItemUnkSpeak, imagelistSpeak); SetAllContactIcons(WinApi.GetDlgItem(handle, IDC_SPEAK_LIST), imagelistSpeak); SetListGroupIcons(WinApi.GetDlgItem(handle, IDC_SPEAK_LIST), WinApi.SendDlgItemMessage(handle, IDC_SPEAK_LIST, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_ROOT, 0), 0, imagelistSpeak, null); } private void SetUnknownIcons(IntPtr hwndList, int hItem, Win32ImageList imageList) { if (WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETEXTRAIMAGE, hItem, WinApi.MakeLParam(0, 0)) == 0xFF) { int icon = imageList[StandartIcons.SKINICON_OTHER_SMALLDOT]; if (!readDBBool("status_u", "speak_config", true)) { icon = imageList[StandartIcons.ID_STATUS_ONLINE]; } WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETEXTRAIMAGE, hItem, WinApi.MakeLParam(0, icon)); } if (WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETEXTRAIMAGE, hItem, WinApi.MakeLParam(1, 0)) == 0xFF) { int icon = imageList[StandartIcons.SKINICON_OTHER_SMALLDOT]; if (!readDBBool("message_u", "speak_config", true)) { icon = imageList[StandartIcons.SKINICON_EVENT_MESSAGE]; } WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETEXTRAIMAGE, hItem, WinApi.MakeLParam(1, icon)); } } private void SetListGroupIcons(IntPtr hwndList, int hFirstItem, int hParentItem, Win32ImageList imageList, int[] groupChildCount) { int[] childCount = { 0, 0 }; int[] iconOn = { 1, 1 }; int[] iconshow = { imageList[StandartIcons.ID_STATUS_ONLINE], imageList[StandartIcons.SKINICON_EVENT_MESSAGE] }; int typeOfFirst = WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETITEMTYPE, hFirstItem, 0); int hItem; //check groups if (typeOfFirst == ContactListConstants.CLCIT_GROUP) { hItem = hFirstItem; } else { hItem = WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_NEXTGROUP, hFirstItem); } while (hItem != 0) { int hChildItem = WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_CHILD, hItem); if (hChildItem != 0) { SetListGroupIcons(hwndList, hChildItem, hItem, imageList, childCount); } for (int i = 0; i < iconOn.Length; i++) { if (iconOn[i] != 0 && WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETEXTRAIMAGE, hItem, i) != imageList[StandartIcons.SKINICON_OTHER_SMALLDOT]) { iconOn[i] = 0; } } hItem = WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_NEXTGROUP, hItem); } //check contacts if (typeOfFirst == ContactListConstants.CLCIT_CONTACT) { hItem = hFirstItem; } else { hItem = WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_NEXTCONTACT, hFirstItem); } while (hItem != 0) { for (int i = 0; i < iconOn.Length; i++) { int iImage = WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETEXTRAIMAGE, hItem, i); if (iconOn[i] != 0 && iImage != imageList[StandartIcons.SKINICON_OTHER_SMALLDOT]) { iconOn[i] = 0; } if (iImage != 0xFF) { childCount[i]++; } } hItem = WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETNEXTITEM, ContactListConstants.CLGN_NEXTCONTACT, hItem); } //set icons for (int i = 0; i < iconOn.Length; i++) { WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETEXTRAIMAGE, hParentItem, WinApi.MakeLParam(i, childCount[i] != 0 ? (iconOn[i] == 0 ? iconshow[i] : imageList[StandartIcons.SKINICON_OTHER_SMALLDOT]) : 0xFF)); if (groupChildCount != null) { groupChildCount[i] += childCount[i]; } } } private void SetAllContactIcons(IntPtr hwndList, Win32ImageList imageList) { WinApi.SendMessage(hwndList, ContactListConstants.CLM_AUTOREBUILD, 0, 0); int hContact = MirandaContext.Current.CallService(API.MS_DB_CONTACT_FINDFIRST, IntPtr.Zero, IntPtr.Zero); do { int hItem = WinApi.SendMessage(hwndList, ContactListConstants.CLM_FINDCONTACT, hContact, 0); if (hItem == 0) { hItem = WinApi.SendMessage(hwndList, ContactListConstants.CLM_AUTOREBUILD, 0, 0); } else { if (hItem != 0) { int szProto = MirandaContext.Current.CallService(API.MS_PROTO_GETCONTACTBASEPROTO, (IntPtr)hItem, IntPtr.Zero); if (szProto != 0) { if (WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETEXTRAIMAGE, hItem, WinApi.MakeLParam(0, 0)) == 0xFF) { int icon = imageList[StandartIcons.SKINICON_OTHER_SMALLDOT]; if (!readDBBool("status", "speak_config", (IntPtr)hContact, true)) { icon = imageList[StandartIcons.ID_STATUS_ONLINE]; } WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETEXTRAIMAGE, hItem, WinApi.MakeLParam(0, icon)); } if (WinApi.SendMessage(hwndList, ContactListConstants.CLM_GETEXTRAIMAGE, hItem, WinApi.MakeLParam(1, 0)) == 0xFF) { int icon = imageList[StandartIcons.SKINICON_OTHER_SMALLDOT]; if (!readDBBool("message", "speak_config", (IntPtr)hContact, true)) { icon = imageList[StandartIcons.SKINICON_EVENT_MESSAGE]; } WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETEXTRAIMAGE, hItem, WinApi.MakeLParam(1, icon)); } } } } } while ((hContact = MirandaContext.Current.CallService(API.MS_DB_CONTACT_FINDNEXT, (IntPtr)hContact, IntPtr.Zero)) > 0); } private void ResetListOptions(IntPtr hwndList) { WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETBKBITMAP, 0, IntPtr.Zero); WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETBKCOLOR, WinApi.GetSysColor(WinApi.COLOR_WINDOW), 0); WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETGREYOUTFLAGS, 0, 0); WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETLEFTMARGIN, 2, 0); WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETINDENT, 10, 0); for (int i = 0; i <= ContactListConstants.FONTID_MAX; i++) { WinApi.SendMessage(hwndList, ContactListConstants.CLM_SETTEXTCOLOR, i, WinApi.GetSysColor(WinApi.COLOR_WINDOWTEXT)); } WinApi.SetWindowLong(hwndList, WinApi.GWL_STYLE, WinApi.GetWindowLong(hwndList, WinApi.GWL_STYLE) | ContactListConstants.CLS_SHOWHIDDEN); } private void setIcons(IntPtr handle, int IDC_LIST, Win32ImageList imageList) { WinApi.SendDlgItemMessage(handle, IDC_LIST, ContactListConstants.CLM_SETEXTRAIMAGELIST, 0, imageList.Handle); } private void setIcons(Win32ImageList imageList, string iconKey, int ID, IntPtr handle) { WinApi.SendDlgItemMessage(handle, ID, WinApi.STM_SETICON, imageList.GetIcon(iconKey), 0); } private int addStringCList(Int32 ID, string text, IntPtr handle) { int length; IntPtr str = Util.GetStringPtr(text, out length); CLCINFOITEM cii = new CLCINFOITEM(); cii.cbSize = Marshal.SizeOf(cii); cii.flags = ContactListConstants.CLCIIF_GROUPFONT; cii.pszText = Marshal.StringToHGlobalUni(text); IntPtr cmdPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cii)); Marshal.StructureToPtr(cii, cmdPtr, false); int ret = WinApi.SendDlgItemMessage(handle, ID, ContactListConstants.CLM_ADDINFOITEM, 0, cmdPtr); if (str != IntPtr.Zero) Marshal.FreeHGlobal(str); return ret; } /// /// Read a boolean value from Miranda Databse /// /// Name /// Module public static bool readDBBool(string name, string owner) { return readDBBool(name, owner, false); } /// /// Read a boolean value from Mirana Database and if it not Present use standart /// /// Name /// Module /// Default Value public static bool readDBBool(string name, string owner, bool standart) { return readDBBool(name, owner, IntPtr.Zero, standart); } /// /// Read a value from Miranda Databse from specefic user and use a default value if not present /// /// Name /// Module /// Default value /// Userhandle /// public static bool readDBBool(string name, string owner, IntPtr contact, bool standart) { object value = ContactInfo.FromHandle(contact).ReadSetting(name, owner, DatabaseSettingType.Byte); if (value != null) { if ((byte)value == 1) { return true; } else { return false; } } return standart; } /// /// Read a value from Miranda Database /// /// Name /// Module /// Return 0 if not present public static long readDBLong(string name, string owner) { object value = ContactInfo.ReadSetting(IntPtr.Zero, name, owner, DatabaseSettingType.UInt32); if (value != null) { return (UInt32)value; } return 0; } /// /// Read a value from Miranda Databse /// /// Name /// Module /// Returns an empty String if not presend public static string readDBString(string name, string owner) { object value = ContactInfo.ReadSetting(IntPtr.Zero, name, owner, DatabaseSettingType.AsciiString); if (value != null) { return (string)value; } return ""; } /// /// Write a boolean value into Miranda Databse /// /// Name /// Module /// Value public static bool writeDBBool(string name, string owner, bool value) { writeDBBool(name, owner, value, IntPtr.Zero); return readDBBool(name, owner) == value; } /// /// Write a boolean value into Miranda Database for specific user /// /// Name /// Module /// Value /// User handle public static bool writeDBBool(string name, string owner, bool value, IntPtr contact) { byte v = (value) ? (byte)1 : (byte)0; ContactInfo.FromHandle(contact).WriteSetting(name, owner, v, DatabaseSettingType.Byte); return readDBBool(name, owner, contact, false) == value; } /// /// Write a long value into Miranda Databse /// /// Name /// Module /// long value public static bool writeDBlong(string name, string owner, uint value) { ContactInfo.FromHandle(IntPtr.Zero).WriteSetting(name, owner, (UInt32)value, DatabaseSettingType.UInt32); return readDBLong(name, owner) == value; } /// /// Write a string value into Miranda Databse /// /// Name /// Module /// string value public static bool writeDBstring(string name, string owner, string value) { ContactInfo.FromHandle(IntPtr.Zero).WriteSetting(name, owner, (string)value, DatabaseSettingType.AsciiString); return readDBString(name, owner) == value; } } }