public partial class Form1 : Form
{
public struct POINTAPI
{
public int x;
public int y;
}
uint WM_GETTEXT = 13;
uint WM_GETTEXTLENGTH = 14;
// System.Windows.Forms.Cursor.Current.Position
[DllImport("user32")]
public static extern bool GetCursorPos(out POINTAPI lpPoint);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32")]
public static extern int WindowFromPoint(int xPoint, int yPoint);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
как поймать слово под курсом мыши по аналогии Лингво
нагуглил кучу статей. и на русском , и на англ.
это было мое первое знакомство с WinAPI.
в том числе на вашем сайте нашел хороший раздел с описаниями функций API , а также статью, где разбирается аналогичная тема.
Ни один код у меня нормально не работал. и я долго скурпулезно изучал каждую буковку своего кода , пока не добился хоть какого-то результата. код получился такой.
Код:
это идет в самом самом начале.
потом использую все это в такой функции:
Код:
private string poluchit_slovo_kuda_naveden_cursor()
{
POINTAPI pt;
if (GetCursorPos(out pt))
{
IntPtr lTextlen;
IntPtr hnwd = new IntPtr(WindowFromPoint(pt.x, pt.y));
StringBuilder wintest = new StringBuilder(200);
StringBuilder wintest2 = new StringBuilder(200);
lTextlen = SendMessage(hnwd, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
int dlina_pojm_texta = GetWindowText(hnwd, wintest, lTextlen.ToInt32()+1);
return wintest.ToString();
}
else return "";
}
{
POINTAPI pt;
if (GetCursorPos(out pt))
{
IntPtr lTextlen;
IntPtr hnwd = new IntPtr(WindowFromPoint(pt.x, pt.y));
StringBuilder wintest = new StringBuilder(200);
StringBuilder wintest2 = new StringBuilder(200);
lTextlen = SendMessage(hnwd, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
int dlina_pojm_texta = GetWindowText(hnwd, wintest, lTextlen.ToInt32()+1);
return wintest.ToString();
}
else return "";
}
эта функция работает, когда я навожу мышь на кнопку своей формы - выдает текст кнопки. Работает в текстовом поле моей формы - полностью считывает оттуда текст и возвращает. Работает, когда навожу на заголовки форм виндовса - на любое окно наведу - выдает четки названия. например - заголовки страниц броузера, заголовок формы VS и т.п.
ВОПРОС!
1) как сделать, чтобы ловил также текст внутри страниц броузера, Worda , блокнота, файлов справки ???
2) как сделать, чтобы ловил именно слово, а не весь текст большого текстового окна (в случае внутри моей формы например, когда он вместо одного слова хватает целый текст).
3) я вот думаю - можно ли , скажем при наведении на слово мышкой (скажем во время нажатого Alt) - из C# отправить сигнал будто мы 2 раза мышкой его кликнули и скопировали? - с буфером работать то проще. вот только как симитировать этот двойной клик + Ctr+C.
первый вариант предпочтительнее, 3-й тоже нормальный. а второй вопрос - так между делом.
Он заточен под определенные окна, и слова ловит далеко не везде.
Те посылает запоминает буфер обмена, шлет окну ctrl+c, сохраняет текст, восстанавливает оригинальный буффер обмена.
и если через буфер обмена, тоже подходит . только как это сделать?
Код:
uint WM_COPY = 0x301;
string getSelectedText()
{
POINTAPI pt;
if (GetCursorPos(out pt))
{
IntPtr hWnd = new IntPtr(WindowFromPoint(pt.x, pt.y));
SendMessage(hWnd, WM_COPY, IntPtr.Zero, IntPtr.Zero);
return Clipboard.GetText();
}
else return "";
}
string getSelectedText()
{
POINTAPI pt;
if (GetCursorPos(out pt))
{
IntPtr hWnd = new IntPtr(WindowFromPoint(pt.x, pt.y));
SendMessage(hWnd, WM_COPY, IntPtr.Zero, IntPtr.Zero);
return Clipboard.GetText();
}
else return "";
}
Сообщение WM_COPY копирует выделенный текст в буфер обмена.
вот если Ctr+C нажму - тогда функция срабатывает (но тогда она и работает, если в функции будет только одна строчка
Код:
return Clipboard.GetText();
Я вот подумал о другом. в принципе - при наведении это ведь и необязательно.
Вот например пользователь скопировал текст в буфер - как сделать, чтобы приложение узнало, что в буфер поступила новая инфа, чтобы отреагировать?
и еще - как научить приложение реагировать на нажатия клавиш. КОгда окно программы активно - понятно.
Код:
if (e.KeyCode == Keys.ControlKey)
{
string slovo = Clipboard.GetText();
}
{
string slovo = Clipboard.GetText();
}
а как быть, если окно программы не активно, а свернуто. и активно другое приложение? как вернуться к нашему приложению при нажатии Ctr+Shift например.
Цитата: rustamh
нет, функция не работает просто при выделении.
Работает. Но не во всех приложениях. Из Notepad и Wordpad выделенный текст копируется.
В некоторых случаях можно обойтись управляемыми средствами C#:
Код:
// посылаем активному окну Ctrl+C
SendKeys.Send("^c");
// или так
SendKeys.SendWait("^c");
SendKeys.Send("^c");
// или так
SendKeys.SendWait("^c");
Такой метод копирует данные в буфер обмена во всех (вроде бы) приложениях. Но эта команда посылает сообщение активному на данный момент приложению.
Цитата: rustamh
Вот например пользователь скопировал текст в буфер - как сделать, чтобы приложение узнало, что в буфер поступила новая инфа, чтобы отреагировать?
Можно запустить таймер и в его обработчике проверять буфер.