delphi – 在使用Windows API绘制一个按钮时,是否负责绘制标题?

前端之家收集整理的这篇文章主要介绍了delphi – 在使用Windows API绘制一个按钮时,是否负责绘制标题?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
介绍

我已经对Windows API和Parts and States有一点乐趣,看看控件如何可以画在画布上.

有了很多的尝试和错误,我设法得出这个程序,将一个按钮画在画布上:

type
  TButtonState = (bsDefault,bsDisabled,bsHot,bsNormal,bsPressed);

procedure DrawButton(ACanvas: TCanvas; X,Y,AWidth,AHeight: Integer;
  AFont: TFont; Caption: string; ButtonState: TButtonState);
var
  Size: TSize;
  R: TRect;
  H: HTHEME;
begin
  Size.cx := AWidth;
  Size.cy := AHeight;

  R := Rect(X,X + AWidth,Y + AHeight);

  if Winapi.uxTheme.UseThemes then
  begin
    H := OpenThemeData(0,'BUTTON');
    if H <> 0 then
    try
      ACanvas.Brush.Style := bsClear;
      if AFont <> nil then
      begin
        ACanvas.Font.Assign(AFont);
      end;

      case ButtonState of
        bsDefault:
        begin
          GetThemePartSize(H,ACanvas.Handle,BP_PUSHBUTTON,PBS_DEFAULTED,nil,TS_DRAW,Size);
          DrawThemeBackground(H,R,nil);
        end;

        bsDisabled:
        begin
          GetThemePartSize(H,PBS_DISABLED,nil);
          //ACanvas.Font.Color := $00838383; //todo get actual disabled font color
        end;

        bsHot:
        begin
          GetThemePartSize(H,PBS_HOT,nil);
        end;

        bsNormal:
        begin
          GetThemePartSize(H,PBS_NORMAL,nil);
        end;

        bsPressed:
        begin
          GetThemePartSize(H,PBS_PRESSED,nil);
        end;
      end;

      // draw the button caption
      DrawText(ACanvas.Handle,PChar(Caption),Length(Caption),DT_CENTER or DT_VCENTER or DT_SINGLELINE);
    finally
      CloseThemeData(H);
    end
  end
  else
  begin
    // draw button in classic theme?
  end;
end;

如果我这样调用那个程序:

procedure TForm1.FormPaint(Sender: TObject);
begin
  DrawButton(Image1.Canvas,10,75,25,Form1.Font,'Normal',bsNormal);
  DrawButton(Image1.Canvas,40,'Default',bsDefault);
  DrawButton(Image1.Canvas,70,'Disabled',bsDisabled);
  DrawButton(Image1.Canvas,100,'Hot',bsHot);
  DrawButton(Image1.Canvas,130,'Pressed',bsPressed);
end;

结果是我的预期是如此,像任何Windows按钮控件一样出现:

虽然我正在玩这个程序,但我很快意识到该按钮没有标题,我看不到添加字幕的方式,而不是自己绘制在按钮的顶部.您可以看到,“禁用”按钮仍然显示默认的字体颜色,禁用的控件通常具有不同的颜色,以帮助显示控件被禁用.标准Windows主题下禁用的字体颜色为$00838383(使用屏幕颜色选择器找到),但硬编码值绝对不是一个好主意,因为这些值通常对每个主题都是唯一的.

我的问题有几个部分,当使用Winows API绘制一个按钮时,我们必须自己手动绘制字幕?如果是这样,如何确保我正在绘制正确的字体名称,样式和大小等,以确保按钮与系统绘制的按钮相同?

奖金

主题未启用时,应如何以经典Windows样式绘制按钮?

解决方法

你应该自己画出文字.您可以使用主题API来绘制文本.例如:
...
 bsDisabled:
        begin
          GetThemePartSize(H,nil);
          DrawThemeText(H,DT_CENTER or DT_VCENTER or DT_SINGLELINE,R);
          //ACanvas.Font.Color := $00838383; //todo get actual disabled font color
        end;
...

由于您可以使用适当的状态调用api,请将该调用包括在分支中,并删除对DrawText的调用.

您可以使用DrawFrameControl作为经典风格.例如:

DrawFrameControl(ACanvas.Handle,DFC_BUTTON,DFCS_BUTTONPUSH);

猜你在找的Delphi相关文章