Tip: (thanks to Josir Gomes for this)
"To load the JPEG image from file, you have to use the LoadFromFile from the new fieldtype.
If you use DbImage.Picture.LoadFromFile(), the image will not be loaded correctly."
Removed Bugs:
11 July 2002:
DBGraphicSupport.pas
Problem with handling empty Blob-fields solved (TEnhBlobField.SaveToAnyImage)
Graphic-Support
This package enables standard TDBImage-components to display JPEG, EMF,
WMF and ICO graphics, that are stored in Blob-fields in databases,
and TQRDBImage-components (QuickReport) to print them as well.
The advantage of GraphicSupport is, that you don't need an extra component
in the palette, but just use the existing ones, as you are used to.
GraphicSupport also shows a simple approach to add support for any
type of graphic, you can get or write a TGraphic-compatible class for.
Study the sources to understand why; especially the function GetGraphicClass.
GraphicSupport is written for Delphi 6. If you dare a Delphi 5
or Delphi 4 Version, let me know.
Problem
Why doesn't a JPEG-stream, stored in a Blob-Field, get displayed in a
TDBImage component? Simple: TBlobField (that handles the transfer of
Blob-data to TBitmap and TPicture) doesn't know that there may be a
suitable class for JPEGs, creates a TBitmap and passes the Blob-data
to it. BANG....TBitmap spits out it's 'I don't know this format'-
message and leaves the DBImage-canvas blank.
Solution
Everything we have to do is to define a descendant of TBlobField that
"knows" additional graphic formats!
But that's only half the way, because who tells the IDE
or TDataset (or it's descendants), that it has to use the 'enhanced'
Blob-Field instead of the standard one?
To manage this situation it is necessary to understand, how TField-objects
are managed by TDataset (and some other classes). If there's a need
for a TField-object, any class that deals with database-stuff looks
into the constant array "DefaultFieldClasses". This array stores a
hardcoded list, that defines a TField-class for any TFieldType:
(from unit DB.pas)
type
TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord,
ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime,
ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo,
ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, ftFixedChar, ftWideString,
ftLargeint, ftADT, ftArray, ftReference, ftDataSet, ftOraBlob, ftOraClob,
ftVariant, ftInterface, ftIDispatch, ftGuid);
const
DefaultFieldClasses: array[TFieldType] of TFieldClass = (
nil, { ftUnknown }
<snip>
...
<snip>
TBlobField, { ftBlob } <<<<this one of special interest!
TMemoField, { ftMemo }
TGraphicField, { ftGraphic } <<<<this one too!
<snip>
...
<snip>
TGuidField); { ftGuid }
Now this constant array defines which TField-class has to be used, if a certain
FieldType is given. What we know is, that constants aren't as constant as
they seem. Especially the content of a constant array.So all we have to do, is
replace the entries for ftBlob and ftGraphic at runtime, so that they contain a
reference to TEnhBlobField and TEnhGraphicField before the IDE or
any DB-class tries to create TField-objects.
First try would be to include a unit that does the replacement in its
initialization-section.
But this will only work for TField-objects that are created at runtime.
To let the Field-Editor create TEnhBlobField references at design-time,
the replacement has to take place before the TField-objects are created
by the IDE. For this purpose a package can do the replacement in its
Register-procedure. If this package is installed into the IDE (and
therefore gets loaded everytime the IDE starts up) anything will work just fine.
The last remaining problem is a very hidden one. In IBDataset Borland
redefines the constant array "DefaultFieldClasses", storing different values
in it. This while using DB.pas itself and therefore knowing the original
constant. So under some circumstances it has to be ensured, that both
definitions are fixed, for what a secod variant of the GraphicSupport unit is
needed: GraphicSupportIB.
GraphicSupportIB does nothing else, than using IBCustomDataset and doing the
replacement a second time.
Addendum for Delphi 6:
With Delphi 6 Borland compiled the DB-packages with $J- and overwriting the
constants directly is not supported any longer.
I've added a workaround to continue the functionality of my package:
TFieldClass(Pointer(@DefaultFieldClasses[ftBlob])^) := TEnhBlobField;
This line tricks the compiler, because
- getting the address of a constant is allowed - @,
- tracting it as a ointer is allowed too - Pointer(,
- dereference pointers is okay as well - ^,
- and typecasting works, sometimes even if it shouldn't - TFieldClass(.
I'm very glad to present JPEGSupport for Delphi 6 - finally. :-)
For QuickReport-Users:
Remember:
QRDBImage prints JPEGs too, if this package is installed!
For questions or comments please contact
Robert Kuhlmann
email: robert.kuhlmann.dev@ewetel.net
ChipHead
- 粉丝: 3
- 资源: 7
最新资源
- YOLOv8完整网络结构图详细visio
- LCD1602电子时钟程序
- 西北太平洋热带气旋【灾害风险统计】及【登陆我国次数评估】数据集-1980-2023
- 全球干旱数据集【自校准帕尔默干旱程度指数scPDSI】-190101-202312-0.5x0.5
- 基于Python实现的VAE(变分自编码器)训练算法源代码+使用说明
- 全球干旱数据集【标准化降水蒸发指数SPEI-12】-190101-202312-0.5x0.5
- C语言小游戏-五子棋-详细代码可运行
- 全球干旱数据集【标准化降水蒸发指数SPEI-03】-190101-202312-0.5x0.5
- spring boot aop记录修改前后的值demo
- 全球干旱数据集【标准化降水蒸发指数SPEI-01】-190101-202312-0.5x0.5
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页