Федеральное государственное образовательное учреждение Высшего профессионального образования «Южный федеральный университет» Авакян Леон Александрович «использование win api функций в среде делфи» (учебно-методическое пособие)

2.2. Создание кнопок (button) средствами WinAPI

Создание кнопки производится с помощью уже использованной нами для создания окна функцией CreateWindow. В качестве класса окна нужно использовать определенный в системе класс кнопки BUTTON. Основные доступные классы, предоставляемые операционной системой, следующие: LISTBOX, COMBOBOX, MEMO, MAINMENU, EDIT, SCROLLBAR, BUTTON, LISTVIEW, STATIC, TREEVIEW, HEADER, TOOLBAR, STATUSBAR, TRACKBAR, UPDOWN, PROGRESS, TABCONTROL, RICHEDIT, POPUPMENU, CHECKBOX, LABEL, GAUGE.

Изменим оконную функцию, описанную в предыдущем разделе, следующим образом:

function WindowProc(hWnd: THandle; uMsg, wParam, lParam: Integer): Integer; stdcall; export;

{функцияокна}

begin

Result := 0;

case uMsg of

WM_DESTROY: //если uMsg равна WM_DESTROY(кодзакрытияокна), тозакрываемся

begin

halt(0);

end;

WM_CREATE: begin

// созданиекнопки

hButton := CreateWindowEx (0,

'BUTTON', // определенныйкласскнопки

'&Нажмите здесь', // надпись на кнопке

ws_Child or ws_Visible

or bs_PushButton, // стилидлякнопки

10, 10, // координаты левого верхнего угла

200, 80, // размер

hWnd, // handle родителя

id_Button, // идентификатор кнопки (задается программистом)

hInstance,

nil);

end;

WM_COMMAND:

// проверяем, от какой кнопки пришло сообщение

if LoWord (wParam) = id_Button then

// еслиэтособытие - click

if HiWord (wParam) = bn_Clicked then

// код обработки нажатия кнопки

MessageBox (hWnd, 'Вы нажали на кнопку', '', MB_OK);

end;

Result := DefWindowProc(hWnd, uMsg, wParam, lParam);

end;

Теперь при создании окна (при получении сообщения WM_CREATE) создается экземпляр кнопки с указанными параметрами.

Обработка сообщений, передаваемых элементам управления, реализована с помощью сообщения WM_COMMAND, приходящего родительскому окну. В этом случае, первые 2 байта wParam хранят идентификатор элемента, остальные 2 – код уведомления/события. Таким образом, для того, чтобы обработать нажатие на кнопку, нужно принять сообщение WM_COMMAND и проанализировать параметр оконной функции wParam.

2.3. Создание однострокового редактора (Edit) средствами WinAPI

Создание строкового редактора осуществляется аналогично кнопке с помощью процедуры CreateWindow, но с использованием класса EDIT:

hEdit := CreateWindow ('EDIT', // стандартный класс

'Hello', // текст

WS_CHILD or WS_VISIBLE or WS_TABSTOP or

WS_BORDER, // стиль

10, 10, // положение

150, 24, // размер

hWnd, // родительское окно

id_Edit, // идентификатор данного контрола

hInstance, // как обычно - экземпляр программы

nil) ;

Чтобы созданный элемент был дочерним по отношению к главному окну – необходимо указать флаг WS_CHILD в стиле элемента. Также, для каждого элемента применимы как стандартные WS_ флаги стилей, так и свои собственные (ES_, BS_, SS_ и т.д.) которые зачастую являются специфичными только для этого типа элементов.

Для получения доступа к текстовой строке Edit’а, воспользуемся функциями GetWindowText и SetWindowText. Первая функция копирует строку в указанный буфер. В нашем случае этой строкой является содержимое edit’а. Вторая функция позволяет установить текст (если это возможно).

Дополним предыдущий пример с использованием этих функций так, чтобы при нажатии на кнопку появлялось окно с текстом edit’а. Оконная функция будет иметь следующий вид:

function WindowProc(hWnd: THandle; uMsg, wParam, lParam: Integer): Integer; stdcall; export;

{функция окна}

varp^: Pointer; // буфер для считывания строки

begin

Result := 0;

case uMsg of

WM_DESTROY:

halt(0);

WM_CREATE: begin

// create button

hButton := CreateWindowEx (0,'BUTTON','&Click here',

ws_Child or ws_Visible or bs_PushButton, 10, 100, 200, 80, hWnd,

id_Button, hInstance, nil);

// create edit

hEdit := CreateWindow ('EDIT','Hello',

WS_CHILD or WS_VISIBLE or WS_TABSTOP or WS_BORDER,

10, 10,250, 24,hWnd,id_Edit,hInstance,nil) ;

SetWindowText( hEdit, 'некоторый текст'); // меняем текст

end;

WM_COMMAND:

if LoWord (wParam) = id_Button then

if HiWord (wParam) = bn_Clicked then

// обработканажатиякнопки

begin

GetMem(p, 255*SizeOf(Char)); // подготовкабуфера

GetWindowText(hEdit, p, 255*SizeOf(Char)); // считываниетекставбуфер

MessageBox (hWnd, PChar(p), 'текст в Edit', MB_OK);

FreeMem(p); // освобождениебуфера

end;

end;

Result := DefWindowProc(hWnd, uMsg, wParam, lParam);

end;

Результат работы представлен на рисунке:

2.3. Создание многострокового редактора (Memo) средствами WinAPI

Создание многострокового редактора производится на основе уже рассмотренного элемента EDIT путем использования стиля ES_MULTILINE следующим образом:

hMemo := CreateWindow('EDIT', 'Memo1', WS_VISIBLE or WS_CHILD or WS_DLGFRAME or WS_VSCROLL or ES_MULTILINE or ES_AUTOVSCROLL, // cтилидля edit-элемента

5, 180, 250, 70, hWnd, 0, hInstance, nil);

Модифицируем код предыдущего пункта так, чтобы текст edit’а сохранялся в Memo1 после нажатия на кнопку. Для этого изменим код обработчика нажатия на кнопку следующим образом:

var p: PChar;

WM_COMMAND:

if LoWord (wParam) = id_Button then

if HiWord (wParam) = bn_Clicked then

// обработка нажатия кнопки

begin

GetMem(p, 32*1024); // подготовка буфера

// получим текст из Memo

GetWindowText(hMemo, p, 32*1024);

// добавление символа конца строки

Move(#13#10, PChar(Integer(p) + Length(p))^, 2);

// добавление текста из Edit

GetWindowText(hEdit, PChar(Integer(p + Length(p))), 32*1024);

// устанавливаем новый текcт в Memo

SetWindowText(hMemo, p);

// прокрутка memo до самого конца

while (LOWORD(SendMessage(hMemo, EM_SCROLL, SB_PAGEDOWN,0))<> 0) do;

FreeMem(p); // освобождение буфера

end;

Результат работы представлен на рисунке:

2.4. Меню на WinAPI

Работа с меню тоже достаточно проста и логична. Как и каждый элемент управления, меню имеет свой дескриптор (HMENU). Он позволяет обращаться и изменять свойства пункта или группы пунктов.

Основные функции, необходимые нам для работы с меню:

  - CreateMenu – создаёт главное меню

  - CreatePopupMenu – создание всплывающего меню

  - AppendMenu – добавление какого-либо пункта в меню

  - ModifyMenu – изменение свойств пункта или группы

  - SetMenu – установка меню для окна

Удаление пунктов (DeleteMenu) используется редко и остается для самостоятельного изучения.

Обработка сообщений присланных меню аналогична работе с кнопками – приходит сообщение WM_COMMAND с идентификатором пункта.

Ниже приведен код, который создает главное меню окна и всплывающее меню:

const

sClassName = 'myWindow'; // Имяклассаокна

id_Button = 100; // id for button click

id_edit = 101; // id for edit

// ids for menu

id_action = 1;

id_save = 2;

id_about = 3;

id_exit = 4;

WM_CREATE: begin

// create button

hButton := CreateWindowEx (0,'BUTTON','&Click here', ws_Child or ws_Visible or bs_PushButton, 10, 100, 200, 80, hWnd,

id_Button, hInstance, nil);

// create edit

hEdit := CreateWindow ('EDIT', 'Hello', WS_CHILD or WS_VISIBLE or WS_TABSTOP or ES_MULTILINE or ws_border,

10, 10, 250, 24, hWnd, id_Edit, hInstance, nil) ;

SetWindowText( hEdit, 'некоторый текст');

// create memo

hMemo := CreateWindow('EDIT', 'Memo1', WS_VISIBLE or WS_CHILD or WS_DLGFRAME or WS_VSCROLL or ES_MULTILINE or ES_AUTOVSCROLL, 5, 180, 250, 70, hWnd, 0, hInstance, nil);

// созданиеменю

m_main := CreateMenu;

m_file := CreatePopupMenu;

// MF_STRING - обычная строка

// MF_SEPARATOR - разделительная полоса в меню

// MF_POPUP - добавляет всплывающее меню

// заполняем всплывающее меню

AppendMenu(m_file, MF_STRING, id_save, 'сохранить как'); // сохранить содержимое memo

AppendMenu(m_file, MF_SEPARATOR, 0, nil); // разделитель

AppendMenu(m_file, MF_STRING, id_exit, 'выход'); // выход из программы

// заполняем главное меню

AppendMenu(m_main, MF_POPUP, m_file, 'файл'); // "цепляем" всплывающее меню

AppendMenu(m_main, MF_STRING, id_about, 'о программе'); // добавляем пункт

// выравниваемпункт меню "о программе" по правому краю

ModifyMenu(m_main, 1, MF_BYPOSITION or MF_HELP, id_about, 'о программе');

// назначаем главное меню программы

SetMenu(hWnd, m_main);

end;

Для задания реакции на выбор конкретного пункта меню обрабатываем сообщение WM_COMMAND, как и в случае кнопки, например, следующим образом:

WM_COMMAND:

case LoWord (wParam) of

id_Button:

id_about: // окошкоопрограмме

MessageBox(hWnd, 'программа на чистом WinAPI', 'о программе', MB_ICONINFORMATION);

id_exit: // отправляем сами себе сообщение о закрытии окна

PostMessage( hWnd, WM_CLOSE, 0, 0 );

end;

Полученное меню представлено на рисунке:

2.5. Стандартные диалоговые окна

Стандартные компоненты OpenDialog, SaveDialog и аналогичные также используют чистый WinAPI код. Но необходимые для их создания функции находятся в библиотеке “commdlg32.dll”. Следовательно, для того, чтобы их использовать, необходимо подключить модуль CommDlg.pas к нашему проекту (добавить его в секцию uses).

Для создания и работы с диалогами существует множество функций, но нам понадобится только одна: GetSaveFileName. Эта функция открывает стандартное окно выбора файла для сохранения, схожее, как две капли воды, с окном, открываемым TSaveDialog’ом. Результат функции при неудачном выборе файла (нажатие кнопки отмены или другие напасти) равен нулю.

Для её использования нам необходимо описать структуру TOpenFilename, характеризующую окно диалога (фильтры, максимальная длина имени файла, выбор нескольких файлов и другие флаги).

Изменим код предыдущего примера так, чтобы при выборе пункта меню “Сохранить”, открывалось стандартное диалоговое окно сохранения для выбора файла. Для этого добавим следующий код в область обработки сообщения WM_COMMAND:

id_exit: // отправляем сами себе сообщение о закрытии окна

PostMessage( hWnd, WM_CLOSE, 0, 0 );

id_save:

begin

// заполняемструктуру TSaveDialog

ZeroMemory(@SaveDialog, SizeOf(SaveDialog));

with SaveDialog do begin

lStructSize := SizeOf(SaveDialog);

hWndOwner := hWnd;

lpstrFilter := 'Текстовые документы (*.txt)'#0'*.txt'#0#0;

lpstrDefExt := 'txt';

// папка должна существовать и файл доступен для записи

Flags := OFN_PATHMUSTEXISTYLE="or OFN_HIDEREADONLY;

// максимальная длина имени файла

nMaxFile := 250;

nMaxFileTitle := nMaxFile;

GetMem(lpstrFile, nMaxFile);

// подготовкабуферадляименифайла

ZeroMemory(lpstrFile, nMaxFile);

end;

if GetSaveFileName(SaveDialog) then begin

// пользователь указал имя файла

GetMem(p, 32*1024);

GetWindowText(hMemo, p, 32*1024);

AssignFile(F, SaveDialog.lpstrFile);

Rewrite(F, 1);

BlockWrite(F, p^, Length(p));

CloseFile(F);

FreeMem(p);

end;

FreeMem(SaveDialog.lpstrFile);

end;

Проектное задание

Модифицировать программу, полученную в конце модуля, так, чтобы при изменении размеров окна элементы управления меняли свои позиции и размеры. Добавить возможность загрузки текстового файла.

Указание: обработать сообщение WM_RESIZE, изменять размеры компонентов функцией SetWindowRect.

  1. Каталог конкурентоспособных предприятий краснодарского края (1)

    Документ
    Осуществление первичной проверки в производственных условиях селекционных перспективных сортов риса, а также производства и реализации семян риса высших репродукций,
  2. Каталог конкурентоспособных предприятий краснодарского края (2)

    Документ
    Буровое и нефтепромысловое оборудование, циркуляционные системы, башни сотовой связи, блоки к циркуляционным системам, емкости до 60м3, поддоны стеновых панелей для панельного домостроения,
  3. Каталог конкурентоспособных предприятий краснодарского края (3)

    Документ
    Омская, Курганинская, Челябинская, Сведрловская, Курская, Белгородская, Воронежская, Волгоградская, Ростовская области, Республики Адыгея, Башкортостан,
  4. М. П. Горчакова-Сибирская (отв ред., Спбгиэу), д-р философ наук, проф (2)

    Документ
    д-р пед. наук, проф. М. П. Горчакова-Сибирская (отв. ред., СПбГИЭУ), д-р философ. наук, проф. Е. А. Гусева (зам. отв. ред. СПбГИЭУ), канд. филолог. наук, Е.
  5. М. П. Горчакова-Сибирская (отв ред., Спбгиэу), д-р философ наук, проф (1)

    Документ
    д-р пед. наук, проф. М. П. Горчакова-Сибирская (отв. ред., СПбГИЭУ), д-р философ. наук, проф. Е. А. Гусева (зам. отв. ред. СПбГИЭУ), канд. пед. наук М.
  6. Департамент внешнеэкономических и межрегиональных связей Костромской области

    Документ
    В целях развития двустороннего межрегионального сотрудничества и расширения взаимовыгодных поставок потребительских товаров и продукции производственно технического назначения департамент внешнеэкономических и межрегиональных связей
  7. Каталог конкурентноспособных предприятий кубани (1)

    Документ
    Мясо, включая субпродукты, сыры жирные, масло животное, цельномолочная продукция, рыбная продукция, зерновые, продукция растениеводства и животноводства
  8. Каталог конкурентноспособных предприятий кубани (2)

    Документ
    Производство прочего подъемно - транспортного оборудования (домкратные установки для подъема подвижного состава,гидравлический инструмент для ремонта и текущего содержания пути и др.
  9. Выпускаемые товары и услуги

    Документ
    Производство изделий медицинского, технического и бытового назначения на основе натурального латекса (перчатки анатомические, хирургические, технические,

Другие похожие документы..