在StatusBar中绘制图像不适用于XE7版本

时间:2015-05-14 14:46:12

标签: delphi delphi-xe3 delphi-xe7

我的应用程序将在初始化状态栏中显示一些信息。 我通过在状态栏上绘制图标(打开和关闭)来显示它。 以下代码在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中: enter image description here

更新
(见评论)
发生错误的原因是OnResizeEvent的{​​{1}}。

FormMain

我调试时显示的值在两个版本中都是相同的:
在XE3中:
FormMain.Width = 1400
ClientWidth = 1024

在XE7中:
FormMain.Width = 1400
ClientWidth = 1024

定义的尺寸宽度为754,高度为515 出于某些不明原因,在XE7中没有绘制图标 如果我在打开表单后调整表单大小,图标会正确显示!

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

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

由于painels 1~5具有固定的尺寸(总数= 448),我没有看到重新计算painel [0]宽度的原因。

同样,问题只出现在XE7中。

enter image description here

1 个答案:

答案 0 :(得分:3)

您需要将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;

结果:

Statusbar image

根据海报的评论(在此答案下方),问题似乎与表格OnResize事件中的代码实际相关,因为这两个问题不再有足够的空间面板。有问题的代码(取自海报的评论):

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;

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

宽度为800像素的表格 - 请注明状态栏面板,其中包含日期:

enter image description here

宽度为600像素的表格 - 缺少日期的备注状态栏面板

enter image description here

这里的解决方案是首先扣除面板3和4的宽度,然后将剩余空间的百分比分配给面板0.注意我使用表格{{1}而不是ClientWidth

Width