Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СКТ - 5,6сем.doc
Скачиваний:
6
Добавлен:
01.05.2025
Размер:
9 Мб
Скачать
☆

Работа с мышью

Сообщения посылаются при перемещении мышки и при нажатии кнопок. В ответ на действия с мышью ядро Windows посылает следующие сообщения.

Действие пользователя

Сообщение

Перемещение мышки

Нажата левая кнопка

Отпущена левая кнопка

Дважды нажата левая кнопка

Нажата средняя кнопка

Отпущена средняя кнопка

Дважды нажата средняя кнопка

Нажата правая кнопка

Отпущена правая кнопка

Дважды нажата правая кнопка

WM_MouseMove

WM_LButtonDown

WM_LButtonUp

WM_LButtonDblClk

WM_MButtonDown

WM_MButtonUp

WM_MButtonDblClk

WM_RButtonDown

WM_RButtonUp

WM_RButtonDblClk

Поле wParam сообщений, относящихся к мышке, содержит слово, описывающее состояние клавиатуры и кнопок мышки. Например, значение wParam равно mk_Control, если нажата клавиша Control. Равно mk_LButton, если нажата левая кнопка мышки и т.д.

Поле lParam содержит координаты курсора. LParamLo содержит координату по оси Х, lParamHi содержит координату по оси Y. Эти координаты всегда определены относительно левого верхнего угла окна. Команды для получения координат:

x:=LOWORD(LParam);

y:=HIWORD(LParam);

Сообщения, относящиеся к мышке, посылаются окну только в том случае, если курсор находится внутри окна или сообщения от мышки перехватываются данным окном. Это может произойти в случае использования функции SetCapture, которая указывает Windows на необходимость посылки всех сообщений от мышки указанному окну. Эта функция позволяет перехватать весь ввод от мышки и перенаправить его указанному окну, независимо от положения курсора.

Обычно эта функция используется при выполнении выделения какой-либо области экрана с помощью мышки. Перехватывание мышки одним окном делает недоступным сообщения от мышки другим окнам. После завершения выполнения этих операций мышь должна быть возвращена всем окнам при помощи процедуры ReleaseCapture.

Ресурс панель диалога

Панелью диалога называется специализированное окно, поддерживающее стандарт фирмы IBM SAA/CUA для ввода/вывода информации. Состав и расположение элементов управления в диалоговой панели указывается в ресурсе, описывающем панель диалога. Ядро Windows предоставляет шесть типов элементов управления:

  1. кнопки

  2. комбинированные списки

  3. строки редактирования

  4. списки

  5. полосы прокрутки

  6. статический текст

Помимо использования предопределенных элементов управления, также возможно использование нестандартных элементов управления, создаваемых программистом.

Панели диалога могут быть двух типов – модальные и немодальные. Модальная панель диалога не позволяет пользователю взаимодействовать с другими окнами программы до тех пор, пока пользователь не закроет эту панель. Немодальная панель диалога по своему поведению подобна окну, и пользователь может параллельно взаимодействовать с другими окнами или другими немодальными панелями диалога программы.

Для создания и использования панели диалога необходимо выполнить следующие шаги:

  1. создать ресурс типа панели диалога

  2. создать диалоговую функцию, обрабатывающую сообщения посылаемые панели диалога

  3. создать панель диалога, используя функцию DialogBox для модальных или функцию CreateDialog для немодальных панелей.

  4. для завершения работы с панелью диалога необходимо использовать функцию EndDialog для модальных или DestroyWindows для немодальных панелей диалога.

Рассмотрим ресурс панели диалога.

Dial DIALOG 18, 18, 142, 92 координаты

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION «Ввод целых чисел»

BEGIN

CONTROL «Введите координату х:», 201, «STATIC», SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 14, 95, 8

CONTROL «», 202, «EDIT», ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 90, 13, 26, 12

CONTROL «Ок», 203, «BUTTON», BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 21, 64, 24, 14

CONTROL «Отмена», 204, «BUTTON», BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 82, 64, 31, 14

CONTROL «», 205, «EDIT», ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 90, 30, 26, 12

END

Диалоговая функция имеет вид.

Function About (Dlg: hWnd; iMessage, wParam: Word; lParam: LongInt): WordBool; export;

begin

About:=False;

case iMessage of

WM_InitDialog:

About := True;

WM_Command:

case wParam of

203, 204: {ok, cancel}

begin

EndDialog(Dlg, 0);

About := True;

end;

end;

end;

end;

Сообщение WM_InitDialog посылается перед отображением панели диалога. В обработчике этого сообщения можно предусмотреть установку фокуса на любой элемент управления, входящий в состав панели диалога, при помощи функции SetFocus. Параметром этой функции является ссылка на элемент управления, который должен получить фокус; возвращаемое значение дает ссылку на элемент управления, который потерял фокус в результате действия этой функции. Если не требуется специальных действий, то обработчик должен возвратить True. В этом случае ядро Windows установит фокус на первый элемент управления в ресурсе, имеющий стиль WS_TABSTOP.

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

Для модальной панели диалога можно использовать те же стили, что и для окон (ws_Caption, ws_SysMenu). При отображении модальной панели начинает работу собственный цикл обработки сообщений. Родительское окно становится неактивным, сообщения ему не посылаются. Таким образом, модальная панель не должна иметь атрибут ws_Child, так как при неактивном родительском окне становятся неактивными все дочерние окна. Для отображения модальной панели используется функция DialogBox, для завершения работы – EndDialog.

function W1(Wnd: hWnd; iMessage, wParam:Word; lParam: LongInt): LongInt; export;

var ProcInst: Pointer;

begin

case iMessage of

WM_Command:

case Wparam of

110: идентификатор окна About

begin

ProcInst := MakeProcInstance(@About, hInstance);

DialogBox(hInstance, 'AboutBox', Wnd, ProcInst);

FreeProcInstance(ProcInst);

end;

end;

WM_Destroy:

PostQuitMessage(0);

end;

W1 := DefWindowProc(Wnd, iMessage, wParam, lParam);

end;

Функция MakeProcInstance обеспечивает доступность данных программы в косвенно вызываемых функциях. Функция FreeProcInstance освобождает выделенную под панель диалога память.

Немодальная панель диалога обычно имеет стили ws_Popup, ws_Caption, ws_Border и ws_SystemMenu. Немодальные панели получают сообщения от основного цикла обработки сообщений (функция WinMain). Для проверки того, предназначено сообщение окну или панели диалога, используется функция IsDialogMessage. Таким образом, цикл обработки сообщений будет выглядеть следующим образом.

While GetMessage(Msg, 0, 0, 0) do

begin if(mhDlg and ord(IsDialogMessage(mhDlg,aMsg)))=0 then

begin

TranslateMessage(msg);

DispatchMessage(msg);

end;

end;

В связи с тем, что немодальная панель может присутствовать не все время работы программы, то необходимо проверять ссылку на панель диалога mhDlg для того, чтобы убедиться в присутствии такой панели. Функция IsDialogMessage отправляет сообщения, посылаемые панели диалога на обработку, поэтому для таких сообщений не должна вызываться пара функций TranslateMessage и DispatchMessage. Для завершения работы с немодальной панелью используется функция DestroyWindow.

Имеется специальный тип панели диалога – панель сообщения, которая состоит из заголовка, нескольких строк, содержащих сообщение и кнопок. Панель сообщения вызывается функцией MessageBox.

Nitem:=MessageBox(Parent,Text,Caption,TextType);

Обработка элементов управления диалогового окна

В следующем примере будет использоваться элемент управления кнопка-переключатель (RADIOBUTTON). Для отметки кружка переключателя в окне используется функция CheckRadioButton. Эта функция также позволяет послать часть сообщения, а точнее, wParam, на обработку сообщения WM_COMMAND. При использовании функции CheckRadioButton необходимо последовательно пронумеровать идентификаторы переключателей. Второй параметр функции – это первый идентификатор списка переключателей, третий параметр функции – последний идентификатор.

Элемент управления – строка редактирования – позволяет вводить текстовую и целочисленную информацию. Текстовая информация обрабатывается функцией GetDlgItemText, а при обработке целочисленной информации вызывается функция GetDlgItemInt.

Пример.

program WW;

{$R Dialog}

uses WinProcs, WinTypes;

var

Wnd: hWnd;

n : integer; {содержит номер выбранной радио-кнопки}

x : integer;

function DialogProc(Dlg: hWnd; iMessage, wParam: Word; lParam: LongInt): WordBool; export;

begin

DialogProc:=False;

case iMessage of

WM_InitDialog:

DialogProc := True;

WM_Command:

case wParam of

200: {cancel}

begin

EndDialog(Dlg, 0);

DialogProc := True;

end;

1001: begin n:=1;

CheckRadioButton(Dlg,1001,1002,wParam)

end;

1002: begin

n:=2;

CheckRadioButton(Dlg,1001,1002,wParam);

end;

100: {ok} {202 – строка ввода для целого х}

begin

x:=GetDlgItemInt(Dlg,202,nil,true);

EndDialog(Dlg, 0);

DialogProc := True;

end;

end;

end;

function W1(Wnd: hWnd; iMessage, wParam:Word; lParam: LongInt): LongInt; export;

var

ProcInst: Pointer;

DC: hDC;

PaintStruct: TpaintStruct;

begin

case iMessage of

WM_Command:

case Wparam of

101:

begin

ProcInst := MakeProcInstance(@DialogProc, hInstance);

DialogBox(hInstance, 'D1', Wnd, ProcInst);

FreeProcInstance(ProcInst);

InvalidateRect(Wnd,nil,true); {перерисовка окна после выбора примитива}

UpdateWindow(Wnd);

еnd;

…

end;

WM_Paint:

begin

DC := BeginPaint(Wnd, PaintStruct);

if n=1 then

begin

MoveTo(DC,10,20);

LineTo(DC,100,200);

end;

if n=2 then Ellipse(DC,x,x+100,100,200);

EndPaint(Wnd, PaintStruct);

end;

WM_Destroy:

PostQuitMessage(0);

else

W1 := DefWindowProc(Wnd, iMessage, wParam, lParam);

end;

end;