Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.18;
Скачать: CL | DM;

Вниз

GUI на WinAPI   Найти похожие ветки 

 
Marser ©   (2005-05-25 17:30) [0]

При создании элементарного окна с кнопкой возникла следующая проблема - обработка нажатия левой кнопки мыши на кнопке происходит, однако визуально кнопка на это не реагирует.
Вот код:
program apipro;

uses
 Windows, Messages;
var
 MWND:TWndClassEx;
 mwin,mbut:HWND;
 Mesg:TMsg;
 l:Pointer;
function MWinProc(wnd:HWND;Msg:Integer;wParam:wParam;lParam:lParam):HResult;stdcall;
begin
 case msg of
   wm_destroy:Begin
     postquitmessage(0); exit;
     Result:=0;
   End
 else
    result:=DefWindowProc(wnd,msg,wparam,lparam);
 end
end;
function MButProc(wnd:HWND;Msg:Integer;wParam:wParam;lParam:lParam):HResult;stdcall;
begin
 result:=0;
 case msg of
   WM_LBUTTONDOWN:messagebox(0,"Меня нажали","My button",mb_iconexclamation);
 else
   Result:=CallWindowProc(l,wnd,msg,wparam,lparam);
 end;
end;
procedure createmainwin;
begin
 mwnd.cbSize:=sizeof(TWndClassEx);
 mwnd.style:=CS_HREDRAW or CS_VREDRAW;
 mwnd.lpfnWndProc:=@MWinProc;
 mwnd.cbClsExtra:=0;
 mwnd.cbWndExtra:=0;
 mwnd.hInstance:=HInstance;
 mwnd.hIcon:=LoadIcon(0,idi_application);
 mwnd.hCursor:=LoadCursor(0,IDC_ARROW);
 mwnd.hbrBackground:=COLOR_BTNFACE+1;
 mwnd.lpszMenuName:=nil;
 mwnd.lpszClassName:="WinMin : Main";
 mwnd.hIconSm:=0;
 RegisterClassEx(mwnd);
 mwin:=CreateWindowEx(0,"WinMin : Main","MyWin",WS_OVERLAPPEDWINDOW or WS_BORDER or WS_CAPTION,100,60,
                200,200,0,0,Hinstance,nil);
 ShowWindow(mwin,CmdShow);
end;
procedure createbutton;
begin
 mbut:=createwindow("BUTTON","My Button",WS_CHILDWINDOW or BS_PUSHBUTTON,10,10,80,20,
                      mwin,0,Hinstance,nil);
 ShowWindow(mbut,CmdShow);
 l:=pointer(GetWindowLong(mbut,gwl_wndproc));
 SetWindowLong(mbut,gwl_wndproc,integer(@MButProc))
end;
begin
 createmainwin;
 createbutton;
 While GetMessage(Mesg,0,0,0) do
 begin
  TranslateMessage(Mesg);
  DispatchMessage(Mesg);
 end;
end.

Вариант
function MButProc(wnd:HWND;Msg:Integer;wParam:wParam;lParam:lParam):HResult;stdcall;
begin
 if msg=WM_LBUTTONDOWN then
   messagebox(0,"Меня нажали","My button",mb_iconexclamation);
   Result:=CallWindowProc(l,wnd,msg,wparam,lparam);
 end;
end;

То бишь, полностью стандартная обработка вместе с нестандартной, приводит к непонятному мне зацикливанию.

Одним из вариантов решения был предложен Игорем Осовьяком - дополнительная отсылка собственного сообщения в postmessage с многоступенчатой обработкой, в принципе неплох. Но мне кажется, что всё несколько проще.


 
Polevi ©   (2005-05-25 17:38) [1]

BM_CLICK, BM_CLICKED


 
Marser ©   (2005-05-25 17:44) [2]


> Polevi ©   (25.05.05 17:38) [1] [Новое
>сообщение][Ответить]
> BM_CLICK, BM_CLICKED

BN_CLICKED
Это был первоначальный вариант. Но этого события не происходило, насколько я помню.


 
Игорь Шевченко ©   (2005-05-25 17:47) [3]

Для того, чтобы кнопка реагировала нужно вызывать старую оконную процедуру и не вызывать MessageBox, так как MessageBox меняет окно, захватывающее мышь


 
Marser ©   (2005-05-25 17:48) [4]


> Игорь Шевченко ©   (25.05.05 17:47) [3] [Новое
>сообщение][Ответить]
> Для того, чтобы кнопка реагировала нужно вызывать
> старую оконную процедуру и не вызывать MessageBox, так
> как MessageBox меняет окно, захватывающее мышь

Спасибо! А как же всё-таки запустить messagebox? После обработки старой процедурой?


 
Marser ©   (2005-05-25 17:51) [5]


> Polevi ©   (25.05.05 17:38) [1][Ответить]

BM_CLICK
This message is sent by an application to simulate the user clicking a button. This message causes the button to receive a WM_LBUTTONDOWN and a WM_LBUTTONUP message, and the button"s parent window to receive a BN_CLICKED notification message.

(С)MSDN


 
DVM ©   (2005-05-25 17:53) [6]


> Спасибо! А как же всё-таки запустить messagebox? После обработки
> старой процедурой?

у кнопок есть уведомляющие сообщения (кнопка нажалась и т.д.) именно в них надо вызывать разные messagebox-ы


 
Игорь Шевченко ©   (2005-05-25 17:55) [7]

Marser ©   (25.05.05 17:48) [4]


> А как же всё-таки запустить messagebox? После обработки
> старой процедурой?


Можно попробовать и после, но лучше отправить (PostMessage) сообщение основному окну, пусть оно реагирует.


 
Marser ©   (2005-05-25 17:57) [8]


> DVM ©   (25.05.05 17:53) [6]

bn_clicked уже опробовался. Неудачно.


> Игорь Шевченко ©   (25.05.05 17:55) [7]

То есть, без своего оообщения тут не обойдется?
Мне несложно, конечно, но как-то казалось, что можно обойтись без этого...


 
DVM ©   (2005-05-25 18:00) [9]


> bn_clicked уже опробовался. Неудачно.

ты где это сообщение пытался ловить - в оконной процедуре кнопки или родительском окне?


 
Marser ©   (2005-05-25 18:04) [10]


> DVM ©   (25.05.05 18:00) [9]

Везде ловил.


 
Marser ©   (2005-05-25 18:07) [11]

Частное решение найдено!
Отловил wm_lbuttonUp и делоф!
Спасибо всем, кто пробовал помочь!


 
Marser ©   (2005-05-25 18:08) [12]

Конечно, оно именно частное(возможно нажатие за пределами кнопки). Однако уже выглядит нормально :-)


 
alpet ©   (2005-05-25 18:12) [13]

Зачем вообще подменять у кнопки ее процедуру? Имхо проще обрабатывать в процедуре основного окна сообщение WM_COMMAND.


 
Игорь Шевченко ©   (2005-05-25 18:13) [14]

alpet ©   (25.05.05 18:12) [13]


> Зачем вообще подменять у кнопки ее процедуру?


Обычно для собственной отрисовки


 
Marser ©   (2005-05-25 18:13) [15]


> alpet ©   (25.05.05 18:12) [13] [Новое
>сообщение][Ответить]
> Зачем вообще подменять у кнопки ее процедуру? Имхо
> проще обрабатывать в процедуре основного окна
> сообщение WM_COMMAND.

Уже учтено. Но спасибо!


 
alpet ©   (2005-05-25 18:20) [16]

>Обычно для собственной отрисовки

Хм, понятно. Я что-то привык к WM_DRAWITEM + BS_OWNERDRAW, но так вроде хитрее...


 
alpet ©   (2005-05-25 18:22) [17]

Вернее NM_CUSTOMDRAW, WM_DRAWITEM здесь не причем.


 
Marser ©   (2005-05-25 18:25) [18]

прошу прощения у DVM за проявленное ламерство. С notification и wm_command у меня ещё не было никакого опыта работы.


 
alpet ©   (2005-05-25 18:29) [19]

Вообще все перепутал, NM_CUSTOMDRAW у меня используется для рисования в ListView контроле, а здесь рулят WM_DRAWITEM, WM_CTLCOLORBTN.


 
alpet ©   (2005-05-25 18:31) [20]

По отношению к кнопкам NM_CUSTOMDRAW можно использовать только в Windows XP.


 
Игорь Шевченко ©   (2005-05-26 00:55) [21]

alpet ©   (25.05.05 18:20) [16]


> Хм, понятно. Я что-то привык к WM_DRAWITEM + BS_OWNERDRAW,
> но так вроде хитрее...


Не то, что хитрее, но гибче. Можно обрабатывать сообщения WM_ERASEBKGND (видел в первом таком примере, еще для Windows 3.1), можно обрабатывать сообщения WM_NCPAINT (сам писал такие обработчики для стандартных контролов) и т.д. и т.п., можно менять картинку при наведении мыши, кстати. Customdraw эту проблему не решит.



Страницы: 1 вся ветка

Текущий архив: 2005.07.18;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.054 c
4-1116951389
ДГ
2005-05-24 20:16
2005.07.18
Формы, контролы и т.д. на Winapi


3-1118316867
saasik
2005-06-09 15:34
2005.07.18
DBGrid в рантайме скрывает поля. В дизайне все ОК.


14-1119894843
Ibrox
2005-06-27 21:54
2005.07.18
Авторские права


3-1118187806
Dorian
2005-06-08 03:43
2005.07.18
Как программно перебирать значения в DBGrid?


4-1116845124
Семен Сорокин
2005-05-23 14:45
2005.07.18
DeviceIoControl c кодом FSCTL_FIND_FILES_BY_SID