Создание элементов управления
Материал ориентирован на студентов, умеющих читать и понимать программный код и снабжен большим количеством примеров. Приведены некоторые способы управления созданными элементами. Заполнение нулями необходимо для того, чтобы мусор, который, возможно, остался в памяти, не повлиял на параметры, значения которых явно не прописывается (стиль окна, иконка, курсор…). Пример создания простейшего окна… Читать ещё >
Создание элементов управления (реферат, курсовая, диплом, контрольная)
Разработка программ зачастую напоминает священный ритуал, построенный на произнесении ряда обязательных магических заклинаний. Особенно это касается Windows приложений. Windows-заклинания позволяют вывести графическое окно, обработать поступающие сообщения. Порядок их следования предопределен священными руководствами.
Легалов А. И., д.т.н., проф. Сибирского федерального университета Комплексная цель: научиться создавать полноценные программы без использования дополнительных визуальных библиотек, таких как VCL в Delphi или MFC в C++.
Краткое изложение программного материала: в модуле показано как создавать на основе Win API функций:
- · Окна
- · Кнопки
- · Редакторы ввода
- · Меню
- · Стандартные диалоговые окна
Материал ориентирован на студентов, умеющих читать и понимать программный код и снабжен большим количеством примеров. Приведены некоторые способы управления созданными элементами.
Создание окна средствами WinAPI
Для того, чтобы создать окно, необходимо:
- 1. Создать и зарегистрировать в Windows специальный класс окна с помощью функции RegisterClass ();
- 2. Создать (CreateWindow) и показать (ShowWindow) экземпляр окна;
- 3. На этапе создания необходимо указать процедуру, которая будет обрабатывать сообщения, приходящие из операционной системы. В этой процедуре в дальнейшем и будет сосредоточен весь код.
Регистрация специального класса окна производиться с помощью функции ATOM RegisterClass (CONST WNDCLASS *lpWndClass), возвращаемое значение которой равно нулю в случае ошибки. Информация о классе содержится в структуре lpWndClass типа WNDCLASS* (язык C), которую необходимо предварительно заполнить, например, следующим образом (Delphi):
Var WndClass: TWndClass;
FillChar (WndClass, SizeOf (WndClass), 0); //заполняем структуру нулями.
with WndClass do begin.
hInstance := SysInit. hInstance; //Обязательный параметр, идентификатор приложения.
lpszClassName := sClassName; //имя класса.
lpfnWndProc := @WindowProc; // ссылка на оконную функцию.
hbrBackground := GetStockObject (LTGRAY_BRUSH); // способ заливки клиентской области.
end;
Заполнение нулями необходимо для того, чтобы мусор, который, возможно, остался в памяти, не повлиял на параметры, значения которых явно не прописывается (стиль окна, иконка, курсор…).
После того, как создан класс, создаем на его основе окно. Это делается с помощью функции CreateWindow ().
После того, как окно создано, его можно показать, например, с помощью функции ShowWindow (). Следует отметить, что эту функцию можно применить только к родительскому окну, т. е. если приложение содержит главное окно и дочерние компоненты, то аргументом этой функции является дескриптор главного окна.
Прием сообщений осуществляется с помощью нескольких функций: GetMessage (); TranslateMessage (); DispatchMessage (); DefWindowProc ();
Для того, чтобы организовать цикл получения сообщений, нужно в первую очередь написать функцию окна, т. е. функцию, которая будет совершать какие-либо действия в ответ на сообщение (адрес этой функции указывается в структуре WNDCLASS: IpfnWndProc:=@WindowProc). Необходимо правильно описать функцию:
На языке С++:
LRESULT CALLBACK WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
На языке Object Pascal:
function WindowProc (hWnd: THandle; uMsg, wParam, lParam: Integer): Integer; stdcall; export;
где HWND — дескриптор окна, который был получен после выполнения функции CreateWindow (), uMsg — код сообщения (16 бит) (может использоваться, например, следующим образом: if uMsg=WM_CLOSE then …),.
WPARAM, LPARAM — параметры, которые передаются вместе с сообщением (16 бит).
Цикл обработки сообщений имеет следующий вид:
while GetMessage (Msg, 0, 0, 0) do begin.
TranslateMessage (Msg);
DispatchMessage (Msg);
end;
Функция GetMessage () выбирает первое сообщение из очереди сообщений, предназначенных для данного приложения, функция TranslateMessage () переводит виртуальный код сообщения в строку символов, функция DispatchMessage () отправляет сообщение на обработку оконной функцией, заданной при регистрации класса окна.
Оконная функция может иметь следующий вид:
function WindowProc (hWnd: THandle; uMsg, wParam, lParam: Integer): Integer; stdcall; export;
begin.
Result := 0;
case uMsg of.
WM_DESTROY: …
WM_PAINT: …
…
end.
else.
Result := DefWindowProc (hWnd, uMsg, wParam, lParam);
end;
Внутри блока case располагается код, ответственный за особую реакцию приложения на некоторые сообщения (закрытие окна, его перерисовка). Функция DefWindowProc вызывает стандартную оконную функцию, которая обрабатывает все остальные сообщения, не указанные в блоке.
Пример создания простейшего окна приведен ниже. Обратите внимание, что весь код располагается в файле project1. dpr, как и в случае консольного приложения (но без директивы $APPTYPE CONSOLE).
program project1;
uses.
Windows,.
Messages;
const.
sClassName = 'MyWindow'; // Имя класса окна.
var.
hWnd: THandle; // идентификатор окна (дескриптор).
WndClass: TWndClass; //структура WndClass.
Msg: TMsg; //структура для принятия сообщений.
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;
end;
Result := DefWindowProc (hWnd, uMsg, wParam, lParam); // обработать остальные сообщения.
end;
begin.
FillChar (WndClass, SizeOf (WndClass), 0); //заполняем структуру нулями.
with WndClass do begin.
hInstance := SysInit. hInstance;
lpszClassName := sClassName; //имя класса.
lpfnWndProc := @WindowProc; //ссылка на оконную функцию.
hbrBackground := GetStockObject (LTGRAY_BRUSH);
end;
RegisterClass (WndClass); //регистрируем класс.
hWnd := CreateWindow (sClassName, '', WS_OVERLAPPEDWINDOW, 200, 200, 300, 300, 0, 0, hInstance, NIL); //создаем окно.
if hWnd = 0 then begin //если произошла ошибка, то выходим.
MessageBox (0, 'Initialisation failed', NIL, ID_OK);
Exit;
end;
ShowWindow (hWnd, SW_normal); //показываем окно.
while GetMessage (Msg, HWnd, 0, 0) do begin //получаем сообщение.
TranslateMessage (Msg);
DispatchMessage (Msg);
end;
Halt (Msg.wParam);
end.
В результате работы такой программы должно появиться обычное окно, которое можно закрыть стандартным образом.
Все последующие примеры этой главы будут основаны на приведенном коде, изменяться будет лишь оконная функция.