Свойство DoubleBuffered, добавляемое в dfm в Delphi 2009, не существует в Delphi 2007
Означает ли это, что я не могу разделить форму между delphi 2007 и 2009?
5 ответов
Да. Это невозможно, если вы не удалите свойства, не опубликованные в Delphi 2007, из DFM.
DoubleBuffered уже некоторое время находится в TWinControl. Разница в Delphi 2009 заключается в том, что она опубликована сейчас. Если вы можете жить, игнорируя только ошибки (и не заставляя свойства работать вместо этого), вот возможное решение:
unit Delphi2009Form;
interface
uses
Windows, Classes, SysUtils, Controls, Forms;
type
{$IFDEF VER200}
TDelphi2009Form = class(TForm);
{$ELSE}
TDelphi2009Form = class(TForm)
private
procedure ReaderError(Reader: TReader; const Message: string; var Handled: Boolean);
protected
procedure ReadState(Reader: TReader); override;
end;
TReaderErrorProc = procedure(const Message: string);
var
ReaderErrorProc: TReaderErrorProc = nil;
{$ENDIF}
implementation
{$IFNDEF VER200}
type
THackReader = class(TReader);
procedure TDelphi2009Form.ReaderError(Reader: TReader; const Message: string; var Handled: Boolean);
begin
with THackReader(Reader) do
Handled := AnsiSameText(PropName, 'DoubleBuffered') or AnsiSameText(PropName, 'ParentDoubleBuffered');
if Handled and Assigned(ReaderErrorProc) then
ReaderErrorProc(Message);
end;
procedure TDelphi2009Form.ReadState(Reader: TReader);
begin
Reader.OnError := ReaderError;
inherited ReadState(Reader);
end;
{$ENDIF}
end.
Затем измените объявления форм в вашем проекте для наследования от TDelphi2009Form, например:
type
TFormMain = class(TDelphi2009Form)
...
Это будет работать во время выполнения - ошибки свойств будут игнорироваться. Чтобы заставить его работать во время разработки, также создайте пакет только для дизайна, добавьте designide.dcp в его условие require и добавьте в него следующий модуль:
unit Delphi2009FormReg;
interface
uses
Delphi2009Form;
procedure Register;
implementation
uses
DesignIntf, DesignEditors, ToolsAPI;
procedure ShowReaderError(const Message: string);
begin
with BorlandIDEServices as IOTAMessageServices do
AddTitleMessage(Message);
end;
procedure Register;
begin
RegisterCustomModule(TDelphi2009Form, TCustomModule);
ReaderErrorProc := ShowReaderError;
end;
initialization
finalization
ReaderErrorProc := nil;
end.
Установите пакет в Delphi 2007 IDE, и ошибки свойств для свойств DoubleBuffered и ParentDoubleBuffered будут автоматически игнорироваться при открытии форм в IDE. Значения свойств будут потеряны при сохранении формы в Delphi 2007, поэтому вместо этого следует инициализировать их в коде.
РЕДАКТИРОВАТЬ: я добавил код для вывода сообщений об ошибках читателя в окно сообщений IDE:
Проекты Delphi всегда было чрезвычайно легко перенести на новые версии. Вы должны быть более осторожными, но использование текущего кода со старыми компиляторами также довольно просто. Я сохранил код в Delphi 2005/2006/2007, который другие люди все еще должны были использовать в Delphi 6 и 7.
Если вы удалите несовместимые свойства из DFM, они должны работать должным образом в старых версиях, не путая их в Delphi 2009. Самый большой пример - явные свойства *, представленные в Delphi 2006. У меня есть домашний "скруббер DFM", который удаляет эти из. Помните, что эти свойства существуют по определенной причине, поэтому вы должны удалять только те из них, которые вы хотите иметь обратно совместимыми.
Вы также можете подумать о приобретении инструментов статического анализа кода, таких как CodeHealer или Pascal Analyzer. Помимо указания проблем (особенно CodeHealer) и помощи в очистке кода, вы можете выбрать версию Delphi для анализа, упрощая поиск несовместимостей помимо свойств DFM. И они могут быть автоматизированы как часть вашего процесса сборки.
Просто записка. Делитесь исходным кодом, но сохраняйте отдельные проекты для каждой версии. Это особенно важно между Delphi 2007 и Delphi 2009. Более поздний файл.dproj использует то же расширение, но не совместим с Delphi 2007. Вы также можете столкнуться с некоторой проблемой с несовместимыми ресурсами.
Каждая форма имеет файл dfm, который содержит настройки свойств формы и ее компонентов. Некоторые значения свойств имеют значения по умолчанию, поэтому они не сохраняются, если сохраняется значение по умолчанию. Это просто сделал небольшой тест:
- Создать форму в 2009 году
- Добавьте пару стандартных элементов управления
- Сохрани это
- Откройте его в 2006 году (извините, нет 2007 на этом компьютере)
И это работало без сообщений. Но, возможно, вам не так повезло.
С Delphi часто бывает сложно обмениваться данными между версиями. Возможности обновления велики, но понижение проблематично. Поэтому я не советую делиться файлами форм между разными версиями.
Насколько я знаю, невозможно добавить условные определения в файл dfm. Но опять же, мы действительно этого хотим... Я бы предпочел механизм, который игнорирует неизвестные свойства.
Вы можете безопасно добавить свойства в коде в методе OnCreate для формы и обернуть {$IFDEF VER200} // НОВЫЕ СВОЙСТВА {$ENDIF} вокруг них. Вы можете оставить DoubleBuffered вне ifdefs, как это было в Delphi 2007, но он не доступен для инспектора свойств.
Вам ТОЛЬКО придется беспокоиться о свойствах, которые вы устанавливаете отличными от настроек по умолчанию. Для двойной буферизации вам нужно беспокоиться об этом, только если для нее установлено значение true.
При загрузке формы Delphi 2009 в Delphi 2007 вы получите предупреждение о том, что свойство будет уничтожено, просто запишите эти свойства, поскольку с ними вам придется иметь дело.
Я использую именно такой метод для переноса своего кода в Delphi 2009 из Delphi 2006. Большинство моих проектов содержат несколько общих модулей и должны скомпилироваться в Delphi 2006 для отгрузочной версии и Delphi 2009 для "следующего" выпуска. Я также часто использую определение {$IFDEF UNICODE}, где мне нужно убедиться, что строка является широчайшей или несовместимой в зависимости от процедуры.