artgonch написал(а):
-------------------------------------------------------
> Хочу поинтересоваться, как можно получить
> программный доступ к полю ключ АРМа Каталогизатор:
> [
yadi.sk]
> Есть ли у него какой-то уникальный идентификатор
> среди окон программы?
Это обычный дельфийский контрол TTntEdit, ничем не выделяющийся среди множества своих собратьев. Точно такой же живёт, например, в диалоге «Поиск по словарю/Рубрикатору». Изучение его с помощью утилиты Spy++ (см. приложенный снимок экрана), входящей в поставку Microsoft Visual Studio, не обнаружило у него никаких специфических особенностей (что логично).
Внимательное изучение ресурсов cirbisc_new_unicode.exe показывает, что на самом деле контролов «Ключ» несколько: один для поиска по обычному словарю, другой – для поиска по дереву рубрикатора (есть и ещё и третий, похоже, пока не задействованный). Просто остальные контролы не видны, пока не активируется соответствующий режим. Внешне же они выглядят одинаково, пользователь не замечает подмены (если только он не вооружён Spy++). Так что «заложиться» на один идентификатор контрола не получится.
object FindKeyEdit: TTntEdit
Left = 32
Top = 6
Width = 185
Height = 22
Anchors = [akLeft, akTop, akRight, akBottom]
TabOrder = 0
OnChange = FindKeyEditChange
OnEnter = DictionStringGridEnter
OnKeyDown = FindKeyEditKeyDown
OnKeyPress = FindKeyEditKeyPress
end
...
object TntEdit1: TTntEdit
Left = 88
Top = 64
Width = 121
Height = 22
Font.Charset = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
ParentFont = False
TabOrder = 3
Text = 'TntEdit1'
Visible = False
end
...
object RubFindKeyEdit: TTntEdit
Left = 32
Top = 6
Width = 185
Height = 22
Anchors = [akLeft, akTop, akRight, akBottom]
TabOrder = 0
OnChange = RubFindKeyEditChange
OnEnter = DictionStringGridEnter
OnKeyDown = FindKeyEditKeyDown
OnKeyPress = RubFindKeyEditKeyPress
end
С точки зрения Delphi все эти контролы имеют уникальные (в пределах формы) идентификаторы (FindKeyEdit, TntEdit1, RubFindKeyEdit). Но добраться до идентификаторов средствами WinAPI, похоже, не выйдет.
Впрочем, добраться до самого контрола довольно несложно. Вот программка, которая устанавливает текст в поле «Ключ» и посылает в него перевод строки, чтобы АРМ показал список найденных документов. Вся магия сосредоточена в методе SetKeyText.
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace IrbisKeyWindow
{
public partial class MainForm : Form
{
public delegate bool EnumChildProc
(
IntPtr hwnd,
IntPtr lParam
);
[DllImport("User32")]
public static extern IntPtr FindWindow
(
string lpClassName,
string lpWindowName
);
[DllImport("User32")]
public static extern bool EnumChildWindows
(
IntPtr hWndParent,
EnumChildProc lpEnumFunc,
IntPtr lParam
);
[DllImport("User32")]
public static extern int GetClassName
(
IntPtr hWnd,
StringBuilder lpClassName,
int nMaxCount
);
[DllImport("User32", SetLastError = false)]
public static extern int SendMessage
(
IntPtr hWnd,
int msg,
IntPtr wParam,
string lParam
);
[DllImport("User32", SetLastError = false)]
public static extern int SendMessage
(
IntPtr hWnd,
int msg,
int wParam,
int lParam
);
private const int WM_SETTEXT = 0x000C;
private const int WM_CHAR = 0x0102;
private const int VK_RETURN = 0x0D;
public MainForm()
{
InitializeComponent();
}
private IntPtr foundHwnd;
private bool MyEnumProc
(
IntPtr hwnd,
IntPtr param
)
{
StringBuilder builder = new StringBuilder(1024);
GetClassName ( hwnd, builder, builder.Capacity );
if ( builder.ToString () == "TTntEdit.UnicodeClass" )
{
foundHwnd = hwnd;
return false;
}
return true;
}
private void SetKeyText ( string text )
{
IntPtr mainHwnd = FindWindow("TCmainForm", null);
if (mainHwnd == IntPtr.Zero)
{
MessageBox.Show("Не могу найти АРМ Каталогизатор!");
return;
}
foundHwnd = IntPtr.Zero;
EnumChildWindows(mainHwnd, MyEnumProc, IntPtr.Zero);
if ( foundHwnd == IntPtr.Zero )
{
MessageBox.Show ( "Не могу найти окно Ключ!" );
}
else
{
SendMessage(foundHwnd, WM_SETTEXT, IntPtr.Zero, text);
Thread.Sleep(100);
SendMessage(foundHwnd, WM_CHAR, VK_RETURN, 0);
}
}
private void button1_Click
(
object sender,
EventArgs e
)
{
SetKeyText ( textBox1.Text );
}
[STAThread]
static void Main()
{
Application.Run(new MainForm());
}
}
}
Редактировано 1 раз. Последний раз 01.11.2014 19:21 пользователем amironov73.