【问题标题】:Draw a image in the StatusBar not working in XE7 version在状态栏中绘制图像在 XE7 版本中不起作用
【发布时间】:2015-05-14 14:46:11
【问题描述】:

我的应用程序会在初始化时在状态栏中显示一些信息。 我通过在状态栏上绘制图标(打开和关闭)来显示这一点。 以下代码在 Embarcadero XE3 中运行良好,但在 XE7 版本中不再运行。 该代码不会引发任何异常或错误。 我该如何解决这个问题?

procedure TFormMain.StatusBar1DrawPanel(StatusBar: TStatusBar;
  Panel: TStatusPanel; const Rect: TRect);
var
  i: Integer;
begin
  case Panel.Index of
    3:
    begin
      i := ICON_DATABASE_OFF;
      if HasDatabaseConnection() then
        i := ICON_DATABASE;
      ImageList1.Draw(StatusBar.Canvas, Rect.Left, Rect.Top, i);
    end;
    4:
    begin
      i := ICON_GLOBE_OFF;
      if HasInternetConnection() then
        i := ICON_GLOBE;
      ImageList1.Draw(StatusBar.Canvas, Rect.Left, Rect.Top, i);
    end;
  end;
end;

在 XE3 中:

更新
(见 cmets)
出现该错误是因为FormMainOnResizeEvent

procedure TFormMain.FormResize(Sender: TObject);
begin
  //StatusBar1.Panels[0].Width := FormMain.Width - 448;
  StatusBar1.Panels[0].Width := ClientWidth - 448;
end;

我调试时显示的值在两个版本中是相同的:
在 XE3 中:
FormMain.Width = 1400
客户端宽度 = 1024

在 XE7 中:
FormMain.Width = 1400
客户端宽度 = 1024

定义的尺寸是宽度 754 和高度 515。
由于某些未知原因,在 XE7 中未绘制图标。
如果我在打开表单后调整其大小,则图标显示正确!

我没有应用任何皮肤或更改应用程序的样式。我正在使用默认配置

状态栏将有 6 个面板:
0 - 显示提示(宽度灵活;表单宽度变化时变化)
1 - 将显示当前所选公司的名称(固定宽度)
2 - 将显示当前用户的名称(固定宽度)
3 - 将显示一个图标(固定宽度)
4 - 将显示一个图标(固定宽度)
5 - 将显示日期(固定宽度)

由于 1~5 号板的尺寸固定(总计 = 448),我看不出有理由重新计算板条 [0] 的宽度百分比。

同样,该问题仅出现在 XE7 中。

【问题讨论】:

  • 您是否在项目中使用样式(项目 - 选项 - 应用程序 - 外观)?您的表单的运行时宽度是多少?如果小于 450,如果增加宽度使Panel[0] 宽度为正,图像会出现吗?请使用这些问题的答案编辑您的问题,并在对 Ken Whites 的回答中包含您在 cmets 中提到的事实。
  • 令人沮丧的是,寻求帮助的人太冷漠,无法回答一些简单的细节,这些细节要么可以排除或确认他们问题的可能原因。
  • 已编辑。请检查它。
  • 那么您是否至少尝试重新计算 Panel[0] 的宽度以查看它是否改变了一些东西?或者您只是因为没有任何理由重新计算而直接拒绝它。
  • 是的,我试过了。并且仍然无法正常工作。仅当我在打开窗口后调整窗口大小时。在我看来 XE7 版本有问题。

标签: delphi delphi-xe3 delphi-xe7


【解决方案1】:

您需要将TPanel.Style 设置为psOwnerDraw 而不是默认的psText。如果您不这样做,则不会调用 OnDrawPanel

对类似代码的快速测试表明它可以工作(至少在 XE8 中):

procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
  const Rect: TRect);
begin
  if Panel.Index = 0 then
    ImageList1.Draw(StatusBar.Canvas, Rect.Left, Rect.Top, 0);
end;

结果:

根据发布者的 cmets(在此答案下方),问题似乎实际上与表单的 OnResize 事件中的代码有关,其中两个问题面板不再有足够的空间。有问题的代码(取自发布者的 cmets):

procedure TFormMain.FormResize(Sender: TObject); 
begin 
  StatusBar1.Panels[0].Width := FormMain.Width - 448 ; 
end;

首先,突出代码中最重要的问题:永远不要在该表单的事件处理程序中使用Form.Width!改用Self.Width(或简单的Width,这意味着Self),制作正确的代码

StatusBar1.Panels[0].Width := Self.Width - 448;

(最好使用Self.ClientWidth,这是调整大小(边缘)边框和删除任何滚动条后表单的内部(客户)区域,而不是Width,顺便说一句。)

我认为面板绘图的问题与面板宽度计算有关。如果在调整Panels[0] 大小后面板没有足够的空间,则索引 3 和 4 处的面板变得太小,并且看不到绘制到矩形中的图像。我可以通过将此事件处理程序添加到我的第一个代码块并再次运行应用程序,调整表单大小来重现这一点:

procedure TForm1.FormResize(Sender: TObject);
begin
  StatusBar1.Panels[1].Width := Self.Width - 448;
end;

请注意下面两个图像中第二个面板(Panels1)的外观变化 - 第一个是表单最初以设计宽度 800 显示时,第二个是在将窗口缩小到 600 像素后运行时的宽度。

800 像素宽度的表格 - 带有日期的状态栏面板:

600 像素宽度的表单 - 缺少带有日期的注释状态栏面板

这里的解决方案是先减去面板 3 和 4 的宽度,然后将剩余空间的百分比分配给面板 0。请注意,我在这里使用表单的 ClientWidth 而不是 Width

procedure TFormMain.FormResize(Sender: TObject);
var
  Available: Double;
begin
  Available := ClientWidth - StatusBar1.Panels[3].Width -
               StatusBar1.Panels[4].Width;
  // Allocate 80% of remaining width to first panel
  StatusBar1.Panels[0] := Trunc(Available * 0.8);
end;

【讨论】:

  • 样式设置为psOwnerDraw,但还是不行。正如我所说,在 XE3 中工作正常,但在 XE7 中不行。我没有更改代码。
  • 它与上面的代码完美配合(我在发布之前测试过)。在您的StatusBar1DrawPanel 处理程序(在case 行)中放置一个断点并运行。单步执行代码时会发生什么?
  • 没什么。我意识到,在执行之后,使用以下代码调用 OnFormResize:procedure TFormMain.FormResize(Sender: TObject); begin StatusBar1.Panels [ 0] .Width : = FormMain.Width - 448 ; end; 如果我评论这一行,则图标绘制正确。现在的问题是:为什么更改面板的宽度会停止工作并在 XE3 中正常工作,而不是在 XE7 中?
  • @rodrigopandini:我不知道。我可以将相同的代码(针对我的 StatusBar1 进行了调整)添加到上面的表单中,并且它可以正确绘制。 (我完全添加了:StatusBar1.Panels[1].Width := ClientWidth - 448; 用于测试。)注意:不要在FormMain 的事件处理程序中使用FormMain - 使用Self。 IOW,你的代码应该是StatusBar1.Panels[0].Width := Self.Width - 448;从不在表单的事件处理程序中引用表单的实例变量。
  • @rodrigopandini:我怀疑发生的事情是在FormMain.Width - 488Panels[0]OnResize 中占用之后没有足够的空间容纳面板。在减去面板 3 和 4 的宽度后,将 Panel[0].Width 计算为百分比,看看是否可以解决。
猜你喜欢
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多