资源描述
Delphi编程资料精华汇总
标题: 父窗体fsmDIForm 子窗体fsMDIChild
内容:
设置父窗体Formstyle为fsmDIForm 子窗体为fsMDIChild
1. 如果你需要你的子窗体就是设计时的那个子窗体,
用Application.CreateForm(TFormChild,FormChild);创建该子窗体,则再使用FormChild.Close;时应该不会报错。
2. MDI子窗体的默认关闭操作为最小化,想让它真正关闭,在其OnClose中写Action:=caFree;
3. 如果你的子窗体只是用TFormChild类创建的实例(用TFormChild.Create(Application);或TFormChild.Create(self);创建的),则一般不能用FormChild来引用它(如它是全局变量等情况例外)。可以考虑以下几个方法:
//关闭最早建立的实例
MainForm.MDIChildren[MainForm.MDIChildCount-1].close;
//关闭最晚建立的实例
MainForm.MDIChildren[0].close;
//关闭当前活动实例
MainForm.ActiveChild.close;
//关闭所有子窗体
for i:=0 to MainForm.MDIChildCount-1 do
MainForm.MDIChildren[i].close;
Delphi MDI应用程序高级技巧三则(一)2008-07-28 07:47本文介绍几个Delphi MDI应用程序的编程技巧,虽然纯属技巧,但是本文的方法在正常编程时,通常会被编译器认为是错误的或是违背编程环境缺省许可值的。不过有时为了一些特殊的用途或特殊的视觉效果,按下述的方法一试,可以在明知不可违而违之的情况下,得到很好的结果。
下述各示例均在Delphi6、Windows2000下完成,对涉及的控件命名是任意的,仅为方便说明问题。
一、子窗口的隐藏
在Delphi编程环境下,MDI子窗口在运行期间可以动态地被创建和销毁,但是不能够被隐藏,如果试图通过Visible属性或Hide方法隐藏子窗口,编译器将报出“Cannot hide an MDI Child Form.”的错误提示!
如果某个子窗口中承载了很多要保留的数据而不能销毁,但又暂时不想要它出现在屏幕上时,最好的方法就是将其隐藏,待需要时再将其显示出来则可。下面两种方法可以隐藏和显示子窗口,并避开了编译器的报错提示。
1) 使用Windows API函数ShowWindow(),示例代码如下:
ShowWindow(ChildForm.Handle, SW_HIDE); // 隐藏子窗口
ShowWindow(ChildForm.Handle, SW_RESTORE); // 显示子窗口
说明:使用Windows API直接隐藏子窗口,其子窗口的Visible属性和其显示状态是不一至的。当子窗口不可见时,其Visible属性可能仍然是True。
2) 直接设置子窗口的Visible属性
此时,首先要在需要隐藏的子窗口中重载TCustomForm的VisibleChanging方法,并在其实现过程中屏蔽掉继承代码,否则编译器将在隐藏子窗口时报错。
然后就可以直接设置这个子窗口的Visible属性为False或True来隐藏或显示它了。示例如下:
a) 子窗口部分
…
type
TChildForm = class(TForm)
private
procedure VisibleChanging; override;//重载
…
end;
…
procedure TChildForm.VisibleChanging;
begin
{使用组件属性隐藏子窗口时,需要重载此过程,并且不执行任何继承代码,否则将报错}
//inherited; 不能执行此语句!
end;
b) 隐藏或显示子窗口
ChildForm.Visible:=false;//隐藏子窗口
ChildForm.Visible:=true; //显示子窗口
说明:直接使用组件属性隐藏或显示子窗口,子窗口的Visible属性和其显示状态是一至的。笔者认为这样做要安全一些。
子窗口分布控制2008-07-28 07:531.叠窗口.
Form1.Cascade;
2.横向平铺窗口
Form1.TileMode := tbHorizontal;
Form1.Tile;
3.纵向平铺窗口
Form1.TileMode := tbVertical;
Form1.Tile;
4.重排图标
Form1.ArrangeIcons;
我在每一個MDI的子視窗開啟的時候,都自動用水平方式排列,讓開啟的子視窗能平均排列在畫面中,但當其中一個子視窗關閉的時候,如何讓剩餘開啟的子視窗能重新排列一次?
1.Add a timer on the mainform,set enabled to false & interval to 100
2.add below codes on it's OnTimer event
procedure TMainForm.Timer1Timer(Sender: TObject);
begin
TTimer(Sender).Enabled := False;
MainForm.TileMode := tbHorizontal;
MainForm.Tile;
end;
3.add below codes on MDIChild's on close event
...
implementation
uses MAIN;
{$R *.dfm}
...
procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Mainform.Timer1.Enabled := True;
Action := caFree;
end;
Delphi : 隐藏MDI子窗口带来的问题2008-07-28 08:43在delphi中隐藏MDI子窗口有两种方法:
1)发消息及调用ShowWindow函数:
showwindow(childform.handle, sw_hide); // 隐藏子窗口
showwindow(childform.handle, sw_restore); // 显示子窗口
缺点:使用windows api直接隐藏子窗口,其子窗口的visible属性和其显示状态是不一至的。当子窗口不可见时,其visible属性可能仍然是true。
2)重载子窗口的visiblechanging方法:
private
procedure visiblechanging; override;//重载
procedure tchildform.visiblechanging;
begin
<使用组件属性隐藏子窗口时,需要重载此过程,并且不执行任何继承代码,否则将报错>
//inherited; 不能执行此语句!
end;
此后就可以直接设置visible属性了:
childform.visible:=false;//隐藏子窗口
childform.visible:=true; //显示子窗口
缺点:当子窗口隐藏了后,有些控件的数据没有办法取到,如 TListView, 为这个问题曾经郁闷了很久,不知道是什么原因。例如:子窗口上listview已经有了10行数据,当利用方法2)把使得子窗口不可见了后,调用childform.listview.items.count结果总是0,但是显示此子窗口后10行数据还是在此listview中。
所以使用1),在程序中不要调用visible属性。
使用2),在子窗口隐藏了后不要去取该子窗口的数据。
delphi怎么让限制MDI子窗口重复打开?2008-07-28 09:18delphi怎么让限制MDI子窗口重复打开?
delphi怎么让限制MDI子窗口重复打开?
begin
if Not assigned(form2) then
begin
Application.CreateForm(TForm2, Form2);
end
else
begin
form2.Show;
end;
end;
这个到是可以显示重复打开 但是我关闭改子窗体后 再打开就没出错拉
解决拉
在FORM2关闭的时候
先释放资源 在赋空值
action:=cafree;
form2:=nil;
Delphi中实现MDI子窗体
用MDI实现浏览子窗口,具有窗口管理功能,同屏观看多个网页的内容
① 多文档窗体(MDI)
MDI窗体是一种具有主子结构的窗体体系,微软的Word便是其中的一个典型例子。MDI体系中至少需要两种窗体,只能将其中之一设置为主窗体,其余窗体全部则全部为子窗体,主窗体负责子窗体的管理、切换等工作。自然,子窗体上承载的内容可各不相同。Tidy浏览器最终实现了三种不同的窗体:主窗体、浏览子窗体、源代码子窗体。
② 设置窗体类型
我们通过窗体的FormStyle属性设置窗体类型,它是一个枚举类型,可取的值包括:fsNormal, fsMDIChild, fsMDIForm, fsStayOnTop。分别对应:普通窗体, MDI子窗体,MDI主窗体, 普通顶部窗体。
值得注意的是,窗体的FormStyle属性应在设计期确定,运行期间更改是不可取的。
③ 子窗体的创建
一般而言,主窗体在应用程序启动时自动创建,子窗体通常在响应用户的有关动作之后才创建。并且,同一类子窗体实例可以多次被创建。为了避免程序启动时即创建子窗体,可通过C++Builder的集成环境IDE上的菜单Project\Options上的Form标签页,将所有子窗体从Auto-create forms窗口中,移至Available forms窗口。
④ 子窗体的关闭
MDI窗体技术中另一个值得注意的问题是,用户点击MDI子窗体的关闭按钮企图关闭子窗体,系统默认的动作却是将其最小化。为了真正的实现关闭子窗体并释放所占用的内存,可在OnClose事件中将引用参数Action设置为caFree。Action的其他可取值为:caNone,caHide,caMinimize,分别对应无动作、隐藏、最小化。
⑤ 主窗体的重要属性的使用
ActiveMDIChild属性,指向当前活动的子窗体。此乃TForm *类型的指针,必要时可强制转换为任意类型的子窗体实例。
MDIChildCount属性,用于判断已经创建的子窗体的总数。
MDIChildren属性,是一个TForm *类型的指针数组,指向目前存在的所有的子窗体。结合MDIChildCount属性,可以实现子窗体的遍历。
⑥ 子窗体之间的切换
直接引用主窗体的方法Previous()、Next(),可以实现子窗体的前、后切换。
⑦ 子窗体的布局
直接引用主窗体的方法Tile()、Cascade(),可以实现子窗体的平铺、层叠布局。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
delphi中判断子窗体是否打开 (2008-10-07 15:21:52)
标签:it 分类:DELPHI程序设计
今天在一个程序中,需要判断子窗体是否打开,写了这段代码共享出来
在一个MDI窗体中限制打开多个子窗体,采用遍历的方式判断子窗体是否已经存在:
procedure Tf_Main.btnUpdateClick(Sender: TObject);
var
i:Integer;
begin
for i :=0 to f_main.MDIChildCount -1 do //MDIChildCount:总的子窗体个数
if (f_main.MDIChildren[i] is Tf_Pass) then //判断子窗体是否存在
begin
self.MDIChildren[i].BringToFront; //把窗体放在最前面
MDIChildren[i].SetFocus; //窗体获得焦点
Exit; //退出函数体
end;
//创建新窗体
Application.CreateForm(Tf_Pass,f_Pass);
f_Pass.Show;
end;
允许单击关闭按钮时关闭子窗体:
procedure Tf_Pass.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
f_Pass := nil;
end;
讨论
Delphi(Pascal) code {只能打开一个mdi窗体} try if application.MainForm.MDIChildCount>0 then{判断主窗体里面的子窗体个数是否大于0} activemdichild.Close; finally TForm2.Create(Self);{这是子窗体,MDIChild窗体自己创建自己显示,不用Show} end;
建议你用一个主窗体成员变量或用全局变量来保存你每次打开的当前子窗体句柄(FormXXX.Handle), 当你要打开新的子窗体时,就先向你保存的上个子窗体句柄发WM_CLOSE消息来关闭它(用SendMessage), 最后记得把你新开打的子窗体句柄继续保存,以供下次使用.
procedure TFrmMain.Sys_AboutExecute(Sender: TObject);
var
i: integer;
begin
for i:=0 to application.MainForm.MDIChildCount-1 do
begin
application.MainForm.MDIChildren[i].Close;
end;
end;
Delphi中MDI窗体调用MDI子窗体
////先定义一个函数
private
function FindForm(caption: string): bool;
{ Private declarations }
public
{ Public declarations }
end;
var
MAIN: TMAIN;
implementation
{$R *.dfm}
//-----------通过用户定义的函数,判断窗体是否已存在--------------------
function Tmain.FindForm(caption: string): bool;
var
i:integer;
begin
//result:=false;//防止出现函数返回值没有定义的警告
result:=true;//防止出现函数返回值没有定义的警告
for i:=0 to main.MDIChildCount do
begin
// 通过对窗体标题判断窗体是否存在
if main.MDIChildren[i].Caption=caption then
begin
//如果窗体已存在,则恢复窗体,并返回true
SendMessage(mdichildren[i].Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
mdichildren[i].Enabled:=true;
mdichildren[i].Show;
mdichildren[i].SetFocus;
result:=true;
break;
end
else
//如窗体不存在,则返回false,程序将创建窗体
result:=false;
end
end;
////然后打开MDI子窗体,我合理是caozuorenyuan
//-------------打开操作人员设置窗体----------
procedure TMAIN.N2Click(Sender: TObject);
Var
newform:Tcaozuorenyuan;
begin
if FindForm('操作人员设置')=false then
begin
newform:=Tcaozuorenyuan.Create(application);
newform.Caption:='操作人员设置';
end;
end;
delphi子窗体重复打开问题解决方法
procedure? TfrmMainForm.OpenForm(FormClass: TFormClass; var fm; AOwner:TComponent);
var
i: integer;
Child:TForm;
begin
for i := 0 to Screen.FormCount -1 do
if Screen.Forms[i].ClassType=FormClass then
begin
Child:=TForm(Screen.Forms[i]);
if Child.WindowState=wsMinimized then
ShowWindow(Child.handle,SW_SHOWNORMAL)
else
ShowWindow(Child.handle,SW_SHOWNA);
if (not Child.Visible) then Child.Visible:=True;
Child.BringToFront;
Child.Setfocus;
TForm(fm):=Child;
exit;
end;
Child:=TForm(FormClass.NewInstance);
TForm(fm):=Child;
Child.Create(application);
end;
//OpenForm(FFormClassList[aindex],aForm,nil); //可不重复打开窗体
delphi 子窗体最大化
procedure TForm2.FormCreate(Sender: TObject);
begin
perform(WM_SIZE,SIZE_MAXIMIZED,0);
end;
delphi 抓取网页内容的程序
抓取网页内容,通常大家以为到网上偷数据,然后把到收集到的数据挂到自己网上去。其实也可以将采集到的数据做为公司的参考,或把收集的数据跟自己公司的业务做对比等。
目前网页采集多为3P代码为多(3P即ASP、PHP 、JSP)。用得最有代表的就动易科技公司BBS中新闻采集系统,和网上流传的新浪新闻采集系统等都是用ASP程序来使用,但速度从理论上来说不是很好。如果尝试用其它软件的多线程采集是不是更快?答案是肯定的。用DELPHI、VC、VB、JB都可以,PB似乎比较不好做。以下用DELPHI来解释采集网页数据。
一、 简单的新闻采集
新闻采集是最简单的,只要识别标题、副题、作者、出处、日期、新闻主体、分页就可以了。在采集之前肯定要取得网页的内容,所以在DELPHI里加入idHTTP控件(在indy Clients面板),然后用idHTTP1.GET 方法取得网页的内容,声明如下:
function Get(AURL: string): string; overload;
AURL参数,是string类型,指定一个URL地址字符串。函数返回也是string类型,返回网页的HTML源文件。比如我们可以这样调用:
tmpStr:= idHTTP1.Get(‘
调用成功后,tmpstr变量里存储的就是网易主页的代码了。
接下来,讲一下数据的截取,这里,我定义了这么一个函数:
function TForm1.GetStr(StrSource,StrBegin,StrEnd:string):string;
var
in_star,in_end:integer;
begin
in_star:=AnsiPos(strbegin,strsource)+length(strbegin);
in_end:=AnsiPos(strend,strsource);
result:=copy(strsource,in_sta,in_end-in_star);
end;
StrSource:string类型,表示HTML源文件。
StrBegin:string类型,表示截取开始的标记。
StrEnd:string,表示截取结束的标记。
函数返回字符串StrSource中从StrSource到StrBegin之间的一段文本。
比如:
strtmp:=TForm1.GetStr(‘A123BCD’,‘A’,‘BC’);
运行后,strtmp的值为:’123’。
关于函数里用到的AnsiPos和copy,都是系统定义的,可以从delphi的帮助文件里找到相关说明,我在这里也简单罗嗦一下:
function AnsiPos(const Substr, S: string): Integer
返回Substr在S中第一次出现的位置。
function copy(strsource,in_sta,in_end-in_star): string;
返回字符串strsource中,从in_sta(整型数据)开始到in_end-in_star(整型数据)结束的字符串。
有了以上函数,我们就可以通过设置各种标记,来截取想要的文章内容了。在程序中,比较麻烦的是我们需要设置许多标记,要定位某一项内容,必须设置它的开始和结束标志。比如要取得网页上的文章标题,必须事先查看网页代码,查看出文章标题前边和后边的一些特征代码,通过这些特征代码,来截取文章的标题。
下面我们来实际演示一下,假设要采集的文章地址为
代码为:
<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>新建网页 1</title>
</head>
<body>
<p align="center"><b>文章标题</b></p>
<table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" id="AutoNumber1">
<tr><td width="60%">作者</td>
<td width="40%">出处</td></tr>
</table>
<p><font size="2">这里是文章内容正文。</font></p>
<a href='..new_pr.asp'>上一页</a> <a href='new_ne.asp'>下一页</a>
</body>
</html>
第一步,我们用StrSource:= idHTTP1.Get(‘
然后定义strTitle、strAuthor、strCopyFrom、strContent:
strTitle:= GetStr(StrSource,’ <p align="center"><b>’,’ </b></p>’):
strAuthor:= GetStr(StrSource,’ <tr><td width="60%">’,’ </td>’):
strCopyFrom:= GetStr(StrSource,’ <td width="40%">’,’ </td></tr>’):
strContent:= GetStr(StrSource,’ <p><font size="2">,’ </font></p>’):
这样,就能把文章的标题、副题、作者、出处、日期、内容和分页分别存储在以上变量中。
第二步,用循环的办法,打开下一页,并取得内容,加到strContent变量中。
StrSource:= idHTTP1.Get(‘new_ne.asp’);
strContent:= strContent +GetStr(StrSource,’ <p><font size="2">,’ </font></p>’):
然后再判断有没有下一页,如果还有就接着取得下一页的内容。
这样就完成了一个简单的截取过程。从以上的程序代码可以看到,我们使用的截取办法都是找截取内容的头部和尾部的,如果遇到这个头部和尾部有多个怎么办?似乎没办法,只会找到第一个,所以在找之前应该验证一下是不是只有一处有这个截取的内容的前后部。
打开网页 DELPHI
uses ShellAPI;procedure TForm1.Button1Click(Sender: TObject);begin //用IE打开 ShellExecute(Handle, 'open', 'IExplore.EXE', 'about:blank', nil, SW_SHOWNORMAL); //用火狐打开 ShellExecute(Handle, 'open', 'firefox.exe', 'about:blank', nil, SW_SHOWNORMAL); //用默认浏览器打开 ShellExecute(Handle, 'open', 'Explorer.exe', 'about:blank', nil, SW_SHOWNORMAL);end;//另一种调用IE打开的方法uses ComObj;procedure TForm1.Button1Click(Sender: TObject); procedure OpenInIE(aURL: string); var IE: Variant; begin IE := CreateOleObject('InternetExplorer.Application'); IE.Visible := true; IE.Navigate(aURL); end;begin OpenInIE('');end;//第二种方法可以有更多控制procedure TForm1.Button1Click(Sender: TObject); procedure OpenInIE(aURL: string); //need uses ComObj; var IE: Variant; begin IE := CreateOleObject('InternetExplorer.Application'); IE.Visible := true; //可见 IE.left := 0; IE.top := 0; IE.height := 600; //高度 IE.width := 800; //宽度 IE.menubar := 0; //取消菜单栏 IE.addressbar := 0; //取消地址栏 IE.toolbar := 0; //取消工具栏 IE.statusbar := 0; //取消状态栏 //IE.resizable := 0; //不允许用户改变窗口大小 IE.Navigate(aURL); end;begin OpenInIE('
用户登录 代码
delphi 用户登录 代码
用到的ADO控件是 ADOConnection、ADOquery
procedure TForm1.Button1Click(Sender: TObject);
var
databasename:string;
ip:string;
begin
databasename:='jswlibs';//数据库
ip:='192.168.1.126';//数据库服务器
ADOConnection1.close;
ADOConnection1.ConnectionString:='Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog='+databasename+';Data Source='+ip;
ADOConnection1.Connected:=true;//打开链接
ADOquery1.Connection:= ADOConnection1;//动态链接
ADOquery1.Close;
ADOquery1.SQL.Clear;
ADOquery1.SQL.add('select * from sys_gzry where xm='''+edit1.text+''' and mm = '''+edit2.text+'''');//查询语句
ADOquery1.Active:=true;
ADOquery1.open;
if ADOquery1.RecordCount>0 then// 判断是否有记录
begin
label3.Caption:='登录成功!';
exit;
end;
label3.Caption:='登录错误!';
end;
本程序的数据库链接和操作都是动态的,控件要用的时候直接调用就可以啦。
delphi 显示数据
delphi 显示数据
标准动态 显示数据
procedure TForm1.Button2Click(Sender: TObject);
var
databasename:string;
ip:string;
begin
adoconnection1.Close;
databasename:=ComboBox2.Text;//数据库
ip:=ComboBox1.Text;//数据库服务器
ADOquery1.SQL.Text:=ComboBox3.Text;
ADOConnection1.ConnectionString:='Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog='+databasename+';Data Source='+ip;
adoquery1.Connection:= ADOConnection1;
ADOConnection1.Connected:=true;
ADOquery1.SQL.Text:=ComboBox3.Text;//获取查询语句
ADOquery1.Active:=true;
datasource2.DataSet:=ADOquery1;
dbgrid1.DataSource:=datasource2;
end;
本文来自CSDN博客,转载请标明出处:
delphi中多文档子窗体的创建方法是怎样呢
unit mainfrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ToolWin, Menus, ExtCtrls, RzPanel, ImgList, RzButton,
RzStatus, RzCommon, StdCtrls, jpeg, DB, ADODB,shellapi,
Buttons, RzLine, RzGroupBar,md5,inifiles, SkinCaption, WinSkinData;
type
TMAIN = class(TForm)
private
{ Private declarations }
public
function FindForm(caption: string): bool;
{ Public declarations }
end;
var
MAIN: TMAIN;
implementation
{$R *.dfm}
//-----------通过用户定义的函数,判断窗体是否已存在--------------------
function Tmain.FindForm(caption: stri
展开阅读全文