2015-05-14 4 views
2

Мое приложение будет отображать некоторые сведения в строке состояния при инициализации. Я показываю это путем рисования значков (вкл. И выкл.) В строке состояния. Следующий код отлично работает в Embarcadero XE3, но больше не работает в версии XE7. Код не вызывает никаких исключений или ошибок. Как я могу это исправить?Нарисуйте изображение в StatusBar, не работающем в версии 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

UPDATE
(См комментарии)
ошибка происходит потому, что OnResizeEvent из FormMain.

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

Значения, показавшие, когда я отладки одинаковы в обоих вариантах:
В XE3:
FormMain.Width = 1400
ClientWidth = 1024

В XE7:
FormMain. Ширина = 1400
ClientWidth = 1024

Определенный размер 754 для ширины и 515 для высоты.
По какой-то непонятной причине в XE7 значки не выделены.
Если я изменил размер формы после ее открытия, значки отображаются правильно!

Я не применял ни одной кожи или менял стиль моего приложения. Я использую конфигурации по умолчанию

Строка состояния будет иметь 6 painels:
0 - показывать подсказки (ширина гибка, изменения, когда форма изменение ширины)
1 - покажет имя текущей выбранной компании (фиксированная ширина)
2 - покажет имя текущего пользователя (фиксированная ширина)
3 - покажет иконку (фиксированная ширина)
4 - покажет иконку (фиксированная ширина)
5 - покажет дата (фиксированная ширина)

С момента основания nels 1 ~ 5 имеют фиксированный размер (всего = 448), я не вижу причин для пересчета в% ширины болиля [0].

Опять же, проблема возникает только в XE7.

enter image description here

+0

Вы используете стили в своем проекте (Project - Options - Application - Appearance)? Какова ширина времени выполнения вашей формы? Если оно меньше 450, появляются ли изображения, если вы увеличиваете ширину, чтобы ширина панели [0] 'была положительной? Пожалуйста, отредактируйте свой вопрос с ответами на эти вопросы и включите факты, которые вы упомянули в комментариях к ответу Ken Whites. –

+0

Неудобно найти, что люди, обращающиеся за помощью, слишком небрежны, чтобы ответить несколькими простыми деталями, которые либо исключили бы, либо подтвердили бы возможные причины их проблем. –

+0

Отредактировано. Пожалуйста, просмотрите его. – rodrigopandini

ответ

3

Вы должны установить TPanel.Style в psOwnerDraw, а не по умолчанию psText. Если вы этого не сделаете, OnDrawPanel не вызывается.

Быстрый тест подобного кода показывает, что он работает (по крайней мере, в X Е8):

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

Основываясь на комментариях плаката (ниже этого ответа), похоже, что проблема действительно связана с кодом в событииформы, где больше нет места для двух проблемных панелей. Код в вопросе (взято из комментариев автора):

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, BTW.)

Проблема с чертежом панели, я думаю, связана с вычислением ширины панели. Если после калибровки 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. Обратите внимание, что я использую форму 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; 
+0

Стиль установлен на psOwnerDraw, но все равно не работает. Как я уже говорил, отлично работает в XE3, но не в XE7. Я не менял код. – rodrigopandini

+0

Он отлично работает с кодом выше (который я тестировал перед публикацией). Поместите контрольную точку в обработчик 'StatusBar1DrawPanel' (в строке' case') и запустите. Что происходит при выполнении кода? –

+0

Ничего. Я понял, что в результате выполнения OnFormResize вызывается с последующим кодом: 'procedure TFormMain.FormResize (Sender: TObject); begin StatusBar1.Panels [0]. Ширина: = FormMain.Width - 448; end; ' Если я прокомментирую эту строку, значки будут правильно нарисованы. Теперь вопросы: зачем менять ширину панели, прекратит работу и правильно работает в XE3, а не в XE7? – rodrigopandini