📄 mmdib.pas
字号:
{========================================================================}
{= (c) 1995-98 SwiftSoft Ronald Dittrich =}
{========================================================================}
{= All Rights Reserved =}
{========================================================================}
{= D 01099 Dresden = Tel.: +0351-8012255 =}
{= Loewenstr.7a = info@swiftsoft.de =}
{========================================================================}
{= Actual versions on http://www.swiftsoft.de/mmtools.html =}
{========================================================================}
{= This code is for reference purposes only and may not be copied or =}
{= distributed in any format electronic or otherwise except one copy =}
{= for backup purposes. =}
{= =}
{= No Delphi Component Kit or Component individually or in a collection=}
{= subclassed or otherwise from the code in this unit, or associated =}
{= .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed =}
{= without express permission from SwiftSoft. =}
{= =}
{= For more licence informations please refer to the associated =}
{= HelpFile. =}
{========================================================================}
{= $Date: 20.01.1998 - 18:00:00 $ =}
{========================================================================}
unit MMDIB;
{$I COMPILER.INC}
interface
uses
{$IFDEF WIN32}
Windows,
{$ELSE}
WinProcs,
WinTypes,
{$ENDIF}
SysUtils,
MMSystem,
MMUtils;
const
{$IFDEF CBUILDER3} {$EXTERNALSYM BFT_ICON } {$ENDIF}
BFT_ICON = $4349; { 'IC' }
{$IFDEF CBUILDER3} {$EXTERNALSYM BFT_BITMAP } {$ENDIF}
BFT_BITMAP = $4d42; { 'BM' }
{$IFDEF CBUILDER3} {$EXTERNALSYM BFT_CURSOR } {$ENDIF}
BFT_CURSOR = $5450; { 'PT' }
{$IFDEF CBUILDER3} {$EXTERNALSYM BI_BITFIELDS } {$ENDIF}
BI_BITFIELDS = 3;
{$IFDEF CBUILDER3} {$EXTERNALSYM HALFTONE } {$ENDIF}
HALFTONE = COLORONCOLOR;
{ flags for _lseek }
{$IFDEF CBUILDER3} {$EXTERNALSYM SEEK_CUR } {$ENDIF}
SEEK_CUR = 1;
{$IFDEF CBUILDER3} {$EXTERNALSYM SEEK_END } {$ENDIF}
SEEK_END = 2;
{$IFDEF CBUILDER3} {$EXTERNALSYM SEEK_SET } {$ENDIF}
SEEK_SET = 0;
{ flags for orientation }
TOPDOWN = -1;
BOTTOMUP = 1;
type
PRGBQUAD = ^TRGBQUAD;
PDIB = PBitmapInfoHeader;
HDIB = THandle;
(************************************************************************)
procedure ClearSystemPalette;
function CreateSystemColorPalette: PLogPalette;
function LoadPalette(FName: string): PLOGPALETTE;
function SavePalette(FName: string; pLogPal: PLOGPALETTE): Boolean;
(************************************************************************)
function DIB_Create(bits, orientation, width, height: integer; AllocBits: Boolean): PDIB;
function DIB_ReadBitmapInfo(fh: THandle): PDIB;
function DIB_OpenFile(szFile: PChar): PDIB;
function DIB_SetUsage(pbi: PDIB; hPal: HPALETTE; wUsage: UINT): Boolean;
procedure DIB_MapToPalette(var pbi: PDIB; hpal: HPALETTE);
procedure DIB_Display(pbi: PDIB; DC: HDC; aRect: TRect);
function DIB_BitmapToDIB(Handle: HBitmap; Palette: HPalette;
Bits, Orientation: integer): PDIB;
procedure DIB_DIBToBitmap(pbi: PDIB; var Bitmap: HBitmap;
var Pal: HPalette);
(************************************************************************)
function IsWinDIB(pbi: PBITMAPINFOHEADER): Boolean;
function HandleFrom_DIB(lpbi: PDIB): THandle;
function DIB_FromHandle(h: THandle): PDIB;
procedure DIB_Free(lpbi: PDIB);
function DIB_Width(lpbi: PDIB): integer;
function DIB_Height(lpbi: PDIB): integer;
function DIB_BitCount(lpbi: PDIB): integer;
function DIB_Compression(lpbi: PDIB): Longint;
function DIB_NumColors(lpbi: PDIB): Longint;
function DIB_WidthBytesN(lpbi: PDIB; n: integer): Longint;
function DIB_WidthBytes(lpbi: PDIB): Longint;
function DIB_BISize(lpbi: PDIB): integer;
function DIB_SizeImage(lpbi: PDIB): Longint;
function DIB_Size(lpbi: PDIB): Longint;
function DIB_PaletteSize(lpbi: PDIB): DWORD;
function DIB_FlipY(lpbi: PDIB; y: integer): integer;
function DIB_Colors(lpbi: PDIB): PRGBQUAD;
function DIB_Ptr(lpbi: PDIB): Pointer;
function DIB_XYN(lpbi: PDIB; pb: Pointer; x,y,n: integer): Pointer;
function DIB_XY(lpbi: PDIB;x,y: integer): Pointer;
function DIB_Info(pDIB: PDIB): PBitmapInfo;
implementation
{$IFNDEF WIN32}
function _hread(hFile: THANDLE; lpBuffer: Pointer; lBytes: Longint): Longint;
Far; external 'KERNEL' name '_hread';
{$ENDIF}
(************************************************************************)
function IsWinDIB(pbi: PDIB): Boolean;
begin
if (pbi^.biSize <> sizeof(TBITMAPINFOHEADER)) then
Result := False
else
Result := True;
end;
(************************************************************************)
function HandleFrom_DIB(lpbi: PDIB): THandle;
begin
{$IFDEF WIN32}
Result := GlobalHandle(lpbi);
{$ELSE}
Result := GlobalHandle(SELECTOROF(lpbi));
{$ENDIF}
end;
(************************************************************************)
function DIB_FromHandle(h: THandle): PDIB;
begin
Result := GlobalLock(h);
end;
(************************************************************************)
procedure DIB_Free(lpbi: PDIB);
begin
if (lpbi <> nil) then GlobalFreePtr(lpbi);
end;
(************************************************************************)
function WIDTHBYTES(i: Longint): Longint;
begin
Result := ((i+31) and not 31) div 8; { DWORD aligned ! }
end;
(************************************************************************)
function DIB_Width(lpbi: PDIB): integer;
begin
Result := lpbi^.biWidth;
end;
(************************************************************************)
function DIB_Height(lpbi: PDIB): integer;
begin
Result := lpbi^.biHeight;
end;
(************************************************************************)
function DIB_BitCount(lpbi: PDIB): integer;
begin
if IsWinDIB(lpbi) then
Result := lpbi^.biBitCount
else
Result := PBitmapCoreHeader(lpbi)^.bcBitCount;
end;
(************************************************************************)
function DIB_Compression(lpbi: PDIB): Longint;
begin
Result := lpbi^.biCompression;
end;
(************************************************************************)
function DIB_NumColors(lpbi: PDIB): Longint;
begin
if (lpbi^.biClrUsed = 0) and (lpbi^.biBitCount <= 8) then
Result := (1 shl lpbi^.biBitCount)
else
Result := lpbi^.biClrUsed;
end;
(************************************************************************)
function DIB_WidthBytesN(lpbi: PDIB; n: integer): Longint;
begin
Result := WIDTHBYTES(lpbi^.biWidth * Long(n));
end;
(************************************************************************)
function DIB_WidthBytes(lpbi: PDIB): Longint;
begin
Result := DIB_WidthBytesN(lpbi, lpbi^.biBitCount);
end;
(************************************************************************)
function DIB_BISize(lpbi: PDIB): integer;
begin
Result := lpbi^.biSize + DWORD(DIB_PaletteSize(lpbi));
end;
(************************************************************************)
function DIB_SizeImage(lpbi: PDIB): Longint;
begin
if (lpbi^.biSizeImage = 0) then
Result := DIB_WidthBytes(lpbi) * Long(lpbi^.biHeight)
else
Result := lpbi^.biSizeImage;
end;
(************************************************************************)
function DIB_Size(lpbi: PDIB): Longint;
begin
Result := lpbi^.biSize + lpbi^.biSizeImage + (lpbi^.biClrUsed * sizeof(TRGBQUAD));
end;
(************************************************************************)
function DIB_PaletteSize(lpbi: PDIB): DWORD;
begin
Result := DIB_NumColors(lpbi) * sizeof(TRGBQUAD);
end;
(************************************************************************)
function DIB_FlipY(lpbi: PDIB; y: integer): integer;
begin
Result := lpbi^.biHeight-1-y;
end;
(************************************************************************)
function DIB_Colors(lpbi: PDIB): PRGBQUAD;
begin
Result := PRGBQUAD(PChar(lpbi) + lpbi^.biSize);
end;
(************************************************************************)
function DIB_Ptr(lpbi: PDIB): Pointer;
begin
{$IFDEF WIN32}
{ HACK for NT BI_BITFIELDS DIBs }
if (lpbi^.biCompression = BI_BITFIELDS) then
Result := PChar(DIB_Colors(lpbi)) + 3 * sizeof(TRGBQUAD)
else
{$ENDIF}
Result := PChar(DIB_Colors(lpbi)) + lpbi^.biClrUsed * sizeof(TRGBQUAD);
end;
(************************************************************************)
function DIB_XYN(lpbi: PDIB; pb: Pointer; x,y,n: integer): Pointer;
begin
Result := pb;
incHuge(Result,Long(x)*Long(n) div Long(8)+DIB_WidthBytesN(lpbi,n)*Long(y));
end;
(************************************************************************)
function DIB_XY(lpbi: PDIB;x,y: integer): Pointer;
begin
Result := DIB_XYN(lpbi,DIB_Ptr(lpbi),x,y,lpbi^.biBitCount);
end;
(************************************************************************)
procedure FixBitmapInfo(lpbi: PDIB);
begin
if (lpbi^.biSizeImage = 0) then
lpbi^.biSizeImage := DIB_SizeImage(lpbi);
if (lpbi^.biClrUsed = 0) then
lpbi^.biClrUsed := DIB_NumColors(lpbi);
if (lpbi^.biCompression = BI_BITFIELDS) and (lpbi^.biClrUsed = 0) then
lpbi^.biClrUsed := 3;
end;
(************************************************************************)
function DIB_Info(pDIB: PDIB): PBitmapInfo;
begin
Result := Pointer(pDIB);
end;
(************************************************************************)
(* Clear the System Palette so that we can ensure an identity palette *)
(* mapping for fast performance. *)
(************************************************************************)
procedure ClearSystemPalette;
type
{ Logical Palette }
TLogPal = record
palVersion: Word;
palNumEntries: Word;
palEntry: array[0..256] of TPaletteEntry;
end;
var
i: integer;
LogPal: TLogPal;
ScreenPal: HPalette;
ScreenDC: HDC;
begin
with LogPal do
begin
palVersion := $300;
palNumEntries := 256;
{ Reset everything in the system palette to black }
for i := 0 to 255 do
begin
palEntry[i].peRed := 0;
palEntry[i].peGreen := 0;
palEntry[i].peBlue := 0;
palEntry[i].peFlags := PC_NOCOLLAPSE;
end;
{ Create, select, realize, deselect, and delete the palette }
ScreenDC := GetDC(0);
ScreenPal := CreatePalette(PLogPalette(@LogPal)^);
if (ScreenPal <> 0) then
begin
ScreenPal := SelectPalette(ScreenDC,ScreenPal,False);
RealizePalette(ScreenDC);
ScreenPal := SelectPalette(ScreenDC,ScreenPal,False);
DeleteObject(ScreenPal);
end;
ReleaseDC(0, ScreenDC);
end;
end;
(************************************************************************)
function CreateSystemColorPalette: PLogPalette;
type
{ Logical Palette }
PLogPal = ^TLogPal;
TLogPal = record
palVersion: Word;
palNumEntries: Word;
palEntry: array[0..256] of TPaletteEntry;
end;
var
DC: HDC;
Size: integer;
pPal: PLogPal;
begin
{ Get a screen DC to work with }
DC := GetDC(0);
try
{ allocate a log pal and fill it with the color table info }
Size := sizeof(TLogPalette) + 256 * sizeOf(TPaletteEntry);
pPal := GlobalAllocMem(Size);
FillChar(pPal^, Size, 0);
with pPal^ do
begin
palVersion := $300; { Windows 3.0 }
palNumEntries := 256; { table size }
{ Make sure we are on a palettized device }
if (GetDeviceCaps(DC, RASTERCAPS) and RC_PALETTE <> 0) and
(GetDeviceCaps(DC, NUMCOLORS) <= 256) then
begin
{ Get the system colors in the first and last 10 slots }
GetSystemPaletteEntries(DC, 0, 10, palEntry);
GetSystemPaletteEntries(DC, 246, 10, palEntry[246]);
end
else
begin
{ set the entrys by hand }
Longint(palEntry[0]) := RGB($00,$00,$00); { black }
Longint(palEntry[1]) := RGB($80,$00,$00); { dark red }
Longint(palEntry[2]) := RGB($00,$80,$00); { dark green }
Longint(palEntry[3]) := RGB($80,$80,$00); { dark yellow }
Longint(palEntry[4]) := RGB($00,$00,$80); { dark blue }
Longint(palEntry[5]) := RGB($80,$00,$80); { dark magneta }
Longint(palEntry[6]) := RGB($00,$80,$80); { dark cyan }
Longint(palEntry[7]) := RGB($C0,$C0,$C0); { light gray }
Longint(palEntry[8]) := RGB($C0,$DC,$C0); { money green }
Longint(palEntry[9]) := RGB($A6,$CA,$F0); { sky blue }
Longint(palEntry[246]):= RGB($FF,$FB,$F0); { cream }
Longint(palEntry[247]):= RGB($A0,$A0,$A4); { medium gray }
Longint(palEntry[248]):= RGB($80,$80,$80); { dark gray }
Longint(palEntry[249]):= RGB($FF,$00,$00); { red }
Longint(palEntry[250]):= RGB($00,$FF,$00); { green }
Longint(palEntry[251]):= RGB($FF,$FF,$00); { yellow }
Longint(palEntry[252]):= RGB($00,$00,$FF); { blue }
Longint(palEntry[253]):= RGB($FF,$00,$FF); { magneta }
Longint(palEntry[254]):= RGB($00,$FF,$FF); { cyan }
Longint(palEntry[255]):= RGB($FF,$FF,$FF); { white }
end;
end;
finally
ReleaseDC(0,DC);
end;
Result := PLogPalette(pPal);
end;
{$IFNDEF WIN32}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -