Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.09.02;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.09.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.057 c
2-1186662201
alex_tonk
2007-08-09 16:23
2007.09.02
Сохранить как DBF файл


15-1185785539
StriderMan
2007-07-30 12:52
2007.09.02
.NET vs Java


1-1182934736
rolex2002
2007-06-27 12:58
2007.09.02
Unicode. Функция copy для widestring.


2-1186506722
viktoras
2007-08-07 21:12
2007.09.02
Создание меню


2-1186488239
elserpiente
2007-08-07 16:03
2007.09.02
список полей таблицы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский