API и FreeBasic. (дочерние окна-edit)

Класс Edit предназначен для создания контрола, в который можно как программно , так и вручную с клавиатуры вводить текст. А после ввода есть возможность как редактировать, так и удалять этот текст. Кроме того, на основе этого класса построены некоторые другие классы (например: ListBox, Up-Down Control и др.). Класс имеет очень сложную внутреннюю структуру, однако для разработчиков процесс взаимодействия максимально облегчен. К данному классу привязано немалая часть сообщений, которые позволяют проделывать практически любые операции с этим контролом. Вот наиболее используемые сообщения:

  • em_CanUndo - Опpеделяет, может ли оpган упpавления pедактиpованием ответить на сообщение em_Undo.
  • em_EmptyUndoBuffer - Делает пустым буфеp отмены оpгана упpавления pедактиpованием, котоpый запpещает возможность отмены последнего pедактиpования.
  • em_FmtLines - Указывает оpгану упpавления pедактиpованием, добавлять или нет специальную последовательность символа конца стpоки к стpокам текста, в котоpых имел место пеpенос слов.
  • em_GetHandle - Возвpащает описатель буфеpа оpгана упpавления pедактиpованием. Буфеp содеpжит текст оpгана упpавления pедактиpованием.
  • em_GetLine - Возвpащает одну стpоку из оpгана упpавления pедактиpованием.
  • em_GetLineCount - Возвpащает число стpок текста в оpгане упpавления pедактиpованием.
  • em_GetModify - Возвpащает флаг модификации оpгана упpавления pедактиpованием. Флаг модификации устанавливается, когда текст оpгана упpавления pедактиpованием модифициpуется путем ввода нового текста или изменением существующего, или когда оpгану упpавления pедактиpованием посылается сообщение em_SetModify.
  • em_GetRect - Считывает фоpматиpующий пpямоугольник оpгана упpавления pедактиpованием.
  • em_GetSel - Возвpащает начальный и конечный индексы выбpанного текста в оpгане упpавления pедактиpованием.
  • em_LimitText - Устанавливает пpедельное число символов, котоpое может быть введено в оpган упpавления pедактиpованием.
  • em_LineFromChar - Возвpащает номеp стpоки в оpгане упpавления pедактиpованием, котоpая содеpжит индекс указанного символа.
  • em_LineIndex - Возвpащает индекс символа в начале стpоки в оpгане упpавления pедактиpованием.
  • em_LineLength - Возвpащает длину стpоки, находящейся в оpгане упpавления pедактиpованием, котоpая содеpжит индекс указанного символа, в байтах.
  • em_LineScroll - Пpокpучивает оpган упpавления pедактиpованием.
  • em_ReplaceSel - Заменяет выбpанный текст в оpгане упpавления pедактиpованием.
  • em_SetHandle - Устанавливает текстовый буфеp оpгана упpавления pедактиpованием.
  • em_SetModify - Устанавливает флаг модификации оpгана упpавления pедактиpованием.
  • em_SetPasswordChar - Устанавливает символ, отобpажаемый вместо символов, набpанных в оpгане упpавления pедактиpованием, созданном со стилем es_Password.
  • em_SetRect - Устанавливает фоpматиpующий пpямоугольник для оpгана упpавления pедактиpованием и соответствующим обpазом вновь отобpажает текст.
  • em_SetRectNP - Устанавливает фоpматиpующий пpямоугольник для оpгана упpавления pедактиpованием без нового отобpажения текста.
  • em_SetSel - Опpеделяет выбpанный текст в оpгане упpавления pедактиpованием.
  • em_SetTabStops - Устанавливает позиции табуляции оpгана упpавления pедактиpованием.
  • em_SetWordBreak - Изменяет функцию pазpыва слов оpгана упpавления pедактиpованием.
  • em_Undo - Отменяет последнюю модификацию текста в оpгане упpавления pедактиpованием.

Каждое из этих сообщений можно послать с помощью уже известной функции SendMessage. Полный список, а так же дополнительные параметры при отсылке этих  сообщений можно найти здесь: http://msdn.microsoft.com/en-us/library/aa924582.aspx

Класс Edit так же как и другие классы, кроме общих стилей окон, имеет свои собственные стили и это позволяет значительно расширить возможности редактора:

  • ES_AUTOHSCROLL - Автоматически прокручивает текст вправо на 10 символов, когда пользователь напечатает символ в конце строчки. Когда пользователь нажимает клавишу ENTER, управление прокручивает весь текст обратно, чтобы установить нуль.
  • ES_AUTOVSCROLL - Автоматически перемещает текст вверх на одну страницу, когда пользователь нажимает клавишу ENTER на последней строчке.
  • ES_CENTER - Выравнивает по центру текст в многостроковом поле редактирования текста.
  • ES_LEFT - Выравнивание текста слева.
  • ES_LOWERCASE - Преобразовывает все символы в нижний регистр, поскольку они печатаются внутри поля редактирования текста.
  • ES_MULTILINE - Обозначает многостроковое окно редактирования текста. Значение по умолчанию - одностроковое окно редактирования текста. Когда многостроковое поле редактирования находится в диалоговом окне, заданная по умолчанию ответная реакция на нажим клавиши ENTER должна активизировать кнопку по умолчанию. Чтобы использовать клавишу ENTER для перевода строки, стиль используйте ES_WANTRETURN. Когда многостроковое окно редактирования не в диалоговом окне и определен стиль ES_AUTOVSCROLL, поле редактирования показывает столько строчек, сколько это возможно и прокручивает вертикально, когда пользователь нажимает клавишу ENTER. Если Вы не определяете ES_AUTOVSCROLL, окно редактирования показывает столько строчек, сколько это возможно и подает звуковой сигнал, если пользователь нажимает клавишу ENTER, но больше ни строчки не может отобразиться в окне. Если Вы определяете стиль ES_AUTOHSCROLL, многостроковое окно редактирования автоматически горизонтально прокручивается, когда каретка проходит за правый край элемента управления. Чтобы запустить новую строку, пользователь должен нажать клавишу ENTER. Если Вы не определяете ES_AUTOHSCROLL, элемент управления, когда это необходимо, автоматически переносит без разрыва слова в начало следующей строки. Новая строка образуется и тогда, если пользователь нажимает клавишу ENTER. Размер окна определяет позицию перехода слова на новую строку. Если размер окна изменяется, изменяется позиция перехода на новую строку, а текст восстанавливается. Многостроковое окно редактирования текста может иметь линейки прокрутки . Окно редактирования с линейками прокрутки обрабатывают свои собственные сообщения от линейки прокрутки. Обратите внимание, что окно редактирования без линеек прокрутки, прокручивают текст, как описано в предыдущих параграфах и обрабатывают любые сообщений прокрутки, посланные родительским окном.
  • ES_NOHIDESEL - Отрицает заданное по умолчанию поведение для поля редактирования текста. Заданное по умолчанию поведение скрывает выбор, когда элемент управления теряет фокус ввода и инвертирует выбор, когда панель управления принимает фокус ввода. Если Вы определяете ES_NOHIDESEL, выбранный текст инвертируется, даже если панель управления не имеет фокуса.
  • ES_NUMBER - Позволяет ввести в поле редактирования только цифры.
  • ES_OEMCONVERT - Преобразует текст, введенный в окно редактирования. Текст преобразуется из набора символов Windows - в набор символов OEM, а затем обратно - в набор Windows. Это гарантирует соответствующее символьное преобразование, когда из прикладной программы вызывается функция CharToOem, чтобы преобразовать строку Windows в окне редактирования в символы OEM. Этот стиль наиболее полезен для окон редактирования текста, которые содержат имена файлов.
  • ES_PASSWORD - Отображает звездочку (*) вместо каждого символа, введенного с клавиатуры в окно редактирования. Вы можете использовать сообщение EM_SETPASSWORDCHAR, чтобы заменить ею символ, который отображается.
  • ES_READONLY - Не допускает пользователя к вводу или редактированию текста в окне редактирования.
  • ES_RIGHT - Выравнивает по правому краю текст в многострочном окне редактирования.
  • ES_UPPERCASE - Преобразует все символы в символы верхнего регистра, когда они вводятся в окно редактирования.
  • ES_WANTRETURN - Определяет, чтобы служебный код возврата каретки был вставлен тогда, когда пользователь нажимает клавишу ENTER при вводе текста в многострочное поле редактирования текста в диалоговом окне. Если Вы не определяете этот стиль, нажимая клавишу ENTER, вы получите тот же самый эффект, словно нажали заданную по умолчанию командную кнопку диалогового окна. Этот стиль не имеет никакого влияния в однострочном окне редактирования.

Далее пример создания нескольких контролов:

#INCLUDE "windows.bi"
Dim msg As MSG 'структурированная переменная MSG
Dim As WNDCLASSEX wc 'структурированная переменная WNDCLASSEX
Dim As String NameClass="MyClass" ' переменная имени класса
Dim As HINSTANCE Hinst=GetModuleHandle(0) ' хендл модуля
' функция класса
Function wndproc(hwnd As HWND, msg As Uinteger,_
    wparam As WPARAM, lparam As LPARAM) As Integer
    Static As HWND edit1,edit2,edit3,edit4,button
    Select Case msg
        Case WM_CREATE
            edit1=CreateWindowEx(0,"edit","Простой Edit с горизонтальным автоскролом",WS_VISIBLE Or WS_CHILD Or ES_AUTOHSCROLL,10,10,130,20,hwnd,Cast(HMENU,1),0,0)
            edit2=CreateWindowEx(0,"edit","Ввод с клавиатуры только чисел",WS_VISIBLE Or ES_NUMBER Or WS_CHILD,10,40,230,20,hwnd,Cast(HMENU,2),0,0)
            edit3=CreateWindowEx(0,"edit","Пароль",WS_VISIBLE Or ES_PASSWORD Or WS_CHILD,10,70,80,20,hwnd,Cast(HMENU,3),0,0)
            edit4=CreateWindowEx(0,"edit","Многострочный Edit" ,WS_VISIBLE Or ES_MULTILINE Or ES_AUTOVSCROLL Or WS_CHILD,10,100,100,100,hwnd,Cast(HMENU,4),0,0)
            button=CreateWindowEx(0,"button","вставить текст" ,WS_VISIBLE  Or WS_CHILD,130,100,100,20,hwnd,Cast(HMENU,5),0,0)
        Case WM_COMMAND
            If Loword(wparam)=3 Then
                Dim As ZString*256 text
                GetWindowText(Edit3,@text,256)
                SetWindowText(Edit4,@text)
            Elseif Loword(wparam)=5 Then
                Dim As ZString*256 text
                GetWindowText(Edit2,@text,256)
                SendMessage(Edit4,EM_REPLACESEL,1,Cast(Lparam,@text))
            Endif
        Case WM_DESTROY
            PostQuitMessage(0)
    End Select
    Return DefWindowProc(hwnd,msg,wparam,lparam)
End Function
' Заполнение структуры WNDCLASSEX
With wc
    .cbSize=SizeOf(WNDCLASSEX)
    .style=CS_HREDRAW Or CS_VREDRAW
    .lpfnWndProc=@wndproc
    .hInstance=Hinst
    .hIcon=LoadIcon(0,IDI_QUESTION)
    .hCursor=LoadCursor(0,IDC_ARROW)
    .hbrBackground=Cast(HBRUSH,COLOR_WINDOW)
    .lpszClassName=StrPtr(NameClass)
    .hIconSm=.hIcon
End With
' Регистрация класса окна
If RegisterClassEx(@wc)=0 Then
    Print "Register error, press any key"
    Sleep
    End
Endif
'Создание окна
CreateWindowEx(0,NameClass,"Главное окно",_
WS_VISIBLE Or WS_OVERLAPPEDWINDOW,10,10,300,300,0,0,Hinst,0)
' Цикл сообщений
While GetMessage(@msg,0,0,0)
    TranslateMessage(@msg)
    DispatchMessage(@msg)
Wend


Вот что примерно должно получится:

editapi.png

  • Первый контрол сделан с горизонтальным автоскролом при достижении символами границы. Если сделаете контрол активным, то сможете с помощью клавиш со стрелками просмотреть все содержимое контрола.
  • Второй контрол дает возможность вводить только числовые значения с клавиатуры, однако это не распространяется на программный метод ввода.
  • Третий контрол используется для ввода паролей, поэтому при вводе вместо символов видны звездочки
  • Четвертый контрол имеет свойства многострочного редактора с вертикальным автоскролом.

Кроме того в примере определены события для ввода текста программно. Если вы будете вводить какой-то текст в третий контрол, то он будет отображаться в четвертом. А если нажмете на кнопку, то программа возьмет текст из второго контрола и поместит его в то место, где располагается курсор.

Часто при разработке редакторов используют расширенную версию класса Edit. Этот класс под названием RichEdit обладает рядом улучшений и преимуществ, такие как: многоуровневые операции undo/redo, drag and drop текста, поиск текста в обоих направлениях от положения курсора, автоматическое определение и выделение URL-ссылок в тексте и др.

Основное отличие в его создании заключается только в дополнительном подключении библиотеки RICHED20.DLL , входящей в состав Windows, а так же указание имени класса RICHEDIT20A. Сообщения , посылаемые контролам Edit и RichEdit в большинстве своем являются общими. Пример:

#INCLUDE "windows.bi"
LoadLibrary "RICHED20.DLL"
Dim msg As MSG 'структурированная переменная MSG
Dim As WNDCLASSEX wc 'структурированная переменная WNDCLASSEX
Dim As String NameClass="MyClass" ' переменная имени класса
Dim As HINSTANCE Hinst=GetModuleHandle(0) ' хендл модуля
' функция класса
Function wndproc(hwnd As HWND, msg As Uinteger,_
    wparam As WPARAM, lparam As LPARAM) As Integer
    Select Case msg
        Case WM_DESTROY
            PostQuitMessage(0)
        Case WM_CREATE
            CreateWindowEx(WS_EX_CLIENTEDGE, "RICHEDIT20A", "RichEdit Control",_
            WS_VISIBLE Or WS_CHILD Or WS_HSCROLL Or WS_VSCROLL  Or ES_MULTILINE Or ES_AUTOHSCROLL Or ES_AUTOVSCROLL,_
            10,10,200,200, hwnd, Cast(HMENU,1), 0, 0)
    End Select
    Return DefWindowProc(hwnd,msg,wparam,lparam)
End Function
' Заполнение структуры WNDCLASSEX
With wc
    .cbSize=SizeOf(WNDCLASSEX)
    .style=CS_HREDRAW Or CS_VREDRAW
    .lpfnWndProc=@wndproc
    .hInstance=Hinst
    .hIcon=LoadIcon(0,IDI_WINLOGO)
    .hCursor=LoadCursor(0,IDC_ARROW)
    .hbrBackground=Cast(HBRUSH,COLOR_WINDOWFRAME)
    .lpszClassName=StrPtr(NameClass)
    .hIconSm=.hIcon
End With
' Регистрация класса окна
If RegisterClassEx(@wc)=0 Then
    Print "Register error, press any key"
    Sleep
    End
Endif
'Создание окна
CreateWindowEx(0,NameClass,"RichEdit",_
WS_VISIBLE Or WS_OVERLAPPEDWINDOW,100,100,240,260,0,0,Hinst,0)
' Цикл сообщений
While GetMessage(@msg,0,0,0)
    TranslateMessage(@msg)
    DispatchMessage(@msg)
Wend

На этом все. Всего доброго!

содержание | назад | вперед