2

我编写了一个自定义的 TMemo,但注意到文本与边框相撞,根本没有填充。虽然我可以尝试通过抵消它等来解决 ClientRect 内部的问题,但在现阶段这不是一个非常优雅的解决方案。TMemo 至少有 1px 的填充,不属于客户区域,所以我想我会尝试做同样的事情(我假设这就是他们所做的)。

所以我已经使用 WM_NCCALCSIZE 缩小了客户区,但是当然边界没有完全绘制,所以我也必须实现 WM_NCPAINT。这样可行。我现在绘制一个 clBlack 边框,然后是 clWindow 的填充矩形。到目前为止,一切都很好。

在 XP(经典风格)上,但是 1px 边框看起来有点奇怪,所以我想也许有一种方法可以绘制旧的“客户端边缘”边框,并且还符合 XP/Vista/Win7 主题客户端边缘外观(我没有不知道如何使用渐变手动绘制)。

这就是我有点卡住的地方。有谁知道如何以我可以进行填充的方式绘制边框,以及如何保持适当的“客户端边缘”外观(1px 或 2px)?

非常感激。;)

(当然也欢迎其他方法)

=====

编辑: 经过一番修修补补,我想出了以下解决方案。我以为我会把它贴在这里。

procedure TTest.WMNCCalcSize(var Msg: TWMNCCalcSize);
begin
  inherited;

  InflateRect(Msg.CalcSize_Params.rgrc[0], -1, -1);

  Msg.Result := 0;
end;

procedure TTest.WMNCPaint(var Msg: TWMNCPaint);
var
  lCanvas: TCanvas;
  lRect: TRect;
  iBorderWidth: integer;
  iInflate: integer;
begin
  if ThemeServices.ThemesEnabled
    ThemeServices.PaintBorder(self, true)
  else
    inherited;

  lCanvas := TCanvas.Create;
  try
    lCanvas.Handle := GetWindowDC(Handle);
    with lCanvas do
    begin
      lRect := Rect(0, 0, Width, Height);
      iBorderWidth := (Width - ClientWidth) div 2;
      iInflate := -(iBorderWidth - 1);
      InflateRect(varRect, iInflate, iInflate);

      Brush.Color := clWindow;
      FrameRect(lRect);
    end;
  finally
    ReleaseDC(Handle, lCanvas.Handle);
    FreeAndNil(lCanvas);
  end;

  Msg.result := 0;
end;

编辑: 啊!当有滚动条在播放时,上面的这些东西就会崩溃。我还没有解决方案。有什么建议么?

4

0 回答 0