speak
30
Speak/Speak/Core/ActionClickEvent.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal class ActionClickEvent : EventArgs
|
||||||
|
{
|
||||||
|
private string action;
|
||||||
|
private bool autoSend;
|
||||||
|
|
||||||
|
public ActionClickEvent(string action, bool autoSend)
|
||||||
|
{
|
||||||
|
this.action = action;
|
||||||
|
this.autoSend = autoSend;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Action
|
||||||
|
{
|
||||||
|
get { return action; }
|
||||||
|
set { action = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AutoSend
|
||||||
|
{
|
||||||
|
get { return autoSend; }
|
||||||
|
set { autoSend = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
86
Speak/Speak/Core/ActionProcessor.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak.Fork;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal class ActionProcessor
|
||||||
|
{
|
||||||
|
private ContactManager cm;
|
||||||
|
private Buttons btns;
|
||||||
|
|
||||||
|
public ActionProcessor(ContactManager cm, Buttons btns)
|
||||||
|
{
|
||||||
|
this.cm = cm;
|
||||||
|
this.btns = btns;
|
||||||
|
|
||||||
|
btns.OnAction += ActionHandler;
|
||||||
|
cm.OnAction += ActionHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ActionHandler(object sender, ActionEvent e)
|
||||||
|
{
|
||||||
|
string[] actionInfo = e.Action.Split('/');
|
||||||
|
|
||||||
|
switch (actionInfo[0])
|
||||||
|
{
|
||||||
|
case "autofork":
|
||||||
|
Settings.Instance.AutoFork = !Settings.Instance.AutoFork;
|
||||||
|
Settings.Save();
|
||||||
|
break;
|
||||||
|
case "forkdel":
|
||||||
|
DialogResult dr = MessageBox.Show(
|
||||||
|
"Ты уверен в том, что делаешь?" + Environment.NewLine +
|
||||||
|
"Хочешь удалить из контакт листа все псевдоконтакты с комментариями?",
|
||||||
|
"[xJuick] Подтверждение очистки контакт листа",
|
||||||
|
MessageBoxButtons.YesNoCancel,
|
||||||
|
MessageBoxIcon.Exclamation);
|
||||||
|
|
||||||
|
if (dr == DialogResult.Yes)
|
||||||
|
cm.ClearContacts();
|
||||||
|
break;
|
||||||
|
case "fork":
|
||||||
|
if (actionInfo.Length == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Match m = Sites.SitesManager.GetContactSite(e.HContact).NumRegex.Match(actionInfo[1]);
|
||||||
|
if (!m.Success)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cm.ChangeForkState(e.HContact, m.Groups["post"].Value);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "avatars":
|
||||||
|
Settings.Instance.ShowAvatars = !Settings.Instance.ShowAvatars;
|
||||||
|
Settings.Save();
|
||||||
|
cm.Avatars();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ActionEvent : EventArgs
|
||||||
|
{
|
||||||
|
private string action;
|
||||||
|
private IntPtr hContact;
|
||||||
|
|
||||||
|
public ActionEvent(IntPtr hContact, string action)
|
||||||
|
{
|
||||||
|
this.hContact = hContact;
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Action
|
||||||
|
{
|
||||||
|
get { return action; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr HContact
|
||||||
|
{
|
||||||
|
get { return hContact; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
172
Speak/Speak/Core/AvatarProcessor.cs
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Xml;
|
||||||
|
using Speak.Sites;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal class AvatarProcessor
|
||||||
|
{
|
||||||
|
private object lockObject = new object();
|
||||||
|
private /*volatile*/ Queue<AvatarQueueItem> queue;
|
||||||
|
private HTTP http;
|
||||||
|
private ISite site;
|
||||||
|
|
||||||
|
private string avatarsPath;
|
||||||
|
|
||||||
|
public AvatarProcessor(ISite site)
|
||||||
|
{
|
||||||
|
this.site = site;
|
||||||
|
avatarsPath = Settings.xJuickAvatarsFolder + "\\" + site.Name + "_{0}.png";
|
||||||
|
http = new HTTP();
|
||||||
|
queue = new Queue<AvatarQueueItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToQueue(string userName, AvatarCallBack callback)
|
||||||
|
{
|
||||||
|
//string url = String.Format(ava32, userName);
|
||||||
|
//lock(lockObject)
|
||||||
|
{
|
||||||
|
foreach (AvatarQueueItem aItem in queue)
|
||||||
|
{
|
||||||
|
if (aItem.UserName.Equals(userName))
|
||||||
|
{
|
||||||
|
if (callback != null)
|
||||||
|
aItem.AddCallBack(callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.Enqueue(new AvatarQueueItem(userName, callback));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dequeue()
|
||||||
|
{
|
||||||
|
while (queue.Count != 0)
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
{
|
||||||
|
if (queue.Count != 0)
|
||||||
|
{
|
||||||
|
AvatarQueueItem item = queue.Dequeue();
|
||||||
|
if (DownloadAvatar(item.UserName))
|
||||||
|
{
|
||||||
|
item.CallSubscribers(String.Format(avatarsPath, item.UserName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Process()
|
||||||
|
{
|
||||||
|
if (queue.Count != 0)
|
||||||
|
{
|
||||||
|
Thread thread = new Thread(Dequeue);
|
||||||
|
thread.IsBackground = false;
|
||||||
|
thread.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetUserAvatar(string userName, AvatarCallBack callback)
|
||||||
|
{
|
||||||
|
string fullPath = Path.GetFullPath(String.Format(avatarsPath, userName));
|
||||||
|
if (File.Exists(fullPath))
|
||||||
|
return fullPath;
|
||||||
|
|
||||||
|
AddToQueue(userName, callback);
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DownloadAvatar(string user)
|
||||||
|
{
|
||||||
|
string avatarUrl = site.GetAvatarPath(user);
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(avatarUrl))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Stream avatar = http.GetImage(avatarUrl);
|
||||||
|
if (avatar != null)
|
||||||
|
{
|
||||||
|
if (File.Exists(String.Format(avatarsPath, user)))
|
||||||
|
return false;
|
||||||
|
Stream fs = FileStream.Synchronized(File.Open(String.Format(avatarsPath, user), FileMode.Create, FileAccess.Write, FileShare.None));
|
||||||
|
byte[] bytes = new byte[255];
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while ((count = avatar.Read(bytes, 0, 255)) > 0)
|
||||||
|
{
|
||||||
|
fs.Write(bytes, 0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
avatar.Close();
|
||||||
|
fs.Close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal delegate void AvatarCallBack(string userName, string avatarPath);
|
||||||
|
|
||||||
|
internal class AvatarQueueItem
|
||||||
|
{
|
||||||
|
private string userName;
|
||||||
|
private List<AvatarCallBack> callbacks;
|
||||||
|
|
||||||
|
public AvatarQueueItem(string avatarUrl, AvatarCallBack callback)
|
||||||
|
{
|
||||||
|
this.userName = avatarUrl;
|
||||||
|
callbacks = new List<AvatarCallBack>();
|
||||||
|
callbacks.Add(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UserName
|
||||||
|
{
|
||||||
|
get { return userName; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCallBack(AvatarCallBack callBack)
|
||||||
|
{
|
||||||
|
callbacks.Add(callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CallSubscribers(string avatarPath)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = callbacks.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (callbacks[i] != null)
|
||||||
|
callbacks[i].Invoke(userName, avatarPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, obj)) return false;
|
||||||
|
if (ReferenceEquals(this, obj)) return true;
|
||||||
|
if (obj.GetType() != typeof (AvatarQueueItem)) return false;
|
||||||
|
return Equals((AvatarQueueItem) obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(AvatarQueueItem other)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, other)) return false;
|
||||||
|
if (ReferenceEquals(this, other)) return true;
|
||||||
|
return Equals(other.userName, userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
return ((userName != null ? userName.GetHashCode() : 0)*397) ^ (callbacks != null ? callbacks.GetHashCode() : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
359
Speak/Speak/Core/Buttons.cs
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Virtuoso.Miranda.Plugins.Native;
|
||||||
|
using Speak.Structs;
|
||||||
|
using Speak.Utils;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal class Buttons
|
||||||
|
{
|
||||||
|
private bool hidden;
|
||||||
|
private bool enabled;
|
||||||
|
private List<ButtonInfo> buttons;
|
||||||
|
private List<ButtonInfo> hardcodedButtons;
|
||||||
|
|
||||||
|
private const string AUTOFORK_COMMAND = "xJuick://AutoFork";
|
||||||
|
private const string AVATARS_COMMAND = "xJuick://Avatars";
|
||||||
|
private const string FORKDEL_COMMAND = "xJuick://ForkDel";
|
||||||
|
|
||||||
|
public Buttons()
|
||||||
|
{
|
||||||
|
buttons = new List<ButtonInfo>();
|
||||||
|
hardcodedButtons = new List<ButtonInfo>();
|
||||||
|
hardcodedButtons.Add(new ButtonInfo("Отдельное окно для комментариев", AUTOFORK_COMMAND, "xJuick_Fork", true, true));
|
||||||
|
hardcodedButtons.Add(new ButtonInfo("Удалить контакты комментариев", FORKDEL_COMMAND, "xJuick_ForkDel"));
|
||||||
|
hardcodedButtons.Add(new ButtonInfo("Включить/Выключить аватары", AVATARS_COMMAND, "xJuick_Avatars"));
|
||||||
|
|
||||||
|
hidden = true;
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddButton(string name, string command)
|
||||||
|
{
|
||||||
|
AddButton(name, command, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddButton(string name, string command, string iconName)
|
||||||
|
{
|
||||||
|
buttons.Add(new ButtonInfo(name, command, iconName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddButtons(ButtonInfo[] buttons)
|
||||||
|
{
|
||||||
|
this.buttons.AddRange(buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntPtr GetIcon(ButtonInfo btn)
|
||||||
|
{
|
||||||
|
UnmanagedStringHandle str = new UnmanagedStringHandle(btn.IconName, StringEncoding.Ansi);
|
||||||
|
IntPtr hIcon = new IntPtr(MirandaContext.Current.CallService(API.MS_SKIN2_GETICON, UIntPtr.Zero, str.IntPtr));
|
||||||
|
str.Free();
|
||||||
|
if (hIcon != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
btn.HIcon = hIcon;
|
||||||
|
return btn.HIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
IconName iName = new IconName();
|
||||||
|
iName.Init();
|
||||||
|
iName.cbSize = Marshal.SizeOf(iName);
|
||||||
|
iName.szSection = Settings.IcoLibPath;
|
||||||
|
iName.szDescription = btn.Name;
|
||||||
|
iName.pszName = btn.IconName;
|
||||||
|
iName.hDefaultIcon = IconTable.GetDefaultIcon(btn.IconName);
|
||||||
|
|
||||||
|
hIcon = Marshal.AllocHGlobal(Marshal.SizeOf(iName));
|
||||||
|
Marshal.StructureToPtr(iName, hIcon, false);
|
||||||
|
btn.HIcon = new IntPtr(MirandaContext.Current.CallService(API.MS_SKIN2_ADDICON, UIntPtr.Zero, hIcon));
|
||||||
|
|
||||||
|
return btn.HIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetButtonState(IntPtr hContact, ButtonInfo btn, UInt32 state)
|
||||||
|
{
|
||||||
|
BBButton bbButton = new BBButton();
|
||||||
|
bbButton.cbSize = Marshal.SizeOf(bbButton);
|
||||||
|
bbButton.pszModuleName = Settings.ModuleName;
|
||||||
|
bbButton.szTooltip = btn.Name;
|
||||||
|
bbButton.dwButtonID = btn.ButtonID;
|
||||||
|
bbButton.iButtonWidth = 0;
|
||||||
|
bbButton.hIcon = btn.HIcon;
|
||||||
|
bbButton.bbbFlags = state;
|
||||||
|
|
||||||
|
IntPtr bbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(bbButton));
|
||||||
|
Marshal.StructureToPtr(bbButton, bbPtr, false);
|
||||||
|
MirandaContext.Current.CallService(API.MS_BB_SETBUTTONSTATE, hContact, bbPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Create()
|
||||||
|
{
|
||||||
|
Delete();
|
||||||
|
Create(290, hardcodedButtons);
|
||||||
|
Create(340, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Create(uint startIndex, List<ButtonInfo> btns)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
ButtonInfo btn = btns[i];
|
||||||
|
if (!btn.Enabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BBButton bbButton = new BBButton();
|
||||||
|
bbButton.cbSize = Marshal.SizeOf(bbButton);
|
||||||
|
bbButton.pszModuleName = Settings.ModuleName;
|
||||||
|
bbButton.szTooltip = btn.Name;
|
||||||
|
bbButton.dwDefPos = startIndex + (uint)i + 1;
|
||||||
|
bbButton.dwButtonID = btn.ButtonID = bbButton.dwDefPos;
|
||||||
|
bbButton.iButtonWidth = 0;
|
||||||
|
bbButton.bbbFlags |= TabSRMMConstants.BBBF_ISCHATBUTTON | TabSRMMConstants.BBBF_ISIMBUTTON | TabSRMMConstants.BBBF_ISLSIDEBUTTON;
|
||||||
|
if (btn.IsPush)
|
||||||
|
bbButton.bbbFlags |= TabSRMMConstants.BBBF_ISPUSHBUTTON;
|
||||||
|
|
||||||
|
if (hidden)
|
||||||
|
bbButton.bbbFlags |= TabSRMMConstants.BBBF_HIDDEN;
|
||||||
|
|
||||||
|
bbButton.hIcon = btn.HIcon == IntPtr.Zero ? GetIcon(btn) : btn.HIcon;
|
||||||
|
|
||||||
|
IntPtr bbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(bbButton));
|
||||||
|
Marshal.StructureToPtr(bbButton, bbPtr, false);
|
||||||
|
MirandaContext.Current.CallService(API.MS_BB_ADDBUTTON, IntPtr.Zero, bbPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Click(UInt32 buttonID, IntPtr hContact)
|
||||||
|
{
|
||||||
|
if (!Click(buttonID, hContact, buttons))
|
||||||
|
Click(buttonID, hContact, hardcodedButtons);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool Click(UInt32 buttonID, IntPtr hContact, List<ButtonInfo> btns)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
ButtonInfo btn = btns[i];
|
||||||
|
if (btn.ButtonID == buttonID)
|
||||||
|
{
|
||||||
|
// Нет, я не идиот (кажется).
|
||||||
|
// Просто MirandaContext.Current.HookEvent вызывается дважды
|
||||||
|
btn.Pressed = !btn.Pressed;
|
||||||
|
if (btn.Pressed)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (btn.Command.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
Util.OpenURL(btn.Command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btn.Command.StartsWith("xJuick://", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
InvokeOnAction(hContact, btn.Command.Substring(9).ToLower());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSSData css = new CSSData();
|
||||||
|
css.hContact = hContact;
|
||||||
|
css.szProtoService = API.PSS_MESSAGE;
|
||||||
|
css.wParam = IntPtr.Zero;
|
||||||
|
css.lParam = new UnmanagedStringHandle(btn.Command, StringEncoding.Ansi).IntPtr;
|
||||||
|
|
||||||
|
IntPtr cmdPtr = Marshal.AllocHGlobal(Marshal.SizeOf(css));
|
||||||
|
Marshal.StructureToPtr(css, cmdPtr, false);
|
||||||
|
MirandaContext.Current.CallService(API.MS_PROTO_CALLCONTACTSERVICE, IntPtr.Zero, cmdPtr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Delete()
|
||||||
|
{
|
||||||
|
Delete(buttons);
|
||||||
|
Delete(hardcodedButtons);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Delete(List<ButtonInfo> btns)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (btns[i].ButtonID == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BBButton bbButton = new BBButton();
|
||||||
|
bbButton.cbSize = Marshal.SizeOf(bbButton);
|
||||||
|
bbButton.pszModuleName = Settings.ModuleName;
|
||||||
|
bbButton.dwButtonID = btns[i].ButtonID;
|
||||||
|
bbButton.iButtonWidth = 0;
|
||||||
|
bbButton.szTooltip = "";
|
||||||
|
|
||||||
|
IntPtr bbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(bbButton));
|
||||||
|
Marshal.StructureToPtr(bbButton, bbPtr, false);
|
||||||
|
MirandaContext.Current.CallService(API.MS_BB_REMOVEBUTTON, IntPtr.Zero, bbPtr);
|
||||||
|
|
||||||
|
btns[i].ButtonID = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hide(IntPtr hContact)
|
||||||
|
{
|
||||||
|
hidden = true;
|
||||||
|
Hide(hContact, buttons);
|
||||||
|
Hide(hContact, hardcodedButtons);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Hide(IntPtr hContact, List<ButtonInfo> btns)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
SetButtonState(hContact, btns[i], TabSRMMConstants.BBSF_HIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Show(IntPtr hContact)
|
||||||
|
{
|
||||||
|
hidden = false;
|
||||||
|
Show(hContact, buttons);
|
||||||
|
Show(hContact, hardcodedButtons);
|
||||||
|
|
||||||
|
for (int i = 0, iCount = hardcodedButtons.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (hardcodedButtons[i].Command.Equals(AUTOFORK_COMMAND))
|
||||||
|
{
|
||||||
|
SetButtonState(hContact, hardcodedButtons[i], Settings.Instance.AutoFork ? TabSRMMConstants.BBSF_PUSHED : TabSRMMConstants.BBSF_RELEASED);
|
||||||
|
}
|
||||||
|
// doesnt work in IE and HPP
|
||||||
|
else if (hardcodedButtons[i].Command.Equals(AVATARS_COMMAND))
|
||||||
|
{
|
||||||
|
SetButtonState(hContact, hardcodedButtons[i], Settings.CurrentLog != LogHandler.Default ? TabSRMMConstants.BBSF_HIDDEN : TabSRMMConstants.BBSF_RELEASED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Show(IntPtr hContact, List<ButtonInfo> btns)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
SetButtonState(hContact, btns[i], TabSRMMConstants.BBSF_RELEASED);
|
||||||
|
btns[i].Pressed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Hidden
|
||||||
|
{
|
||||||
|
get { return hidden; }
|
||||||
|
set { hidden = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Enabled
|
||||||
|
{
|
||||||
|
get { return enabled; }
|
||||||
|
set { enabled = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<ActionEvent> OnAction;
|
||||||
|
public void InvokeOnAction(IntPtr hContact, string action)
|
||||||
|
{
|
||||||
|
if (OnAction == null)
|
||||||
|
return;
|
||||||
|
OnAction(this, new ActionEvent(hContact, action));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class ButtonInfo
|
||||||
|
{
|
||||||
|
private uint buttonID;
|
||||||
|
private string name;
|
||||||
|
private string command;
|
||||||
|
private string iconName;
|
||||||
|
private bool pressed;
|
||||||
|
private bool isPush;
|
||||||
|
private bool enabled;
|
||||||
|
|
||||||
|
public ButtonInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonInfo(string name, string command, string iconName) : this(name, command, iconName, false, true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonInfo(string name, string command, string iconName, bool isPush, bool enabled) : this()
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.command = command;
|
||||||
|
this.iconName = iconName;
|
||||||
|
this.isPush = isPush;
|
||||||
|
buttonID = 0;
|
||||||
|
pressed = true;
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute(AttributeName = "enabled")]
|
||||||
|
public bool Enabled
|
||||||
|
{
|
||||||
|
get { return enabled; }
|
||||||
|
set { enabled = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public bool Pressed
|
||||||
|
{
|
||||||
|
get { return pressed; }
|
||||||
|
set { pressed = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public bool IsPush
|
||||||
|
{
|
||||||
|
get { return isPush; }
|
||||||
|
set { isPush = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore] [NonSerialized] public IntPtr HIcon;
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public uint ButtonID
|
||||||
|
{
|
||||||
|
get { return buttonID; }
|
||||||
|
set { buttonID = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute(AttributeName = "name")]
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
set { name = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute(AttributeName = "command")]
|
||||||
|
public string Command
|
||||||
|
{
|
||||||
|
get { return command; }
|
||||||
|
set { command = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute(AttributeName = "iconname")]
|
||||||
|
public string IconName
|
||||||
|
{
|
||||||
|
get { return iconName; }
|
||||||
|
set { iconName = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonInfo Clone()
|
||||||
|
{
|
||||||
|
return new ButtonInfo(name, command, iconName, isPush, enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
206
Speak/Speak/Core/HTTP.cs
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak.Properties;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal class HTTP
|
||||||
|
{
|
||||||
|
private readonly Encoding cp1251;
|
||||||
|
private readonly Encoding utf;
|
||||||
|
private static readonly Encoding staticUtf = Encoding.UTF8;
|
||||||
|
private static string UserAgent = "xJuick v0.0.6a http://xa0c.net";
|
||||||
|
|
||||||
|
public HTTP()
|
||||||
|
{
|
||||||
|
cp1251 = Encoding.GetEncoding(1251);
|
||||||
|
utf = Encoding.UTF8;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<ContentEventArgs> OnContentReady;
|
||||||
|
private void InvokeOnContentReady(ContentEventArgs e)
|
||||||
|
{
|
||||||
|
EventHandler<ContentEventArgs> onContentReadyHandler = OnContentReady;
|
||||||
|
if (onContentReadyHandler != null) onContentReadyHandler(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendGetAsync(string url)
|
||||||
|
{
|
||||||
|
Thread thread = new Thread(SendGet);
|
||||||
|
thread.IsBackground = true;
|
||||||
|
thread.Start(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendGet(object urlObj)
|
||||||
|
{
|
||||||
|
SendGet(urlObj.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SendGet(string url)
|
||||||
|
{
|
||||||
|
return SendGet(url, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string SendGet(string url, bool async)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||||
|
request.UserAgent = UserAgent;
|
||||||
|
request.Timeout = 4000;
|
||||||
|
|
||||||
|
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
||||||
|
|
||||||
|
string result = ReadResponse(response);
|
||||||
|
if (async)
|
||||||
|
InvokeOnContentReady(new ContentEventArgs(result));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
InvokeOnContentReady(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string StaticSendGet(string url)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||||
|
request.UserAgent = UserAgent;
|
||||||
|
request.Timeout = 4000;
|
||||||
|
|
||||||
|
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
||||||
|
|
||||||
|
return StaticReadResponse(response);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// nah
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream GetImage(string url)
|
||||||
|
{
|
||||||
|
return GetImage(url, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream GetImage(string url, bool returnBlankAvatar)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WebRequest wreq = WebRequest.Create(url);
|
||||||
|
HttpWebResponse httpResponse = (HttpWebResponse)wreq.GetResponse();
|
||||||
|
if (httpResponse.ContentType != "text/html")
|
||||||
|
{
|
||||||
|
return httpResponse.GetResponseStream();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Match m = Regexps.Image.Match(ReadResponse(httpResponse));
|
||||||
|
if (!m.Success)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string imgUrl = m.Groups["image"].Value;
|
||||||
|
if (!imgUrl.StartsWith("http://"))
|
||||||
|
{
|
||||||
|
if (imgUrl.StartsWith("//"))
|
||||||
|
imgUrl = "http:" + imgUrl;
|
||||||
|
else
|
||||||
|
imgUrl = "http://" + imgUrl;
|
||||||
|
}
|
||||||
|
return GetImage(imgUrl, returnBlankAvatar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
MemoryStream stream = new MemoryStream();
|
||||||
|
if (returnBlankAvatar)
|
||||||
|
{
|
||||||
|
//Resources.avatar_notfound.Save(stream, ImageFormat.Png);
|
||||||
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ReadResponse(HttpWebResponse response)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
Stream stream = response.GetResponseStream();
|
||||||
|
//StreamReader reader = new StreamReader(stream, response.CharacterSet.ToLower().IndexOf("utf") == -1 ? cp1251 : utf);
|
||||||
|
StreamReader reader = new StreamReader(stream, utf);
|
||||||
|
char[] chars = new Char[256];
|
||||||
|
int count = reader.Read(chars, 0, 256);
|
||||||
|
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
string str = new String(chars, 0, count);
|
||||||
|
result = result + str;
|
||||||
|
count = reader.Read(chars, 0, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Close();
|
||||||
|
stream.Close();
|
||||||
|
reader.Close();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string StaticReadResponse(HttpWebResponse response)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
Stream stream = response.GetResponseStream();
|
||||||
|
//StreamReader reader = new StreamReader(stream, response.CharacterSet.ToLower().IndexOf("utf") == -1 ? cp1251 : utf);
|
||||||
|
StreamReader reader = new StreamReader(stream, staticUtf);
|
||||||
|
char[] chars = new Char[256];
|
||||||
|
int count = reader.Read(chars, 0, 256);
|
||||||
|
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
string str = new String(chars, 0, count);
|
||||||
|
result = result + str;
|
||||||
|
count = reader.Read(chars, 0, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Close();
|
||||||
|
stream.Close();
|
||||||
|
reader.Close();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ContentEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
private string content;
|
||||||
|
|
||||||
|
public ContentEventArgs(string content)
|
||||||
|
{
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Content
|
||||||
|
{
|
||||||
|
get { return content; }
|
||||||
|
set { content = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
Speak/Speak/Core/IMessageProcessor.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal interface IMessageProcessor : IDisposable
|
||||||
|
{
|
||||||
|
void Update();
|
||||||
|
void ShowThreads();
|
||||||
|
void Avatars();
|
||||||
|
void SettingsChanged();
|
||||||
|
event EventHandler<ActionClickEvent> JuickClicked;
|
||||||
|
}
|
||||||
|
}
|
96
Speak/Speak/Core/ImagePreview.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak.UI;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal static class ImagePreview
|
||||||
|
{
|
||||||
|
private static PreviewForm pForm = new PreviewForm();
|
||||||
|
private static string[] imageTypes;
|
||||||
|
|
||||||
|
static ImagePreview()
|
||||||
|
{
|
||||||
|
imageTypes = new string[] { ".jpg", ".png", ".gif" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsImage(string url)
|
||||||
|
{
|
||||||
|
string ext = Path.GetExtension(url);
|
||||||
|
for (int i = 0, iCount = imageTypes.Length; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (imageTypes[i].Equals(ext, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Show(Int32 x, Int32 y, string url)
|
||||||
|
{
|
||||||
|
pForm.Left = x;
|
||||||
|
pForm.Top = y;
|
||||||
|
if (!pForm.Visible)
|
||||||
|
{
|
||||||
|
pForm.Show();
|
||||||
|
}
|
||||||
|
string pUrl = Settings.Instance.PreviewEngine.Url;
|
||||||
|
|
||||||
|
pForm.Url = !pUrl.Equals("{0}") ? String.Format(pUrl, System.Web.HttpUtility.UrlEncode(url)) : url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Hide()
|
||||||
|
{
|
||||||
|
if (pForm.Visible)
|
||||||
|
{
|
||||||
|
pForm.Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class PreviewEngine
|
||||||
|
{
|
||||||
|
private string name;
|
||||||
|
private string url;
|
||||||
|
private bool enabled;
|
||||||
|
|
||||||
|
public PreviewEngine()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreviewEngine(string name, string url, bool enabled)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.url = url;
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
set { name = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Url
|
||||||
|
{
|
||||||
|
get { return url; }
|
||||||
|
set { url = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Enabled
|
||||||
|
{
|
||||||
|
get { return enabled; }
|
||||||
|
set { enabled = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreviewEngine Clone()
|
||||||
|
{
|
||||||
|
return new PreviewEngine(name, url, enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
134
Speak/Speak/Core/LinkButton.cs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class LinkButton
|
||||||
|
{
|
||||||
|
private string action;
|
||||||
|
private string displayName;
|
||||||
|
private string iconName;
|
||||||
|
private bool autoSend;
|
||||||
|
private bool enabled;
|
||||||
|
private LinkDisplayType displayType;
|
||||||
|
|
||||||
|
public LinkButton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkButton(string action, string displayName, bool autoSend, LinkDisplayType displayType) : this (action, displayName, String.Empty, autoSend, displayType, true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkButton(string action, string displayName, string iconName, bool autoSend, LinkDisplayType displayType, bool enabled) : this()
|
||||||
|
{
|
||||||
|
this.action = action;
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.autoSend = autoSend;
|
||||||
|
this.displayType = displayType;
|
||||||
|
this.iconName = iconName;
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute(AttributeName = "enabled")]
|
||||||
|
public bool Enabled
|
||||||
|
{
|
||||||
|
get { return enabled; }
|
||||||
|
set { enabled = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute("action")]
|
||||||
|
public string Action
|
||||||
|
{
|
||||||
|
get { return action; }
|
||||||
|
set { action = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute("displayname")]
|
||||||
|
public string DisplayName
|
||||||
|
{
|
||||||
|
get { return displayName; }
|
||||||
|
set { displayName = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute("autosend")]
|
||||||
|
public bool AutoSend
|
||||||
|
{
|
||||||
|
get { return autoSend; }
|
||||||
|
set { autoSend = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute("displayon")]
|
||||||
|
public LinkDisplayType DisplayType
|
||||||
|
{
|
||||||
|
get { return displayType; }
|
||||||
|
set { displayType = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute("iconname")]
|
||||||
|
public string IconName
|
||||||
|
{
|
||||||
|
get { return iconName; }
|
||||||
|
set { iconName = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkButton Clone()
|
||||||
|
{
|
||||||
|
return new LinkButton(action, displayName, iconName, autoSend, displayType, enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class SimpleWordAction
|
||||||
|
{
|
||||||
|
private string action;
|
||||||
|
private bool autosend;
|
||||||
|
|
||||||
|
public SimpleWordAction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleWordAction(string action, bool autosend)
|
||||||
|
{
|
||||||
|
this.action = action;
|
||||||
|
this.autosend = autosend;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute("action")]
|
||||||
|
public string Action
|
||||||
|
{
|
||||||
|
get { return action; }
|
||||||
|
set { action = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlAttribute("autosend")]
|
||||||
|
public bool Autosend
|
||||||
|
{
|
||||||
|
get { return autosend; }
|
||||||
|
set { autosend = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LinkDisplayType
|
||||||
|
{
|
||||||
|
Nicks,
|
||||||
|
Posts,
|
||||||
|
Comments,
|
||||||
|
Always,
|
||||||
|
Image
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ActionWordType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
URL,
|
||||||
|
Comments,
|
||||||
|
Post,
|
||||||
|
Nick,
|
||||||
|
Tag
|
||||||
|
}
|
||||||
|
}
|
164
Speak/Speak/Core/LogWindow.cs
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Speak.Fork;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.Structs;
|
||||||
|
using Speak.Utils;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal static class LogWindow
|
||||||
|
{
|
||||||
|
private static ISettingOwner ownerTabSRMM;
|
||||||
|
private static ISettingOwner ownerScriver;
|
||||||
|
private static ISettingOwner ownerHistoryPP;
|
||||||
|
private static bool isIEInstalled;
|
||||||
|
private static bool isHPPInstalled;
|
||||||
|
public static bool hppImitated;
|
||||||
|
public static string CurrentLogEngine;
|
||||||
|
|
||||||
|
public static Color SRMMBackColor;
|
||||||
|
|
||||||
|
public const string TabSRMMEngine = "tabSRMM";
|
||||||
|
public const string ScriverEngine = "Scriver";
|
||||||
|
public const string ScriverEnginePlus = "Scriver+";
|
||||||
|
public const string SRMMEngine = "SRMM";
|
||||||
|
public const string SRMMEnginePlus = "SRMM+";
|
||||||
|
|
||||||
|
|
||||||
|
static LogWindow()
|
||||||
|
{
|
||||||
|
ownerTabSRMM = new ContactManager.SettingOwner("Tab_SRMsg");
|
||||||
|
ownerScriver = new ContactManager.SettingOwner("SRMM");
|
||||||
|
ownerHistoryPP = new ContactManager.SettingOwner("HistoryPlusPlus");
|
||||||
|
|
||||||
|
isIEInstalled = ServiceManager.ServiceExists(API.MS_IEVIEW_WINDOW);
|
||||||
|
isHPPInstalled = ServiceManager.ServiceExists(API.MS_HPP_EG_WINDOW);
|
||||||
|
|
||||||
|
SRMMBackColor = Color.Empty;
|
||||||
|
CurrentLogEngine = Util.CurrentMessageEngine(); // tabSRMM, Scriver, SRMM
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static IntPtr FindRealLogWindow(IntPtr mainHandle, LogHandler currentLog)
|
||||||
|
//{
|
||||||
|
// return FindRealLogWindow(mainHandle, currentLog, IntPtr.Zero);
|
||||||
|
//}
|
||||||
|
|
||||||
|
public static IntPtr FindRealLogWindow(IntPtr mainHandle, LogHandler currentLog, IntPtr hContact, out LogHandler contactLog)
|
||||||
|
{
|
||||||
|
string className = String.Empty;
|
||||||
|
|
||||||
|
if (hContact != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
LogHandler forcedLog = GetForcedContactLogSettings(hContact);
|
||||||
|
if (forcedLog != LogHandler.Default)
|
||||||
|
{
|
||||||
|
switch (forcedLog)
|
||||||
|
{
|
||||||
|
case LogHandler.ForcedHPP:
|
||||||
|
if (isHPPInstalled)
|
||||||
|
currentLog = LogHandler.HistoryPP;
|
||||||
|
else
|
||||||
|
currentLog = LogHandler.Default;
|
||||||
|
break;
|
||||||
|
case LogHandler.ForcedIEView:
|
||||||
|
if (isIEInstalled)
|
||||||
|
{
|
||||||
|
if (!hppImitated)
|
||||||
|
currentLog = LogHandler.IEView;
|
||||||
|
else
|
||||||
|
currentLog = LogHandler.ImitatedHPP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentLog = LogHandler.Default;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LogHandler.ForcedDefault:
|
||||||
|
currentLog = LogHandler.Default;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (currentLog)
|
||||||
|
{
|
||||||
|
case LogHandler.ImitatedHPP:
|
||||||
|
case LogHandler.HistoryPP:
|
||||||
|
className = "TExtHistoryGrid";
|
||||||
|
break;
|
||||||
|
case LogHandler.IEView:
|
||||||
|
className = "Internet Explorer_Server";
|
||||||
|
break;
|
||||||
|
case LogHandler.Default:
|
||||||
|
SRMMBackColor = ColorTranslator.FromWin32(Convert.ToInt32(ContactInfo.ReadSetting(IntPtr.Zero, "BkgColour", ownerScriver, DatabaseSettingType.UInt32)));
|
||||||
|
className = CurrentLogEngine.Equals("tabSRMM") || CurrentLogEngine.Equals("SRMM") ? "RichEdit20A" : "RichEdit20W";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException("currentLog");
|
||||||
|
}
|
||||||
|
contactLog = currentLog;
|
||||||
|
IntPtr logPtr = !CurrentLogEngine.Equals(ScriverEnginePlus) && !CurrentLogEngine.Equals(SRMMEnginePlus) ? WinApi.GetLogWindow(mainHandle, className) : WinApi.GetLogWindowByStyles(mainHandle, className);
|
||||||
|
return logPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogHandler GetForcedContactLogSettings(IntPtr hContact)
|
||||||
|
{
|
||||||
|
LogHandler result = LogHandler.Default;
|
||||||
|
if (CurrentLogEngine.Equals("tabSRMM"))
|
||||||
|
{
|
||||||
|
byte hppForced = Convert.ToByte(ContactInfo.ReadSetting(hContact, "hpplog", ownerTabSRMM, DatabaseSettingType.Byte));
|
||||||
|
byte ieviewForced = Convert.ToByte(ContactInfo.ReadSetting(hContact, "ieview", ownerTabSRMM, DatabaseSettingType.Byte));
|
||||||
|
|
||||||
|
return (hppForced == 1 ? LogHandler.ForcedHPP : (ieviewForced == 1 ? LogHandler.ForcedIEView : ((ieviewForced == 255 && hppForced == 255) ? LogHandler.ForcedDefault : LogHandler.Default)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogHandler GetViewMode()
|
||||||
|
{
|
||||||
|
bool useIE = false;
|
||||||
|
bool useHPP = false;
|
||||||
|
hppImitated = Convert.ToBoolean(ContactInfo.ReadSetting(IntPtr.Zero, "IEViewAPI", ownerHistoryPP, DatabaseSettingType.Byte));
|
||||||
|
|
||||||
|
switch (CurrentLogEngine)
|
||||||
|
{
|
||||||
|
case TabSRMMEngine:
|
||||||
|
useHPP = Convert.ToBoolean(ContactInfo.ReadSetting(IntPtr.Zero, "default_hpp", ownerTabSRMM, DatabaseSettingType.Byte));
|
||||||
|
useIE = Convert.ToBoolean(ContactInfo.ReadSetting(IntPtr.Zero, "default_ieview", ownerTabSRMM, DatabaseSettingType.Byte));
|
||||||
|
break;
|
||||||
|
case ScriverEngine:
|
||||||
|
useIE = Convert.ToBoolean(ContactInfo.ReadSetting(IntPtr.Zero, "UseIEView", ownerScriver, DatabaseSettingType.Byte));
|
||||||
|
break;
|
||||||
|
case SRMMEngine:
|
||||||
|
return LogHandler.Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (isIEInstalled && useIE && !hppImitated)
|
||||||
|
? LogHandler.IEView
|
||||||
|
//: ((isHPPInstalled && (useHPP || (useIE && hppImitated))) ? LogHandler.HistoryPP : LogHandler.Default);
|
||||||
|
: ((isHPPInstalled && useHPP && !useIE)
|
||||||
|
? LogHandler.HistoryPP
|
||||||
|
: ((isHPPInstalled && useIE && hppImitated) ? LogHandler.ImitatedHPP : LogHandler.Default));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LogHandler
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
IEView,
|
||||||
|
HistoryPP,
|
||||||
|
ImitatedHPP,
|
||||||
|
|
||||||
|
ForcedHPP,
|
||||||
|
ForcedIEView,
|
||||||
|
ForcedDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
194
Speak/Speak/Core/MirandaDB.cs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Virtuoso.Miranda.Plugins.Helpers;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Virtuoso.Miranda.Plugins.Native;
|
||||||
|
using Speak.Structs;
|
||||||
|
using Speak.Utils;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal static class MirandaDB
|
||||||
|
{
|
||||||
|
private static Type dbeType = typeof(DBEVENTINFO);
|
||||||
|
private static int dbeTypeSize = Marshal.SizeOf(dbeType);
|
||||||
|
|
||||||
|
public static DatabaseEventInfoEx GetEvent(IntPtr eventHandler)
|
||||||
|
{
|
||||||
|
if (eventHandler == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
IntPtr hStruct = IntPtr.Zero;
|
||||||
|
DatabaseEventInfoEx result = null;
|
||||||
|
InteropBuffer buffer = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int blobSize = MirandaContext.Current.CallService(API.MS_DB_EVENT_GETBLOBSIZE, eventHandler, IntPtr.Zero);
|
||||||
|
if (blobSize == -1)
|
||||||
|
{
|
||||||
|
throw new ArgumentException();
|
||||||
|
}
|
||||||
|
buffer = InteropBufferPool.AcquireBuffer(blobSize);
|
||||||
|
buffer.Lock();
|
||||||
|
|
||||||
|
DBEVENTINFO dbev = new DBEVENTINFO(blobSize, buffer.IntPtr);
|
||||||
|
hStruct = Marshal.AllocHGlobal(dbeTypeSize);
|
||||||
|
Marshal.StructureToPtr(dbev, hStruct, false);
|
||||||
|
|
||||||
|
MirandaContext.Current.CallService(API.MS_DB_EVENT_GET, eventHandler, hStruct);
|
||||||
|
dbev = (DBEVENTINFO)Marshal.PtrToStructure(hStruct, dbeType);
|
||||||
|
result = new DatabaseEventInfoEx(dbev);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (buffer != null)
|
||||||
|
buffer.Unlock();
|
||||||
|
if (hStruct != IntPtr.Zero)
|
||||||
|
Marshal.FreeHGlobal(hStruct);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DirectCopyHistory(IntPtr fromContact, IntPtr toContact, Regex condition)
|
||||||
|
{
|
||||||
|
if (fromContact == IntPtr.Zero || toContact == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IntPtr hStruct = IntPtr.Zero;
|
||||||
|
InteropBuffer buffer = null;
|
||||||
|
IEnumerable<IntPtr> source = MirandaContext.Current.MirandaDatabase.GetEventHandles(fromContact);
|
||||||
|
List<IntPtr> deleteList = new List<IntPtr>();
|
||||||
|
foreach (IntPtr hist in source)
|
||||||
|
{
|
||||||
|
int blobSize = MirandaContext.Current.CallService(API.MS_DB_EVENT_GETBLOBSIZE, hist, IntPtr.Zero);
|
||||||
|
if (blobSize == -1)
|
||||||
|
{
|
||||||
|
throw new ArgumentException();
|
||||||
|
}
|
||||||
|
buffer = InteropBufferPool.AcquireBuffer(blobSize);
|
||||||
|
buffer.Lock();
|
||||||
|
|
||||||
|
DBEVENTINFO dbev = new DBEVENTINFO(blobSize, buffer.IntPtr);
|
||||||
|
hStruct = Marshal.AllocHGlobal(dbeTypeSize);
|
||||||
|
Marshal.StructureToPtr(dbev, hStruct, false);
|
||||||
|
|
||||||
|
MirandaContext.Current.CallService(API.MS_DB_EVENT_GET, hist, hStruct);
|
||||||
|
dbev = (DBEVENTINFO)Marshal.PtrToStructure(hStruct, dbeType);
|
||||||
|
|
||||||
|
if (condition != null)
|
||||||
|
{
|
||||||
|
if (dbev.EventType != (ushort)DatabaseEventType.Message)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DatabaseEventInfoEx dbevEx = new DatabaseEventInfoEx(dbev);
|
||||||
|
if (!condition.Match(dbevEx.Data).Success)
|
||||||
|
{
|
||||||
|
buffer.Unlock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dbev.Flags = dbev.Flags & ~(uint)DatabaseEventProperties.First;
|
||||||
|
hStruct = Marshal.AllocHGlobal(dbeTypeSize);
|
||||||
|
Marshal.StructureToPtr(dbev, hStruct, false);
|
||||||
|
MirandaContext.Current.CallService(API.MS_DB_EVENT_ADD, toContact, hStruct);
|
||||||
|
deleteList.Add(hist);
|
||||||
|
buffer.Unlock();
|
||||||
|
Marshal.FreeHGlobal(hStruct);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = deleteList.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
DeleteEvent(fromContact, deleteList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteEvent(IntPtr hContact, IntPtr histHandle)
|
||||||
|
{
|
||||||
|
MirandaContext.Current.CallService(API.MS_DB_EVENT_DELETE, hContact, histHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddEvent(IntPtr toContact, string data, ISettingOwner owner, DatabaseEventType type, DatabaseEventProperties flags, DateTime timestamp)
|
||||||
|
{
|
||||||
|
IntPtr hStruct = IntPtr.Zero;
|
||||||
|
IntPtr pBlob = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int blobSize;
|
||||||
|
pBlob = Util.GetStringPtr(data, out blobSize);
|
||||||
|
|
||||||
|
DBEVENTINFO dbev = new DBEVENTINFO(blobSize, pBlob);
|
||||||
|
dbev.EventType = (ushort)DatabaseEventType.Message;
|
||||||
|
dbev.Flags = (uint)flags | MainConstants.DBEF_UTF;
|
||||||
|
dbev.Module = Translate.ToHandle(owner.Name, StringEncoding.Ansi).IntPtr;
|
||||||
|
dbev.Timestamp = Utilities.GetTimestamp(timestamp);
|
||||||
|
|
||||||
|
hStruct = Marshal.AllocHGlobal(dbeTypeSize);
|
||||||
|
Marshal.StructureToPtr(dbev, hStruct, false);
|
||||||
|
MirandaContext.Current.CallService(API.MS_DB_EVENT_ADD, toContact, hStruct);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (hStruct != IntPtr.Zero)
|
||||||
|
Marshal.FreeHGlobal(hStruct);
|
||||||
|
if (pBlob != IntPtr.Zero)
|
||||||
|
Marshal.FreeHGlobal(pBlob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DatabaseEventInfoEx
|
||||||
|
{
|
||||||
|
private string data;
|
||||||
|
private DatabaseEventType eventType;
|
||||||
|
private DatabaseEventProperties flags;
|
||||||
|
private DateTime timeStamp;
|
||||||
|
private Protocol ownerModule;
|
||||||
|
|
||||||
|
public DatabaseEventInfoEx(DBEVENTINFO unmanagedDBEvent)
|
||||||
|
{
|
||||||
|
|
||||||
|
ownerModule = Protocol.UnknownProtocol;
|
||||||
|
if (unmanagedDBEvent.Module != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
if(!MirandaContext.Current.Protocols.TryGetValue(Translate.ToString(unmanagedDBEvent.Module, StringEncoding.Ansi), out ownerModule))
|
||||||
|
ownerModule = Protocol.UnknownProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = (DatabaseEventProperties)unmanagedDBEvent.Flags;
|
||||||
|
eventType = (DatabaseEventType)((short)unmanagedDBEvent.EventType);
|
||||||
|
data = Util.GetNormalRussian(unmanagedDBEvent.BlobPtr, unmanagedDBEvent.BlobSize);
|
||||||
|
timeStamp = Util.GetDateTime(unmanagedDBEvent.Timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Data
|
||||||
|
{
|
||||||
|
get { return data; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseEventType EventType
|
||||||
|
{
|
||||||
|
get { return eventType; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseEventProperties Flags
|
||||||
|
{
|
||||||
|
get { return flags; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime TimeStamp
|
||||||
|
{
|
||||||
|
get { return timeStamp; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Protocol OwnerModule
|
||||||
|
{
|
||||||
|
get { return ownerModule; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
107
Speak/Speak/Core/Regexps.cs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
internal static class Regexps
|
||||||
|
{
|
||||||
|
public static Regex _NumRegEx = new Regex(
|
||||||
|
"(?<full>(?<post>\\#\\d+)(?<cmnt>/\\d+)?)",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Regex UID = new Regex(
|
||||||
|
"/(?<uid>\\d+)\\.png",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Regex GetHistoryRegEx(string postNumber)
|
||||||
|
{
|
||||||
|
return new Regex(
|
||||||
|
String.Format("\\B(?<post>{0})", postNumber.Replace("#", "\\#")),
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Regex TopNameRegEx = new Regex(
|
||||||
|
"\\B@(?<name>\\w+[-_\\.\\w]*\\w+)\\:",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Regex _NameRegEx = new Regex(
|
||||||
|
"(?<name>\\B@\\w+[-_\\.\\w]*\\w+)(?<isFirst>\\:{1})?",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Regex JidRegEx = new Regex(
|
||||||
|
"(?<name>\\B@[\\w-_\\.]+\\@[\\w-_\\.]+)",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Regex Russian = new Regex(
|
||||||
|
"[А-Я]+",
|
||||||
|
RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Regex Image = new Regex(
|
||||||
|
"<img.+?src=\"(?<image>[^\"]*)\"",
|
||||||
|
RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Regex PureReplyRegEx = new Regex(
|
||||||
|
"\\B(?<full>\\#(?<post>\\d+)(?:/(?<cmnt>\\d+))?)",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Regex ReplyRegEx = new Regex(
|
||||||
|
"(?<full>\\#(?<post>\\d+)(?:/(?<cmnt>\\d+)){1})\\ http://juick." +
|
||||||
|
"com/(?(post)\\k<post>)(?(cmnt)\\#\\k<cmnt>)", // do I need to add '$' to the end?
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
351
Speak/Speak/Core/Settings.cs
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Speak.Fork;
|
||||||
|
using Speak.Sites;
|
||||||
|
|
||||||
|
namespace Speak.Core
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class Settings
|
||||||
|
{
|
||||||
|
private static string filepath = "";
|
||||||
|
public static string xJuickDataFolder = "";
|
||||||
|
public static string xJuickAvatarsFolder = "";
|
||||||
|
private static Settings instance;
|
||||||
|
|
||||||
|
private bool autoFork;
|
||||||
|
private bool fastIEView;
|
||||||
|
private bool showAvatars;
|
||||||
|
private bool showContextAvatars;
|
||||||
|
private string jabberProtocolName;
|
||||||
|
|
||||||
|
public static bool SomeEventsDoubled = LogWindow.CurrentLogEngine.Equals("tabSRMM");
|
||||||
|
public static readonly string ModuleName = "xJuick";
|
||||||
|
public static readonly string IcoLibPath = "TabSRMM/Toolbar/" + ModuleName;
|
||||||
|
public static readonly string DefaultProtocolName = "yours@jabber.protocol.name";
|
||||||
|
private static ContactManager.SettingOwner owner = new ContactManager.SettingOwner(ModuleName);
|
||||||
|
public static LogHandler CurrentLog = LogHandler.Default;
|
||||||
|
private SimpleWordAction srmmNickAction;
|
||||||
|
private SimpleWordAction srmmNumberAction;
|
||||||
|
private PreviewEngine currenPreview;
|
||||||
|
|
||||||
|
private ISite[] sites;
|
||||||
|
private ButtonInfo[] buttons;
|
||||||
|
private LinkButton[] srmmLinkButtons;
|
||||||
|
private PreviewEngine[] previewEngines;
|
||||||
|
private string[] activeContacts;
|
||||||
|
|
||||||
|
static Settings()
|
||||||
|
{
|
||||||
|
InitDirectories(Path.GetDirectoryName(Application.ExecutablePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitDirectories(string basePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
xJuickDataFolder = Path.Combine(Path.Combine(basePath, "plugins"), "xJuick");
|
||||||
|
xJuickAvatarsFolder = Path.Combine(xJuickDataFolder, "Avatars");
|
||||||
|
if (!Directory.Exists(xJuickDataFolder))
|
||||||
|
Directory.CreateDirectory(xJuickDataFolder);
|
||||||
|
if (!Directory.Exists(xJuickAvatarsFolder))
|
||||||
|
Directory.CreateDirectory(xJuickAvatarsFolder);
|
||||||
|
|
||||||
|
filepath = Path.Combine(xJuickDataFolder, "config.xml");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// eat this! >:)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public static Settings Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Load();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
instance = new Settings();
|
||||||
|
}
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Reload()
|
||||||
|
{
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Load()
|
||||||
|
{
|
||||||
|
//LoadXML();
|
||||||
|
bool useXML = File.Exists(filepath);
|
||||||
|
if (useXML)
|
||||||
|
{
|
||||||
|
LoadXML();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IFormatter bs = new BinaryFormatter();
|
||||||
|
using (MemoryStream ms = new MemoryStream((byte[])ContactInfo.ReadSetting(IntPtr.Zero, "Settings", owner, DatabaseSettingType.Blob)))
|
||||||
|
{
|
||||||
|
instance = (Settings)bs.Deserialize(ms);
|
||||||
|
if (instance.PreviewEngines == null)
|
||||||
|
{
|
||||||
|
instance.PreviewEngines = DefaultEngines();
|
||||||
|
}
|
||||||
|
if (instance.Sites == null)
|
||||||
|
{
|
||||||
|
instance.Sites = GetSites();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LoadXML()
|
||||||
|
{
|
||||||
|
using (FileStream fs = new FileStream(filepath, FileMode.Open))
|
||||||
|
{
|
||||||
|
XmlSerializer xs = new XmlSerializer(typeof(Settings));
|
||||||
|
instance = (Settings)xs.Deserialize(fs) ?? new Settings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Save()
|
||||||
|
{
|
||||||
|
bool useXML = File.Exists(filepath);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (useXML)
|
||||||
|
{
|
||||||
|
SaveXML();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ContactInfo ci = ContactInfo.FromHandle(IntPtr.Zero);
|
||||||
|
IFormatter bs = new BinaryFormatter();
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
bs.Serialize(ms, instance);
|
||||||
|
byte[] data = new byte[ms.Length];
|
||||||
|
ms.Position = 0;
|
||||||
|
ms.Read(data, 0, (int)ms.Length);
|
||||||
|
ci.WriteSettingAsBlob("Settings", owner, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveXML()
|
||||||
|
{
|
||||||
|
using (FileStream fs = new FileStream(filepath, FileMode.Create))
|
||||||
|
{
|
||||||
|
XmlSerializer xs = new XmlSerializer(typeof(Settings));
|
||||||
|
xs.Serialize(fs, instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Settings()
|
||||||
|
{
|
||||||
|
List<ButtonInfo> buttons = new List<ButtonInfo>();
|
||||||
|
buttons.Add(new ButtonInfo("10 последних сообщений", "#+", ModuleName + "_GetLast"));
|
||||||
|
/*
|
||||||
|
buttons.Add(new ButtonInfo("10 горячих сообщений", "#", ModuleName + "_GetTop"));
|
||||||
|
buttons.Add(new ButtonInfo("10 популярных тегов", "*", ModuleName + "_GetTopTags"));
|
||||||
|
buttons.Add(new ButtonInfo("10 популярных пользователей", "@", ModuleName + "_GetTopUsers"));
|
||||||
|
buttons.Add(new ButtonInfo("Ваши подписки", "S", ModuleName + "_GetSubscriptions"));
|
||||||
|
*/
|
||||||
|
buttons.Add(new ButtonInfo("Ссылка для логина", "LOGIN", ModuleName + "_GetLogin"));
|
||||||
|
|
||||||
|
this.buttons = buttons.ToArray();
|
||||||
|
|
||||||
|
List<LinkButton> linkButtons = new List<LinkButton>();
|
||||||
|
linkButtons.Add(new LinkButton("%NUMBER%", "Прочитать", ModuleName + "_Magnifier", true, LinkDisplayType.Posts, true));
|
||||||
|
linkButtons.Add(new LinkButton("xJuick://Fork/%NUMBER%", "Отдельное окно", ModuleName + "_ForkSmall", true, LinkDisplayType.Posts, true));
|
||||||
|
linkButtons.Add(new LinkButton("%NUMBER%+", "Много прочитать", ModuleName + "_Plus", true, LinkDisplayType.Posts, true));
|
||||||
|
linkButtons.Add(new LinkButton("S %NUMBER%", "Хочу следить", ModuleName + "_Tick", true, LinkDisplayType.Posts, true));
|
||||||
|
linkButtons.Add(new LinkButton("U %NUMBER%", "Не хочу следить", ModuleName + "_Minus", true, LinkDisplayType.Posts, true));
|
||||||
|
linkButtons.Add(new LinkButton("! %NUMBER%", "SPAM it", ModuleName + "_Exclamation", false, LinkDisplayType.Posts, true));
|
||||||
|
|
||||||
|
linkButtons.Add(new LinkButton("%NUMBER%", "Перечитать пост", ModuleName + "_Magnifier", true, LinkDisplayType.Comments, true));
|
||||||
|
linkButtons.Add(new LinkButton("xJuick://Fork/%NUMBER%", "Отдельное окно", ModuleName + "_ForkSmall", true, LinkDisplayType.Comments, true));
|
||||||
|
linkButtons.Add(new LinkButton("U %NUMBER%", "Задолбали комменты", ModuleName + "_Minus", true, LinkDisplayType.Comments, true));
|
||||||
|
linkButtons.Add(new LinkButton("D %COMMENT%", "Удалить", ModuleName + "_Cross", false, LinkDisplayType.Comments, true));
|
||||||
|
|
||||||
|
linkButtons.Add(new LinkButton("%NICK%", "Инфо", ModuleName + "_Magnifier", true, LinkDisplayType.Nicks, true));
|
||||||
|
linkButtons.Add(new LinkButton("%NICK%+", "10 постов", ModuleName + "_Plus", true, LinkDisplayType.Nicks, true));
|
||||||
|
linkButtons.Add(new LinkButton("PM %NICK% ", "Приват", ModuleName + "_Ballon", false, LinkDisplayType.Nicks, true));
|
||||||
|
linkButtons.Add(new LinkButton("S %NICK%", "Хочу следить", ModuleName + "_Tick", true, LinkDisplayType.Nicks, true));
|
||||||
|
linkButtons.Add(new LinkButton("U %NICK%", "Не хочу следить", ModuleName + "_Minus", true, LinkDisplayType.Nicks, true));
|
||||||
|
linkButtons.Add(new LinkButton("BL %NICK%", "Занести в блэклист", ModuleName + "_BlackUser", false, LinkDisplayType.Nicks, true));
|
||||||
|
|
||||||
|
this.srmmLinkButtons = linkButtons.ToArray();
|
||||||
|
|
||||||
|
PreviewEngines = DefaultEngines();
|
||||||
|
|
||||||
|
jabberProtocolName = "yours@jabber.protocol.name";
|
||||||
|
|
||||||
|
activeContacts = new string[0];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.sites = GetSites();
|
||||||
|
|
||||||
|
autoFork = false;
|
||||||
|
fastIEView = true;
|
||||||
|
showAvatars = true;
|
||||||
|
showContextAvatars = true;
|
||||||
|
|
||||||
|
srmmNickAction = new SimpleWordAction("%NICK% ", false);
|
||||||
|
srmmNumberAction = new SimpleWordAction("%NUMBER% ", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ISite[] GetSites()
|
||||||
|
{
|
||||||
|
List<ISite> sites = new List<ISite>();
|
||||||
|
foreach (KeyValuePair<string, ISite> site in SitesManager.Sites)
|
||||||
|
{
|
||||||
|
sites.Add(site.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sites.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PreviewEngine[] DefaultEngines()
|
||||||
|
{
|
||||||
|
List<PreviewEngine> engines = new List<PreviewEngine>();
|
||||||
|
engines.Add(new PreviewEngine("m-software.de", "http://www.m-software.de/screenshot/Screenshot.png?url={0}&delay=10&type=jpg&scale=3", true));
|
||||||
|
engines.Add(new PreviewEngine("images.websnapr.com", "http://images.websnapr.com/?url={0}&size=s", false));
|
||||||
|
return engines.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlArrayItem("JID")]
|
||||||
|
public string[] ActiveContacts
|
||||||
|
{
|
||||||
|
get { return activeContacts; }
|
||||||
|
set { activeContacts = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISite[] Sites
|
||||||
|
{
|
||||||
|
get { return sites; }
|
||||||
|
set { sites = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string JabberProtocolName
|
||||||
|
{
|
||||||
|
get { return jabberProtocolName; }
|
||||||
|
set { jabberProtocolName = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonInfo[] Buttons
|
||||||
|
{
|
||||||
|
get { return buttons; }
|
||||||
|
set { buttons = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AutoFork
|
||||||
|
{
|
||||||
|
get { return autoFork; }
|
||||||
|
set { autoFork = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShowAvatars
|
||||||
|
{
|
||||||
|
get { return showAvatars; }
|
||||||
|
set { showAvatars = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShowContextAvatars
|
||||||
|
{
|
||||||
|
get { return showContextAvatars; }
|
||||||
|
set { showContextAvatars = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FastIEView
|
||||||
|
{
|
||||||
|
get { return fastIEView; }
|
||||||
|
set { fastIEView = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkButton[] SRMMLinkButtons
|
||||||
|
{
|
||||||
|
get { return srmmLinkButtons; }
|
||||||
|
set { srmmLinkButtons = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public bool ShowPreview
|
||||||
|
{
|
||||||
|
get { return currenPreview != null; }
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public PreviewEngine PreviewEngine
|
||||||
|
{
|
||||||
|
get { return currenPreview; }
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreviewEngine[] PreviewEngines
|
||||||
|
{
|
||||||
|
get { return previewEngines; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
previewEngines = value;
|
||||||
|
for (int i = 0, iCount = previewEngines.Length; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (previewEngines[i].Enabled)
|
||||||
|
{
|
||||||
|
currenPreview = previewEngines[i];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currenPreview = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleWordAction SRMMNickAction
|
||||||
|
{
|
||||||
|
get { return srmmNickAction; }
|
||||||
|
set { srmmNickAction = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleWordAction SRMMNumberAction
|
||||||
|
{
|
||||||
|
get { return srmmNumberAction; }
|
||||||
|
set { srmmNumberAction = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ResetToDefault()
|
||||||
|
{
|
||||||
|
instance = new Settings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
101
Speak/Speak/Fork/ContactContainer.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.HPP;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.RichEdit;
|
||||||
|
using Speak.Sites;
|
||||||
|
|
||||||
|
namespace Speak.Fork
|
||||||
|
{
|
||||||
|
internal class ContactContainer : IDisposable
|
||||||
|
{
|
||||||
|
private ContactManager parent;
|
||||||
|
private ContactInfo contact;
|
||||||
|
private IMessageProcessor processor;
|
||||||
|
|
||||||
|
public ContactContainer(ContactManager parent, ContactInfo contact)
|
||||||
|
{
|
||||||
|
this.parent = parent;
|
||||||
|
this.contact = contact;
|
||||||
|
processor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactInfo Contact
|
||||||
|
{
|
||||||
|
get { return contact; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal IMessageProcessor Processor
|
||||||
|
{
|
||||||
|
get { return processor; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateProcessor()
|
||||||
|
{
|
||||||
|
if (processor != null)
|
||||||
|
processor.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitMessageProcessor(ISite site, IntPtr hContact, IntPtr hWnd)
|
||||||
|
{
|
||||||
|
if (processor == null)
|
||||||
|
{
|
||||||
|
LogHandler currenLog = Settings.CurrentLog;
|
||||||
|
IntPtr logHandle = currenLog != LogHandler.ImitatedHPP ? LogWindow.FindRealLogWindow(hWnd, currenLog, hContact, out currenLog) : IntPtr.Zero;
|
||||||
|
|
||||||
|
if (logHandle == IntPtr.Zero && currenLog != LogHandler.ImitatedHPP)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
"Cant find LOG window of '" + LogWindow.CurrentLogEngine + "'." + Environment.NewLine +
|
||||||
|
"Links highlighting will be disabled",
|
||||||
|
"[xJuick] InitMessageProcessor() error",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (currenLog)
|
||||||
|
{
|
||||||
|
case LogHandler.Default:
|
||||||
|
processor = new RichEditHandler(site, logHandle);
|
||||||
|
break;
|
||||||
|
case LogHandler.IEView:
|
||||||
|
processor = new IEHandler(site, logHandle);
|
||||||
|
break;
|
||||||
|
case LogHandler.HistoryPP:
|
||||||
|
processor = new HistoryppHandler(site, logHandle, false);
|
||||||
|
break;
|
||||||
|
case LogHandler.ImitatedHPP:
|
||||||
|
processor = new HistoryppHandler(site, hWnd, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
processor.JuickClicked += processor_JuickClicked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processor_JuickClicked(object sender, ActionClickEvent e)
|
||||||
|
{
|
||||||
|
parent.OnJuickClicked(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
if (processor != null)
|
||||||
|
{
|
||||||
|
processor.JuickClicked -= processor_JuickClicked;
|
||||||
|
processor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
636
Speak/Speak/Fork/ContactManager.cs
Normal file
@ -0,0 +1,636 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Virtuoso.Miranda.Plugins.Helpers;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Virtuoso.Miranda.Plugins.Native;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.HPP;
|
||||||
|
using Speak.RichEdit;
|
||||||
|
using Speak.Sites;
|
||||||
|
using Speak.Structs;
|
||||||
|
using Speak.UI;
|
||||||
|
using Speak.Utils;
|
||||||
|
|
||||||
|
namespace Speak.Fork
|
||||||
|
{
|
||||||
|
class ContactManager : IDisposable
|
||||||
|
{
|
||||||
|
internal class SettingOwner : ISettingOwner
|
||||||
|
{
|
||||||
|
private string name;
|
||||||
|
|
||||||
|
public SettingOwner(string name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
set { name = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ownerProtocol;
|
||||||
|
//private ContactContainer juickContact;
|
||||||
|
private List<ContactContainer> siteContacts;
|
||||||
|
|
||||||
|
// todo: FIX IT!!!111
|
||||||
|
private const string namePrefix = "[xJuick] ";
|
||||||
|
private const string xJuickSiteField = "Site";
|
||||||
|
private List<ContactContainer> forkContacts;
|
||||||
|
private SettingOwner pOwner;
|
||||||
|
private SettingOwner mpOwner;
|
||||||
|
private SettingOwner clOwner;
|
||||||
|
private SettingOwner sOwner;
|
||||||
|
private IntPtr rootName;
|
||||||
|
private bool addAsTemporary;
|
||||||
|
private StatusModes mode;
|
||||||
|
private Dictionary<string, ISite> additionalContacts;
|
||||||
|
|
||||||
|
|
||||||
|
public ContactManager(IntPtr rootName, ISite[] currentSites, string ownerProtocol)
|
||||||
|
{
|
||||||
|
|
||||||
|
siteContacts = new List<ContactContainer>();
|
||||||
|
|
||||||
|
|
||||||
|
this.rootName = rootName;
|
||||||
|
mode = StatusModes.OnThePhone;
|
||||||
|
additionalContacts = new Dictionary<string, ISite>();
|
||||||
|
forkContacts = new List<ContactContainer>();
|
||||||
|
|
||||||
|
pOwner = new SettingOwner("Protocol");
|
||||||
|
mpOwner = new SettingOwner(ownerProtocol);
|
||||||
|
clOwner = new SettingOwner("CList");
|
||||||
|
sOwner = new SettingOwner("xJuickSite");
|
||||||
|
|
||||||
|
List<string> mainContacts = new List<string>();
|
||||||
|
for (int i = 0, iCount = currentSites.Length; i < iCount; i++)
|
||||||
|
{
|
||||||
|
mainContacts.Add(currentSites[i].MainContact);
|
||||||
|
|
||||||
|
ISite site = currentSites[i];
|
||||||
|
for (int j = 0, jCount = currentSites[i].AdditionalContacts.Length; j < jCount; j++)
|
||||||
|
{
|
||||||
|
additionalContacts[currentSites[i].AdditionalContacts[j]] = site;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FillContactList(mainContacts, ownerProtocol))
|
||||||
|
throw new Exception("No protocols found");
|
||||||
|
|
||||||
|
addAsTemporary = false;
|
||||||
|
|
||||||
|
MirandaContext.Current.MirandaDatabase.ContactDeleted += MirandaDatabase_ContactDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool MirandaDatabase_ContactDeleted(object sender, MirandaContactEventArgs e)
|
||||||
|
{
|
||||||
|
int deleteIndex = -1;
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Contact.MirandaHandle == e.ContactInfo.MirandaHandle)
|
||||||
|
{
|
||||||
|
if (IsAdditional(forkContacts[i].Contact.UniqueID.ToString()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
deleteIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deleteIndex != -1)
|
||||||
|
{
|
||||||
|
CopyHistory(e.ContactInfo.MirandaHandle, GetMainContactHandle(e.ContactInfo.MirandaHandle), null);
|
||||||
|
forkContacts.RemoveAt(deleteIndex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsMainContact(IntPtr hMainContact)
|
||||||
|
{
|
||||||
|
return GetMainContactContainer(hMainContact) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContactContainer GetMainContactContainer(IntPtr hMainContact)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = siteContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (hMainContact == siteContacts[i].Contact.MirandaHandle)
|
||||||
|
return siteContacts[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr GetMainContactHandle(IntPtr childHContact)
|
||||||
|
{
|
||||||
|
ISite site = SitesManager.GetContactSite(childHContact);
|
||||||
|
|
||||||
|
if (site == null)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
for (int i = 0, iCount = siteContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (siteContacts[i].Contact.UniqueID.ToString() == site.MainContact)
|
||||||
|
{
|
||||||
|
return siteContacts[i].Contact.MirandaHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero; // yeah. maybe will implement multi-juick later :)
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool FillContactList(List<string> mainContacts, string ownerProtocol)
|
||||||
|
{
|
||||||
|
// quiet unload
|
||||||
|
if (Util.EnumProtocols().Count == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Dictionary<string, Dictionary<string, ContactInfo>> protocols = new Dictionary<string, Dictionary<string, ContactInfo>>();
|
||||||
|
int contactsCount = 0;
|
||||||
|
|
||||||
|
IEnumerable<IntPtr> hContacts = MirandaContext.Current.MirandaDatabase.GetContactHandles();
|
||||||
|
foreach (IntPtr hContact in hContacts)
|
||||||
|
{
|
||||||
|
contactsCount++;
|
||||||
|
ContactInfo ci = ContactInfo.FromHandle(hContact);
|
||||||
|
|
||||||
|
if (ci == null || ci.UniqueID == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string jid = ci.UniqueID.ToString();
|
||||||
|
|
||||||
|
bool isAdditional = IsAdditional(jid);
|
||||||
|
if (jid.StartsWith(namePrefix) || isAdditional)
|
||||||
|
{
|
||||||
|
if (!IsOnContact(ci.MirandaHandle))
|
||||||
|
AddToContact(ci.MirandaHandle);
|
||||||
|
|
||||||
|
forkContacts.Add(new ContactContainer(this, ci));
|
||||||
|
|
||||||
|
string contactSite = (string)ci.ReadSetting(xJuickSiteField, sOwner, DatabaseSettingType.AsciiString);
|
||||||
|
if (!String.IsNullOrEmpty(contactSite))
|
||||||
|
{
|
||||||
|
ISite contactSiteObject = SitesManager.GetContactSite(contactSite, true);
|
||||||
|
if (contactSiteObject != null)
|
||||||
|
SitesManager.SitesInfo[ci.MirandaHandle] = contactSiteObject;
|
||||||
|
}
|
||||||
|
else if (isAdditional)
|
||||||
|
{
|
||||||
|
SitesManager.SitesInfo[ci.MirandaHandle] = additionalContacts[jid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mainContacts.IndexOf(jid) != -1)
|
||||||
|
{
|
||||||
|
ISite site = SitesManager.GetContactSite(jid, false);
|
||||||
|
if (site != null)
|
||||||
|
SitesManager.SitesInfo[hContact] = site;
|
||||||
|
|
||||||
|
string ownerProto = (string)ci.ReadSetting("p", pOwner, DatabaseSettingType.AsciiString);
|
||||||
|
if (!protocols.ContainsKey(jid))
|
||||||
|
protocols[jid] = new Dictionary<string, ContactInfo>();
|
||||||
|
|
||||||
|
protocols[jid].Add(ownerProto, ci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contactsCount == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
foreach (KeyValuePair<string, Dictionary<string, ContactInfo>> jp in protocols)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, ContactInfo> p in jp.Value)
|
||||||
|
{
|
||||||
|
if (p.Key.Equals(ownerProtocol, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
this.ownerProtocol = ownerProtocol;
|
||||||
|
ContactInfo ci = jp.Value[this.ownerProtocol];
|
||||||
|
ContactContainer mainContact = new ContactContainer(this, ci);
|
||||||
|
siteContacts.Add(mainContact);
|
||||||
|
if (!IsOnContact(ci.MirandaHandle))
|
||||||
|
AddToContact(ci.MirandaHandle);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(this.ownerProtocol))
|
||||||
|
{
|
||||||
|
if (protocols.Count == 0)
|
||||||
|
{
|
||||||
|
System.Windows.Forms.MessageBox.Show("Found ZERO protocols with main accounts (check options)" + Environment.NewLine +
|
||||||
|
"xJuick plugin will be unloaded now.", "[xJuick] Jabber Protocol error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ProtocolSelect ps = new ProtocolSelect(protocols);
|
||||||
|
if (ps.ShowDialog() != DialogResult.OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(ps.ResultProtocol) || ps.ResultContactInfo == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this.ownerProtocol = ps.ResultProtocol;
|
||||||
|
ContactInfo ci = ps.ResultContactInfo;
|
||||||
|
|
||||||
|
ContactContainer mainContact = new ContactContainer(this, ci);
|
||||||
|
siteContacts.Add(mainContact);
|
||||||
|
if (!IsOnContact(ci.MirandaHandle))
|
||||||
|
AddToContact(ci.MirandaHandle);
|
||||||
|
|
||||||
|
Settings.Instance.JabberProtocolName = this.ownerProtocol;
|
||||||
|
Settings.Save();*/
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsForked(IntPtr hContact)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Contact.MirandaHandle == hContact)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAdditional(string UID)
|
||||||
|
{
|
||||||
|
return additionalContacts.ContainsKey(UID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactInfo GetContactInfo(string mainContact, string name)
|
||||||
|
{
|
||||||
|
ContactInfo result = null;
|
||||||
|
|
||||||
|
string sname = namePrefix + name;
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Contact != null && forkContacts[i].Contact.UniqueID != null)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Contact.UniqueID.ToString().Equals(sname, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
result = forkContacts[i].Contact;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("GetContactInfo() -> Null ID [???]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (result == null && Settings.Instance.AutoFork)
|
||||||
|
{
|
||||||
|
result = MakeFork(mainContact, name);
|
||||||
|
}
|
||||||
|
else if (result != null)
|
||||||
|
ChangeStatus(result, mode);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContactInfo MakeFork(string mainContact, string name)
|
||||||
|
{
|
||||||
|
ContactInfo result = AddNewContact(mainContact, name);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
SitesManager.SitesInfo[result.MirandaHandle] = SitesManager.GetContactSite(mainContact, false);
|
||||||
|
|
||||||
|
if (!IsOnContact(result.MirandaHandle))
|
||||||
|
AddToContact(result.MirandaHandle);
|
||||||
|
|
||||||
|
forkContacts.Add(new ContactContainer(this, result));
|
||||||
|
ChangeStatus(result, mode);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyHistory(IntPtr fromContact, IntPtr toContact, Regex condition)
|
||||||
|
{
|
||||||
|
MirandaDB.DirectCopyHistory(fromContact, toContact, condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SettingsChanged()
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = siteContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (siteContacts[i].Processor != null)
|
||||||
|
siteContacts[i].Processor.SettingsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Processor != null)
|
||||||
|
{
|
||||||
|
forkContacts[i].Processor.SettingsChanged();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenChat(IntPtr hContact, IntPtr hWnd)
|
||||||
|
{
|
||||||
|
ContactContainer contact = GetMainContactContainer(hContact);
|
||||||
|
ISite site = SitesManager.GetContactSite(hContact);
|
||||||
|
|
||||||
|
if (site == null)
|
||||||
|
{
|
||||||
|
if (contact != null)
|
||||||
|
{
|
||||||
|
string cintactID = contact.Contact.UniqueID.ToString();
|
||||||
|
site = SitesManager.GetContactSite(cintactID, true);
|
||||||
|
if (site != null)
|
||||||
|
SitesManager.SitesInfo[hContact] = site;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ContactInfo ci = ContactInfo.FromHandle(hContact);
|
||||||
|
string contactSite = (string)ci.ReadSetting(xJuickSiteField, pOwner, DatabaseSettingType.AsciiString);
|
||||||
|
if (!String.IsNullOrEmpty(contactSite))
|
||||||
|
{
|
||||||
|
site = SitesManager.GetContactSite(contactSite, false);
|
||||||
|
}
|
||||||
|
else if (IsAdditional(ci.UniqueID.ToString()))
|
||||||
|
{
|
||||||
|
site = additionalContacts[ci.UniqueID.ToString()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (site == null)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (contact != null)
|
||||||
|
{
|
||||||
|
contact.InitMessageProcessor(site, hContact, hWnd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Contact.MirandaHandle == hContact)
|
||||||
|
{
|
||||||
|
forkContacts[i].InitMessageProcessor(site, hContact, hWnd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseChat(IntPtr hContact)
|
||||||
|
{
|
||||||
|
//SitesManager.SitesInfo.Remove(hContact);
|
||||||
|
|
||||||
|
ContactContainer contact = GetMainContactContainer(hContact);
|
||||||
|
if (contact != null)
|
||||||
|
{
|
||||||
|
contact.Close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Contact.MirandaHandle == hContact)
|
||||||
|
{
|
||||||
|
forkContacts[i].Close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessHistoryItem(IntPtr smallHandle, ItemRenderDetails ird)
|
||||||
|
{
|
||||||
|
ContactContainer item = null;
|
||||||
|
|
||||||
|
ContactContainer contact = GetMainContactContainer(ird.hContact);
|
||||||
|
if (contact != null)
|
||||||
|
{
|
||||||
|
item = contact;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Contact.MirandaHandle == ird.hContact)
|
||||||
|
{
|
||||||
|
item = forkContacts[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (item.Processor is HistoryppHandler)
|
||||||
|
((HistoryppHandler)item.Processor).ProcessHistoryItem(smallHandle, ird);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Avatars()
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = siteContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (siteContacts[i].Processor != null)
|
||||||
|
siteContacts[i].Processor.Avatars();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Processor != null)
|
||||||
|
forkContacts[i].Processor.Avatars();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(IntPtr hContact)
|
||||||
|
{
|
||||||
|
ContactContainer contact = GetMainContactContainer(hContact);
|
||||||
|
if (contact != null)
|
||||||
|
{
|
||||||
|
contact.UpdateProcessor();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (forkContacts[i].Contact.MirandaHandle == hContact)
|
||||||
|
{
|
||||||
|
forkContacts[i].UpdateProcessor();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContactInfo AddNewContact(string mainContact, string uid)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrEmpty(ownerProtocol))
|
||||||
|
return null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ContactInfo ci = ContactInfo.CreateContact();
|
||||||
|
|
||||||
|
ci.WriteSetting("FullName", mpOwner, uid, DatabaseSettingType.AsciiString);
|
||||||
|
ci.WriteSetting("jid", mpOwner, namePrefix + uid, DatabaseSettingType.AsciiString);
|
||||||
|
ci.WriteSetting("p", pOwner, ownerProtocol, DatabaseSettingType.AsciiString);
|
||||||
|
ci.WriteSetting(xJuickSiteField, sOwner, mainContact, DatabaseSettingType.AsciiString);
|
||||||
|
|
||||||
|
if (addAsTemporary)
|
||||||
|
{
|
||||||
|
ci.WriteSetting("NotOnList", clOwner, 1, DatabaseSettingType.Byte);
|
||||||
|
ci.WriteSetting("Delete", clOwner, 1, DatabaseSettingType.Byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ci;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
/*QuickDebug qd = new QuickDebug(ex.Message + Environment.NewLine + ex.StackTrace);
|
||||||
|
qd.ShowDialog();*/
|
||||||
|
MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactInfo CheckForHandle(IntPtr hContact, string message)
|
||||||
|
{
|
||||||
|
Match m = Regexps.ReplyRegEx.Match(message);
|
||||||
|
if (m.Success)
|
||||||
|
{
|
||||||
|
string mainContact = SitesManager.GetContactSite(hContact).MainContact;
|
||||||
|
return GetContactInfo(mainContact, "#" + m.Groups["post"].Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactInfo CheckForHandlePure(IntPtr hContact, string message)
|
||||||
|
{
|
||||||
|
Match m = Regexps.PureReplyRegEx.Match(message);
|
||||||
|
if (m.Success)
|
||||||
|
{
|
||||||
|
ISite site = SitesManager.GetContactSite(hContact);
|
||||||
|
string mainContact = site == null ? String.Empty : site.MainContact;
|
||||||
|
return GetContactInfo(mainContact, "#" + m.Groups["post"].Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeForkState(IntPtr hContact, string name)
|
||||||
|
{
|
||||||
|
string mainContact = SitesManager.GetContactSite(hContact).MainContact;
|
||||||
|
ContactInfo result = GetContactInfo(mainContact, name);
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
result = MakeFork(mainContact, name);
|
||||||
|
if (result != null)
|
||||||
|
CopyHistory(GetMainContactHandle(hContact), result.MirandaHandle, Regexps.GetHistoryRegEx(name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.OpenMessageWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddToContact(IntPtr hContact)
|
||||||
|
{
|
||||||
|
MirandaContext.Current.CallService(API.MS_PROTO_ADDTOCONTACT, hContact, rootName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsOnContact(IntPtr hContact)
|
||||||
|
{
|
||||||
|
return Convert.ToBoolean(MirandaContext.Current.CallService(API.MS_PROTO_ISPROTOONCONTACT, hContact, rootName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChangeStatus(ContactInfo ci, StatusModes status)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ci.WriteSetting("Status", mpOwner, (UInt16)status, DatabaseSettingType.UInt16);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearContacts()
|
||||||
|
{
|
||||||
|
ContactContainer[] fk = forkContacts.ToArray();
|
||||||
|
for (int i = 0, iCount = fk.Length; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (!IsAdditional(fk[i].Contact.UniqueID.ToString()))
|
||||||
|
{
|
||||||
|
fk[i].Contact.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forkContacts.Clear();
|
||||||
|
forkContacts = new List<ContactContainer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnJuickClicked(object sender, ActionClickEvent e)
|
||||||
|
{
|
||||||
|
IntPtr hContact = ((ContactContainer) sender).Contact.MirandaHandle;
|
||||||
|
if (!e.AutoSend)
|
||||||
|
{
|
||||||
|
UnmanagedStringHandle str = new UnmanagedStringHandle(e.Action, StringEncoding.Ansi);
|
||||||
|
MirandaContext.Current.CallService(API.MS_MSG_SENDMESSAGE, hContact, str.IntPtr);
|
||||||
|
str.Free();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (e.Action.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
Util.OpenURL(e.Action);
|
||||||
|
}
|
||||||
|
else if (e.Action.StartsWith("xJuick://", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
InvokeOnAction(hContact, e.Action.Substring(9).ToLower());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CSSData css = new CSSData();
|
||||||
|
css.hContact = hContact; //juickContact.Contact.MirandaHandle;
|
||||||
|
css.szProtoService = API.PSS_MESSAGE;
|
||||||
|
css.wParam = IntPtr.Zero;
|
||||||
|
css.lParam = new UnmanagedStringHandle(e.Action, StringEncoding.Ansi).IntPtr;
|
||||||
|
|
||||||
|
IntPtr cmdPtr = Marshal.AllocHGlobal(Marshal.SizeOf(css));
|
||||||
|
Marshal.StructureToPtr(css, cmdPtr, false);
|
||||||
|
MirandaContext.Current.CallService(API.MS_PROTO_CALLCONTACTSERVICE, IntPtr.Zero, cmdPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<ActionEvent> OnAction;
|
||||||
|
public void InvokeOnAction(IntPtr hContact, string action)
|
||||||
|
{
|
||||||
|
if (OnAction == null)
|
||||||
|
return;
|
||||||
|
OnAction(this, new ActionEvent(hContact, action));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = forkContacts.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
forkContacts[i].Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
708
Speak/Speak/HPP/HistoryppHandler.cs
Normal file
@ -0,0 +1,708 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.RichEdit;
|
||||||
|
using Speak.Sites;
|
||||||
|
using Speak.Structs;
|
||||||
|
using Speak.UI;
|
||||||
|
using Speak.Utils;
|
||||||
|
|
||||||
|
namespace Speak.HPP
|
||||||
|
{
|
||||||
|
internal class HistoryppHandler : IMessageProcessor
|
||||||
|
{
|
||||||
|
private IntPtr wHandle;
|
||||||
|
private ISite site;
|
||||||
|
private Subclassing subclass;
|
||||||
|
private List<HppActionOleObject> btns;
|
||||||
|
private List<HppAvatarObject> avatars;
|
||||||
|
private Dictionary<IntPtr, RichEditInfo> chachedRects;
|
||||||
|
|
||||||
|
|
||||||
|
private AvatarProcessor ap;
|
||||||
|
private ContextMenu context;
|
||||||
|
|
||||||
|
private SimpleWordAction srmmNickAction;
|
||||||
|
private SimpleWordAction srmmNumberAction;
|
||||||
|
|
||||||
|
private bool needRecalc;
|
||||||
|
private bool inRecalc;
|
||||||
|
private bool initialized;
|
||||||
|
private bool lazyInit;
|
||||||
|
|
||||||
|
private static Guid IID_IOleObject = typeof(IOleObject).GUID;
|
||||||
|
|
||||||
|
public HistoryppHandler(ISite site, IntPtr wHandle, bool lazyInit)
|
||||||
|
{
|
||||||
|
this.site = site;
|
||||||
|
Int32 hppVersion = MirandaContext.Current.CallService(API.MS_HPP_GETVERSION, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
byte[] hppVBytes = BitConverter.GetBytes(hppVersion);
|
||||||
|
Version vHpp = new Version(hppVBytes[3], hppVBytes[2], hppVBytes[1], hppVBytes[0]);
|
||||||
|
if (vHpp < HppConstaints.MinumumVersion)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
"You version of History++ plugin (" + vHpp.ToString() + ") is too old." + Environment.NewLine +
|
||||||
|
"Minimum supported version is " + HppConstaints.MinumumVersion.ToString() + Environment.NewLine +
|
||||||
|
"Links highlighting will be disabled",
|
||||||
|
"[xJuick] History++ version checking...",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Error);
|
||||||
|
initialized = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
needRecalc = inRecalc = false;
|
||||||
|
initialized = !lazyInit;
|
||||||
|
this.lazyInit = lazyInit;
|
||||||
|
this.wHandle = wHandle;
|
||||||
|
|
||||||
|
if (initialized)
|
||||||
|
{
|
||||||
|
subclass = new Subclassing(wHandle);
|
||||||
|
subclass.StartSubclassing(WndProc);
|
||||||
|
}
|
||||||
|
|
||||||
|
btns = new List<HppActionOleObject>();
|
||||||
|
avatars = new List<HppAvatarObject>();
|
||||||
|
chachedRects = new Dictionary<IntPtr, RichEditInfo>();
|
||||||
|
|
||||||
|
srmmNickAction = Settings.Instance.SRMMNickAction;
|
||||||
|
srmmNumberAction = Settings.Instance.SRMMNumberAction;
|
||||||
|
|
||||||
|
ap = new AvatarProcessor(site);
|
||||||
|
MakeContextMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MakeContextMenu()
|
||||||
|
{
|
||||||
|
context = new ContextMenu();
|
||||||
|
foreach (LinkButton lb in Settings.Instance.SRMMLinkButtons)
|
||||||
|
{
|
||||||
|
if (!lb.Enabled)
|
||||||
|
continue;
|
||||||
|
ActionMenuItem mi = new ActionMenuItem(lb);
|
||||||
|
//mi.Image = IconTable.GetActionIcon(lb.IconName);
|
||||||
|
mi.Click += ActionMenuClick;
|
||||||
|
context.MenuItems.Add(mi);
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionMenuItem contextAvatar = new ActionMenuItem(new LinkButton(String.Empty, String.Empty, false, LinkDisplayType.Image));
|
||||||
|
context.MenuItems.Add(contextAvatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int WndProc(IntPtr hWnd, int Msg, int wParam, int lParam)
|
||||||
|
{
|
||||||
|
bool lmb = false;
|
||||||
|
switch (Msg)
|
||||||
|
{
|
||||||
|
case WinApi.WM_LBUTTONDBLCLK:
|
||||||
|
case WinApi.WM_LBUTTONDOWN:
|
||||||
|
case WinApi.WM_LBUTTONUP:
|
||||||
|
int x = Util.LoWord(lParam);
|
||||||
|
int y = Util.HiWord(lParam);
|
||||||
|
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
HppActionOleObject btn = btns[i];
|
||||||
|
RECT rect = chachedRects[btn.Owner].Rect;
|
||||||
|
if (rect.IsEmpty)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (btn.HitTest(x, y - rect.Top))
|
||||||
|
{
|
||||||
|
if (Msg == WinApi.WM_LBUTTONDOWN)
|
||||||
|
{
|
||||||
|
btn.SetLMBDownState();
|
||||||
|
}
|
||||||
|
else if (Msg == WinApi.WM_LBUTTONUP)
|
||||||
|
{
|
||||||
|
btn.SetLMBUpState(hWnd, rect.Top);
|
||||||
|
}
|
||||||
|
|
||||||
|
lmb = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
if (!lmb)
|
||||||
|
result = subclass.CallParent(hWnd, Msg, wParam, lParam);
|
||||||
|
|
||||||
|
switch (Msg)
|
||||||
|
{
|
||||||
|
case WinApi.WM_MOUSEMOVE:
|
||||||
|
int x = Util.LoWord(lParam);
|
||||||
|
int y = Util.HiWord(lParam);
|
||||||
|
|
||||||
|
if (needRecalc)
|
||||||
|
{
|
||||||
|
RecalcRects();
|
||||||
|
needRecalc = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
HppActionOleObject btn = btns[i];
|
||||||
|
RECT rect = chachedRects[btn.Owner].Rect;
|
||||||
|
if (!rect.IsEmpty)
|
||||||
|
btn.MouseMoving(x, y - rect.Top);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((wParam & WinApi.MK_CONTROL) == WinApi.MK_CONTROL) && Settings.Instance.ShowPreview)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<IntPtr, RichEditInfo> rect in chachedRects)
|
||||||
|
{
|
||||||
|
if (!rect.Value.Rect.IsEmpty)
|
||||||
|
{
|
||||||
|
if (y > rect.Value.Rect.Top && y < rect.Value.Rect.Bottom)
|
||||||
|
{
|
||||||
|
string url = GetCurrentURL(x - rect.Value.Rect.Left, y - rect.Value.Rect.Top, RichEditHelpers.GetIText(rect.Key), rect.Key);
|
||||||
|
if (!String.IsNullOrEmpty(url))
|
||||||
|
{
|
||||||
|
POINT pt = new POINT(x, y);
|
||||||
|
WinApi.ClientToScreen(wHandle, ref pt);
|
||||||
|
ImagePreview.Show(pt.X, pt.Y + 10, url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImagePreview.Hide();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImagePreview.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
//case WinApi.WM_PAINT:
|
||||||
|
case WinApi.WM_VSCROLL:
|
||||||
|
case WinApi.WM_RESIZE:
|
||||||
|
needRecalc = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SettingsChanged()
|
||||||
|
{
|
||||||
|
MakeContextMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
if (!initialized)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowThreads()
|
||||||
|
{
|
||||||
|
if (!initialized)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Avatars()
|
||||||
|
{
|
||||||
|
if (!initialized)
|
||||||
|
return;
|
||||||
|
// not supported
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearButtons(IntPtr oldOwner)
|
||||||
|
{
|
||||||
|
List<HppActionOleObject> newBtns = new List<HppActionOleObject>();
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (btns[i].Owner != oldOwner)
|
||||||
|
newBtns.Add(btns[i]);
|
||||||
|
}
|
||||||
|
btns = newBtns;
|
||||||
|
|
||||||
|
List<HppAvatarObject> newAvatars = new List<HppAvatarObject>();
|
||||||
|
for (int i = 0, iCount = newAvatars.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (avatars[i].Owner != oldOwner)
|
||||||
|
newAvatars.Add(avatars[i]);
|
||||||
|
}
|
||||||
|
avatars = newAvatars;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecalcRects()
|
||||||
|
{
|
||||||
|
inRecalc = true;
|
||||||
|
Dictionary<IntPtr, RichEditInfo> newRects = new Dictionary<IntPtr, RichEditInfo>();
|
||||||
|
foreach (KeyValuePair<IntPtr, RichEditInfo> rect in chachedRects)
|
||||||
|
{
|
||||||
|
IntPtr h = rect.Key;
|
||||||
|
RichEditInfo ri = RichEditHelpers.GetRichEditInfo(h, wHandle);
|
||||||
|
RECT r = ri.Rect;
|
||||||
|
|
||||||
|
newRects.Add(h, ri);
|
||||||
|
|
||||||
|
if (r.Top > 0)
|
||||||
|
{
|
||||||
|
SetActionObjectPosition(h, true);
|
||||||
|
}
|
||||||
|
else if (r.Bottom > 0 /*&& !rect.Value.Equals(r)*/)
|
||||||
|
{
|
||||||
|
SetActionObjectPosition(h, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = avatars.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
avatars[i].BgColor = newRects[avatars[i].Owner].BgColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
chachedRects = newRects;
|
||||||
|
inRecalc = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessHistoryItem(IntPtr smallHandle, ItemRenderDetails ird)
|
||||||
|
{
|
||||||
|
if (lazyInit)
|
||||||
|
{
|
||||||
|
LogHandler currentLog;
|
||||||
|
wHandle = LogWindow.FindRealLogWindow(wHandle, Settings.CurrentLog, ird.hContact, out currentLog);
|
||||||
|
if (wHandle != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
subclass = new Subclassing(wHandle);
|
||||||
|
subclass.StartSubclassing(WndProc);
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
lazyInit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IRichEditOle richEditOle = RichEditHelpers.SendMessage(smallHandle, REConstants.EM_GETOLEINTERFACE, 0);
|
||||||
|
ITextDocument itr = RichEditHelpers.GetIText(smallHandle);
|
||||||
|
|
||||||
|
if (!inRecalc)
|
||||||
|
{
|
||||||
|
if (chachedRects.ContainsKey(smallHandle))
|
||||||
|
ClearButtons(smallHandle);
|
||||||
|
chachedRects[smallHandle] = RichEditInfo.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itr != null)
|
||||||
|
Routine(itr, richEditOle, smallHandle);
|
||||||
|
|
||||||
|
needRecalc = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetRichEditText(ITextDocument richEdit)
|
||||||
|
{
|
||||||
|
string text = richEdit.Range(0, Int32.MaxValue).Text;
|
||||||
|
if (String.IsNullOrEmpty(text))
|
||||||
|
return String.Empty;
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Routine(ITextDocument richEdit, IRichEditOle ole, IntPtr handle)
|
||||||
|
{
|
||||||
|
string text = GetRichEditText(richEdit);
|
||||||
|
|
||||||
|
bool readOnly = (WinApi.GetWindowLong(handle, WinApi.GWL_STYLE) & REConstants.ES_READONLY) != 0;
|
||||||
|
if (readOnly)
|
||||||
|
WinApi.SendMessage(handle, REConstants.EM_SETREADONLY, 0, 0);
|
||||||
|
|
||||||
|
richEdit.Freeze();
|
||||||
|
// posts/comments
|
||||||
|
Match m = site.NumRegex.Match(text);
|
||||||
|
while (m.Success)
|
||||||
|
{
|
||||||
|
string victimWord = m.Groups["full"].Value;
|
||||||
|
ActionWordType actionWord = !String.IsNullOrEmpty(m.Groups["cmnt"].Value)
|
||||||
|
? ActionWordType.Comments
|
||||||
|
: ActionWordType.Post;
|
||||||
|
|
||||||
|
|
||||||
|
int selStart = text.IndexOf(victimWord);
|
||||||
|
bool correctID = true;
|
||||||
|
|
||||||
|
if (victimWord.Length < 3)
|
||||||
|
correctID = false;
|
||||||
|
|
||||||
|
// fucking urls
|
||||||
|
if (correctID && victimWord.Length < 5)
|
||||||
|
{
|
||||||
|
richEdit.Selection.Start = selStart;
|
||||||
|
richEdit.Selection.End = selStart + 1;
|
||||||
|
CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
|
||||||
|
cf.cbSize = (UInt32)Marshal.SizeOf(cf);
|
||||||
|
cf.szFaceName = new char[32];
|
||||||
|
|
||||||
|
IntPtr wpar = new IntPtr(REConstants.SCF_SELECTION);
|
||||||
|
IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
|
||||||
|
Marshal.StructureToPtr(cf, lpar, false);
|
||||||
|
|
||||||
|
new IntPtr(WinApi.SendMessage(handle, REConstants.EM_GETCHARFORMAT, wpar, lpar));
|
||||||
|
|
||||||
|
cf = (CHARFORMAT2_STRUCT)Marshal.PtrToStructure(lpar, typeof(CHARFORMAT2_STRUCT));
|
||||||
|
|
||||||
|
if (
|
||||||
|
((cf.dwMask & REConstants.CFM_LINK) == REConstants.CFM_LINK) &&
|
||||||
|
((cf.dwEffects & REConstants.CFE_LINK) == REConstants.CFE_LINK)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
correctID = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.FreeCoTaskMem(lpar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (correctID)
|
||||||
|
{
|
||||||
|
AddActionObject(richEdit, ole, handle, selStart, victimWord, actionWord);
|
||||||
|
text = GetRichEditText(richEdit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
m = m.NextMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
// JIDs
|
||||||
|
m = Regexps.JidRegEx.Match(text);
|
||||||
|
while (m.Success)
|
||||||
|
{
|
||||||
|
string victimWord = m.Groups["name"].Value;
|
||||||
|
|
||||||
|
AddActionObject(richEdit, ole, handle, text.IndexOf(victimWord), victimWord, ActionWordType.Nick);
|
||||||
|
text = GetRichEditText(richEdit);
|
||||||
|
|
||||||
|
m = m.NextMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @nicks
|
||||||
|
m = site.NameRegex.Match(text);
|
||||||
|
while (m.Success)
|
||||||
|
{
|
||||||
|
string victimWord = m.Groups["name"].Value;
|
||||||
|
ActionObjectType objectType = !String.IsNullOrEmpty(m.Groups["isFirst"].Value) ? ActionObjectType.FirstNick : ActionObjectType.Nick;
|
||||||
|
AddActionObject(richEdit, ole, handle, text.IndexOf(victimWord), victimWord, ActionWordType.Nick, objectType);
|
||||||
|
text = GetRichEditText(richEdit);
|
||||||
|
|
||||||
|
m = m.NextMatch();
|
||||||
|
}
|
||||||
|
richEdit.Unfreeze();
|
||||||
|
|
||||||
|
// avatars
|
||||||
|
if (Settings.Instance.ShowAvatars)
|
||||||
|
ShowAvatars(richEdit, ole, handle);
|
||||||
|
|
||||||
|
if (readOnly)
|
||||||
|
WinApi.SendMessage(handle, REConstants.EM_SETREADONLY, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowAvatars(ITextDocument richEdit, IRichEditOle richEditOle, IntPtr owner)
|
||||||
|
{
|
||||||
|
List<KeyValuePair<string, int>> avatars = new List<KeyValuePair<string, int>>();
|
||||||
|
//Int32 lastLine = -1;
|
||||||
|
for (int i = 0, iCount = richEditOle.GetObjectCount(); i < iCount; i++)
|
||||||
|
{
|
||||||
|
REOBJECT reoObject = new REOBJECT();
|
||||||
|
if (richEditOle.GetObject(i, reoObject, GETOBJECTOPTIONS.REO_GETOBJ_POLEOBJ) == 0)
|
||||||
|
{
|
||||||
|
if (reoObject.clsid == HppActionOleObject.Guid)
|
||||||
|
{
|
||||||
|
IntPtr iaolep;
|
||||||
|
Marshal.QueryInterface(reoObject.poleobj, ref IID_IOleObject, out iaolep);
|
||||||
|
|
||||||
|
IActionOleObject iao = (IActionOleObject)Marshal.GetTypedObjectForIUnknown(iaolep, typeof(IActionOleObject));
|
||||||
|
if (!iao.IsTailObjectSet && iao.ObjectType == ActionObjectType.FirstNick)
|
||||||
|
{
|
||||||
|
// select for yourself
|
||||||
|
//int lineIndex = WinApi.SendMessage(owner, REConstants.EM_EXLINEFROMCHAR, 0, reoObject.cp);
|
||||||
|
//int charOffset = reoObject.cp - WinApi.SendMessage(wHandle, REConstants.EM_LINEINDEX, lineIndex, 0);
|
||||||
|
//avatars.Add(new KeyValuePair<string, int>(iao.Text.Substring(1), reoObject.cp + avatars.Count - (lastLine != lineIndex ? charOffset : 0)));
|
||||||
|
avatars.Add(new KeyValuePair<string, int>(iao.Text.Substring(1), reoObject.cp + avatars.Count));
|
||||||
|
//lastLine = lineIndex;
|
||||||
|
iao.IsTailObjectSet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int offset = 0;
|
||||||
|
foreach (KeyValuePair<string, int> ava in avatars)
|
||||||
|
{
|
||||||
|
int index = offset + ava.Value;
|
||||||
|
richEdit.Selection.Start = index;
|
||||||
|
richEdit.Selection.End = index;
|
||||||
|
RichEditHelpers.InsertControl(richEditOle, new HppAvatarObject(owner, wHandle, ap, ava.Key));
|
||||||
|
richEdit.Range(index + 1, index + 1).Text = " ";
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
ap.Process();
|
||||||
|
needRecalc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// well. it's not supported yet, since I dunno how to invalidate hpp window
|
||||||
|
private void DeleteAvatars(ITextDocument richEdit, IRichEditOle richEditOle)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = richEditOle.GetObjectCount(); i < iCount; i++)
|
||||||
|
{
|
||||||
|
REOBJECT reoObject = new REOBJECT();
|
||||||
|
if (richEditOle.GetObject(i, reoObject, GETOBJECTOPTIONS.REO_GETOBJ_POLEOBJ) == 0)
|
||||||
|
{
|
||||||
|
if (reoObject.clsid == AvatarObject.Guid)
|
||||||
|
{
|
||||||
|
richEdit.Range(reoObject.cp, reoObject.cp + 2).Text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (btns[i].ObjectType == ActionObjectType.FirstNick)
|
||||||
|
btns[i].IsTailObjectSet = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddActionObject(ITextDocument richEdit, IRichEditOle ole, IntPtr owner, int selStart, string fullWord, ActionWordType actionType)
|
||||||
|
{
|
||||||
|
AddActionObject(richEdit, ole, owner, selStart, fullWord, actionType, ActionObjectType.Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddActionObject(ITextDocument richEdit, IRichEditOle ole, IntPtr owner, int selStart, string fullWord, ActionWordType actionType, ActionObjectType objectType)
|
||||||
|
{
|
||||||
|
richEdit.Selection.Start = selStart;
|
||||||
|
richEdit.Selection.End = selStart + fullWord.Length;
|
||||||
|
|
||||||
|
HppActionOleObject aoo = new HppActionOleObject();
|
||||||
|
aoo.ObjectType = objectType;
|
||||||
|
aoo.ActionType = actionType;
|
||||||
|
aoo.Owner = owner;
|
||||||
|
aoo.MainHandle = wHandle;
|
||||||
|
aoo.Left = 0;
|
||||||
|
aoo.ActionClicked += actionObject_JuickClicked;
|
||||||
|
aoo.Font = new Font(richEdit.Selection.Font.Name, richEdit.Selection.Font.Size);
|
||||||
|
aoo.ForeColor = ColorTranslator.FromWin32(richEdit.Selection.Font.ForeColor);
|
||||||
|
aoo.Text = fullWord;
|
||||||
|
|
||||||
|
btns.Add(aoo);
|
||||||
|
RichEditHelpers.InsertControl(ole, aoo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetActionObjectPosition(IntPtr owner, bool redraw)
|
||||||
|
{
|
||||||
|
IRichEditOle ole = RichEditHelpers.SendMessage(owner, REConstants.EM_GETOLEINTERFACE, 0);
|
||||||
|
ITextDocument richEdit = RichEditHelpers.GetIText(owner);
|
||||||
|
if (richEdit == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ITextRange range = richEdit.Range(0, Int32.MaxValue);
|
||||||
|
for (int i = 0, iCount = ole.GetObjectCount(); i < iCount; i++)
|
||||||
|
{
|
||||||
|
REOBJECT reoObject = new REOBJECT();
|
||||||
|
if (ole.GetObject(i, reoObject, GETOBJECTOPTIONS.REO_GETOBJ_POLEOBJ) == 0)
|
||||||
|
{
|
||||||
|
bool isButton = reoObject.clsid == HppActionOleObject.Guid;
|
||||||
|
if ((isButton) || (Settings.Instance.ShowAvatars && reoObject.clsid == HppAvatarObject.Guid))
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
range.SetRange(reoObject.cp, reoObject.cp);
|
||||||
|
range.GetPoint(REConstants.TomStart | REConstants.TA_LEFT | REConstants.TA_BOTTOM, out x, out y);
|
||||||
|
|
||||||
|
|
||||||
|
IntPtr iaolep;
|
||||||
|
Marshal.QueryInterface(reoObject.poleobj, ref IID_IOleObject, out iaolep);
|
||||||
|
|
||||||
|
IActionOleObject iao = (IActionOleObject)Marshal.GetTypedObjectForIUnknown(iaolep, typeof(IActionOleObject));
|
||||||
|
|
||||||
|
POINT stc = new POINT(x, y);
|
||||||
|
WinApi.ScreenToClient(owner, ref stc);
|
||||||
|
iao.Left = stc.X;
|
||||||
|
iao.Bottom = stc.Y;
|
||||||
|
if (redraw)
|
||||||
|
{
|
||||||
|
if (isButton)
|
||||||
|
{
|
||||||
|
((HppActionOleObject) iao).Draw();
|
||||||
|
((HppActionOleObject) iao).Drawn = false;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HppAvatarObject avo = (HppAvatarObject)iao;
|
||||||
|
if (!avo.Drawn && avo.Ready)
|
||||||
|
avo.Draw();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ActionMenuClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
ActionMenuItem mi = (ActionMenuItem)sender;
|
||||||
|
InvokeJuick(new ActionClickEvent(mi.Action, mi.AutoSend));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void actionObject_JuickClicked(object sender, ActionObjectClickEvent e)
|
||||||
|
{
|
||||||
|
ActionWordType actionWord = e.ActionType;
|
||||||
|
if (e.MenuLocation != Point.Empty)
|
||||||
|
{
|
||||||
|
if (actionWord == ActionWordType.None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0, iCount = context.MenuItems.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
ActionMenuItem btn = (ActionMenuItem)context.MenuItems[i];
|
||||||
|
btn.MainWord = e.ActionText;
|
||||||
|
if (btn.DisplayType != LinkDisplayType.Always)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(btn.DisplayType == LinkDisplayType.Comments && actionWord != ActionWordType.Comments) ||
|
||||||
|
(btn.DisplayType == LinkDisplayType.Posts && actionWord != ActionWordType.Post) ||
|
||||||
|
(btn.DisplayType == LinkDisplayType.Nicks && actionWord != ActionWordType.Nick)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
btn.Visible = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btn.DisplayType == LinkDisplayType.Image)
|
||||||
|
{
|
||||||
|
if (Settings.Instance.ShowContextAvatars)
|
||||||
|
{
|
||||||
|
string avatarPath = ap.GetUserAvatar(btn.MainWord.Substring(1), null);
|
||||||
|
if (String.IsNullOrEmpty(avatarPath))
|
||||||
|
{
|
||||||
|
ap.Process();
|
||||||
|
btn.Visible = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btn.Image = Image.FromFile(avatarPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btn.Visible = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Match m = site.NumRegex.Match(btn.MainWord);
|
||||||
|
if (m.Success)
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrEmpty(m.Groups["cmnt"].Value))
|
||||||
|
{
|
||||||
|
btn.AdditionalWord = m.Groups["full"].Value;
|
||||||
|
btn.MainWord = m.Groups["post"].Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.Visible = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
context.Show(sender as Control, e.MenuLocation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (actionWord == ActionWordType.Nick)
|
||||||
|
InvokeJuick(new ActionClickEvent(srmmNickAction.Action.Replace("%NICK%", e.ActionText), srmmNickAction.Autosend));
|
||||||
|
else if (actionWord == ActionWordType.Post || actionWord == ActionWordType.Comments)
|
||||||
|
InvokeJuick(new ActionClickEvent(srmmNumberAction.Action.Replace("%NUMBER%", e.ActionText), srmmNumberAction.Autosend));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetCurrentURL(int x, int y, ITextDocument richEdit, IntPtr handle)
|
||||||
|
{
|
||||||
|
POINTL pointl = new POINTL(x, y);
|
||||||
|
Subclassing.SetLastError(0);
|
||||||
|
int charIndex = WinApi.SendMessage(handle, REConstants.EM_CHARFROMPOS, 0, ref pointl);
|
||||||
|
int err = Marshal.GetLastWin32Error();
|
||||||
|
if (err != 0 && err != 6)
|
||||||
|
return String.Empty;
|
||||||
|
|
||||||
|
if (charIndex <= 0)
|
||||||
|
return null;
|
||||||
|
int lineIndex = WinApi.SendMessage(handle, REConstants.EM_EXLINEFROMCHAR, 0, charIndex);
|
||||||
|
int charOffset = charIndex - WinApi.SendMessage(handle, REConstants.EM_LINEINDEX, lineIndex, 0);
|
||||||
|
int len = WinApi.SendMessage(handle, REConstants.EM_LINELENGTH, charIndex, 0);
|
||||||
|
|
||||||
|
string line = richEdit.Range(charIndex - charOffset, (charIndex - charOffset) + len).Text;
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(line))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (charOffset == len)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
string result = String.Empty;
|
||||||
|
int i = charOffset - 1;
|
||||||
|
int j = charOffset - 1;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
while (i >= 0 && line[i] != ' ')
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
i = i + 1;
|
||||||
|
|
||||||
|
if (j == -1)
|
||||||
|
return null;
|
||||||
|
while (j < len && line[j] != ' ')
|
||||||
|
{
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < i)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
result = line.Substring(i, j - i).Trim();
|
||||||
|
if (result.IndexOf("http://") != -1)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { return String.Empty; }
|
||||||
|
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<ActionClickEvent> JuickClicked;
|
||||||
|
private void InvokeJuick(ActionClickEvent e)
|
||||||
|
{
|
||||||
|
EventHandler<ActionClickEvent> handler = JuickClicked;
|
||||||
|
if (handler != null) handler(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (subclass != null)
|
||||||
|
{
|
||||||
|
subclass.StopSubclass();
|
||||||
|
subclass.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
157
Speak/Speak/HPP/HppActionOleObject.cs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.RichEdit;
|
||||||
|
using Speak.Structs;
|
||||||
|
|
||||||
|
namespace Speak.HPP
|
||||||
|
{
|
||||||
|
[Guid("f16cc4c1-ea72-4777-9205-892fd50bf6e5")]
|
||||||
|
internal class HppActionOleObject: ActionOleObject
|
||||||
|
{
|
||||||
|
private IntPtr owner;
|
||||||
|
private IntPtr mainHandle;
|
||||||
|
private bool drawn;
|
||||||
|
new public static readonly Guid Guid = new Guid("f16cc4c1-ea72-4777-9205-892fd50bf6e5");
|
||||||
|
|
||||||
|
internal void Draw()
|
||||||
|
{
|
||||||
|
TFVCNDATA_NMHDR mh = new TFVCNDATA_NMHDR();
|
||||||
|
mh.cbSize = Marshal.SizeOf(mh);
|
||||||
|
mh.handleFrom = owner; // "mini" RE handle
|
||||||
|
mh.code = HppConstaints.NM_FIREVIEWCHANGE;
|
||||||
|
mh.bEvent = HppConstaints.FVCN_PREFIRE;
|
||||||
|
mh.bAction = HppConstaints.FVCA_DRAW;
|
||||||
|
mh.rcRect = new RECT(Left, Top, Right, Bottom);
|
||||||
|
mh.lparam = IntPtr.Zero;
|
||||||
|
|
||||||
|
IntPtr cmd = Marshal.AllocHGlobal(Marshal.SizeOf(mh));
|
||||||
|
Marshal.StructureToPtr(mh, cmd, false);
|
||||||
|
|
||||||
|
WinApi.SendMessage(mainHandle, WinApi.WM_NOTIFY, owner, cmd);
|
||||||
|
|
||||||
|
mh = (TFVCNDATA_NMHDR)Marshal.PtrToStructure(cmd, typeof(TFVCNDATA_NMHDR));
|
||||||
|
|
||||||
|
if (mh.bAction == HppConstaints.FVCA_CUSTOMDRAW && mh.hDC != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
BackColor = mh.clrBackground.GetColor();
|
||||||
|
Rectangle rect = new Rectangle(Left, Top, Right - Left, Bottom - Top);
|
||||||
|
|
||||||
|
Graphics g = Graphics.FromHdc(mh.hDC);
|
||||||
|
DrawBackground(g, rect);
|
||||||
|
Draw(g, Left);
|
||||||
|
g.Dispose();
|
||||||
|
|
||||||
|
mh.bEvent = HppConstaints.FVCN_POSTFIRE;
|
||||||
|
cmd = Marshal.AllocHGlobal(Marshal.SizeOf(mh));
|
||||||
|
Marshal.StructureToPtr(mh, cmd, false);
|
||||||
|
WinApi.SendMessage(mainHandle, WinApi.WM_NOTIFY, owner, cmd);
|
||||||
|
drawn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Draw(Graphics g, int leftOffset)
|
||||||
|
{
|
||||||
|
TextRenderer.DrawText(
|
||||||
|
g, Text, Font,
|
||||||
|
onControl ? new Point(leftOffset + 1, Top + (Height - textSize.Height) / 2) : new Point(leftOffset + 1, Top + Height - textSize.Height),
|
||||||
|
onControl ? hoverForeColor : ForeColor, TextFormatFlags.Default);
|
||||||
|
|
||||||
|
|
||||||
|
/*using (Bitmap bm = Properties.Resources.power)
|
||||||
|
{
|
||||||
|
g.DrawImage(bm, leftOffset + Width - iconWidth, Top + ((Height - iconHeight) / 2) + 1);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawBackground(Graphics g, Rectangle rect)
|
||||||
|
{
|
||||||
|
Rectangle activePart = rect;
|
||||||
|
switch (currentHover)
|
||||||
|
{
|
||||||
|
case HoverPart.None:
|
||||||
|
break;
|
||||||
|
case HoverPart.MainWord:
|
||||||
|
//activePart = new Rectangle(0, 0, textSize.Width, Height - 1);
|
||||||
|
activePart = new Rectangle(rect.Left, rect.Top, textSize.Width, rect.Height - 1);
|
||||||
|
break;
|
||||||
|
case HoverPart.Icon:
|
||||||
|
activePart = new Rectangle(rect.Left + textSize.Width, rect.Top, iconWidth-1, Height-1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (SolidBrush b = new SolidBrush(BackColor))
|
||||||
|
{
|
||||||
|
g.FillRectangle(b, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onControl)
|
||||||
|
{
|
||||||
|
using (SolidBrush b = new SolidBrush(hoverBackColor))
|
||||||
|
{
|
||||||
|
g.FillRectangle(b, activePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (Pen p = new Pen(borderColor, 1.0f))
|
||||||
|
{
|
||||||
|
g.DrawRectangle(p, activePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle border = new Rectangle(rect.Location, new Size(rect.Width-1, rect.Height-1));
|
||||||
|
using (Pen p = new Pen(borderColor, 1.0f))
|
||||||
|
{
|
||||||
|
g.DrawRectangle(p, border);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
|
||||||
|
{
|
||||||
|
if (!drawn)
|
||||||
|
{
|
||||||
|
base.OnPaint(e);
|
||||||
|
drawn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Drawn
|
||||||
|
{
|
||||||
|
get { return drawn; }
|
||||||
|
set { drawn = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)
|
||||||
|
{
|
||||||
|
//base.OnPaintBackground(pevent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Invalidate()
|
||||||
|
{
|
||||||
|
Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr Owner
|
||||||
|
{
|
||||||
|
get { return owner; }
|
||||||
|
set { owner = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr MainHandle
|
||||||
|
{
|
||||||
|
get { return mainHandle; }
|
||||||
|
set { mainHandle = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
new public Guid GUID
|
||||||
|
{
|
||||||
|
get { return Guid; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
181
Speak/Speak/HPP/HppAvatarObject.cs
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.RichEdit;
|
||||||
|
using Speak.Structs;
|
||||||
|
|
||||||
|
namespace Speak.HPP
|
||||||
|
{
|
||||||
|
// бляяя....
|
||||||
|
[Guid("04175c1c-6ab3-4688-837a-6b478fc64b65")]
|
||||||
|
internal class HppAvatarObject : AvatarObject, IActionOleGUID, IActionOleObject
|
||||||
|
{
|
||||||
|
private bool drawn;
|
||||||
|
private bool drawnInternal;
|
||||||
|
private volatile bool gotBottom;
|
||||||
|
private IntPtr owner;
|
||||||
|
private IntPtr mainHandle;
|
||||||
|
new public static readonly Guid Guid = new Guid("04175c1c-6ab3-4688-837a-6b478fc64b65");
|
||||||
|
|
||||||
|
public HppAvatarObject(IntPtr owner, IntPtr mainHandle, AvatarProcessor ap, string key) : base(ap, key, Color.Pink)
|
||||||
|
{
|
||||||
|
drawn = false;
|
||||||
|
Width = Height = 32;
|
||||||
|
this.mainHandle = mainHandle;
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Draw()
|
||||||
|
{
|
||||||
|
//if (!gotBottom)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
TFVCNDATA_NMHDR mh = new TFVCNDATA_NMHDR();
|
||||||
|
mh.cbSize = Marshal.SizeOf(mh);
|
||||||
|
mh.handleFrom = owner; // "mini" RE handle
|
||||||
|
mh.code = HppConstaints.NM_FIREVIEWCHANGE;
|
||||||
|
mh.bEvent = HppConstaints.FVCN_PREFIRE;
|
||||||
|
mh.bAction = HppConstaints.FVCA_DRAW;
|
||||||
|
mh.rcRect = new RECT(Left, Top, Right, Bottom);
|
||||||
|
mh.lparam = IntPtr.Zero;
|
||||||
|
|
||||||
|
IntPtr cmd = Marshal.AllocHGlobal(Marshal.SizeOf(mh));
|
||||||
|
Marshal.StructureToPtr(mh, cmd, false);
|
||||||
|
|
||||||
|
WinApi.SendMessage(mainHandle, WinApi.WM_NOTIFY, owner, cmd);
|
||||||
|
|
||||||
|
mh = (TFVCNDATA_NMHDR)Marshal.PtrToStructure(cmd, typeof(TFVCNDATA_NMHDR));
|
||||||
|
|
||||||
|
if (mh.bAction == HppConstaints.FVCA_CUSTOMDRAW && mh.hDC != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Graphics g = Graphics.FromHdc(mh.hDC);
|
||||||
|
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
|
||||||
|
g.DrawImage(image, Left, Top, Width, Height);
|
||||||
|
g.Dispose();
|
||||||
|
|
||||||
|
mh.bEvent = HppConstaints.FVCN_POSTFIRE;
|
||||||
|
cmd = Marshal.AllocHGlobal(Marshal.SizeOf(mh));
|
||||||
|
Marshal.StructureToPtr(mh, cmd, false);
|
||||||
|
WinApi.SendMessage(mainHandle, WinApi.WM_NOTIFY, owner, cmd);
|
||||||
|
drawn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void AvatarCallback(string userName, string avatarPath)
|
||||||
|
{
|
||||||
|
drawnInternal = false;
|
||||||
|
image = Image.FromFile(avatarPath);
|
||||||
|
if (gotBottom)
|
||||||
|
Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
|
||||||
|
{
|
||||||
|
if (!drawnInternal && Ready)
|
||||||
|
{
|
||||||
|
base.OnPaint(e);
|
||||||
|
drawnInternal = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)
|
||||||
|
{
|
||||||
|
//base.OnPaintBackground(pevent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Invalidate()
|
||||||
|
{
|
||||||
|
//Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Ready
|
||||||
|
{
|
||||||
|
get { return image != null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Drawn
|
||||||
|
{
|
||||||
|
get { return drawn; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color BgColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return BackColor;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
drawn = false;
|
||||||
|
BackColor = value;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr Owner
|
||||||
|
{
|
||||||
|
get { return owner; }
|
||||||
|
}
|
||||||
|
|
||||||
|
new public Guid GUID
|
||||||
|
{
|
||||||
|
get { return Guid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
new public int Bottom
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Top = value - Height;
|
||||||
|
gotBottom = true;
|
||||||
|
if (Ready)
|
||||||
|
Draw();
|
||||||
|
}
|
||||||
|
get { return base.Bottom; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionObjectType ObjectType
|
||||||
|
{
|
||||||
|
get { return ActionObjectType.Default; }
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsTailObjectSet
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HitTest(int x, int y)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MouseMoving(int x, int y)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLMBDownState()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLMBUpState(IntPtr richEditHwnd, int topOffset)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionWordType ActionType
|
||||||
|
{
|
||||||
|
get { return ActionWordType.None; }
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1927
Speak/Speak/Interfaces/HTMLDispIDs.cs
Normal file
110
Speak/Speak/Interfaces/HTMLDocumentEvents2.cs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.Interfaces
|
||||||
|
{
|
||||||
|
[ComVisible(true), ComImport()]
|
||||||
|
[TypeLibType((short)4160)]
|
||||||
|
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
|
||||||
|
[Guid("3050f613-98b5-11cf-bb82-00aa00bdce0b")]
|
||||||
|
public interface HTMLDocumentEvents2
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONHELP)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onhelp([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
*/
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONCLICK)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onclick([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
/*
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONDBLCLICK)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool ondblclick([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONKEYDOWN)]
|
||||||
|
void onkeydown([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONKEYUP)]
|
||||||
|
void onkeyup([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONKEYPRESS)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onkeypress([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONMOUSEDOWN)]
|
||||||
|
void onmousedown([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONMOUSEMOVE)]
|
||||||
|
void onmousemove([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONMOUSEUP)]
|
||||||
|
void onmouseup([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONMOUSEOUT)]
|
||||||
|
void onmouseout([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONMOUSEOVER)]
|
||||||
|
void onmouseover([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONREADYSTATECHANGE)]
|
||||||
|
void onreadystatechange([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREUPDATE)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onbeforeupdate([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONAFTERUPDATE)]
|
||||||
|
void onafterupdate([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONROWEXIT)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onrowexit([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONROWENTER)]
|
||||||
|
void onrowenter([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONDRAGSTART)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool ondragstart([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONSELECTSTART)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onselectstart([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONERRORUPDATE)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onerrorupdate([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONCONTEXTMENU)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool oncontextmenu([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONSTOP)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onstop([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONROWSDELETE)]
|
||||||
|
void onrowsdelete([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONROWSINSERTED)]
|
||||||
|
void onrowsinserted([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONCELLCHANGE)]
|
||||||
|
void oncellchange([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONPROPERTYCHANGE)]
|
||||||
|
void onpropertychange([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONDATASETCHANGED)]
|
||||||
|
void ondatasetchanged([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONDATAAVAILABLE)]
|
||||||
|
void ondataavailable([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONDATASETCOMPLETE)]
|
||||||
|
void ondatasetcomplete([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREEDITFOCUS)]
|
||||||
|
void onbeforeeditfocus([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONSELECTIONCHANGE)]
|
||||||
|
void onselectionchange([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONCONTROLSELECT)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool oncontrolselect([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONMOUSEWHEEL)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onmousewheel([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONFOCUSIN)]
|
||||||
|
void onfocusin([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONFOCUSOUT)]
|
||||||
|
void onfocusout([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONACTIVATE)]
|
||||||
|
void onactivate([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONDEACTIVATE)]
|
||||||
|
void ondeactivate([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREACTIVATE)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onbeforeactivate([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
[DispId(HTMLDispIDs.DISPID_HTMLDOCUMENTEVENTS2_ONBEFOREDEACTIVATE)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool onbeforedeactivate([In, MarshalAs(UnmanagedType.Interface)] IHTMLEventObj pEvtObj);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
1025
Speak/Speak/Interfaces/IHTMLDocument2.cs
Normal file
784
Speak/Speak/Interfaces/IHTMLElement.cs
Normal file
@ -0,0 +1,784 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.Interfaces
|
||||||
|
{
|
||||||
|
[Guid("3050F1FF-98B5-11CF-BB82-00AA00BDCE0B")]
|
||||||
|
[ComImport]
|
||||||
|
[TypeLibType((short)4160)]
|
||||||
|
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
|
||||||
|
public interface IHTMLElement
|
||||||
|
{
|
||||||
|
/// <summary><para><c>setAttribute</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>setAttribute</c> method was the following: <c>HRESULT setAttribute (BSTR strAttributeName, VARIANT AttributeValue, [optional, defaultvalue(1)] long lFlags)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT setAttribute (BSTR strAttributeName, VARIANT AttributeValue, [optional, defaultvalue(1)] long lFlags);
|
||||||
|
// VB6: Sub setAttribute (ByVal strAttributeName As String, ByVal AttributeValue As Any, [ByVal lFlags As Long = 1])
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLELEMENT_SETATTRIBUTE)] // - 2147417611)]
|
||||||
|
void setAttribute([MarshalAs(UnmanagedType.BStr)] string strAttributeName, object AttributeValue, int lFlags);
|
||||||
|
|
||||||
|
/// <summary><para><c>getAttribute</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>getAttribute</c> method was the following: <c>HRESULT getAttribute (BSTR strAttributeName, [optional, defaultvalue(0)] long lFlags, [out, retval] VARIANT* ReturnValue)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT getAttribute (BSTR strAttributeName, [optional, defaultvalue(0)] long lFlags, [out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function getAttribute (ByVal strAttributeName As String, [ByVal lFlags As Long = 0]) As Any
|
||||||
|
[DispId(-2147417610)]
|
||||||
|
object getAttribute([MarshalAs(UnmanagedType.BStr)] string strAttributeName, int lFlags);
|
||||||
|
|
||||||
|
/// <summary><para><c>removeAttribute</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>removeAttribute</c> method was the following: <c>HRESULT removeAttribute (BSTR strAttributeName, [optional, defaultvalue(1)] long lFlags, [out, retval] VARIANT_BOOL* ReturnValue)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT removeAttribute (BSTR strAttributeName, [optional, defaultvalue(1)] long lFlags, [out, retval] VARIANT_BOOL* ReturnValue);
|
||||||
|
// VB6: Function removeAttribute (ByVal strAttributeName As String, [ByVal lFlags As Long = 1]) As Boolean
|
||||||
|
[DispId(-2147417609)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool removeAttribute([MarshalAs(UnmanagedType.BStr)] string strAttributeName, int lFlags);
|
||||||
|
|
||||||
|
/// <summary><para><c>scrollIntoView</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>scrollIntoView</c> method was the following: <c>HRESULT scrollIntoView ([optional] VARIANT varargStart)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT scrollIntoView ([optional] VARIANT varargStart);
|
||||||
|
// VB6: Sub scrollIntoView ([ByVal varargStart As Any])
|
||||||
|
[DispId(-2147417093)]
|
||||||
|
void scrollIntoView(object varargStart);
|
||||||
|
|
||||||
|
/// <summary><para><c>contains</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>contains</c> method was the following: <c>HRESULT contains (IHTMLElement* pChild, [out, retval] VARIANT_BOOL* ReturnValue)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT contains (IHTMLElement* pChild, [out, retval] VARIANT_BOOL* ReturnValue);
|
||||||
|
// VB6: Function contains (ByVal pChild As IHTMLElement) As Boolean
|
||||||
|
[DispId(-2147417092)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
bool contains(IHTMLElement pChild);
|
||||||
|
|
||||||
|
/// <summary><para><c>insertAdjacentHTML</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>insertAdjacentHTML</c> method was the following: <c>HRESULT insertAdjacentHTML (BSTR where, BSTR html)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT insertAdjacentHTML (BSTR where, BSTR html);
|
||||||
|
// VB6: Sub insertAdjacentHTML (ByVal where As String, ByVal html As String)
|
||||||
|
[DispId(-2147417082)]
|
||||||
|
void insertAdjacentHTML([MarshalAs(UnmanagedType.BStr)] string where, [MarshalAs(UnmanagedType.BStr)] string html);
|
||||||
|
|
||||||
|
/// <summary><para><c>insertAdjacentText</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>insertAdjacentText</c> method was the following: <c>HRESULT insertAdjacentText (BSTR where, BSTR text)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT insertAdjacentText (BSTR where, BSTR text);
|
||||||
|
// VB6: Sub insertAdjacentText (ByVal where As String, ByVal text As String)
|
||||||
|
[DispId(-2147417081)]
|
||||||
|
void insertAdjacentText([MarshalAs(UnmanagedType.BStr)] string where, [MarshalAs(UnmanagedType.BStr)] string text);
|
||||||
|
|
||||||
|
/// <summary><para><c>click</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>click</c> method was the following: <c>HRESULT click (void)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT click (void);
|
||||||
|
// VB6: Sub click
|
||||||
|
[DispId(-2147417079)]
|
||||||
|
void click();
|
||||||
|
|
||||||
|
/// <summary><para><c>toString</c> method of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>toString</c> method was the following: <c>HRESULT toString ([out, retval] BSTR* ReturnValue)</c>;</para></remarks>
|
||||||
|
// IDL: HRESULT toString ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function toString As String
|
||||||
|
[DispId(-2147417076)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
string toString();
|
||||||
|
|
||||||
|
/// <summary><para><c>all</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>all</c> property was the following: <c>IDispatch* all</c>;</para></remarks>
|
||||||
|
// IDL: IDispatch* all;
|
||||||
|
// VB6: all As IDispatch
|
||||||
|
object all
|
||||||
|
{
|
||||||
|
// IDL: HRESULT all ([out, retval] IDispatch** ReturnValue);
|
||||||
|
// VB6: Function all As IDispatch
|
||||||
|
[DispId(-2147417074)]
|
||||||
|
[return: MarshalAs(UnmanagedType.IDispatch)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>children</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>children</c> property was the following: <c>IDispatch* children</c>;</para></remarks>
|
||||||
|
// IDL: IDispatch* children;
|
||||||
|
// VB6: children As IDispatch
|
||||||
|
object children
|
||||||
|
{
|
||||||
|
// IDL: HRESULT children ([out, retval] IDispatch** ReturnValue);
|
||||||
|
// VB6: Function children As IDispatch
|
||||||
|
[DispId(-2147417075)]
|
||||||
|
[return: MarshalAs(UnmanagedType.IDispatch)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>className</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>className</c> property was the following: <c>BSTR className</c>;</para></remarks>
|
||||||
|
// IDL: BSTR className;
|
||||||
|
// VB6: className As String
|
||||||
|
string className
|
||||||
|
{
|
||||||
|
// IDL: HRESULT className ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function className As String
|
||||||
|
[DispId(-2147417111)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT className (BSTR value);
|
||||||
|
// VB6: Sub className (ByVal value As String)
|
||||||
|
[DispId(-2147417111)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>document</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>document</c> property was the following: <c>IDispatch* document</c>;</para></remarks>
|
||||||
|
// IDL: IDispatch* document;
|
||||||
|
// VB6: document As IDispatch
|
||||||
|
object document
|
||||||
|
{
|
||||||
|
// IDL: HRESULT document ([out, retval] IDispatch** ReturnValue);
|
||||||
|
// VB6: Function document As IDispatch
|
||||||
|
[DispId(-2147417094)]
|
||||||
|
[return: MarshalAs(UnmanagedType.IDispatch)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>filters</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>filters</c> property was the following: <c>IHTMLFiltersCollection* filters</c>;</para></remarks>
|
||||||
|
// IDL: IHTMLFiltersCollection* filters;
|
||||||
|
// VB6: filters As IHTMLFiltersCollection
|
||||||
|
//IHTMLFiltersCollection filters
|
||||||
|
object filters
|
||||||
|
{
|
||||||
|
// IDL: HRESULT filters ([out, retval] IHTMLFiltersCollection** ReturnValue);
|
||||||
|
// VB6: Function filters As IHTMLFiltersCollection
|
||||||
|
[DispId(-2147417077)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Interface)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>id</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>id</c> property was the following: <c>BSTR id</c>;</para></remarks>
|
||||||
|
// IDL: BSTR id;
|
||||||
|
// VB6: id As String
|
||||||
|
string id
|
||||||
|
{
|
||||||
|
// IDL: HRESULT id ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function id As String
|
||||||
|
[DispId(-2147417110)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT id (BSTR value);
|
||||||
|
// VB6: Sub id (ByVal value As String)
|
||||||
|
[DispId(-2147417110)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>innerHTML</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>innerHTML</c> property was the following: <c>BSTR innerHTML</c>;</para></remarks>
|
||||||
|
// IDL: BSTR innerHTML;
|
||||||
|
// VB6: innerHTML As String
|
||||||
|
string innerHTML
|
||||||
|
{
|
||||||
|
// IDL: HRESULT innerHTML ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function innerHTML As String
|
||||||
|
[DispId(-2147417086)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT innerHTML (BSTR value);
|
||||||
|
// VB6: Sub innerHTML (ByVal value As String)
|
||||||
|
[DispId(-2147417086)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>innerText</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>innerText</c> property was the following: <c>BSTR innerText</c>;</para></remarks>
|
||||||
|
// IDL: BSTR innerText;
|
||||||
|
// VB6: innerText As String
|
||||||
|
string innerText
|
||||||
|
{
|
||||||
|
// IDL: HRESULT innerText ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function innerText As String
|
||||||
|
[DispId(-2147417085)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT innerText (BSTR value);
|
||||||
|
// VB6: Sub innerText (ByVal value As String)
|
||||||
|
[DispId(-2147417085)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>isTextEdit</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>isTextEdit</c> property was the following: <c>VARIANT_BOOL isTextEdit</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT_BOOL isTextEdit;
|
||||||
|
// VB6: isTextEdit As Boolean
|
||||||
|
bool isTextEdit
|
||||||
|
{
|
||||||
|
// IDL: HRESULT isTextEdit ([out, retval] VARIANT_BOOL* ReturnValue);
|
||||||
|
// VB6: Function isTextEdit As Boolean
|
||||||
|
[DispId(-2147417078)]
|
||||||
|
[return: MarshalAs(UnmanagedType.VariantBool)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>lang</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>lang</c> property was the following: <c>BSTR lang</c>;</para></remarks>
|
||||||
|
// IDL: BSTR lang;
|
||||||
|
// VB6: lang As String
|
||||||
|
string lang
|
||||||
|
{
|
||||||
|
// IDL: HRESULT lang ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function lang As String
|
||||||
|
[DispId(-2147413103)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT lang (BSTR value);
|
||||||
|
// VB6: Sub lang (ByVal value As String)
|
||||||
|
[DispId(-2147413103)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>language</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>language</c> property was the following: <c>BSTR language</c>;</para></remarks>
|
||||||
|
// IDL: BSTR language;
|
||||||
|
// VB6: language As String
|
||||||
|
string language
|
||||||
|
{
|
||||||
|
// IDL: HRESULT language ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function language As String
|
||||||
|
[DispId(-2147413012)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT language (BSTR value);
|
||||||
|
// VB6: Sub language (ByVal value As String)
|
||||||
|
[DispId(-2147413012)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>offsetHeight</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>offsetHeight</c> property was the following: <c>long offsetHeight</c>;</para></remarks>
|
||||||
|
// IDL: long offsetHeight;
|
||||||
|
// VB6: offsetHeight As Long
|
||||||
|
int offsetHeight
|
||||||
|
{
|
||||||
|
// IDL: HRESULT offsetHeight ([out, retval] long* ReturnValue);
|
||||||
|
// VB6: Function offsetHeight As Long
|
||||||
|
[DispId(-2147417101)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>offsetLeft</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>offsetLeft</c> property was the following: <c>long offsetLeft</c>;</para></remarks>
|
||||||
|
// IDL: long offsetLeft;
|
||||||
|
// VB6: offsetLeft As Long
|
||||||
|
int offsetLeft
|
||||||
|
{
|
||||||
|
// IDL: HRESULT offsetLeft ([out, retval] long* ReturnValue);
|
||||||
|
// VB6: Function offsetLeft As Long
|
||||||
|
[DispId(-2147417104)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>offsetParent</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>offsetParent</c> property was the following: <c>IHTMLElement* offsetParent</c>;</para></remarks>
|
||||||
|
// IDL: IHTMLElement* offsetParent;
|
||||||
|
// VB6: offsetParent As IHTMLElement
|
||||||
|
IHTMLElement offsetParent
|
||||||
|
{
|
||||||
|
// IDL: HRESULT offsetParent ([out, retval] IHTMLElement** ReturnValue);
|
||||||
|
// VB6: Function offsetParent As IHTMLElement
|
||||||
|
[DispId(-2147417100)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>offsetTop</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>offsetTop</c> property was the following: <c>long offsetTop</c>;</para></remarks>
|
||||||
|
// IDL: long offsetTop;
|
||||||
|
// VB6: offsetTop As Long
|
||||||
|
int offsetTop
|
||||||
|
{
|
||||||
|
// IDL: HRESULT offsetTop ([out, retval] long* ReturnValue);
|
||||||
|
// VB6: Function offsetTop As Long
|
||||||
|
[DispId(-2147417103)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>offsetWidth</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>offsetWidth</c> property was the following: <c>long offsetWidth</c>;</para></remarks>
|
||||||
|
// IDL: long offsetWidth;
|
||||||
|
// VB6: offsetWidth As Long
|
||||||
|
int offsetWidth
|
||||||
|
{
|
||||||
|
// IDL: HRESULT offsetWidth ([out, retval] long* ReturnValue);
|
||||||
|
// VB6: Function offsetWidth As Long
|
||||||
|
[DispId(-2147417102)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onafterupdate</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onafterupdate</c> property was the following: <c>VARIANT onafterupdate</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onafterupdate;
|
||||||
|
// VB6: onafterupdate As Any
|
||||||
|
object onafterupdate
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onafterupdate ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onafterupdate As Any
|
||||||
|
[DispId(-2147412090)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onafterupdate (VARIANT value);
|
||||||
|
// VB6: Sub onafterupdate (ByVal value As Any)
|
||||||
|
[DispId(-2147412090)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onbeforeupdate</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onbeforeupdate</c> property was the following: <c>VARIANT onbeforeupdate</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onbeforeupdate;
|
||||||
|
// VB6: onbeforeupdate As Any
|
||||||
|
object onbeforeupdate
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onbeforeupdate ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onbeforeupdate As Any
|
||||||
|
[DispId(-2147412091)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onbeforeupdate (VARIANT value);
|
||||||
|
// VB6: Sub onbeforeupdate (ByVal value As Any)
|
||||||
|
[DispId(-2147412091)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onclick</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onclick</c> property was the following: <c>VARIANT onclick</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onclick;
|
||||||
|
// VB6: onclick As Any
|
||||||
|
object onclick
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onclick ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onclick As Any
|
||||||
|
[DispId(-2147412104)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onclick (VARIANT value);
|
||||||
|
// VB6: Sub onclick (ByVal value As Any)
|
||||||
|
[DispId(-2147412104)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>ondataavailable</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>ondataavailable</c> property was the following: <c>VARIANT ondataavailable</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT ondataavailable;
|
||||||
|
// VB6: ondataavailable As Any
|
||||||
|
object ondataavailable
|
||||||
|
{
|
||||||
|
// IDL: HRESULT ondataavailable ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function ondataavailable As Any
|
||||||
|
[DispId(-2147412071)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT ondataavailable (VARIANT value);
|
||||||
|
// VB6: Sub ondataavailable (ByVal value As Any)
|
||||||
|
[DispId(-2147412071)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>ondatasetchanged</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>ondatasetchanged</c> property was the following: <c>VARIANT ondatasetchanged</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT ondatasetchanged;
|
||||||
|
// VB6: ondatasetchanged As Any
|
||||||
|
object ondatasetchanged
|
||||||
|
{
|
||||||
|
// IDL: HRESULT ondatasetchanged ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function ondatasetchanged As Any
|
||||||
|
[DispId(-2147412072)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT ondatasetchanged (VARIANT value);
|
||||||
|
// VB6: Sub ondatasetchanged (ByVal value As Any)
|
||||||
|
[DispId(-2147412072)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>ondatasetcomplete</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>ondatasetcomplete</c> property was the following: <c>VARIANT ondatasetcomplete</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT ondatasetcomplete;
|
||||||
|
// VB6: ondatasetcomplete As Any
|
||||||
|
object ondatasetcomplete
|
||||||
|
{
|
||||||
|
// IDL: HRESULT ondatasetcomplete ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function ondatasetcomplete As Any
|
||||||
|
[DispId(-2147412070)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT ondatasetcomplete (VARIANT value);
|
||||||
|
// VB6: Sub ondatasetcomplete (ByVal value As Any)
|
||||||
|
[DispId(-2147412070)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>ondblclick</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>ondblclick</c> property was the following: <c>VARIANT ondblclick</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT ondblclick;
|
||||||
|
// VB6: ondblclick As Any
|
||||||
|
object ondblclick
|
||||||
|
{
|
||||||
|
// IDL: HRESULT ondblclick ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function ondblclick As Any
|
||||||
|
[DispId(-2147412103)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT ondblclick (VARIANT value);
|
||||||
|
// VB6: Sub ondblclick (ByVal value As Any)
|
||||||
|
[DispId(-2147412103)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>ondragstart</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>ondragstart</c> property was the following: <c>VARIANT ondragstart</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT ondragstart;
|
||||||
|
// VB6: ondragstart As Any
|
||||||
|
object ondragstart
|
||||||
|
{
|
||||||
|
// IDL: HRESULT ondragstart ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function ondragstart As Any
|
||||||
|
[DispId(-2147412077)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT ondragstart (VARIANT value);
|
||||||
|
// VB6: Sub ondragstart (ByVal value As Any)
|
||||||
|
[DispId(-2147412077)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onerrorupdate</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onerrorupdate</c> property was the following: <c>VARIANT onerrorupdate</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onerrorupdate;
|
||||||
|
// VB6: onerrorupdate As Any
|
||||||
|
object onerrorupdate
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onerrorupdate ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onerrorupdate As Any
|
||||||
|
[DispId(-2147412074)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onerrorupdate (VARIANT value);
|
||||||
|
// VB6: Sub onerrorupdate (ByVal value As Any)
|
||||||
|
[DispId(-2147412074)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onfilterchange</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onfilterchange</c> property was the following: <c>VARIANT onfilterchange</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onfilterchange;
|
||||||
|
// VB6: onfilterchange As Any
|
||||||
|
object onfilterchange
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onfilterchange ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onfilterchange As Any
|
||||||
|
[DispId(-2147412069)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onfilterchange (VARIANT value);
|
||||||
|
// VB6: Sub onfilterchange (ByVal value As Any)
|
||||||
|
[DispId(-2147412069)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onhelp</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onhelp</c> property was the following: <c>VARIANT onhelp</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onhelp;
|
||||||
|
// VB6: onhelp As Any
|
||||||
|
object onhelp
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onhelp ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onhelp As Any
|
||||||
|
[DispId(-2147412099)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onhelp (VARIANT value);
|
||||||
|
// VB6: Sub onhelp (ByVal value As Any)
|
||||||
|
[DispId(-2147412099)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onkeydown</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onkeydown</c> property was the following: <c>VARIANT onkeydown</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onkeydown;
|
||||||
|
// VB6: onkeydown As Any
|
||||||
|
object onkeydown
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onkeydown ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onkeydown As Any
|
||||||
|
[DispId(-2147412107)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onkeydown (VARIANT value);
|
||||||
|
// VB6: Sub onkeydown (ByVal value As Any)
|
||||||
|
[DispId(-2147412107)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onkeypress</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onkeypress</c> property was the following: <c>VARIANT onkeypress</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onkeypress;
|
||||||
|
// VB6: onkeypress As Any
|
||||||
|
object onkeypress
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onkeypress ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onkeypress As Any
|
||||||
|
[DispId(-2147412105)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onkeypress (VARIANT value);
|
||||||
|
// VB6: Sub onkeypress (ByVal value As Any)
|
||||||
|
[DispId(-2147412105)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onkeyup</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onkeyup</c> property was the following: <c>VARIANT onkeyup</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onkeyup;
|
||||||
|
// VB6: onkeyup As Any
|
||||||
|
object onkeyup
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onkeyup ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onkeyup As Any
|
||||||
|
[DispId(-2147412106)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onkeyup (VARIANT value);
|
||||||
|
// VB6: Sub onkeyup (ByVal value As Any)
|
||||||
|
[DispId(-2147412106)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onmousedown</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onmousedown</c> property was the following: <c>VARIANT onmousedown</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onmousedown;
|
||||||
|
// VB6: onmousedown As Any
|
||||||
|
object onmousedown
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onmousedown ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onmousedown As Any
|
||||||
|
[DispId(-2147412110)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onmousedown (VARIANT value);
|
||||||
|
// VB6: Sub onmousedown (ByVal value As Any)
|
||||||
|
[DispId(-2147412110)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onmousemove</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onmousemove</c> property was the following: <c>VARIANT onmousemove</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onmousemove;
|
||||||
|
// VB6: onmousemove As Any
|
||||||
|
object onmousemove
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onmousemove ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onmousemove As Any
|
||||||
|
[DispId(-2147412108)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onmousemove (VARIANT value);
|
||||||
|
// VB6: Sub onmousemove (ByVal value As Any)
|
||||||
|
[DispId(-2147412108)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onmouseout</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onmouseout</c> property was the following: <c>VARIANT onmouseout</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onmouseout;
|
||||||
|
// VB6: onmouseout As Any
|
||||||
|
object onmouseout
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onmouseout ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onmouseout As Any
|
||||||
|
[DispId(-2147412111)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onmouseout (VARIANT value);
|
||||||
|
// VB6: Sub onmouseout (ByVal value As Any)
|
||||||
|
[DispId(-2147412111)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onmouseover</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onmouseover</c> property was the following: <c>VARIANT onmouseover</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onmouseover;
|
||||||
|
// VB6: onmouseover As Any
|
||||||
|
object onmouseover
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onmouseover ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onmouseover As Any
|
||||||
|
[DispId(-2147412112)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onmouseover (VARIANT value);
|
||||||
|
// VB6: Sub onmouseover (ByVal value As Any)
|
||||||
|
[DispId(-2147412112)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onmouseup</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onmouseup</c> property was the following: <c>VARIANT onmouseup</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onmouseup;
|
||||||
|
// VB6: onmouseup As Any
|
||||||
|
object onmouseup
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onmouseup ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onmouseup As Any
|
||||||
|
[DispId(-2147412109)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onmouseup (VARIANT value);
|
||||||
|
// VB6: Sub onmouseup (ByVal value As Any)
|
||||||
|
[DispId(-2147412109)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onrowenter</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onrowenter</c> property was the following: <c>VARIANT onrowenter</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onrowenter;
|
||||||
|
// VB6: onrowenter As Any
|
||||||
|
object onrowenter
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onrowenter ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onrowenter As Any
|
||||||
|
[DispId(-2147412093)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onrowenter (VARIANT value);
|
||||||
|
// VB6: Sub onrowenter (ByVal value As Any)
|
||||||
|
[DispId(-2147412093)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onrowexit</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onrowexit</c> property was the following: <c>VARIANT onrowexit</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onrowexit;
|
||||||
|
// VB6: onrowexit As Any
|
||||||
|
object onrowexit
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onrowexit ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onrowexit As Any
|
||||||
|
[DispId(-2147412094)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onrowexit (VARIANT value);
|
||||||
|
// VB6: Sub onrowexit (ByVal value As Any)
|
||||||
|
[DispId(-2147412094)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>onselectstart</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>onselectstart</c> property was the following: <c>VARIANT onselectstart</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT onselectstart;
|
||||||
|
// VB6: onselectstart As Any
|
||||||
|
object onselectstart
|
||||||
|
{
|
||||||
|
// IDL: HRESULT onselectstart ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function onselectstart As Any
|
||||||
|
[DispId(-2147412075)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT onselectstart (VARIANT value);
|
||||||
|
// VB6: Sub onselectstart (ByVal value As Any)
|
||||||
|
[DispId(-2147412075)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>outerHTML</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>outerHTML</c> property was the following: <c>BSTR outerHTML</c>;</para></remarks>
|
||||||
|
// IDL: BSTR outerHTML;
|
||||||
|
// VB6: outerHTML As String
|
||||||
|
string outerHTML
|
||||||
|
{
|
||||||
|
// IDL: HRESULT outerHTML ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function outerHTML As String
|
||||||
|
[DispId(-2147417084)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT outerHTML (BSTR value);
|
||||||
|
// VB6: Sub outerHTML (ByVal value As String)
|
||||||
|
[DispId(-2147417084)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>outerText</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>outerText</c> property was the following: <c>BSTR outerText</c>;</para></remarks>
|
||||||
|
// IDL: BSTR outerText;
|
||||||
|
// VB6: outerText As String
|
||||||
|
string outerText
|
||||||
|
{
|
||||||
|
// IDL: HRESULT outerText ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function outerText As String
|
||||||
|
[DispId(-2147417083)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT outerText (BSTR value);
|
||||||
|
// VB6: Sub outerText (ByVal value As String)
|
||||||
|
[DispId(-2147417083)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>parentElement</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>parentElement</c> property was the following: <c>IHTMLElement* parentElement</c>;</para></remarks>
|
||||||
|
// IDL: IHTMLElement* parentElement;
|
||||||
|
// VB6: parentElement As IHTMLElement
|
||||||
|
IHTMLElement parentElement
|
||||||
|
{
|
||||||
|
// IDL: HRESULT parentElement ([out, retval] IHTMLElement** ReturnValue);
|
||||||
|
// VB6: Function parentElement As IHTMLElement
|
||||||
|
[DispId(-2147418104)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>parentTextEdit</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>parentTextEdit</c> property was the following: <c>IHTMLElement* parentTextEdit</c>;</para></remarks>
|
||||||
|
// IDL: IHTMLElement* parentTextEdit;
|
||||||
|
// VB6: parentTextEdit As IHTMLElement
|
||||||
|
IHTMLElement parentTextEdit
|
||||||
|
{
|
||||||
|
// IDL: HRESULT parentTextEdit ([out, retval] IHTMLElement** ReturnValue);
|
||||||
|
// VB6: Function parentTextEdit As IHTMLElement
|
||||||
|
[DispId(-2147417080)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>recordNumber</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>recordNumber</c> property was the following: <c>VARIANT recordNumber</c>;</para></remarks>
|
||||||
|
// IDL: VARIANT recordNumber;
|
||||||
|
// VB6: recordNumber As Any
|
||||||
|
object recordNumber
|
||||||
|
{
|
||||||
|
// IDL: HRESULT recordNumber ([out, retval] VARIANT* ReturnValue);
|
||||||
|
// VB6: Function recordNumber As Any
|
||||||
|
[DispId(-2147417087)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>sourceIndex</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>sourceIndex</c> property was the following: <c>long sourceIndex</c>;</para></remarks>
|
||||||
|
// IDL: long sourceIndex;
|
||||||
|
// VB6: sourceIndex As Long
|
||||||
|
int sourceIndex
|
||||||
|
{
|
||||||
|
// IDL: HRESULT sourceIndex ([out, retval] long* ReturnValue);
|
||||||
|
// VB6: Function sourceIndex As Long
|
||||||
|
[DispId(-2147417088)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>style</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>style</c> property was the following: <c>IHTMLStyle* style</c>;</para></remarks>
|
||||||
|
// IDL: IHTMLStyle* style;
|
||||||
|
// VB6: style As IHTMLStyle
|
||||||
|
IHTMLStyle style
|
||||||
|
{
|
||||||
|
// IDL: HRESULT style ([out, retval] IHTMLStyle** ReturnValue);
|
||||||
|
// VB6: Function style As IHTMLStyle
|
||||||
|
[DispId(-2147418038)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>tagName</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>tagName</c> property was the following: <c>BSTR tagName</c>;</para></remarks>
|
||||||
|
// IDL: BSTR tagName;
|
||||||
|
// VB6: tagName As String
|
||||||
|
string tagName
|
||||||
|
{
|
||||||
|
// IDL: HRESULT tagName ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function tagName As String
|
||||||
|
[DispId(-2147417108)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary><para><c>title</c> property of <c>IHTMLElement</c> interface.</para></summary>
|
||||||
|
/// <remarks><para>An original IDL definition of <c>title</c> property was the following: <c>BSTR title</c>;</para></remarks>
|
||||||
|
// IDL: BSTR title;
|
||||||
|
// VB6: title As String
|
||||||
|
string title
|
||||||
|
{
|
||||||
|
// IDL: HRESULT title ([out, retval] BSTR* ReturnValue);
|
||||||
|
// VB6: Function title As String
|
||||||
|
[DispId(-2147418043)]
|
||||||
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
|
get;
|
||||||
|
// IDL: HRESULT title (BSTR value);
|
||||||
|
// VB6: Sub title (ByVal value As String)
|
||||||
|
[DispId(-2147418043)]
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
Speak/Speak/Interfaces/IHTMLEventObj.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.Interfaces
|
||||||
|
{
|
||||||
|
[ComVisible(true), ComImport()]
|
||||||
|
[TypeLibType((short)4160)] //TypeLibTypeFlags.FDispatchable
|
||||||
|
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
|
||||||
|
[Guid("3050f32d-98b5-11cf-bb82-00aa00bdce0b")]
|
||||||
|
public interface IHTMLEventObj
|
||||||
|
{
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_SRCELEMENT)]
|
||||||
|
IHTMLElement SrcElement { [return: MarshalAs(UnmanagedType.Interface)] get; }
|
||||||
|
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_ALTKEY)]
|
||||||
|
bool AltKey { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_CTRLKEY)]
|
||||||
|
bool CtrlKey { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_SHIFTKEY)]
|
||||||
|
bool ShiftKey { get; }
|
||||||
|
//VARIANT
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_RETURNVALUE)]
|
||||||
|
Object ReturnValue { set; get; }
|
||||||
|
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_CANCELBUBBLE)]
|
||||||
|
bool CancelBubble { set; [return: MarshalAs(UnmanagedType.VariantBool)] get; }
|
||||||
|
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_FROMELEMENT)]
|
||||||
|
IHTMLElement FromElement { [return: MarshalAs(UnmanagedType.Interface)] get; }
|
||||||
|
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_TOELEMENT)]
|
||||||
|
IHTMLElement ToElement { [return: MarshalAs(UnmanagedType.Interface)] get; }
|
||||||
|
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_KEYCODE)]
|
||||||
|
int keyCode { set; get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_BUTTON)]
|
||||||
|
int Button { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_TYPE)]
|
||||||
|
string EventType { [return: MarshalAs(UnmanagedType.BStr)] get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_QUALIFIER)]
|
||||||
|
string Qualifier { [return: MarshalAs(UnmanagedType.BStr)] get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_REASON)]
|
||||||
|
int Reason { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_X)]
|
||||||
|
int X { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_Y)]
|
||||||
|
int Y { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_CLIENTX)]
|
||||||
|
int ClientX { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_CLIENTY)]
|
||||||
|
int ClientY { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_OFFSETX)]
|
||||||
|
int OffsetX { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_OFFSETY)]
|
||||||
|
int OffsetY { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_SCREENX)]
|
||||||
|
int ScreenX { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_SCREENY)]
|
||||||
|
int ScreenY { get; }
|
||||||
|
[DispId(HTMLDispIDs.DISPID_IHTMLEVENTOBJ_SRCFILTER)]
|
||||||
|
object SrcFilter { [return: MarshalAs(UnmanagedType.IDispatch)] get; }
|
||||||
|
}
|
||||||
|
}
|
1497
Speak/Speak/Interfaces/IHTMLStyle.cs
Normal file
310
Speak/Speak/Interop/IEHandler.cs
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.Interfaces;
|
||||||
|
using Speak.Sites;
|
||||||
|
using Speak.Utils;
|
||||||
|
|
||||||
|
namespace Speak.Interop
|
||||||
|
{
|
||||||
|
internal class IEHandler : Invokable, IMessageProcessor
|
||||||
|
{
|
||||||
|
private string documentBody;
|
||||||
|
private IHTMLDocument2 doc;
|
||||||
|
|
||||||
|
private IntPtr wHandle;
|
||||||
|
private static Guid IID_IHTMLDocument = new Guid("626FC520-A41E-11CF-A731-00A0C9082637");
|
||||||
|
private static Guid IID_HTMLDocumentEvents2 = typeof(HTMLDocumentEvents2).GUID;
|
||||||
|
|
||||||
|
private int cookie = -1;
|
||||||
|
private IConnectionPoint connPoint;
|
||||||
|
private IConnectionPointContainer connPointContainer;
|
||||||
|
private Handler handler;
|
||||||
|
|
||||||
|
private const int MAX_UPDATETIME_WAITING = 1500; // 1.5 секунды
|
||||||
|
private bool inUpdate;
|
||||||
|
private bool jsExists;
|
||||||
|
private bool doBrake;
|
||||||
|
|
||||||
|
private Settings settings;
|
||||||
|
private AvatarProcessor ap;
|
||||||
|
private ISite site;
|
||||||
|
|
||||||
|
public IEHandler(ISite site, IntPtr wHandle) : base (wHandle)
|
||||||
|
{
|
||||||
|
jsExists = true;
|
||||||
|
inUpdate = true;
|
||||||
|
|
||||||
|
this.site = site;
|
||||||
|
|
||||||
|
settings = Settings.Instance;
|
||||||
|
this.wHandle = wHandle;
|
||||||
|
|
||||||
|
documentBody = String.Empty;
|
||||||
|
doc = IEDocumentFromHandle(this.wHandle);
|
||||||
|
|
||||||
|
handler = new Handler(this);
|
||||||
|
connPointContainer = (IConnectionPointContainer)doc;
|
||||||
|
connPointContainer.FindConnectionPoint(ref IID_HTMLDocumentEvents2, out connPoint);
|
||||||
|
connPoint.Advise(handler, out cookie);
|
||||||
|
|
||||||
|
//script = (HTMLWindow2Class)doc.Script;
|
||||||
|
//scriptWindow = typeof (HTMLWindow2Class);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// По-хорошему, это надо бы в OnDownloadComplete, но мне лень. :)
|
||||||
|
object joinedString = doc.Script.GetType().InvokeMember("eval", System.Reflection.BindingFlags.InvokeMethod, null, doc.Script, new object[] { "jInit();" });
|
||||||
|
if (Settings.Instance.ShowAvatars)
|
||||||
|
InsertAvatars(joinedString.ToString());
|
||||||
|
|
||||||
|
//doc.Script.GetType().InvokeMember("eval", System.Reflection.BindingFlags.InvokeMethod, null, doc.Script, new object[] { "jInit();" });
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
jsExists = false;
|
||||||
|
MessageBox.Show(
|
||||||
|
"Cant find javascript:jInit() function." + Environment.NewLine +
|
||||||
|
"Have you edit IEView template file?" + Environment.NewLine + Environment.NewLine +
|
||||||
|
ex.Message,
|
||||||
|
"[xJuick] JavaScript init error",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
documentBody = doc.body.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InsertAvatars(string unsplittedUsers)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrEmpty(unsplittedUsers))
|
||||||
|
return;
|
||||||
|
ap = new AvatarProcessor(site);
|
||||||
|
string[] users = unsplittedUsers.Split('#');
|
||||||
|
List<KeyValuePair<string, string>> avatars = new List<KeyValuePair<string, string>>();
|
||||||
|
for (int i = 0, iCount = users.Length; i < iCount; i++)
|
||||||
|
{
|
||||||
|
string avatarPath = ap.GetUserAvatar(users[i].Substring(1), AvatarCallBack);
|
||||||
|
if (!String.IsNullOrEmpty(avatarPath))
|
||||||
|
{
|
||||||
|
avatars.Add(new KeyValuePair<string, string>(users[i], avatarPath.Replace('\\', '/')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = avatars.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
doc.Script.GetType().InvokeMember("eval", System.Reflection.BindingFlags.InvokeMethod, null, doc.Script, new object[] { "jInsertAvatar('" + avatars[i].Key + "', '" + avatars[i].Value + "');" });
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avatars.Count != users.Length)
|
||||||
|
ap.Process();
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate void UpdateAvatar(string userName, string avatarPath);
|
||||||
|
private void PerformAvatarCallBack(string userName, string avatarPath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
doc.Script.GetType().InvokeMember("eval", System.Reflection.BindingFlags.InvokeMethod, null, doc.Script, new object[] { "jInsertAvatar('@" + userName + "', '" + avatarPath + "');" });
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AvatarCallBack(string userName, string avatarPath)
|
||||||
|
{
|
||||||
|
avatarPath = avatarPath.Replace('\\', '/');
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
UpdateAvatar d = PerformAvatarCallBack;
|
||||||
|
Invoke(d, new object[] { userName, avatarPath });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PerformAvatarCallBack(userName, avatarPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FoundIEView
|
||||||
|
{
|
||||||
|
get { return doc != null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate void UpdateChecker();
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
inUpdate = !inUpdate;
|
||||||
|
if (inUpdate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!jsExists)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Мда... Вы этого не видели :)
|
||||||
|
// Нет. Не надо смотреть на этот апдейт. :)
|
||||||
|
documentBody = doc.body.innerHTML;
|
||||||
|
UpdateChecker updater = InfinityLoop;
|
||||||
|
updater.BeginInvoke(UpdateCallback, updater);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SettingsChanged()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowThreads()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Avatars()
|
||||||
|
{
|
||||||
|
// not implemented :)
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate void UpdatePerformer();
|
||||||
|
private void PerformUpdate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
object joinedString = doc.Script.GetType().InvokeMember("eval", System.Reflection.BindingFlags.InvokeMethod, null, doc.Script, new object[] { "jInit();" });
|
||||||
|
if (Settings.Instance.ShowAvatars)
|
||||||
|
InsertAvatars(joinedString.ToString());
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCallback(IAsyncResult result)
|
||||||
|
{
|
||||||
|
UpdateChecker flusher = (UpdateChecker)result.AsyncState;
|
||||||
|
|
||||||
|
flusher.EndInvoke(result);
|
||||||
|
|
||||||
|
if (doBrake)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (InvokeRequired)
|
||||||
|
{
|
||||||
|
UpdatePerformer d = PerformUpdate;
|
||||||
|
Invoke(d, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
doc.Script.GetType().InvokeMember("eval", System.Reflection.BindingFlags.InvokeMethod, null, doc.Script, new object[] { "jInit();" });
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InfinityLoop()
|
||||||
|
{
|
||||||
|
int currentTime = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (doBrake)
|
||||||
|
return;
|
||||||
|
// Ещё вариант: if (doc.containsElementWithID("jText")) { .. }
|
||||||
|
// ...но опасно :)
|
||||||
|
if (settings.FastIEView && !documentBody.Equals(doc.body.innerHTML, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
documentBody = doc.body.innerHTML;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Thread.Sleep(100);
|
||||||
|
currentTime += 100;
|
||||||
|
// well... не дождались апдейта
|
||||||
|
if (currentTime >= MAX_UPDATETIME_WAITING)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IHTMLDocument2 IEDocumentFromHandle(IntPtr hWnd)
|
||||||
|
{
|
||||||
|
IHTMLDocument2 document = null;
|
||||||
|
int lRes;
|
||||||
|
|
||||||
|
if (WinApi.WM_HTML_GETOBJECT != 0)
|
||||||
|
{
|
||||||
|
WinApi.SendMessageTimeout(hWnd, WinApi.WM_HTML_GETOBJECT, 0, 0, WinApi.SMTO_ABORTIFHUNG, 1000, out lRes);
|
||||||
|
|
||||||
|
if (!(lRes == 0))
|
||||||
|
{
|
||||||
|
Guid iid = IID_IHTMLDocument;
|
||||||
|
WinApi.ObjectFromLresult(lRes, ref iid, 0, ref document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<ActionClickEvent> JuickClicked;
|
||||||
|
public void InvokeJuick(string action, bool autoSend)
|
||||||
|
{
|
||||||
|
if (JuickClicked == null)
|
||||||
|
return;
|
||||||
|
JuickClicked(this, new ActionClickEvent(action, autoSend));
|
||||||
|
}
|
||||||
|
|
||||||
|
~IEHandler()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Implementation of IDisposable
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
doBrake = true;
|
||||||
|
if (cookie != -1)
|
||||||
|
{
|
||||||
|
connPoint.Unadvise(cookie);
|
||||||
|
}
|
||||||
|
cookie = -1;
|
||||||
|
handler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class Handler : HTMLDocumentEvents2
|
||||||
|
{
|
||||||
|
private IEHandler parent;
|
||||||
|
|
||||||
|
public Handler(IEHandler parent)
|
||||||
|
{
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool onclick(IHTMLEventObj pEvtObj)
|
||||||
|
{
|
||||||
|
IHTMLElement el = pEvtObj.SrcElement;
|
||||||
|
if (!el.tagName.Equals("DIV", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string action = el.getAttribute("action", 0).ToString();
|
||||||
|
if (String.IsNullOrEmpty(action))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string autoSendStr = el.getAttribute("autosend", 0).ToString();
|
||||||
|
bool autoSend = autoSendStr.Equals("1") ||
|
||||||
|
autoSendStr.Equals("true", StringComparison.CurrentCultureIgnoreCase);
|
||||||
|
|
||||||
|
|
||||||
|
pEvtObj.ReturnValue = false;
|
||||||
|
pEvtObj.CancelBubble = true;
|
||||||
|
|
||||||
|
|
||||||
|
parent.InvokeJuick(action, autoSend);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
84
Speak/Speak/Interop/Structs.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.Interop
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct COLORREF
|
||||||
|
{
|
||||||
|
public uint ColorDWORD;
|
||||||
|
|
||||||
|
public COLORREF(System.Drawing.Color color)
|
||||||
|
{
|
||||||
|
ColorDWORD = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
public System.Drawing.Color GetColor()
|
||||||
|
{
|
||||||
|
return System.Drawing.Color.FromArgb((int)(0x000000FFU & ColorDWORD),
|
||||||
|
(int)(0x0000FF00U & ColorDWORD) >> 8, (int)(0x00FF0000U & ColorDWORD) >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetColor(System.Drawing.Color color)
|
||||||
|
{
|
||||||
|
ColorDWORD = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RECT
|
||||||
|
{
|
||||||
|
public int Left;
|
||||||
|
public int Top;
|
||||||
|
public int Right;
|
||||||
|
public int Bottom;
|
||||||
|
|
||||||
|
public RECT(int left, int top, int right, int bottom)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Top = top;
|
||||||
|
Right = right;
|
||||||
|
Bottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RECT Empty
|
||||||
|
{
|
||||||
|
get { return new RECT(0,0,0,0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty
|
||||||
|
{
|
||||||
|
get { return (Left == Right) && (Top == Bottom) && (Right == Top) && (Bottom == 0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(RECT rect)
|
||||||
|
{
|
||||||
|
return Top == rect.Top && Bottom == rect.Bottom && Left == rect.Left && Right == rect.Right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct POINT
|
||||||
|
{
|
||||||
|
public int X;
|
||||||
|
public int Y;
|
||||||
|
|
||||||
|
public POINT(int x, int y)
|
||||||
|
{
|
||||||
|
this.X = x;
|
||||||
|
this.Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator System.Drawing.Point(POINT p)
|
||||||
|
{
|
||||||
|
return new System.Drawing.Point(p.X, p.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator POINT(System.Drawing.Point p)
|
||||||
|
{
|
||||||
|
return new POINT(p.X, p.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
71
Speak/Speak/Interop/Subclassing.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.Interop
|
||||||
|
{
|
||||||
|
public class Subclassing : IDisposable
|
||||||
|
{
|
||||||
|
private const int GWL_WNDPROC = -4;
|
||||||
|
|
||||||
|
[DllImport("user32", SetLastError = true)]
|
||||||
|
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);
|
||||||
|
[DllImport("user32", SetLastError = true)]
|
||||||
|
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newProc);
|
||||||
|
[DllImport("user32")]
|
||||||
|
private static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, int wParam, int lParam);
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern void SetLastError(uint dwErrCode);
|
||||||
|
|
||||||
|
private IntPtr wHandle;
|
||||||
|
private Win32WndProc wProc;
|
||||||
|
private IntPtr oldWndProc = IntPtr.Zero;
|
||||||
|
|
||||||
|
public Subclassing(IntPtr wHandle)
|
||||||
|
{
|
||||||
|
this.wHandle = wHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int StartSubclassing(Win32WndProc newWindowProc)
|
||||||
|
{
|
||||||
|
wProc = newWindowProc;
|
||||||
|
SetLastError(0);
|
||||||
|
if (oldWndProc != IntPtr.Zero)
|
||||||
|
SetWindowLong(wHandle, GWL_WNDPROC, wProc);
|
||||||
|
else
|
||||||
|
oldWndProc = SetWindowLong(wHandle, GWL_WNDPROC, wProc);
|
||||||
|
return Marshal.GetLastWin32Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CallParent(IntPtr hWnd, int Msg, int wParam, int lParam)
|
||||||
|
{
|
||||||
|
if (Msg == 0x02 || Msg == 0x10)
|
||||||
|
{
|
||||||
|
StopSubclass();
|
||||||
|
}
|
||||||
|
return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopSubclass()
|
||||||
|
{
|
||||||
|
if (wHandle != IntPtr.Zero && oldWndProc != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
SetWindowLong(wHandle, GWL_WNDPROC, oldWndProc);
|
||||||
|
wHandle = IntPtr.Zero;
|
||||||
|
wProc = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Implementation of IDisposable
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
StopSubclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate int Win32WndProc(IntPtr hWnd, int Msg, int wParam, int lParam);
|
||||||
|
}
|
356
Speak/Speak/Interop/WinApi.cs
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using Speak.Interfaces;
|
||||||
|
using Speak.RichEdit;
|
||||||
|
|
||||||
|
namespace Speak.Interop
|
||||||
|
{
|
||||||
|
internal class WinApi
|
||||||
|
{
|
||||||
|
public static int SMTO_ABORTIFHUNG = 0x2;
|
||||||
|
public static int WM_HTML_GETOBJECT = RegisterWindowMessage("WM_HTML_GETOBJECT");
|
||||||
|
public const int WM_USER = 0x0400;
|
||||||
|
public static int GWL_STYLE = -16;
|
||||||
|
public const int NM_CLICK = -2;
|
||||||
|
public const int WM_HSCROLL = -16;
|
||||||
|
public static IntPtr HWND_DESKTOP = IntPtr.Zero;
|
||||||
|
|
||||||
|
public const Int32 PSM_CHANGED = WM_USER + 104;
|
||||||
|
public const Int32 PSN_APPLY = ((0 - 200) - 2);
|
||||||
|
|
||||||
|
public const Int32 MK_CONTROL = 0x8;
|
||||||
|
|
||||||
|
public const int WM_MOUSEMOVE = 0x200;
|
||||||
|
public const int WM_LBUTTONDOWN = 0x201;
|
||||||
|
public const int WM_LBUTTONUP = 0x202;
|
||||||
|
public const int WM_RBUTTONDOWN = 0x204;
|
||||||
|
public const int WM_RBUTTONUP = 0x205;
|
||||||
|
public const int WM_MBUTTONDOWN = 0x207;
|
||||||
|
public const int WM_MBUTTONUP = 0x208;
|
||||||
|
public const int WM_LBUTTONDBLCLK = 0x203;
|
||||||
|
public const int WM_MBUTTONDBLCLK = 0x209;
|
||||||
|
public const int WM_RBUTTONDBLCLK = 0x206;
|
||||||
|
public const int WM_KEYUP = 0x101;
|
||||||
|
public const int WM_KEYDOWN = 0x100;
|
||||||
|
public const int WM_SYSKEYDOWN = 0x104;
|
||||||
|
|
||||||
|
public const int UM_CHECKSTATECHANGE = WM_USER + 100;
|
||||||
|
|
||||||
|
public const int WM_VSCROLL = 0x115;
|
||||||
|
public const int WM_UPDATE = 0x401;
|
||||||
|
public const int WM_RESIZE = 0x0085;
|
||||||
|
public const int WM_PAINT = 0x0F;
|
||||||
|
public const int WM_SETTEXT = 0xC;
|
||||||
|
public const int WM_NOTIFY = 0x4E;
|
||||||
|
public const int WM_GETTEXT = 13;
|
||||||
|
public const int WM_GETTEXTLENGTH = 14;
|
||||||
|
|
||||||
|
public const int WM_INITDIALOG = 0x0110;
|
||||||
|
public const int WM_COMMAND = 0x0111;
|
||||||
|
public const int WM_SETFOCUS = 0x0007;
|
||||||
|
|
||||||
|
public const int WM_DESTROY = 0x2;
|
||||||
|
|
||||||
|
public const int BM_GETCHECK = 0x00F0;
|
||||||
|
public const int BM_SETCHECK = 0x00F1;
|
||||||
|
public const int BST_UNCHECKED = 0;
|
||||||
|
public const int BST_CHECKED = 1;
|
||||||
|
public const int BST_INDETERMINATE = 2;
|
||||||
|
public const int BST_PUSHED = 4;
|
||||||
|
public const int BST_FOCUS = 8;
|
||||||
|
|
||||||
|
public const int CB_ADDSTRING = 0x0143;
|
||||||
|
public const int CB_SETCURSEL = 0x014E;
|
||||||
|
public const int CB_GETCURSEL = 0x0147;
|
||||||
|
public const int CB_GETLBTEXT = 0x0148;
|
||||||
|
public const int CB_SELECTSTRING = 0x014D;
|
||||||
|
|
||||||
|
public const int CB_GETLBTEXTLEN = 0x0149;
|
||||||
|
public const int CB_RESETCONTENT = 0x014B;
|
||||||
|
|
||||||
|
public const int CBN_SELCHANGE = 1;
|
||||||
|
|
||||||
|
public const int LVM_FIRST = 0x1000;
|
||||||
|
public const int LVM_INSERTITEM = LVM_FIRST + 7;
|
||||||
|
public const int LVIF_TEXT = 0x0001;
|
||||||
|
public const int LVIF_IMAGE = 0x0002;
|
||||||
|
public const int LVIF_PARAM = 0x0004;
|
||||||
|
public const int LVIF_INDENT = 0x0010;
|
||||||
|
|
||||||
|
public const int ILC_MASK = 0x0001;
|
||||||
|
public const int ILC_COLOR32 = 0x0020;
|
||||||
|
|
||||||
|
public const int BN_CLICKED = 0;
|
||||||
|
public const int EN_CHANGE = 0x300;
|
||||||
|
|
||||||
|
public const int STM_SETICON = 368;
|
||||||
|
public const uint ILD_NORMAL = 0;
|
||||||
|
public const int COLOR_WINDOW = 5; //http://msdn.microsoft.com/en-us/library/windows/desktop/ms724371(v=vs.85).aspx
|
||||||
|
public const int COLOR_WINDOWTEXT = 8;
|
||||||
|
public const int TBM_SETRANGE = WM_USER + 6;
|
||||||
|
public const int TBM_SETPOS = WM_USER + 5;
|
||||||
|
public const int TBM_GETPOS = WM_USER;
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern int GetSysColor(int XAmount);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int SendMessage(IntPtr hWnd, Int32 Msg, Int32 wParam, Int32 lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int SendMessage(IntPtr hWnd, Int32 Msg, Int64 wParam, Int64 lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int SendMessage(IntPtr hWnd, Int32 Msg, Int32 wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int SendMessage(IntPtr hWnd, Int32 Msg, Int32 wParam, ref POINTL lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "SendMessageA", /*CharSet = CharSet.Auto, */SetLastError = true)]
|
||||||
|
public static extern int SendMessageA(IntPtr hwnd, int msg, int wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
public static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
public static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool ScrollWindow(IntPtr hWnd, int XAmount, int YAmount, IntPtr lpRect, IntPtr wpRect);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool DestroyIcon(int hIcon);
|
||||||
|
|
||||||
|
[DllImport("comctl32.dll")]
|
||||||
|
public static extern bool ImageList_Destroy(int himl);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "SendMessageTimeoutA")]
|
||||||
|
public static extern int SendMessageTimeout(IntPtr hwnd, int msg, int wParam, int lParam, int fuFlags, int uTimeout, out int lpdwResult);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
|
[DllImport("OLEACC.dll")]
|
||||||
|
public static extern int ObjectFromLresult(int lResult, ref Guid riid, int wParam, ref IHTMLDocument2 ppvObject);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", EntryPoint = "RegisterWindowMessageA")]
|
||||||
|
public static extern int RegisterWindowMessage(string lpString);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool ClientToScreen(IntPtr hwnd, ref POINT lpPoint);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool ScreenToClient(IntPtr hwnd, ref POINT lpPoint);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern Int32 SendDlgItemMessage(IntPtr hDlg, int nIDDlgItem, uint Msg, Int32 wParam, Int32 lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern Int32 SendDlgItemMessage(IntPtr hDlg, int nIDDlgItem, uint Msg, Int32 wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
|
||||||
|
|
||||||
|
[DllImport("comctl32.dll", SetLastError = true)]
|
||||||
|
public static extern IntPtr ImageList_Create(int cx, int cy, uint flags, int cInitial, int cGrow);
|
||||||
|
|
||||||
|
[DllImport("comctl32.dll", SetLastError = true)]
|
||||||
|
public static extern Int32 ImageList_ReplaceIcon(IntPtr imageList, Int32 iconIndex, IntPtr hIcon);
|
||||||
|
|
||||||
|
[DllImport("comctl32.dll", SetLastError = true)]
|
||||||
|
public static extern Int32 ImageList_GetIcon(IntPtr imageList, Int32 iconIndex, uint flags);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern uint GetMessagePos();
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern Int32 GetFocus();
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern Int32 SetFocus(IntPtr hWnd);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr GetParent(IntPtr hWnd);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
public static extern int MapWindowPoints(IntPtr hwndFrom, IntPtr hwndTo, ref POINT lpPoints, [MarshalAs(UnmanagedType.U4)] int cPoints);
|
||||||
|
|
||||||
|
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||||
|
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||||
|
|
||||||
|
[DllImport("user32")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
|
||||||
|
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
|
||||||
|
|
||||||
|
public static IntPtr MakeLParam(int wLow, int wHigh)
|
||||||
|
{
|
||||||
|
return (IntPtr)(((short)wHigh << 16) | (wLow & 0xffff));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static List<IntPtr> GetChildWindows(IntPtr parent)
|
||||||
|
{
|
||||||
|
List<IntPtr> result = new List<IntPtr>();
|
||||||
|
GCHandle listHandle = GCHandle.Alloc(result);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
EnumWindowProc childProc = EnumWindow;
|
||||||
|
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (listHandle.IsAllocated)
|
||||||
|
listHandle.Free();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetWindowName(IntPtr window)
|
||||||
|
{
|
||||||
|
StringBuilder className = new StringBuilder(100);
|
||||||
|
GetClassName(window, className, className.Capacity);
|
||||||
|
return className.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
|
||||||
|
{
|
||||||
|
GCHandle gch = GCHandle.FromIntPtr(pointer);
|
||||||
|
List<IntPtr> list = gch.Target as List<IntPtr>;
|
||||||
|
if (list == null)
|
||||||
|
{
|
||||||
|
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
|
||||||
|
}
|
||||||
|
list.Add(handle);
|
||||||
|
// You can modify this to check to see if you want to cancel the operation, then return a null here
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr GetLogWindow(IntPtr parent, string className)
|
||||||
|
{
|
||||||
|
List<IntPtr> childs = GetChildWindows(parent);
|
||||||
|
for (int i = 0, iCount = childs.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
System.Diagnostics.Debug.WriteLine("[" + childs[i].ToString("X") + "] " + GetWindowName(childs[i]));
|
||||||
|
#endif
|
||||||
|
if (GetWindowName(childs[i]).StartsWith(className))
|
||||||
|
return childs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sciver 2.8.1.1+ fix
|
||||||
|
public static IntPtr GetLogWindowByStyles(IntPtr parent, string className)
|
||||||
|
{
|
||||||
|
List<IntPtr> childs = GetChildWindows(parent);
|
||||||
|
for (int i = 0, iCount = childs.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (GetWindowName(childs[i]).StartsWith(className))
|
||||||
|
{
|
||||||
|
Int32 exStyles = GetWindowLong(childs[i], GWL_STYLE);
|
||||||
|
if (exStyles != 0 && ((exStyles & REConstants.ES_READONLY) != 0) && ((exStyles & REConstants.ES_AUTOVSCROLL) != 0))
|
||||||
|
return childs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct NMHDR
|
||||||
|
{
|
||||||
|
public IntPtr handleFrom;
|
||||||
|
public Int32 idFrom;
|
||||||
|
public Int32 code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct WindowShowStyle
|
||||||
|
{
|
||||||
|
/// <summary>Hides the window and activates another window.</summary>
|
||||||
|
public const Int32 SW_HIDE = 0;
|
||||||
|
|
||||||
|
/// <summary>Activates and displays a window. If the window is minimized
|
||||||
|
/// or maximized, the system restores it to its original size and
|
||||||
|
/// position. An application should specify this flag when displaying
|
||||||
|
/// the window for the first time.</summary>
|
||||||
|
public const Int32 SW_SHOWNORMAL = 1;
|
||||||
|
|
||||||
|
/// <summary>Activates the window and displays it as a minimized window.</summary>
|
||||||
|
public const Int32 SW_SHOWMINIMIZED = 2;
|
||||||
|
|
||||||
|
/// <summary>Activates the window and displays it as a maximized window.</summary>
|
||||||
|
public const Int32 SW_SHOWMAXIMIZED = 3;
|
||||||
|
|
||||||
|
/// <summary>Maximizes the specified window.</summary>
|
||||||
|
public const Int32 SW_MAXIMIZE = 3;
|
||||||
|
|
||||||
|
/// <summary>Displays a window in its most recent size and position.
|
||||||
|
/// This value is similar to "ShowNormal", except the window is not
|
||||||
|
/// actived.</summary>
|
||||||
|
public const Int32 SW_SHOWNOACTIVATE = 4;
|
||||||
|
|
||||||
|
/// <summary>Activates the window and displays it in its current size
|
||||||
|
/// and position.</summary>
|
||||||
|
public const Int32 SW_SHOW = 5;
|
||||||
|
|
||||||
|
/// <summary>Minimizes the specified window and activates the next
|
||||||
|
/// top-level window in the Z order.</summary>
|
||||||
|
public const Int32 SW_MINIMIZE = 6;
|
||||||
|
|
||||||
|
/// <summary>Displays the window as a minimized window. This value is
|
||||||
|
/// similar to "ShowMinimized", except the window is not activated.</summary>
|
||||||
|
public const Int32 SW_SHOWMINNOACTIVE = 7;
|
||||||
|
|
||||||
|
/// <summary>Displays the window in its current size and position. This
|
||||||
|
/// value is similar to "Show", except the window is not activated.</summary>
|
||||||
|
public const Int32 SW_SHOWNA = 8;
|
||||||
|
|
||||||
|
/// <summary>Activates and displays the window. If the window is
|
||||||
|
/// minimized or maximized, the system restores it to its original size
|
||||||
|
/// and position. An application should specify this flag when restoring
|
||||||
|
/// a minimized window.</summary>
|
||||||
|
public const Int32 SW_RESTORE = 9;
|
||||||
|
|
||||||
|
/// <summary>Sets the show state based on the SW_ value specified in the
|
||||||
|
/// STARTUPINFO structure passed to the CreateProcess function by the
|
||||||
|
/// program that started the application.</summary>
|
||||||
|
/// <remarks>See SW_SHOWDEFAULT</remarks>
|
||||||
|
public const Int32 ShowDefault = 10;
|
||||||
|
|
||||||
|
/// <summary>Windows 2000/XP: Minimizes a window, even if the thread
|
||||||
|
/// that owns the window is hung. This flag should only be used when
|
||||||
|
/// minimizing windows from a different thread.</summary>
|
||||||
|
public const Int32 SW_FORCEMINIMIZE = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
interface IServiceProvider
|
||||||
|
{
|
||||||
|
void QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
|
||||||
|
}
|
||||||
|
}
|
230
Speak/Speak/MainClass.cs
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Virtuoso.Miranda.Plugins;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Virtuoso.Hyphen.Mini;
|
||||||
|
using Virtuoso.Hyphen.Mini.Custom;
|
||||||
|
using Virtuoso.Miranda.Plugins.ThirdParty.Updater;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak;
|
||||||
|
using Speak.Opt;
|
||||||
|
using Speak.Storage;
|
||||||
|
using Speak.TTS;
|
||||||
|
using Speak.Structs;
|
||||||
|
|
||||||
|
[assembly: ExposingPlugin(typeof(MainClass))]
|
||||||
|
|
||||||
|
namespace Speak
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// MainClass of Speak
|
||||||
|
/// </summary>
|
||||||
|
public class MainClass : StandalonePlugin
|
||||||
|
{
|
||||||
|
private Options option;
|
||||||
|
|
||||||
|
private MainClass()
|
||||||
|
{
|
||||||
|
this.option = new Options();
|
||||||
|
this.option.Changed += new Options.ChangedEventHandler(option_hasUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Run after the Plugin Initialisation
|
||||||
|
/// </summary>
|
||||||
|
protected override void AfterPluginInitialization()
|
||||||
|
{
|
||||||
|
option_hasUpdated(Options.EventChanged.Active);
|
||||||
|
option_hasUpdated(Options.EventChanged.Announce);
|
||||||
|
option_hasUpdated(Options.EventChanged.Engine);
|
||||||
|
RegisterUpdate();
|
||||||
|
EventManager.CreateEventHook(API.ME_OPT_INITIALISE, this.option.Opts, this);
|
||||||
|
EventManager.CreateEventHook(API.ME_DB_EVENT_ADDED, Message, this);
|
||||||
|
EventManager.CreateEventHook(API.ME_DB_CONTACT_SETTINGCHANGED, StatusChange, this);
|
||||||
|
SpeakWelcome();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void BeforePluginDisable()
|
||||||
|
{
|
||||||
|
EventManager.RemoveEventHook(API.ME_OPT_INITIALISE, this);
|
||||||
|
EventManager.RemoveEventHook(API.ME_DB_EVENT_ADDED, this);
|
||||||
|
EventManager.RemoveEventHook(API.ME_DB_CONTACT_SETTINGCHANGED, this);
|
||||||
|
TextToSpeak.getInstance().Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int Message(UIntPtr wParam, IntPtr lParam)
|
||||||
|
{
|
||||||
|
DatabaseEventInfo d = DatabaseEventInfo.FromHandle(lParam);
|
||||||
|
if (d.Type == DatabaseEventType.Message && !((d.Flags & DatabaseEventProperties.Sent) == DatabaseEventProperties.Sent))
|
||||||
|
{
|
||||||
|
ContactInfo c = ContactInfo.FromHandle(d.GetContactHandle());
|
||||||
|
Settings s = Settings.getInstance();
|
||||||
|
if (s.canMessageRead(d.Data, c.UniqueID.ToString()))
|
||||||
|
{
|
||||||
|
TextToSpeak tts = TextToSpeak.getInstance();
|
||||||
|
string text = String.Format(s.getSpeakString(), c.DisplayName, d.Data);
|
||||||
|
string sig = text + d.Timestamp;
|
||||||
|
//MessageBox.Show(sig);
|
||||||
|
tts.speak(text, sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int StatusChange(UIntPtr wParam, IntPtr lParam)
|
||||||
|
{
|
||||||
|
ContactInfo c = ContactInfo.FromHandle(wParam);
|
||||||
|
if (c.UniqueID == null) //Unknown User (maybe myself)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Settings s = Settings.getInstance();
|
||||||
|
if (s.hasChangedStatus(c.UniqueID.ToString(), c.Status.ToString()))
|
||||||
|
{
|
||||||
|
if (s.canStatusRead(c.UniqueID.ToString()))
|
||||||
|
{
|
||||||
|
TextToSpeak tts = TextToSpeak.getInstance();
|
||||||
|
string text = String.Format(s.getStatusString(c.Status), c.DisplayName, c.Status.ToString());
|
||||||
|
tts.speak(text,"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void option_hasUpdated(Options.EventChanged e)
|
||||||
|
{
|
||||||
|
if (e == Options.EventChanged.Engine)
|
||||||
|
{
|
||||||
|
TextToSpeak tts = TextToSpeak.getInstance();
|
||||||
|
tts.setVoice(Options.readDBString("engine", "speak_config"));
|
||||||
|
tts.setVolume(int.Parse(Options.readDBLong("volume", "speak_config").ToString()));
|
||||||
|
tts.setRate(int.Parse(Options.readDBLong("rate", "speak_config").ToString()));
|
||||||
|
tts.setPitch(int.Parse(Options.readDBLong("pitch", "speak_config").ToString()));
|
||||||
|
}
|
||||||
|
if (e == Options.EventChanged.Active)
|
||||||
|
{
|
||||||
|
Settings s = Settings.getInstance();
|
||||||
|
s.ReadContactList();
|
||||||
|
}
|
||||||
|
if (e == Options.EventChanged.Announce)
|
||||||
|
{
|
||||||
|
Settings s = Settings.getInstance();
|
||||||
|
s.SetGlobalSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SpeakWelcome()
|
||||||
|
{
|
||||||
|
TextToSpeak tts = TextToSpeak.getInstance();
|
||||||
|
tts.speak(Options.readDBString("welcome_msg", "speak_config"), "welcome" + DateTime.Now);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterUpdate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Update update = new Update(this, new Uri(this.HomePage.ToString() + "files/miranda/speak_last.zip"), new Uri(this.HomePage.ToString() + "files/miranda/speak_updater_version.txt"), " ");
|
||||||
|
UpdaterPlugin.RegisterForUpdate(update);
|
||||||
|
}
|
||||||
|
catch (NotSupportedException) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Constants
|
||||||
|
/// <summary>
|
||||||
|
/// Get Version
|
||||||
|
/// </summary>
|
||||||
|
private static Version VERSION = new Version(0, 8, 0, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get Author
|
||||||
|
/// </summary>
|
||||||
|
public override string Author
|
||||||
|
{
|
||||||
|
get { return "BlubbFish"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get Description
|
||||||
|
/// </summary>
|
||||||
|
public override string Description
|
||||||
|
{
|
||||||
|
get { return ".NET Speak Provider"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get HasOptions
|
||||||
|
/// </summary>
|
||||||
|
public override bool HasOptions
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get Hompage
|
||||||
|
/// </summary>
|
||||||
|
public override Uri HomePage
|
||||||
|
{
|
||||||
|
get { return new Uri("http://dev.blubbfish.net"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get Name
|
||||||
|
/// </summary>
|
||||||
|
public override string Name
|
||||||
|
{
|
||||||
|
get { return "Speak"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get Version
|
||||||
|
/// </summary>
|
||||||
|
public override Version Version
|
||||||
|
{
|
||||||
|
get { return VERSION; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get AutorEmail
|
||||||
|
/// </summary>
|
||||||
|
public override string AuthorEmail
|
||||||
|
{
|
||||||
|
get { return "dev@blubbfish.net"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get Copyright String
|
||||||
|
/// </summary>
|
||||||
|
public override string Copyright
|
||||||
|
{
|
||||||
|
get { return "2013 © BlubbFish"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get GUID PrluginInterfaces
|
||||||
|
/// </summary>
|
||||||
|
public override Guid[] PluginInterfaces
|
||||||
|
{
|
||||||
|
get { return new Guid[] { uuid }; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get ReplaceDefaultModule
|
||||||
|
/// </summary>
|
||||||
|
public override int ReplacesDefaultModule
|
||||||
|
{
|
||||||
|
get { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get GUID
|
||||||
|
/// </summary>
|
||||||
|
public override Guid UUID
|
||||||
|
{
|
||||||
|
get { return uuid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Guid uuid = new Guid("65BC8980-1028-40A4-A52F-440C48035E02");
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
967
Speak/Speak/Opt/Options.cs
Normal file
@ -0,0 +1,967 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enum of the Events
|
||||||
|
/// </summary>
|
||||||
|
public enum EventChanged
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// When A Usercontact has Changed
|
||||||
|
/// </summary>
|
||||||
|
Active,
|
||||||
|
/// <summary>
|
||||||
|
/// When the Global Settings Changed
|
||||||
|
/// </summary>
|
||||||
|
Announce,
|
||||||
|
/// <summary>
|
||||||
|
/// When the Engine Settings Changed
|
||||||
|
/// </summary>
|
||||||
|
Engine,
|
||||||
|
/// <summary>
|
||||||
|
/// No Events has Raised
|
||||||
|
/// </summary>
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delegate an Event of Changed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">Eventtype</param>
|
||||||
|
public delegate void ChangedEventHandler(EventChanged e);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises When Settings was Changed
|
||||||
|
/// </summary>
|
||||||
|
public event ChangedEventHandler Changed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal Raising for Event
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
protected virtual void OnChanged(EventChanged e)
|
||||||
|
{
|
||||||
|
if (Changed != null)
|
||||||
|
Changed(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Option Class that Handles the Optionsdialog
|
||||||
|
/// </summary>
|
||||||
|
public Options()
|
||||||
|
{
|
||||||
|
initImageLists();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initImageLists()
|
||||||
|
{
|
||||||
|
imagelistSpeak = createImageList(new List<string>() { StandartIcons.SKINICON_OTHER_SMALLDOT, StandartIcons.SKINICON_EVENT_MESSAGE, StandartIcons.ID_STATUS_ONLINE });
|
||||||
|
}
|
||||||
|
|
||||||
|
private Win32ImageList createImageList(List<string> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Here you Can Connect your Options
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wparam">Miranda Handle</param>
|
||||||
|
/// <param name="lparam"></param>
|
||||||
|
/// <returns>0</returns>
|
||||||
|
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<string> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read a boolean value from Miranda Databse
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
public static bool readDBBool(string name, string owner)
|
||||||
|
{
|
||||||
|
return readDBBool(name, owner, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read a boolean value from Mirana Database and if it not Present use standart
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
/// <param name="standart">Default Value</param>
|
||||||
|
public static bool readDBBool(string name, string owner, bool standart)
|
||||||
|
{
|
||||||
|
return readDBBool(name, owner, IntPtr.Zero, standart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read a value from Miranda Databse from specefic user and use a default value if not present
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
/// <param name="contact">Default value</param>
|
||||||
|
/// <param name="standart">Userhandle</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read a value from Miranda Database
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
/// <returns>Return 0 if not present</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read a value from Miranda Databse
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
/// <returns>Returns an empty String if not presend</returns>
|
||||||
|
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 "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a boolean value into Miranda Databse
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
/// <param name="value">Value</param>
|
||||||
|
public static bool writeDBBool(string name, string owner, bool value)
|
||||||
|
{
|
||||||
|
writeDBBool(name, owner, value, IntPtr.Zero);
|
||||||
|
return readDBBool(name, owner) == value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a boolean value into Miranda Database for specific user
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
/// <param name="value">Value</param>
|
||||||
|
/// <param name="contact">User handle</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a long value into Miranda Databse
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
/// <param name="value">long value</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write a string value into Miranda Databse
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name</param>
|
||||||
|
/// <param name="owner">Module</param>
|
||||||
|
/// <param name="value">string value</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
64
Speak/Speak/Opt/Win32ImageList.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text;
|
||||||
|
using Speak.Interop;
|
||||||
|
|
||||||
|
namespace Speak.Opt
|
||||||
|
{
|
||||||
|
internal class Win32ImageList
|
||||||
|
{
|
||||||
|
private IntPtr handle;
|
||||||
|
private Dictionary<string, int> icons;
|
||||||
|
private int defaultIndex;
|
||||||
|
private string defaultName;
|
||||||
|
|
||||||
|
public Win32ImageList() : this (16, 16, 0) { }
|
||||||
|
|
||||||
|
public Win32ImageList(int width, int height, int count)
|
||||||
|
{
|
||||||
|
handle = WinApi.ImageList_Create(width, height, WinApi.ILC_MASK | WinApi.ILC_COLOR32, count, 0);
|
||||||
|
icons = new Dictionary<string, int>();
|
||||||
|
defaultIndex = -1;
|
||||||
|
defaultName = "xJuick_Default";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int AddIcon(string iconKey, IntPtr hIcon)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
if (icons.ContainsKey(iconKey))
|
||||||
|
return icons[iconKey];
|
||||||
|
result = WinApi.ImageList_ReplaceIcon(handle, -1, hIcon);
|
||||||
|
|
||||||
|
if (result != -1)
|
||||||
|
{
|
||||||
|
icons.Add(iconKey, result);
|
||||||
|
if (defaultName.Equals(iconKey))
|
||||||
|
defaultIndex = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr Handle
|
||||||
|
{
|
||||||
|
get { return handle; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int this[string iconKey]
|
||||||
|
{
|
||||||
|
get { return icons.ContainsKey(iconKey) ? icons[iconKey] : defaultIndex; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Length
|
||||||
|
{
|
||||||
|
get { return icons.Count; }
|
||||||
|
}
|
||||||
|
public int GetIcon(string iconKey)
|
||||||
|
{
|
||||||
|
int icon = this.icons[iconKey];
|
||||||
|
return WinApi.ImageList_GetIcon(handle, icon, WinApi.ILD_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
Speak/Speak/Opt/dialog.res
Normal file
36
Speak/Speak/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||||
|
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||||
|
// die mit einer Assembly verknüpft sind.
|
||||||
|
[assembly: AssemblyTitle("Speak")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("Speak")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
|
||||||
|
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
|
||||||
|
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||||
|
[assembly: Guid("8661d35b-6865-4e4e-a32b-feb32a681897")]
|
||||||
|
|
||||||
|
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||||
|
//
|
||||||
|
// Hauptversion
|
||||||
|
// Nebenversion
|
||||||
|
// Buildnummer
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||||
|
// übernehmen, indem Sie "*" eingeben:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
93
Speak/Speak/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Dieser Code wurde von einem Tool generiert.
|
||||||
|
// Laufzeitversion:4.0.30319.18033
|
||||||
|
//
|
||||||
|
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||||
|
// der Code erneut generiert wird.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Speak.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||||
|
/// </summary>
|
||||||
|
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
||||||
|
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
||||||
|
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
||||||
|
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Speak.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
||||||
|
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Icon ähnlich wie (Symbol).
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Icon icon_message {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("icon_message", resourceCulture);
|
||||||
|
return ((System.Drawing.Icon)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Icon ähnlich wie (Symbol).
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Icon icon_small_dot {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("icon_small_dot", resourceCulture);
|
||||||
|
return ((System.Drawing.Icon)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Icon ähnlich wie (Symbol).
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Icon status_online {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("status_online", resourceCulture);
|
||||||
|
return ((System.Drawing.Icon)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
130
Speak/Speak/Properties/Resources.resx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<data name="icon_message" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\icon_message.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
<data name="icon_small_dot" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\icon_small_dot.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
<data name="status_online" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\status_online.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
BIN
Speak/Speak/Resources/icon_message.ico
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
Speak/Speak/Resources/icon_small_dot.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/Resources/status_online.ico
Normal file
After Width: | Height: | Size: 6.7 KiB |
349
Speak/Speak/RichEdit/ActionOleObject.cs
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Security.Permissions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.Structs;
|
||||||
|
using Speak.UI;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[Guid("49b0db79-a3d5-494f-be22-544286053dd9")]
|
||||||
|
internal class ActionOleObject : Control, IActionOleObject, IActionOleGUID
|
||||||
|
{
|
||||||
|
protected Color normalBackColor;
|
||||||
|
protected Color hoverBackColor;
|
||||||
|
protected Color hoverForeColor;
|
||||||
|
protected Color borderColor;
|
||||||
|
|
||||||
|
protected bool pressed;
|
||||||
|
protected bool onControl;
|
||||||
|
protected bool isTailObjectSet;
|
||||||
|
protected string text;
|
||||||
|
protected int iconWidth;
|
||||||
|
protected int iconHeight;
|
||||||
|
protected Size textSize;
|
||||||
|
|
||||||
|
protected TextFormatFlags textFormat;
|
||||||
|
protected HoverPart currentHover;
|
||||||
|
protected ActionWordType actionType;
|
||||||
|
protected ActionObjectType objectType;
|
||||||
|
|
||||||
|
protected enum HoverPart { None, MainWord, Icon }
|
||||||
|
public static readonly Guid Guid = new Guid("49b0db79-a3d5-494f-be22-544286053dd9");
|
||||||
|
|
||||||
|
public ActionOleObject()
|
||||||
|
{
|
||||||
|
//SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||||
|
this.SetStyle(ControlStyles.DoubleBuffer, true);
|
||||||
|
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||||
|
this.SetStyle(ControlStyles.UserPaint, true);
|
||||||
|
|
||||||
|
currentHover = HoverPart.None;
|
||||||
|
iconWidth = Properties.Resources.icon_small_dot.Width;
|
||||||
|
iconHeight = Properties.Resources.icon_small_dot.Height;
|
||||||
|
|
||||||
|
Width = 18;
|
||||||
|
Height = 18;
|
||||||
|
|
||||||
|
normalBackColor = Color.Green;
|
||||||
|
hoverBackColor = Color.White;
|
||||||
|
hoverForeColor = Color.Black;
|
||||||
|
borderColor = Color.Black;
|
||||||
|
BackColor = normalBackColor;
|
||||||
|
|
||||||
|
text = String.Empty;
|
||||||
|
Text = "";
|
||||||
|
|
||||||
|
textFormat = new TextFormatFlags();
|
||||||
|
textFormat |= TextFormatFlags.Default ;
|
||||||
|
|
||||||
|
onControl = false;
|
||||||
|
actionType = ActionWordType.None;
|
||||||
|
objectType = ActionObjectType.Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoResize()
|
||||||
|
{
|
||||||
|
textSize = TextRenderer.MeasureText(Text, Font, Size, TextFormatFlags.Default);
|
||||||
|
Size = new Size(textSize.Width + iconWidth, iconHeight > textSize.Height ? iconHeight : textSize.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaint(PaintEventArgs e)
|
||||||
|
{
|
||||||
|
Graphics g = e.Graphics;
|
||||||
|
TextRenderer.DrawText(
|
||||||
|
g, Text, Font,
|
||||||
|
onControl ? new Point(1, (Height - textSize.Height) / 2) : new Point(1, Height - textSize.Height),
|
||||||
|
onControl ? hoverForeColor : ForeColor, TextFormatFlags.Default);
|
||||||
|
|
||||||
|
|
||||||
|
/*using (Bitmap bm = Properties.Resources.power)
|
||||||
|
{
|
||||||
|
g.DrawImage(bm, Width - iconWidth, (Height - iconHeight) / 2 + 1);
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaintBackground(PaintEventArgs pevent)
|
||||||
|
{
|
||||||
|
Graphics g = pevent.Graphics;
|
||||||
|
Rectangle clip = pevent.ClipRectangle;
|
||||||
|
Rectangle activePart;
|
||||||
|
|
||||||
|
switch (currentHover)
|
||||||
|
{
|
||||||
|
case HoverPart.None:
|
||||||
|
base.OnPaintBackground(new PaintEventArgs(g, clip));
|
||||||
|
return;
|
||||||
|
case HoverPart.MainWord:
|
||||||
|
activePart = new Rectangle(0, 0, textSize.Width, Height - 1);
|
||||||
|
break;
|
||||||
|
case HoverPart.Icon:
|
||||||
|
activePart = new Rectangle(textSize.Width, 0, iconWidth - 1, Height - 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (SolidBrush b = new SolidBrush(BackColor))
|
||||||
|
{
|
||||||
|
g.FillRectangle(b, activePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (Pen p = new Pen(borderColor, 1.0f))
|
||||||
|
{
|
||||||
|
g.DrawRectangle(p, activePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle border = new Rectangle(clip.Location, new Size(clip.Width - 1, clip.Height - 1));
|
||||||
|
using (Pen p = new Pen(borderColor, 1.0f))
|
||||||
|
{
|
||||||
|
g.DrawRectangle(p, border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetHoverPart(int x, int y)
|
||||||
|
{
|
||||||
|
if (x > Left + (Width - iconWidth))
|
||||||
|
{
|
||||||
|
currentHover = HoverPart.Icon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentHover = HoverPart.MainWord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new private void Click(IntPtr richEditHwnd, Int32 topOffset)
|
||||||
|
{
|
||||||
|
switch (currentHover)
|
||||||
|
{
|
||||||
|
case HoverPart.None:
|
||||||
|
break;
|
||||||
|
case HoverPart.MainWord:
|
||||||
|
InvokeAction(text, Point.Empty);
|
||||||
|
break;
|
||||||
|
case HoverPart.Icon:
|
||||||
|
|
||||||
|
POINT pt = new POINT(Left, Top);
|
||||||
|
WinApi.ClientToScreen(richEditHwnd, ref pt);
|
||||||
|
|
||||||
|
InvokeAction(text, new Point(pt.X - Left + Width - iconWidth - (topOffset == Int32.MinValue ? 3 : -1), (topOffset != Int32.MinValue ? topOffset : 0) + pt.Y - Top - 7));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<ActionObjectClickEvent> ActionClicked;
|
||||||
|
private void InvokeAction(string action, Point menuLocation)
|
||||||
|
{
|
||||||
|
EventHandler<ActionObjectClickEvent> handler = ActionClicked;
|
||||||
|
if (handler != null) handler(this, new ActionObjectClickEvent(action, actionType, menuLocation));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guid GUID
|
||||||
|
{
|
||||||
|
get { return Guid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Implementation of IActionOleObject
|
||||||
|
|
||||||
|
public bool IsTailObjectSet
|
||||||
|
{
|
||||||
|
get { return isTailObjectSet; }
|
||||||
|
set { isTailObjectSet = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionObjectType ObjectType
|
||||||
|
{
|
||||||
|
get { return objectType; }
|
||||||
|
set { objectType = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionWordType ActionType
|
||||||
|
{
|
||||||
|
get { return actionType; }
|
||||||
|
set { actionType = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
new public int Bottom
|
||||||
|
{
|
||||||
|
set { Top = value - Height; }
|
||||||
|
get { return base.Bottom; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLMBDownState()
|
||||||
|
{
|
||||||
|
pressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLMBUpState(IntPtr hwnd, Int32 topOffset)
|
||||||
|
{
|
||||||
|
if (pressed)
|
||||||
|
{
|
||||||
|
pressed = false;
|
||||||
|
Click(hwnd, topOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MouseMoving(int x, int y)
|
||||||
|
{
|
||||||
|
bool isHover = HitTest(x, y);
|
||||||
|
|
||||||
|
if (isHover)
|
||||||
|
{
|
||||||
|
HoverPart oldHP = currentHover;
|
||||||
|
SetHoverPart(x, y);
|
||||||
|
if (!onControl)
|
||||||
|
{
|
||||||
|
BackColor = hoverBackColor;
|
||||||
|
onControl = true;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
else if (oldHP != currentHover)
|
||||||
|
{
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
Cursor.Current = Cursors.Hand;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (onControl)
|
||||||
|
{
|
||||||
|
currentHover = HoverPart.None;
|
||||||
|
BackColor = normalBackColor;
|
||||||
|
onControl = false;
|
||||||
|
pressed = false;
|
||||||
|
Invalidate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
new protected virtual void Invalidate()
|
||||||
|
{
|
||||||
|
base.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HitTest(int x, int y)
|
||||||
|
{
|
||||||
|
return x >= Left && x < (Left+Width) && y >= Top && y < base.Bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color BgColor
|
||||||
|
{
|
||||||
|
get { return normalBackColor; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != normalBackColor)
|
||||||
|
{
|
||||||
|
BackColor = normalBackColor = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new public string Text
|
||||||
|
{
|
||||||
|
get { return text; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.Text = value;
|
||||||
|
if (!text.Equals(value))
|
||||||
|
{
|
||||||
|
text = value;
|
||||||
|
DoResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum ActionObjectType
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Nick,
|
||||||
|
FirstNick
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ActionObjectClickEvent : EventArgs
|
||||||
|
{
|
||||||
|
private string actionText;
|
||||||
|
private Point menuLocation;
|
||||||
|
private ActionWordType actionType;
|
||||||
|
|
||||||
|
public ActionObjectClickEvent(string actionText, ActionWordType actionType, Point menuLocation)
|
||||||
|
{
|
||||||
|
this.actionText = actionText;
|
||||||
|
this.menuLocation = menuLocation;
|
||||||
|
this.actionType = actionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ActionText
|
||||||
|
{
|
||||||
|
get { return actionText; }
|
||||||
|
set { actionText = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point MenuLocation
|
||||||
|
{
|
||||||
|
get { return menuLocation; }
|
||||||
|
set { menuLocation = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionWordType ActionType
|
||||||
|
{
|
||||||
|
get { return actionType; }
|
||||||
|
set { actionType = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Guid("3289a6c9-b670-4840-b297-733372ab26b5")]
|
||||||
|
internal interface IActionOleObject
|
||||||
|
{
|
||||||
|
string Text { get; set; }
|
||||||
|
int Width { get; }
|
||||||
|
int Height { get; }
|
||||||
|
int Left { get; set; }
|
||||||
|
int Bottom { set; }
|
||||||
|
ActionObjectType ObjectType { get; set; }
|
||||||
|
bool IsTailObjectSet { get; set; }
|
||||||
|
bool HitTest(int x, int y);
|
||||||
|
void MouseMoving(int x, int y);
|
||||||
|
Color BgColor { get; set; }
|
||||||
|
void SetLMBDownState();
|
||||||
|
void SetLMBUpState(IntPtr richEditHwnd, Int32 topOffset);
|
||||||
|
|
||||||
|
ActionWordType ActionType { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal interface IActionOleGUID
|
||||||
|
{
|
||||||
|
Guid GUID { get; }
|
||||||
|
}
|
||||||
|
}
|
75
Speak/Speak/RichEdit/AvatarObject.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak.Core;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[Guid("a2c9c6c9-aa99-46bd-9f67-c3a8b38c5da2")]
|
||||||
|
internal class AvatarObject : Control, IActionOleGUID, IDisposable
|
||||||
|
{
|
||||||
|
protected Image image;
|
||||||
|
public static readonly Guid Guid = new Guid("a2c9c6c9-aa99-46bd-9f67-c3a8b38c5da2");
|
||||||
|
|
||||||
|
public AvatarObject(AvatarProcessor ap, string nick, Color bgColor)
|
||||||
|
{
|
||||||
|
SetStyle(ControlStyles.DoubleBuffer, true);
|
||||||
|
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||||
|
SetStyle(ControlStyles.UserPaint, true);
|
||||||
|
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||||
|
|
||||||
|
BackColor = bgColor;
|
||||||
|
string imagePath = ap.GetUserAvatar(nick, AvatarCallback);
|
||||||
|
if (!String.IsNullOrEmpty(imagePath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
image = Image.FromFile(imagePath);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
File.Delete(imagePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Width = Height = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void AvatarCallback(string userName, string avatarPath)
|
||||||
|
{
|
||||||
|
image = Image.FromFile(avatarPath);
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaint(PaintEventArgs e)
|
||||||
|
{
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
|
||||||
|
e.Graphics.DrawImage(image, 0, 0, Width, Height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base.OnPaint(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new protected virtual void Invalidate()
|
||||||
|
{
|
||||||
|
base.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guid GUID
|
||||||
|
{
|
||||||
|
get { return Guid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
new public void Dispose()
|
||||||
|
{
|
||||||
|
image = null;
|
||||||
|
base.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
927
Speak/Speak/RichEdit/IRichEditOle.cs
Normal file
@ -0,0 +1,927 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[Flags(), ComVisible(false)]
|
||||||
|
public enum STGM : int
|
||||||
|
{
|
||||||
|
STGM_DIRECT = 0x0,
|
||||||
|
STGM_TRANSACTED = 0x10000,
|
||||||
|
STGM_SIMPLE = 0x8000000,
|
||||||
|
STGM_READ = 0x0,
|
||||||
|
STGM_WRITE = 0x1,
|
||||||
|
STGM_READWRITE = 0x2,
|
||||||
|
STGM_SHARE_DENY_NONE = 0x40,
|
||||||
|
STGM_SHARE_DENY_READ = 0x30,
|
||||||
|
STGM_SHARE_DENY_WRITE = 0x20,
|
||||||
|
STGM_SHARE_EXCLUSIVE = 0x10,
|
||||||
|
STGM_PRIORITY = 0x40000,
|
||||||
|
STGM_DELETEONRELEASE = 0x4000000,
|
||||||
|
STGM_NOSCRATCH = 0x100000,
|
||||||
|
STGM_CREATE = 0x1000,
|
||||||
|
STGM_CONVERT = 0x20000,
|
||||||
|
STGM_FAILIFTHERE = 0x0,
|
||||||
|
STGM_NOSNAPSHOT = 0x200000,
|
||||||
|
}
|
||||||
|
|
||||||
|
// DVASPECT
|
||||||
|
[Flags(), ComVisible(false)]
|
||||||
|
public enum DVASPECT : int
|
||||||
|
{
|
||||||
|
DVASPECT_CONTENT = 1,
|
||||||
|
DVASPECT_THUMBNAIL = 2,
|
||||||
|
DVASPECT_ICON = 4,
|
||||||
|
DVASPECT_DOCPRINT = 8,
|
||||||
|
DVASPECT_OPAQUE = 16,
|
||||||
|
DVASPECT_TRANSPARENT = 32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLIPFORMAT
|
||||||
|
[ComVisible(false)]
|
||||||
|
public enum CLIPFORMAT : int
|
||||||
|
{
|
||||||
|
CF_TEXT = 1,
|
||||||
|
CF_BITMAP = 2,
|
||||||
|
CF_METAFILEPICT = 3,
|
||||||
|
CF_SYLK = 4,
|
||||||
|
CF_DIF = 5,
|
||||||
|
CF_TIFF = 6,
|
||||||
|
CF_OEMTEXT = 7,
|
||||||
|
CF_DIB = 8,
|
||||||
|
CF_PALETTE = 9,
|
||||||
|
CF_PENDATA = 10,
|
||||||
|
CF_RIFF = 11,
|
||||||
|
CF_WAVE = 12,
|
||||||
|
CF_UNICODETEXT = 13,
|
||||||
|
CF_ENHMETAFILE = 14,
|
||||||
|
CF_HDROP = 15,
|
||||||
|
CF_LOCALE = 16,
|
||||||
|
CF_MAX = 17,
|
||||||
|
CF_OWNERDISPLAY = 0x80,
|
||||||
|
CF_DSPTEXT = 0x81,
|
||||||
|
CF_DSPBITMAP = 0x82,
|
||||||
|
CF_DSPMETAFILEPICT = 0x83,
|
||||||
|
CF_DSPENHMETAFILE = 0x8E,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object flags
|
||||||
|
[Flags(), ComVisible(false)]
|
||||||
|
public enum REOOBJECTFLAGS : uint
|
||||||
|
{
|
||||||
|
REO_NULL = 0x00000000, // No flags
|
||||||
|
REO_READWRITEMASK = 0x0000003F, // Mask out RO bits
|
||||||
|
REO_DONTNEEDPALETTE = 0x00000020, // Object doesn't need palette
|
||||||
|
REO_BLANK = 0x00000010, // Object is blank
|
||||||
|
REO_DYNAMICSIZE = 0x00000008, // Object defines size always
|
||||||
|
REO_INVERTEDSELECT = 0x00000004, // Object drawn all inverted if sel
|
||||||
|
REO_BELOWBASELINE = 0x00000002, // Object sits below the baseline
|
||||||
|
REO_RESIZABLE = 0x00000001, // Object may be resized
|
||||||
|
REO_LINK = 0x80000000, // Object is a link (RO)
|
||||||
|
REO_STATIC = 0x40000000, // Object is static (RO)
|
||||||
|
REO_SELECTED = 0x08000000, // Object selected (RO)
|
||||||
|
REO_OPEN = 0x04000000, // Object open in its server (RO)
|
||||||
|
REO_INPLACEACTIVE = 0x02000000, // Object in place active (RO)
|
||||||
|
REO_HILITED = 0x01000000, // Object is to be hilited (RO)
|
||||||
|
REO_LINKAVAILABLE = 0x00800000, // Link believed available (RO)
|
||||||
|
REO_GETMETAFILE = 0x00400000 // Object requires metafile (RO)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OLERENDER
|
||||||
|
[ComVisible(false)]
|
||||||
|
public enum OLERENDER : int
|
||||||
|
{
|
||||||
|
OLERENDER_NONE = 0,
|
||||||
|
OLERENDER_DRAW = 1,
|
||||||
|
OLERENDER_FORMAT = 2,
|
||||||
|
OLERENDER_ASIS = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TYMED
|
||||||
|
[Flags(), ComVisible(false)]
|
||||||
|
public enum TYMED : int
|
||||||
|
{
|
||||||
|
TYMED_NULL = 0,
|
||||||
|
TYMED_HGLOBAL = 1,
|
||||||
|
TYMED_FILE = 2,
|
||||||
|
TYMED_ISTREAM = 4,
|
||||||
|
TYMED_ISTORAGE = 8,
|
||||||
|
TYMED_GDI = 16,
|
||||||
|
TYMED_MFPICT = 32,
|
||||||
|
TYMED_ENHMF = 64,
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential), ComVisible(false)]
|
||||||
|
public struct FORMATETC
|
||||||
|
{
|
||||||
|
public CLIPFORMAT cfFormat;
|
||||||
|
public IntPtr ptd;
|
||||||
|
public DVASPECT dwAspect;
|
||||||
|
public int lindex;
|
||||||
|
public TYMED tymed;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential), ComVisible(false)]
|
||||||
|
public struct STGMEDIUM
|
||||||
|
{
|
||||||
|
//[MarshalAs(UnmanagedType.I4)]
|
||||||
|
public int tymed;
|
||||||
|
public IntPtr unionmember;
|
||||||
|
public IntPtr pUnkForRelease;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true),
|
||||||
|
ComImport(),
|
||||||
|
Guid("00000103-0000-0000-C000-000000000046"),
|
||||||
|
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IEnumFORMATETC
|
||||||
|
{
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Next(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int celt,
|
||||||
|
[Out]
|
||||||
|
FORMATETC rgelt,
|
||||||
|
[In, Out, MarshalAs(UnmanagedType.LPArray)]
|
||||||
|
int[] pceltFetched);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Skip(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int celt);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Reset();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Clone(
|
||||||
|
[Out, MarshalAs(UnmanagedType.LPArray)]
|
||||||
|
IEnumFORMATETC[] ppenum);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true), StructLayout(LayoutKind.Sequential)]
|
||||||
|
public class COMRECT
|
||||||
|
{
|
||||||
|
public int left;
|
||||||
|
public int top;
|
||||||
|
public int right;
|
||||||
|
public int bottom;
|
||||||
|
|
||||||
|
public COMRECT()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public COMRECT(int left, int top, int right, int bottom)
|
||||||
|
{
|
||||||
|
this.left = left;
|
||||||
|
this.top = top;
|
||||||
|
this.right = right;
|
||||||
|
this.bottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMRECT FromXYWH(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
return new COMRECT(x, y, x + width, y + height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GETOBJECTOPTIONS
|
||||||
|
{
|
||||||
|
REO_GETOBJ_NO_INTERFACES = 0x00000000,
|
||||||
|
REO_GETOBJ_POLEOBJ = 0x00000001,
|
||||||
|
REO_GETOBJ_PSTG = 0x00000002,
|
||||||
|
REO_GETOBJ_POLESITE = 0x00000004,
|
||||||
|
REO_GETOBJ_ALL_INTERFACES = 0x00000007,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GETCLIPBOARDDATAFLAGS
|
||||||
|
{
|
||||||
|
RECO_PASTE = 0,
|
||||||
|
RECO_DROP = 1,
|
||||||
|
RECO_COPY = 2,
|
||||||
|
RECO_CUT = 3,
|
||||||
|
RECO_DRAG = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct CHARRANGE
|
||||||
|
{
|
||||||
|
public int cpMin;
|
||||||
|
public int cpMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public class REOBJECT
|
||||||
|
{
|
||||||
|
public int cbStruct = Marshal.SizeOf(typeof(REOBJECT)); // Size of structure
|
||||||
|
public int cp; // Character position of object
|
||||||
|
public Guid clsid; // Class ID of object
|
||||||
|
public IntPtr poleobj; // OLE object interface
|
||||||
|
public IStorage pstg; // Associated storage interface
|
||||||
|
public IOleClientSite polesite; // Associated client site interface
|
||||||
|
public Size sizel; // Size of object (may be 0,0)
|
||||||
|
public uint dvAspect; // Display aspect to use
|
||||||
|
public uint dwFlags; // Object status flags
|
||||||
|
public uint dwUser; // Dword for user's use
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true), Guid("0000010F-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IAdviseSink
|
||||||
|
{
|
||||||
|
|
||||||
|
//C#r: UNDONE (Field in interface) public static readonly Guid iid;
|
||||||
|
void OnDataChange(
|
||||||
|
[In]
|
||||||
|
FORMATETC pFormatetc,
|
||||||
|
[In]
|
||||||
|
STGMEDIUM pStgmed);
|
||||||
|
|
||||||
|
void OnViewChange(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwAspect,
|
||||||
|
[In, MarshalAs(UnmanagedType.I4)]
|
||||||
|
int lindex);
|
||||||
|
|
||||||
|
void OnRename(
|
||||||
|
[In, MarshalAs(UnmanagedType.Interface)]
|
||||||
|
object pmk);
|
||||||
|
|
||||||
|
void OnSave();
|
||||||
|
|
||||||
|
|
||||||
|
void OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(false), StructLayout(LayoutKind.Sequential)]
|
||||||
|
public sealed class STATDATA
|
||||||
|
{
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.U4)]
|
||||||
|
public int advf;
|
||||||
|
[MarshalAs(UnmanagedType.U4)]
|
||||||
|
public int dwConnection;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(false), StructLayout(LayoutKind.Sequential)]
|
||||||
|
public sealed class tagOLEVERB
|
||||||
|
{
|
||||||
|
[MarshalAs(UnmanagedType.I4)]
|
||||||
|
public int lVerb;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
public String lpszVerbName;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.U4)]
|
||||||
|
public int fuFlags;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.U4)]
|
||||||
|
public int grfAttribs;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true), ComImport(), Guid("00000104-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IEnumOLEVERB
|
||||||
|
{
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Next(
|
||||||
|
[MarshalAs(UnmanagedType.U4)]
|
||||||
|
int celt,
|
||||||
|
[Out]
|
||||||
|
tagOLEVERB rgelt,
|
||||||
|
[Out, MarshalAs(UnmanagedType.LPArray)]
|
||||||
|
int[] pceltFetched);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Skip(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int celt);
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
|
||||||
|
void Clone(
|
||||||
|
out IEnumOLEVERB ppenum);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true), Guid("00000105-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IEnumSTATDATA
|
||||||
|
{
|
||||||
|
|
||||||
|
//C#r: UNDONE (Field in interface) public static readonly Guid iid;
|
||||||
|
|
||||||
|
void Next(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int celt,
|
||||||
|
[Out]
|
||||||
|
STATDATA rgelt,
|
||||||
|
[Out, MarshalAs(UnmanagedType.LPArray)]
|
||||||
|
int[] pceltFetched);
|
||||||
|
|
||||||
|
|
||||||
|
void Skip(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int celt);
|
||||||
|
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
|
||||||
|
void Clone(
|
||||||
|
[Out, MarshalAs(UnmanagedType.LPArray)]
|
||||||
|
IEnumSTATDATA[] ppenum);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true), Guid("0000011B-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IOleContainer
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
void ParseDisplayName(
|
||||||
|
[In, MarshalAs(UnmanagedType.Interface)] object pbc,
|
||||||
|
[In, MarshalAs(UnmanagedType.BStr)] string pszDisplayName,
|
||||||
|
[Out, MarshalAs(UnmanagedType.LPArray)] int[] pchEaten,
|
||||||
|
[Out, MarshalAs(UnmanagedType.LPArray)] object[] ppmkOut);
|
||||||
|
|
||||||
|
|
||||||
|
void EnumObjects(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)] int grfFlags,
|
||||||
|
[Out, MarshalAs(UnmanagedType.LPArray)] object[] ppenum);
|
||||||
|
|
||||||
|
|
||||||
|
void LockContainer(
|
||||||
|
[In, MarshalAs(UnmanagedType.I4)] int fLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true),
|
||||||
|
ComImport(),
|
||||||
|
Guid("0000010E-0000-0000-C000-000000000046"),
|
||||||
|
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IDataObject
|
||||||
|
{
|
||||||
|
[PreserveSig()]
|
||||||
|
uint GetData(
|
||||||
|
ref FORMATETC a,
|
||||||
|
ref STGMEDIUM b);
|
||||||
|
|
||||||
|
[PreserveSig()]
|
||||||
|
uint GetDataHere(
|
||||||
|
ref FORMATETC pFormatetc,
|
||||||
|
out STGMEDIUM pMedium);
|
||||||
|
|
||||||
|
[PreserveSig()]
|
||||||
|
uint QueryGetData(
|
||||||
|
ref FORMATETC pFormatetc);
|
||||||
|
|
||||||
|
[PreserveSig()]
|
||||||
|
uint GetCanonicalFormatEtc(
|
||||||
|
ref FORMATETC pformatectIn,
|
||||||
|
out FORMATETC pformatetcOut);
|
||||||
|
|
||||||
|
[PreserveSig()]
|
||||||
|
uint SetData(
|
||||||
|
ref FORMATETC pFormatectIn,
|
||||||
|
ref STGMEDIUM pmedium,
|
||||||
|
[In, MarshalAs(UnmanagedType.Bool)]
|
||||||
|
bool fRelease);
|
||||||
|
|
||||||
|
[PreserveSig()]
|
||||||
|
uint EnumFormatEtc(
|
||||||
|
uint dwDirection, IEnumFORMATETC penum);
|
||||||
|
|
||||||
|
[PreserveSig()]
|
||||||
|
uint DAdvise(
|
||||||
|
ref FORMATETC pFormatetc,
|
||||||
|
int advf,
|
||||||
|
[In, MarshalAs(UnmanagedType.Interface)]
|
||||||
|
IAdviseSink pAdvSink,
|
||||||
|
out uint pdwConnection);
|
||||||
|
|
||||||
|
[PreserveSig()]
|
||||||
|
uint DUnadvise(
|
||||||
|
uint dwConnection);
|
||||||
|
|
||||||
|
[PreserveSig()]
|
||||||
|
uint EnumDAdvise(
|
||||||
|
[Out, MarshalAs(UnmanagedType.Interface)]
|
||||||
|
out IEnumSTATDATA ppenumAdvise);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true), Guid("00000118-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IOleClientSite
|
||||||
|
{
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SaveObject();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetMoniker(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)] int dwAssign,
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)] int dwWhichMoniker,
|
||||||
|
[Out, MarshalAs(UnmanagedType.Interface)] out object ppmk);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetContainer([MarshalAs(UnmanagedType.Interface)] out IOleContainer container);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int ShowObject();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int OnShowWindow(
|
||||||
|
[In, MarshalAs(UnmanagedType.I4)] int fShow);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int RequestNewObjectLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(false), StructLayout(LayoutKind.Sequential)]
|
||||||
|
public sealed class tagLOGPALETTE
|
||||||
|
{
|
||||||
|
[MarshalAs(UnmanagedType.U2)/*leftover(offset=0, palVersion)*/]
|
||||||
|
public short palVersion;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.U2)/*leftover(offset=2, palNumEntries)*/]
|
||||||
|
public short palNumEntries;
|
||||||
|
|
||||||
|
// UNMAPPABLE: palPalEntry: Cannot be used as a structure field.
|
||||||
|
// /** @com.structmap(UNMAPPABLE palPalEntry) */
|
||||||
|
// public UNMAPPABLE palPalEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComVisible(true), ComImport(), Guid("00000112-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IOleObject
|
||||||
|
{
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SetClientSite(
|
||||||
|
[In, MarshalAs(UnmanagedType.Interface)]
|
||||||
|
IOleClientSite pClientSite);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetClientSite(out IOleClientSite site);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SetHostNames(
|
||||||
|
[In, MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
string szContainerApp,
|
||||||
|
[In, MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
string szContainerObj);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Close(
|
||||||
|
[In, MarshalAs(UnmanagedType.I4)]
|
||||||
|
int dwSaveOption);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SetMoniker(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwWhichMoniker,
|
||||||
|
[In, MarshalAs(UnmanagedType.Interface)]
|
||||||
|
object pmk);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetMoniker(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwAssign,
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwWhichMoniker,
|
||||||
|
out object moniker);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int InitFromData(
|
||||||
|
[In, MarshalAs(UnmanagedType.Interface)]
|
||||||
|
IDataObject pDataObject,
|
||||||
|
[In, MarshalAs(UnmanagedType.I4)]
|
||||||
|
int fCreation,
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwReserved);
|
||||||
|
|
||||||
|
int GetClipboardData(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwReserved,
|
||||||
|
out IDataObject data);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int DoVerb(
|
||||||
|
[In, MarshalAs(UnmanagedType.I4)]
|
||||||
|
int iVerb,
|
||||||
|
[In]
|
||||||
|
IntPtr lpmsg,
|
||||||
|
[In, MarshalAs(UnmanagedType.Interface)]
|
||||||
|
IOleClientSite pActiveSite,
|
||||||
|
[In, MarshalAs(UnmanagedType.I4)]
|
||||||
|
int lindex,
|
||||||
|
[In]
|
||||||
|
IntPtr hwndParent,
|
||||||
|
[In]
|
||||||
|
COMRECT lprcPosRect);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int EnumVerbs(out IEnumOLEVERB e);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Update();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int IsUpToDate();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetUserClassID(
|
||||||
|
[In, Out]
|
||||||
|
ref Guid pClsid);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetUserType(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwFormOfType,
|
||||||
|
[Out, MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
out string userType);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SetExtent(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwDrawAspect,
|
||||||
|
[In]
|
||||||
|
Size pSizel);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetExtent(
|
||||||
|
[In, MarshalAs(UnmanagedType.U4)]
|
||||||
|
int dwDrawAspect,
|
||||||
|
[Out]
|
||||||
|
Size pSizel);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Advise([In, MarshalAs(UnmanagedType.Interface)] IAdviseSink pAdvSink, out int cookie);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int Unadvise([In, MarshalAs(UnmanagedType.U4)] int dwConnection);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int EnumAdvise(out IEnumSTATDATA e);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetMiscStatus([In, MarshalAs(UnmanagedType.U4)] int dwAspect, out int misc);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SetColorScheme([In] tagLOGPALETTE pLogpal);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[Guid("0000000d-0000-0000-C000-000000000046")]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IEnumSTATSTG
|
||||||
|
{
|
||||||
|
// The user needs to allocate an STATSTG array whose size is celt.
|
||||||
|
[PreserveSig]
|
||||||
|
uint
|
||||||
|
Next(
|
||||||
|
uint celt,
|
||||||
|
[MarshalAs(UnmanagedType.LPArray), Out]
|
||||||
|
System.Runtime.InteropServices.ComTypes.STATSTG[] rgelt,
|
||||||
|
out uint pceltFetched
|
||||||
|
);
|
||||||
|
|
||||||
|
void Skip(uint celt);
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.Interface)]
|
||||||
|
IEnumSTATSTG Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[Guid("0000000b-0000-0000-C000-000000000046")]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IStorage
|
||||||
|
{
|
||||||
|
int CreateStream(
|
||||||
|
/* [string][in] */ string pwcsName,
|
||||||
|
/* [in] */ uint grfMode,
|
||||||
|
/* [in] */ uint reserved1,
|
||||||
|
/* [in] */ uint reserved2,
|
||||||
|
/* [out] */ out IStream ppstm);
|
||||||
|
|
||||||
|
int OpenStream(
|
||||||
|
/* [string][in] */ string pwcsName,
|
||||||
|
/* [unique][in] */ IntPtr reserved1,
|
||||||
|
/* [in] */ uint grfMode,
|
||||||
|
/* [in] */ uint reserved2,
|
||||||
|
/* [out] */ out IStream ppstm);
|
||||||
|
|
||||||
|
int CreateStorage(
|
||||||
|
/* [string][in] */ string pwcsName,
|
||||||
|
/* [in] */ uint grfMode,
|
||||||
|
/* [in] */ uint reserved1,
|
||||||
|
/* [in] */ uint reserved2,
|
||||||
|
/* [out] */ out IStorage ppstg);
|
||||||
|
|
||||||
|
int OpenStorage(
|
||||||
|
/* [string][unique][in] */ string pwcsName,
|
||||||
|
/* [unique][in] */ IStorage pstgPriority,
|
||||||
|
/* [in] */ uint grfMode,
|
||||||
|
/* [unique][in] */ IntPtr snbExclude,
|
||||||
|
/* [in] */ uint reserved,
|
||||||
|
/* [out] */ out IStorage ppstg);
|
||||||
|
|
||||||
|
int CopyTo(
|
||||||
|
/* [in] */ uint ciidExclude,
|
||||||
|
/* [size_is][unique][in] */ Guid rgiidExclude,
|
||||||
|
/* [unique][in] */ IntPtr snbExclude,
|
||||||
|
/* [unique][in] */ IStorage pstgDest);
|
||||||
|
|
||||||
|
int MoveElementTo(
|
||||||
|
/* [string][in] */ string pwcsName,
|
||||||
|
/* [unique][in] */ IStorage pstgDest,
|
||||||
|
/* [string][in] */ string pwcsNewName,
|
||||||
|
/* [in] */ uint grfFlags);
|
||||||
|
|
||||||
|
int Commit(
|
||||||
|
/* [in] */ uint grfCommitFlags);
|
||||||
|
|
||||||
|
int Revert();
|
||||||
|
|
||||||
|
int EnumElements(
|
||||||
|
/* [in] */ uint reserved1,
|
||||||
|
/* [size_is][unique][in] */ IntPtr reserved2,
|
||||||
|
/* [in] */ uint reserved3,
|
||||||
|
/* [out] */ out IEnumSTATSTG ppenum);
|
||||||
|
|
||||||
|
int DestroyElement(
|
||||||
|
/* [string][in] */ string pwcsName);
|
||||||
|
|
||||||
|
int RenameElement(
|
||||||
|
/* [string][in] */ string pwcsOldName,
|
||||||
|
/* [string][in] */ string pwcsNewName);
|
||||||
|
|
||||||
|
int SetElementTimes(
|
||||||
|
/* [string][unique][in] */ string pwcsName,
|
||||||
|
/* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pctime,
|
||||||
|
/* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME patime,
|
||||||
|
/* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pmtime);
|
||||||
|
|
||||||
|
int SetClass(
|
||||||
|
/* [in] */ Guid clsid);
|
||||||
|
|
||||||
|
int SetStateBits(
|
||||||
|
/* [in] */ uint grfStateBits,
|
||||||
|
/* [in] */ uint grfMask);
|
||||||
|
|
||||||
|
int Stat(
|
||||||
|
/* [out] */ out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
|
||||||
|
/* [in] */ uint grfStatFlag);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[Guid("0000000a-0000-0000-C000-000000000046")]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface ILockBytes
|
||||||
|
{
|
||||||
|
int ReadAt(
|
||||||
|
/* [in] */ ulong ulOffset,
|
||||||
|
/* [unique][out] */ IntPtr pv,
|
||||||
|
/* [in] */ uint cb,
|
||||||
|
/* [out] */ out IntPtr pcbRead);
|
||||||
|
|
||||||
|
int WriteAt(
|
||||||
|
/* [in] */ ulong ulOffset,
|
||||||
|
/* [size_is][in] */ IntPtr pv,
|
||||||
|
/* [in] */ uint cb,
|
||||||
|
/* [out] */ out IntPtr pcbWritten);
|
||||||
|
|
||||||
|
int Flush();
|
||||||
|
|
||||||
|
int SetSize(
|
||||||
|
/* [in] */ ulong cb);
|
||||||
|
|
||||||
|
int LockRegion(
|
||||||
|
/* [in] */ ulong libOffset,
|
||||||
|
/* [in] */ ulong cb,
|
||||||
|
/* [in] */ uint dwLockType);
|
||||||
|
|
||||||
|
int UnlockRegion(
|
||||||
|
/* [in] */ ulong libOffset,
|
||||||
|
/* [in] */ ulong cb,
|
||||||
|
/* [in] */ uint dwLockType);
|
||||||
|
|
||||||
|
int Stat(
|
||||||
|
/* [out] */ out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
|
||||||
|
/* [in] */ uint grfStatFlag);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0c733a30-2a1c-11ce-ade5-00aa0044773d")]
|
||||||
|
public interface ISequentialStream
|
||||||
|
{
|
||||||
|
int Read(
|
||||||
|
/* [length_is][size_is][out] */ IntPtr pv,
|
||||||
|
/* [in] */ uint cb,
|
||||||
|
/* [out] */ out uint pcbRead);
|
||||||
|
|
||||||
|
int Write(
|
||||||
|
/* [size_is][in] */ IntPtr pv,
|
||||||
|
/* [in] */ uint cb,
|
||||||
|
/* [out] */ out uint pcbWritten);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[Guid("0000000c-0000-0000-C000-000000000046")]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IStream : ISequentialStream
|
||||||
|
{
|
||||||
|
int Seek(
|
||||||
|
/* [in] */ ulong dlibMove,
|
||||||
|
/* [in] */ uint dwOrigin,
|
||||||
|
/* [out] */ out ulong plibNewPosition);
|
||||||
|
|
||||||
|
int SetSize(
|
||||||
|
/* [in] */ ulong libNewSize);
|
||||||
|
|
||||||
|
int CopyTo(
|
||||||
|
/* [unique][in] */ [In] IStream pstm,
|
||||||
|
/* [in] */ ulong cb,
|
||||||
|
/* [out] */ out ulong pcbRead,
|
||||||
|
/* [out] */ out ulong pcbWritten);
|
||||||
|
|
||||||
|
int Commit(
|
||||||
|
/* [in] */ uint grfCommitFlags);
|
||||||
|
|
||||||
|
int Revert();
|
||||||
|
|
||||||
|
int LockRegion(
|
||||||
|
/* [in] */ ulong libOffset,
|
||||||
|
/* [in] */ ulong cb,
|
||||||
|
/* [in] */ uint dwLockType);
|
||||||
|
|
||||||
|
int UnlockRegion(
|
||||||
|
/* [in] */ ulong libOffset,
|
||||||
|
/* [in] */ ulong cb,
|
||||||
|
/* [in] */ uint dwLockType);
|
||||||
|
|
||||||
|
int Stat(
|
||||||
|
/* [out] */ out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
|
||||||
|
/* [in] */ uint grfStatFlag);
|
||||||
|
|
||||||
|
int Clone(
|
||||||
|
/* [out] */ out IStream ppstm);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Definition for interface IPersist.
|
||||||
|
/// </summary>
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000010c-0000-0000-C000-000000000046")]
|
||||||
|
public interface IPersist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// getClassID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pClassID"></param>
|
||||||
|
void GetClassID( /* [out] */ out Guid pClassID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Definition for interface IPersistStream.
|
||||||
|
/// </summary>
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000109-0000-0000-C000-000000000046")]
|
||||||
|
public interface IPersistStream : IPersist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// GetClassID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pClassID"></param>
|
||||||
|
new void GetClassID(out Guid pClassID);
|
||||||
|
/// <summary>
|
||||||
|
/// isDirty
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[PreserveSig]
|
||||||
|
int IsDirty();
|
||||||
|
/// <summary>
|
||||||
|
/// Load
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pStm"></param>
|
||||||
|
void Load([In] System.Runtime.InteropServices.ComTypes.IStream pStm);
|
||||||
|
/// <summary>
|
||||||
|
/// Save
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pStm"></param>
|
||||||
|
/// <param name="fClearDirty"></param>
|
||||||
|
void Save([In] System.Runtime.InteropServices.ComTypes.IStream pStm, [In, MarshalAs(UnmanagedType.Bool)] bool fClearDirty);
|
||||||
|
/// <summary>
|
||||||
|
/// GetSizeMax
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pcbSize"></param>
|
||||||
|
void GetSizeMax(out long pcbSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport(), Guid("00020D00-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IRichEditOle
|
||||||
|
{
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetClientSite(out IOleClientSite site);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetObjectCount();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetLinkCount();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetObject(int iob, [In, Out] REOBJECT lpreobject, [MarshalAs(UnmanagedType.U4)]GETOBJECTOPTIONS flags);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int InsertObject(REOBJECT lpreobject);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int ConvertObject(int iob, Guid rclsidNew, string lpstrUserTypeNew);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int ActivateAs(Guid rclsid, Guid rclsidAs);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SetHostNames(string lpstrContainerApp, string lpstrContainerObj);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SetLinkAvailable(int iob, bool fAvailable);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SetDvaspect(int iob, uint dvaspect);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int HandsOffStorage(int iob);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int SaveCompleted(int iob, IStorage lpstg);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int InPlaceDeactivate();
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int ContextSensitiveHelp(bool fEnterMode);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int GetClipboardData([In, Out] ref CHARRANGE lpchrg, [MarshalAs(UnmanagedType.U4)] GETCLIPBOARDDATAFLAGS reco, out IDataObject lplpdataobj);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.I4)]
|
||||||
|
[PreserveSig]
|
||||||
|
int ImportDataObject(IDataObject lpdataobj, int cf, IntPtr hMetaPict);
|
||||||
|
}
|
||||||
|
}
|
52
Speak/Speak/RichEdit/ITextDocument.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[ComImport]
|
||||||
|
[DefaultMember("Name")]
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[Guid("8CC497C0-A1DF-11CE-8098-00AA0047BE5D")]
|
||||||
|
[TypeLibType(TypeLibTypeFlags.FDispatchable | TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible)]
|
||||||
|
internal interface ITextDocument
|
||||||
|
{
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
ITextSelection Selection { get; }
|
||||||
|
|
||||||
|
int StoryCount { get; }
|
||||||
|
|
||||||
|
ITextStoryRanges StoryRanges { get; }
|
||||||
|
//void GetStoryRanges(ref IntPtr ppStories);
|
||||||
|
|
||||||
|
int Saved { get; set; }
|
||||||
|
|
||||||
|
float DefaultTabStop { get; set; }
|
||||||
|
|
||||||
|
void New();
|
||||||
|
|
||||||
|
void Open([In, MarshalAs(UnmanagedType.Struct)] ref object pVar, [In] int Flags, [In] int CodePage);
|
||||||
|
|
||||||
|
void Save([In, MarshalAs(UnmanagedType.Struct)] ref object pVar, [In] int Flags, [In] int CodePage);
|
||||||
|
|
||||||
|
int Freeze();
|
||||||
|
|
||||||
|
int Unfreeze();
|
||||||
|
|
||||||
|
void BeginEditCollection();
|
||||||
|
|
||||||
|
void EndEditCollection();
|
||||||
|
|
||||||
|
int Undo([In] int Count);
|
||||||
|
|
||||||
|
int Redo([In] int Count);
|
||||||
|
|
||||||
|
ITextRange Range([In] int cp1, [In] int cp2);
|
||||||
|
|
||||||
|
ITextRange RangeFromPoint([In] int x, [In] int y);
|
||||||
|
}
|
||||||
|
}
|
76
Speak/Speak/RichEdit/ITextFont.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[ComImport]
|
||||||
|
[DefaultMember("Duplicate")]
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[Guid("8CC497C3-A1DF-11CE-8098-00AA0047BE5D")]
|
||||||
|
[TypeLibType(TypeLibTypeFlags.FDispatchable | TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible)]
|
||||||
|
public interface ITextFont
|
||||||
|
{
|
||||||
|
ITextFont Duplicate { [return: MarshalAs(UnmanagedType.Interface)] get; set; }
|
||||||
|
|
||||||
|
int CanChange();
|
||||||
|
|
||||||
|
int IsEqual([In, MarshalAs(UnmanagedType.Interface)] ITextFont pFont);
|
||||||
|
|
||||||
|
void Reset([In] int Value);
|
||||||
|
|
||||||
|
int Style { get; set; }
|
||||||
|
|
||||||
|
int AllCaps { get; set; }
|
||||||
|
|
||||||
|
int Animation { get; set; }
|
||||||
|
|
||||||
|
int BackColor { get; set; }
|
||||||
|
|
||||||
|
int Bold { get; set; }
|
||||||
|
|
||||||
|
int Emboss { get; set; }
|
||||||
|
|
||||||
|
int ForeColor { get; set; }
|
||||||
|
|
||||||
|
int Hidden { get; set; }
|
||||||
|
|
||||||
|
int Engrave { get; set; }
|
||||||
|
|
||||||
|
int Italic { get; set; }
|
||||||
|
|
||||||
|
float Kerning { get; set; }
|
||||||
|
|
||||||
|
int LanguageID { get; set; }
|
||||||
|
|
||||||
|
string Name { get; set; }
|
||||||
|
|
||||||
|
int Outline { get; set; }
|
||||||
|
|
||||||
|
float Position { get; set; }
|
||||||
|
|
||||||
|
int Protected { get; set; }
|
||||||
|
|
||||||
|
int Shadow { get; set; }
|
||||||
|
|
||||||
|
float Size { get; set; }
|
||||||
|
|
||||||
|
int SmallCaps { get; set; }
|
||||||
|
|
||||||
|
float Spacing { get; set; }
|
||||||
|
|
||||||
|
int StrikeThrough { get; set; }
|
||||||
|
|
||||||
|
int Subscript { get; set; }
|
||||||
|
|
||||||
|
int Superscript { get; set; }
|
||||||
|
|
||||||
|
int Underline { get; set; }
|
||||||
|
|
||||||
|
int Weight { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
80
Speak/Speak/RichEdit/ITextPara.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[ComImport]
|
||||||
|
[DefaultMember("Duplicate")]
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[Guid("8CC497C4-A1DF-11CE-8098-00AA0047BE5D")]
|
||||||
|
[TypeLibType(TypeLibTypeFlags.FDispatchable | TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible)]
|
||||||
|
public interface ITextPara
|
||||||
|
{
|
||||||
|
ITextPara Duplicate { get; set; }
|
||||||
|
|
||||||
|
int CanChange();
|
||||||
|
|
||||||
|
int IsEqual([In, MarshalAs(UnmanagedType.Interface)] ITextPara pPara);
|
||||||
|
|
||||||
|
void Reset([In] int Value);
|
||||||
|
|
||||||
|
int Style { get; set; }
|
||||||
|
|
||||||
|
int Alignment { get; set; }
|
||||||
|
|
||||||
|
int Hyphenation { get; set; }
|
||||||
|
|
||||||
|
float FirstLineIndent { get; }
|
||||||
|
|
||||||
|
int KeepTogether { get; set; }
|
||||||
|
|
||||||
|
int KeepWithNext { get; set; }
|
||||||
|
|
||||||
|
float LeftIndent { get; }
|
||||||
|
|
||||||
|
float LineSpacing { get; }
|
||||||
|
|
||||||
|
int LineSpacingRule { get; }
|
||||||
|
|
||||||
|
int ListAlignment { get; set; }
|
||||||
|
|
||||||
|
int ListLevelIndex { get; set; }
|
||||||
|
|
||||||
|
int ListStart { get; set; }
|
||||||
|
|
||||||
|
float ListTab { get; set; }
|
||||||
|
|
||||||
|
int ListType { get; set; }
|
||||||
|
|
||||||
|
int NoLineNumber { get; set; }
|
||||||
|
|
||||||
|
int PageBreakBefore { get; set; }
|
||||||
|
|
||||||
|
float RightIndent { get; set; }
|
||||||
|
|
||||||
|
void SetIndents([In] float StartIndent, [In] float LeftIndent, [In] float RightIndent);
|
||||||
|
|
||||||
|
void SetLineSpacing([In] int LineSpacingRule, [In] float LineSpacing);
|
||||||
|
|
||||||
|
float SpaceAfter { get; set; }
|
||||||
|
|
||||||
|
float SpaceBefore { get; set; }
|
||||||
|
|
||||||
|
int WidowControl { get; set; }
|
||||||
|
|
||||||
|
int TabCount { get; }
|
||||||
|
|
||||||
|
void AddTab([In] float tbPos, [In] int tbAlign, [In] int tbLeader);
|
||||||
|
|
||||||
|
void ClearAllTabs();
|
||||||
|
|
||||||
|
void DeleteTab([In] float tbPos);
|
||||||
|
|
||||||
|
void GetTab([In] int iTab, out float ptbPos, out int ptbAlign, out int ptbLeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
108
Speak/Speak/RichEdit/ITextRange.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[ComImport]
|
||||||
|
[DefaultMember("Text")]
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[Guid("8CC497C2-A1DF-11CE-8098-00AA0047BE5D")]
|
||||||
|
[TypeLibType(TypeLibTypeFlags.FDispatchable | TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible)]
|
||||||
|
public interface ITextRange
|
||||||
|
{
|
||||||
|
string Text { get; set; }
|
||||||
|
|
||||||
|
int Char { get; set; }
|
||||||
|
|
||||||
|
ITextRange GetDuplicate();
|
||||||
|
|
||||||
|
ITextRange FormattedText { get; set; }
|
||||||
|
|
||||||
|
int Start { get; set; }
|
||||||
|
|
||||||
|
int End { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
ITextFont Font { get; set; }
|
||||||
|
|
||||||
|
ITextPara Para { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
int StoryLength { get; }
|
||||||
|
|
||||||
|
int StoryType { get; }
|
||||||
|
|
||||||
|
void Collapse([In] int bStart);
|
||||||
|
|
||||||
|
int Expand([In] int Unit);
|
||||||
|
|
||||||
|
int GetIndex([In] int Unit);
|
||||||
|
|
||||||
|
void SetIndex([In] int Unit, [In] int Index, [In] int Extend);
|
||||||
|
|
||||||
|
void SetRange([In] int cpActive, [In] int cpOther);
|
||||||
|
|
||||||
|
int InRange([In, MarshalAs(UnmanagedType.Interface)] ITextRange pRange);
|
||||||
|
|
||||||
|
int InStory([In, MarshalAs(UnmanagedType.Interface)] ITextRange pRange);
|
||||||
|
|
||||||
|
int IsEqual([In, MarshalAs(UnmanagedType.Interface)] ITextRange pRange);
|
||||||
|
|
||||||
|
void Select();
|
||||||
|
|
||||||
|
int StartOf([In] int Unit, [In] int Extend);
|
||||||
|
|
||||||
|
int EndOf([In] int Unit, [In] int Extend);
|
||||||
|
|
||||||
|
int Move([In] int Unit, [In] int Count);
|
||||||
|
|
||||||
|
int MoveStart([In] int Unit, [In] int Count);
|
||||||
|
|
||||||
|
int MoveEnd([In] int Unit, [In] int Count);
|
||||||
|
|
||||||
|
int MoveWhile([In, MarshalAs(UnmanagedType.Struct)] ref object Cset, [In] int Count);
|
||||||
|
|
||||||
|
int MoveStartWhile([In, MarshalAs(UnmanagedType.Struct)] ref object Cset, [In] int Count);
|
||||||
|
|
||||||
|
int MoveEndWhile([In, MarshalAs(UnmanagedType.Struct)] ref object Cset, [In] int Count);
|
||||||
|
|
||||||
|
int MoveUntil([In, MarshalAs(UnmanagedType.Struct)] ref object Cset, [In] int Count);
|
||||||
|
|
||||||
|
int MoveStartUntil([In, MarshalAs(UnmanagedType.Struct)] ref object Cset, [In] int Count);
|
||||||
|
|
||||||
|
int MoveEndUntil([In, MarshalAs(UnmanagedType.Struct)] ref object Cset, [In] int Count);
|
||||||
|
|
||||||
|
int FindText([In, MarshalAs(UnmanagedType.BStr)] string bstr, [In] int cch, [In] int Flags);
|
||||||
|
|
||||||
|
int FindTextStart([In, MarshalAs(UnmanagedType.BStr)] string bstr, [In] int cch, [In] int Flags);
|
||||||
|
|
||||||
|
int FindTextEnd([In, MarshalAs(UnmanagedType.BStr)] string bstr, [In] int cch, [In] int Flags);
|
||||||
|
|
||||||
|
int Delete([In] int Unit, [In] int Count);
|
||||||
|
|
||||||
|
void Cut([MarshalAs(UnmanagedType.Struct)] out object pVar);
|
||||||
|
|
||||||
|
void Copy([MarshalAs(UnmanagedType.Struct)] out object pVar);
|
||||||
|
|
||||||
|
void Paste([In, MarshalAs(UnmanagedType.Struct)] ref object pVar, [In] int Format);
|
||||||
|
|
||||||
|
int CanPaste([In, MarshalAs(UnmanagedType.Struct)] ref object pVar, [In] int Format);
|
||||||
|
|
||||||
|
int CanEdit();
|
||||||
|
|
||||||
|
void ChangeCase([In] int Type);
|
||||||
|
|
||||||
|
void GetPoint([In] int Type, out int px, out int py);
|
||||||
|
|
||||||
|
void SetPoint([In] int x, [In] int y, [In] int Type, [In] int Extend);
|
||||||
|
|
||||||
|
void ScrollIntoView([In] int Value);
|
||||||
|
|
||||||
|
[return: MarshalAs(UnmanagedType.IUnknown)]
|
||||||
|
object GetEmbeddedObject();
|
||||||
|
}
|
||||||
|
}
|
35
Speak/Speak/RichEdit/ITextSelection.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[ComImport]
|
||||||
|
[DefaultMember("Text")]
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[Guid("8CC497C1-A1DF-11CE-8098-00AA0047BE5D")]
|
||||||
|
[TypeLibType(TypeLibTypeFlags.FDispatchable | TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible)]
|
||||||
|
public interface ITextSelection : ITextRange
|
||||||
|
{
|
||||||
|
int Flags { get; set; }
|
||||||
|
|
||||||
|
int Type { get; }
|
||||||
|
|
||||||
|
int MoveLeft([In] int Unit, [In] int Count, [In] int Extend);
|
||||||
|
|
||||||
|
int MoveRight([In] int Unit, [In] int Count, [In] int Extend);
|
||||||
|
|
||||||
|
int MoveUp([In] int Unit, [In] int Count, [In] int Extend);
|
||||||
|
|
||||||
|
int MoveDown([In] int Unit, [In] int Count, [In] int Extend);
|
||||||
|
|
||||||
|
int HomeKey([In] int Unit, [In] int Extend);
|
||||||
|
|
||||||
|
int EndKey([In] int Unit, [In] int Extend);
|
||||||
|
|
||||||
|
void TypeText([In, MarshalAs(UnmanagedType.BStr)] string bstr);
|
||||||
|
}
|
||||||
|
}
|
22
Speak/Speak/RichEdit/ITextStoryRanges.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[ComImport]
|
||||||
|
[DefaultMember("Item")]
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[Guid("8CC497C5-A1DF-11CE-8098-00AA0047BE5D")]
|
||||||
|
public interface ITextStoryRanges : IEnumerable
|
||||||
|
{
|
||||||
|
[return: MarshalAs(UnmanagedType.Interface)]
|
||||||
|
ITextRange Item([In] int Index);
|
||||||
|
|
||||||
|
int Count { get; }
|
||||||
|
}
|
||||||
|
}
|
100
Speak/Speak/RichEdit/REConstants.cs
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
internal static class REConstants
|
||||||
|
{
|
||||||
|
public static Int32 ErrTransparentConst = -9999997;
|
||||||
|
|
||||||
|
public const int WM_USER = 0x0400;
|
||||||
|
public const int EM_STREAMIN = WM_USER + 73;
|
||||||
|
public const int EM_STREAMOUT = WM_USER + 74;
|
||||||
|
|
||||||
|
public static int SF_RTF = 0x02;
|
||||||
|
public static int SF_TEXT = 0x01;
|
||||||
|
public static int SF_UNICODE = 0x010;
|
||||||
|
|
||||||
|
public const int ES_READONLY = 0x800;
|
||||||
|
public const int ES_AUTOVSCROLL = 0x40;
|
||||||
|
|
||||||
|
public static int SCF_SELECTION = 0x0001;
|
||||||
|
public static int SCF_WORD = 0x0002;
|
||||||
|
public static int SCF_ALL = 0x0004;
|
||||||
|
|
||||||
|
public static UInt32 CFM_LINK = 0x00000020;
|
||||||
|
public static UInt32 CFE_LINK = 0x0020;
|
||||||
|
|
||||||
|
public static int EM_GETLINE = 0xC4;
|
||||||
|
public static int EM_LINELENGTH = 0xC1;
|
||||||
|
public static int EM_POSFROMCHAR = 0xD6;
|
||||||
|
public static int EM_GETTEXTRANGE = 0x44;
|
||||||
|
public const int EM_GETCHARFORMAT = WM_USER + 58;
|
||||||
|
public static int EM_SETCHARFORMAT = WM_USER + 68;
|
||||||
|
public static int EM_HIDESELECTION = 0x43F;
|
||||||
|
|
||||||
|
public const int EM_CHARFROMPOS = 0x0D7;
|
||||||
|
public static int EM_LINEINDEX = 0x0BB;
|
||||||
|
public static int EM_EXLINEFROMCHAR = WM_USER + 54;
|
||||||
|
|
||||||
|
public static int EM_GETOLEINTERFACE = WM_USER + 60;
|
||||||
|
public static int EM_SETREADONLY = 0x00CF;
|
||||||
|
|
||||||
|
public static int TomStart = 0x20;
|
||||||
|
public static int TomEnd = 0;
|
||||||
|
public static int TA_TOP = 0;
|
||||||
|
public static int TA_BOTTOM = 8;
|
||||||
|
public static int TA_LEFT = 0;
|
||||||
|
public static int TA_RIGHT = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate UInt32 EditStreamCallback(IntPtr dwCookie, IntPtr pbBuff, Int32 cb, out IntPtr pcb);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct EditStream
|
||||||
|
{
|
||||||
|
public IntPtr dwCookie;
|
||||||
|
public UInt32 dwError;
|
||||||
|
public EditStreamCallback pfnCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct CHARFORMAT2_STRUCT
|
||||||
|
{
|
||||||
|
public UInt32 cbSize;
|
||||||
|
public UInt32 dwMask;
|
||||||
|
public UInt32 dwEffects;
|
||||||
|
public Int32 yHeight;
|
||||||
|
public Int32 yOffset;
|
||||||
|
public Int32 crTextColor;
|
||||||
|
public byte bCharSet;
|
||||||
|
public byte bPitchAndFamily;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public char[] szFaceName;
|
||||||
|
public UInt16 wWeight;
|
||||||
|
public UInt16 sSpacing;
|
||||||
|
public int crBackColor; // Color.ToArgb() -> Int32
|
||||||
|
public int lcid;
|
||||||
|
public int dwReserved;
|
||||||
|
public Int16 sStyle;
|
||||||
|
public Int16 wKerning;
|
||||||
|
public byte bUnderlineType;
|
||||||
|
public byte bAnimation;
|
||||||
|
public byte bRevAuthor;
|
||||||
|
public byte bReserved1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct POINTL
|
||||||
|
{
|
||||||
|
public POINTL(int x, int y)
|
||||||
|
{
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int x;
|
||||||
|
public int y;
|
||||||
|
}
|
||||||
|
}
|
656
Speak/Speak/RichEdit/RichEditHandler.cs
Normal file
@ -0,0 +1,656 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Virtuoso.Miranda.Plugins.Native;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.Sites;
|
||||||
|
using Speak.Structs;
|
||||||
|
using Speak.UI;
|
||||||
|
using Speak.Utils;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
[System.Runtime.InteropServices.GuidAttribute("1EC46826-B20F-4B93-830F-7ABC39F371CC")]
|
||||||
|
internal class RichEditHandler : IMessageProcessor
|
||||||
|
{
|
||||||
|
private IntPtr wHandle;
|
||||||
|
|
||||||
|
private IRichEditOle richEditOle;
|
||||||
|
private ITextDocument richEdit = null;
|
||||||
|
private IntPtr richEditPtr = IntPtr.Zero;
|
||||||
|
private IntPtr pRichEdit;
|
||||||
|
private IntPtr tmpPtr;
|
||||||
|
private ISite site;
|
||||||
|
|
||||||
|
private AvatarProcessor ap;
|
||||||
|
|
||||||
|
private SimpleWordAction srmmNickAction;
|
||||||
|
private SimpleWordAction srmmNumberAction;
|
||||||
|
|
||||||
|
private Subclassing subclass;
|
||||||
|
private ContextMenu context;
|
||||||
|
private List<ActionOleObject> btns = new List<ActionOleObject>();
|
||||||
|
private bool needRecalc;
|
||||||
|
|
||||||
|
private static Guid IID_ITextDocument = typeof(ITextDocument).GUID;
|
||||||
|
private static Guid IID_IOleObject = typeof(IOleObject).GUID;
|
||||||
|
|
||||||
|
public RichEditHandler(ISite site, IntPtr wHandle)
|
||||||
|
{
|
||||||
|
pRichEdit = IntPtr.Zero;
|
||||||
|
tmpPtr = IntPtr.Zero;
|
||||||
|
|
||||||
|
this.site = site;
|
||||||
|
this.wHandle = wHandle;
|
||||||
|
|
||||||
|
string errMessage = String.Empty;
|
||||||
|
tmpPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
|
||||||
|
Marshal.WriteIntPtr(tmpPtr, IntPtr.Zero);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
richEditOle = RichEditHelpers.SendMessage(this.wHandle, REConstants.EM_GETOLEINTERFACE, 0);
|
||||||
|
|
||||||
|
subclass = new Subclassing(this.wHandle);
|
||||||
|
int subResult = subclass.StartSubclassing(WndProc);
|
||||||
|
if (subResult != 0)
|
||||||
|
throw new Exception(
|
||||||
|
"Epic fail of RichView subclassing." + Environment.NewLine +
|
||||||
|
"ErrorCode: " + subResult.ToString() + Environment.NewLine +
|
||||||
|
"Message: " + new System.ComponentModel.Win32Exception(subResult).Message);
|
||||||
|
|
||||||
|
if (WinApi.SendMessage(this.wHandle, REConstants.EM_GETOLEINTERFACE, IntPtr.Zero, tmpPtr) != 0)
|
||||||
|
{
|
||||||
|
pRichEdit = Marshal.ReadIntPtr(tmpPtr);
|
||||||
|
if (pRichEdit != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Marshal.QueryInterface(pRichEdit, ref IID_ITextDocument, out richEditPtr);
|
||||||
|
|
||||||
|
richEdit = (ITextDocument)Marshal.GetTypedObjectForIUnknown(richEditPtr, typeof(ITextDocument));
|
||||||
|
if (richEdit == null)
|
||||||
|
errMessage = "Failed to get the object wrapper for the interface.";
|
||||||
|
}
|
||||||
|
catch (Exception ex) { errMessage = ex.Message; }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errMessage = "Failed to get the pRichEdit pointer.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) { errMessage = ex.Message; }
|
||||||
|
|
||||||
|
if (richEdit == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
"Cant connect to SRMM's RichEdit window." + Environment.NewLine +
|
||||||
|
"Links highlighting will be disabled" + Environment.NewLine + Environment.NewLine +
|
||||||
|
errMessage,
|
||||||
|
"[xJuick] SRMM init error",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
srmmNickAction = Settings.Instance.SRMMNickAction;
|
||||||
|
srmmNumberAction = Settings.Instance.SRMMNumberAction;
|
||||||
|
|
||||||
|
ap = new AvatarProcessor(site);
|
||||||
|
MakeContextMenu();
|
||||||
|
Routine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MakeContextMenu()
|
||||||
|
{
|
||||||
|
context = new ContextMenu();
|
||||||
|
foreach (LinkButton lb in Settings.Instance.SRMMLinkButtons)
|
||||||
|
{
|
||||||
|
if (!lb.Enabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ActionMenuItem mi = new ActionMenuItem(lb);
|
||||||
|
//mi.Image = IconTable.GetActionIcon(lb.IconName);
|
||||||
|
mi.Click += ActionMenuClick;
|
||||||
|
context.MenuItems.Add(mi);
|
||||||
|
}
|
||||||
|
ActionMenuItem contextAvatar = new ActionMenuItem(new LinkButton(String.Empty, String.Empty, false, LinkDisplayType.Image));
|
||||||
|
//contextAvatar.Image = Image.FromFile(ap.GetUserAvatar("xa0c", null));
|
||||||
|
context.MenuItems.Add(contextAvatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int WndProc(IntPtr hWnd, int Msg, int wParam, int lParam)
|
||||||
|
{
|
||||||
|
bool lmb = false;
|
||||||
|
switch (Msg)
|
||||||
|
{
|
||||||
|
case WinApi.WM_LBUTTONDBLCLK:
|
||||||
|
case WinApi.WM_LBUTTONDOWN:
|
||||||
|
case WinApi.WM_LBUTTONUP:
|
||||||
|
int x = Util.LoWord(lParam);
|
||||||
|
int y = Util.HiWord(lParam);
|
||||||
|
|
||||||
|
foreach (ActionOleObject btn in btns)
|
||||||
|
{
|
||||||
|
if (btn.HitTest(x, y))
|
||||||
|
{
|
||||||
|
if (Msg == WinApi.WM_LBUTTONDOWN)
|
||||||
|
{
|
||||||
|
btn.SetLMBDownState();
|
||||||
|
}
|
||||||
|
else if (Msg == WinApi.WM_LBUTTONUP)
|
||||||
|
{
|
||||||
|
btn.SetLMBUpState(hWnd, Int32.MinValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
lmb = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
if (!lmb)
|
||||||
|
result = subclass.CallParent(hWnd, Msg, wParam, lParam);
|
||||||
|
|
||||||
|
switch (Msg)
|
||||||
|
{
|
||||||
|
case WinApi.WM_MOUSEMOVE:
|
||||||
|
if (needRecalc)
|
||||||
|
{
|
||||||
|
SetActionObjectPosition();
|
||||||
|
needRecalc = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = Util.LoWord(lParam);
|
||||||
|
int y = Util.HiWord(lParam);
|
||||||
|
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
btns[i].MouseMoving(x, y);
|
||||||
|
|
||||||
|
if (((wParam & WinApi.MK_CONTROL) == WinApi.MK_CONTROL) && Settings.Instance.ShowPreview)
|
||||||
|
{
|
||||||
|
string url = GetCurrentURL(x, y);
|
||||||
|
if (!String.IsNullOrEmpty(url) /*&& ImagePreview.IsImage(url)*/)
|
||||||
|
{
|
||||||
|
POINT pt = new POINT(x,y);
|
||||||
|
WinApi.ClientToScreen(wHandle, ref pt);
|
||||||
|
ImagePreview.Show(pt.X, pt.Y+10, url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImagePreview.Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImagePreview.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case REConstants.EM_STREAMIN:
|
||||||
|
Routine();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WinApi.WM_SETTEXT:
|
||||||
|
string text = Marshal.PtrToStringAnsi(new IntPtr(lParam));
|
||||||
|
if (String.IsNullOrEmpty(text))
|
||||||
|
btns.Clear();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WinApi.WM_PAINT:
|
||||||
|
needRecalc = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MainConstants.WM_REMAKERICH:
|
||||||
|
Routine();
|
||||||
|
needRecalc = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SettingsChanged()
|
||||||
|
{
|
||||||
|
MakeContextMenu();
|
||||||
|
Avatars();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
// well... do nothing :)
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowThreads()
|
||||||
|
{
|
||||||
|
// not implemented :)
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Avatars()
|
||||||
|
{
|
||||||
|
bool readOnly = (WinApi.GetWindowLong(wHandle, WinApi.GWL_STYLE) & REConstants.ES_READONLY) != 0;
|
||||||
|
if (readOnly)
|
||||||
|
WinApi.SendMessage(wHandle, REConstants.EM_SETREADONLY, 0, 0);
|
||||||
|
|
||||||
|
if (!Settings.Instance.ShowAvatars)
|
||||||
|
DeleteAvatars();
|
||||||
|
else
|
||||||
|
ShowAvatars();
|
||||||
|
|
||||||
|
if (readOnly)
|
||||||
|
WinApi.SendMessage(wHandle, REConstants.EM_SETREADONLY, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetActionObjectPosition()
|
||||||
|
{
|
||||||
|
ITextRange range = richEdit.Range(0, Int32.MaxValue);
|
||||||
|
for (int i = 0, iCount = richEditOle.GetObjectCount(); i < iCount; i++)
|
||||||
|
{
|
||||||
|
REOBJECT reoObject = new REOBJECT();
|
||||||
|
if (richEditOle.GetObject(i, reoObject, GETOBJECTOPTIONS.REO_GETOBJ_POLEOBJ) == 0)
|
||||||
|
{
|
||||||
|
if (reoObject.clsid == ActionOleObject.Guid)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
range.SetRange(reoObject.cp, reoObject.cp);
|
||||||
|
range.GetPoint(REConstants.TomStart | REConstants.TA_LEFT | REConstants.TA_BOTTOM, out x, out y);
|
||||||
|
|
||||||
|
|
||||||
|
IntPtr iaolep;
|
||||||
|
Marshal.QueryInterface(reoObject.poleobj, ref IID_IOleObject, out iaolep);
|
||||||
|
|
||||||
|
IActionOleObject iao = (IActionOleObject)Marshal.GetTypedObjectForIUnknown(iaolep, typeof(IActionOleObject));
|
||||||
|
|
||||||
|
|
||||||
|
POINT stc = new POINT(x, y);
|
||||||
|
WinApi.ScreenToClient(wHandle, ref stc);
|
||||||
|
iao.Left = stc.X;
|
||||||
|
iao.Bottom = stc.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Routine()
|
||||||
|
{
|
||||||
|
bool readOnly = (WinApi.GetWindowLong(wHandle, WinApi.GWL_STYLE) & REConstants.ES_READONLY) != 0;
|
||||||
|
if (readOnly)
|
||||||
|
WinApi.SendMessage(wHandle, REConstants.EM_SETREADONLY, 0, 0);
|
||||||
|
|
||||||
|
richEdit.Freeze();
|
||||||
|
string text = richEdit.Range(0, Int32.MaxValue).Text;
|
||||||
|
|
||||||
|
// posts/comments
|
||||||
|
Match m = site.NumRegex.Match(text);
|
||||||
|
while (m.Success)
|
||||||
|
{
|
||||||
|
string victimWord = m.Groups["full"].Value;
|
||||||
|
ActionWordType actionWord = !String.IsNullOrEmpty(m.Groups["cmnt"].Value)
|
||||||
|
? ActionWordType.Comments
|
||||||
|
: ActionWordType.Post;
|
||||||
|
|
||||||
|
|
||||||
|
int selStart = text.IndexOf(victimWord);
|
||||||
|
bool correctID = true;
|
||||||
|
|
||||||
|
if (victimWord.Length < 3)
|
||||||
|
correctID = false;
|
||||||
|
|
||||||
|
// fucking urls
|
||||||
|
if (correctID && victimWord.Length < 5)
|
||||||
|
{
|
||||||
|
richEdit.Selection.Start = selStart;
|
||||||
|
richEdit.Selection.End = selStart+1;
|
||||||
|
CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
|
||||||
|
cf.cbSize = (UInt32) Marshal.SizeOf(cf);
|
||||||
|
cf.szFaceName = new char[32];
|
||||||
|
|
||||||
|
IntPtr wpar = new IntPtr(REConstants.SCF_SELECTION);
|
||||||
|
IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
|
||||||
|
Marshal.StructureToPtr(cf, lpar, false);
|
||||||
|
|
||||||
|
new IntPtr(WinApi.SendMessage(wHandle, REConstants.EM_GETCHARFORMAT, wpar, lpar));
|
||||||
|
|
||||||
|
cf = (CHARFORMAT2_STRUCT) Marshal.PtrToStructure(lpar, typeof (CHARFORMAT2_STRUCT));
|
||||||
|
|
||||||
|
if (
|
||||||
|
((cf.dwMask & REConstants.CFM_LINK) == REConstants.CFM_LINK) &&
|
||||||
|
((cf.dwEffects & REConstants.CFE_LINK) == REConstants.CFE_LINK)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
correctID = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.FreeCoTaskMem(lpar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (correctID)
|
||||||
|
{
|
||||||
|
AddActionObject(selStart, victimWord, actionWord);
|
||||||
|
text = richEdit.Range(0, Int32.MaxValue).Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
m = m.NextMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
// JIDs
|
||||||
|
m = Regexps.JidRegEx.Match(text);
|
||||||
|
while (m.Success)
|
||||||
|
{
|
||||||
|
string victimWord = m.Groups["name"].Value;
|
||||||
|
|
||||||
|
AddActionObject(text.IndexOf(victimWord), victimWord, ActionWordType.Nick);
|
||||||
|
text = richEdit.Range(0, Int32.MaxValue).Text;
|
||||||
|
|
||||||
|
m = m.NextMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @nicks
|
||||||
|
m = site.NameRegex.Match(text);
|
||||||
|
while (m.Success)
|
||||||
|
{
|
||||||
|
string victimWord = m.Groups["name"].Value;
|
||||||
|
ActionObjectType objectType = !String.IsNullOrEmpty(m.Groups["isFirst"].Value) ? ActionObjectType.FirstNick : ActionObjectType.Nick;
|
||||||
|
AddActionObject(text.IndexOf(victimWord), victimWord, ActionWordType.Nick, objectType);
|
||||||
|
text = richEdit.Range(0, Int32.MaxValue).Text;
|
||||||
|
|
||||||
|
m = m.NextMatch();
|
||||||
|
}
|
||||||
|
richEdit.Unfreeze();
|
||||||
|
|
||||||
|
// avatars
|
||||||
|
if (Settings.Instance.ShowAvatars)
|
||||||
|
ShowAvatars();
|
||||||
|
|
||||||
|
if (readOnly)
|
||||||
|
WinApi.SendMessage(wHandle, REConstants.EM_SETREADONLY, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteAvatars()
|
||||||
|
{
|
||||||
|
richEdit.Freeze();
|
||||||
|
for (int i = 0, iCount = richEditOle.GetObjectCount(); i < iCount; i++)
|
||||||
|
{
|
||||||
|
REOBJECT reoObject = new REOBJECT();
|
||||||
|
if (richEditOle.GetObject(i, reoObject, GETOBJECTOPTIONS.REO_GETOBJ_POLEOBJ) == 0)
|
||||||
|
{
|
||||||
|
if (reoObject.clsid == AvatarObject.Guid)
|
||||||
|
{
|
||||||
|
richEdit.Range(reoObject.cp, reoObject.cp + 2).Text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, iCount = btns.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if(btns[i].ObjectType == ActionObjectType.FirstNick)
|
||||||
|
btns[i].IsTailObjectSet = false;
|
||||||
|
}
|
||||||
|
richEdit.Unfreeze();
|
||||||
|
|
||||||
|
// well... Надо бы инвалидейт вместо скролла сделать, нр-но
|
||||||
|
//WinApi.SendMessage(wHandle, WinApi.WM_VSCROLL, 7, 0);
|
||||||
|
WinApi.SendMessage(wHandle, MainConstants.WM_REMAKERICH, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowAvatars()
|
||||||
|
{
|
||||||
|
richEdit.Freeze();
|
||||||
|
List<KeyValuePair<string, int>> avatars = new List<KeyValuePair<string, int>>();
|
||||||
|
//Int32 lastLine = -1;
|
||||||
|
for (int i = 0, iCount = richEditOle.GetObjectCount(); i < iCount; i++)
|
||||||
|
{
|
||||||
|
REOBJECT reoObject = new REOBJECT();
|
||||||
|
if (richEditOle.GetObject(i, reoObject, GETOBJECTOPTIONS.REO_GETOBJ_POLEOBJ) == 0)
|
||||||
|
{
|
||||||
|
if (reoObject.clsid == ActionOleObject.Guid)
|
||||||
|
{
|
||||||
|
IntPtr iaolep;
|
||||||
|
Marshal.QueryInterface(reoObject.poleobj, ref IID_IOleObject, out iaolep);
|
||||||
|
|
||||||
|
IActionOleObject iao = (IActionOleObject)Marshal.GetTypedObjectForIUnknown(iaolep, typeof(IActionOleObject));
|
||||||
|
if (!iao.IsTailObjectSet && iao.ObjectType == ActionObjectType.FirstNick)
|
||||||
|
{
|
||||||
|
int lineIndex = WinApi.SendMessage(wHandle, REConstants.EM_EXLINEFROMCHAR, 0, reoObject.cp);
|
||||||
|
// select for yourself
|
||||||
|
//int charOffset = reoObject.cp - WinApi.SendMessage(wHandle, REConstants.EM_LINEINDEX, lineIndex, 0);
|
||||||
|
//avatars.Add(new KeyValuePair<string, int>(iao.Text.Substring(1), reoObject.cp + avatars.Count - (lastLine != lineIndex ? charOffset : 0)));
|
||||||
|
avatars.Add(new KeyValuePair<string, int>(iao.Text.Substring(1), reoObject.cp + avatars.Count));
|
||||||
|
//lastLine = lineIndex;
|
||||||
|
iao.IsTailObjectSet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int offset = 0;
|
||||||
|
foreach (KeyValuePair<string, int> ava in avatars)
|
||||||
|
{
|
||||||
|
int index = offset + ava.Value;
|
||||||
|
richEdit.Selection.Start = index;
|
||||||
|
richEdit.Selection.End = index;
|
||||||
|
Color backColor = richEdit.Selection.Font.BackColor != REConstants.ErrTransparentConst ? ColorTranslator.FromWin32(richEdit.Selection.Font.BackColor) : LogWindow.SRMMBackColor;
|
||||||
|
|
||||||
|
RichEditHelpers.InsertControl(richEditOle, new AvatarObject(ap, ava.Key, backColor));
|
||||||
|
richEdit.Range(index + 1, index + 1).Text = " ";
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
ap.Process();
|
||||||
|
richEdit.Unfreeze();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ActionMenuClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
ActionMenuItem mi = (ActionMenuItem) sender;
|
||||||
|
InvokeJuick(new ActionClickEvent(mi.Action, mi.AutoSend));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void actionObject_JuickClicked(object sender, ActionObjectClickEvent e)
|
||||||
|
{
|
||||||
|
|
||||||
|
ActionWordType actionWord = e.ActionType;
|
||||||
|
if (e.MenuLocation != Point.Empty)
|
||||||
|
{
|
||||||
|
if (actionWord == ActionWordType.None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0, iCount = context.MenuItems.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
ActionMenuItem btn = (ActionMenuItem)context.MenuItems[i];
|
||||||
|
btn.MainWord = e.ActionText;
|
||||||
|
if (btn.DisplayType != LinkDisplayType.Always)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(btn.DisplayType == LinkDisplayType.Comments && actionWord != ActionWordType.Comments) ||
|
||||||
|
(btn.DisplayType == LinkDisplayType.Posts && actionWord != ActionWordType.Post) ||
|
||||||
|
(btn.DisplayType == LinkDisplayType.Nicks && actionWord != ActionWordType.Nick)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
btn.Visible = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btn.DisplayType == LinkDisplayType.Image)
|
||||||
|
{
|
||||||
|
if (Settings.Instance.ShowContextAvatars)
|
||||||
|
{
|
||||||
|
string avatarPath = ap.GetUserAvatar(btn.MainWord.Substring(1), null);
|
||||||
|
if (String.IsNullOrEmpty(avatarPath))
|
||||||
|
{
|
||||||
|
ap.Process();
|
||||||
|
btn.Visible = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btn.Image = Image.FromFile(avatarPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btn.Visible = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Match m = site.NumRegex.Match(btn.MainWord);
|
||||||
|
if (m.Success)
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrEmpty(m.Groups["cmnt"].Value))
|
||||||
|
{
|
||||||
|
btn.AdditionalWord = m.Groups["full"].Value;
|
||||||
|
btn.MainWord = m.Groups["post"].Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.Visible = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
context.Show(sender as Control, e.MenuLocation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (actionWord == ActionWordType.Nick)
|
||||||
|
InvokeJuick(new ActionClickEvent(srmmNickAction.Action.Replace("%NICK%", e.ActionText), srmmNickAction.Autosend));
|
||||||
|
else if (actionWord == ActionWordType.Post || actionWord == ActionWordType.Comments)
|
||||||
|
InvokeJuick(new ActionClickEvent(srmmNumberAction.Action.Replace("%NUMBER%", e.ActionText), srmmNumberAction.Autosend));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddActionObject(int selStart, string fullWord, ActionWordType actionType)
|
||||||
|
{
|
||||||
|
AddActionObject(selStart, fullWord, actionType, ActionObjectType.Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddActionObject(int selStart, string fullWord, ActionWordType actionType, ActionObjectType objectType)
|
||||||
|
{
|
||||||
|
richEdit.Selection.Start = selStart;
|
||||||
|
richEdit.Selection.End = selStart + fullWord.Length;
|
||||||
|
|
||||||
|
ActionOleObject aoo = new ActionOleObject();
|
||||||
|
aoo.ObjectType = objectType;
|
||||||
|
aoo.ActionType = actionType;
|
||||||
|
aoo.ActionClicked += actionObject_JuickClicked;
|
||||||
|
|
||||||
|
ITextFont font = richEdit.Selection.Font;
|
||||||
|
|
||||||
|
aoo.BgColor = font.BackColor != REConstants.ErrTransparentConst ? ColorTranslator.FromWin32(font.BackColor) : LogWindow.SRMMBackColor;
|
||||||
|
aoo.Font = new Font(font.Name, font.Size);
|
||||||
|
aoo.ForeColor = ColorTranslator.FromWin32(font.ForeColor);
|
||||||
|
aoo.Text = fullWord;
|
||||||
|
|
||||||
|
btns.Add(aoo);
|
||||||
|
RichEditHelpers.InsertControl(richEditOle, aoo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetCurrentURL(int x, int y)
|
||||||
|
{
|
||||||
|
POINTL pointl = new POINTL(x, y);
|
||||||
|
Subclassing.SetLastError(0);
|
||||||
|
int charIndex = WinApi.SendMessage(wHandle, REConstants.EM_CHARFROMPOS, 0, ref pointl);
|
||||||
|
int err = Marshal.GetLastWin32Error();
|
||||||
|
if (err != 0 && err != 6)
|
||||||
|
return String.Empty;
|
||||||
|
|
||||||
|
if (charIndex <= 0)
|
||||||
|
return null;
|
||||||
|
int lineIndex = WinApi.SendMessage(wHandle, REConstants.EM_EXLINEFROMCHAR, 0, charIndex);
|
||||||
|
int charOffset = charIndex - WinApi.SendMessage(wHandle, REConstants.EM_LINEINDEX, lineIndex, 0);
|
||||||
|
int len = WinApi.SendMessage(wHandle, REConstants.EM_LINELENGTH, charIndex, 0);
|
||||||
|
|
||||||
|
string line = richEdit.Range(charIndex - charOffset, (charIndex - charOffset) + len).Text;
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(line))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (charOffset == len)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
string result = String.Empty;
|
||||||
|
int i = charOffset - 1;
|
||||||
|
int j = charOffset - 1;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
while (i >= 0 && line[i] != ' ')
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
i = i + 1;
|
||||||
|
|
||||||
|
if (j == -1)
|
||||||
|
return null;
|
||||||
|
while (j < len && line[j] != ' ')
|
||||||
|
{
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < i)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
result = line.Substring(i, j - i).Trim();
|
||||||
|
if (result.IndexOf("http://") != -1)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { return String.Empty; }
|
||||||
|
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<ActionClickEvent> JuickClicked;
|
||||||
|
public void InvokeJuick(ActionClickEvent e)
|
||||||
|
{
|
||||||
|
EventHandler<ActionClickEvent> handler = JuickClicked;
|
||||||
|
if (handler != null) handler(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Implementation of IDisposable
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (pRichEdit != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.Release(pRichEdit);
|
||||||
|
pRichEdit = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpPtr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeCoTaskMem(tmpPtr);
|
||||||
|
tmpPtr = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (richEditPtr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.Release(richEditPtr);
|
||||||
|
richEditPtr = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (richEditOle != null)
|
||||||
|
{
|
||||||
|
richEditOle = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subclass != null)
|
||||||
|
{
|
||||||
|
subclass.StopSubclass();
|
||||||
|
subclass.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
richEdit = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
138
Speak/Speak/RichEdit/RichEditHelpers.cs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.Structs;
|
||||||
|
|
||||||
|
namespace Speak.RichEdit
|
||||||
|
{
|
||||||
|
internal static class RichEditHelpers
|
||||||
|
{
|
||||||
|
private static Guid IID_ITextDocument = typeof(ITextDocument).GUID;
|
||||||
|
private static Type TFVCNDATAType = typeof(TFVCNDATA_NMHDR);
|
||||||
|
private static Int32 TFVCNDATASize = Marshal.SizeOf(TFVCNDATAType);
|
||||||
|
|
||||||
|
[DllImport("ole32.dll", PreserveSig = false)]
|
||||||
|
public static extern int CreateILockBytesOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease, [Out] out ILockBytes ppLkbyt);
|
||||||
|
|
||||||
|
[DllImport("ole32.dll")]
|
||||||
|
public static extern int StgCreateDocfileOnILockBytes(ILockBytes plkbyt, uint grfMode, uint reserved, out IStorage ppstgOpen);
|
||||||
|
|
||||||
|
//public static int WM_USER = 0x0400;
|
||||||
|
//public static int EM_GETOLEINTERFACE = WM_USER + 60;
|
||||||
|
|
||||||
|
[DllImport("User32.dll", CharSet = CharSet.Auto, PreserveSig = false)]
|
||||||
|
public static extern IRichEditOle SendMessage(IntPtr hWnd, int message, int wParam);
|
||||||
|
|
||||||
|
public static void InsertControl(IRichEditOle richEditOle, IActionOleGUID control)
|
||||||
|
{
|
||||||
|
if (control == null || richEditOle == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ILockBytes pLockBytes;
|
||||||
|
CreateILockBytesOnHGlobal(IntPtr.Zero, true, out pLockBytes);
|
||||||
|
|
||||||
|
IOleClientSite pOleClientSite;
|
||||||
|
richEditOle.GetClientSite(out pOleClientSite);
|
||||||
|
|
||||||
|
REOBJECT reoObject = new REOBJECT();
|
||||||
|
|
||||||
|
reoObject.cp = -1;//REO_CP_SELECTION;
|
||||||
|
|
||||||
|
reoObject.clsid = control.GUID;
|
||||||
|
reoObject.poleobj = Marshal.GetIUnknownForObject(control);
|
||||||
|
reoObject.polesite = pOleClientSite;
|
||||||
|
reoObject.dvAspect = (uint)(DVASPECT.DVASPECT_CONTENT);
|
||||||
|
reoObject.dwFlags = (uint)(REOOBJECTFLAGS.REO_BELOWBASELINE | REOOBJECTFLAGS.REO_BLANK);
|
||||||
|
|
||||||
|
richEditOle.InsertObject(reoObject);
|
||||||
|
|
||||||
|
Marshal.ReleaseComObject(pLockBytes);
|
||||||
|
Marshal.ReleaseComObject(pOleClientSite);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ITextDocument GetIText(IntPtr handle)
|
||||||
|
{
|
||||||
|
IntPtr pRichEdit = IntPtr.Zero;
|
||||||
|
IntPtr tmpPtr = IntPtr.Zero;
|
||||||
|
IntPtr richEditPtr = IntPtr.Zero;
|
||||||
|
tmpPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
|
||||||
|
Marshal.WriteIntPtr(tmpPtr, IntPtr.Zero);
|
||||||
|
ITextDocument richEdit = null;
|
||||||
|
if (WinApi.SendMessage(handle, REConstants.EM_GETOLEINTERFACE, IntPtr.Zero, tmpPtr) != 0)
|
||||||
|
{
|
||||||
|
if ((pRichEdit = Marshal.ReadIntPtr(tmpPtr)) != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.QueryInterface(pRichEdit, ref IID_ITextDocument, out richEditPtr);
|
||||||
|
|
||||||
|
richEdit = (ITextDocument)Marshal.GetTypedObjectForIUnknown(richEditPtr, typeof(ITextDocument));
|
||||||
|
if (richEdit == null)
|
||||||
|
throw new Exception("Failed to get the object wrapper for the interface.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to get the pRichEdit pointer.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return richEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RichEditInfo GetRichEditInfo(IntPtr owner, IntPtr mainHandle)
|
||||||
|
{
|
||||||
|
TFVCNDATA_NMHDR mh = new TFVCNDATA_NMHDR();
|
||||||
|
mh.cbSize = TFVCNDATASize;
|
||||||
|
mh.handleFrom = owner;
|
||||||
|
mh.code = HppConstaints.NM_FIREVIEWCHANGE;
|
||||||
|
mh.bEvent = HppConstaints.FVCN_GETINFO;
|
||||||
|
mh.bAction = HppConstaints.FVCA_NONE;
|
||||||
|
mh.rcRect = new RECT(0, 0, 0, 0);
|
||||||
|
|
||||||
|
IntPtr cmd = Marshal.AllocHGlobal(TFVCNDATASize);
|
||||||
|
Marshal.StructureToPtr(mh, cmd, false);
|
||||||
|
|
||||||
|
WinApi.SendMessage(mainHandle, WinApi.WM_NOTIFY, owner, cmd);
|
||||||
|
|
||||||
|
mh = (TFVCNDATA_NMHDR)Marshal.PtrToStructure(cmd, TFVCNDATAType);
|
||||||
|
|
||||||
|
if (mh.bAction == HppConstaints.FVCA_INFO)
|
||||||
|
return new RichEditInfo(mh.rcRect, mh.clrBackground.GetColor());
|
||||||
|
|
||||||
|
return RichEditInfo.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class RichEditInfo
|
||||||
|
{
|
||||||
|
private RECT rect;
|
||||||
|
private Color bgColor;
|
||||||
|
|
||||||
|
public RichEditInfo(RECT rect, Color bgColor)
|
||||||
|
{
|
||||||
|
this.rect = rect;
|
||||||
|
this.bgColor = bgColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RichEditInfo Empty
|
||||||
|
{
|
||||||
|
get { return new RichEditInfo(RECT.Empty, Color.Empty);}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty
|
||||||
|
{
|
||||||
|
get { return rect.IsEmpty && bgColor.IsEmpty; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public RECT Rect
|
||||||
|
{
|
||||||
|
get { return rect; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color BgColor
|
||||||
|
{
|
||||||
|
get { return bgColor; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
83
Speak/Speak/Sites/BNWSite.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace Speak.Sites
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class BNWSite : ISite
|
||||||
|
{
|
||||||
|
private string name;
|
||||||
|
private string mainContact;
|
||||||
|
private string[] additionalContacts;
|
||||||
|
private static Regex numRegEx = new Regex(
|
||||||
|
"(?<full>(?<post>\\#[A-Z\\d]+)(?<cmnt>/[A-Z\\d]+)?)",
|
||||||
|
RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
private static Regex nameRegEx = new Regex(
|
||||||
|
"(?<name>\\B@\\w+[-_\\.\\w]*\\w+)(?<isFirst>\\:{1})?",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public BNWSite()
|
||||||
|
{
|
||||||
|
name = "BNW";
|
||||||
|
mainContact = "bnw.blasux.ru";
|
||||||
|
additionalContacts = new string[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ISite CreateDefaultInstance()
|
||||||
|
{
|
||||||
|
return new BNWSite();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region -=[ Avatars ]=-
|
||||||
|
public override string GetAvatarPath(string userName)
|
||||||
|
{
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public override Regex NumRegex
|
||||||
|
{
|
||||||
|
get { return numRegEx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public override Regex NameRegex
|
||||||
|
{
|
||||||
|
get { return nameRegEx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
set { name = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string MainContact
|
||||||
|
{
|
||||||
|
get { return mainContact; }
|
||||||
|
set { mainContact = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string[] AdditionalContacts
|
||||||
|
{
|
||||||
|
get { return additionalContacts; }
|
||||||
|
set { additionalContacts = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
Speak/Speak/Sites/ISite.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace Speak.Sites
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public abstract class ISite
|
||||||
|
{
|
||||||
|
public abstract ISite CreateDefaultInstance();
|
||||||
|
|
||||||
|
public abstract string GetAvatarPath(string userName);
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public abstract Regex NumRegex
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public abstract Regex NameRegex
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract string Name
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract string MainContact
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract string[] AdditionalContacts
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
Speak/Speak/Sites/JuickSite.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Speak.Core;
|
||||||
|
|
||||||
|
namespace Speak.Sites
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class JuickSite : ISite
|
||||||
|
{
|
||||||
|
private string name;
|
||||||
|
private string mainContact;
|
||||||
|
private string[] additionalContacts;
|
||||||
|
private static Regex numRegEx = new Regex(
|
||||||
|
"(?<full>(?<post>\\#\\d+)(?<cmnt>/\\d+)?)",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
private static Regex nameRegEx = new Regex(
|
||||||
|
"(?<name>\\B@\\w+[-_\\.\\w]*\\w+)(?<isFirst>\\:{1})?",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
public JuickSite()
|
||||||
|
{
|
||||||
|
name = "Juick";
|
||||||
|
mainContact = "juick@juick.com";
|
||||||
|
additionalContacts = new string[] {"jubo@nologin.ru"};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ISite CreateDefaultInstance()
|
||||||
|
{
|
||||||
|
return new JuickSite();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region -=[ Avatars ]=-
|
||||||
|
private static string ava32 = "http://i.juick.com/as/{0}.png";
|
||||||
|
//private static string ava96 = "http://i.juick.com/a/{0}.png";
|
||||||
|
private static string rss = "http://rss.juick.com/{0}/blog";
|
||||||
|
public override string GetAvatarPath(string userName)
|
||||||
|
{
|
||||||
|
string userUrl = String.Format(rss, userName);
|
||||||
|
string avatarUrl = String.Empty;
|
||||||
|
string rssContent = HTTP.StaticSendGet(userUrl);
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
doc.LoadXml(rssContent);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
XmlNodeList nodes = doc.GetElementsByTagName("image");
|
||||||
|
if (nodes == null || nodes.Count == 0)
|
||||||
|
return avatarUrl;
|
||||||
|
|
||||||
|
XmlNodeList childNodes = nodes[0].ChildNodes;
|
||||||
|
for (int i = 0, iCount = childNodes.Count; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (childNodes[i].Name.Equals("url", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
Match m = Regexps.UID.Match(childNodes[i].InnerXml);
|
||||||
|
if (m.Success)
|
||||||
|
avatarUrl = String.Format(ava32, m.Groups["uid"].Value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return avatarUrl;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public override Regex NumRegex
|
||||||
|
{
|
||||||
|
get { return numRegEx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public override Regex NameRegex
|
||||||
|
{
|
||||||
|
get { return nameRegEx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
set { name = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string MainContact
|
||||||
|
{
|
||||||
|
get { return mainContact; }
|
||||||
|
set { mainContact = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string[] AdditionalContacts
|
||||||
|
{
|
||||||
|
get { return additionalContacts; }
|
||||||
|
set { additionalContacts = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
102
Speak/Speak/Sites/PstoSite.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using Speak.Core;
|
||||||
|
|
||||||
|
namespace Speak.Sites
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class PstoSite : ISite
|
||||||
|
{
|
||||||
|
private string name;
|
||||||
|
private string mainContact;
|
||||||
|
private string[] additionalContacts;
|
||||||
|
private static Regex numRegEx = new Regex(
|
||||||
|
"(?<full>(?<post>\\#[A-Za-z\\d]+)(?<cmnt>/[\\d]+)?)",
|
||||||
|
RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
private static Regex nameRegEx = new Regex(
|
||||||
|
"(?<name>\\B@\\w+[-_\\.\\w]*\\w+)(?<isFirst>\\:{1}|\\ \\-\\>)?",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Multiline
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
private static Regex AvaIDRegEx = new Regex(
|
||||||
|
"src=\\\"/(?:.+?)/80/(?<avaID>\\d+)\\.png\\\"",
|
||||||
|
RegexOptions.IgnoreCase
|
||||||
|
| RegexOptions.Singleline
|
||||||
|
| RegexOptions.CultureInvariant
|
||||||
|
| RegexOptions.IgnorePatternWhitespace
|
||||||
|
| RegexOptions.Compiled
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public PstoSite()
|
||||||
|
{
|
||||||
|
name = "Psto";
|
||||||
|
mainContact = "psto@psto.net";
|
||||||
|
additionalContacts = new string[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ISite CreateDefaultInstance()
|
||||||
|
{
|
||||||
|
return new PstoSite();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region -=[ Avatars ]=-
|
||||||
|
private string userPageUrl = "http://{0}.psto.net";
|
||||||
|
private string avaUrl = "http://psto.net/img/a/40/{0}.png";
|
||||||
|
public override string GetAvatarPath(string userName)
|
||||||
|
{
|
||||||
|
string userUrl = String.Format(userPageUrl, userName);
|
||||||
|
string avatarUrl = String.Empty;
|
||||||
|
string userPageContent = HTTP.StaticSendGet(userUrl);
|
||||||
|
|
||||||
|
Match m = AvaIDRegEx.Match(userPageContent);
|
||||||
|
if (m.Success)
|
||||||
|
avatarUrl = String.Format(avaUrl, m.Groups["avaID"].Value);
|
||||||
|
|
||||||
|
return avatarUrl;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public override Regex NumRegex
|
||||||
|
{
|
||||||
|
get { return numRegEx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[XmlIgnore]
|
||||||
|
public override Regex NameRegex
|
||||||
|
{
|
||||||
|
get { return nameRegEx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
set { name = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string MainContact
|
||||||
|
{
|
||||||
|
get { return mainContact; }
|
||||||
|
set { mainContact = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string[] AdditionalContacts
|
||||||
|
{
|
||||||
|
get { return additionalContacts; }
|
||||||
|
set { additionalContacts = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
66
Speak/Speak/Sites/SitesManager.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Speak.Core;
|
||||||
|
|
||||||
|
namespace Speak.Sites
|
||||||
|
{
|
||||||
|
class SitesManager
|
||||||
|
{
|
||||||
|
public static Dictionary<string, ISite> Sites;
|
||||||
|
public static Dictionary<IntPtr, ISite> SitesInfo;
|
||||||
|
|
||||||
|
static SitesManager()
|
||||||
|
{
|
||||||
|
Sites = new Dictionary<string, ISite>();
|
||||||
|
SitesInfo = new Dictionary<IntPtr, ISite>();
|
||||||
|
|
||||||
|
ISite juick = new JuickSite();
|
||||||
|
Sites.Add(juick.Name, juick);
|
||||||
|
ISite bnw = new BNWSite();
|
||||||
|
Sites.Add(bnw.Name, bnw);
|
||||||
|
ISite psto = new PstoSite();
|
||||||
|
Sites.Add(psto.Name, psto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ISite CreateDefaultSiteInstance()
|
||||||
|
{
|
||||||
|
ISite site = new PstoSite();
|
||||||
|
site.AdditionalContacts = new string[0];
|
||||||
|
return site;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ISite GetContactSite(IntPtr hContact)
|
||||||
|
{
|
||||||
|
if (SitesInfo.ContainsKey(hContact))
|
||||||
|
return SitesInfo[hContact];
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ISite GetContactSite(string UID, bool searchInAdditional)
|
||||||
|
{
|
||||||
|
for (int i = 0, iCount = Settings.Instance.Sites.Length; i < iCount; i++)
|
||||||
|
{
|
||||||
|
if (UID.Equals(Settings.Instance.Sites[i].MainContact, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
return Settings.Instance.Sites[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!searchInAdditional)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
for (int j = 0, jCount = Settings.Instance.Sites[i].AdditionalContacts.Length; j < jCount; j++)
|
||||||
|
{
|
||||||
|
if (UID.Equals(Settings.Instance.Sites[i].AdditionalContacts[j], StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
return Settings.Instance.Sites[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
169
Speak/Speak/Speak.csproj
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{EC92954F-19E9-43D6-8871-09C651108FA9}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Speak</RootNamespace>
|
||||||
|
<AssemblyName>Speak.master</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>..\..\..\..\..\Desktop\Miranda\Plugins\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<DocumentationFile>..\..\..\..\..\Desktop\Miranda\Plugins\Speak.master.XML</DocumentationFile>
|
||||||
|
<NoWarn>1591</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>..\..\..\..\..\Desktop\Miranda\Plugins\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<DocumentationFile>..\..\..\..\..\Desktop\Miranda\Plugins\Speak.master.XML</DocumentationFile>
|
||||||
|
<NoWarn>1591</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<Win32Resource>C:\Users\netz\Documents\Visual Studio 2012\Projects\Speak\Speak\Opt\dialog.res</Win32Resource>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Hyphen">
|
||||||
|
<HintPath>..\..\..\..\..\Desktop\Miranda\Plugins\Hyphen.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Speech" />
|
||||||
|
<Reference Include="System.Web" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Core\ActionClickEvent.cs" />
|
||||||
|
<Compile Include="Core\ActionProcessor.cs" />
|
||||||
|
<Compile Include="Core\AvatarProcessor.cs" />
|
||||||
|
<Compile Include="Core\Buttons.cs" />
|
||||||
|
<Compile Include="Core\HTTP.cs" />
|
||||||
|
<Compile Include="Core\ImagePreview.cs" />
|
||||||
|
<Compile Include="Core\IMessageProcessor.cs" />
|
||||||
|
<Compile Include="Core\LinkButton.cs" />
|
||||||
|
<Compile Include="Core\LogWindow.cs" />
|
||||||
|
<Compile Include="Core\MirandaDB.cs" />
|
||||||
|
<Compile Include="Core\Regexps.cs" />
|
||||||
|
<Compile Include="Core\Settings.cs" />
|
||||||
|
<Compile Include="Fork\ContactContainer.cs" />
|
||||||
|
<Compile Include="Fork\ContactManager.cs" />
|
||||||
|
<Compile Include="HPP\HistoryppHandler.cs" />
|
||||||
|
<Compile Include="HPP\HppActionOleObject.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="HPP\HppAvatarObject.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Interfaces\HTMLDispIDs.cs" />
|
||||||
|
<Compile Include="Interfaces\HTMLDocumentEvents2.cs" />
|
||||||
|
<Compile Include="Interfaces\IHTMLDocument2.cs" />
|
||||||
|
<Compile Include="Interfaces\IHTMLElement.cs" />
|
||||||
|
<Compile Include="Interfaces\IHTMLEventObj.cs" />
|
||||||
|
<Compile Include="Interfaces\IHTMLStyle.cs" />
|
||||||
|
<Compile Include="Interop\IEHandler.cs" />
|
||||||
|
<Compile Include="Interop\Structs.cs" />
|
||||||
|
<Compile Include="Interop\Subclassing.cs" />
|
||||||
|
<Compile Include="Interop\WinApi.cs" />
|
||||||
|
<Compile Include="MainClass.cs" />
|
||||||
|
<Compile Include="Opt\Options.cs" />
|
||||||
|
<Compile Include="Opt\Win32ImageList.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RichEdit\ActionOleObject.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RichEdit\AvatarObject.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RichEdit\IRichEditOle.cs" />
|
||||||
|
<Compile Include="RichEdit\ITextDocument.cs" />
|
||||||
|
<Compile Include="RichEdit\ITextFont.cs" />
|
||||||
|
<Compile Include="RichEdit\ITextPara.cs" />
|
||||||
|
<Compile Include="RichEdit\ITextRange.cs" />
|
||||||
|
<Compile Include="RichEdit\ITextSelection.cs" />
|
||||||
|
<Compile Include="RichEdit\ITextStoryRanges.cs" />
|
||||||
|
<Compile Include="RichEdit\REConstants.cs" />
|
||||||
|
<Compile Include="RichEdit\RichEditHandler.cs" />
|
||||||
|
<Compile Include="RichEdit\RichEditHelpers.cs" />
|
||||||
|
<Compile Include="Sites\BNWSite.cs" />
|
||||||
|
<Compile Include="Sites\ISite.cs" />
|
||||||
|
<Compile Include="Sites\JuickSite.cs" />
|
||||||
|
<Compile Include="Sites\PstoSite.cs" />
|
||||||
|
<Compile Include="Sites\SitesManager.cs" />
|
||||||
|
<Compile Include="Storage\Settings.cs" />
|
||||||
|
<Compile Include="Structs\API.cs" />
|
||||||
|
<Compile Include="Structs\IconLib.cs" />
|
||||||
|
<Compile Include="Structs\Miranda.cs" />
|
||||||
|
<Compile Include="Structs\TabSRMM.cs" />
|
||||||
|
<Compile Include="TTS\TextToSpeak.cs" />
|
||||||
|
<Compile Include="UI\ActionMenuItem.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="UI\PreviewForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="UI\PreviewForm.designer.cs">
|
||||||
|
<DependentUpon>PreviewForm.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Utils\IconTable.cs" />
|
||||||
|
<Compile Include="Utils\Invokable.cs" />
|
||||||
|
<Compile Include="Utils\Util.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Resources\icon_message.ico" />
|
||||||
|
<Content Include="Resources\icon_small_dot.ico" />
|
||||||
|
<Content Include="Resources\status_online.ico" />
|
||||||
|
<Content Include="Speak.dll">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Opt\dialog.res" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="UI\PreviewForm.resx">
|
||||||
|
<DependentUpon>PreviewForm.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<PostBuildEvent>if not exist IL mkdir IL
|
||||||
|
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64\ildasm.exe" /linenum "$(TargetFileName)" /out="IL\$(ProjectName).il"</PostBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
BIN
Speak/Speak/Speak.dll
Normal file
157
Speak/Speak/Storage/Settings.cs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Speak.Opt;
|
||||||
|
|
||||||
|
namespace Speak.Storage
|
||||||
|
{
|
||||||
|
class Settings
|
||||||
|
{
|
||||||
|
private class Contact
|
||||||
|
{
|
||||||
|
public string Status;
|
||||||
|
public bool message_read;
|
||||||
|
public bool status_read;
|
||||||
|
public Contact(string status, bool rmessage, bool rstatus)
|
||||||
|
{
|
||||||
|
this.Status = status;
|
||||||
|
this.message_read = rmessage;
|
||||||
|
this.status_read = rstatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static Settings instance;
|
||||||
|
private Dictionary<string, Contact> contactlist;
|
||||||
|
private long maxTextLength = 0;
|
||||||
|
private bool globalActive = true;
|
||||||
|
private bool unknownmessageread = true;
|
||||||
|
private bool unknownstatusread = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a Setting Class
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Settings Object</returns>
|
||||||
|
public static Settings getInstance()
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
instance = new Settings();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Settings()
|
||||||
|
{
|
||||||
|
this.contactlist = new Dictionary<string, Contact>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadContactList()
|
||||||
|
{
|
||||||
|
this.contactlist = new Dictionary<string, Contact>();
|
||||||
|
ReadOnlyCollection<ContactInfo> list = MirandaContext.Current.MirandaDatabase.GetContacts();
|
||||||
|
foreach (ContactInfo item in list)
|
||||||
|
{
|
||||||
|
if (item.UniqueID != null)
|
||||||
|
{
|
||||||
|
//System.Windows.Forms.MessageBox.Show("leer");
|
||||||
|
Contact c = new Contact(item.Status.ToString(),
|
||||||
|
Options.readDBBool("message", "speak_config", item.MirandaHandle, true),
|
||||||
|
Options.readDBBool("status", "speak_config", item.MirandaHandle, true));
|
||||||
|
this.contactlist.Add(item.UniqueID.ToString(), c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void SetGlobalSettings()
|
||||||
|
{
|
||||||
|
this.maxTextLength = Options.readDBLong("max_msg_size", "speak_config");
|
||||||
|
this.globalActive = Options.readDBBool("active", "speak_config", true);
|
||||||
|
this.unknownmessageread = Options.readDBBool("message_u", "speak_config", true);
|
||||||
|
this.unknownstatusread = Options.readDBBool("status_u", "speak_config", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool canMessageRead(string text, string uid)
|
||||||
|
{
|
||||||
|
if (!this.globalActive)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (text.Length > this.maxTextLength)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Contact c;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
c = this.contactlist[uid];
|
||||||
|
}
|
||||||
|
catch (System.Collections.Generic.KeyNotFoundException)
|
||||||
|
{
|
||||||
|
return this.unknownmessageread;
|
||||||
|
}
|
||||||
|
return c.message_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getSpeakString()
|
||||||
|
{
|
||||||
|
return "{0} meint: {1}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasChangedStatus(string uid, string status)
|
||||||
|
{
|
||||||
|
Contact c;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
c = this.contactlist[uid];
|
||||||
|
}
|
||||||
|
catch (System.Collections.Generic.KeyNotFoundException)
|
||||||
|
{
|
||||||
|
if (uid != "" && status != "")
|
||||||
|
{
|
||||||
|
ReadContactList();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c.Status != status)
|
||||||
|
{
|
||||||
|
this.contactlist[uid] = new Contact(status, c.message_read, c.status_read);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool canStatusRead(string uid)
|
||||||
|
{
|
||||||
|
Contact c = this.contactlist[uid];
|
||||||
|
if (c != null)
|
||||||
|
{
|
||||||
|
return c.status_read;
|
||||||
|
}
|
||||||
|
return this.unknownstatusread;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getStatusString(StatusMode? status)
|
||||||
|
{
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case StatusMode.Offline:
|
||||||
|
return "{0} ist Off";
|
||||||
|
case StatusMode.Online:
|
||||||
|
return "{0} ist da";
|
||||||
|
case StatusMode.Away:
|
||||||
|
return "{0} ist nur mal kurz weg";
|
||||||
|
case StatusMode.Invisible:
|
||||||
|
return "{0} hat sich versteckt";
|
||||||
|
case StatusMode.NA:
|
||||||
|
return "{0} ist nicht mehr da";
|
||||||
|
case StatusMode.DND:
|
||||||
|
return "{0} will in ruhe gelassen werden, schnautze";
|
||||||
|
case StatusMode.Occupied:
|
||||||
|
return "{0} ist beschäftigt";
|
||||||
|
case StatusMode.FreeForChat:
|
||||||
|
return "{0} will chatten";
|
||||||
|
}
|
||||||
|
return "{0} ist {1}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
98
Speak/Speak/Structs/API.cs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Speak.Structs
|
||||||
|
{
|
||||||
|
internal static class API
|
||||||
|
{
|
||||||
|
public static string MS_SYSTEM_GETVERSION = "Miranda/System/GetVersion";
|
||||||
|
|
||||||
|
public static string MS_DB_EVENT_ADD = "DB/Event/Add";
|
||||||
|
public static string MS_DB_EVENT_GET = "DB/Event/Get";
|
||||||
|
public static string MS_DB_EVENT_DELETE = "DB/Event/Delete";
|
||||||
|
public static string MS_DB_EVENT_GETBLOBSIZE = "DB/Event/GetBlobSize";
|
||||||
|
public static string MS_DB_TIME_TIMESTAMPTOLOCAL = "DB/Time/TimestampToLocal";
|
||||||
|
|
||||||
|
|
||||||
|
public static string MS_PROTO_ADDTOCONTACT = "Proto/AddToContact";
|
||||||
|
public static string MS_PROTO_ISPROTOONCONTACT = "Proto/IsProtoOnContact";
|
||||||
|
public static string MS_PROTO_REGISTERMODULE = "Proto/RegisterModule";
|
||||||
|
public static string MS_PROTO_CHAINSEND = "Proto/ChainSend";
|
||||||
|
public static string MS_PROTO_CHAINRECV = "Proto/ChainRecv";
|
||||||
|
public static string MS_PROTO_CALLCONTACTSERVICE = "Proto/CallContactService";
|
||||||
|
public static string MS_PROTO_GETCONTACTBASEPROTO = "Proto/GetContactBaseProto";
|
||||||
|
|
||||||
|
public static string PS_SETSTATUS = "/SetStatus";
|
||||||
|
public static string PS_GETSTATUS = "/GetStatus";
|
||||||
|
|
||||||
|
public static string PSR_MESSAGE = "/RecvMessage";
|
||||||
|
public static string PSR_MESSAGEW = "/RecvMessageW";
|
||||||
|
public static string PSS_MESSAGE = "/SendMsg";
|
||||||
|
public static string PSS_MESSAGEW = "/SendMsgW"; // instant send msg
|
||||||
|
|
||||||
|
public static string MS_MSG_SENDMESSAGE = "SRMsg/SendCommand"; // type msg
|
||||||
|
public static string ME_MSG_WINDOWEVENT = "MessageAPI/WindowEvent";
|
||||||
|
|
||||||
|
public static string MS_SKIN2_ADDICON = "Skin2/Icons/AddIcon";
|
||||||
|
public static string MS_SKIN2_GETICON = "Skin2/Icons/GetIcon";
|
||||||
|
public static string MS_SKIN2_GETICONBYHANDLE = "Skin2/Icons/GetIconByHandle";
|
||||||
|
public static string ME_SKIN2_ICONSCHANGED = "Skin2/IconsChanged";
|
||||||
|
|
||||||
|
public static string MS_BB_ADDBUTTON = "TabSRMM/ButtonsBar/AddButton";
|
||||||
|
public static string MS_BB_REMOVEBUTTON = "TabSRMM/ButtonsBar/RemoveButton";
|
||||||
|
public static string MS_BB_GETBUTTONSTATE = "TabSRMM/ButtonsBar/GetButtonState";
|
||||||
|
public static string MS_BB_SETBUTTONSTATE = "TabSRMM/ButtonsBar/SetButtonState";
|
||||||
|
public static string ME_MSG_TOOLBARLOADED = "TabSRMM/ButtonsBar/ModuleLoaded";
|
||||||
|
public static string ME_MSG_BUTTONPRESSED = "TabSRMM/ButtonsBar/ButtonPressed";
|
||||||
|
|
||||||
|
public static string ME_IEVIEW_OPTIONSCHANGED = "IEVIEW/OptionsChanged";
|
||||||
|
public static string ME_DB_CONTACT_SETTINGCHANGED = "DB/Contact/SettingChanged";
|
||||||
|
|
||||||
|
public static string ME_DB_EVENT_ADDED = "DB/Event/Added";
|
||||||
|
|
||||||
|
public static string MS_UTILS_OPENURL = "Utils/OpenURL";
|
||||||
|
|
||||||
|
public static string ME_OPT_INITIALISE = "Opt/Initialise";
|
||||||
|
public static string MS_OPT_ADDPAGE = "Opt/AddPage";
|
||||||
|
|
||||||
|
public static string MS_GC_NEWSESSION = "GChat/NewChat";
|
||||||
|
|
||||||
|
public static string MS_MSG_GETWINDOWCLASS = "MessageAPI/WindowClass";
|
||||||
|
|
||||||
|
public static string MS_PROTO_ENUMPROTOS = "Proto/EnumProtos";
|
||||||
|
public static string MS_PROTO_ENUMPROTOCOLS = "Proto/EnumProtocols";
|
||||||
|
public static string MS_PROTO_ENUMACCOUNTS = "Proto/EnumAccounts";
|
||||||
|
|
||||||
|
public static string MS_IEVIEW_WINDOW = "IEVIEW/NewWindow";
|
||||||
|
|
||||||
|
public static string ME_HPP_RICHEDIT_ITEMPROCESS = "History++/RichEdit/ItemProcessEvent";
|
||||||
|
public static string MS_HPP_EG_WINDOW = "History++/ExtGrid/NewWindow";
|
||||||
|
public static string MS_HPP_GETVERSION = "History++/GetVersion";
|
||||||
|
|
||||||
|
public static string MS_DB_GETPROFILEPATH = "DB/GetProfilePath";
|
||||||
|
public static string MS_DB_GETPROFILENAME = "DB/GetProfileName";
|
||||||
|
|
||||||
|
public static Int32 CALLSERVICE_NOTFOUND = unchecked((int) 0x80000000);
|
||||||
|
public static string MS_DB_CONTACT_FINDFIRST = "DB/Contact/FindFirst";
|
||||||
|
public static string MS_DB_CONTACT_FINDNEXT = "DB/Contact/FindNext";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StatusModes
|
||||||
|
{
|
||||||
|
Offline = 40071,
|
||||||
|
Online = 40072,
|
||||||
|
Away = 40073,
|
||||||
|
DND = 40074,
|
||||||
|
NA = 40075,
|
||||||
|
Occupied = 40076,
|
||||||
|
FreeForChat = 40077,
|
||||||
|
Invisible = 40078,
|
||||||
|
OnThePhone = 40079,
|
||||||
|
OutToLunch = 40080,
|
||||||
|
Idle = 40081
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
34
Speak/Speak/Structs/IconLib.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Speak.Structs
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
|
struct IconName
|
||||||
|
{
|
||||||
|
public Int32 cbSize;
|
||||||
|
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string szSection;
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string szDescription;
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string pszName;
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string pczDefaultFile;
|
||||||
|
|
||||||
|
public Int32 iDefaultIndex;
|
||||||
|
public IntPtr hDefaultIcon;
|
||||||
|
public Int32 cx;
|
||||||
|
public Int32 cy;
|
||||||
|
public Int32 flags;
|
||||||
|
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
pszName = pczDefaultFile = String.Empty;
|
||||||
|
cx = cy = 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
462
Speak/Speak/Structs/Miranda.cs
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Virtuoso.Miranda.Plugins.Native;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.Utils;
|
||||||
|
|
||||||
|
namespace Speak.Structs
|
||||||
|
{
|
||||||
|
public static class MainConstants
|
||||||
|
{
|
||||||
|
public const UInt32 MSG_WINDOW_EVT_OPENING = 1; // window is about to be opened
|
||||||
|
public const UInt32 MSG_WINDOW_EVT_OPEN = 2; // window has been opened
|
||||||
|
public const UInt32 MSG_WINDOW_EVT_CLOSING = 3; // window is about to be closed
|
||||||
|
public const UInt32 MSG_WINDOW_EVT_CLOSE = 4; // window has been closed
|
||||||
|
public const UInt32 MSG_WINDOW_EVT_CUSTOM = 5; // custom event for message plugins to use
|
||||||
|
// (custom uFlags may be used)
|
||||||
|
public const Int32 MSG_WINDOW_UFLAG_MSG_FROM = 0x00000001;
|
||||||
|
public const Int32 MSG_WINDOW_UFLAG_MSG_TO = 0x00000002;
|
||||||
|
public const Int32 MSG_WINDOW_UFLAG_MSG_BOTH = 0x00000004;
|
||||||
|
|
||||||
|
public const Int32 DBEF_UTF = 16;
|
||||||
|
|
||||||
|
public const Int32 MI_IDC_LOG = 1001; // rich edit
|
||||||
|
public const Int32 MI_IDC_MESSAGE = 1002; // edit control
|
||||||
|
public const Int32 MI_IDC_QUOTE = 1034; // button control
|
||||||
|
public const Int32 MI_IDC_NAME = 1009; // text control
|
||||||
|
public const Int32 MI_IDC_ADD = 1070; // add button
|
||||||
|
public const Int32 WM_REMAKERICH = WinApi.WM_USER + 0x3457;
|
||||||
|
public const uint ODPF_BOLDGROUPS = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ContactListConstants
|
||||||
|
{
|
||||||
|
public const int CLM_FIRST = 0x1000; //this is the same as LVM_FIRST
|
||||||
|
public const int CLN_FIRST = -100;
|
||||||
|
public const int CLM_ADDINFOITEM = CLM_FIRST + 53; //lParam=&cii, returns hItem
|
||||||
|
public const int CLM_SETEXTRAIMAGELIST = CLM_FIRST + 32; //lParam=HIMAGELIST, wParam=WideImageList
|
||||||
|
public const int CLM_SETBKBITMAP = CLM_FIRST + 27; //wParam=mode, lParam=hBitmap (don't delete it), NULL for none
|
||||||
|
public const int CLM_SETBKCOLOR = CLM_FIRST + 28; //wParam=a COLORREF, default is GetSysColor(COLOR_3DFACE)
|
||||||
|
public const int CLM_SETGREYOUTFLAGS = CLM_FIRST + 39; //wParam=new flags
|
||||||
|
public const int CLM_SETLEFTMARGIN = CLM_FIRST + 47; //wParam=pixels
|
||||||
|
public const int CLM_SETINDENT = CLM_FIRST + 34; //wParam=new indent, default is 3 pixels
|
||||||
|
public const int FONTID_MAX = 18;
|
||||||
|
public const int CLM_SETTEXTCOLOR = CLM_FIRST + 52; //wParam=FONTID_, lParam=COLORREF
|
||||||
|
public const int CLS_SHOWHIDDEN = 0x0002;
|
||||||
|
public const int CLM_SETEXTRACOLUMNS = CLM_FIRST + 30; //wParam=number of extra columns (zero to MAXEXTRACOLUMNS from clc.h, currently 16)
|
||||||
|
public const int CLCIIF_GROUPFONT = 0x80;
|
||||||
|
public const int CLM_FINDCONTACT = CLM_FIRST + 8; //wParam=hContact, returns an hItem
|
||||||
|
public const int CLM_GETEXTRAIMAGE = CLM_FIRST + 16; ////wParam=hItem, lParam=MAKELPARAM(iColumn (0 based),0), returns iImage or 0xFFa
|
||||||
|
public const int CLM_SETEXTRAIMAGE = CLM_FIRST + 31; //wParam=hItem, lParam=MAKELPARAM(iColumn (0 based),iImage). iImage=0xFF is a blank
|
||||||
|
public const int CLM_AUTOREBUILD = CLM_FIRST+2;
|
||||||
|
public const int CLM_GETNEXTITEM = CLM_FIRST + 50; //wParam=flag, lParam=hItem, returns an hItem
|
||||||
|
public const int CLGN_ROOT = 0;
|
||||||
|
public const int CLM_GETITEMTYPE = CLM_FIRST + 49; //wParam=hItem, returns a CLCIT_
|
||||||
|
public const int CLCIT_GROUP = 0;
|
||||||
|
public const int CLGN_NEXTGROUP = 7;
|
||||||
|
public const int CLGN_CHILD = 1;
|
||||||
|
public const int CLCIT_CONTACT = 1;
|
||||||
|
public const int CLGN_NEXTCONTACT = 5;
|
||||||
|
public const int CLM_GETEXTRAIMAGELIST = CLM_FIRST + 17; //returns HIMAGELIST
|
||||||
|
public const int CLN_OPTIONSCHANGED = CLN_FIRST - 6; //nothing valid. If you set some extended options they have been overwritten and should be re-set
|
||||||
|
public const int CLN_NEWCONTACT = CLN_FIRST - 8; //hItem,flags valid. sent when a new contact is added without a full list rebuild
|
||||||
|
public const int CLN_LISTREBUILT = CLN_FIRST - 9; //hItem,flags valid. sent when contact is moved without a full list rebuild
|
||||||
|
public const int CLM_HITTEST = CLM_FIRST + 25; //lParam=MAKELPARAM(x,y) (relative to control), wParam=(PDWORD)&hitTest (see encoding of HitTest() in clc.h, can be NULL) returns hItem or NULL
|
||||||
|
public const int CLCIT_INFO = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StandartIcons
|
||||||
|
{
|
||||||
|
public const string SKINICON_OTHER_SMALLDOT = "Small Dot";
|
||||||
|
public const string SKINICON_EVENT_MESSAGE = "Message";
|
||||||
|
public const string ID_STATUS_ONLINE = "Online";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HppConstaints
|
||||||
|
{
|
||||||
|
public static Version MinumumVersion = new Version(1, 5, 1, 4);
|
||||||
|
|
||||||
|
public const UInt32 IRDHW_CONTACTHISTORY = 0x1;
|
||||||
|
public const UInt32 IRDHW_GLOBALHISTORY = 0x2;
|
||||||
|
public const UInt32 IRDHW_GLOBALSEARCH = 0x3;
|
||||||
|
public const UInt32 IRDHW_EXTERNALGRID = 0x4;
|
||||||
|
|
||||||
|
public const UInt32 IRDF_SELECTED = 0x1;
|
||||||
|
public const UInt32 IRDF_INLINE = 0x2;
|
||||||
|
public const UInt32 IRDF_EVENT = 0x4;
|
||||||
|
|
||||||
|
public const Int32 NM_FIREVIEWCHANGE = 1;
|
||||||
|
|
||||||
|
public const Int32 FVCN_PREFIRE = 1;
|
||||||
|
public const Int32 FVCN_POSTFIRE = 2;
|
||||||
|
|
||||||
|
public const Int32 FVCA_NONE = 0;
|
||||||
|
public const Int32 FVCA_INFO = 255;
|
||||||
|
public const Int32 FVCN_GETINFO = 255;
|
||||||
|
|
||||||
|
public const Int32 FVCA_DRAW = 1;
|
||||||
|
public const Int32 FVCA_CUSTOMDRAW = 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct MessageWindowEventData
|
||||||
|
{
|
||||||
|
public Int32 cbSize;
|
||||||
|
public IntPtr hContact;
|
||||||
|
public IntPtr hWnd; // top level window for the contact
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string szModule; // used to get plugin type (which means you could use local if needed)
|
||||||
|
public UInt32 uType; // see event types below
|
||||||
|
public UInt32 uFlags; // used to indicate message direction for all event types except custom
|
||||||
|
public IntPtr pointer; // used to store pointer to custom data
|
||||||
|
public IntPtr hWndInput; // input area window for the contact (or NULL if there is none)
|
||||||
|
public IntPtr hLog; // log area window for the contact (or NULL if there is none)
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
internal struct ItemRenderDetails
|
||||||
|
{
|
||||||
|
public UInt32 cbSize;
|
||||||
|
public IntPtr hContact;
|
||||||
|
public IntPtr hDBEvent;
|
||||||
|
public UInt32 dwEventTime;
|
||||||
|
public UInt16 wEventType;
|
||||||
|
public byte isEventSent;
|
||||||
|
public UInt32 dwFlags; // ???
|
||||||
|
public byte bHistoryWindow;
|
||||||
|
|
||||||
|
public IntPtr pProto;
|
||||||
|
public IntPtr pModule;
|
||||||
|
public IntPtr pText;
|
||||||
|
public IntPtr pExtended;
|
||||||
|
|
||||||
|
public string Proto
|
||||||
|
{
|
||||||
|
get { return pProto == IntPtr.Zero ? String.Empty : Marshal.PtrToStringAnsi(pProto); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Module
|
||||||
|
{
|
||||||
|
get { return pModule == IntPtr.Zero ? String.Empty : Marshal.PtrToStringAnsi(pModule); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get { return pText == IntPtr.Zero ? String.Empty : Marshal.PtrToStringUni(pText); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Extended
|
||||||
|
{
|
||||||
|
get { return pExtended == IntPtr.Zero ? String.Empty : Marshal.PtrToStringAnsi(pExtended); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEventSent
|
||||||
|
{
|
||||||
|
get { return Convert.ToBoolean(isEventSent); }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct NMCLISTCONTROL
|
||||||
|
{
|
||||||
|
public NMHDR hdr;
|
||||||
|
public int hItem;
|
||||||
|
public int action;
|
||||||
|
public int iColumn;
|
||||||
|
public int flags;
|
||||||
|
public POINT pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct TFVCNDATA_NMHDR
|
||||||
|
{
|
||||||
|
public IntPtr handleFrom;
|
||||||
|
public UInt32 idFrom;
|
||||||
|
public UInt32 code;
|
||||||
|
|
||||||
|
|
||||||
|
public Int32 cbSize;
|
||||||
|
public byte bEvent;
|
||||||
|
public byte bAction;
|
||||||
|
public IntPtr hDC;
|
||||||
|
public RECT rcRect;
|
||||||
|
public COLORREF clrBackground;
|
||||||
|
public bool fTransparent;
|
||||||
|
public IntPtr lparam;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct DBTimeToString
|
||||||
|
{
|
||||||
|
public IntPtr Format;
|
||||||
|
public IntPtr Output;
|
||||||
|
public int MaxBytes;
|
||||||
|
public DBTimeToString(string format)
|
||||||
|
{
|
||||||
|
UnmanagedStringHandle str = new UnmanagedStringHandle(format, StringEncoding.Ansi);
|
||||||
|
this.Format = str.IntPtr;
|
||||||
|
this.Output = IntPtr.Zero;
|
||||||
|
this.MaxBytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Free()
|
||||||
|
{
|
||||||
|
if (this.Format != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(this.Format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct ProtoRecieveEvent
|
||||||
|
{
|
||||||
|
public UInt32 flags;
|
||||||
|
public UInt32 timestamp;
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 2048)]
|
||||||
|
public string szMessage;
|
||||||
|
public Int32 lParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct PGDest
|
||||||
|
{
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string pszModule; //Name of the protocol (same as you registered with)
|
||||||
|
public IntPtr szID; //Unique identifier of the session, or NULL to broadcast to all sessions as specified above
|
||||||
|
public Int32 iType; //Use GC_EVENT_* as defined above. Only one event per service call.
|
||||||
|
|
||||||
|
public string ID
|
||||||
|
{
|
||||||
|
set { szID = Marshal.StringToHGlobalAnsi(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Free()
|
||||||
|
{
|
||||||
|
if (szID != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(szID);
|
||||||
|
szID = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct GCEvent
|
||||||
|
{
|
||||||
|
public Int32 cbSize;
|
||||||
|
public IntPtr pDest; // pointer to a GCDEST structure which specifies the session to receive the event
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string szText; // usage depends on type of event, max 2048 characters
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string szNick; // usage depends on type of event
|
||||||
|
public IntPtr szUID; // usage depends on type of event, Do NOT use spaces for unique user identifiers.
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string szStatus; // usage depends on type of event
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string szUserInfo; // Additional user information that is displayed after the nickname.
|
||||||
|
// IRC use it to display a hostmask for JOIN, PART (and more) events.
|
||||||
|
public bool bIsMe; // Is this event from the Miranda user?
|
||||||
|
public UInt32 dwFlags; // event flags: GCEF_ADDTOLOG, GC_UNICODE
|
||||||
|
// FALSE any other time than when initializing the window (before sending SESSION_INITDONE)
|
||||||
|
public UInt32 dwItemData; // User specified data.
|
||||||
|
public UInt32 time; // Timestamp of the event
|
||||||
|
|
||||||
|
public GCEvent(bool z)
|
||||||
|
{
|
||||||
|
cbSize = 0;
|
||||||
|
pDest = new IntPtr();
|
||||||
|
szText = null;
|
||||||
|
szNick = null;
|
||||||
|
szUID = new IntPtr();
|
||||||
|
szStatus = null;
|
||||||
|
szUserInfo = null;
|
||||||
|
bIsMe = false;
|
||||||
|
dwFlags = 0u;
|
||||||
|
dwItemData = 0u;
|
||||||
|
time = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UID
|
||||||
|
{
|
||||||
|
set { szUID = Marshal.StringToHGlobalAnsi(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Free()
|
||||||
|
{
|
||||||
|
if (szUID != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(szUID);
|
||||||
|
szUID = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct GCRegister
|
||||||
|
{
|
||||||
|
public Int32 cbSize; //Set to sizeof(GCREGISTER);
|
||||||
|
public UInt32 dwFlags; //Use GC_* flags above to indicate features supported
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string pszModule; //This MUST be the protocol name as registered with Miranda IM
|
||||||
|
public IntPtr pszModuleDispName; //This is the protocol's real name as it will be displayed to the user
|
||||||
|
public Int32 iMaxText; //Max message length the protocol supports. Will limit the typing area input. 0 = no limit
|
||||||
|
public Int32 nColors; //Number of colors in the colorchooser menu for the color buttons. Max = 100
|
||||||
|
|
||||||
|
public IntPtr pColors; // ^TCOLORREF; //pointer to the first item in a static COLORREF array containing the colors
|
||||||
|
//that should be showed in the colorchooser menu.
|
||||||
|
//ie: COLORREF crCols[nColors];
|
||||||
|
// pColors = &crCols[0];
|
||||||
|
|
||||||
|
public string ModuleDispName
|
||||||
|
{
|
||||||
|
set { pszModuleDispName = Marshal.StringToHGlobalAnsi(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Free()
|
||||||
|
{
|
||||||
|
if (pszModuleDispName != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(pszModuleDispName);
|
||||||
|
pszModuleDispName = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct GSession
|
||||||
|
{
|
||||||
|
public Int32 cbSize; //Set to sizeof(GCSESSION);
|
||||||
|
public Int32 iType; //Use one of the GCW_* flags above to set the type of session
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string pszModule; //The name of the protocol owning the session (the same as pszModule when you register)
|
||||||
|
public IntPtr szName; //The name of the session as it will be displayed to the user
|
||||||
|
//[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public IntPtr szID; //The unique identifier for the session.
|
||||||
|
public IntPtr szStatusbarText; //Optional text to set in the statusbar of the chat room window, or NULL.
|
||||||
|
public UInt32 dwFlags;
|
||||||
|
public UInt32 dwItemData; //Set user defined data for this session. Retrieve it by using the GC_EVENT_GETITEMDATA event
|
||||||
|
|
||||||
|
|
||||||
|
public string StatusbarText
|
||||||
|
{
|
||||||
|
set { szStatusbarText = Marshal.StringToHGlobalAnsi(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
set { szName = Marshal.StringToHGlobalAnsi(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ID
|
||||||
|
{
|
||||||
|
set { szID = Marshal.StringToHGlobalAnsi(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Free()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (szStatusbarText != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(szStatusbarText);
|
||||||
|
szStatusbarText = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (szName != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(szName);
|
||||||
|
szName = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (szID != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(szID);
|
||||||
|
szID = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct CSSData
|
||||||
|
{
|
||||||
|
public IntPtr hContact;
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string szProtoService;
|
||||||
|
|
||||||
|
public IntPtr wParam;
|
||||||
|
public IntPtr lParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*typedef struct {
|
||||||
|
int cbSize;
|
||||||
|
const TCHAR *pszText;
|
||||||
|
HANDLE hParentGroup;
|
||||||
|
DWORD flags;
|
||||||
|
HICON hIcon; //todo
|
||||||
|
} CLCINFOITEM;*/
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct CLCINFOITEM
|
||||||
|
{
|
||||||
|
public Int32 cbSize;
|
||||||
|
public IntPtr pszText;
|
||||||
|
public IntPtr hParentGroup;
|
||||||
|
public UInt32 flags;
|
||||||
|
public IntPtr hIcon;
|
||||||
|
}
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct OptionsDialogPage
|
||||||
|
{
|
||||||
|
public Int32 cbSize;
|
||||||
|
public Int32 position;
|
||||||
|
//[MarshalAsAttribute(UnmanagedType.LPTStr, SizeConst = 64)]
|
||||||
|
//public string szTitle;
|
||||||
|
public IntPtr szTitle;
|
||||||
|
public IntPtr pfnDlgProc;
|
||||||
|
public IntPtr pszTemplate;
|
||||||
|
public IntPtr hInstance; // Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0])
|
||||||
|
public IntPtr hIcon;
|
||||||
|
//[MarshalAsAttribute(UnmanagedType.LPTStr, SizeConst = 64)]
|
||||||
|
public IntPtr szGroup;
|
||||||
|
public Int32 groupPosition;
|
||||||
|
public IntPtr hGroupIcon;
|
||||||
|
|
||||||
|
|
||||||
|
public UInt32 flags;
|
||||||
|
public Int32 nIDBottomSimpleControl;
|
||||||
|
public Int32 nIDRightSimpleControl;
|
||||||
|
public Int32 expertOnlyControls;
|
||||||
|
public Int32 nExpertOnlyControls;
|
||||||
|
public Int32 szTab;
|
||||||
|
|
||||||
|
//public IntPtr dwInitParam;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||||
|
public struct PLUGININFOEX
|
||||||
|
{
|
||||||
|
public int Size;
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
|
public string ShortName;
|
||||||
|
public uint Version;
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
|
public string Description;
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
|
public string Author;
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
|
public string AuthorEmail;
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
|
public string Copyright;
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
|
public string HomePage;
|
||||||
|
public byte Flags;
|
||||||
|
public int ReplacesDefaultModule;
|
||||||
|
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32+16+16+8)]
|
||||||
|
public byte[] MUUID; // Ex
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
63
Speak/Speak/Structs/TabSRMM.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Speak.Interop;
|
||||||
|
|
||||||
|
namespace Speak.Structs
|
||||||
|
{
|
||||||
|
public static class TabSRMMConstants
|
||||||
|
{
|
||||||
|
public const UInt32 BBBF_DISABLED = 0x0001;
|
||||||
|
public const UInt32 BBBF_HIDDEN = 0x0002;
|
||||||
|
public const UInt32 BBBF_ISPUSHBUTTON = 0x0004;
|
||||||
|
public const UInt32 BBBF_ISARROWBUTTON = 0x0008;
|
||||||
|
public const UInt32 BBBF_ISCHATBUTTON = 0x0010;
|
||||||
|
public const UInt32 BBBF_ISIMBUTTON = 0x0020;
|
||||||
|
public const UInt32 BBBF_ISLSIDEBUTTON = 0x0040;
|
||||||
|
public const UInt32 BBBF_ISRSIDEBUTTON = 0x0080;
|
||||||
|
public const UInt32 BBBF_CANBEHIDDEN = 0x0100;
|
||||||
|
public const UInt32 BBBF_ISDUMMYBUTTON = 0x0200;
|
||||||
|
public const UInt32 BBBF_ANSITOOLTIP = 0x0400;
|
||||||
|
public const UInt32 BBBF_CREATEBYID = 0x0800; //only for tabsrmm internal use
|
||||||
|
|
||||||
|
public const UInt32 BBSF_DOSNT_EXISTS = 0; // added by xa0c
|
||||||
|
public const UInt32 BBSF_HIDDEN = 1;
|
||||||
|
public const UInt32 BBSF_DISABLED = 2;
|
||||||
|
public const UInt32 BBSF_PUSHED = 4;
|
||||||
|
public const UInt32 BBSF_RELEASED = 8;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct CustomButtonClickData
|
||||||
|
{
|
||||||
|
public Int32 cbSize;
|
||||||
|
|
||||||
|
public POINT point;
|
||||||
|
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string pszName;
|
||||||
|
public UInt32 dwButtonID;
|
||||||
|
public IntPtr hwindForm;
|
||||||
|
public IntPtr hContact;
|
||||||
|
public UInt32 flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct BBButton
|
||||||
|
{
|
||||||
|
public Int32 cbSize;
|
||||||
|
public UInt32 dwButtonID;
|
||||||
|
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPStr, SizeConst = 64)]
|
||||||
|
public string pszModuleName;
|
||||||
|
[MarshalAsAttribute(UnmanagedType.LPTStr, SizeConst = 64)]
|
||||||
|
public string szTooltip;
|
||||||
|
|
||||||
|
public UInt32 dwDefPos;
|
||||||
|
public Int32 iButtonWidth;
|
||||||
|
public UInt32 bbbFlags;
|
||||||
|
public IntPtr hIcon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
157
Speak/Speak/TTS/TextToSpeak.cs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Speech.Synthesis;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Speak.TTS
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Speak Text
|
||||||
|
/// </summary>
|
||||||
|
class TextToSpeak
|
||||||
|
{
|
||||||
|
private SpeechSynthesizer syn;
|
||||||
|
private Queue<string> quene;
|
||||||
|
private static TextToSpeak instance;
|
||||||
|
private List<string> last;
|
||||||
|
private Boolean runner;
|
||||||
|
private Thread workerThread;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the Instance of TextToSpeak Class
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>TextToSpeak</returns>
|
||||||
|
public static TextToSpeak getInstance()
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
instance = new TextToSpeak();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextToSpeak()
|
||||||
|
{
|
||||||
|
this.syn = new SpeechSynthesizer();
|
||||||
|
this.quene = new Queue<string>();
|
||||||
|
this.last = new List<string>();
|
||||||
|
this.runner = true;
|
||||||
|
this.workerThread = new Thread(this.Speaker);
|
||||||
|
workerThread.Start();
|
||||||
|
while (!workerThread.IsAlive) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Speaker()
|
||||||
|
{
|
||||||
|
while (runner)
|
||||||
|
{
|
||||||
|
string text = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
text = quene.Dequeue();
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException) { }
|
||||||
|
if (text != "")
|
||||||
|
{
|
||||||
|
syn.Speak(text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Thread.Sleep(300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a Text to the to Speak Quene
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">Text that will be spoken</param>
|
||||||
|
/// <param name="signature">Signature of Message, to catch to offten spoken text</param>
|
||||||
|
public void speak(string text, string signature)
|
||||||
|
{
|
||||||
|
if (!last.Contains(signature))
|
||||||
|
{
|
||||||
|
last.Add(signature);
|
||||||
|
quene.Enqueue(text);
|
||||||
|
}
|
||||||
|
if (last.Count > 10)
|
||||||
|
{
|
||||||
|
last.RemoveAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a list of Installed Voices
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static List<String> getVoices()
|
||||||
|
{
|
||||||
|
List<string> ret = new List<string>();
|
||||||
|
ReadOnlyCollection<InstalledVoice> voices = new SpeechSynthesizer().GetInstalledVoices();
|
||||||
|
foreach (InstalledVoice item in voices)
|
||||||
|
{
|
||||||
|
ret.Add(item.VoiceInfo.Name);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a voice to the current Speak Engine
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="voice">Name of the Voice</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool setVoice(string voice)
|
||||||
|
{
|
||||||
|
if (voice == "")
|
||||||
|
return false;
|
||||||
|
this.syn.SelectVoice(voice);
|
||||||
|
return this.syn.Voice.Name == voice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set a new Volume to the Current Speak Engine
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="volume"></param>
|
||||||
|
/// <returns>from 0 to 100</returns>
|
||||||
|
public bool setVolume(int volume)
|
||||||
|
{
|
||||||
|
if (volume > 100 || volume < 0)
|
||||||
|
return false;
|
||||||
|
this.syn.Volume = volume;
|
||||||
|
return this.syn.Volume == volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set a new Rate to the Current Speak engine
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rate"></param>
|
||||||
|
/// <returns>from 0 to 100</returns>
|
||||||
|
public bool setRate(int rate)
|
||||||
|
{
|
||||||
|
if (rate > 100 || rate < 0)
|
||||||
|
return false;
|
||||||
|
rate = rate / 5;
|
||||||
|
rate = rate - 10;
|
||||||
|
this.syn.Rate = rate;
|
||||||
|
return this.syn.Rate == rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setting a new Pitch to the current Speak Engine
|
||||||
|
/// NOT IMPLEMENTED
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pitch"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool setPitch(int pitch)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
this.workerThread.Abort();
|
||||||
|
this.runner = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
132
Speak/Speak/UI/ActionMenuItem.cs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak.Core;
|
||||||
|
|
||||||
|
namespace Speak.UI
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ActionMenuItem : MenuItem
|
||||||
|
{
|
||||||
|
private Image itemImage;
|
||||||
|
private string displayName;
|
||||||
|
private string action;
|
||||||
|
private bool autoSend;
|
||||||
|
private LinkDisplayType displayType;
|
||||||
|
private string mainWord;
|
||||||
|
private string additionalWord;
|
||||||
|
|
||||||
|
public ActionMenuItem(LinkButton link)
|
||||||
|
{
|
||||||
|
OwnerDraw = true;
|
||||||
|
Text = displayName = link.DisplayName;
|
||||||
|
action = link.Action;
|
||||||
|
autoSend = link.AutoSend;
|
||||||
|
mainWord = String.Empty;
|
||||||
|
additionalWord = String.Empty;
|
||||||
|
displayType = link.DisplayType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image Image
|
||||||
|
{
|
||||||
|
get { return itemImage; }
|
||||||
|
set { itemImage = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkDisplayType DisplayType
|
||||||
|
{
|
||||||
|
get { return displayType; }
|
||||||
|
set { displayType = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Action
|
||||||
|
{
|
||||||
|
get { return action.Replace("%NUMBER%", mainWord).Replace("%NICK%", mainWord).Replace("%COMMENT%", additionalWord); }
|
||||||
|
set { action = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AutoSend
|
||||||
|
{
|
||||||
|
get { return autoSend; }
|
||||||
|
set { autoSend = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AdditionalWord
|
||||||
|
{
|
||||||
|
get { return additionalWord; }
|
||||||
|
set { additionalWord = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MainWord
|
||||||
|
{
|
||||||
|
get { return mainWord; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
mainWord = value;
|
||||||
|
Text = displayName.Replace("%NUMBER%", mainWord).Replace("%NICK%", mainWord).Replace("%COMMENT%", additionalWord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMeasureItem(MeasureItemEventArgs e)
|
||||||
|
{
|
||||||
|
Font menuFont = SystemInformation.MenuFont;
|
||||||
|
|
||||||
|
StringFormat strfmt = new StringFormat();
|
||||||
|
|
||||||
|
SizeF sizef = e.Graphics.MeasureString(Text, menuFont, 1000, strfmt);
|
||||||
|
e.ItemWidth = (int)Math.Ceiling(sizef.Width) + itemImage.Width;
|
||||||
|
e.ItemHeight = itemImage.Height > sizef.Height ? itemImage.Height : (int)Math.Ceiling(sizef.Height);
|
||||||
|
base.OnMeasureItem(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDrawItem(DrawItemEventArgs e)
|
||||||
|
{
|
||||||
|
Font menuFont = SystemInformation.MenuFont;
|
||||||
|
SolidBrush menuBrush = null;
|
||||||
|
if (Enabled == false)
|
||||||
|
{
|
||||||
|
menuBrush = new SolidBrush(SystemColors.GrayText);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menuBrush = (e.State & DrawItemState.Selected) != 0 ? new SolidBrush(SystemColors.HighlightText) : new SolidBrush(SystemColors.MenuText);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringFormat strfmt = new StringFormat();
|
||||||
|
strfmt.LineAlignment = StringAlignment.Center;
|
||||||
|
|
||||||
|
Rectangle rectImage = e.Bounds;
|
||||||
|
rectImage.Width = itemImage.Width;
|
||||||
|
rectImage.Height = itemImage.Height;
|
||||||
|
if (displayType != LinkDisplayType.Image)
|
||||||
|
{
|
||||||
|
rectImage.Y = e.Bounds.Top + (e.Bounds.Height - itemImage.Height) / 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rectImage.X = e.Bounds.Left + (e.Bounds.Width - itemImage.Width) / 2;
|
||||||
|
rectImage.Y = e.Bounds.Top + (e.Bounds.Height - itemImage.Height) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle rectText = e.Bounds;
|
||||||
|
|
||||||
|
rectText.X += rectImage.Width;
|
||||||
|
|
||||||
|
e.Graphics.FillRectangle(
|
||||||
|
(e.State & DrawItemState.Selected) != 0 ? SystemBrushes.Highlight : SystemBrushes.Menu,
|
||||||
|
e.Bounds);
|
||||||
|
|
||||||
|
e.Graphics.DrawImage(itemImage, rectImage);
|
||||||
|
|
||||||
|
e.Graphics.DrawString(
|
||||||
|
Text, menuFont, menuBrush,
|
||||||
|
e.Bounds.Left + itemImage.Width,
|
||||||
|
e.Bounds.Top + ((e.Bounds.Height) / 2),
|
||||||
|
strfmt);
|
||||||
|
|
||||||
|
menuBrush.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
205
Speak/Speak/UI/PreviewForm.cs
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.Interop;
|
||||||
|
|
||||||
|
namespace Speak.UI
|
||||||
|
{
|
||||||
|
public partial class PreviewForm : Form
|
||||||
|
{
|
||||||
|
private HTTP http;
|
||||||
|
private Thread downloadThread;
|
||||||
|
private Image image;
|
||||||
|
private string url;
|
||||||
|
private int retryCount;
|
||||||
|
private int sleep = 1500;
|
||||||
|
private bool abort;
|
||||||
|
|
||||||
|
public PreviewForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
url = String.Empty;
|
||||||
|
http = new HTTP();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override CreateParams CreateParams
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
const int CS_DROPSHADOW = 0x20000;
|
||||||
|
CreateParams param = base.CreateParams;
|
||||||
|
param.ClassStyle += CS_DROPSHADOW;
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetImage()
|
||||||
|
{
|
||||||
|
Stream imageStream = http.GetImage(url, false);
|
||||||
|
if (imageStream is MemoryStream && imageStream.Length == 0)
|
||||||
|
{
|
||||||
|
SetError("Error while downloading");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
byte[] bt = new byte[255];
|
||||||
|
int read = 0;
|
||||||
|
FileStream fs = File.OpenWrite("C:\\img.jpg");
|
||||||
|
while ((read = imageStream.Read(bt, 0, 255)) != 0)
|
||||||
|
{
|
||||||
|
fs.Write(bt, 0, read);
|
||||||
|
}
|
||||||
|
fs.Close();
|
||||||
|
return;
|
||||||
|
*/
|
||||||
|
image = Image.FromStream(imageStream);
|
||||||
|
if (image.Height == 1)
|
||||||
|
{
|
||||||
|
if (abort)
|
||||||
|
{
|
||||||
|
SetError("Aborted");
|
||||||
|
abort = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetError("Uncached, retrying [" + ++retryCount + "]...");
|
||||||
|
Thread.Sleep(sleep);
|
||||||
|
GetImage();
|
||||||
|
}
|
||||||
|
SetError("done");
|
||||||
|
CrossInvalidate();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
SetError("Cant create image");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate void CrossInvalidateDelegate();
|
||||||
|
private void CrossInvalidate()
|
||||||
|
{
|
||||||
|
if (this.InvokeRequired)
|
||||||
|
{
|
||||||
|
CrossInvalidateDelegate d = CrossInvalidate;
|
||||||
|
this.Invoke(d, new object[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Draw(Graphics.FromHwnd(Handle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate void SetErrorDelegate(string errorText);
|
||||||
|
private void SetError(string errorText)
|
||||||
|
{
|
||||||
|
if (lblInfo.InvokeRequired)
|
||||||
|
{
|
||||||
|
SetErrorDelegate d = SetError;
|
||||||
|
lblInfo.Invoke(d, new object[] { errorText });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblInfo.Text = errorText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Clear()
|
||||||
|
{
|
||||||
|
lblInfo.Text = "Loading...";
|
||||||
|
lblInfo.Visible = true;
|
||||||
|
Width = 150;
|
||||||
|
Height = 80;
|
||||||
|
retryCount = 0;
|
||||||
|
abort = false;
|
||||||
|
url = String.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
new public void Show()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
base.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
new public void Hide()
|
||||||
|
{
|
||||||
|
if (downloadThread != null)
|
||||||
|
{
|
||||||
|
//abort = true;
|
||||||
|
//downloadThread.Abort();
|
||||||
|
}
|
||||||
|
base.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Draw(Graphics g)
|
||||||
|
{
|
||||||
|
Width = image.Width;
|
||||||
|
Height = image.Height;
|
||||||
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||||
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
lblInfo.Visible = false;
|
||||||
|
g.DrawImage(image, 0, 0, Width, Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaint(PaintEventArgs e)
|
||||||
|
{
|
||||||
|
if (image == null || image.Height == 1)
|
||||||
|
{
|
||||||
|
base.OnPaint(e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Draw(e.Graphics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPaintBackground(PaintEventArgs e)
|
||||||
|
{
|
||||||
|
if (image == null || image.Height == 1)
|
||||||
|
{
|
||||||
|
base.OnPaintBackground(e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Draw(e.Graphics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string Url
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!url.Equals(value))
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
url = value;
|
||||||
|
|
||||||
|
if(downloadThread != null)
|
||||||
|
{
|
||||||
|
abort = true;
|
||||||
|
//downloadThread.Abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
downloadThread = new Thread(GetImage);
|
||||||
|
downloadThread.IsBackground = false;
|
||||||
|
downloadThread.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
66
Speak/Speak/UI/PreviewForm.designer.cs
generated
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
namespace Speak.UI
|
||||||
|
{
|
||||||
|
partial class PreviewForm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.lblInfo = new System.Windows.Forms.Label();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// lblInfo
|
||||||
|
//
|
||||||
|
this.lblInfo.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.lblInfo.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.lblInfo.Name = "lblInfo";
|
||||||
|
this.lblInfo.Size = new System.Drawing.Size(150, 80);
|
||||||
|
this.lblInfo.TabIndex = 0;
|
||||||
|
this.lblInfo.Text = "Loading...";
|
||||||
|
this.lblInfo.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||||
|
//
|
||||||
|
// PreviewForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(224)))), ((int)(((byte)(192)))));
|
||||||
|
this.ClientSize = new System.Drawing.Size(150, 80);
|
||||||
|
this.Controls.Add(this.lblInfo);
|
||||||
|
this.DoubleBuffered = true;
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||||
|
this.Name = "PreviewForm";
|
||||||
|
this.ShowIcon = false;
|
||||||
|
this.ShowInTaskbar = false;
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||||
|
this.TopMost = true;
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Label lblInfo;
|
||||||
|
}
|
||||||
|
}
|
120
Speak/Speak/UI/PreviewForm.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
30
Speak/Speak/Utils/IconTable.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.Properties;
|
||||||
|
using Speak.Structs;
|
||||||
|
|
||||||
|
namespace Speak.Utils
|
||||||
|
{
|
||||||
|
internal static class IconTable
|
||||||
|
{
|
||||||
|
public static IntPtr GetDefaultIcon(string btnName)
|
||||||
|
{
|
||||||
|
switch (btnName)
|
||||||
|
{
|
||||||
|
case StandartIcons.SKINICON_OTHER_SMALLDOT:
|
||||||
|
return Resources.icon_small_dot.Handle;
|
||||||
|
case StandartIcons.SKINICON_EVENT_MESSAGE:
|
||||||
|
return Resources.icon_message.Handle;
|
||||||
|
case StandartIcons.ID_STATUS_ONLINE:
|
||||||
|
return Resources.status_online.Handle;
|
||||||
|
}
|
||||||
|
return Resources.icon_small_dot.Handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static Image GetActionIcon(string btnName)
|
||||||
|
{
|
||||||
|
return Resources.icon_small_dot;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
134
Speak/Speak/Utils/Invokable.cs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Speak.Utils
|
||||||
|
{
|
||||||
|
// It's fucking awesome.
|
||||||
|
// So am I. :)
|
||||||
|
internal class Invokable
|
||||||
|
{
|
||||||
|
private const int GWL_WNDPROC = -4;
|
||||||
|
private const int WM_USER = 0x0400;
|
||||||
|
private const int WF_THREADCALLBACKMESSAGE = WM_USER + 123;
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||||
|
public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
static extern IntPtr CreateWindowEx(int dwExStyle, string lpClassName, string lpWindowName, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
static extern uint GetCurrentThreadId();
|
||||||
|
|
||||||
|
[DllImport("user32")]
|
||||||
|
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newProc);
|
||||||
|
[DllImport("user32")]
|
||||||
|
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);
|
||||||
|
[DllImport("user32")]
|
||||||
|
private static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, int wParam, int lParam);
|
||||||
|
private delegate int Win32WndProc(IntPtr hWnd, int Msg, int wParam, int lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
static extern bool DestroyWindow(IntPtr hwnd);
|
||||||
|
|
||||||
|
private Queue<CallBackDelegate> callbackDelegates;
|
||||||
|
|
||||||
|
private Win32WndProc wProc;
|
||||||
|
private IntPtr oldWndProc = IntPtr.Zero;
|
||||||
|
|
||||||
|
private IntPtr handle;
|
||||||
|
public Invokable(IntPtr parent)
|
||||||
|
{
|
||||||
|
callbackDelegates = new Queue<CallBackDelegate>();
|
||||||
|
handle = CreateWindowEx(0, "#32769", "WF_InvokableNativeWindow", 0, -1, -1, 0, 0, parent, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
StartSubclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartSubclass()
|
||||||
|
{
|
||||||
|
wProc = new Win32WndProc(WndProc);
|
||||||
|
|
||||||
|
if (oldWndProc != IntPtr.Zero)
|
||||||
|
SetWindowLong(handle, GWL_WNDPROC, wProc);
|
||||||
|
else
|
||||||
|
oldWndProc = SetWindowLong(handle, GWL_WNDPROC, wProc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopSubclass()
|
||||||
|
{
|
||||||
|
if (handle != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
SetWindowLong(handle, GWL_WNDPROC, oldWndProc);
|
||||||
|
DestroyWindow(handle);
|
||||||
|
handle = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Invokable() : this(IntPtr.Zero) { }
|
||||||
|
|
||||||
|
public object Invoke(Delegate method, object[] args)
|
||||||
|
{
|
||||||
|
callbackDelegates.Enqueue(new CallBackDelegate(method, args));
|
||||||
|
SendMessage(handle, WF_THREADCALLBACKMESSAGE, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool InvokeRequired
|
||||||
|
{
|
||||||
|
get { return GetWindowThreadProcessId(handle, IntPtr.Zero) != GetCurrentThreadId(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InnerInvoke()
|
||||||
|
{
|
||||||
|
lock (callbackDelegates)
|
||||||
|
{
|
||||||
|
while (callbackDelegates.Count != 0)
|
||||||
|
{
|
||||||
|
CallBackDelegate d = callbackDelegates.Dequeue();
|
||||||
|
d.Delegate.DynamicInvoke(d.Args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int WndProc(IntPtr hWnd, int Msg, int wParam, int lParam)
|
||||||
|
{
|
||||||
|
switch (Msg)
|
||||||
|
{
|
||||||
|
case WF_THREADCALLBACKMESSAGE:
|
||||||
|
InnerInvoke();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Invokable()
|
||||||
|
{
|
||||||
|
StopSubclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class CallBackDelegate
|
||||||
|
{
|
||||||
|
private Delegate _delegate;
|
||||||
|
private object[] _args;
|
||||||
|
|
||||||
|
public CallBackDelegate(Delegate _delegate, object[] args)
|
||||||
|
{
|
||||||
|
this._delegate = _delegate;
|
||||||
|
this._args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Delegate Delegate
|
||||||
|
{
|
||||||
|
get { return _delegate; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] Args
|
||||||
|
{
|
||||||
|
get { return _args; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
188
Speak/Speak/Utils/Util.cs
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using Virtuoso.Miranda.Plugins.Collections;
|
||||||
|
using Virtuoso.Miranda.Plugins.Infrastructure;
|
||||||
|
using Virtuoso.Miranda.Plugins.Native;
|
||||||
|
using Speak.Core;
|
||||||
|
using Speak.Fork;
|
||||||
|
using Speak.Interop;
|
||||||
|
using Speak.Structs;
|
||||||
|
using Encoder=System.Text.Encoder;
|
||||||
|
|
||||||
|
namespace Speak.Utils
|
||||||
|
{
|
||||||
|
internal static class Util
|
||||||
|
{
|
||||||
|
public static DateTime unixEpoc = new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
public static string GetNormalRussian(IntPtr strPtr)
|
||||||
|
{
|
||||||
|
return Util.GetNormalRussian(strPtr, 2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetNormalRussian(IntPtr strPtr, uint size)
|
||||||
|
{
|
||||||
|
byte[] buff = new byte[size];
|
||||||
|
byte letter = 0;
|
||||||
|
int counter = 0;
|
||||||
|
while ((letter = Marshal.ReadByte(strPtr, counter)) != 0)
|
||||||
|
{
|
||||||
|
buff[counter] = letter;
|
||||||
|
counter++;
|
||||||
|
if (counter == size)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Encoding.UTF8.GetString(buff, 0, counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr GetStringPtr(string str, out int length)
|
||||||
|
{
|
||||||
|
byte[] array = Encoding.UTF8.GetBytes(str);
|
||||||
|
IntPtr strPtr = Marshal.AllocHGlobal(array.Length+1);
|
||||||
|
Marshal.Copy(array, 0, strPtr, array.Length);
|
||||||
|
Marshal.WriteByte(strPtr, array.Length, 0);
|
||||||
|
length = array.Length + 1;
|
||||||
|
return strPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OpenURL(string url)
|
||||||
|
{
|
||||||
|
UnmanagedStringHandle str = new UnmanagedStringHandle(url, StringEncoding.Ansi);
|
||||||
|
MirandaContext.Current.CallService(API.MS_UTILS_OPENURL, new IntPtr(1), str);
|
||||||
|
str.Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime GetDateTime(uint timestamp)
|
||||||
|
{
|
||||||
|
int ts = MirandaContext.Current.CallService(API.MS_DB_TIME_TIMESTAMPTOLOCAL, new UIntPtr(timestamp), IntPtr.Zero);
|
||||||
|
return unixEpoc.AddSeconds(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> EnumProtocols()
|
||||||
|
{
|
||||||
|
List<string> result = new List<string>();
|
||||||
|
IntPtr countPtr = Marshal.AllocHGlobal(4);
|
||||||
|
IntPtr arrayPtr = Marshal.AllocHGlobal(4);
|
||||||
|
|
||||||
|
MirandaContext.Current.CallService(API.MS_PROTO_ENUMPROTOCOLS, countPtr, arrayPtr);
|
||||||
|
|
||||||
|
byte[] intArr = new byte[4];
|
||||||
|
Marshal.Copy(countPtr, intArr, 0, 4);
|
||||||
|
int pCount = BitConverter.ToInt32(intArr, 0);
|
||||||
|
|
||||||
|
intArr = new byte[4];
|
||||||
|
Marshal.Copy(arrayPtr, intArr, 0, 4);
|
||||||
|
Int32 itemPtr = BitConverter.ToInt32(intArr, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < pCount; i++)
|
||||||
|
{
|
||||||
|
intArr = new byte[4];
|
||||||
|
Marshal.Copy(new IntPtr(itemPtr+i*4), intArr, 0, 4);
|
||||||
|
IntPtr pdPtr = new IntPtr(BitConverter.ToInt32(intArr, 0));
|
||||||
|
PROTOCOLDESCRIPTOR descriptor = (PROTOCOLDESCRIPTOR)(Marshal.PtrToStructure(pdPtr, typeof(PROTOCOLDESCRIPTOR)));
|
||||||
|
string name = Marshal.PtrToStringAnsi(descriptor.Name);
|
||||||
|
result.Add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.FreeHGlobal(countPtr);
|
||||||
|
Marshal.FreeHGlobal(arrayPtr);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StatusMode GetProtocolStatus(string pName)
|
||||||
|
{
|
||||||
|
return (StatusMode)MirandaContext.Current.CallService(String.Format("{0}{1}", pName, API.PS_GETSTATUS), IntPtr.Zero, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
private delegate IntPtr MirandaPluginInfo(UInt32 mirandaVersion);
|
||||||
|
public static string CurrentMessageEngine()
|
||||||
|
{
|
||||||
|
// SRMM
|
||||||
|
// tabSRMM
|
||||||
|
// Scriver
|
||||||
|
int buffSize = 50;
|
||||||
|
IntPtr buffPtr = Marshal.AllocHGlobal(buffSize);
|
||||||
|
MirandaContext.Current.CallService(API.MS_MSG_GETWINDOWCLASS, buffPtr, new IntPtr(buffSize));
|
||||||
|
byte[] buff = new byte[buffSize];
|
||||||
|
byte letter = 0;
|
||||||
|
int counter = 0;
|
||||||
|
while ((letter = Marshal.ReadByte(buffPtr, counter)) != 0)
|
||||||
|
{
|
||||||
|
buff[counter] = letter;
|
||||||
|
counter++;
|
||||||
|
if (counter == buffSize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Marshal.FreeHGlobal(buffPtr);
|
||||||
|
string engine = Encoding.ASCII.GetString(buff, 0, counter);
|
||||||
|
|
||||||
|
// Scriver 2.8.1.1+ fix
|
||||||
|
if (engine.Equals(LogWindow.ScriverEngine))
|
||||||
|
{
|
||||||
|
Version vScriver = GetModuleVersion("scriver.dll");
|
||||||
|
if (vScriver != null && vScriver > new Version(2, 8, 1, 1))
|
||||||
|
{
|
||||||
|
return LogWindow.ScriverEnginePlus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// SRMM 0.9.0.0+ fix
|
||||||
|
else if (engine.Equals(LogWindow.SRMMEngine))
|
||||||
|
{
|
||||||
|
Version vSRMM = GetModuleVersion("srmm.dll");
|
||||||
|
if (vSRMM != null && vSRMM > new Version(0, 9, 0, 0))
|
||||||
|
{
|
||||||
|
return LogWindow.SRMMEnginePlus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Version GetModuleVersion(string moduleName)
|
||||||
|
{
|
||||||
|
foreach (System.Diagnostics.ProcessModule module in System.Diagnostics.Process.GetCurrentProcess().Modules)
|
||||||
|
{
|
||||||
|
if (module.ModuleName.Equals(moduleName, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
UInt32 mirandaVersion = (UInt32)MirandaContext.Current.CallService(API.MS_SYSTEM_GETVERSION, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
IntPtr pAddressOfFunctionToCall = WinApi.GetProcAddress(module.BaseAddress, "MirandaPluginInfoEx");
|
||||||
|
if (pAddressOfFunctionToCall == IntPtr.Zero)
|
||||||
|
break;
|
||||||
|
|
||||||
|
MirandaPluginInfo pPluginInfo = (MirandaPluginInfo)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(MirandaPluginInfo));
|
||||||
|
IntPtr pluginInfo = pPluginInfo(mirandaVersion);
|
||||||
|
PLUGININFOEX pInfo = (PLUGININFOEX)Marshal.PtrToStructure(pluginInfo, typeof(PLUGININFOEX));
|
||||||
|
byte[] vBytes = BitConverter.GetBytes(pInfo.Version);
|
||||||
|
return new Version(vBytes[3], vBytes[2], vBytes[1], vBytes[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Int32 MakeLParam(int LoWord, int HiWord)
|
||||||
|
{
|
||||||
|
return (HiWord << 16) | (LoWord & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int MakeLong(short lowPart, short highPart)
|
||||||
|
{
|
||||||
|
return (int)(((ushort)lowPart) | (uint)(highPart << 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static short HiWord(int dword)
|
||||||
|
{
|
||||||
|
return (short)(dword >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static short LoWord(int dword)
|
||||||
|
{
|
||||||
|
return (short)dword;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
Speak/Speak/contributors.txt
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
Miranda IM is proudly brought to you by:
|
||||||
|
|
||||||
|
Gennady Feldman
|
||||||
|
Tim Hunter
|
||||||
|
Kubilay Kocak
|
||||||
|
Boris Krasnovskiy
|
||||||
|
Josef Kucera
|
||||||
|
Aaron Landwehr
|
||||||
|
Lyon Lim
|
||||||
|
Tjado Maecke
|
||||||
|
Piotr Piastucki
|
||||||
|
Robert Rainwater
|
||||||
|
Alex Sanda
|
||||||
|
Adam Strzelecki
|
||||||
|
Victor Pavlychko
|
||||||
|
Bartosz Białek
|
||||||
|
|
||||||
|
Retired Members:
|
||||||
|
|
||||||
|
Martin Öberg
|
||||||
|
Denis Stanishevskiy
|
||||||
|
Richard Hughes
|
||||||
|
Emostar
|
||||||
|
Esnow
|
||||||
|
Figbug
|
||||||
|
Tristan_VdV
|
||||||
|
Crypt0gl
|
||||||
|
Lowspirit
|
||||||
|
Glutnix
|
||||||
|
Santithorn Bunchua
|
||||||
|
Sam K
|
||||||
|
Jörgen Persson
|
||||||
|
George Hazan
|
||||||
|
Artem Shpynov
|
||||||
|
Maxim Mluhov
|
||||||
|
Ricardo Domenecci
|
||||||
|
|
||||||
|
Our plugin developers, too multitudinous to name individually, but whos works are nontheless crucial to our success.
|
||||||
|
Special mention to Scott Ellis, a welcome part of arguably almost every Miranda IM installation :)
|
||||||
|
|
||||||
|
Our translators, who have done great things to expand our reach, and who are infuriated that
|
||||||
|
I won't let them change this text.
|
||||||
|
|
||||||
|
Our media developers, who bring us the icons, sounds and skins you love so much.
|
||||||
|
Special mention to Angeli-Ka, a0x, Faith Healer, Quadrone, and Valkyre for their work on the application icons.
|
||||||
|
|
||||||
|
Our bug reporters and moderators, who strive thanklessly to bring quality into Miranda.
|
||||||
|
Special mention to Piotr Lukaszewski aka nowotny, not always smiling, but always doing his part.
|
||||||
|
|
||||||
|
Our forum residents, who discover new and exciting ways to break Miranda daily and who are the gestalt
|
||||||
|
slash 'mob' that shapes how Miranda IM works and evolves.
|
||||||
|
|
||||||
|
Our users, who...er...use it, and without who...well...we love that you love Miranda.
|
BIN
Speak/Speak/res/Icon_exit.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/Icon_show_hide.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/Off.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/On.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/_blank.ico
Normal file
After Width: | Height: | Size: 318 B |
BIN
Speak/Speak/res/arrow_sort_column_down.bmp
Normal file
After Width: | Height: | Size: 150 B |
BIN
Speak/Speak/res/arrow_sort_column_up.bmp
Normal file
After Width: | Height: | Size: 150 B |
BIN
Speak/Speak/res/chat_join.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/chat_leave.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/check_off.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/check_on.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/contact_add.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/contact_delete.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/contact_groups.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/contact_rename.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/contact_view_details.ico
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
Speak/Speak/res/cursor_drag_copy.cur
Normal file
After Width: | Height: | Size: 326 B |
BIN
Speak/Speak/res/cursor_drop_user.cur
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Speak/Speak/res/cursor_hyperlink.cur
Normal file
After Width: | Height: | Size: 326 B |
BIN
Speak/Speak/res/group_closed.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/group_opened.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/icon_accmgr.ico
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
Speak/Speak/res/icon_all.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/icon_ansi.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/icon_auth_request.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/icon_changefont.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/icon_connecting.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/icon_down_arrow.ico
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Speak/Speak/res/icon_file.ico
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
Speak/Speak/res/icon_find_user.ico
Normal file
After Width: | Height: | Size: 6.7 KiB |