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

Вниз

Курсор над кнопкой   Найти похожие ветки 

 
Dmitry_177   (2007-03-05 20:22) [0]

Создаю кнопки с флагом BS_OWNERDRAW, чтобы самому перерисовывать их в WM_DRAWITEM..

По идее в структуре DrawItemStruct, т.е. так:
(PDrawItemStruct(lParam)^.itemState and ODS_HOTLIGHT) <> 0

если это выполняется то курсор над кнопкой, но так почему-то не работает... А с пунктами меню так работает.. Как мне тогда определить над кнопкой ли курсор, чтобы перерисовать кнопку?


 
tesseract ©   (2007-03-06 14:40) [1]


> А с пунктами меню так работает.. Как мне тогда определить
> над кнопкой ли курсор,


OnMouseLeave/OnMouseEnter.


 
DVM ©   (2007-03-06 14:43) [2]


> OnMouseLeave/OnMouseEnter.

Это же по WinApi конференция.


 
tesseract ©   (2007-03-06 14:49) [3]

тогда см TrackMouseEvent +   WM_MOUSEHOVER WM_MOUSELEAVE


 
Dmitry_177   (2007-03-06 16:22) [4]

Помогите примером пожалуйста с TrackMouseEvent, что-то я не пойму как она работает...:(


 
Dmitry_177   (2007-03-06 17:19) [5]

Я как понимаю функция срабатывает ОДИН раз, где-то вычитал что в сообщении WM_MOUSELEAVE нужно устанавливать функцию на TME_HOVER, а в WM_MOUSEHOVER на TME_LEAVE, т.е. чтобы одно сообщение вызывало на другую.. Т.е. примерно так:

function WindowProc(Window: HWnd; Message: Cardinal; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
 tme: TTRACKMOUSEEVENT;
...
   case Message of
     WM_MOUSELEAVE: begin
                     tme.cbSize := SizeOf(TTRACKMOUSEEVENT);
                     tme.dwFlags := TME_HOVER;
                     tme.hwndTrack := Window;
                     tme.dwHoverTime := HOVER_DEFAULT;
                     TrackMouseEvent(tme);
                     // действия, когда курсор вышел за границы..
                    end;

     WM_MOUSEHOVER: begin
                     tme.cbSize := SizeOf(TTRACKMOUSEEVENT);
                     tme.dwFlags := TME_LEAVE;
                     tme.hwndTrack := Window;
                     tme.dwHoverTime := HOVER_DEFAULT;
                     TrackMouseEvent(tme);
                     // действия, когда курсор зашел в пределы..
                    end;

Но вопрос в том, как ее изначально вызвать? Ведь сообщения WM_MOUSELEAVE и WM_MOUSEHOVER сами ниоткуда то не придут...


 
tesseract ©   (2007-03-07 14:13) [6]


> Но вопрос в том, как ее изначально вызвать?


The TrackMouseEvent function posts messages when the mouse pointer leaves a window or hovers over a window for a specified amount of time.

The TRACKMOUSEEVENT structure is used by the TrackMouseEvent function to track when the mouse pointer leaves a window or hovers over a window for a specified amount of time.

TRACKMOUSEEVENT.dwHoverTime

Specifies the hover time-out (if TME_HOVER was specified in dwFlags), in milliseconds. Can be HOVER_DEFAULT, which means to use the system default hover time-out.


 
Dmitry_177   (2007-03-11 19:35) [7]

Попробовал я вобщем так сделать, вроде работает.. Но блин, пропала прорисовка кнопки при нажатии на нее, я ее обрабатывал в WM_DRAWITEM главной процедуре окна, т.е. в WindowProc. Может из за сабклассинга уже не доходит WM_DRAWITEM главному окну??? Вот весь код тестового проекта:

program TestButton;

uses
 Windows,
 Messages;

const
 WindowName            = "TestButton";
 ID_TestBtn            = 10;

var
 WindowClass: TWndClass;
 hWindow: HWND;
 hTestBtn: HWND;
 AMessage: TMsg;
 old_proc: Pointer;
 bNextButtonTrack: boolean = false;
 tme: tagTRACKMOUSEEVENT;

function ButtonProc(Window: HWnd; Message: Cardinal; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
 DC: HDC;
 PStruct: PAINTSTRUCT;
 Pen: HPEN;
 Brush: HBRUSH;
 SelObjPn: HGDIOBJ;
 SelObjBr: HGDIOBJ;
begin
 case Message of
   WM_MOUSEMOVE: begin
                   if not bNextButtonTrack then
                     begin
                       tme.cbSize := SizeOf(tagTRACKMOUSEEVENT);
                       tme.hwndTrack := Window;
                       tme.dwFlags := TME_LEAVE;
                       tme.dwHoverTime := HOVER_DEFAULT;
                       bNextButtonTrack := TrackMouseEvent(tme);

                       InvalidateRect(Window, nil, true);
                     end;
                 end;

   WM_MOUSELEAVE: begin
                   bNextButtonTrack := false;
                   InvalidateRect(Window, nil, true);
                 end;

   WM_PAINT: begin
               if bNextButtonTrack then
                 begin
                   DC := BeginPaint(Window, PStruct);

                   Pen := CreatePen(PS_SOLID, 1, $00000000);
                   SelObjPn := SelectObject(DC, Pen);
                   Brush := CreateSolidBrush($0000FF00);
                   SelObjBr := SelectObject(DC, Brush);

                   Rectangle(DC, PStruct.rcPaint.Left, PStruct.rcPaint.Top, PStruct.rcPaint.Right, PStruct.rcPaint.Bottom);

                   SelectObject(DC, SelObjPn);
                   DeleteObject(Pen);
                   SelectObject(DC, SelObjBr);
                   DeleteObject(Brush);

                   EndPaint(Window, PStruct);
                 end
               else
                 begin
                   DC := BeginPaint(Window, PStruct);

                   Pen := CreatePen(PS_SOLID, 1, $00000000);
                   SelObjPn := SelectObject(DC, Pen);
                   Brush := CreateSolidBrush($00FFFFFF);
                   SelObjBr := SelectObject(DC, Brush);

                   Rectangle(DC, PStruct.rcPaint.Left, PStruct.rcPaint.Top, PStruct.rcPaint.Right, PStruct.rcPaint.Bottom);

                   SelectObject(DC, SelObjPn);
                   DeleteObject(Pen);
                   SelectObject(DC, SelObjBr);
                   DeleteObject(Brush);

                   EndPaint(Window, PStruct);
                 end;
             end;
 end;

 Result := CallWindowProc(old_proc, Window, Message, wParam, lParam);
end;

function WindowProc(Window: HWnd; Message: Cardinal; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
 Pen: HPEN;
 Brush: HBRUSH;
 SelObjPn: HGDIOBJ;
 SelObjBr: HGDIOBJ;
begin
 Result := 0;
   case Message of
     WM_CREATE: begin
                 hTestBtn := CreateWindow("BUTTON", "TestButton", BS_OWNERDRAW or WS_CHILD or WS_VISIBLE, 20, 20, 30, 32, Window, ID_TestBtn, HInstance, nil);

                 old_proc := Pointer(GetWindowLong(Window, GWL_WNDPROC));
                 SetWindowLong(hTestBtn, GWL_WNDPROC, LongInt(@ButtonProc));
               end;

     WM_DRAWITEM: begin
                   with PDrawItemStruct(lParam)^ do
                     begin
                       FrameRect(hDC, rcItem, GetStockObject(WHITE_BRUSH));
                       if (itemState and ODS_SELECTED) <> 0 then
                         begin
                           Pen := CreatePen(PS_SOLID, 1, $00000000);
                           SelObjPn := SelectObject(hDC, Pen);
                           Brush := CreateSolidBrush($000000FF);
                           SelObjBr := SelectObject(hDC, Brush);

                           Rectangle(hDC, rcItem.Left, rcItem.Top, rcItem.Right, rcItem.Bottom);

                           SelectObject(hDC, SelObjPn);
                           DeleteObject(Pen);
                           SelectObject(hDC, SelObjBr);
                           DeleteObject(Brush);
                         end;
                     end;
                   Result := 1;
                 end;

     WM_DESTROY: begin
                   PostQuitMessage(0);
                   Exit;
                 end;
   else
     Result := DefWindowProc(Window, Message, wParam, lParam);
   end;
end;

begin
 with WindowClass do
   begin
     lpszClassName := WindowName;
     lpfnWndProc := @WindowProc;
     cbClsExtra := 0;
     cbWndExtra := 0;
     hInstance := 0;
     lpszMenuName := nil;
     hIcon := LoadIcon(0, IDI_APPLICATION);
     hCursor := LoadCursor(0, IDC_ARROW);
     hbrBackground := GetStockObject(WHITE_BRUSH);
   end;

 if RegisterClass(WindowClass) = 0 then Exit;

 hWindow := CreateWindow(WindowName, WindowName, WS_OVERLAPPEDWINDOW, (GetSystemMetrics(SM_CXSCREEN) - 500) div 2, (GetSystemMetrics(SM_CYSCREEN) - 300) div 2, 500, 300, 0, 0, HInstance, nil);

 ShowWindow(hWindow, SW_SHOWNORMAL);
 UpdateWindow(hWindow);

 while GetMessage(AMessage, 0, 0, 0) do
   begin
     TranslateMessage(AMessage);
     DispatchMessage(AMessage);
   end;
end.

Можно просто скопировать его в Delphi и компилировать.. Можно конечно обрабатывать WM_LBUTTONDOWN/WM_LBUTTONUP кнопки, но это же только с мышкой, а на кнопку же можно еще нажать и с помощью клавиатуры.. Лучше всего было бы обрабатывать нажатие, чтобы перерисовывать ее в WM_DRAWITEM мне так кажется.. Помогите пожалуста, может кто-то уже делал что я хочу, чтобы не придумывать велосипед..



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

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

Наверх




Память: 0.51 MB
Время: 0.024 c
4-1173905354
ffo_2
2007-03-14 23:49
2007.09.02
Как программно нажать Ctrl + V?


4-1173165948
vir
2007-03-06 10:25
2007.09.02
Получить хенл окна имеющего фокус.


15-1186501950
Quazi
2007-08-07 19:52
2007.09.02
Алгоритм расчета DataMatrix


11-1168775119
Psychedelic
2007-01-14 14:45
2007.09.02
Как отличать друг от друга компоненты


15-1186502485
Ivolg
2007-08-07 20:01
2007.09.02
Превести c C в Delphi