我写了一个小程序,用来提取某一文件中的所有BITMAP资源,存成文件。但执行时没报错,也不成功,各位帮忙看看呀(50分)

阿魁

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls, Buttons, shlobj;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Label1: TLabel;<br>&nbsp; &nbsp; Edit1: TEdit;<br>&nbsp; &nbsp; SpeedButton1: TSpeedButton;<br>&nbsp; &nbsp; Label2: TLabel;<br>&nbsp; &nbsp; Label3: TLabel;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; Label4: TLabel;<br>&nbsp; &nbsp; Edit2: TEdit;<br>&nbsp; &nbsp; SpeedButton2: TSpeedButton;<br>&nbsp; &nbsp; OpenDialog1: TOpenDialog;<br>&nbsp; &nbsp; procedure SpeedButton1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure SpeedButton2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; bmpCount : integer;<br><br>&nbsp; //回调函数,我不知声明对不对,但不报错<br>&nbsp; function CallBack(h : Thandle; resType : pchar; resName : pchar; lParam : cardinal):boolean; stdcall;<br><br>implementation<br><br>{$R *.dfm}<br><br>function CallBack(h : Thandle; resType : pchar; resName : pchar; lParam : cardinal):boolean;<br>var<br>&nbsp; bmp : TBitmap;<br>&nbsp; fileName : string;<br>begin<br>&nbsp; bmp := TBitmap.Create;<br>&nbsp; try<br>&nbsp; &nbsp; bmp.Handle := LoadBitmap(h,resName);<br>&nbsp; &nbsp; fileName := resName;<br>&nbsp; &nbsp; fileName := form1.Edit2.Text + '/' + fileName + '.bmp';<br>&nbsp; &nbsp; bmp.SaveToFile(fileName);<br>&nbsp; finally<br>&nbsp; &nbsp; bmp.Free;<br>&nbsp; &nbsp; CallBack := false;<br>&nbsp; end;<br>&nbsp; bmpCount := bmpCount+1;<br>&nbsp; form1.Label3.Caption := intToStr(bmpCount);<br>&nbsp; CallBack := true;<br>end;<br><br>//打开资源文件<br>procedure TForm1.SpeedButton1Click(Sender: TObject);<br>begin<br>&nbsp; if openDialog1.Execute then<br>&nbsp; &nbsp; edit1.Text := openDialog1.FileName;<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp; close;<br>end;<br><br>//选择存放目录<br>procedure TForm1.SpeedButton2Click(Sender: TObject);<br>var<br>&nbsp; pid : PItemIDList;<br>&nbsp; bi : TBrowseInfo;<br>&nbsp; savepath : string;<br>begin<br>&nbsp; setLength(savepath,255);<br>&nbsp; FillChar(bi,sizeof(bi),0);<br>&nbsp; bi.hwndOwner := self.Handle;<br>&nbsp; bi.pidlRoot := nil;<br>&nbsp; bi.pszDisplayName := pchar(savepath);<br>&nbsp; bi.lpszTitle := '选择Bitmap文件存放路径:';<br>&nbsp; bi.ulFlags := BIF_RETURNONLYFSDIRS;<br>&nbsp; pid := SHBrowseForFolder(bi);<br>&nbsp; if pid&lt;&gt;nil then<br>&nbsp; begin<br>&nbsp; &nbsp; SHGetPathFromIDList(pid,pchar(savepath));<br>&nbsp; &nbsp; setLength(savepath,strlen(pchar(savepath)));<br>&nbsp; &nbsp; edit2.Text := savepath;<br>&nbsp; end;<br>end;<br><br>//提取BITMAP资源<br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; h : Thandle;<br>begin<br>&nbsp; if edit1.Text = '' then<br>&nbsp; begin<br>&nbsp; &nbsp; beep;<br>&nbsp; &nbsp; edit1.SetFocus;<br>&nbsp; &nbsp; exit;<br>&nbsp; end;<br>&nbsp; if edit2.Text = '' then<br>&nbsp; begin<br>&nbsp; &nbsp; beep;<br>&nbsp; &nbsp; edit2.SetFocus;<br>&nbsp; &nbsp; exit;<br>&nbsp; end;<br><br>&nbsp; h := LoadLibraryEx(pchar(edit1.Text),0,LOAD_LIBRARY_AS_DATAFILE);<br><br>&nbsp; if h=0 then<br>&nbsp; begin<br>&nbsp; &nbsp; showMessage('load file '+edit1.Text+' error!');<br>&nbsp; &nbsp; exit;<br>&nbsp; end;<br><br>&nbsp; //枚举资源<br>&nbsp; EnumResourceNames(h,RT_BITMAP,@CallBack,1);<br><br>&nbsp; //FreeLibrary(h);<br><br>&nbsp; //showMessage('done!');<br><br>end;<br><br>end.<br><br>==============<br>另外:EnumResourceNames是不是立即返回?如果是,我怎么知道列举完成了?
 
程序是对的<br>EnumResourceNames是对每一个指定的资源调用一次你的回调函数而已<br>所以不是立即返回<br>
 
可是我明知道我打开的文件里有BITMAP,为什么得不到不存后的文件呢?<br>我跟踪以下吧。
 
我这里一切都OK,保存了一大堆BMP。
 
真的?<br>把你的代码贴出来看看吧。<br><br>我这边CallBack根本就不被调用。[:(]
 
不用贴了, 除了把 &nbsp;FreeLibrary(H);的注释去掉以外,其他的未做任何改动。[:)]
 
奇怪了。<br>我用WIN2000,你呢?
 
保存的图片能正常查看吗?<br><br>我试过了,有的文件可以,是因为在生成资源是,起了名字。可是保存的文件根本看不了。<br>而想VC生成的资源,没有名字,只有ID(数字),根本不起作用。<br><br>有经验的同志帮忙呀。
 
我也是Win2kAS + Delphi6<br>我取的是Delphi6编译出来的EXE,一切正常。<br><br>是你说的那个原因<br>&nbsp; &nbsp; FileName := resName; 这句出错了<br>你只要换个FileName就行了,比如bmp001.bmp, bmp002.bmp....<br>搞定!
 
对了, 保存出来的图片是正常的。
 
不行了。<br>对没有名字只有数字ID的资源不起作用;对有名字,却被压缩了的文件(如用ASPACK压缩)也不起作用。<br><br>关键是:EnumResourceNames列举的是资源名字,而不是ID,问题就在这儿。<br><br>肯定有解决办法的,我到MSDN去查查。
 
&gt;是你说的那个原因<br>&gt; &nbsp; &nbsp;FileName := resName; 这句出错了<br>&gt;你只要换个FileName就行了,比如bmp001.bmp, bmp002.bmp....<br>&gt;搞定!<br><br>关键是,要用resName来取得资源啊,不然怎么去的资源?<br><br>哎???等等,我再去试试~~~ [?]
 
资源它已取回来了, 因为resName Points to a null-terminated string that <br>contains the name of the bitmap resource to be loaded. Alternatively, <br>this parameter can consist of the resource identifier in the low-order word <br>and zero in the high-order word. <br>所有用下面的代码就搞定了: 我用金山词霸的主执行文件试了一下,OK了。<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; FileName := resName;<br>&nbsp; &nbsp; except<br>&nbsp; &nbsp; &nbsp; FileName := IntToStr(Integer(resName));<br>&nbsp; &nbsp; end;<br>
 
搞定!<br><br>解释如下:<br>如果资源有名字,则参数resName指向以NULL结束的字符串;如果没有名字,则resName好像<br>是指向数字,这就是资源的ID。<br><br>我还是不太懂,但怎么处理我是明白了。<br>希望有经验的同志,给指点一下。
 
to xianjun:<br>好一番折腾,终于搞定了,非常感谢你的参与。 [:)]
 
顶部