ShIvADeSt Блин, немного непонятные некоторые ньюансы у Вашего кода. Допустим TRUE или FALSE принимает. Но надо понимать OverOK у Вас в WM_MOUSEMOVE TRUE принимает, а NotOver - FALSE? Я не гуру, нам бы простым любителям-программистам что-нибудь попроще.
И еще у Вас код if (DStr.itemState and ODS_FOCUS)<>0 then Focused:=True else Focused:=False;
Используется переменная Focused для DrawButton*. Вот тут я не знаю к чему мне результаты этого Focused, а ведь (DStr.itemState and ODS_FOCUS)<>0 поди тут тоже важно.
Изменил на такой код, немного переработав:
[more=Далее...]program hButton;
{$R hButton.res}
uses
Windows, Messages;
const
RES_DIALOG = 101;
RC_BUTTON = 101;
var
hApp : Integer;
OldBtnProc : Pointer;
hBtnTrack : Boolean;
TrackMouse : TTRACKMOUSEEVENT;
PS : PAINTSTRUCT;
Rect : TRect;
NewBmp : HBITMAP;
OldBmp : HBITMAP;
CompDC : HDC;
// bRegion : HRGN;
procedure PaintImageFileButton(DC : HDC; RtBtn : TRect; szPathFile : WideString);
begin
CompDC := CreateCompatibleDC(0);
NewBmp := LoadImageW(hInstance, PWideChar(szPathFile), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE or LR_LOADFROMFILE);
OldBmp := SelectObject(CompDC, NewBmp);
BitBlt(PS.hDC, 0, 0, RtBtn.Right - RtBtn.Left, RtBtn.Bottom - RtBtn.Top, CompDC, 0, 0, SRCCOPY);
SelectObject(CompDC, OldBmp);
DeleteDC(CompDC);
DeleteObject(NewBmp);
end;
function DrawCloseButton(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
bRect : TRect;
begin
case uMsg of
WM_MOUSEMOVE:
begin
if not hBtnTrack then
begin
TrackMouse.cbSize := SizeOf(TrackMouse);
TrackMouse.hwndTrack := hWnd;
TrackMouse.dwFlags := TME_LEAVE;
TrackMouse.dwHoverTime := HOVER_DEFAULT;
hBtnTrack := TrackMouseEvent(TrackMouse);
InvalidateRect(hWnd, nil, TRUE);
end;
end;
WM_MOUSELEAVE:
begin
TrackMouse.cbSize := SizeOf(TrackMouse);
TrackMouse.hwndTrack := hWnd;
TrackMouse.dwFlags := TME_HOVER;
TrackMouse.dwHoverTime := HOVER_DEFAULT;
TrackMouseEvent(TrackMouse);
hBtnTrack := FALSE;
InvalidateRect(hWnd, nil, TRUE);
end;
WM_PAINT:
begin
GetClientRect(hWnd, bRect);
BeginPaint(hWnd, PS);
case hBtnTrack of
TRUE:
PaintImageFileButton(PS.hDC, bRect, 'CloseButtonOver.bmp');
FALSE:
PaintImageFileButton(PS.hDC, bRect, 'CloseButtonNormal.bmp');
end;
EndPaint(hWnd, PS);
end;
end;
Result := CallWindowProcW(OldBtnProc, hWnd, uMsg, wParam, lParam);
end;
procedure Button_OnDrawItemW(lpdis: PDRAWITEMSTRUCT);
//var
//Focused: Boolean;
begin
//if (lpdis.itemState and ODS_FOCUS)<>0 then Focused:=True else Focused:=False;
// if (lpdis.itemState and ODS_SELECTED) <> 0 then
// PaintImageFileButton(lpdis.hdc, lpdis.rcItem, 'CloseButtonDown.bmp')
// else
// PaintImageFileButton(lpdis.hdc, lpdis.rcItem, 'CloseButtonNormal.bmp');
// if hBtnTrack and not ((lpdis.itemState and ODS_SELECTED) <> 0) then
// PaintImageFileButton(lpdis.hdc, lpdis.rcItem, 'CloseButtonOver.bmp');
// PaintImageFileButton(lpdis.hdc, lpdis.rcItem, 'CloseButtonDown.bmp');
{ курсор перемещаем над кнопкой с зажатой левой кнопкой мыши }
if hBtnTrack and ((lpdis.itemState and ODS_SELECTED) <> 0) and ((lpdis.itemState and ODS_FOCUS) <> 0) then
PaintImageFileButton(lpdis.hdc, lpdis.rcItem, 'CloseButtonDown.bmp')
else
{ обычное состояние кнопки }
PaintImageFileButton(lpdis.hdc, lpdis.rcItem, 'CloseButtonNormal.bmp');
ReleaseDC(lpdis.hwndItem, lpdis.hdc);
end;
function MainWndProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM) : BOOL; stdcall;
begin
Result := TRUE;
case uMsg of
WM_INITDIALOG:
begin
hApp := hWnd;
SetWindowLongW(hApp, GWL_EXSTYLE, GetWindowLong(hApp, GWL_EXSTYLE) or WS_EX_LAYERED);
SetLayeredWindowAttributes(hApp, $00FF00FF, 255, LWA_COLORKEY + LWA_ALPHA);
OldBtnProc := Pointer(GetWindowLongW(GetDlgItem(hApp, RC_BUTTON), GWL_WNDPROC));
SetWindowLongW(GetDlgItem(hApp, RC_BUTTON), GWL_WNDPROC, LongInt(@DrawCloseButton));
// GetWindowRect(GetDlgItem(hApp, RC_BUTTON), Rect);
// bRegion := CreateRoundRectRgn(0, 0, Rect.Right - Rect.Left - 3, Rect.Bottom - Rect.Top - 3, 8, 8);
// CombineRgn(bRegion, bRegion, bRegion, RGN_COPY);
// SetWindowRgn(GetDlgItem(hApp, RC_BUTTON), bRegion, TRUE);
end;
WM_PAINT:
begin
GetClientRect(hApp, Rect);
BeginPaint(hApp, PS);
PaintImageFileButton(PS.hDC, Rect, 'MainWindow.bmp');
EndPaint(hApp, PS);
end;
WM_DRAWITEM:
begin
case LoWord(wParam) of
RC_BUTTON:
Button_OnDrawItemW(PDRAWITEMSTRUCT(lParam));
end;
Result := FALSE;
end;
WM_LBUTTONDOWN:
SendMessageW(hApp, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
WM_COMMAND:
begin
case LoWord(wParam) of
RC_BUTTON:
SendMessageW(hApp, WM_CLOSE, 0, 0);
end;
end;
WM_CLOSE, WM_DESTROY:
PostQuitMessage(0);
else
Result := FALSE;
end;
end;
begin
DialogBoxW(hInstance, PWideChar(RES_DIALOG), 0, @MainWndProc);
end.
[/more]
Но... пока непонятно, как сделать такой эффект: Курсор навели на кнопку, подождали, нажали кнопку, должна измениться картинка у кнопки с наведенной на нажатую. Сделал вроде как через ODS_FOCUS проверку, но не выходит ничего. Хм, непонятен этот момент.
И все-таки хочется чтобы Вы скачали проект по ссылке и посмотрели. А то все слова слова, а тут на деле сразу. И вот хотел узнать, Вы определяетев обоработчике еще и тип контрола через ODT_BUTTON. Я вроде как без него сделал, вроде картинки рисуются на кнопке. Стоит ли так выполнять отрисовку?
Спасибо.