Win API
Создание поля для ввода текста на Win API

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: 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, вставляем полученный текст в нужное окно. И в конце не забываем отчистить память.

На этом все. Удачи в программировании.

.: Пример к данной статье :.


При использовании материала - ссылка на сайт обязательна