论坛风格切换切换到宽版
  • 3689阅读
  • 8回复

请问 Inno 使用哪个函数创建保存文件对话框? [复制链接]

上一主题 下一主题
离线无尽天空
 
发帖
182
金钱
0
威望
0
只看楼主 倒序阅读 0 发表于: 2007-03-01
Inno 有 GetOpenFileName 打开文件,但是却找不到哪个函数是创建保存文件对话框,请各位大虾指教。
离线swlove
发帖
102
金钱
0
威望
0
只看该作者 1 发表于: 2007-03-01
楼主兄, 借贵宝地用下 ,懒得开贴了

下面代码 ,我想删除ListBox里从第一项以后的所有项 ,可实现的

是按一次按钮删除一项,怎样才能一次过删除 ? 用Clear是删除所

有的

QUOTE( MyProgram.iss @ 2007年3月1日 2:25:28 )
procedure RefreshButtonOnClick(Sender: TObject);
var
i:integer;
begin
for i:=1 to ListBox.Items.Count-1 do
  ListBox.Items.Delete(i);
end;

离线tracky

发帖
1807
金钱
10
威望
1
只看该作者 2 发表于: 2007-03-01
to 楼主:
显示保存文件对话框要调用 GetSaveFileName API。

to 楼上:
QUOTE
procedure RefreshButtonOnClick(Sender: TObject);
var
i: integer;
j: integer;
begin
j := ListBox.Items.Count - 1;
for i:= 1 to j do ListBox.Items.Delete(1);
end;

你把 ListBox.Items.Count 的值放在 for 循环里了,ListBox.Items.Delete(1) 语句每执行一次 ListBox.Items.Count 的值都在递减,所以不能完全删完,另外 ListBox.Items.Delete(i) 语句不能把循环基数值放进去的,TStrings 的索引从 0 开始,你固定为 1 则代表每次都删除第二行
╭∩╮(︶︿︶)╭∩╮
离线gnatix

发帖
7696
金钱
-8279
威望
-828
只看该作者 3 发表于: 2007-03-01
QUOTE(无尽天空 @ 2007年 03月 01日 00时 57分) [snapback]324377[/snapback]

Inno 有 GetOpenFileName 打开文件,但是却找不到哪个函数是创建保存文件对话框,请各位大虾指教。

INNO 本身没有提供相应的函数。tracky 说了要调用 API 来说实现。不过直接调用它还不是那么方便,所以我在编写 Easy UHARC 时为了方便调用,自己写了一个函数 GetMySaveFileName(),它的用法和 INNO 现有的 GetOpenFileName() 一样。供你参考:
QUOTE( getsavefilename.iss @ 2007年3月1日 8:25:38 )
[Code]
const
OFN_OVERWRITEPROMPT = $2;

type
TOpenFileName = record
 
lStructSize: Longint;
  hwndOwner: Longint;
  hInstance: Longint;
  lpstrFilter: PChar;
  lpstrCustomFilter: PChar;
  nMaxCustFilter: Longint;
  nFilterIndex: Longint;
  lpstrFile: PChar;
  nMaxFile: Longint;
  lpstrFileTitle: PChar;
  nMaxFileTitle: Longint;
  lpstrInitialDir: PChar;
  lpstrTitle: PChar;
  Flags: Longint;
  nFileOffset: Word;
  nFileExtension: Word;
  lpstrDefExt: PChar;
  lCustData: Longint;
  lpfnHook: Longint;
  lpTemplateName: PChar;
end;

function GetSaveFileName(var lpofn: TOpenFileName): boolean;
external 'GetSaveFileNameA@comdlg32.dll';

function GetMySaveFileName(sTitle: string; var SaveFN: string; sStartDir, sFilter, sDefExt: string): boolean;
var
F: TOpenFileName;
S, Title, StartDir, Filter, DefExt: string;
z: Char;
iVal: boolean;
begin
S := ' ';
SetLength(S, 512);

Title := sTitle;
StartDir := sStartDir;
Filter := sFilter;
DefExt := sDefExt;

z := Chr(0);

F.hwndOwner := StrToInt(ExpandConstant('{wizardhwnd}'));
F.lStructSize := 76;
F.Flags := OFN_OVERWRITEPROMPT;

F.lpstrTitle := PChar(Title);

if StartDir <> '' then
 
F.lpstrInitialDir := PChar(StartDir);

if Filter <> '' then
begin
 
StringChangeEx(Filter, '|', z, True);
  Filter := Filter + z + z;
  F.lpstrFilter := PChar(Filter);
end;

F.nFilterIndex := 1;

if DefExt <> '' then
 
F.lpstrDefExt := PChar(DefExt);

F.lpstrFile := PChar(S);
F.nMaxFile := Length(S);

iVal := GetSaveFileName(F);

if iVal then
 
SaveFN := F.lpstrFile
else
 
SaveFN := '';

Result := iVal;
end;

procedure InitializeWizard();
var
yourfilename: string;
begin
if
GetMySaveFileName('选择目标文件', yourfilename, ExpandConstant('{userdocs}'), '可执行程序文件 (*.exe)|*.exe|所有文件 (*.*)|*.*', 'exe') then
 
MsgBox('你将保存文件: ' + yourfilename, mbInformation, MB_OK);
end;



注意:如果你使用的不是最新的 INNO 版本,请将
  StringChangeEx(Filter, '|', z, True);
改成
  StringChange(Filter, '|', z);
离线新手入门
发帖
129
金钱
0
威望
0
只看该作者 4 发表于: 2007-03-01
保存文件时:
缺少诸如 \ ; * ?   > 非法文件名必要的判断.
离线无尽天空
发帖
182
金钱
0
威望
0
只看该作者 5 发表于: 2007-03-01
QUOTE
to 楼主:
显示保存文件对话框要调用 GetSaveFileName API。

原来真的要通过 API 来实现,那么就不够 Delphi 本身的 OpenDialog 跟 SaveDialog 来得方便。

不过也要谢谢 gnatix 兄的把调用方法简化了。
离线秋枫

发帖
241
金钱
180
威望
18
只看该作者 6 发表于: 2007-03-01
QUOTE(swlove @ 2007年 03月 01日 02时 29分) [snapback]324381[/snapback]

楼主兄, 借贵宝地用下 ,懒得开贴了

下面代码 ,我想删除ListBox里从第一项以后的所有项 ,可实现的

是按一次按钮删除一项,怎样才能一次过删除 ? 用Clear是删除所

有的

QUOTE( MyProgram.iss @ 2007年3月1日 2:25:28 )
<!--fonto:--><span style="font-family:"><!--/fonto-->procedure RefreshButtonOnClick(Sender: TObject);
var
i:integer;
begin
for i:=1 to ListBox.Items.Count-1 do
  ListBox.Items.Delete(i);
end;
[/font]



Downto,另第一个Item是0序号的。


QUOTE(tracky @ 2007年 03月 01日 04时 58分) [snapback]324386[/snapback]

to 楼主:
显示保存文件对话框要调用 GetSaveFileName API。

to 楼上:
QUOTE
<!--fonto:--><span style="font-family:"><!--/fonto-->procedure RefreshButtonOnClick(Sender: TObject);
var
i: integer;
j: integer;
begin
j := ListBox.Items.Count - 1;
for i:= 1 to j do ListBox.Items.Delete(1);
end;
[/font]

你把 ListBox.Items.Count 的值放在 for 循环里了,ListBox.Items.Delete(1) 语句每执行一次 ListBox.Items.Count 的值都在递减,所以不能完全删完,另外 ListBox.Items.Delete(i) 语句不能把循环基数值放进去的,TStrings 的索引从 0 开始,你固定为 1 则代表每次都删除第二行


Tracky这个说法还是有问题的。最好的方法是用Downto。另,我认为Count这个值不会每次循环都计算。即使用j来固定值,第一次删掉[0],那么原来的[1]就变成了[0],而这时i=1,也就是说,第二次删[1]的时候,原来由[1]变成[0]的那个条目是删除不掉di
QUOTE( 无标题 @ 2007-3-1 下午 07:34:03 )
[code]
procedure RefreshButtonOnClick(Sender: TObject);
var
i:integer;
begin
for
i:=ListBox.Items.Count-1 downto 0 do
ListBox.Items.Delete(i);
end;
离线tracky

发帖
1807
金钱
10
威望
1
只看该作者 7 发表于: 2007-03-02
QUOTE

Tracky这个说法还是有问题的。最好的方法是用Downto。另,我认为Count这个值不会每次循环都计算。即使用j来固定值,第一次删掉[0],那么原来的[1]就变成了[0],而这时i=1,也就是说,第二次删[1]的时候,原来由[1]变成[0]的那个条目是删除不掉di


如果你把 Count 放在 for 循环的目标值位置,这个 Count 值是会每次都变化的,另外我那个代码没有问题的,你可以调试一下,ListBox.Items.Delete(1) 是指删除 ListBox 的第二行值,循环次数为 ListBox.Items.Count - 1,这样经过一个循环就可以删掉 ListBox 除第一行外所有的数据。
╭∩╮(︶︿︶)╭∩╮
离线秋枫

发帖
241
金钱
180
威望
18
只看该作者 8 发表于: 2007-03-02
嗯。看错了。