:: MVP ::
|
|
:: RSS ::
|
|
|
Сегодня мы добавим в наше приложение поле для ввода текста. Если провести
аналогию с VCL, то у нас получится TEdit. Мы узнаем, как отреагировать
на изменение содержимого в этом поле (аналогично событию OnChange), и каким
образом можно работать с текстом в окне. Для этого текст, который мы будем
вводить в наше поле, будет также отображаться в другом поле, аналогичном
TLabel в VCL.
Начнем с объявления констант и переменных, необходимых для работы с этими
полями.
const
EditID = 1;
var
Edit: HWND;
Static: HWND;
|
Переходим непосредственно к созданию полей.
// Создаем текстовое поле (аналог TEdit)
Edit := CreateWindowEx( WS_EX_CLIENTEDGE, 'Edit', '',
ES_AUTOHSCROLL or WS_CHILD or WS_VISIBLE,
10, 10, 270, 20, Wnd, EditID, hInstance, nil );
SendMessage( Edit, WM_SETFONT, GetStockObject( ANSI_VAR_FONT ), 0 );
// Создаем текстовое поле (аналог TLabel)
Static := CreateWindowEx( 0, 'Static', '', WS_CHILD or WS_VISIBLE,
10, 46, 270, 20, Wnd, 0, hInstance, nil );
SendMessage( Static, WM_SETFONT, GetStockObject( ANSI_VAR_FONT ), 0 );
|
Эти функции нам уже знакомы, посмотрим, что же в них изменилось. Первое,
на что надо обратить внимание, это имя класса создаваемого окна. В первом
случае это 'Edit', а во втором 'Static'. Текстовое поле имеет расширенный
стиль, а именно, бордюр. Этого мы добились, используя флаг WS_EX_CLIENTEDGE.
Отсутствие этого флага привело бы к созданию "плоского" (Flat) поля (такой
эффект мы можем наблюдать у поля Static). Также обратим внимание на флаг
ES_AUTOHSCROLL при задании стиля окна. Благодаря этому, текст в окне будет
автоматически прокручиваться, если его ширина превысит ширину текстового
поля (на поле Static этот флаг не действует).
Теперь посмотрим, как нужно работать с этим полем.
function WindowProc( Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM ): LRESULT; stdcall;
var
p: PChar;
n: integer;
begin
case Msg of
WM_DESTROY: begin
PostQuitMessage( 0 );
Result := 0;
Exit;
end;
WM_SETFOCUS: SetFocus( Edit );
WM_COMMAND: begin
case LoWord( wParam ) of
EditID:
case HiWord( wParam ) of
EN_CHANGE: begin
n := GetWindowTextLength( lParam ) + 1;
GetMem( p, n );
GetWindowText( lParam, p, n );
SetWindowText( Static, p );
FreeMem( p, n );
end;
end;
end;
end;
else
Result := DefWindowProc( Wnd, Msg, wParam, lParam );
end;
end;
|
Обработка сообщения WM_SETFOCUS сделана для того, чтобы передавать фокус
ввода текстовому полю каждый раз, когда форма становится активной. С
сообщением WM_COMMAND мы уже знакомы. Если наше текстовое поле
(LoWord(wParam)=EditID) послало сообщение, что его содержимое изменилось
(HiWord(wParam)=EN_CHANGE), то мы отображаем этот текст в поле Static.
Используя функцию GetWindowTextLength, мы узнаем длину текста в окне
(handle окна передается в функцию в качестве параметра). Эта функция
возвpащает длину текста в байтах, но не включает пустой символ окончания.
По этому мы делаем +1. Далее выделяем память, и, воспользовавшись функцией
GetWindowText, получаем текст окна. Аналогично, функцией SetWindowText,
вставляем полученный текст в нужное окно. И в конце не забываем отчистить память.
На этом все. Удачи в программировании.
.: Пример к данной статье :.
|
При использовании материала - ссылка на сайт обязательна
|
|