клік мишкою

Знайшов WM_LBUTTONUP, WM_LBUTTONDOWN, WM_LBUTTONDBCLK. А ось що то типу WM_LBUTTONCLK (одинарний клік мишею) - не знайшов.

Як тоді відловлювати одинарні кліки мишею?

WM_LBUTTONCLK = WM_LBUTTONDOWN + WM_LBUTTONUP = BM_CLICK (для деяких контролів)

WM_хBUTTONDOWN, де X це L, R, M в залежності від кнопки миші.

Любіть книгу - джерело знань

Ігор Шевченко, не згоден. BUTTONDOWN настає, коли ви тільки натискати на кнопку миші (але не відпускаєте її). А зауважте жоден контрол не реагує ТІЛЬКИ на натискання клавіші без її відпускання. Тобто, якщо ви натиснете на кнопку лівою кнопкою миші, а потім відведете курсор в інше місце і відпустіть, то події OnMouseDown не наступить. Хочеться реалізувати таку ж поведінку у себе в програмі тільки на WinApi.

Song, WM_LBUTTONCLK = WM_LBUTTONDOWN + WM_LBUTTONUP - це я розумію. Але як відстежити, що сюди натиснули кнопки, а потім її відпустили?

Під час обробки WM_хBUTTONDOWN треба встановити прапорець, що на вікні натиснута х-тая копка миші. (Наприклад, csClicked в ControlState у TControl)
При обробці WM_xBUTTONUP перевіряєте, якщо прапорець встановлений, значить, натиснення і відпуск кнопки миші (яке і вважається за click, я не був не зовсім правий 22.08.02 17:49) було виконано на одному і тому ж вікні. Після цього, прапорець скидається і виконується процедура Click

Ігор Шевченко, я теж так подумав. Тільки це не зовсім так. Адже в рельності, якщо натиснути на контрол кнопкою миші, потім відвести курсор в сторону і відпустити кнопку, то стан csClicked скидається. (А якщо реалізовувати по вашій схемі, то у купи контролів може бути стан csClicked). Тобто потрібно ставити щось типу глобального хука на wm_lbuttonup і перевіряти - якщо подія сталася над контролом зі станом csClicked, то натиснення відбулося. Якщо не над ним, то стан csClicked скидається. Ось це имхо і Довга.
Хотілося б простіше.

Ви б подивилися Controls.pas, як реалізований метод TControl.Click
і коли він викликається, перш ніж робити такі заяви.


procedure TControl.WMLButtonDown (var Message: TWMLButtonDown);
begin
SendCancelMode (Self);
inherited;
if csCaptureMouse in ControlStyle then MouseCapture: = True;
if csClickEvents in ControlStyle then Include (FControlState, csClicked);
DoMouseDown (Message, mbLeft, []);
end;


procedure TControl.WMLButtonUp (var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture: = False;
if csClicked in ControlState then
begin
Exclude (FControlState, csClicked);
if PtInRect (ClientRect, SmallPointToPoint (Message.Pos)) then Click;
end;
DoMouseUp (Message, mbLeft);
end;

Ігор Шевченко, знову мабуть ви мене не зрозуміли. Думаю, що Релізація події OnClick в TControl.click складається НЕ тільки з цих процедур. Найідеальніше - якщо ви мені надасте код процедури (процедур), який реалізує Click тільки за допомогою WinApi. Але я ціную ваш час і природно не наполягаю на цьому. Просто хочеться відзначити, що якщо OnClick буде оброблятися ТІЛЬКИ по цих процедур, то вийде "неправильний" click.

Насправді. Підведіть курсор до контролю. Затисніть кнопку миші. Відведіть курсор в сторону. Відпустіть кнопку миші. Натисніть кнопку миші, підведіть курсор до контролю. Відпустіть кнопку миші. Події Click НЕ ВІДБУДЕТЬСЯ.

Якщо алгоритм click "а описується тільки двома представленими вище процедурами. Виконайте те ж саме. Тобто, підведіть курсор до контролю. Затисніть кнопку миші. Відведіть курсор в сторону. Відпустіть кнопку миші. Натисніть кнопку миші, підведіть курсор до контролю. Відпустіть кнопку миші. події Click ВІДБУДЕТЬСЯ.
Тому як у контрола було властивість csClicked, коли на ньому натиснули кнопку. А коли кнопку віджимають властивість csClicked не зніметься, так як віджимати кнопку немає над контролом.

Сподіваюся пояснив зрозуміло. Якщо що - питайте.

> Roxtady
ну конечно не буквально тільки цими процедурами. треба ще подивитися як реалізовані властивості, які використовуються в цих процедурах. а конкретніше - MouseCapture.

необхідне тобі політика на апі реалізується функцією SetCapture.

nikkie, можна детальніше. Я не зовсім зрозумів яким чином за допомогою SetCapture можна реалізувати таку поведінку при click "е.

P.S. І незрозумілий знову ж питання. Чому подія WM_LBUTTONDBCLK є, а події WM_LBUTTONCLK нету?

> Ігор Шевченко
> Під час обробки WM_хBUTTONDOWN треба встановити прапорець, що на вікні натиснута х-тая копка миші.

Якщо компонентів багато, то треба не прапорець, а запам'ятовувати вікно, на якому відбулося опускання клавіші, а при WM_XBUTTONUP перевіряти, піднята вона на тому ж вікні.

Схожі статті