Теперь прекрасно работает и отрисовка прозрачности, и не меняется положение по оси Z. Исправления коснулись метода DoDrawChildrenDblBuffered
//[procedure DoDrawChildrenDblBuffered]
procedure DoDrawChildrenDblBuffered( DC: HDC; WndParent: HWnd; const RectParent: TRect; W: HWnd );
var R, CR: TRect;
Save: Integer;
P, P0: TPoint;
begin
W := GetWindow( W, GW_HWNDLAST ); // получаем дескриптор последнего окна (инверсия координаты Z)
while W <> 0 do begin
if IsWindowVisible( W ) then begin
Save := SaveDC( DC );
GetWindowRect( W, R );
GetWindowOrgEx( DC, P );
SetWindowOrgEx( DC, P.x - ( R.Left - RectParent.Left ), P.y - ( R.Top - RectParent.Top ), nil );
IntersectClipRect( DC, 0, 0, R.Right - R.Left, R.Bottom - R.Top );
SendMessage( W, WM_PRINT, DC, PRF_NONCLIENT );
GetClientRect( W, CR );
P0.x := 0; P0.y := 0;
ClientToScreen( W, P0 );
OffsetRect( CR, P0.x, P0.y );
SetWindowOrgEx( DC, P.x - (CR.Left - RectParent.Left), P.y - (CR.Top - RectParent.Top), nil );
IntersectClipRect( DC, 0, 0, CR.Right - CR.Left, CR.Bottom - CR.Top );
SendMessage( W, WM_ERASEBKGND, DC, 0 );
SendMessage( W, WM_PAINT, DC, 0 );
DoDrawChildrenDblBuffered( DC, W, CR, GetWindow( W, GW_CHILD ) );
RestoreDC( DC, Save );
end;
W := GetWindow( W, GW_HWNDPREV ); // получаем дескриптор предыдущего окна того же уровня
end;
end;
и немного измененный WndProcBufferedDraw (синхронизированный с перерисовкой дочерних окон при fDblBufPainting = true)
//[function WndProcBufferedDraw]
function WndProcBufferedDraw( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
begin
Result := False;
if (Self_.DblBufTopParent = nil) or (Self_.DblBufTopParent.fDblBufPainting) then exit;
case Msg.message of
WM_PAINT:
begin
if (Self_.fCannotDoubleBuf) or not Self_.fDoubleBuffered or
Self_.CannotDoubleBuf or (Msg.wParam <> 0) then exit;
DoDrawDblBuffered( Self_ );
Rslt := 0;
Result := True;
end;
WM_NCPAINT:
begin
if (Self_.fCannotDoubleBuf) or not Self_.fDoubleBuffered or Self_.CannotDoubleBuf or
Self_.fIsForm then exit;
Rslt := 0;
Result := True;
end;
WM_SETTEXT:
begin
if not Self_.fIsStaticControl then exit;
ShowWindow( Self_.fHandle, SW_HIDE );
Rslt := DefWindowProc( Self_.fHandle, WM_SETTEXT, Msg.wParam, Msg.lParam );
ShowWindow( Self_.fHandle, SW_SHOWNA );
UpdateWindow( Self_.fHandle ); // necessary!!!
Result := True;
end;
WM_HSCROLL, WM_VSCROLL, WM_WINDOWPOSCHANGED: Self_.Invalidate;
WM_COMMAND:
case HiWord( Msg.wParam ) of
LBN_SELCHANGE: Self_.Invalidate;
end;
end;
end;
Galkov писал(а):
Разберись, предложи фиксинг - можно будет продолжить разговорGalkov, я предложил фиксинги и жду от тебя ответа.