Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 14.02.2016, 18:58
alekso alekso вне форума
Прохожий
 
Регистрация: 17.08.2015
Сообщения: 11
Версия Delphi: DELPHI XE
Репутация: 10
По умолчанию Вопрос по азам Delphi

есть форма с одним label . На события onclick и ondblckick вешаются два обработчика события. Вот код:unit Unit1;
Код:
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;

    procedure Label1DblClick(Sender: TObject);
    procedure Label1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.dfm}

procedure TForm1.Label1Click(Sender: TObject);
begin
ShowMessage('Одинарный клик');
end;

procedure TForm1.Label1DblClick(Sender: TObject);
begin
ShowMessage('Двойной клик');
end;

end.

Программы не отделяет двойной и одинарный клик-почему?

Как delphi определяет от какого из элементов формы приходит событие onclick если на форме несколько элементов одного типа (например button) если в процедурах объекта FORM это явно не прописано. Инициатором события выступает TOBJECT (SENDER:TOBJECT);

Как Delphi определяет какое событие произошло click или dblclick. Это же также явно не прописано и вызывает событие тот же TOBJECT?

Код:
procedure TForm1.Label1DblClick(Sender: TObject);
begin
ShowMessage('Двойной клик');
end;
Админ: Пользуемся тегами для оформления кода! При рецедиве последуют санкции!

Последний раз редактировалось Admin, 14.02.2016 в 19:16.
Ответить с цитированием
  #2  
Старый 14.02.2016, 23:29
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Клик от дблклика отличается паузой между двумя кликами. Если пауза между кликами попадает в заранее заданный интервал, то система получает событие ДблКлик. Клик происходит не в пустоту, а по некоей области экрана. Системой проверяется какой контрол находится под курсором мыши в момент клика.
А вы неправильно понимаете ситуацию. При двойном клике срабатывают 2 события клика. И если вы проигнорируете первый клик, то вы получите событие ДаблКлика. Но вы то этому не даете произойти выдавая сообщение в паузе между кликами. Отмените выдачу сообщения на клик и у вас заработает двойной клик.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 14.02.2016 в 23:36.
Ответить с цитированием
Этот пользователь сказал Спасибо Страдалецъ за это полезное сообщение:
alekso (15.02.2016)
  #3  
Старый 15.02.2016, 11:49
alekso alekso вне форума
Прохожий
 
Регистрация: 17.08.2015
Сообщения: 11
Версия Delphi: DELPHI XE
Репутация: 10
По умолчанию

Цитата:
Сообщение от Страдалецъ
Клик от дблклика отличается паузой между двумя кликами. Если пауза между кликами попадает в заранее заданный интервал, то система получает событие ДблКлик. Клик происходит не в пустоту, а по некоей области экрана. Системой проверяется какой контрол находится под курсором мыши в момент клика.
А вы неправильно понимаете ситуацию. При двойном клике срабатывают 2 события клика. И если вы проигнорируете первый клик, то вы получите событие ДаблКлика. Но вы то этому не даете произойти выдавая сообщение в паузе между кликами. Отмените выдачу сообщения на клик и у вас заработает двойной клик.


А каким образом определяется событие от элемента Управления,
SENDER передает помимо имени объекта сформировавшего события
еще и тип события (одинарный клик, двойной клик и.т.д) ?
Если да то как программно получить тип события?

Последний раз редактировалось alekso, 15.02.2016 в 12:06.
Ответить с цитированием
  #4  
Старый 15.02.2016, 13:02
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Это уже вопросы не по основам Дельфи, а к обработке сообщений Windows. Дельфи, как и все другие программы написанные в Windows и для Windows использует эту систему сообщений, а эта тема уж поверьте одним постом не закончится, а посему отправляю вас к Гуглю. Там на эту тему море готовой информации.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 15.02.2016 в 13:05.
Ответить с цитированием
  #5  
Старый 15.02.2016, 13:50
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

а TLabel в Delphi вообще уникальный объект. Он вроде для пользователя и есть, но его вроде и нет для Windows
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #6  
Старый 15.02.2016, 15:01
alekso alekso вне форума
Прохожий
 
Регистрация: 17.08.2015
Сообщения: 11
Версия Delphi: DELPHI XE
Репутация: 10
По умолчанию

Наверное я не совсем корректно задал вопрос. Попробую разъяснить на примере EDITa.
есть два события клик на edit и изменение в edite:
Код:
procedure TForm3.Edit1Change(Sender: TObject);
begin
ShowMessage('изменение в edit');
end;

procedure TForm3.Edit1Click(Sender: TObject); если объект на FORM3 выполнил действие №1 то покажи SHOWMESSAGE1
//как определяется какое именно действие произошло и процедура узнает что нужно сделать именно действие ShowMessage('Click');
// В процедуре же явно не описано что нужно обрабатывать событие click или change

begin
ShowMessage('Click');
end;

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

Код:
procedure TForm3.Edit1Change(Sender: TObject);  если объект на FORM3 выполнил действие №2 то покажи SHOWMESSAGE2
begin
ShowMessage('изменение в edit');
end;

procedure TForm3.Edit1Click(Sender: TObject);
begin
ShowMessage('Click');
end;
Админ: пятидневный бан за систематическое нарушение правил.

Последний раз редактировалось Admin, 16.02.2016 в 19:09.
Ответить с цитированием
  #7  
Старый 15.02.2016, 15:42
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Цитата:
Сообщение от alekso
я имел ввиду каким образом delphi узнает что произошло именно событие нажатие на метке и обрабатывает его и как можно получить название событие, полагаю что это неявно передает SENDER как инициатор события.
Например какой именно класс иницировал событие я получить могу так:
procedure TForm3.Label1Click(Sender: TObject);
var
st:string;
begin
st:=sender.ClassName;
ShowMessage(st);
end;

А как получить какое именно событие произошло?

Вкратце:
-Программа на VCL работает в потоке, в котором кружится цикл приема сообщений от системы.
-В глобальном смысле, контролы (формы, кнопки, поля ввода и т.д. и т.п.) - окна windows. Вернее даже не сами окна, а обертки над этими окнами. Когда контрол пораждает окно, к этому окну привязывается функция обработки приходящих сообшений Windows.
-В параметры этой функции система передает ряд параметров, по одному из них обертка VCL получает ссылку на контрол-обертку окна и передает этому контролу параметры прилетевшего сообщения.
-Контрол обертка обрабатывает эти сообщения (WM_ACTIVATE, WM_SHOW, WM_MOUSEDOWN и т.д. и т.п.)
-Исходя из перечня обрабатываемых сообщений, контрол генерирует событие OnActivate, OnClick, OnDblClick и т.д. и т.п., передавая в параметр этих событий себя как Sender.

Т.е. при сработке события ты можешь узнать, кто его вызвал.

Что касается "А как получить какое именно событие произошло?". Если ты в событии OnClick пытаешься узнать, какое событие произошло, то наверное OnClick. Либо некорректен вопрос, либо ты не понимаешь чего тебе самому нужно.

И да, TLabel - не оконный контрол. У него нет окна и сообщения получает не он, а его Parent. Но это уже дебри - не забивай голову.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
Этот пользователь сказал Спасибо dr. F.I.N. за это полезное сообщение:
alekso (15.02.2016)
  #8  
Старый 15.02.2016, 16:04
alekso alekso вне форума
Прохожий
 
Регистрация: 17.08.2015
Сообщения: 11
Версия Delphi: DELPHI XE
Репутация: 10
По умолчанию

Цитата:
Сообщение от dr. F.I.N.
Вкратце:
-Программа на VCL работает в потоке, в котором кружится цикл приема сообщений от системы.
-В глобальном смысле, контролы (формы, кнопки, поля ввода и т.д. и т.п.) - окна windows. Вернее даже не сами окна, а обертки над этими окнами. Когда контрол пораждает окно, к этому окну привязывается функция обработки приходящих сообшений Windows.
-В параметры этой функции система передает ряд параметров, по одному из них обертка VCL получает ссылку на контрол-обертку окна и передает этому контролу параметры прилетевшего сообщения.
-Контрол обертка обрабатывает эти сообщения (WM_ACTIVATE, WM_SHOW, WM_MOUSEDOWN и т.д. и т.п.)
-Исходя из перечня обрабатываемых сообщений, контрол генерирует событие OnActivate, OnClick, OnDblClick и т.д. и т.п., передавая в параметр этих событий себя как Sender.

Т.е. при сработке события ты можешь узнать, кто его вызвал.

Что касается "А как получить какое именно событие произошло?". Если ты в событии OnClick пытаешься узнать, какое событие произошло, то наверное OnClick. Либо некорректен вопрос, либо ты не понимаешь чего тебе самому нужно.

И да, TLabel - не оконный контрол. У него нет окна и сообщения получает не он, а его Parent. Но это уже дебри - не забивай голову.



Вопрос скорей вот такой, где именно в коде (а не в инспекторе объектов) я могу увидеть что по событию onclick должна вызваться процедура Edit1Click (ну или другая в зависимости от того как я ее назову).
Ответить с цитированием
  #9  
Старый 15.02.2016, 16:08
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Цитата:
Сообщение от alekso
Вопрос скорей вот такой, где именно в коде (а не в инспекторе объектов) я могу увидеть что по событию onclick должна вызваться процедура Edit1Click (ну или другая в зависимости от того как я ее назову).
Посмотри файл .dfm соответствующий юниту с формой:
Код:
object fAuthorization: TfAuthorization
  Left = 407
  Top = 372
  BorderStyle = bsDialog
  .....................
  KeyPreview = True
  OldCreateOrder = False
  Position = poMainFormCenter
  OnKeyPress = FormKeyPress <<<---------------
  ..........................
  object lePassword: TLabeledEdit
    Left = 136
    Top = 24
    Width = 121
    Height = 21
    EditLabel.Width = 41
    EditLabel.Height = 13
    EditLabel.Caption = #1055#1072#1088#1086#1083#1100':'
    MaxLength = 20
    PasswordChar = '*'
    TabOrder = 1
    OnChange = leLoginChange <<<---------------
  end
......
end

Но и во время работы программы ты можешь самостоятельно назначить любому контролу процедуру обработки события.
procedure TFomr1.MyClickEvent(Sender: TObject);
begin
///////
end;

OkButton.OnClick := MyClickEvent;
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.

Последний раз редактировалось dr. F.I.N., 15.02.2016 в 16:11.
Ответить с цитированием
Этот пользователь сказал Спасибо dr. F.I.N. за это полезное сообщение:
alekso (15.02.2016)
  #10  
Старый 15.02.2016, 16:13
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Можно проверить на задержке, а не двойной ли клик поступил, или тут только одинарка подоспела
Код:
procedure TForm1.Label1Click(Sender: TObject);
var
 Msg: TMsg;
 TargetTime: Cardinal;
begin
 TargetTime:= GetTickCount + GetDoubleClickTime;

 while GetTickCount < TargetTime do
  if PeekMessage(Msg, Handle, WM_LBUTTONDBLCLK, 0, 0) then Exit;

 (Sender as TLabel).Caption:= 'Одинарный клик';
 end;

procedure TForm1.Label1DblClick(Sender: TObject);
begin
 (Sender as TLabel).Caption:= 'Двойной клик';
end;

А увидеть имя процедуры можно в *.dfm файле данной формы
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
alekso (15.02.2016)
  #11  
Старый 15.02.2016, 16:15
alekso alekso вне форума
Прохожий
 
Регистрация: 17.08.2015
Сообщения: 11
Версия Delphi: DELPHI XE
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Можно проверить на задержке, а не двойной ли клик поступил, или тут только одинарка подоспела
Код:
procedure TForm1.Label1Click(Sender: TObject);
var
 Msg: TMsg;
 TargetTime: Cardinal;
begin
 TargetTime:= GetTickCount + GetDoubleClickTime;

 while GetTickCount < TargetTime do
  if PeekMessage(Msg, Handle, WM_LBUTTONDBLCLK, 0, 0) then Exit;

 (Sender as TLabel).Caption:= 'Одинарный клик';
 end;

procedure TForm1.Label1DblClick(Sender: TObject);
begin
 (Sender as TLabel).Caption:= 'Двойной клик';
end;

А увидеть имя процедуры можно в *.dfm файле данной формы



Спасибо огромное!!!
Ответить с цитированием
  #12  
Старый 16.02.2016, 16:36
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

А вот ещё про клики
http://www.transl-gunsmoker.ru/2009/09/windows.html
На его сайте есть ещё много интересного
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:49.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter