Delphi XE2 ve sonraki sürümler, Windows API bildirimlerinin büyük bir bölümünü kapsamlı Winapi.Windows birimine taşıdı ve bazı record bildirimlerini sıkılaştırdı. Eski Delphi sürümlerinde derlenen kod, bir Enhanced Metafile kaydı tagLOGBRUSH32 değeri sunarken GDI API tagLOGBRUSH veya TLogBrush beklediğinde bu yüzden başarısız olabilir.
Belirti genellikle EMF kayıtları yeniden oynatılırken veya PEMRCreateBrushIndirect üzerinden GDI fırça nesneleri yeniden oluşturulurken görünür. Aşağıdaki gibi doğrudan bir çağrı makul görünür, ancak iki record türü yeni Delphi derleyicilerinde assignment-compatible değildir.
|
1 2 3 4 5 |
procedure VEMRCREATEBRUSHINDIRECT(Data: PEMRCreateBrushIndirect); begin GDIObjects[Data^.ihBrush] := CreateBrushIndirect(Data^.lb); //GDIObjects and CreateBrushIndirect are defined in the winapi.windows unit. end; |
Derleyici E2010 Incompatible types: 'tagLOGBRUSH' and 'tagLOGBRUSH32' bildirir. Record'u güvensiz bir cast ile zorlamayın. Daha güvenli çözüm, yerel bir TLogBrush oluşturmak, uyumlu alanları açıkça kopyalamak ve bu yapıyı CreateBrushIndirect çağrısına vermektir.
|
1 2 3 4 5 6 7 8 9 |
procedure VEMRCREATEBRUSHINDIRECT(Data: PEMRCreateBrushIndirect); var LogBrush: TLogBrush; begin LogBrush.lbStyle := Data^.lb.lbStyle; LogBrush.lbColor := Data^.lb.lbColor; LogBrush.lbHatch := Data^.lb.lbHatch; GDIObjects[Data^.ihBrush] := CreateBrushIndirect(LogBrush); end; |
Açık kopyalama neden daha güvenlidir
tagLOGBRUSH32, serileştirilmiş metafile verilerinin kararlı 32-bit alan düzenine sahip olması için EMF kayıt biçiminde kullanılır. Buna karşılık CreateBrushIndirect, geçerli API bildiriminde kullanılan normal Windows fırça yapısını kabul eder. lbStyle, lbColor ve lbHatch alanlarını kopyalamak dönüşümü belgeler ve derleyiciye özgü record uyumluluğuna bağımlılığı önler.
Bu desen, eski grafik kodu Unicode Delphi'ye veya 64-bit hedeflere taşınırken de daha kolay incelenir. Sonraki bir Windows SDK bildirimi tür alias'larını tekrar değiştirirse, alan alan yapılan dönüşüm amaçlanan veri sınırını açık hale getirir.
Taşıma kontrol listesi
- Modern Delphi projelerinde
Winapi.Windowsbirimini uses listesinde tutun. - EMF kayıt alanlarını GDI çağrısının beklediği API yapısına kopyalayın.
- İkili düzeni ve yaşam süresini doğrulamadıkça bunu kör bir pointer cast ile değiştirmeyin.
- Fırça oluşturulduktan sonra
GDIObjectstablonuz için mevcut nesne sahipliği kurallarını koruyun.
Bu neden Delphi yükseltmelerinde görünür
Eski EMF oynatma kodu, Windows kayıtlarını çoğu zaman API yapıları ile serileştirilmiş metafile yapıları birbirinin yerine geçebilirmiş gibi ele alır. Eski birimler ve daha gevşek alias'lar bazen bu varsayımın derlenmesine izin verirdi. Modern Delphi bildirimleri daha sıkıdır, bu yüzden derleyici Windows API içinde zaten var olan sınırı ortaya çıkarır.
Bu hata bu nedenle yalnızca bir sözdizimi sorunu değildir. Kodun bir dosya biçimi yapısından canlı bir GDI çağrısına geçtiğini gösteren yararlı bir uyarıdır. Dönüşümü açık tutmak, kod daha sonra 64-bit derlemeler, Unicode geçişi veya güncellenmiş Windows SDK bildirimleri için incelendiğinde daha güvenli hale getirir.
Ne yapılmamalı
Bir pointer cast derleyici hatasını kaldırıyor gibi görünebilir, ancak gerçek dönüşümü gizler ve sonraki bakımı zorlaştırabilir. Ayrıca inceleyenlere hangi alanların özellikle kullanıldığı konusunda ipucu vermez. Alan kopyası kısa, deterministik ve kendi kendini belgeleyen bir çözümdür; bu nedenle uygulama kodu ve komponent örnekleri için daha iyi varsayılandır.
EMF parser'ınız benzer birçok kaydı işliyorsa, bu dönüşümü küçük bir yardımcı fonksiyona sarın ve birkaç fırça stiliyle test edin. Böylece replay loop okunabilir kalır ve Windows API sınırı açık kalmaya devam eder.