Кнопки, редакторы, статические элементы

April 26, 2010 by admin Комментировать »

В этом подразделе мы коснемся вопросов, связанных с использованием таких управляющих и декоративных элементов интерфейсов как кнопки, строки редактирования, статические компоненты.

Все перечисленные компоненты интерфейса представляют собой специфические окна, классы которых описаны в самой операционной системе Windows. Эти окна характеризуются тем, что все они будут располагаться в области главного окна приложения. Таким образом, они являются дочерними окнами. Для них описаны дополнительные стили и списки получаемых и обрабатываемых сообщений [2]. Практически всегда для таких окон требуются идентификаторы.

Все необходимые, для выполнения лабораторной работы, вопросы по работе с такими интерфейсными элементами мы обсудим на примере конкретного простого приложения.

clip_image002Пусть нам необходимо разработать программу для перевода целых неотрицательных чисел из десятеричного их представления в шестнадцатеричное представление. Чтобы долго не объяснять интерфейсную часть этого приложения, посмотрим на рисунок. Главное окно в строке заголовка содержит иконку системного меню, наименование программы, кнопку сворачивания окна и кнопку завершения работы. Кнопка распа­хивания окна заблокирована. Элементы интерфейса, расположен­ные в рабочей области главного окна в особенных дополнительных по­яс­не­ниях не нуждаются. Здесь имеются:

? три кнопки (окна класса "button") – очистки ( С ), вычисления ( = ) и выхода из программы ( Exit );

? три статических элемента (окна класса "static") – надписи "Десятеричное число" и "Шестнадцатеричное число", а также декоративный элемент в виде строки подчеркивания;

? два однострочных редактора (окна класса "edit") – верхнее для ввода целого числа и нижнее – для вывода результата преобразования.

Текст этой программы приведен в Приложении Б.

Исполняемая часть кода вызывающей (главной) программы не претерпела практически никаких изменений. Единственное отличие от предыдущего примера содержится в основной части программы в строке, помеченной звездочкой {*}. Здесь вызывается функция CreateWindow для создания окна приложения. Второй параметр этой функции образован в виде арифметического выражения. Вычитание флажка стиля окна WS_MAXIMIZEBOX из обобщенного параметра стиля WS_OVERLAPPEDWINDOW приводит к блокировке кнопки максимизации (распахивания) окна. Пятый и шестой параметры функции содержат значения ширины и высоты окна (константы winWidth, winHeight). Также в разделе объявлений главной программы (строки 1..12) введены несколько других констант и переменных.

Первые две константы (строки 1 и 2) предназначены для указания имени класса окна и значения заголовка окна программы. Две следующие константы (строка 3) содержат линейные размеры окна – ширину и высоту в пикселях.

Последние пять констант предназначены для хранения идентификационных значений для трех кнопок (строка 4) и двух строк редактирования (строка 5). Значения этих констант могут выбираться произвольно.

Глобальные переменные программы (строки 6 .. 12) имеют следующее назначение:

? Window, h1Oper, hRezult – описатели (handle) главного окна и
двух строчных редакторов;

? Mess – переменная для хранения данных сообщений;

? WindowClass – переменная для организации окна приложения;

? st, cMass, i – вспомогательные переменные.

Рассмотрим содержание функции окна программы WindowProc. Состав и назначение параметров функции – это стандарт.

Для того чтобы поместить в окне приложения управляющие элементы, необходимо создать соответствующие им окошки. Для выполнения этих операций используется функция CreateWindow. Обычно команды по созданию дочерних окон задаются в функции главного окна. Размещаются эти команды в функции окна там, где происходит обработка сообщения WM_CREATE (строки 17..28). Это сообщение генерируется Window однажды – при создании главного окна приложения. В нашем случае это строки с 19 по 26. Рассмотрим некоторые из этих команд более подробно.

Текстовые статические окна (аналог компонента класса TLabel в Delphi). Строка 19. Здесь создается окно класса "static". Это один из зарезервированных в Windows классов окон, предназначенных для вывода текстовой информации. Стиль окна детализируется флажковыми атрибутами WS_CHILD, WS_VISIBLE, SS_LEFT – дочернее окно, окошко становится сразу видимым, текст в окошке выравнивается по левой границе. Возвращаемый функцией описатель окошка мы не запоминаем в переменной, т.к. нам он в дальнейшем не понадобится. Аналогичным образом создается и окошко в строке 22. Третье статическое окошко создается командой в строке 21. Это окно мы используем как декоративное – оно нам служит для изображения продолговатого прямоугольника и выступает в качестве результирующей черты. Второй параметр, равный Nil, означает отсутствие текста в данном окне. Третье слагаемое в третьем параметре – SS_WHITEFRAME – это параметр стиля класса "static", означающий, что граница окна будет иметь белый цвет.

Окна однострочных текстовых редакторов (аналог компонента класса TEdit в Delphi). Строка 20. Здесь создается окно класса "edit" и выводится в строку редактирования символ нуль (первые два параметра функции). Третий параметр функции – сумма пяти флажков-параметров стиля. Из них первые три стандартные стили окна. А последние два – ES_LEFT и ES_NUMBER – специфические атрибуты окон класса "edit": выравнивание текста по левой границе окна и установка режима ввода только десятеричных цифр. Последний параметр позволяет нам здесь застраховать программу от ввода пользователем некорректной (нецифровой) информации. Девятый параметр (ed1Oper) предназначен для сопоставления с этим компонентом идентификационного номера, определенного нами как константа со значением 5001. О назначении этого параметра мы поговорим ниже.

Почти также создается окно текстового редактора для вывода результата преобразования (строка 23). По смыслу программы в этом месте можно было бы использовать и статический интерфейсный элемент. Но мы выбрали здесь строку редактирования только для того, чтобы показать еще два полезных атрибута стиля окон класса "edit" – ES_AUTOHSCROLL и ES_READONLY – свойство автоскроллирования (прокрутки) выводимой в область окна информации и свойство "только_для_чтения", запрещающее пользователю редактировать текстовую информацию в этом окошке.

При создании этих двух окон редактирования мы запомнили значения их описателей в соответствующих переменных h1Oper и hRezult, они нам еще понадобятся.

И последние три элемента – обыкновенные (в смысле создания) кнопки (аналог класса TButton в Delphi). Они создаются командами в строках 24, 25 и 26. Это, соответственно, кнопки очистки ( С ), вычисления ( = ) и выхода из программы ( Exit ). В функциях CreateWindow первым параметром стоит имя класса окна "button" – кнопка. Во втором параметре – текстовая строка – надпись на кнопке. Третий параметр содержит, кроме всего прочего, специфический атрибут класса?кнопки – BS_DEFPUSHBUTTON – рамка вокруг кнопки и реализация эффекта "вдавливания" кнопки. Всем кнопкам сопоставлены индивидуальные идентификационные номера для распознавания их в дальнейшем.

Итак, в момент создания окна приложения, ОС Windows посылает функции окна сообщение WM_CREATE и все окошки появляются в рабочей области главного окна. При нажатии на любую из наших кнопок, она генерирует сообщение WM_COMMAND, которое функция окна программы должна обработать. В строках 29..61 функции окна мы программируем специфику обработки этих сообщений. При получении сообщения WM_COMMAND, функция окна должна выяснить, какой из интерфейсных элементов (какая из кнопок) является источником этого сообщения. Для этого мы анализируем младшее слово LoWord параметра wPar, в котором в функцию окна передается идентификационный номер источника сообщения (строка 30). Эти идентификационные номера обозначены константами btnExit, btnClear и btnEq.

Щелчок на кнопке  Exit приводит к передаче главному окну программы сообщения WM_DESTROY(строка 33). При получении этого сообщения цикл обработки сообщений в главной программе завершается и приложение прекращает свою работу.

Щелчок на кнопке  C , по нашему разумению, должен привести к очистке (начальной установке) содержимого текстовых редакторов h1Oper и hRezult. Этого эффекта мы достигаем очень просто – функциями SetWindowText передаем в их рабочие области символ ‘0’ (строка 38) и полностью очищаем окно вывода результата преобразования (строка 39). Одновременно, здесь же, переводим курсор ввода текстовой информации в окно h1Oper, чтобы пользователь мог сразу набирать новое целое число (строка 40).

Вся функциональность нашего, с позволения сказать, приложения сосредоточена в строках 43..58. Здесь реализована последовательность действий по преобразованию целого числа в его шестнадцатеричное представление.

Сначала (строка 45) мы выясняем, сколько цифр в исходном числе. Затем читаем (строка 46) их все и завершающий символ #0 в символьный массив cMass. После этого копируем содержимое массива символов в строковую переменную st (строка 47). Далее, можно преобразовывать содержимое переменной st в шестнадцатеричное представление функцией IntToHex, предварительно получив из строки st целое число (StrToInt64). Однако эти действия мы проводим, предварительно проверив наличие в строке st символов (строка 48). От ввода нецифровых символов в строку st мы застрахованы (атрибут ES_NUMBER при создании окошка). Требуется также проверить и "пустышку", иначе функция StrToInt64 аварийно завершится. Об этом мы сообщим пользователю через окно MessageBox (строка 56) и предоставим ему возможность ввести исходное число (строка 57). В случае штатной работы шестнадцатеричное представление числа отображаем в окошке результата (строка 51). Для разнообразия, мы здесь используем не функцию SetWindowText, а посылаем окну hRezult сообщение WM_TEXT, одновременно передавая ему через параметр LPARAM адрес на строку st с текстом для вывода в окно (строка 51).

Вот, собственно, и вся программа. В строках 62..68 описаны стандартные действия по реакции на сообщение WM_DESTROY (строки 62..66) и обработке по умолчанию остальных сообщений от Windows (строка 68).

 

ПРИЛОЖЕНИЕ Б

(обязательное)

Текст программы

program Dec2Hex;

uses Windows, Messages, SysUtils;

const

{1} ClassName : PChar = ‘VAK_Class’;

{2} WinName : PChar = ‘Преобразователь 10 -> 16’;

{3} winWidth = 490; winHeight = 260;

{4} btnClear = 3001; btnEq = 3002; btnExit = 3003;

{5} ed1Oper = 5001; edRezult = 5002;

var

{6} Window,

{7} h1Oper, hRezult : HWnd;

{8} Mess : TMsg;

{9} WindowClass : TWndClass;

{10} st : String;

{11} cMass : array[0..31] of Char = ‘0000000000000000000000000000000’;

{12} i : Integer;

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

{13} function WindowProc(Wind : HWND; Mess : LongWord;
wPar, lPar : LongInt):LongInt; stdcall;

{14} Begin

{15} WindowProc:=0;

{16} case Mess of

{17} WM_CREATE :

{18} begin

{19} CreateWindow(‘static’,’Десятеричное число’,
WS_CHILD+WS_VISIBLE+SS_LEFT,
30,20,190,20,Wind,0,hInstance,Nil);

{20} h1Oper:=CreateWindow(‘edit’,’0′,
WS_CHILD+WS_VISIBLE+WS_BORDER+ES_LEFT+ES_NUMBER,
290,17,150,30,Wind,ed1Oper,hInstance,Nil);

{21} CreateWindow(‘static’,Nil,
WS_CHILD+WS_VISIBLE+SS_WHITEFRAME,
170,60,270,5,Wind,0,hInstance,Nil);

{22} CreateWindow(‘static’,’Шестнадцатеричное число’,
WS_CHILD+WS_VISIBLE+SS_LEFT,
30,80,250,20,Wind,0,hInstance,Nil);

{23} hRezult:=CreateWindow(‘edit’,”,
WS_CHILD+WS_VISIBLE+WS_BORDER+
ES_LEFT+ES_AUTOHSCROLL+ES_READONLY,
290,77,170,30,Wind,edRezult,hInstance,Nil);

{24} CreateWindow(‘button’,’C’,
WS_CHILD+WS_VISIBLE+BS_DEFPUSHBUTTON,
230,130,80,30,Wind,btnClear,HInstance,Nil);

{25} CreateWindow(‘button’,’=’,
WS_CHILD+WS_VISIBLE+BS_DEFPUSHBUTTON,
330,130,80,30,Wind,btnEq,HInstance,Nil);

{26} CreateWindow(‘button’,’Exit’,
WS_CHILD+WS_VISIBLE+BS_DEFPUSHBUTTON,
330,180,80,30,Wind,btnExit,HInstance,Nil);

{27} Exit;

{28} end;

{29} WM_COMMAND :

{30} case LoWord(wPar) of

{31} btnExit :

{32} begin

{33} SendMessage(Wind,WM_DESTROY,0,0);

{34} Exit;

{35} end;

{36} btnClear :

{37} begin

{38} SetWindowText(h1Oper,’0′);

{39} SetWindowText(hRezult,”);

{40} SetFocus(h1Oper);

{41} Exit;

{42} end;

{43} btnEq :

{44} begin

{45} i:=GetWindowTextLength(h1Oper);;

{46} GetWindowText(h1Oper,@cMass,i+1);

{47} st:=cMass;

{48} if st<>” then

{49} begin

{50} st:=’$’+IntToHex(StrToInt64(st),0);

{51} SendMessage(hRezult,WM_SETTEXT,0,LPARAM(PChar(st)));

{52} SetFocus(h1Oper);

{53} end

{54} else

{55} begin

{56} MessageBox(0,PChar(‘Нет данных’),PChar(‘Error’),MB_OK);

{57} SetFocus(h1Oper);

{58} end;

{59} Exit;

{60} end;

{61} end;

{62} WM_DESTROY:

{63} begin

{64} PostQuitMessage(Wind);

{65} Halt(0);

{66} end;

{67} end;

{68} Result:=DefWindowProc(Wind,Mess,wPar,lPar);

{69} End;

{ Основная программа }

{$R VAK.RES}

BEGIN

with WindowClass do

begin

style:=CS_HREDRAW OR CS_VREDRAW;

lpfnWndProc:=@WindowProc;

cbClsExtra:=0;

cbWndExtra:=0;

WindowClass.hInstance:=SysInit.HInstance;

hIcon:=LoadIcon(hInstance,’ICON_0′);

hCursor:=LoadCursor(0,IDC_ARROW);;

hbrBackground:=GetStockObject(LTGRAY_BRUSH);

lpszMenuName:=”;

lpszClassName:=ClassName;

end;

if RegisterClass(WindowClass)=0 then

begin

MessageBox(0,PChar(‘Нет Класса’),PChar(‘Error’),Mb_OK);

Halt(255);

end;

{*} Window:=CreateWindow(ClassName,WinName,

WS_OVERLAPPEDWINDOW-WS_MAXIMIZEBOX,

CW_USEDEFAULT,CW_USEDEFAULT,

winWidth,winHeight,0,0,HInstance,Nil);

if Window=0 then

begin

MessageBox(0,PChar(‘Нет Окна’),PChar(‘Error’),Mb_OK);

Halt(255);

end;

ShowWindow(Window,SW_SHOW);

UpdateWindow(Window);

while GetMessage(Mess,Window,0,0) do

begin

TranslateMessage(Mess);

DispatchMessage(Mess);

end;

Halt(Mess.WParam);

END.

Оставить комментарий

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