Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Обработка WM_LBUTTONDOWN [D7, WinXP]


Dmitry_177 ©   (2006-11-23 22:11:00) 

Как мне обрабатывать сообщение WM_LBUTTONDOWN по нажатию на кнопке? Т.е. нужно определить на какой кнопке была нажата левая кнопка мыши, попробовал так:

function WindowProc(Window: HWnd; Message: Word; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
...
WM_LBUTTONDOWN: begin
                       if Window = hButton then MessageBox(0, '1', '1', 0);
                     end;

не работает, где hButton это хендл кнопки


Belorus   (2006-12-01 00:53:00) [1]

procedure MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 If ssLeft in Shift then
 Begin
   ReleaseCapture;
   Perform(WM_SYSCommand,61457,1);
 End;    
End;


Чапаев   (2006-11-30 22:08:00) [2]

> [18] Dmitry_177   (30.11.06 19:25)
Ну и зря.

Тогда уж делай что-то вроде if PtInRect(Point(X,Y),ButtonRect) then Result:=HTCLIENT else Result:=HTCAPTION;


Dmitry_177   (2006-11-30 19:25:00) [3]

Мне перетаскивать форму нужно ткнув в любое ее место... Если делать через WM_MOUSEMOVE мне кажется что это будет менее эффективнее...


Чапаев   (2006-11-30 10:48:00) [4]

> [16] Dmitry_177   (30.11.06 02:44)
Ну конечно не доходит. Ты же таким образом объявляешь: всё что есть на форме -- это заголовок. Заголовок -- неклиентская область и клиентские сообщения окну не доходят, конечно.

Можешь вместо WM_LBUTTONDOWN на кнопке ловить нечто вроде WM_NCLBUTTONDOWN (не помню точное название) в главном окне. Но вообще лучше подумай, как обойтись без объявления всей области окна заголовком.


Dmitry_177   (2006-11-30 02:44:00) [5]

В главной процедуре обрабатываю сообщение WM_NCHITTEST,

     WM_NCHITTEST: begin
                     if Window = hWindow then
                       if GetAsyncKeyState(VK_LBUTTON) < 0 then
                         Result := HTCAPTION;
                   end;

И не доходит сообщение WM_LBUTTONDOWN до кнопки, сделав его обработку сабклассингом... Что делать?


Чапаев   (2006-11-25 15:01:00) [6]

> [13] GrayFace ©   (25.11.06 14:43)
;-) Так это ж уже не "просто WM_*BUTTONUP"


GrayFace   (2006-11-25 14:44:00) [7]

Ну и, конечно, в UP ReleaseCapture


GrayFace   (2006-11-25 14:43:00) [8]

Чапаев ©   (24.11.06 10:40) [9]
Просто WM_*BUTTONUP обрабатывать неправильно потому, что кнопка может быть нажата "где-то", а отпущена над кнопкой. А это, по совести, за клик не должно считаться.

Просто надо в DOWN делать SetCapture.


Игорь Шевченко   (2006-11-24 15:33:00) [9]


> Как мне обрабатывать сообщение WM_LBUTTONDOWN по нажатию
> на кнопке? Т.е. нужно определить на какой кнопке была нажата
> левая кнопка мыши


Если все кнопки одного оконного класса, то:

var
 OldButtonProc: Pointer;

function ButtonWindowProc(Window: HWnd; Message: UINT; wParam:
 WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
 if Message = WM_LBUTTONDOWN then begin
   ...
 end;
 Result := CallWindowProc (OldButtonProc, Window, Message, wParam, lParam);
end;

OldButtonProc := Pointer(GetWindowLong(AnyButtonHandle, GWL_WNDPROC);

Для каждой кнопки сделать:
SetWindowLong(ButtonHandle, GWL_WNDPROC, LongInt(@ButtonWndProc));


Чапаев   (2006-11-24 10:46:00) [10]

> ситуацию "кнопка может быть нажата "где-то", а отпущена
> над кнопкой" считаю извратом
Эти юзера такие затейники! ;-)

ЗЫ. Засим удаляюсь на работу.


Elen   (2006-11-24 10:45:00) [11]


> [9] Чапаев

Тоже верно. Тогда [7] конечно же. а ситуацию "кнопка может быть нажата "где-то", а отпущена над кнопкой" считаю извратом


Чапаев   (2006-11-24 10:40:00) [12]

> [8] Elen ©   (24.11.06 10:35)
Просто WM_*BUTTONUP обрабатывать неправильно потому, что кнопка может быть нажата "где-то", а отпущена над кнопкой. А это, по совести, за клик не должно считаться.


Elen   (2006-11-24 10:35:00) [13]


> Если мы говорим об одном и том же ;-)

Да. Но разными способами. В принципе автору теперь остается выбирать - а мнения у нас одинаковые, и разнообразные. Это хорошо, колега.


Чапаев   (2006-11-24 10:27:00) [14]

> [6] Elen ©   (24.11.06 10:25)
Как по мне, я бы оьрабатывал WM_COMMAND. (Если мы говорим об одном и том же ;-) ). А задача, поставленная автором ветки, решается субклассингом.


Elen   (2006-11-24 10:25:00) [15]


> [5] Чапаев

Понимаю. Автор и меня в заблуждение ввел.  Как по мне я б ловила такое в OnMouseUp.


Чапаев   (2006-11-24 10:15:00) [16]

Удалено модератором


Elen   (2006-11-24 10:01:00) [17]

Удалено модератором


Чапаев   (2006-11-24 09:55:00) [18]

> [1] Elen ©   (24.11.06 07:44)
Аффтар, ты попутал грешное с праведным. WindowProc() и процедуры диспетчеризации (?) отдельных событий -- разные вещи.


> [0] Dmitry_177   (23.11.06 22:11)
А зачем? В принципе, задача разрешима, но скорей всего -- нет смысла её решать. Зачем тебе это нужно?


Dmitry_177   (2006-11-24 09:46:00) [19]

Это и имелось ввиду:


function WindowProc(Window: HWnd; Message: Word; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
 Result := 0;
   case Message of
     WM_LBUTTONDOWN: begin
                       if Window = hButton then MessageBox(0, '1', '1', 0);
                     end;
...

   else
     Result := DefWindowProc(Window, Message, wParam, lParam);
   end;
end;
end;


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


Elen   (2006-11-24 07:44:00) [20]

Ну для начала :
function WindowProc(Window: HWnd; Message: Word; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; message WM_LBUTTONDOWN

а вообще хотелось бы увидеть побольше кода и услышать реальную задачу


Наверх

Титульная страница Поиск, карта сайта Написать письмо