⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmdib.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{========================================================================}
{=                (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 + -