温柔一刀,请进来聊聊(200分)

  • 主题发起人 主题发起人 Zephyr
  • 开始时间 开始时间
Z

Zephyr

Unregistered / Unconfirmed
GUEST, unregistred user!
>>-----------------------------------------------------------------------------
>>Sigh!由于你一开始没有把问题说清楚,
>>我失去了一次得分机会,也许你失去了一次获得解答的机会 :-)
>>
>>btw:GGCAT的方法真的可行?
>>-----------------------------------------------------------------------------
>>该问题的URL是:http://www.delphibbs.com/delphibbs/dispq.asp?LID=339677

我想你知道我想和你聊什么了吧:-)

其实GGCAT的方法并不能完全解决我的问题,我在用GGCAT的方法试过之后,决定不用
Toolbar和ImageList了,改用SpeedButton来做工具条,因为它的Glyph是TBitamp,比
较好操作。

我实际上还是比较倾向于使用Toolbar和ImageList,如果你有办法解决的话,我再次
给你(也包括其他人)一次得分机会,也再给我自己一次获得解答的机会。

btw: 我对前面回答过此问题的各位朋友并无任何不敬之意。我对GGCAT等人的解答表
示感谢,但我想知道是否有更好的解决方法。
 
程序退出保存位图

var
i: Integer;
Bmp: TBitmap;
Path: String;
begin
Bmp := TBitmap.Create;
Path := ExtractFilePath(Application.ExeName);
try
Bmp.Width := ImageList1.Width;
Bmp.Height := ImageList1.Height;
Bmp.PixelFormat := pf24Bit;
for i := 0 to ImageList1.Count - 1 do begin
ImageList1.GetBitmap(i, Bmp);
Bmp.SaveToFile(Format('%s%d.bmp', [Path, i]));
end;
finally
Bmp.Free;
end;
end;

程序启动载入位图
var
i: Integer;
FileName, Path: String;
Bmp: TBitmap;
begin
i := 0;
Path := ExtractFilePath(Application.ExeName);
Bmp := TBitmap.Create;
try
repeat
FileName := Format('%s%d.bmp', [Path, i]);
if FileExists(FileName) then begin
Bmp.LoadFromFile(FileName);
ImageList1.AddMasked(Bmp, clWhite);
end else Break;
Inc(i);
until False;
finally
Bmp.Free;
end;
end;

不知道合不合你意?
 
最简单的方法:
写入
Var FS:TFileStream;
begin
FS:=TfileStream.Create(AfileName,fmopenWrite or fmCreate);
FS.WriteComponentRes('Image',ImageList1);
FS.Free;

读出
FS:=TfileStream.Create(AfileName,fmOpenRead);
FS.ReadComponentRes(ImageList1);
FS.Free;
 
ImageList_Read和ImageList_Write
是两个WinAPI,用他们直接就可以对ImageList
进行文件存取,什么转换也不用,而你是针对
转换成BMP再存取遇到的困难提出问题,
因此我也就“失去”了从根本上给你来一刀的机会 :-)
以后提问题从“根儿”上来吧!

ps: 这两个API调用比较复杂,可以看VCL源代码,
照猫画虎,去掉不必要的部分,就可以解决了。
 
温兄果然是高手高手高高手。
我对温兄的敬仰有如滔滔江水,连绵不绝(以下略去1.2MByte);

这两个API 使用十分简单,又安全可靠;
在下就替温兄费费口舌,顺便蹭点分,意下如何。

uses ..... ,CommCtrl;
Var FS:TFileStream;
SP:TStreamAdapter;
Begin
写:
FS:=TFileSteam.Create(AFileName,fmOpenWrite or fmCreate);
SP:=TStreamAdapter.Create(FS);
ImageList_Write(ImageList1.Handle,SP);
SP.Free; FS.Free;

读:
FS:=TFileSteam.Create(AFileName,fmOpenRead);
SP:=TStreamAdapter.Create(FS);
ImageList1.Handle:=ImageList_Read(SP);
SP.Free; FS.Free;

 
to GGCAT:
想说什么就直接说嘛!虽然这次不说我也知道你想 :-)
-- 恭维我的时候还不忘抬高自己,手法不错嘛!呵呵

不过如果象你说的这么简单,delphiVCL中的那么多代码岂不是白费力气?
其中各种处理都是为什么,我也不能一一说清楚,也不知道是否都必要。
但是起码要Free掉原来的ImageList的handle,这一点应该是可以看到的吧!
而free过程中似乎又有一点小问题,所以我才说...

其他的地方你写的基本没问题。
 
汗,汗,汗

寒冷的冬天,却有汗从我额头一滴一滴落到键盘.......
 
唉,想不到因自己的错让两位大侠如此辛苦,真是多谢了。

其实我一开始就查过了VCL代码,也查过了ImageList_Read和ImageList_Write,只是
那时看得一头雾水,觉得它用起来有点麻烦,所以就没有深入下去。

实际上到现在我也没讲清楚最终我要实现什么功能(看来我的表达能力实在够呛)。我以
为只要解决ImageList的存取问题即可达到目的,结果还是不行。

我想要实现的功能是:在程序中用户可以自行定义工具条及菜单,包括它们的图标、热键、
标题(Caption)和所执行的命令。由于工具条图标使用ImageList提供,当用户更改或添
加新的工具条按钮图标时我必须保存那些图标(实际上就是那种16X16的按钮位图),这样
在用户从硬盘上删除或移动那些图标后程序仍可使用。但ImageList未提供合适的方法在程
序运行中添加或更改位图(我试过了,都有一些问题出现),所以我提了最初的那个问题。
现在我用TSpeedButton和TPanel来做工具条,由于TSpeedButton的Glyph属性为Bitmap,这
样我就可以在程序运行时任意更改它,任意以自己的方式保存那些按钮位图。目前我正在
试验这种方法,我想应该可行。

对于两位大侠所提供的方法,我会再试试,看是否可以更好的解决问题。

再次向两位表示我的歉意和谢意。

btw:如果两位还有什么高招的话,请继续,我很乐意听听看。
当然了,此问题的200分会归两位所有。
 
多人接受答案了。
 
你的问题从技术问题变成了非技术问题,因此也就不好回答了。
不过看你的意思,如果你继续用Imagelist的话,我说的方法应该可以解决了。
如果你用bitmap,应该也很好解决,就象你上面说的那样。

因此我也就没再继续讨论了。
 
后退
顶部