Каждый (почти) элемент управления в Windows - это само окно. У него есть свой класс и имя экземпляра. Поскольку конструкция каждого окна MailTo в каждом почтовом клиенте остается неизменной, после получения знаний о том, как найти соответствующий элемент управления, можно построить решение.
Вот где Spy ++ из Visual Studio пригодится (если у вас его нет, попробуйте найти какой-нибудь похожий инструмент, есть бесплатная версия на http://msdn.microsoft.com/pl-pl/magazine/cc163617(en-us).aspx, но в ней нет классного инструмента поиска).
Итак, после запуска Spy ++ и почтовой программы мы нажимаем «Новая почта» и появляется окно почтовой рассылки. Обновите Spy ++ и используйте инструмент «Найти окно» - нажмите на свой список TO, и вы узнаете, как он построен.
Я начал с Outlook Express. Почтовое окно имеет класс ATH_Note, тогда внутри адресной области находится окно класса OE_Envelope и внутри этого окна есть несколько окон, некоторые из которых имеют класс RichEdit20W. Поле «Кому» является первым.
procedure UpdateToOE;
var
Window:Thandle;
Text:PChar;
begin
{Lets find Mail window}
Window:=FindWindow('ATHNote',nil);
if (Window = 0) then Exit;
{Lets find adress area inside}
Window:= FindWindowEx(Window,0,'OEEnvelope',nil);
if (Window = 0) then Exit;
{Lets find TO field - remeber this is the first field of this class}
Window:= FindWindowEx(Window,0,'RichEdit20W',nil);
if (Window = 0) then Exit;
{Prepare text into PChar}
Text:='test@test.com';
{Send message WMSETTEXT which will set our text in control}
SendMessage(Window,WMSETTEXT,0,Integer(Text));
{Sending one extra space to prevent OE does not notice - answer to grzegorz's question}
SendMessage(Window,WM_CHAR,32,1);
//done!
End;
Примечание: FindWindowEx, когда второй параметр равен 0, всегда будет искать ПЕРВЫЙ в строке - так, но если вы сделаете что-то вроде этого:
Window:=FindWindow('ATH_Note',nil);<br>
if (Window = 0) then Exit;<br>
Window:= FindWindowEx(Window,0,'OE_Envelope',nil);<br>
if (Window = 0) then Exit;<br>
Sibling:= FindWindowEx(Window,0,'RichEdit20W',nil);<br>
if (Sibling = 0) then Exit;<br>
Window:=FindWindowEx(Window, Sibling, 'RichEdit20W',nil);<br>
if (Window = 0) then Exit;<br>
Text:='test@test.com';<br>
SendMessage(Window,WM_SETTEXT,0,Integer(Text));<br>
Текст будет помещен во ВТОРОЕ поле редактирования. См. Msdn для FindWindowEx.
Таким образом, это хорошо для OE (XP SP3 IE7). Но что с MS Outlook? Я проверил это с помощью Spy ++ на работе, и поле «Кому» является вторым по счету классом «RichEdit20WPT» (примечание T в конце), родительским классом является «# 32770 (Dialog)», родительским классом является «AfxWndW» и один раз снова родительский класс - «AfxWndW» (это своего рода TPanel в стиле MS в TPanel) и - тадам! - почтовое окно класса «rctrl_renwnd32». Таким образом, псевдокод для этого будет:
Window:=FindWindow('rctrl_renwnd32',nil);<br>
Window:= FindWindowEx(Window,0,’AfxWndW’,nil);<br>
Window:= FindWindowEx(Window,0,’AfxWndW’,nil);<br>
Window:= FindWindowEx(Window,0,’#32770 (Dialog)’,nil);<br>
//Search for FIRST (don’t know what it is)<br>
Sibling:= FindWindowEx(Window,0,’RichEdit20WPT’,nil);<br>
//Search for TO field<br>
Window:= FindWindowEx(Window,Sibling,’RichEdit20WPT’,nil);<br>
Text:='test@test.com';<br>
SendMessage(Window,WM_SETTEXT,0,Integer(Text));<br>
Возможно, вы захотите использовать WM_GETTEXT для извлечения текущего текста и обновления нового текста соответствующим образом, но это выходит за рамки попадания в поле редактирования.
Кстати: этот код сильно зависит от версии Outlook, поэтому попробуйте проверить свою версию с помощью Spy ++ до этого.