再次关于来自程序资源的动画(* .ani)游标(Delphi 2010)

时间:2011-04-01 22:20:54

标签: delphi

我创建了一个资源文件Cur.rc。它包含

CUR1   21   "MYCURSOR.ANI"

mycursor.ani是一个存在的文件。这是一个普通的.ani动画光标。

我使用

编译资源文件
Brcc32 cur.rc  

会生成文件cur.res

在我的项目的Unit1中(我也尝试了项目的.dpr文件),我添加了

{$R cur.res} 

在FormCreate事件中,

Screen.Cursors[8]:=LoadCursor(HInstance, 'CUR1');
Screen.Cursor := 8;
// p.s. 8 - for an example, can be 0.... n or a constant

我运行该应用程序。光标应该变为我的动画光标。

这应该很简单。我尝试了不同来源的几个不同的光标文件。但它不起作用。

如果您从文件加载它是有效的:

Screen.Cursors [8]:=LoadCursorFromFile('d:\1.ani'); 
Screen.Cursor:=8;

如何从资源加载动画光标?为什么它不像加载普通光标那样工作?


这不起作用。显然,没有办法从资源加载动画光标而不先进入文件。

但这有效:

// MyCursor.rc
BGCURSOR ANICURSOR "D:\TEMP\Background.ani"

// Unit1.pas
{$R MyCursor.res MyCursor.rc}

procedure TForm1.FormCreate(Sender: TObject);
var
  Res: TResourceStream;
  FileName: string;
  HC: HCURSOR;
const
  BGCursor = 8;  // Can be anything from 0..32767
begin
  Res := TResourceStream.Create(MainInstance, 'BGCURSOR', 'ANICURSOR');
  try
    FileName := ExtractFilePath(ParamStr(0)) + 'BGCursor.ani';
    Res.SaveToFile(FileName);
    HC := LoadCursorFromFile(PChar(FileName));
    Screen.Cursors[BGCursor] := HC;
    Screen.Cursor := BGCursor;
  finally
    DeleteFile(FileName);
    Res.Free;
  end;
end;

我在两个答案之后写它,因为评论不希望被应用。

P.S。在Delphi 2010上写过,但我想,就像在Delphi 7上一样。

基本问题:

仅适用于Panel1。 完整集中的初始代码,此处为文本,如果长到以下:

完整的例子试图做出:

1. 3 panels - at form start on everyone are appointed the cursor.
2. Works only on the first or at loading of the cursor from a file
3. All in the complete set (the small program, cursors, etc.) - exe (executed) - too there

完整集中的初始代码,此处为文本,如果长到以下:

interface

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

Const
  CurConst = 8; // 8 .. example, 8 is like me :)
  CurConst1 = 7;
  CurConst2 = 6;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Button1: TButton;
    Panel3: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  cur: HCursor;

implementation

{$R *.dfm}
{$R My.res}

procedure TForm1.Button1Click(Sender: TObject);
var 
  s: string;
begin
  s:=IncludeTrailingPathDelimiter(extractfilepath(paramstr(0)))+'sc1.ani';
  showmessage('Temp value: '+ s);
  Screen.Cursors[CurConst]:=LoadCursorFromFile(pchar(s));
  panel1.Cursor:=CurConst;
  panel2.Cursor:=CurConst;
  panel3.Cursor:=CurConst;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // panel 1
  Screen.Cursors[CurConst] := LoadCursor(HInstance,'V_0');
  panel1.Cursor:=CurConst;
  // panel 2
  Screen.Cursors[CurConst1] := LoadCursor(HInstance,'V_1');
  panel2.Cursor := CurConst1;
  // panel 2
  Screen.Cursors[CurConst2] := LoadCursor(HInstance,'V_2');
  panel3.Cursor := CurConst2;
end;

end.

DownLoad(完整项目代码):http://www.sendspace.com/file/jbzrpx(关闭弹出窗口,向下看);镜像:注意 - 没有必要支付任何费用(在慢速参考下下载(大小为4 mb))http://rapidshare.com/files/455515706/TestCursor.zip(没有病毒 - 测试赛门铁克 - 11.6.3000 SEP)一般来说,有一个初始代码完整的一套 - 会明白的。

4 个答案:

答案 0 :(得分:9)

显然api的资源加载器比文件加载器更挑剔,或者要求有点不同。

由于包含可执行文件,我能够让您的游标在您提供的完整项目代码下载中工作,甚至无需触及代码:

  • 在十六进制编辑器中打开'sc1.ani'。
  • 找到文件中的第二个双字(第一个是签名'RIFF')。双字是'62 0F 00 00',即3938,这是文件大小。将其修改为'5A 0F 00 00',即'3930',现在它表示长度标识符之后的剩余字节总数。保存ani文件。
  • 在“Resource Hacker”或兼容资源编辑器中打开可执行文件,并将“V_1”替换为修改后的文件。
  • 保存可执行文件并运行。


您可以使用Greenfish Icon Editor打开动画光标,然后再次保存。它似乎产生了兼容的文件。

答案 1 :(得分:1)

使用欺骗性命名的CreateIconFromResource API函数。

var
  res: TCustomMemoryStream;
  cur: HCursor;
begin
  res := TResourceStream.Create(MainInstance, 'BGCURSOR', 'ANICURSOR');
  try
    cur := CreateIconFromResource(res.Memory, res.Size, False, $30000);
    Win32Check(cur <> 0);
    Screen.Cursors[8] := cur;
  finally
    res.Free;
  end;
end;

答案 2 :(得分:1)

这对我在柏林很有用:

更具体一点:如果您在这里登陆是因为您正在寻找一种方法来加载动画光标而无需先将其保存到文件中,这对我有用。唯一的区别是,将数据移动到堆中并从那里加载它。

function GetResourceAsAniCursor(const ResName: string; Width, Height: Integer): HCursor;
var
  resInfo: HRSRC;
  resSize: cardinal;
  resHandle: HGLOBAL;
  resData, Data: pchar;
begin
  Result := 0;
  resInfo := FindResource(MainInstance, PWideChar(ResName), PWideChar('ANICURSOR'));
  resHandle := LoadResource(MainInstance, resInfo);
  if resHandle <> 0 then
  begin
    resSize := SizeofResource(MainInstance, resInfo);
    resData := LockResource(resHandle);
    Data := AllocMem(resSize);
    try
      Move(resData^, Data^, resSize);
      Result := CreateIconFromResourceEx(PByte(Data), resSize, False, $00030000, Width, Height, 0);
    finally
      FreeMem(Data);
    end;
  end;
end;

用法:

const 
 crMyAniCursor = 1;

 Screen.Cursors[crMyAniCursor] := GetResourceAsAniCursor('MYANICURSOR', 128, 128);

答案 3 :(得分:0)

这不起作用。显然,没有办法从资源加载动画光标而不先进入文件。

但这有效:

// MyCursor.rc
BGCURSOR ANICURSOR "D:\TEMP\Background.ani"

// Unit1.pas
{$R MyCursor.res MyCursor.rc}

procedure TForm1.FormCreate(Sender: TObject);
var
  Res: TResourceStream;
  FileName: string;
  HC: HCURSOR;
const
  BGCursor = 8;  // Can be anything from 0..32767
begin
  Res := TResourceStream.Create(MainInstance, 'BGCURSOR', 'ANICURSOR');
  try
    FileName := ExtractFilePath(ParamStr(0)) + 'BGCursor.ani';
    Res.SaveToFile(FileName);
    HC := LoadCursorFromFile(PChar(FileName));
    Screen.Cursors[BGCursor] := HC;
    Screen.Cursor := BGCursor;
  finally
    DeleteFile(FileName);
    Res.Free;
  end;
end;