-
Notifications
You must be signed in to change notification settings - Fork 1
/
c32bppDIB.cls
2486 lines (2067 loc) · 108 KB
/
c32bppDIB.cls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "c32bppDIB"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
' COMPILE THE APPLICATION FOR BEST PERFORMANCE
' Credits/Acknowledgements - Thanx goes to:
' Paul Caton for his class on calling non VB-Friendly DLLs that use _cdecl calling convention
' http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=70195&lngWId=1
' Carles P.V for his pvResize logic
' Used when manually scaling images with NearestNeighbor or BiLinear interpolation
' Carles P.V for his GIF LZW encoding routines. Used when saving to GIF
' http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=45899&lngWId=1
' Alfred Koppold for his PNG, VB-only, decompression routines. Used when zLib & GDI+ not available
' http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=56537&lngWId=1
' John Korejwa for his JPG, VB-only, encoding routines. Used when saving as JPG and GDI+ not available
' http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=50065&lngWId=1
' John Kleinen for example of a method of calling OLE class functions via API (See GetDroppedFileNames)
' http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=49268&lngWId=1
' Steve McMahon for his example on 24bpp to 8bpp palette reduction using oct trees
' http://www.vbaccelerator.com/home/VB/Code/vbMedia/Image_Processing/Colour_Depth_Reduction/VB6_Colour_Depth_Sample.asp
' www.zlib.net for their free zLIB.dll, the standard DLL for compressing/decompressing PNGs
' Without it, we'd be limited to GDI+ for creating PNGs
' coders like you that provide constructive criticism to make this class better & more all-inclusive
' Without your comments, this project probably would have died several versions/updates ago
' For most current updates/enhancements visit the following. Last changed 10 Oct 08
' Visit http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=67466&lngWId=1
' To see a usercontrol applying a version of this class
' AlphaImage Control. http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=68262&lngWId=1
' Image List Control. http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=69621&lngWId=1
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' O V E R V I E W
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' AlphaBlend API :: (msimg32.dll) , GDI+ API (gdiplus.dll)
' About 32bpp pre-multiplied RGB (pARGB) bitmaps, if you are not aware.
' - These are used specifically for the AlphaBlend API & are GDI+ compatible
' - Only TGA directly identifies premultiplied pixels. Though they can exist in
' PNG & BMP also, there is no flag saying: "Hey, I have premultiplied pixels"
' - The following 4 formats can contain alpha channels: PNG, TGA, BMP, ICO
' Advantages:
' - Images can be per-pixel alpha blended
' - Overall image opacity can be simultaneously adjusted during rendering
' - AlphaBlend does both BitBlt & StretchBlt for pARGB images.
' - Speed: AlphaBlend & GDI+ are pretty quick APIs vs manual blending
' Disadvantages:
' - The original RGB values are permanently destroyed during pre-multiplying
' -- Premultiplied formula: preMultipliedRed=(OriginalRed * Alpha) \ 255
' -- There is no way to convert pARGB back to non-premultiplied RGB values
' The formula would be: reconstructedRed=(preMultipliedRed * 255) \ Alpha.
' but because of integer division when pre-multiplying, the result is very
' close and if this should be premultiplied again & converted again, the
' calculated colors can eventually be completely different than the original.
' Fully opaque pixels pixels are not affected. Any transparent pixel is
' permanently destroyed & can never be returned. Its value becomes vbBlack
' ** Note: When images are converted to other image formats for saving,
' removal of premultiplication is performed to meet their specs.
' - Displaying a pre-multiplied bitmap without AlphaBlend/GDI+ will not result in
' the image being displayed as expected.
' - Not ideal for saving due to its size: SizeOf= W x H x 4
' -- better to save source image instead or compress the DIB bytes using favorite compression utility
' -- with GDI+ or zLib, image can be converted to PNG for excellent reduced storage
' -- Saving as a compressed TGA format generally provides very good file sizes
' - AlphaBlend API is not included/compatible with Win95, NT4 and lower
' - AlphaBlend on Win9x systems can be buggy, especially when rendering to DIBs vs DDBs
' Note that GDI+ is standard on WinXP+, and can be used on Win98,ME,2K & on NT4 if SP6 is installed
' :: side note. I have actually used GDI+ on Win95 without problems; have not tried on NT4 SP5 or lower
' Download GDI+ from:
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlus.asp
' Download ZLib from: http://www.zlib.net
' ----------------------------------------------
' About Win95, Win98, WinME, NT3.5 & NT4 support
' ----------------------------------------------
' These routines may not honor AlphaBlend if it exists on those systems. Win98's version,
' for example, has several bugs that can crash the application when AlphaBlending to DIBs.
' NT4, NT3.5 & Win95 do not come with AlphaBlend and I do not have WinME to test with.
' Therefore, to support these older systems, the Render routine will alphablend manually
' regardless if the AlhpaBlend API exists on the older system or not. However, this can
' be overridden by you. See isAlphaBlendFriendly routine. Therefore, AlphaBlend is only
' reliable on Win2K and above. XP & above already have GDI+
' Class Purpose:
' ----------------------------------------------
' This class holds the 32bpp image. It also marshals any new image thru
' the battery of parsers to determine best method for converting the image
' to a 32bpp alpha-compatible image. It handles rendering, rotating, scaling,
' mirroring of DIBs using manual processes, AlphaBlend, and/or GDI+.
' There are several ways an image can be loaded
' 1. From filename (unicode supported) :: LoadPicture_File
' 2. From a byte array :: LoadPicture_Stream
' 3. From stdPicture object or VB's .Picture object :: LoadPicture_StdPicture
' 4. From VB's Resource file :: LoadPicture_Resource
' 5. From a memory image handle or VB's .Picture.Handle property :: LoadPicture_ByHandle
' 6. From the clipboard :: LoadPicture_ClipBoard
' 7. From file drag/drop's Data object (unicode supported) :: LoadPicture_DropedFiles
' 8. From Pasted files (unicode supported) :: LoadPicture_PastedFiles
' The parser order is very important for fastest/best results. See
' spt_LoadPictureEx how the routine marshals the image thru the parsers.
' cPNGparser :: will convert PNG, all bit depths; aborts quickly if not PNG
' cGIFparser :: will convert non-transparent/transparent GIFs; aborts quickly
' cICOpraser :: will convert XP-Alpha, paletted, true color, & Vista PNG icons
' -- can also convert most non-animated cursors
' cBMPparser :: will convert bitmaps, wmf/emf & jpgs
' cTGAparser :: will convert TGA (Targa, TrueVision) images only
' As a last resort, when GDI+ exists, anything unable to be processed by the
' parsers (i.e., TIFFs) are sent to GDI+. If GDI+ can process the image, then
' the image will be converted, internally, to PNG to enable additional processing.
' The parsers are efficient. Most image formats have a magic number that give
' a hint to what type of image the file/stream is. However, checks need to
' be employed because non-image files could feasibly have those same magic
' numbers. If the image is determined not to be one the parser is designed to
' handle, the parser rejects it and the next parser takes over. Rejection occurs,
' generally, in only a few lines of code. The icon parser is slightly different
' because PNG files can be included into a Vista ico file. When this occurs, the
' icon parser will pass off the PNG format to the PNG parser automatically.
' And last but not least, the parsers have no advanced knowledge of the image
' format; as far as they are concerned, anything passed is just a byte array.
' Relying on file extensions when available is unreliable
' Class Organization:
' ----------------------------------------------
' Search the class for the words NEW SECTION
' The class routines are organized in the following sections:
' Class Initialization & Termination Routines
' Public Properties & Methods (almost 60 and growing)
' Public Read-Only Properties
' Public Methods
' Class to Class Communication Methods
' Local Support Functions
' ----------------------------------------------
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' CHANGE HISTORY
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' Accompanying Usage_c32bppSuite.rtf is updated with every change
' Last changed: 16 Feb 09. See change history within the RTF file
' -- most noticable changes
' :: fixed icon parsing class which can misparse icon masks
' :: fixed cPNGreader class which could misparse grayscale png transparency
' 26 Dec 06: First version
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
'._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
' IMPORTANT FOR UPDATES/ENHANCEMENTS IMPORTANT FOR UPDATES/ENHANCEMENTS
' -----------------------------------------------------------------------------
' NOTE TO SELF: Whenever any routine recreates the DIB (new DIB memory handle),
' a call to Set m_GDIplus = Nothing must be made before changes are applied. This is because
' when the optional KeepGDIplusActive property=True, GDI+ is wrapped around the DIB.
' Deleting the DIB and not releasing GDI+ can cause crashes or unexpected results.
' No APIs are declared public. This is to prevent possibly, differently
' declared APIs, or different versions of the same API, from conflicting
' with any APIs you declared in your project. Same rule for UDTs.
' Note: I did take liberties, changing parameter types, in several APIs throughout
' Used to determine operating system
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (ByRef lpVersionInformation As Any) As Long
Private Type OSVERSIONINFOEX
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128 ' up to here is OSVERSIONINFO vs EX
wServicePackMajor As Integer ' 8 bytes larger than OSVERSIONINFO
wServicePackMinor As Integer
wSuiteMask As Integer
wProductType As Byte
wReserved As Byte
End Type
' APIs used to manage the 32bpp DIB
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (ByRef Ptr() As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Sub FillMemory Lib "kernel32.dll" Alias "RtlFillMemory" (ByRef Destination As Any, ByVal Length As Long, ByVal Fill As Byte)
Private Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal hdc As Long, ByRef pBitmapInfo As Any, ByVal un As Long, ByRef Pointer As Long, ByVal Handle As Long, ByVal dw As Long) As Long
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdcDest As Long, ByVal nXOriginDest As Long, ByVal nYOriginDest As Long, ByVal nWidthDest As Long, ByVal nHeightDest As Long, ByVal hdcSrc As Long, ByVal nXOriginSrc As Long, ByVal nYOriginSrc As Long, ByVal nWidthSrc As Long, ByVal nHeightSrc As Long, ByVal lBlendFunction As Long) As Long
Private Declare Function SetStretchBltMode Lib "gdi32.dll" (ByVal hdc As Long, ByVal nStretchMode As Long) As Long
Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function SetDIBitsToDevice Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dX As Long, ByVal dY As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, ByRef BITS As Any, ByRef BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
'@Ignore ProcedureNotUsed
Private Declare Function GetDIBits Lib "gdi32.dll" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, ByRef lpBits As Any, ByRef lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Const STRETCH_HALFTONE As Long = &H4&
' APIs used for fonts/text
'@Ignore ProcedureNotUsed
Private Declare Function GetGDIObject Lib "gdi32.dll" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, ByRef lpObject As Any) As Long
Private Type Size
Cx As Long
Cy As Long
End Type
Private Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName As String * 32
End Type
Private Type TEXTMETRIC
tmHeight As Long
tmAscent As Long
tmDescent As Long
tmInternalLeading As Long
tmExternalLeading As Long
tmAveCharWidth As Long
tmMaxCharWidth As Long
tmWeight As Long
tmOverhang As Long
tmDigitizedAspectX As Long
tmDigitizedAspectY As Long
tmFirstChar As Byte
tmLastChar As Byte
tmDefaultChar As Byte
tmBreakChar As Byte
tmItalic As Byte
tmUnderlined As Byte
tmStruckOut As Byte
tmPitchAndFamily As Byte
tmCharSet As Byte
End Type
Public Enum eTextAlignment
TA_CENTER = 6
TA_LEFT = 0
TA_RIGHT = 2
TA_RTLREADING = 256
End Enum
Public Enum AlphaTypeEnum
AlphaNone = 0
AlphaSimple = 1
AlphaComplex = 2
End Enum
' APIs used to create files
'Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, ByRef lpNumberOfBytesWritten As Long, ByRef lpOverlapped As Any) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetFileSize Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpFileSizeHigh As Long) As Long
Private Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByRef lpOverlapped As Any) As Long
Private Declare Function SetFilePointer Lib "kernel32.dll" (ByVal hFile As Long, ByVal lDistanceToMove As Long, ByRef lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Const INVALID_HANDLE_VALUE = -1&
' ////////////////////////////////////////////////////////////////
' Unicode-capable Drag and Drop of file names with wide characters
' ////////////////////////////////////////////////////////////////
Private Declare Function DispCallFunc Lib "oleaut32" (ByVal pvInstance As Long, _
ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As VbVarType, _
ByVal paCNT As Long, ByRef paTypes As Integer, _
ByRef paValues As Long, ByRef retVAR As Variant) As Long
Private Declare Function lstrlenW Lib "kernel32.dll" (ByRef lpString As Any) As Long
Private Declare Function GlobalFree Lib "kernel32.dll" (ByVal hMem As Long) As Long
' ////////////////////////////////////////////////////////////////
' Unicode-capable Pasting of file names with wide characters
' ////////////////////////////////////////////////////////////////
Private Declare Function DragQueryFile Lib "shell32.dll" Alias "DragQueryFileA" (ByVal hDrop As Long, ByVal UINT As Long, ByVal lpStr As String, ByVal ch As Long) As Long
Private Declare Function OpenClipboard Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare Function CloseClipboard Lib "user32.dll" () As Long
Private Type FORMATETC
cfFormat As Long
pDVTARGETDEVICE As Long
dwAspect As Long
lIndex As Long
TYMED As Long
End Type
Private Type DROPFILES
pFiles As Long
ptX As Long
ptY As Long
fNC As Long
fWide As Long
End Type
Private Type STGMEDIUM
TYMED As Long
data As Long
pUnkForRelease As IUnknown
End Type
' ////////////////////////////////////////////////////////////////
' used to create the checkerboard pattern on demand
'@Ignore ProcedureNotUsed
Private Declare Function FillRect Lib "user32.dll" (ByVal hdc As Long, ByRef lpRect As RECT, ByVal hBrush As Long) As Long
'Private Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal crColor As Long) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type SafeArray
cDims As Integer
fFeatures As Integer
cbElements As Long
cLocks As Long
pvData As Long
rgSABound(0 To 3) As Long ' reusable UDT for 1 & 2 dim arrays
' array items: 0=1D item count, 1=1D LBound, 2=2D item count, 3=2D LBound
End Type
Private Type ICONINFO
fIcon As Long
xHotspot As Long
yHotspot As Long
hbmMask As Long
hbmColor As Long
End Type
Private Type BITMAPINFOHEADER
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiPalette As Long
End Type
Private Enum eOScapability
osAlphaBlendUsable = 1 ' then AlphaBlend enabled & used when needed
osGDIplusUsable = 2 ' then GDI+ enabled & used when needed (set in isGDIplusEnabled)
'oszLIBusable = 4 ' then zLib enabled & can be used to create/read PNGs (no longer used, tested as needed)
osWin2KorBetter = 8 ' AlphaBlend capable system else it isn't for these classes. See isAlphaBlendFriendly property for more info
osWin98MEonly = 16 ' Win98 or WinME. When m_OScap includes osWin98MEonly+osAlphaBlendUsable then user overrode isAlphaBlendFriendly
osGDIplusNotAvail = 32 ' then NT4 w/less than SP6 or Win95. Otherwise system is GDI+ capable else it isn't
osIsNT = 64 ' NT-based system. Unicode compatible
End Enum
Public Enum eImageFormat ' source image format
imgError = -1 ' no DIB has been initialized
imgNone = 0 ' no image loaded
imgBitmap = 1 ' standard bitmap or jpg
imgIcon = 3 ' standard icon
imgWMF = 2 ' windows meta file
imgEMF = 4 ' enhanced WMF
imgCursor = 5 ' standard cursor
imgBmpARGB = 6 ' 32bpp bitmap where RGB is not pre-multiplied
imgBmpPARGB = 7 ' 32bpp bitmap where RGB is pre-multiplied
imgIconARGB = 8 ' XP-type icon; 32bpp ARGB
imgGIF = 9 ' gif; if class.Alpha=AlphaSimple, then transparent GIF
imgPNG = 10 ' PNG image
imgPNGicon = 11 ' PNG in icon file (Vista)
imgCursorARGB = 12 ' alpha blended cursors? do they exist yet?
imgCheckerBoard = 64 ' image is displaying own checkerboard pattern; not a true image
imgTGA = 128 ' if alpha<>AlphaNone, then transparent TGA
End Enum
Public Enum ePngProperties ' following are recognized "Captions" within a PNG file
pngProp_Title = 1 ' See cPNGwriter.SetPngProperty for more information
pngProp_Author = 2
pngProp_Description = 4
pngProp_Copyright = 8
pngProp_CreationTime = 16
pngProp_Software = 32
pngProp_Disclaimer = 64
pngProp_Warning = 128
pngProp_Source = 256
pngProp_Comment = 512
' special properties
pngProp_Miscellaneous = 1024 ' this is free-form text can be of any length & contain most any characters
pngProp_DateTimeModified = 2048 ' date/time of the last image modification (not the time of initial image creation)
pngProp_DefaultBkgColor = 4096 ' default background color to use if PNG viewer does not do transparency
pngProp_FilterMethod = 8192 ' one of the eFilterMethods values
pngProp_ClearProps = -1 ' resets all PNG properties
End Enum
Public Enum eTrimOptions ' see TrimImage method
trimAll = 0 ' can be combined using OR
trimLeft = 1
trimTop = 2
trimRight = 4
trimBottom = 8
End Enum
Public Enum eScaleOptions ' See ScaleImage method
ScaleToSize = 0 ' [Default] will always scale
scaleDownAsNeeded = 1 ' will only scale down if image won't fit
ScaleStretch = 2 ' wll always stretch/distort
End Enum
Public Enum eGrayScaleFormulas
gsclNTSCPAL = 0 ' R=R*.299, G=G*.587, B=B*.114 - Default
gsclCCIR709 = 1 ' R=R*.213, G=G*.715, B=B*.072
gsclSimpleAvg = 2 ' R,G, and B = (R+G+B)/3
gsclRedMask = 3 ' uses mostly the Red sample value: RGB = .8Green,.1Red,.1Red
gsclGreenMask = 4 ' uses mostly the Green sample value: RGB = .1Red,.8Green,.1Red
gsclBlueMask = 5 ' uses mostly the Blue sample value: RGB = .1Red,.1Red,.8Blue
gsclRedGreenMask = 6 ' uses Red & Green sample value: RGB = .45Red,.45Green,.1Blue
gsclBlueGreenMask = 7 ' uses Blue & Green sample value: RGB = .1Red,.45Green,.45Blue
gsclNone = -1
End Enum
Public Enum eFilterMethods
filterDefault = 0 ' paletted PNGs will use filterNone while others will use filterPaeth
filterNone = 1 ' no byte preparation used; else preps bytes using one of the following
filterAdjLeft = 2 ' see cPNGwriter.EncodeFilter_Sub
filterAdjTop = 3 ' see cPNGwriter.EncodeFilter_Up
filterAdjAvg = 4 ' see cPNGwriter.EncodeFilter_Avg
filterPaeth = 5 ' see cPNGwriter.EncodeFilter_Paeth
filterAdaptive = 6 ' this is a best guess of the above 4 (can be different for each DIB scanline)
End Enum
Public Enum eRegionStyles ' See CreateRegion
regionBounds = 0
regionEnclosed = 1
regionShaped = 2
End Enum
Public Enum eConstants ' See SourceIconSizes
HIGH_COLOR = &HFFFF00
TRUE_COLOR = &HFF000000
TRUE_COLOR_ALPHA = &HFFFFFFFF
End Enum
Private m_Tag As Variant ' user-defined, user usage only. See TAG property
'Private m_PNGprops As cPNGwriter ' used for more advanced PNG creation options
Private m_StretchQuality As Boolean ' if true will use BiLinear or better interpolation
Private m_Handle As Long ' handle to 32bpp DIB
Private m_Pointer As Long ' pointer to DIB bits
Private m_Height As Long ' height of DIB
Private m_Width As Long ' width of DIB
Private m_hDC As Long ' DC if self-managing one
Private m_prevDCobject As Long ' object deselected from DC when needed
Private m_osCAP As eOScapability ' See eOScapability enumeration above
Private m_Format As eImageFormat ' type of source image
Private m_ManageDC As Boolean ' does class manage its own DC?
Private m_AlphaImage As AlphaTypeEnum ' does the DIB contain alpha/transparency?
Private m_GDItoken As Long ' GDI+ token when GDI+ is initialized
Private m_ImageByteCache() As Byte ' should you want the DIB class to cache original bytes
' ^^ N/A if image is loaded by handle, stdPicture, or resource
Private m_GDIplus As cGDIPlus ' maintains GDI+ instance to speed up drawing
Private m_KeepGDIplusActive As Boolean ' see KeepGDIplusActive property
' NEW SECTION *******************************************************************************
' CLASS INITIALIZATION & TERMINATION ROUTINES
' *******************************************************************************************
Private Sub Class_Initialize()
' Determine operating system for compatibility of 32bpp images
' http://vbnet.mvps.org/code/helpers/iswinversion.htm
' http://msdn2.microsoft.com/en-gb/library/ms724834.aspx
Dim osType As OSVERSIONINFOEX
Const VER_PLATFORM_WIN32_WINDOWS As Long = 1
' Retrieve version data for OS.
osType.dwOSVersionInfoSize = Len(osType)
If GetVersionEx(osType) = 0 Then
' The OSVERSIONINFOEX structure is only supported
' in NT4/SP6+ and NT5.x, so we're likely running
' on an earlier version of Windows. Revert structure
' size to OSVERSIONINFO and try again.
osType.dwOSVersionInfoSize = Len(osType) - 8
Call GetVersionEx(osType)
End If
If osType.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then
If osType.dwMinorVersion = 0 Then ' Win95; can't use AlphaBlend nor GDI+
m_osCAP = osGDIplusNotAvail ' fyi. I copied gdi+ onto win95 & it worked! but is it trustworthy
Else ' flag as Alphablend disabled, but capable & is Win98/ME
m_osCAP = osWin98MEonly
End If
Else
If osType.dwMajorVersion > 4 Then ' if Win2K or better
m_osCAP = osAlphaBlendUsable Or osWin2KorBetter ' flag as AlphaBlend enabled (Win2K or better) and capable
Else ' WinNT4. If SP6 or better than GDI+ capable else not. Regardless, not AlphaBlend capable
If osType.wServicePackMajor < 6 Then m_osCAP = osGDIplusNotAvail
End If
m_osCAP = m_osCAP Or osIsNT
End If
' Note for programmers: To test the spt_Win9xBlend function on systems with GDI+
' 1. Unrem next line
' m_osCAP = osGDIplusNotAvail
' 2. Rem out the next two lines
Me.isGDIplusEnabled = True ' attempt to start GDI+, test system capability, add osGDIplusUsable to m_OScap
If Me.isGDIplusEnabled Then Me.HighQualityInterpolation = True
m_Format = imgError
End Sub
Private Sub Class_Terminate()
DestroyDIB ' simply clean up
End Sub
' NEW SECTION *******************************************************************************
' PUBLIC PROPERTIES AND METHODS
' *******************************************************************************************
Public Property Let Alpha(ByVal AlphaType As AlphaTypeEnum)
m_AlphaImage = AlphaType ' determines the flags used for AlphaBlend API
' this flag is set by the various image parsers; setting it yourself
' can produce less than desirable effects.
End Property
Public Property Get Alpha() As AlphaTypeEnum
Alpha = m_AlphaImage
End Property
Public Property Let HighQualityInterpolation(ByVal Value As Boolean)
' When possible GDI+ will be used for stretching & rotation.
' If GDI+ is used,then high quality equates to BiCubic interpolation
' If not used, then BiLinear (manual processing) will be used.
' If High Quality is false, then Nearest Neighbor (very fast, less quality) interpolation used
m_StretchQuality = Value
End Property
Public Property Get HighQualityInterpolation() As Boolean
HighQualityInterpolation = m_StretchQuality
End Property
Public Property Get ImageType() As eImageFormat
ImageType = m_Format ' returns image format of the source image
End Property
Friend Property Let ImageType(ByRef iType As eImageFormat)
m_Format = iType ' set by the various image parsers. This is not used in decision making
' anywhere in these classes, you can do with it what you want -- for now.
End Property
Public Property Let ManageOwnDC(ByVal bManage As Boolean)
' Determines whether or not this class will manage its own DC
' If false, then a DC is created each time the image needs to be Rendered
Dim tDC As Long
If bManage = False Then ' removing management of DC
If Not m_hDC = 0& Then ' DC does exist, destroy it
' first remove the dib, if one exists
If Not m_Handle = 0& Then SelectObject m_hDC, m_prevDCobject
m_prevDCobject = 0&
End If
DeleteDC m_hDC
m_hDC = 0&
Else ' allowing creation of dc
If m_hDC = 0& Then ' create DC only if we have a dib to put in it
If Not m_Handle = 0& Then
tDC = GetDC(0&)
m_hDC = CreateCompatibleDC(tDC)
ReleaseDC 0&, tDC
End If
End If
End If
m_ManageDC = bManage
End Property
Public Property Get ManageOwnDC() As Boolean
ManageOwnDC = m_ManageDC
End Property
Public Property Get isAlphaBlendFriendly() As Boolean
isAlphaBlendFriendly = ((m_osCAP And osAlphaBlendUsable) = osAlphaBlendUsable)
' WinNT4 & below and Win95 are not shipped with msimg32.dll (AlphaBlend API)
' Win98 has bugs & would believe that WinME is buggy too but don't know for sure
' Therefore, the Rendering in this class will not use AlphaBlend on these
' operating systems even if the DLL exists, but will use GDI+ if available
' Can be overridden by setting this property to True
End Property
Public Property Let isAlphaBlendFriendly(ByVal Enabled As Boolean)
' This has been provided to override safety of using AlphaBlend on Win9x systems.
' Caution. Only set this when rendering to a known device dependent bitmap (DDB)
' Alphablend can crash when rendering DIB to DIB vs DIB to DDB. Be warned.
If Enabled = True Then
' Overriding in play: allow AlphaBlend if system is Win98 or better
' By default this is already set for Win2K or better
If ((m_osCAP And osWin2KorBetter) = osWin2KorBetter) Then
m_osCAP = m_osCAP Or osAlphaBlendUsable
ElseIf ((m_osCAP And osWin98MEonly) = osWin98MEonly) Then
m_osCAP = m_osCAP Or osAlphaBlendUsable
End If
Else
m_osCAP = m_osCAP And Not osAlphaBlendUsable ' disallow AlphaBlend
End If
End Property
Public Property Get isGDIplusEnabled() As Boolean
' identifies if GDI+ is usable on the system.
' Before this property is set, GDI+ is tested to ensure it is usable
isGDIplusEnabled = ((m_osCAP And osGDIplusUsable) = osGDIplusUsable)
End Property
Public Property Let isGDIplusEnabled(ByVal Enabled As Boolean)
' Sets the property. If set to False by you, GDI+ will not be used
' for any rendering, but still may be used to create PNG/JPG files if needed
' You can reset it to true at any time. If the system won't support
' GDI+, then the True setting will simply be ignored -- no harm, no foul
' To test success: c32class.isGDIplusEnabled=True: If c32class.isGDIplusEnabled=True Then ' success
If Not Enabled = Me.isGDIplusEnabled Then
m_osCAP = (m_osCAP And Not osGDIplusUsable)
If Enabled Then
If (m_osCAP And osGDIplusNotAvail) = 0 Then ' else Win95, NT4 SP5 or lower
Dim cGDIp As cGDIPlus
If m_GDIplus Is Nothing Then
Set cGDIp = New cGDIPlus
Else
Set cGDIp = m_GDIplus
End If
If cGDIp.isGDIplusOk() = True Then m_osCAP = m_osCAP Or osGDIplusUsable
End If
End If
End If
End Property
Public Property Let gdiToken(ByVal Token As Long)
' Everytime a GDI+ API function is called, the class calls GDI+ apis to
' create a GDI+ token first then destroys the token after the function is called.
' This occurs quite often. However, you can create your own token by calling
' GdiplusStartup and then passing the token to each class for the class to use.
' You would call GdiplusShutdown during your main form's Terminate event to
' release the Token.
' When Token is zero, the classes will revert to creating a token on demand.
' When the Token is not zero, any other DIB class created internally by this class will
' pass the token as needed. The only routine that can create a new instance externally
' and returns that new instance is the CreateDropShadow method. You must set the
' token for that class at some point for that dropshadow class to use the token.
If m_KeepGDIplusActive Then Set m_GDIplus = Nothing ' remove; may be referencing old token
m_GDItoken = Token
End Property
Public Property Get gdiToken() As Long
' returns the GDI+ token if one was created
gdiToken = m_GDItoken
End Property
Public Property Let Tag(ByRef vValue As Variant)
On Error Resume Next
If IsObject(vValue) Then Set m_Tag = vValue Else m_Tag = vValue
End Property
Public Property Set Tag(ByVal vValue As Variant)
Me.Tag = vValue ' use the object check in the Let property
End Property
Public Property Get Tag() As Variant
If IsObject(m_Tag) Then Set Tag = m_Tag Else Tag = m_Tag
End Property
' This setting will keep the current cGDI+ class active which
' prevents destroying the GDI+ hImage and Token objects. This
' can speed up rendering. This option SHOULD NOT be set when the
' class is not compiled. Else crashes will happen when
' user hits END or VB toolbar's STOP button while in IDE
Public Property Get KeepGDIplusActive() As Boolean
KeepGDIplusActive = m_KeepGDIplusActive
End Property
Public Property Let KeepGDIplusActive(ByVal keepActive As Boolean)
m_KeepGDIplusActive = keepActive
If keepActive = False Then
Set m_GDIplus = Nothing
ElseIf Me.isGDIplusEnabled = False Then
' can't set to True if GDI+ not installed
m_KeepGDIplusActive = False
End If
End Property
' NEW SECTION *******************************************************************************
' PUBLIC READ-ONLY PROPERTIES
' *******************************************************************************************
Public Property Get Width() As Long
Width = m_Width ' width of image in pixels
End Property
Public Property Get Height() As Long
Height = m_Height ' height of image in pixels
End Property
Public Property Get BitsPointer() As Long
BitsPointer = m_Pointer ' pointer to the bits of the image
End Property
Public Property Get scanWidth() As Long
scanWidth = m_Width * 4& ' number of bytes per scan line
End Property
Public Property Get Handle() As Long
Handle = m_Handle ' the picture handle of the image
End Property
Public Property Get isZlibEnabled() As Boolean
' To create PNG files, GDI+ or zLib is required. This property informs
' you if zLIB exists in the system's DLL path
If iparseValidateDLL("zlib1.dll", "crc32") = False Then
isZlibEnabled = iparseValidateDLL("zlib.dll", "crc32")
Else
isZlibEnabled = True
End If
End Property
' NEW SECTION *******************************************************************************
' PUBLIC METHODS
' *******************************************************************************************
Public Function LoadPictureFile(ByVal Filename As String, _
Optional ByVal IconCx As Long = 32, _
Optional ByVal IconCy As Long = 32, _
Optional ByVal SaveFormat As Boolean = False, _
Optional ByVal iconBitDepth As Long = 32) As Boolean
' PURPOSE: Convert passed image file into a 32bpp image
' Parameters.
' FileName :: full path of file. Validation occurs before we continue
' iconCx :: desired width of icon if file is an icon file. Default is 32
' iconCy :: desired height of icon if file is an icon file. Default is 32
' ^^ the end parameters: 256,256 is just telling the class that
' we want that size icon if one exists in the passed resource. If not,
' then give us the one closest to it & best quality too.
' SaveFormat :: if true, then the image will be cached as a byte array only
' if the image was successfully loaded. Call GetOrginalFormat to retrieve them.
' iconBitDepth :: the desired bit depth of an icon if the resource is an icon file. Default is 32
' Why would you want to cache the bytes? If this is being used in a usercontrol, saving
' the bytes in WriteProperty will almost always be less size than saving the 32bit DIB.
' Additionally, these classes have the ability to get different sizes from
' the original source (i.e., WMF, icon, cursors) if available, but if the
' 32bit DIB is saved, it is a constant size. The potential of different sizes
' could allow better resizing of the image vs stretching the DIB.
On Error Resume Next
Dim hFile As Long
hFile = iparseGetFileHandle(Filename, True, ((m_osCAP And osIsNT) = osIsNT))
If hFile = INVALID_HANDLE_VALUE Then Exit Function
If GetFileSize(hFile, 0&) > 56 Then
Dim aDIB() As Byte ' dummy array
LoadPictureFile = spt_LoadPictureEx(hFile, Filename, aDIB(), IconCx, IconCy, 0&, 0&, SaveFormat, iconBitDepth)
End If
CloseHandle hFile
End Function
Public Function LoadPictureStdPicture(ByRef Picture As StdPicture) As Boolean
' PURPOSE: Convert passed stdPicture into a 32bpp image
' Revised to allow 32bpp stdPicture objects which can be loaded via VB's LoadPicture
Me.DestroyDIB
If Not Picture Is Nothing Then
' simply pass off to other parsers
If Picture.Type = vbPicTypeIcon Then
' pass to icon/cursor parser
Dim cICO As New cICOparser
Call cICO.ConvertstdPicTo32bpp(Picture.Handle, Me)
Set cICO = Nothing
ElseIf Not Picture.Type = vbPicTypeNone Then
' pass to bmp,jpg,wmf parser
' Note: transparent GIFs should not be passed as stdPictures
' Pass transparent GIFs by Stream or FileName
Dim cBmp As New cBMPparser
If Picture.Type = vbPicTypeBitmap Then
' pass by handle to ensure 32bpp stdPicture objects are processed correctly
Call cBmp.ConvertstdPicTo32bpp(Nothing, Picture.Handle, Me, 0&)
Else ' probably wmf/emf
Call cBmp.ConvertstdPicTo32bpp(Picture, 0&, Me, 0&)
End If
Set cBmp = Nothing
End If
LoadPictureStdPicture = Not (m_Handle = 0&)
End If
End Function
'Public Function LoadPictureClipBoard() As Boolean
'
' ' PURPOSE: Convert clipboard object into a 32bpp image
'
' On Error Resume Next
' With Clipboard
' If (.GetFormat(vbCFBitmap) Or .GetFormat(vbCFDIB) Or .GetFormat(vbCFEMetafile) Or .GetFormat(vbCFMetafile)) Then
' If Not Err Then LoadPictureClipBoard = LoadPictureStdPicture(.GetData())
' End If
' End With
' If Err Then Err.Clear
'End Function
'Public Function LoadPictureDroppedFiles(ByRef DragDrop_DataObject As DataObject, _
' Optional ByVal FileIndex As Long = 1&, _
' Optional ByVal IconCx As Long = 32, _
' Optional ByVal IconCy As Long = 32, _
' Optional ByVal SaveFormat As Boolean = False, _
' Optional ByVal iconBitDepth As Long = 32) As Boolean
'
' ' How to load just the 1st file if 1 or more were dropped
' ' myC32bppDIB.LoadPicture_DroppedFiles Data, 1
'
' ' How to load multiple files into multiple classes
' ' Example assumes your classes are in a collection called colImages
' ' Dim tmpClass As c32bppDIB
' ' For X = 1 To Data.Files.Count
' ' Set tmpClass=New c32bppDIB
' ' If tmpClass.LoadPicture_DroppedFiles(Data, X) Then colImages.Add tmpClass, [key]
' ' Next
'
' ' Parameters
' ' DragDrop_DataObject :: the Data parameter in your form/control's OLEDragDrop event
' ' FileIndex :: the one-bound file that is to be loaded if more than one file were dropped
' ' For the oher parameter descriptions, see LoadPicture_File
'
' ' Note: By calling GetDroppedFileNames yourself, you have more flexibility
'
'' If GetDroppedFileNames(DragDrop_DataObject) Then
'' If FileIndex <= DragDrop_DataObject.Files.count Then
'' LoadPictureDroppedFiles = LoadPictureFile(DragDrop_DataObject.Files(FileIndex), IconCx, IconCy, SaveFormat, iconBitDepth)
'' 'LoadPicture_DropedFiles = LoadPicture_File("E:\dean\steampunk theme\icons\icons MKV\SSL-certificate-folder.ico", 256, 256, False, 32)
'' End If
'' End If
'
'End Function
Public Function LoadDIBinDC(ByVal bLoad As Boolean) As Long
' Purpose: Select/Unselect the DIB into a DC.
' Returns the DC handle when image is loaded
' Called by image parser if it needs to paint the image into the DIB
If bLoad = True Then
Dim tDC As Long
If Not m_Handle = 0& Then ' do we have an image?
If m_hDC = 0& Then ' do we have a DC?
tDC = GetDC(0&) ' if not create one
m_hDC = CreateCompatibleDC(tDC)
ReleaseDC 0&, tDC
End If
If m_prevDCobject = 0& Then
m_prevDCobject = SelectObject(m_hDC, m_Handle)
End If
LoadDIBinDC = m_hDC
End If
Else
If Not m_prevDCobject = 0& Then
SelectObject m_hDC, m_prevDCobject
If m_ManageDC = False Then
DeleteObject m_hDC
m_hDC = 0&
End If
m_prevDCobject = 0&
End If
End If
End Function
'@Ignore FunctionReturnValueNotUsed
Public Function InitializeDIB(ByVal Width As Long, ByVal Height As Long) As Boolean
' Purpose: create a blank (all black, all transparent) DIB of requested height & width
Dim tBMPI As BITMAPINFO
Dim tDC As Long
DestroyDIB ' clear any pre-existing dib
If Width < 0& Then Exit Function
If Height = 0& Then
Exit Function
ElseIf Height < 0& Then
Height = Abs(Height) ' no top-down dibs
End If
On Error Resume Next
With tBMPI.bmiHeader
.biBitCount = 32
.biHeight = Height
.biWidth = Width
.biPlanes = 1
.biSize = 40&
.biSizeImage = .biHeight * .biWidth * 4&
End With
If Err Then
Err.Clear
' only possible error would be that Width*Height*4& is absolutely huge
Exit Function
End If
tDC = GetDC(0&) ' get screen DC
m_Handle = CreateDIBSection(tDC, tBMPI, 0&, m_Pointer, 0&, 0&)
If m_ManageDC = True Then
' create a DC if class is managing its own & one isn't created yet
If m_hDC = 0& Then m_hDC = CreateCompatibleDC(tDC)
End If
' release the screen DC if we captured it
ReleaseDC 0&, tDC
If Not m_Handle = 0& Then ' let's hope system resources allowed DIB creation
m_Width = Width
m_Height = Height
' ref point 0001 - only location where LaVolpe's code has been modified
' expose the size of the original PNG image to the rest of the program
origWidth = m_Width
origHeight = m_Height
'check the size of the preview PNG image and display it
'rDIconConfigForm.lblWidthHeight.Caption = " width " & m_Width & " height " & m_Width & " (pixels)"
EraseDIB ' have experienced new dib filled with non-zeroes. Zero it out
InitializeDIB = True
End If
End Function
Public Sub DestroyDIB()
' PURPOSE: Destroy any existing image
Set m_GDIplus = Nothing
If Not m_hDC = 0& Then ' do we have a DC?
' do we have an image; if so get it out of the DC
If Not m_prevDCobject = 0& Then SelectObject m_hDC, m_prevDCobject
' destroy our DC, no point in keeping it w/o image
DeleteObject m_hDC
m_hDC = 0&
End If
' if we do have an image, destroy it now
If Not m_Handle = 0& Then
DeleteObject m_Handle
Erase m_ImageByteCache
End If
' reset other image attributes
m_Width = 0&
m_Height = 0&
m_Handle = 0&
m_Pointer = 0&
m_prevDCobject = 0&
m_AlphaImage = AlphaNone
m_Format = imgError
End Sub
Public Sub EraseDIB()
' Purpose: clear out an existing DIB pixels, making it 100% transparent/black
If Not m_Handle = 0& Then