WM_PAINT는 마이크로소프트의 공식 정의에서 wParam과 lParam을 모두 사용하지 않았기 때문에 델파이에 의해 이 메시지를 다시 정의했고 DC(Delphi는 메시지를 임의로 바꿀 수 있는 구조를 추가했다. 앞의 4바이트만 메시지로 유지하면 되고 마이크로소프트가 정의한 모든 필요한 정보를 휴대하면 된다)
LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
Parameters
wParam
This parameter is not used.
lParam
This parameter is not used.
Delphi에서 핸들을 제거한 후 재정의하기
TWMPaint = packed record
Msg: Cardinal;
DC: HDC;
Unused: Longint;
Result: Longint;
end;
테스트 결과 크기는 16:
procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage(IntToStr(sizeof(TWMPaint)));
end;
재정의된 활용 과정은 다음과 같습니다.
procedure TWinControl.WMPaint(var Message: TWMPaint);
var
DC, MemDC: HDC;
MemBitmap, OldBitmap: HBITMAP;
PS: TPaintStruct;
begin
if not FDoubleBuffered or (Message.DC <> 0) then // DC,
begin
if not (csCustomPaint in ControlState) and (ControlCount = 0) then // Windows , 0, 。
inherited // 1, Windows , , , BeginPaint ?
else
PaintHandler(Message); // 2, Delphi , BeginPaint
end
else
begin
DC := GetDC(0); // 3, DC, , BeginPaint
MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom);
ReleaseDC(0, DC);
MemDC := CreateCompatibleDC(0);
OldBitmap := SelectObject(MemDC, MemBitmap);
try
DC := BeginPaint(Handle, PS);
Perform(WM_ERASEBKGND, MemDC, MemDC);
Message.DC := MemDC; //
WMPaint(Message); // DC, Message.DC := 0;
BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY);
EndPaint(Handle, PS);
finally
SelectObject(MemDC, OldBitmap);
DeleteDC(MemDC);
DeleteObject(MemBitmap);
end;
end;
end;
전송 계속:
procedure TWinControl.PaintHandler(var Message: TWMPaint);
var
I, Clip, SaveIndex: Integer;
DC: HDC;
PS: TPaintStruct;
begin DC := Message.DC; // ( ), , DC 。 , ,Message.DC 。fixme if DC = 0 then DC := BeginPaint(Handle, PS); // DC , ( , ) try
if FControls = nil then PaintWindow(DC) else
begin
SaveIndex := SaveDC(DC);
Clip := SimpleRegion;
for I := 0 to FControls.Count - 1 do
with TControl(FControls[I]) do
if (Visible or (csDesigning in ComponentState) and
not (csNoDesignVisible in ControlStyle)) and
(csOpaque in ControlStyle) then
begin
Clip := ExcludeClipRect(DC, Left, Top, Left + Width, Top + Height);
if Clip = NullRegion then Break;
end;
if Clip <> NullRegion then PaintWindow(DC);
RestoreDC(DC, SaveIndex);
end;
PaintControls(DC, nil); // DC finally
if Message.DC = 0 then EndPaint(Handle, PS);
end;
end;
procedure TGraphicControl.WMPaint(var Message: TWMPaint);
begin
if Message.DC <> 0 then // , DC , ( )
begin
Canvas.Lock;
try Canvas.Handle := Message.DC; // ,DC Canvas , DC try
Paint;
finally Canvas.Handle := 0; end;
finally
Canvas.Unlock;
end;
end;
end;
procedure TCustomControl.WMPaint(var Message: TWMPaint);
begin
Include(FControlState, csCustomPaint);
inherited;
Exclude(FControlState, csCustomPaint);
end;
procedure TWinControl.WMPrintClient(var Message: TWMPrintClient);
begin
with Message do
if Result <> 1 then
if ((Flags and PRF_CHECKVISIBLE) = 0) or Visible then
PaintHandler(TWMPaint(Message))
else
inherited
else
inherited;
end;
TWinControl에 여러 TCustomControl 하위 컨트롤이 포함되어 있는 실험을 다시 수행합니다.WM_PAINT는 처음으로 부모 컨트롤러에 보내고 TCustom Control 하위 컨트롤러를 순서대로 다시 그립니다. 그러나 모든TCustom Control 하위 컨트롤러는 inherited를 통해 메시지를 전송합니다. 처음 전송했을 때 이 메시지의 DC는 0이 아니었을 것입니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.