Delphi中标准控件是不支持png图片的,据说从Window2000后增加gdiplus.dll库处理更多的gdi图像,其中包括png。
  关键的几个api
  GdipCreateBitmapFromFile(),从文件载入图像(不单只Bitmap)
  GdipCreateBitmapFromStreamICM(),从流中入图像
  GdipCreateHBITMAPFromBitmap(),获取图像的位图
  GdipDisposeImage(),释放图像资源
 
  开始直接调用GdipCreateBitmapFromFile没有成功,返回18的错误
  查一下资料这个错误是:“GdiplusNotInitialized”
  看来必须的初始化gdiplus。
  网上找到一套“TGPBitmap”相关的组件,封装了gdiplus的调用。可以参考其中的代码。
 
  png载入后,再取出其位图。特别注意,这个位图是32位的。包括了R、G、B、Alpha四个色值,其中Alpha就是透明度。UpdateLayeredWindow()API函数可以支持Alpha风格。
 
  如何从流中载入?如何将VCL的流处理成IStream?看看代码吧。
 
效果图:
 
准备一张Png图片,编写rc文件,然后加入到工程中。
代码:
CJ7.rc
Png_Cj7 PNG "CJ7.png"
 
CJ7Unit.pas

unit CJ7Unit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TFormCJ7 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FormCJ7: TFormCJ7;

implementation

{$R *.dfm}

uses ActiveX;

type
  DebugEventLevel = (
    DebugEventLevelFatal,
    DebugEventLevelWarning
  );
  TDebugEventLevel = DebugEventLevel;

DebugEventProc = procedure(level: DebugEventLevel; message: PChar); stdcall;

GdiplusStartupInput = packed record
    GdiplusVersion: Cardinal;
    DebugEventCallback: DebugEventProc;
    SuppressBackgroundThread: BOOL;
    SuppressExternalCodecs: BOOL;
  end;                          
  TGdiplusStartupInput = GdiplusStartupInput;
  PGdiplusStartupInput = ^TGdiplusStartupInput;

NotificationHookProc = function(out token: ULONG): Integer; stdcall;
  NotificationUnhookProc = procedure(token: ULONG); stdcall;

GdiplusStartupOutput = packed record
    NotificationHook  : NotificationHookProc;
    NotificationUnhook: NotificationUnhookProc;
  end;
  TGdiplusStartupOutput = GdiplusStartupOutput;
  PGdiplusStartupOutput = ^TGdiplusStartupOutput;

function GdipCreateHBITMAPFromBitmap(bitmap: THandle; out hbmReturn: HBITMAP;
  background: Longword): Integer; stdcall; external 'gdiplus.dll';

function GdipCreateBitmapFromFile(filename: PWChar; out bitmap: THandle): Integer;
  stdcall; external 'gdiplus.dll';

function GdipCreateBitmapFromStreamICM(stream: ISTREAM;
  out bitmap: THandle): Integer; stdcall; external 'gdiplus.dll';

function GdipDisposeImage(image: THandle): Integer; stdcall;
  stdcall; external 'gdiplus.dll';

function GdiplusStartup(out token: ULONG; input: PGdiplusStartupInput;
  output: PGdiplusStartupOutput): Integer; stdcall; external 'gdiplus.dll';

procedure GdiplusShutdown(token: ULONG); stdcall; external 'gdiplus.dll';

procedure TFormCJ7.FormCreate(Sender: TObject);
var
  vGdip: THandle;
  vBitmap: HBITMAP;
  vOldBitmap: HBITMAP;
  vPoint1, vPoint2: TPoint;
  vSize: TSize;
  vBlendFunction: TBlendFunction;
  vDC: HDC;
  vBitmapInfo: TBitmapInfoHeader;
  vDIBSection: TDIBSection;
  vBuffer: PChar;
  vStream: IStream;
  vGlobal: THandle;
begin
  SetWindowLong(Handle, GWL_EXSTYLE,
    GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
   
  ///////Begin 从资源中载入 
  with TResourceStream.Create(HInstance, 'Png_Cj7', 'PNG') do try
    vGlobal := GlobalAlloc(GHND, Size);
    if vGlobal = 0 then Exit;
    vBuffer := GlobalLock(vGlobal);
    if not Assigned(vBuffer) then Exit;
    try
      Read(vBuffer^, Size);
    finally
      GlobalUnlock(vGdip);
    end;
    if CreateStreamOnHGlobal(vGlobal, False, vStream) <> S_OK then Exit;
    if GdipCreateBitmapFromStreamICM(vStream, vGdip) <> S_OK then Exit;
    GlobalFree(vGlobal);
  finally
    Free;
  end;
  ///////End 从资源中载入

if GdipCreateHBITMAPFromBitmap(vGdip, vBitmap, 0) <> S_OK then Exit;
 
  vBitmapInfo.biSize := SizeOf(vBitmapInfo);
  GetObject(vBitmap, SizeOf(vDIBSection), @vDIBSection);
  vPoint1 := Point(Left, Top);
  vPoint2 := Point(0, 0);
  vSize.cx := vDIBSection.dsBm.bmWidth;
  vSize.cy := vDIBSection.dsBm.bmHeight;
  vBlendFunction.BlendOp := AC_SRC_OVER;
  vBlendFunction.BlendFlags := 0;
  vBlendFunction.SourceConstantAlpha := $FF; // 透明度
  vBlendFunction.AlphaFormat := AC_SRC_ALPHA; //同上
  vDC := CreateCompatibleDC(Canvas.Handle);
  vOldBitmap := SelectObject(vDC, vBitmap);
  UpdateLayeredWindow(Handle, Canvas.Handle,
    @vPoint1, @vSize, vDC, @vPoint2, 0, @vBlendFunction, ULW_ALPHA);
  SelectObject(vDC, vOldBitmap);
  DeleteDC(vDC);
  DeleteObject(vBitmap);
  GdipDisposeImage(vGdip);
end;

procedure TFormCJ7.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  ReleaseCapture;
  Perform(WM_SYSCOMMAND, SC_MOVE or HTCLIENT, 0); // 拖动
end;

var
  vStartupInput: TGDIPlusStartupInput;
  vToken: ULONG;

initialization
  vStartupInput.DebugEventCallback := nil;
  vStartupInput.SuppressBackgroundThread := False;
  vStartupInput.SuppressExternalCodecs   := False;
  vStartupInput.GdiplusVersion := 1;
  GdiplusStartup(vToken, @vStartupInput, nil);

finalization
  GdiplusShutdown(vToken);

end.

想了解gdi+的资料可以参考:

http://msdn2.microsoft.com/en-us/library/ms533798.aspx

http://blog.csdn.net/zswang/article/details/2119649

使用PNG实现半透明的窗体(使用GDI+)的更多相关文章

  1. GDI+用PNG图片做半透明异型窗口

    http://hi.baidu.com/bluew/blog/item/2ecbe58bf93a937d9f2fb4de.html2007-08-09 00:52 我是用PNG图片Alpha透明的方式 ...

  2. 完美PNG半透明窗体解决方案

    当年Vista系统刚出来的时候,最吸引人的莫过于半透明磨砂的窗体界面了,迷倒了多少人.这个界面技术随即引发了编程界的一阵骚动,很多人都在问:如何实现这一界面效果?当然,在Vista下倒是很简单,系统本 ...

  3. Windows 窗体的.Net 框架绘图技术

    当编写一个典型的Windows 窗体程序时,窗体和控件的绘制.效果等操作是不需要特别加以考虑的.这是为什么呢?因为通过使用 .Net 框架,开发人员可以拖动一系列的控件到窗体上,并书写一些简单的与事件 ...

  4. 使用绘图API自定义组件

    -----------------siwuxie095                                 工程名:CustomizeSwing 包名:com.siwuxie095.swi ...

  5. 为组件设定UI

    -----------------siwuxie095                             工程名:CustomizeSwing 包名:com.siwuxie095.swing 类 ...

  6. WPF绘制自定义窗口

    原文:WPF绘制自定义窗口 WPF是制作界面的一大利器,下面就用WPF模拟一下360的软件管理界面,360软件管理界面如下: 界面不难,主要有如下几个要素: 窗体的圆角 自定义标题栏及按钮 自定义状态 ...

  7. 网易云信Duilib开发实践和Windows应用界面开发框架源码开源介绍

    序言 Duilib介绍 Duilib是windows平台下的一款轻量级directUI开源库(遵循BSD协议),完全免费,可用于商业软件开发,只需在软件包里附上协议文件即可.Duilib可以简单方便地 ...

  8. gdi+ 高速绘制透明窗体

    gdi+ 高速绘制透明窗体: 方法一: 1.用Iamge对象载入png资源, 2.调用drawimage函数讲图片绘制出了 3.UpdateLayeredWindow对窗体进行布局 方法二: 1.用B ...

  9. 用C++实现半透明按钮控件(PNG,GDI+)

        使用MFC实现上面的按钮半透明效果能看到父窗口中的内容,上面是效果图(一个是带背景图片的.另一个是不带的). 控件继承自CWnd类(彩色的部分是窗口的背景图片.按钮是PNG图片,第二个图标是鼠 ...

随机推荐

  1. Java冒泡排序与二分法查找的代码随笔

    package javafirst; import java.util.Arrays; class MaoPao{ //升序排列 /** * @param arr 要排序的数组 * @return i ...

  2. 【noip模拟】连环

    [题目描述] 惠子说:“连环可解也”. 这说明他是一个破解机关的高手,连连环都能解开,鲁班锁什么的自然不在话下.一位鲁班的后人非常不服气,于是找到惠子,给他出了一道题. 他首先给了惠子一个长度为 n的 ...

  3. 【16.56%】【codeforces 687B】Remainders Game

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. MySQL旧版本ORDER BY 方法

    MySQL 的order by 它涉及到三个参数:A. sort_buffer_size 排序缓存.B. read_rnd_buffer_size 第二次排序缓存.C. max_length_for_ ...

  5. 微软 2018 年第一笔收购:文件存储公司 Avere Systems

    微软 2018 年第一笔收购:文件存储公司 Avere Systems 2018 年 1 月 4 日, 9:47 上午 · Picturepan2 微软今天宣布收购文件存储公司 Avere Syste ...

  6. Python3.7环境配置

    1.官网下载 https://www.python.org/ 我这是3.7.0 for windows executable installer Download Windows x86 web-ba ...

  7. 打开一个很好的介绍Lucene4 FST文章

    我没有看到源代码.看到这个博客了解一些基本的,像笔者下: http://download.csdn.net/download/guanxinquan/7380591 http://blog.sina. ...

  8. /var/tmp/.oracle 和 oracle listener (监听)的一点理解

    关于 /var/tmp/.oracle 的作用測试 ~---查看 /var/tmp 的权限 [root@lixora var]# ll total 164 ... drwxrwxrwt  3 root ...

  9. 实用WordPress后台MySQL操作命令

    关键字: WordPress MySQL 后台 数据库 地址:http://www.cnblogs.com/txw1958/archive/2013/01/06/wordpress-sql.html ...

  10. silverlight,WPF动画终极攻略之会飞的小鸟篇(Blend 4开发)

    原文:silverlight,WPF动画终极攻略之会飞的小鸟篇(Blend 4开发) 本教程基本涵盖了WPF和silverlight中的各种动画.先上张效果图. 声明下,这个做的不是让大家照搬的,只是 ...