• 一个最简单的Delphi2010的PNG异形窗口方法


    同事演示了一个.NET的的PNG异形窗口.挺漂亮.于是也想用Delphi显摆一个.

    关于Delphi用PNG做异形窗口的资料有不少.都是用GDIPlus或者TPNGImage组件加载PNG图像做的.但是我很懒,不想引用的GDIPlus,也不想去找PNGImage下载.

    好在从Delphi2009开始Delphi中就收购了PNGImage,并集成到后继的版本中.Delphi2010又包装了微软的IWICImagingFactory接口,这样处理PNG的工作就交给操作系统去做了.

    函数很简单一共就几行,关键就是UpdateLayeredWindow.

    发现CodeGear真让我上火.他们收工了PNGImage以后搞的东西居然改出了问题.透明盒渐变都有问题.做异形窗口该渐变部分居然是透明的.该透明的部分居然是不透明的.看了一下被收购前的PNGImage一点问题都没有.CodeGear真实的.

    只好用Delphi2010提供的IWICImagingFactory接口的包装了,这次PNG的处理交给微软的操作系统了,一点问题也没有.其他版本的Delphi只要能对IWICImagingFactory进行包装,也一样能处理.但还是Delphi2010最方便.什么控件也不用,多余的东西都不要.

     

    代码如下,很简单吧:)

    {*******************************************************}
    {                                                       }
    {       异形窗口                                        }
    {                                                       }
    {       2009.12.4 王  锐                                }
    {                                                       }
    {*******************************************************}


    unit UnitYXForm;

    interface
    uses
      Windows, Forms, Classes, Graphics;

    //从文件加载PNG
    procedure YXForm_FromFile(AForm : TForm; AFileName : String);
    //从资源加载PNG
    procedure YXForm_FromResource(AForm : TForm; ResName : String; ResType : PWideChar; Instance : HINST = 0);
    //从图像对象加载
    procedure YXForm_FromGraphic(AForm : TForm; AGraphic : TGraphic);

    implementation

    procedure YXForm_FromFile(AForm : TForm; AFileName : String);
    var
      wic : TWICImage;
    begin
      wic := TWICImage.Create;
      wic.LoadFromFile(AFileName);
      YXForm_FromGraphic(AForm, wic);
      wic.Free;
    end;

    procedure YXForm_FromResource(AForm : TForm; ResName : String;ResType : PWideChar; Instance : HINST);
    var
      wic : TWICImage;
      r : TResourceStream;
    begin
      if Instance = 0 then
        Instance := HInstance;
      r := TResourceStream.Create(Instance, ResName, ResType);
      wic := TWICImage.Create;
      wic.LoadFromStream(r);

      YXForm_FromGraphic(AForm, wic);
      wic.Free;
      r.Free;
    end;

    procedure YXForm_FromGraphic(AForm : TForm; AGraphic : TGraphic);
    var
      ptDst, ptSrc: TPoint;
      Size: TSize;
      BlendFunction: TBlendFunction;
      bmp : TBitmap;
    begin
      bmp := TBitmap.Create;
      bmp.Assign(AGraphic);
      ptDst := Point(AForm.Left, AForm.Top);
      ptSrc := Point(0, 0);
      Size.cx := AGraphic.Width;
      Size.cy := AGraphic.Height;

      BlendFunction.BlendOp := AC_SRC_OVER;
      BlendFunction.BlendFlags := 0;
      BlendFunction.SourceConstantAlpha := $FF; // 透明度
      BlendFunction.AlphaFormat := AC_SRC_ALPHA;

      SetWindowLong(AForm.Handle, GWL_EXSTYLE, GetWindowLong(AForm.Handle,
          GWL_EXSTYLE) or WS_EX_LAYERED);
      UpdateLayeredWindow(AForm.Handle,
         AForm.Canvas.Handle,
         @ptDst,
         @Size,
         bmp.Canvas.Handle,
         @ptSrc,
         0,
         @BlendFunction,
         ULW_ALPHA);
      bmp.Free();
    end;

    end.

     

    想要用的时候很简单,举个例子:

      ff := TForm2.Create(Self);
      YXForm_FromFile(ff, 'c:/a.png');

      ff.Show;

    实现动画也很容易.只要不停地YXForm_FromFile(ff, 'c:/a.png');调用一套动作PNG就可以了.

    效果如下:

     

  • 相关阅读:
    Android ListView带CheckBox实现单选
    android 登录和设置IP/端口功能
    html5 10大html5前端框架
    Html5 8个强大的基于Bootstrap的CSS框架
    Android 探究 LayoutInflater setFactory
    Android onLoadFinished与onLoaderReset
    Android android.database.CursorIndexOutOfBoundsException:Index -1 requested, with a size of 1
    Android 中AIDL的使用与理解
    Android Studio查看android源码
    ArrayList和LinkedList的用法区别:
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3295871.html
Copyright © 2020-2023  润新知