<p class="content" style="MARGIN: 4px 2px 0px">一、Delphi中生成控件的两种方法<br />---- 1、 Form(表单)设计中生成控件 <br />---- 在进行Form设计时,直接在控件工具箱选择所需控件,再设置其属性与响应事件,这种方法比较常见。 <br />---- 2、 程序中动态生成控件 <br />---- 有时候,我们需要在程序运行时动态生成控件,这样做有两大优点:一是可以增加程序的灵活性;二是如果生成控件的多少与程序中间运行结果相关,显然方法一是无法的实现的,必须用程序中动态生成方法。 <br />---- 程序中动态生成控件的方法分为三步,首先,定义生成的控件类型,再用Create函数生成控件,最后对控件的相关属性赋值。以TButton控件为例,步骤如下: <br />---- (1) 定义控件类型 <br /> var<br /> Button1:TButton;<br />---- (2) 生成控件 <br /> Button1:=TButton. Create(self);<br /> Button1.Parent:=Self; <br /> //一般将其父控件设置为Self,如果不设置Parent的值,则控件不会在屏幕显示出来<br />---- (3) 设置其它属性及定义相关事件响应函数,如Caption, Left, Top, Height, Width, Visible, Enabled, Hint和onClick事件响应函数等。 <br /><br />二、动态生成控件方法的应用<br />---- 在开发生产调度与管理系统中,需要动态生成排产计划图,以甘特图表示,应用Shape控件来显示零件的加工状况(每道工序的加工开始时间与结束时间)是非常适合的。应用Chart控件,对加工设备利用率以三维直方图显示,非常直观。现分别将在程序中动态生成Shape控件和Chart控件的过程加以说明。 <br />---- 1、动态生成Shape控件显示排产计划图(甘特图) <br /> procedure TCreateMultiCharts.ProcCreateCharts;<br /> var<br /> i,j,Rows,Columns,RowSpace,ChartsHeight:Integer; <br /> ShapeChart:array of array of TShape;<br /> begin<br /> Rows:=16; //Shape控件数组行数<br /> Columns:=8; // Shape控件数组列数<br /> RowSpace:=20; // Shape控件行间距<br /> ChartsHeight:=20; // Shape控件高度<br /> SetLength(ShapeChart,Rows,Columns); <br /> //设置ShapeChart数组大小<br /> for i:=0 to Rows do<br /> for j:=0 to Columns do<br /> begin<br /> ShapeChart[i][j]:=TShape.Create(self);<br /> with ShapeChart[i,j] do<br /> begin<br /> Parent:=Self; //此行必不可少,否则Shape控件在屏幕显示不出<br /> Shape:=stRectangle; // Shape控件形状为矩形<br /> Top:=45+i*(RowSpace+ChartsHeight);<br /> Left:=Round(180+Q[i,j].StartTime); //因Q[i,j].StartTime为实数,故需进行四舍五入取整<br /> Width:=Round(Q[i,j].Value)<br /> Height:=ChartsHeight; <br /> Brush.Color:=RandomColor; //自定义函数,说明附后<br /> Brush.Style:=bsSolid; //设置填充方式<br /> Enabled:=True;<br /> end;<br /> end;<br />end;<br /> <br />---- 注: <br />---- (1)Q为一记录型二维数组,定义如下: <br /> type<br /> TempData=Record<br /> Value:Real;<br /> StartTime:Real;<br /> end;<br /> Q:array of array of TempData<br />---- 并且在另一过程已对Q的分量进行赋值。 <br />---- (2)为了区分不同的零件,Shape以不同颜色显示,此时,调用了函数RandomColor。该函数为: <br /> function TCreateMultiCharts.RandomColor;<br /> var<br /> red,green,blue:byte;<br /> begin<br /> red:=random(255);<br /> green:=random(255);<br /> blue:=random(255);<br /> result:=red or (green shl 8) or (blue shl 16);<br /> end;<br />---- 2、动态生成Charts控件的ChartSeries组件,显示设备利用率 <br /> procedure TFormMultiMachinesBurthen.<br /> ShowMachineBurthenCharts;<br /> var<br /> i:Integer;<br /> Burthen:Real;<br /> SeriesClass:TChartSeriesClass; <br /> NewSeries:array of TChartSeries;<br /> begin <br /> SetLength(NewSeries,CreateMultiCharts.Rows);<br /> MachinesBurthenCharts.height:=200;<br /> MachinesBurthenCharts.Width:=550;<br /> for i:=0 to CreateMultiCharts.Rows do<br /> begin<br /> SeriesClass:=TBarSeries; //设置形状为三维条形图<br /> NewSeries[i]:=SeriesClass.Create(Self);<br /> NewSeries[i].ParentChart:=MachinesBurthenCharts;<br /> NewSeries[i].Clear;<br /> Burthen:=MachineBurthen[i];<br /> Burthen:=Round(Burthen*100)/100; //只取小数点后两位数字<br /> NewSeries[i].add(Burthen,'',NewSeries[i].SeriesColor);<br /> end;<br /> end;<br /> <br />---- 注: <br />---- (1) MachineBurthen[i]为一实型数组,其值为对应设备的利用率,已在另一函数中计算得到; <br />---- (2) MachinesBurthenCharts为TChart控件,在type段说明。 </p><p><br /> </p><div style="BORDER-BOTTOM: #8ca6de 1px solid" align="right">2004-4-6 10:59:32 </div><div class="inputcaption" style="BORDER-BOTTOM: #8ca6de 1px solid"><table cellspacing="0" cellpadding="3" width="100%" border="0"> <tbody> <tr> <td> </td> <td align="right"><a href="http://www.delphibbs.com/keylife/iblog_comment.asp?xid=6917">查看评语»»»</a> </td> </tr> </tbody></table></div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:29:16 </span> <span style="HEIGHT: 20px">动态创建菜单全接触</span> </p><p class="content" style="MARGIN: 4px 2px 0px">[基本认识]:<br /> 在Delphi的程序开发环境中,封装的VCL减化了我们许多的开发工作,由在界面的设计上使开发的进度很快,但在很多的时候,我们需要自己来设计可视化的用户界面,而且是在程序的运行中,这时我们就得利用Delphi给我们提供的类来完成我们需要的工作了,下面笔者就和朋友们浅入的讨论一下动态创建"菜单"的基本知识,希望本文给那些刚入门的朋友来个抛砖引玉的作用。 <br /> 在delphi的菜单设计中,有两个Delphi的菜单控件:<br /> 1:Tmainmenu;<br /> 2:Tpopupmenu;<br /> 前者是创建窗口的菜单,后者是创建右键弹出式菜单的控件,但在Delphi庞大的类库中有一个类与这两个控件密切相关,它就是:TMenuItem,窗口的菜单和右键弹出式菜单的每个条目都是TMenuItem类的一个对象。此TMenuItem类不出现在控件板上,在程序中用代码可创建其实例。 <br /><br />[基本知识]:<br /> 在tmainmenu,tpopupmenu控件中有一个属性是items,此属性是数组型,里面的参数为菜单项的索引值。<br />文件 编辑 查看 插入 格式 帮助<br />---- ---- ---- ---- ---- ----<br />新建 撤消 标尺 对象 字体 关于<br />打开 拷贝 源码 公式 颜色 <br /> 相信您看过上面的菜单简单表示之后是非常熟悉的,在此菜单中菜单头的索引值代表如下:<br /> "文件"的菜单的items值为0;<br /> "编辑"的菜单的items值为1;以此类推。<br /> items属性是tmenuitem类型,而在此类型中还有一个属性,是items,如果您略懂"类"的关系,您就不难明白此类似"嵌套"的关系。"新建"菜单选项是"文件"菜单选项的子类,用代码表示为tmainmenu.items[0].items[0],"打开"菜单选项为tmainmenu.items[0].items[1],以此类推,而代表"编辑"菜单中的"拷贝"菜单选项的代码为tmainmenu.items[1].items[1],其它菜单代码表示以此类推。 <br /><br />[基本实例]:<br /> 知道了菜单的items结构之后,我们就可以进一步大胆的创建自己有序的菜单了。<br /> 上面讨论到窗口的菜单和右键弹出式菜单的每个条目都是TMenuItem类的一个对象。那么我们就可以create它的一个实例,来添加自己想要的菜单了。<br /><br />[示例过程]:<br />1:新建一个工程。<br />2:添加一个tmainmenu控件。<br />3:添加一个button控件,并在button的onclick事件中写入如下代码:<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> files,edit:tmenuitem;{要有实例的声明}<br />begin<br /> files:=tmenuitem.Create(self);<br /> edit:=tmenuitem.create(self);<br /> files.Caption:='文件';<br /> edit.caption:='编辑';<br /> mainmenu1.AutoHotkeys:=mamanual;{此句代码为不让系统自动设置快捷键}<br /> form1.MainMenu1.Items.Add(files);<br /> form1.mainmenu1.items.add(edit);<br />end; <br /> 运行后,出现如上面例举的菜单的部分结构,如此看来动态创建菜单项的方法是非常简单的,这无疑于Delphi把系统的函数进行了封装。菜单头我们创建完了,接下来就该创建菜单里的菜单项了,由"items属性是tmenuitem类型,而在此类型中还有一个属性,是items"此句话的意思我们可以创建菜单项,代码如下: <br />1:新建一个工程。<br />2:添加一个tmainmenu控件。 <br />3:添加一个button控件,并在button的onclick事件中写入如下代码:<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> files,edit:tmenuitem;<br /> new,copy:tmenuitem;<br />begin<br /> files:=tmenuitem.Create(self);<br /> edit:=tmenuitem.create(self);<br /> files.Caption:='文件';<br /> edit.caption:='编辑';<br /> mainmenu1.AutoHotkeys:=mamanual;{此句代码为不让系统自动设置快捷键}<br /> form1.MainMenu1.Items.Add(files);<br /> form1.mainmenu1.items.add(edit);<br /> {上部代码为创建菜单头}<br /> new:=tmenuitem.create(self);<br /> copy:=tmenuitem.create(self);<br /> new.Caption:='新建';<br /> copy.caption:='拷贝';<br /> files.Add(new);<br /> edit.add(copy);<br /> {上部代码为创建菜单项}<br />end; <br /> 运行效果和上面菜单结构表中基本一样,但此时点击菜单项时不出现任何的事件,显然这样的软件出售量不算理想,我们可以略改代码加个事件上去。<br />代码如下:<br />1:新建一个工程。<br />2:添加一个tmainmenu控件。<br />3:<br />private<br /> procedure abc(sender:tobject);<br /> { Private declarations }<br />var<br /> Form1: TForm1;<br /><br />implementation<br /><br />{$R *.DFM}<br /><br />procedure tform1.abc(sender:tobject);<br />begin<br /> showmessage('welcome you click me!! :) xixi');<br />end;<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> files,edit:tmenuitem;<br /> new,copy:tmenuitem;<br />begin<br /> files:=tmenuitem.Create(self);<br /> edit:=tmenuitem.create(self);<br /> files.Caption:='文件';<br /> edit.caption:='编辑';<br /> mainmenu1.AutoHotkeys:=mamanual;{此句代码为不让系统自动设置快捷键}<br /> form1.MainMenu1.Items.Add(files);<br /> form1.mainmenu1.items.add(edit);<br /> {上部代码为创建菜单头}<br /> new:=tmenuitem.create(self);<br /> copy:=tmenuitem.create(self);<br /> new.Caption:='新建';<br /> copy.caption:='拷贝';<br /> copy.onClick:=abc;<br /> new.onClick:=abc;<br /> files.Add(new);<br /> edit.add(copy);<br /> {上部代码为创建菜单项}<br />end;<br /> 这时这个软件就有了交互的功能。<br /> 有时菜单项中出现一个横的条线和出现一个子的菜单,那么这样的效果怎么用代码实现的呢,下面就是此效果的代码示例:<br />1:新建一个工程。<br />2:添加一个tmainmenu控件。<br />3:<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> files,edit:tmenuitem;<br /> new,copy:tmenuitem;<br /> sub1,sub2,sub3,lines:tmenuitem;<br />begin<br /> files:=tmenuitem.Create(self);<br /> edit:=tmenuitem.create(self);<br /> files.Caption:='文件';<br /> edit.caption:='编辑';<br /> mainmenu1.AutoHotkeys:=mamanual;{此句代码为不让系统自动设置快捷键}<br /> form1.MainMenu1.Items.Add(files);<br /> form1.mainmenu1.items.add(edit);<br /> {上部代码为创建菜单头}<br /> new:=tmenuitem.create(self);<br /> copy:=tmenuitem.create(self);<br /> new.Caption:='新建';<br /> copy.caption:='拷贝';<br /> files.Add(new);<br /> edit.add(copy);<br /> {上部代码为创建菜单项}<br /> sub1:=tmenuitem.create(self);<br /> sub2:=tmenuitem.create(self);<br /> sub3:=tmenuitem.create(self);<br /> lines:=tmenuitem.create(self);<br /> lines.caption:='-';<br /> sub1.caption:='子菜单1';<br /> sub2.caption:='子菜单2';<br /> sub3.caption:='子菜单3';<br /> new.Add(sub1);<br /> new.add(lines);<br /> new.add(sub3);<br /> copy.Add(sub2);<br /> {上面代码出现多项子菜单和横线的效果}<br />end;<br /><br /> 到此讨论的内容就要结束,菜单的创建在Delphi中是非常简单的事,在tmenuitem类中还有许多的事件和方法及属性,如Add, Clear, Click, Create, Delete, Destroy, Find, IndexOf, Insert, Remove等方法的使用都是非常简单的. </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:30:34 </span> <span style="HEIGHT: 20px">TPagecontrol TTablesheet 动态创建</span> </p><p class="content" style="MARGIN: 4px 2px 0px">动态创建TPagecontrol, TTablesheet <br />var<br /> T : TTabSheet;<br /> P : TPageControl;<br />begin<br /> // Create the PageControl<br /> // need to reference the page control so we need a reference to it.<br /><br /> P := TPageControl.Create(application);<br /> with P do begin<br /> Parent := Form1; // set how controls it.<br /> Top := 30;<br /> Left := 30;<br /> Width := 200;<br /> Height := 150;<br /> end; // with TPageControl<br /><br /> // Create 3 pages<br /> T := TTabSheet.Create(P);<br /> with T do begin<br /> Visible := True; // This is necessary or form does not repaint <br /> // correctly<br /> Caption := 'Page 1';<br /> PageControl := P; // Assign Tab to Page Control<br /> end; // with<br /><br /> T := TTabSheet.Create(P);<br /> with T do begin<br /> Visible := True; // This is necessary or form does not repaint <br /> // correctly<br /> Caption := 'Page 2';<br /> PageControl := P; // Assign Tab to Page Control<br /> end; // with<br /><br /> T := TTabSheet.Create(P);<br /> with T do begin<br /> Visible := True; // This is necessary or form does not repaint <br /> // correctly<br /> Caption := 'Page 3';<br /> PageControl := P; // Assign Tab to Page Control<br /><br /> end; // with<br /><br /> // Create 3 buttons, 1 per page<br /> with tbutton.create(application) do begin<br /> Parent := P.Pages[0]; // Tell which page owns the Button<br /> Caption := 'Hello Page 1';<br /> Left := 0;<br /> Top := 0;<br /> end; // with<br /><br /> with tbutton.create(application) do begin<br /> Parent := P.Pages[1]; // Tell which page owns the Button<br /> Caption := 'Hello Page 2';<br /> Left := 50;<br /> Top := 50;<br /> end; // with<br /><br /> with tbutton.create(application) do begin<br /><br /> Parent := P.Pages[2]; // Tell which page owns the Button<br /> Caption := 'Hello Page 3';<br /> Left := 100;<br /> Top := 90;<br /> end; // with<br /><br /> // This needs to be done or the Tab does not sync to the <br /> // correct page, initially. Only if you have more then <br /> // one page.<br /> P.ActivePage := P.Pages[1];<br /> P.ActivePage := P.Pages[0]; // page to really show <br />end;<br /> </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:32:23 </span> <span style="HEIGHT: 20px">动态创建控件依次显示数据库值</span> </p><p class="content" style="MARGIN: 4px 2px 0px">var<br /> Edit1: TEdit;<br /> i: integer;<br />begin<br /> table1.First;<br /> for i := 0 to table1.RecordCount - 1 do begin<br /> Edit1 := TEdit.Create(Self);<br /> Edit1.Parent := aForm;<br /> Edit1.Left := 20;<br /> Edit1.Top := 20 * i;<br /> Edit1.Text := table1.fieldbyname('姓名').asString;<br /> table1.next;<br /> end;<br /> edit1.Destroy;<br />end; </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:40:25 </span> <span style="HEIGHT: 20px">动态加减pagecontrol的页数 --- 配合《TPagecontrol TTablesheet 动态创建》使用</span> </p><p class="content" style="MARGIN: 4px 2px 0px">动态添加:<br /> tabsheet2:=ttabsheet.Create(self);<br /> tabsheet2.Caption:='fkjsd';<br /> tabsheet2.PageControl:=pagecontrol1;<br /><br />删除:<br /> tabsheet1.PageControl:=nil; </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:43:25 </span> <span style="HEIGHT: 20px">快速动态创建MenuItem --- 配合《动态创建菜单全接触》使用</span> </p><p class="content" style="MARGIN: 4px 2px 0px">在设计程序时,有时我们需要动态地创建菜单, 通常我们使用以下的语句<br /> PopupMenu1 := TPopupMenu.Create(Self);<br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := 'First Menu';<br /> Item.onClick := MenuItem1Click;<br /> PopupMenu1.Items.Add(Item);<br /><br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := 'Second Menu';<br /> Item.onClick := MenuItem2Click;<br /> PopupMenu1.Items.Add(Item);<br /><br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := 'Third Menu';<br /> Item.onClick := MenuItem3Click;<br /> PopupMenu1.Items.Add(Item);<br /><br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := '-';<br /> PopupMenu1.Items.Add(Item);<br /><br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := 'Fourth Menu';<br /> Item.onClick := MenuItem4Click;<br /> PopupMenu1.Items.Add(Item);<br /><br />其实我们可以使用一种更快的方法达到同样的功能, 但使用很少的代码, 那就是用NewLine和NewItem, 看看下面的例子, 是不是很简单?<br />PopupMenu1 := TPopupMenu.Create(Self);<br />with PopUpMenu1.Items do<br />begin<br /> Add(NewItem('First Menu',0,False,True,MenuItem1Click,0,'MenuItem1'));<br /> Add(NewItem('Second Menu',0,False,True,MenuItem2Click,0,'MenuItem2'));<br /> Add(NewItem('Third Menu',0,False,True,MenuItem3Click,0,'MenuItem3'));<br /> Add(NewLine); // 增加一个分割棒<br /> Add(NewItem('Fourth Menu',0,False,True,MenuItem4Click,0,'MenuItem4'));<br /> ...<br />end; </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:45:54 </span> <span style="HEIGHT: 20px">[作者:guosoong]在QuickRep上面的动态报表建立</span> </p><p class="content" style="MARGIN: 4px 2px 0px">相信每一个到这里的人,都在100多页中寻找过帮助,或多或少都会感到痛苦的,如果你看到本文之后,如果有一丝快乐,就是我最大的快乐了。<br />话归正题!<br /><br />[项目要求]:一个字段动态建立的数据库文件(.dbf),用户要求查询打印或者把整个数据库都打印出来。<br /><br />[解决方法]:<br />1.首先把当前Table或Query中的数据提取出来。<br />2.用户决定一页报表打印多少列,把提取的数据建立数据库文件。<br />3.建立一个QuickQep窗体,在程序运行时动态建立,并动态建立TQRDBText。<br />下面提供每个工作的源码。望大家修改并通知我谢谢。<br />1.首先把当前Table或Query中的数据提取出来。<br />首先定义数据库内有效数据的数据结构<br />type<br /> printvalue = record<br /> fidlecount: integer; //当前数据库的行号(从0开始,完全是个人习惯)<br /> fidlename: string; //字段名称<br /> fidlevalue: string; //字段内容<br /> end;<br />pNowPrintvalue = ^printvalue; //定义指针<br />这个结构大家可以随意修改<br /><br />//这个命令是TTable的,用于把一个数据库文件全部提取出来 TQuery就留给大家自己做吧<br />procedure TForm1.CreateQRTlistByTTable(filename: string; ValueTlist: Tlist);<br />var<br /> temppoint: pNowPrintvalue;<br /> tempTStrings: Tstrings;<br /> temploop1,temploop2: integer;<br /> temptable: TTable;<br /> tempTString: Tstrings;<br />begin<br /> if filename = '' then exit;<br /> if ValueTlist = nil then ValueTlist := Tlist.Create;<br /> ValueTlist.Clear;<br /> temptable := TTable.Create(nil);<br /> tempTStrings := Tstringlist.Create;<br /> try<br /> if sysutils.FileExists(filename) then<br /> begin<br /> temptable.Close;<br /> temptable.DatabaseName := sysutils.ExtractFilePath(filename);<br /> temptable.TableName := sysutils.ExtractFileName(filename);<br /> temptable.Open;<br /><br /> temptable.First;<br /> tempTStrings := temptable.FieldList;<br /> if tempTStrings.Count <= 0 then exit;<br /> for temploop2 := 0 to temptable.RecordCount -1 do<br /> begin<br /> for temploop1 := 0 to tempTStrings.Count -1 do<br /> begin<br /> if tempTStrings[temploop1] <> '' then<br /> begin<br /> new(temppoint);<br /> temppoint.fidlecount := temploop2;<br /> temppoint.fidlename := tempTStrings[temploop1];<br /> if temptable.FieldValues[tempTStrings[temploop1]] = null then<br /> temppoint.fidlevalue := ' '<br /> else<br /> temppoint.fidlevalue := temptable.FieldValues[tempTStrings[temploop1]];<br /> ValueTlist.Add(temppoint);<br /> end;<br /> end;<br /> temptable.Next;<br /> end;<br /> end;<br /> finally<br /> temptable.Free;<br /> end;<br />end;<br /><br />//上面程序里的TLIST就是下面函数的需要的ValueTlist<br />//QRCOLcount 就是用户决定一页打印的列数<br /><br />function TForm1.WriteQRTempDBF(ValueTlist: Tlist;<br /> QRCOLcount: integer): integer;<br />var<br /> templist: Tlist;<br /> tempint: integer;<br /> temptable: TTable;<br /> temploop1,temploop2,temploop3: integer;<br /> temppoint: pNowPrintvalue;<br /> tempvalue: array of string;<br /> modint,endint:integer;<br />const<br /> tempdbname = 'temprint.DBF'; <br /> FieldNames = 'TEMPFD';<br />begin<br /> result := 0;<br /> if QRCOLcount <= 0 then exit;<br /> if ValueTlist = nil then exit;<br /> if ValueTlist.Count <= 0 then exit;<br /> temploop3 := QRCOLcount;<br /> temploop1 := QRCOLcount;<br /> temploop2 := ValueTlist.Count div temploop3;<br /><br /> if ValueTlist.Count mod temploop3 <> 0 then<br /> begin<br /> temploop2 := temploop2 +1;<br /> modint := ValueTlist.Count mod temploop3;<br /> end;<br /><br /> endint := temploop2;<br /> templist := Tlist.Create;<br /> temptable := TTable.Create(nil);<br /> try<br /> tempint := CreateTempQRFieldList(QRCOLcount,templist); //这里是建立有效数据的数据库文件的命令<br /> if tempint >0 then<br /> begin<br /> tempint := CreateDatebases(temptable,BDEName,tempdbname,ttDBase,templist,false);//这里是建立空数据库的命令<br /> if tempint >0 then<br /> begin<br /> temptable.Close;<br /> temptable.DatabaseName := BDEName; //这里是一个全局的数据库别名,大家可以自己定义<br /> temptable.TableName := tempdbname;<br /> temptable.Open;//下面就是把带入的有效数据,填入数据库的工作<br /> with temptable do<br /> begin<br /> Append;<br /> for temploop2 := 0 to temploop2-1 do<br /> begin<br /> if (temploop2 <> endint-1) then<br /> begin<br /> Insert;<br /> tempvalue := nil;<br /> setlength(tempvalue,QRCOLcount);<br /> for temploop3 := 0 to temploop3-1 do<br /> begin<br /> temppoint := ValueTlist.Items[temploop2*QRCOLcount+temploop3];<br /><br /> FieldByName(FieldNames+inttostr(temploop3)).AsString :=temppoint.fidlename;<br /> tempvalue[temploop3] := temppoint.fidlevalue;<br /><br /><br /> if temploop3 = QRCOLcount-1 then<br /> begin<br /> Post;<br /> inc(result);<br /> Insert;<br /> for temploop1 := 0 to temploop1-1 do<br /> FieldByName(FieldNames+inttostr(temploop1)).AsString :=tempvalue[temploop1];<br /> Post;<br /> inc(result);<br /> end;<br /><br /> end;<br /> end<br /> else<br /> begin<br /> if (modint > 0) then<br /> begin<br /> Insert;<br /> tempvalue := nil;<br /> setlength(tempvalue,modint);<br /> for temploop3 := 0 to modint-1 do<br /> begin<br /> temppoint := ValueTlist.Items[temploop2*QRCOLcount+temploop3];<br /><br /> FieldByName(FieldNames+inttostr(temploop3)).AsString :=temppoint.fidlename;<br /> tempvalue[temploop3] := temppoint.fidlevalue;<br /><br /><br /> if temploop3 = modint-1 then<br /> begin<br /> Post;<br /> inc(result);<br /> Insert;<br /> for temploop1 := 0 to modint-1 do<br /> FieldByName(FieldNames+inttostr(temploop1)).AsString :=tempvalue[temploop1];<br /> Post;<br /> inc(result);<br /> end;<br /> end;<br /> end<br /> else<br /> begin<br /> Insert;<br /> tempvalue := nil;<br /> setlength(tempvalue,QRCOLcount);<br /> for temploop3 := 0 to temploop3-1 do<br /> begin<br /> temppoint := ValueTlist.Items[temploop2*QRCOLcount+temploop3];<br /><br /> FieldByName(FieldNames+inttostr(temploop3)).AsString :=temppoint.fidlename;<br /> tempvalue[temploop3] := temppoint.fidlevalue;<br /><br /><br /> if temploop3 = QRCOLcount-1 then<br /> begin<br /> Post;<br /> inc(result);<br /> Insert;<br /> for temploop1 := 0 to temploop1-1 do<br /> FieldByName(FieldNames+inttostr(temploop1)).AsString :=tempvalue[temploop1];<br /> Post;<br /> inc(result);<br /> end;<br /><br /> end;<br /> end;<br /><br /> end;<br /><br /> end; //for temploop2 := 0 to temploop2-1 do<br /><br /> end;<br /> end;<br /> end;<br /> finally<br /> templist.Free;<br /> temptable.Free;<br /> end;<br />end;<br /><br />//接着就是动态建立TQRDBTEXT控件<br />//SenderParent: TGSQuickReport 只是一个普通的TQuickRep <br />//TGSQuickReport = class(TQuickRep) 只是程序建立时不要让它自动建立<br />//Cols是用户定义的列数<br />procedure TForm1.FormatQRFormWithDataset(NowDataset: TDataset; Cols: integer; SenderParent: TGSQuickReport);<br />var<br /> tempqredit: TQRDBText;<br /> temploop1: integer;<br /><br /> nowtop,nowleft: integer; //当前的起点<br /> nowDetailWidth: extended;<br /> everylabwidth:extended; //每个Lable的宽度和高度<br /> nowcol: integer;<br />const<br /> FieldNames = 'tempfd';<br />begin<br /> if SenderParent = nil then exit;<br /> nowcol := Cols;<br /> nowtop := 0;<br /> nowleft := 0;<br /> nowDetailWidth := trunc(SenderParent.DetailBand1.Size.Width);<br /><br /> everylabwidth := trunc(nowDetailWidth / nowcol);<br /> for temploop1 := 0 to nowcol -1 do<br /> begin<br /> tempqredit := TQRDBText.Create(self);<br /> tempqredit.AutoSize := false;<br /> tempqredit.AutoStretch := false;<br /> tempqredit.Color := clskyblue;//clmoneygreen<br /> tempqredit.Parent := SenderParent.DetailBand1;<br /> tempqredit.Top := nowtop;<br /> tempqredit.Left := nowleft;<br /> tempqredit.Size.Width := everylabwidth;<br /> tempqredit.DataSet := NowDataset;<br /> tempqredit.DataField := FieldNames + inttostr(temploop1);<br /><br /> nowleft:= nowleft + tempqredit.Width;<br /> end;<br />end;<br /><br /><br />//当以上三个步骤作完之后就基本成功了<br />下面一个是一个Button下的命令过程<br />procedure TForm1.BitBtn11Click(Sender: TObject);<br />var<br /> temptlist: Tlist;<br /> tempcount: integer;<br /> temppoint: pNowPrintvalue;<br /> tempQR: TGSQuickReport;<br /> temptable: TTable;<br />const<br /> tempdbname = 'temprint.DBF';<br />begin<br /> temptlist := Tlist.Create;<br /> temptable := TTable.Create(nil);<br /> tempQR := TGSQuickReport.Create(nil);<br /> try<br /> self.OpenDialog1.InitialDir := projectpath;<br /> self.OpenDialog1.Title := '';<br /> self.OpenDialog1.Filter := '';<br /> if self.OpenDialog1.Execute then<br /> begin<br /> CreateQRTlistByTTable(self.OpenDialog1.FileName,temptlist);<br /> if temptlist.Count <= 0 then exit;<br /> tempcount := WriteQRTempDBF(temptlist,4);<br /> if tempcount > 0 then<br /> begin<br /> temptable.Close;<br /> temptable.DatabaseName := BDEName;<br /> temptable.TableName := tempdbname;<br /> temptable.Open;<br /> tempQR.DataSet := temptable;<br /> FormatQRFormWithDataset(temptable,4,tempQR);<br /> end;<br /> tempQR.PreviewModal;<br /> end;<br /> finally<br /> temptable.Close;<br /> temptable.Free;<br /> temptlist.Free;<br /> end;<br />end;<br /><br /><br />//这里再补充两个函数,一个是建立数据库字段信息的函数,一个是动态建立数据库的函数<br />Function CreateTempQRFieldList(cols: integer;var resultlist: Tlist): integer; //建立打印数据库文件列表<br />var<br /> FieldNames: array of string;<br /> FieldDatas: pFieldDatas;<br /> Temploop: integer;<br />const<br /> FieldSize = 40;<br /> FieldType = ftString;<br /> tempfieldname = 'tempfd';<br />begin<br /> resultlist.Clear;<br /> result := 0;<br /> if cols <= 0 then exit;<br /> setlength(FieldNames,cols);<br /> for Temploop := 0 to cols-1 do<br /> begin<br /> New(FieldDatas);<br /> FieldDatas.DataFieldName := tempfieldname + inttostr(temploop);<br /> FieldDatas.DataFieldType := FieldType;<br /> FieldDatas.DataFieldSize := FieldSize;<br /> resultList.Add(FieldDatas);<br /> end;<br /> result := resultList.Count;<br /><br />end;<br /><br /><br />Function CreateDatebases ( Tabless : TTable; //table控件名<br /> DBNames : string; //数据库别名<br /> TNames : string; //数据库名<br /> TTypes : TTableType; //数据库类型<br /> CreateDBFList: Tlist; //数据库内容的列表<br /> CreateIt: boolean): integer;<br />var<br /> TempDatas: pFieldDatas;<br /> TempCounts: integer;<br />begin<br /> result := 0;<br /> TempCounts := CreateDBFList.Count;<br /> if TempCounts <= 0 then exit;<br /> Tabless.Close;<br /> with Tabless do<br /> begin<br /> DatabaseName := DBNames;<br /> TableName := TNames;<br /> TableType := TTypes;<br /><br /> with FieldDefs do<br /> begin<br /> //if Createit then Clear;<br /> clear;<br /> for TempCounts := 0 to TempCounts - 1 do<br /> begin<br /> TempDatas := CreateDBFList.Items[TempCounts];<br /> Add(TempDatas.DataFieldName,TempDatas.DataFieldType,TempDatas.DataFieldSize,false);<br /> inc(result);<br /> end;<br /> end;<br /> CreateTable;<br /> end;<br /> Tabless.Close;<br />end; <br /><br /><br />此前已经有转载。感谢作者提供学习的资料。 </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:48:29 </span> <span style="HEIGHT: 20px">如何根据名字来动态创建对象</span> </p><p class="content" style="MARGIN: 4px 2px 0px">[问题的提出]:<br /> 我希望根据一个字符串,来创建该类的对象,例如我给定'TButton',那么能在运行的时候,动态创建Button出来?不要告诉我用if来判断或者用case来判断等等~,那样的话,有几百个控件的话,岂不是晕倒?<br /><br />[解决方案]:<br /> 请参考下面的代码,下面的代码演示了三种控件的动态创建,若需要动态创建其他的,请修改那个数组常量即可:<br /><br />function DynCreateControlByName(AClassName: string; AOwner: TWinControl = nil): TControl;<br /><br />const<br />/// You can add any class if you want!<br /> ControlClass : array[0..2] of TPersistentClass = (TButton, TEdit, TLabel);<br /><br />var<br /> Cls : TControlClass;<br /><br />begin<br /> Result := nil;<br /> RegisterClasses(ControlClass);<br /> Cls := TControlClass(GetClass(AClassName));<br /> if Cls = nil then exit;<br /> Result := Cls.Create(AOwner);<br />end;<br /><br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> Control : TControl;<br />begin<br /> Control := DynCreateControlByName(Edit1.Text);<br /> if Control <> nil then<br /> with Control do<br /> begin<br /> Parent := Self;<br /> Left := Random(Self.Width) - Width;<br /> Top := Random(Self.Width) - Height;<br /> Perform(WM_SETTEXT,Length(Edit1.Text),integer(pchar(Edit1.Text)));<br /> Show;<br /> end;<br />end;<br />---------------------------------------<br /><br />procedure TForm1.Button2Click(Sender: TObject);<br />begin<br /> TWinControlClass(FindClass('TQRDBText')).Create(Self);<br />end;<br /><br />initialization<br /><br />RegisterClasses([TQRDBText]);<br /><br />finalization<br /> UnregisterClasses([TQRDBText]);<br />end.</p> Loading... <p class="content" style="MARGIN: 4px 2px 0px">一、Delphi中生成控件的两种方法<br />---- 1、 Form(表单)设计中生成控件 <br />---- 在进行Form设计时,直接在控件工具箱选择所需控件,再设置其属性与响应事件,这种方法比较常见。 <br />---- 2、 程序中动态生成控件 <br />---- 有时候,我们需要在程序运行时动态生成控件,这样做有两大优点:一是可以增加程序的灵活性;二是如果生成控件的多少与程序中间运行结果相关,显然方法一是无法的实现的,必须用程序中动态生成方法。 <br />---- 程序中动态生成控件的方法分为三步,首先,定义生成的控件类型,再用Create函数生成控件,最后对控件的相关属性赋值。以TButton控件为例,步骤如下: <br />---- (1) 定义控件类型 <br /> var<br /> Button1:TButton;<br />---- (2) 生成控件 <br /> Button1:=TButton. Create(self);<br /> Button1.Parent:=Self; <br /> //一般将其父控件设置为Self,如果不设置Parent的值,则控件不会在屏幕显示出来<br />---- (3) 设置其它属性及定义相关事件响应函数,如Caption, Left, Top, Height, Width, Visible, Enabled, Hint和onClick事件响应函数等。 <br /><br />二、动态生成控件方法的应用<br />---- 在开发生产调度与管理系统中,需要动态生成排产计划图,以甘特图表示,应用Shape控件来显示零件的加工状况(每道工序的加工开始时间与结束时间)是非常适合的。应用Chart控件,对加工设备利用率以三维直方图显示,非常直观。现分别将在程序中动态生成Shape控件和Chart控件的过程加以说明。 <br />---- 1、动态生成Shape控件显示排产计划图(甘特图) <br /> procedure TCreateMultiCharts.ProcCreateCharts;<br /> var<br /> i,j,Rows,Columns,RowSpace,ChartsHeight:Integer; <br /> ShapeChart:array of array of TShape;<br /> begin<br /> Rows:=16; //Shape控件数组行数<br /> Columns:=8; // Shape控件数组列数<br /> RowSpace:=20; // Shape控件行间距<br /> ChartsHeight:=20; // Shape控件高度<br /> SetLength(ShapeChart,Rows,Columns); <br /> //设置ShapeChart数组大小<br /> for i:=0 to Rows do<br /> for j:=0 to Columns do<br /> begin<br /> ShapeChart[i][j]:=TShape.Create(self);<br /> with ShapeChart[i,j] do<br /> begin<br /> Parent:=Self; //此行必不可少,否则Shape控件在屏幕显示不出<br /> Shape:=stRectangle; // Shape控件形状为矩形<br /> Top:=45+i*(RowSpace+ChartsHeight);<br /> Left:=Round(180+Q[i,j].StartTime); //因Q[i,j].StartTime为实数,故需进行四舍五入取整<br /> Width:=Round(Q[i,j].Value)<br /> Height:=ChartsHeight; <br /> Brush.Color:=RandomColor; //自定义函数,说明附后<br /> Brush.Style:=bsSolid; //设置填充方式<br /> Enabled:=True;<br /> end;<br /> end;<br />end;<br /> <br />---- 注: <br />---- (1)Q为一记录型二维数组,定义如下: <br /> type<br /> TempData=Record<br /> Value:Real;<br /> StartTime:Real;<br /> end;<br /> Q:array of array of TempData<br />---- 并且在另一过程已对Q的分量进行赋值。 <br />---- (2)为了区分不同的零件,Shape以不同颜色显示,此时,调用了函数RandomColor。该函数为: <br /> function TCreateMultiCharts.RandomColor;<br /> var<br /> red,green,blue:byte;<br /> begin<br /> red:=random(255);<br /> green:=random(255);<br /> blue:=random(255);<br /> result:=red or (green shl 8) or (blue shl 16);<br /> end;<br />---- 2、动态生成Charts控件的ChartSeries组件,显示设备利用率 <br /> procedure TFormMultiMachinesBurthen.<br /> ShowMachineBurthenCharts;<br /> var<br /> i:Integer;<br /> Burthen:Real;<br /> SeriesClass:TChartSeriesClass; <br /> NewSeries:array of TChartSeries;<br /> begin <br /> SetLength(NewSeries,CreateMultiCharts.Rows);<br /> MachinesBurthenCharts.height:=200;<br /> MachinesBurthenCharts.Width:=550;<br /> for i:=0 to CreateMultiCharts.Rows do<br /> begin<br /> SeriesClass:=TBarSeries; //设置形状为三维条形图<br /> NewSeries[i]:=SeriesClass.Create(Self);<br /> NewSeries[i].ParentChart:=MachinesBurthenCharts;<br /> NewSeries[i].Clear;<br /> Burthen:=MachineBurthen[i];<br /> Burthen:=Round(Burthen*100)/100; //只取小数点后两位数字<br /> NewSeries[i].add(Burthen,'',NewSeries[i].SeriesColor);<br /> end;<br /> end;<br /> <br />---- 注: <br />---- (1) MachineBurthen[i]为一实型数组,其值为对应设备的利用率,已在另一函数中计算得到; <br />---- (2) MachinesBurthenCharts为TChart控件,在type段说明。 </p><p><br /> </p><div style="BORDER-BOTTOM: #8ca6de 1px solid" align="right">2004-4-6 10:59:32 </div><div class="inputcaption" style="BORDER-BOTTOM: #8ca6de 1px solid"><table cellspacing="0" cellpadding="3" width="100%" border="0"> <tbody> <tr> <td> </td> <td align="right"><span class="external-link"><a class="no-external-link" href="http://www.delphibbs.com/keylife/iblog_comment.asp?xid=6917" target="_blank"><i data-feather="external-link"></i>查看评语»»»</a></span> </td> </tr> </tbody></table></div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:29:16 </span> <span style="HEIGHT: 20px">动态创建菜单全接触</span> </p><p class="content" style="MARGIN: 4px 2px 0px">[基本认识]:<br /> 在Delphi的程序开发环境中,封装的VCL减化了我们许多的开发工作,由在界面的设计上使开发的进度很快,但在很多的时候,我们需要自己来设计可视化的用户界面,而且是在程序的运行中,这时我们就得利用Delphi给我们提供的类来完成我们需要的工作了,下面笔者就和朋友们浅入的讨论一下动态创建"菜单"的基本知识,希望本文给那些刚入门的朋友来个抛砖引玉的作用。 <br /> 在delphi的菜单设计中,有两个Delphi的菜单控件:<br /> 1:Tmainmenu;<br /> 2:Tpopupmenu;<br /> 前者是创建窗口的菜单,后者是创建右键弹出式菜单的控件,但在Delphi庞大的类库中有一个类与这两个控件密切相关,它就是:TMenuItem,窗口的菜单和右键弹出式菜单的每个条目都是TMenuItem类的一个对象。此TMenuItem类不出现在控件板上,在程序中用代码可创建其实例。 <br /><br />[基本知识]:<br /> 在tmainmenu,tpopupmenu控件中有一个属性是items,此属性是数组型,里面的参数为菜单项的索引值。<br />文件 编辑 查看 插入 格式 帮助<br />---- ---- ---- ---- ---- ----<br />新建 撤消 标尺 对象 字体 关于<br />打开 拷贝 源码 公式 颜色 <br /> 相信您看过上面的菜单简单表示之后是非常熟悉的,在此菜单中菜单头的索引值代表如下:<br /> "文件"的菜单的items值为0;<br /> "编辑"的菜单的items值为1;以此类推。<br /> items属性是tmenuitem类型,而在此类型中还有一个属性,是items,如果您略懂"类"的关系,您就不难明白此类似"嵌套"的关系。"新建"菜单选项是"文件"菜单选项的子类,用代码表示为tmainmenu.items[0].items[0],"打开"菜单选项为tmainmenu.items[0].items[1],以此类推,而代表"编辑"菜单中的"拷贝"菜单选项的代码为tmainmenu.items[1].items[1],其它菜单代码表示以此类推。 <br /><br />[基本实例]:<br /> 知道了菜单的items结构之后,我们就可以进一步大胆的创建自己有序的菜单了。<br /> 上面讨论到窗口的菜单和右键弹出式菜单的每个条目都是TMenuItem类的一个对象。那么我们就可以create它的一个实例,来添加自己想要的菜单了。<br /><br />[示例过程]:<br />1:新建一个工程。<br />2:添加一个tmainmenu控件。<br />3:添加一个button控件,并在button的onclick事件中写入如下代码:<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> files,edit:tmenuitem;{要有实例的声明}<br />begin<br /> files:=tmenuitem.Create(self);<br /> edit:=tmenuitem.create(self);<br /> files.Caption:='文件';<br /> edit.caption:='编辑';<br /> mainmenu1.AutoHotkeys:=mamanual;{此句代码为不让系统自动设置快捷键}<br /> form1.MainMenu1.Items.Add(files);<br /> form1.mainmenu1.items.add(edit);<br />end; <br /> 运行后,出现如上面例举的菜单的部分结构,如此看来动态创建菜单项的方法是非常简单的,这无疑于Delphi把系统的函数进行了封装。菜单头我们创建完了,接下来就该创建菜单里的菜单项了,由"items属性是tmenuitem类型,而在此类型中还有一个属性,是items"此句话的意思我们可以创建菜单项,代码如下: <br />1:新建一个工程。<br />2:添加一个tmainmenu控件。 <br />3:添加一个button控件,并在button的onclick事件中写入如下代码:<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> files,edit:tmenuitem;<br /> new,copy:tmenuitem;<br />begin<br /> files:=tmenuitem.Create(self);<br /> edit:=tmenuitem.create(self);<br /> files.Caption:='文件';<br /> edit.caption:='编辑';<br /> mainmenu1.AutoHotkeys:=mamanual;{此句代码为不让系统自动设置快捷键}<br /> form1.MainMenu1.Items.Add(files);<br /> form1.mainmenu1.items.add(edit);<br /> {上部代码为创建菜单头}<br /> new:=tmenuitem.create(self);<br /> copy:=tmenuitem.create(self);<br /> new.Caption:='新建';<br /> copy.caption:='拷贝';<br /> files.Add(new);<br /> edit.add(copy);<br /> {上部代码为创建菜单项}<br />end; <br /> 运行效果和上面菜单结构表中基本一样,但此时点击菜单项时不出现任何的事件,显然这样的软件出售量不算理想,我们可以略改代码加个事件上去。<br />代码如下:<br />1:新建一个工程。<br />2:添加一个tmainmenu控件。<br />3:<br />private<br /> procedure abc(sender:tobject);<br /> { Private declarations }<br />var<br /> Form1: TForm1;<br /><br />implementation<br /><br />{$R *.DFM}<br /><br />procedure tform1.abc(sender:tobject);<br />begin<br /> showmessage('welcome you click me!! :) xixi');<br />end;<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> files,edit:tmenuitem;<br /> new,copy:tmenuitem;<br />begin<br /> files:=tmenuitem.Create(self);<br /> edit:=tmenuitem.create(self);<br /> files.Caption:='文件';<br /> edit.caption:='编辑';<br /> mainmenu1.AutoHotkeys:=mamanual;{此句代码为不让系统自动设置快捷键}<br /> form1.MainMenu1.Items.Add(files);<br /> form1.mainmenu1.items.add(edit);<br /> {上部代码为创建菜单头}<br /> new:=tmenuitem.create(self);<br /> copy:=tmenuitem.create(self);<br /> new.Caption:='新建';<br /> copy.caption:='拷贝';<br /> copy.onClick:=abc;<br /> new.onClick:=abc;<br /> files.Add(new);<br /> edit.add(copy);<br /> {上部代码为创建菜单项}<br />end;<br /> 这时这个软件就有了交互的功能。<br /> 有时菜单项中出现一个横的条线和出现一个子的菜单,那么这样的效果怎么用代码实现的呢,下面就是此效果的代码示例:<br />1:新建一个工程。<br />2:添加一个tmainmenu控件。<br />3:<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> files,edit:tmenuitem;<br /> new,copy:tmenuitem;<br /> sub1,sub2,sub3,lines:tmenuitem;<br />begin<br /> files:=tmenuitem.Create(self);<br /> edit:=tmenuitem.create(self);<br /> files.Caption:='文件';<br /> edit.caption:='编辑';<br /> mainmenu1.AutoHotkeys:=mamanual;{此句代码为不让系统自动设置快捷键}<br /> form1.MainMenu1.Items.Add(files);<br /> form1.mainmenu1.items.add(edit);<br /> {上部代码为创建菜单头}<br /> new:=tmenuitem.create(self);<br /> copy:=tmenuitem.create(self);<br /> new.Caption:='新建';<br /> copy.caption:='拷贝';<br /> files.Add(new);<br /> edit.add(copy);<br /> {上部代码为创建菜单项}<br /> sub1:=tmenuitem.create(self);<br /> sub2:=tmenuitem.create(self);<br /> sub3:=tmenuitem.create(self);<br /> lines:=tmenuitem.create(self);<br /> lines.caption:='-';<br /> sub1.caption:='子菜单1';<br /> sub2.caption:='子菜单2';<br /> sub3.caption:='子菜单3';<br /> new.Add(sub1);<br /> new.add(lines);<br /> new.add(sub3);<br /> copy.Add(sub2);<br /> {上面代码出现多项子菜单和横线的效果}<br />end;<br /><br /> 到此讨论的内容就要结束,菜单的创建在Delphi中是非常简单的事,在tmenuitem类中还有许多的事件和方法及属性,如Add, Clear, Click, Create, Delete, Destroy, Find, IndexOf, Insert, Remove等方法的使用都是非常简单的. </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:30:34 </span> <span style="HEIGHT: 20px">TPagecontrol TTablesheet 动态创建</span> </p><p class="content" style="MARGIN: 4px 2px 0px">动态创建TPagecontrol, TTablesheet <br />var<br /> T : TTabSheet;<br /> P : TPageControl;<br />begin<br /> // Create the PageControl<br /> // need to reference the page control so we need a reference to it.<br /><br /> P := TPageControl.Create(application);<br /> with P do begin<br /> Parent := Form1; // set how controls it.<br /> Top := 30;<br /> Left := 30;<br /> Width := 200;<br /> Height := 150;<br /> end; // with TPageControl<br /><br /> // Create 3 pages<br /> T := TTabSheet.Create(P);<br /> with T do begin<br /> Visible := True; // This is necessary or form does not repaint <br /> // correctly<br /> Caption := 'Page 1';<br /> PageControl := P; // Assign Tab to Page Control<br /> end; // with<br /><br /> T := TTabSheet.Create(P);<br /> with T do begin<br /> Visible := True; // This is necessary or form does not repaint <br /> // correctly<br /> Caption := 'Page 2';<br /> PageControl := P; // Assign Tab to Page Control<br /> end; // with<br /><br /> T := TTabSheet.Create(P);<br /> with T do begin<br /> Visible := True; // This is necessary or form does not repaint <br /> // correctly<br /> Caption := 'Page 3';<br /> PageControl := P; // Assign Tab to Page Control<br /><br /> end; // with<br /><br /> // Create 3 buttons, 1 per page<br /> with tbutton.create(application) do begin<br /> Parent := P.Pages[0]; // Tell which page owns the Button<br /> Caption := 'Hello Page 1';<br /> Left := 0;<br /> Top := 0;<br /> end; // with<br /><br /> with tbutton.create(application) do begin<br /> Parent := P.Pages[1]; // Tell which page owns the Button<br /> Caption := 'Hello Page 2';<br /> Left := 50;<br /> Top := 50;<br /> end; // with<br /><br /> with tbutton.create(application) do begin<br /><br /> Parent := P.Pages[2]; // Tell which page owns the Button<br /> Caption := 'Hello Page 3';<br /> Left := 100;<br /> Top := 90;<br /> end; // with<br /><br /> // This needs to be done or the Tab does not sync to the <br /> // correct page, initially. Only if you have more then <br /> // one page.<br /> P.ActivePage := P.Pages[1];<br /> P.ActivePage := P.Pages[0]; // page to really show <br />end;<br /> </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:32:23 </span> <span style="HEIGHT: 20px">动态创建控件依次显示数据库值</span> </p><p class="content" style="MARGIN: 4px 2px 0px">var<br /> Edit1: TEdit;<br /> i: integer;<br />begin<br /> table1.First;<br /> for i := 0 to table1.RecordCount - 1 do begin<br /> Edit1 := TEdit.Create(Self);<br /> Edit1.Parent := aForm;<br /> Edit1.Left := 20;<br /> Edit1.Top := 20 * i;<br /> Edit1.Text := table1.fieldbyname('姓名').asString;<br /> table1.next;<br /> end;<br /> edit1.Destroy;<br />end; </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:40:25 </span> <span style="HEIGHT: 20px">动态加减pagecontrol的页数 --- 配合《TPagecontrol TTablesheet 动态创建》使用</span> </p><p class="content" style="MARGIN: 4px 2px 0px">动态添加:<br /> tabsheet2:=ttabsheet.Create(self);<br /> tabsheet2.Caption:='fkjsd';<br /> tabsheet2.PageControl:=pagecontrol1;<br /><br />删除:<br /> tabsheet1.PageControl:=nil; </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:43:25 </span> <span style="HEIGHT: 20px">快速动态创建MenuItem --- 配合《动态创建菜单全接触》使用</span> </p><p class="content" style="MARGIN: 4px 2px 0px">在设计程序时,有时我们需要动态地创建菜单, 通常我们使用以下的语句<br /> PopupMenu1 := TPopupMenu.Create(Self);<br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := 'First Menu';<br /> Item.onClick := MenuItem1Click;<br /> PopupMenu1.Items.Add(Item);<br /><br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := 'Second Menu';<br /> Item.onClick := MenuItem2Click;<br /> PopupMenu1.Items.Add(Item);<br /><br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := 'Third Menu';<br /> Item.onClick := MenuItem3Click;<br /> PopupMenu1.Items.Add(Item);<br /><br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := '-';<br /> PopupMenu1.Items.Add(Item);<br /><br /> Item := TMenuItem.Create(PopupMenu1);<br /> Item.Caption := 'Fourth Menu';<br /> Item.onClick := MenuItem4Click;<br /> PopupMenu1.Items.Add(Item);<br /><br />其实我们可以使用一种更快的方法达到同样的功能, 但使用很少的代码, 那就是用NewLine和NewItem, 看看下面的例子, 是不是很简单?<br />PopupMenu1 := TPopupMenu.Create(Self);<br />with PopUpMenu1.Items do<br />begin<br /> Add(NewItem('First Menu',0,False,True,MenuItem1Click,0,'MenuItem1'));<br /> Add(NewItem('Second Menu',0,False,True,MenuItem2Click,0,'MenuItem2'));<br /> Add(NewItem('Third Menu',0,False,True,MenuItem3Click,0,'MenuItem3'));<br /> Add(NewLine); // 增加一个分割棒<br /> Add(NewItem('Fourth Menu',0,False,True,MenuItem4Click,0,'MenuItem4'));<br /> ...<br />end; </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:45:54 </span> <span style="HEIGHT: 20px">[作者:guosoong]在QuickRep上面的动态报表建立</span> </p><p class="content" style="MARGIN: 4px 2px 0px">相信每一个到这里的人,都在100多页中寻找过帮助,或多或少都会感到痛苦的,如果你看到本文之后,如果有一丝快乐,就是我最大的快乐了。<br />话归正题!<br /><br />[项目要求]:一个字段动态建立的数据库文件(.dbf),用户要求查询打印或者把整个数据库都打印出来。<br /><br />[解决方法]:<br />1.首先把当前Table或Query中的数据提取出来。<br />2.用户决定一页报表打印多少列,把提取的数据建立数据库文件。<br />3.建立一个QuickQep窗体,在程序运行时动态建立,并动态建立TQRDBText。<br />下面提供每个工作的源码。望大家修改并通知我谢谢。<br />1.首先把当前Table或Query中的数据提取出来。<br />首先定义数据库内有效数据的数据结构<br />type<br /> printvalue = record<br /> fidlecount: integer; //当前数据库的行号(从0开始,完全是个人习惯)<br /> fidlename: string; //字段名称<br /> fidlevalue: string; //字段内容<br /> end;<br />pNowPrintvalue = ^printvalue; //定义指针<br />这个结构大家可以随意修改<br /><br />//这个命令是TTable的,用于把一个数据库文件全部提取出来 TQuery就留给大家自己做吧<br />procedure TForm1.CreateQRTlistByTTable(filename: string; ValueTlist: Tlist);<br />var<br /> temppoint: pNowPrintvalue;<br /> tempTStrings: Tstrings;<br /> temploop1,temploop2: integer;<br /> temptable: TTable;<br /> tempTString: Tstrings;<br />begin<br /> if filename = '' then exit;<br /> if ValueTlist = nil then ValueTlist := Tlist.Create;<br /> ValueTlist.Clear;<br /> temptable := TTable.Create(nil);<br /> tempTStrings := Tstringlist.Create;<br /> try<br /> if sysutils.FileExists(filename) then<br /> begin<br /> temptable.Close;<br /> temptable.DatabaseName := sysutils.ExtractFilePath(filename);<br /> temptable.TableName := sysutils.ExtractFileName(filename);<br /> temptable.Open;<br /><br /> temptable.First;<br /> tempTStrings := temptable.FieldList;<br /> if tempTStrings.Count <= 0 then exit;<br /> for temploop2 := 0 to temptable.RecordCount -1 do<br /> begin<br /> for temploop1 := 0 to tempTStrings.Count -1 do<br /> begin<br /> if tempTStrings[temploop1] <> '' then<br /> begin<br /> new(temppoint);<br /> temppoint.fidlecount := temploop2;<br /> temppoint.fidlename := tempTStrings[temploop1];<br /> if temptable.FieldValues[tempTStrings[temploop1]] = null then<br /> temppoint.fidlevalue := ' '<br /> else<br /> temppoint.fidlevalue := temptable.FieldValues[tempTStrings[temploop1]];<br /> ValueTlist.Add(temppoint);<br /> end;<br /> end;<br /> temptable.Next;<br /> end;<br /> end;<br /> finally<br /> temptable.Free;<br /> end;<br />end;<br /><br />//上面程序里的TLIST就是下面函数的需要的ValueTlist<br />//QRCOLcount 就是用户决定一页打印的列数<br /><br />function TForm1.WriteQRTempDBF(ValueTlist: Tlist;<br /> QRCOLcount: integer): integer;<br />var<br /> templist: Tlist;<br /> tempint: integer;<br /> temptable: TTable;<br /> temploop1,temploop2,temploop3: integer;<br /> temppoint: pNowPrintvalue;<br /> tempvalue: array of string;<br /> modint,endint:integer;<br />const<br /> tempdbname = 'temprint.DBF'; <br /> FieldNames = 'TEMPFD';<br />begin<br /> result := 0;<br /> if QRCOLcount <= 0 then exit;<br /> if ValueTlist = nil then exit;<br /> if ValueTlist.Count <= 0 then exit;<br /> temploop3 := QRCOLcount;<br /> temploop1 := QRCOLcount;<br /> temploop2 := ValueTlist.Count div temploop3;<br /><br /> if ValueTlist.Count mod temploop3 <> 0 then<br /> begin<br /> temploop2 := temploop2 +1;<br /> modint := ValueTlist.Count mod temploop3;<br /> end;<br /><br /> endint := temploop2;<br /> templist := Tlist.Create;<br /> temptable := TTable.Create(nil);<br /> try<br /> tempint := CreateTempQRFieldList(QRCOLcount,templist); //这里是建立有效数据的数据库文件的命令<br /> if tempint >0 then<br /> begin<br /> tempint := CreateDatebases(temptable,BDEName,tempdbname,ttDBase,templist,false);//这里是建立空数据库的命令<br /> if tempint >0 then<br /> begin<br /> temptable.Close;<br /> temptable.DatabaseName := BDEName; //这里是一个全局的数据库别名,大家可以自己定义<br /> temptable.TableName := tempdbname;<br /> temptable.Open;//下面就是把带入的有效数据,填入数据库的工作<br /> with temptable do<br /> begin<br /> Append;<br /> for temploop2 := 0 to temploop2-1 do<br /> begin<br /> if (temploop2 <> endint-1) then<br /> begin<br /> Insert;<br /> tempvalue := nil;<br /> setlength(tempvalue,QRCOLcount);<br /> for temploop3 := 0 to temploop3-1 do<br /> begin<br /> temppoint := ValueTlist.Items[temploop2*QRCOLcount+temploop3];<br /><br /> FieldByName(FieldNames+inttostr(temploop3)).AsString :=temppoint.fidlename;<br /> tempvalue[temploop3] := temppoint.fidlevalue;<br /><br /><br /> if temploop3 = QRCOLcount-1 then<br /> begin<br /> Post;<br /> inc(result);<br /> Insert;<br /> for temploop1 := 0 to temploop1-1 do<br /> FieldByName(FieldNames+inttostr(temploop1)).AsString :=tempvalue[temploop1];<br /> Post;<br /> inc(result);<br /> end;<br /><br /> end;<br /> end<br /> else<br /> begin<br /> if (modint > 0) then<br /> begin<br /> Insert;<br /> tempvalue := nil;<br /> setlength(tempvalue,modint);<br /> for temploop3 := 0 to modint-1 do<br /> begin<br /> temppoint := ValueTlist.Items[temploop2*QRCOLcount+temploop3];<br /><br /> FieldByName(FieldNames+inttostr(temploop3)).AsString :=temppoint.fidlename;<br /> tempvalue[temploop3] := temppoint.fidlevalue;<br /><br /><br /> if temploop3 = modint-1 then<br /> begin<br /> Post;<br /> inc(result);<br /> Insert;<br /> for temploop1 := 0 to modint-1 do<br /> FieldByName(FieldNames+inttostr(temploop1)).AsString :=tempvalue[temploop1];<br /> Post;<br /> inc(result);<br /> end;<br /> end;<br /> end<br /> else<br /> begin<br /> Insert;<br /> tempvalue := nil;<br /> setlength(tempvalue,QRCOLcount);<br /> for temploop3 := 0 to temploop3-1 do<br /> begin<br /> temppoint := ValueTlist.Items[temploop2*QRCOLcount+temploop3];<br /><br /> FieldByName(FieldNames+inttostr(temploop3)).AsString :=temppoint.fidlename;<br /> tempvalue[temploop3] := temppoint.fidlevalue;<br /><br /><br /> if temploop3 = QRCOLcount-1 then<br /> begin<br /> Post;<br /> inc(result);<br /> Insert;<br /> for temploop1 := 0 to temploop1-1 do<br /> FieldByName(FieldNames+inttostr(temploop1)).AsString :=tempvalue[temploop1];<br /> Post;<br /> inc(result);<br /> end;<br /><br /> end;<br /> end;<br /><br /> end;<br /><br /> end; //for temploop2 := 0 to temploop2-1 do<br /><br /> end;<br /> end;<br /> end;<br /> finally<br /> templist.Free;<br /> temptable.Free;<br /> end;<br />end;<br /><br />//接着就是动态建立TQRDBTEXT控件<br />//SenderParent: TGSQuickReport 只是一个普通的TQuickRep <br />//TGSQuickReport = class(TQuickRep) 只是程序建立时不要让它自动建立<br />//Cols是用户定义的列数<br />procedure TForm1.FormatQRFormWithDataset(NowDataset: TDataset; Cols: integer; SenderParent: TGSQuickReport);<br />var<br /> tempqredit: TQRDBText;<br /> temploop1: integer;<br /><br /> nowtop,nowleft: integer; //当前的起点<br /> nowDetailWidth: extended;<br /> everylabwidth:extended; //每个Lable的宽度和高度<br /> nowcol: integer;<br />const<br /> FieldNames = 'tempfd';<br />begin<br /> if SenderParent = nil then exit;<br /> nowcol := Cols;<br /> nowtop := 0;<br /> nowleft := 0;<br /> nowDetailWidth := trunc(SenderParent.DetailBand1.Size.Width);<br /><br /> everylabwidth := trunc(nowDetailWidth / nowcol);<br /> for temploop1 := 0 to nowcol -1 do<br /> begin<br /> tempqredit := TQRDBText.Create(self);<br /> tempqredit.AutoSize := false;<br /> tempqredit.AutoStretch := false;<br /> tempqredit.Color := clskyblue;//clmoneygreen<br /> tempqredit.Parent := SenderParent.DetailBand1;<br /> tempqredit.Top := nowtop;<br /> tempqredit.Left := nowleft;<br /> tempqredit.Size.Width := everylabwidth;<br /> tempqredit.DataSet := NowDataset;<br /> tempqredit.DataField := FieldNames + inttostr(temploop1);<br /><br /> nowleft:= nowleft + tempqredit.Width;<br /> end;<br />end;<br /><br /><br />//当以上三个步骤作完之后就基本成功了<br />下面一个是一个Button下的命令过程<br />procedure TForm1.BitBtn11Click(Sender: TObject);<br />var<br /> temptlist: Tlist;<br /> tempcount: integer;<br /> temppoint: pNowPrintvalue;<br /> tempQR: TGSQuickReport;<br /> temptable: TTable;<br />const<br /> tempdbname = 'temprint.DBF';<br />begin<br /> temptlist := Tlist.Create;<br /> temptable := TTable.Create(nil);<br /> tempQR := TGSQuickReport.Create(nil);<br /> try<br /> self.OpenDialog1.InitialDir := projectpath;<br /> self.OpenDialog1.Title := '';<br /> self.OpenDialog1.Filter := '';<br /> if self.OpenDialog1.Execute then<br /> begin<br /> CreateQRTlistByTTable(self.OpenDialog1.FileName,temptlist);<br /> if temptlist.Count <= 0 then exit;<br /> tempcount := WriteQRTempDBF(temptlist,4);<br /> if tempcount > 0 then<br /> begin<br /> temptable.Close;<br /> temptable.DatabaseName := BDEName;<br /> temptable.TableName := tempdbname;<br /> temptable.Open;<br /> tempQR.DataSet := temptable;<br /> FormatQRFormWithDataset(temptable,4,tempQR);<br /> end;<br /> tempQR.PreviewModal;<br /> end;<br /> finally<br /> temptable.Close;<br /> temptable.Free;<br /> temptlist.Free;<br /> end;<br />end;<br /><br /><br />//这里再补充两个函数,一个是建立数据库字段信息的函数,一个是动态建立数据库的函数<br />Function CreateTempQRFieldList(cols: integer;var resultlist: Tlist): integer; //建立打印数据库文件列表<br />var<br /> FieldNames: array of string;<br /> FieldDatas: pFieldDatas;<br /> Temploop: integer;<br />const<br /> FieldSize = 40;<br /> FieldType = ftString;<br /> tempfieldname = 'tempfd';<br />begin<br /> resultlist.Clear;<br /> result := 0;<br /> if cols <= 0 then exit;<br /> setlength(FieldNames,cols);<br /> for Temploop := 0 to cols-1 do<br /> begin<br /> New(FieldDatas);<br /> FieldDatas.DataFieldName := tempfieldname + inttostr(temploop);<br /> FieldDatas.DataFieldType := FieldType;<br /> FieldDatas.DataFieldSize := FieldSize;<br /> resultList.Add(FieldDatas);<br /> end;<br /> result := resultList.Count;<br /><br />end;<br /><br /><br />Function CreateDatebases ( Tabless : TTable; //table控件名<br /> DBNames : string; //数据库别名<br /> TNames : string; //数据库名<br /> TTypes : TTableType; //数据库类型<br /> CreateDBFList: Tlist; //数据库内容的列表<br /> CreateIt: boolean): integer;<br />var<br /> TempDatas: pFieldDatas;<br /> TempCounts: integer;<br />begin<br /> result := 0;<br /> TempCounts := CreateDBFList.Count;<br /> if TempCounts <= 0 then exit;<br /> Tabless.Close;<br /> with Tabless do<br /> begin<br /> DatabaseName := DBNames;<br /> TableName := TNames;<br /> TableType := TTypes;<br /><br /> with FieldDefs do<br /> begin<br /> //if Createit then Clear;<br /> clear;<br /> for TempCounts := 0 to TempCounts - 1 do<br /> begin<br /> TempDatas := CreateDBFList.Items[TempCounts];<br /> Add(TempDatas.DataFieldName,TempDatas.DataFieldType,TempDatas.DataFieldSize,false);<br /> inc(result);<br /> end;<br /> end;<br /> CreateTable;<br /> end;<br /> Tabless.Close;<br />end; <br /><br /><br />此前已经有转载。感谢作者提供学习的资料。 </p><div class="bline" align="right"> </div><p><span class="inputcaption" style="HEIGHT: 20px"> 2004-4-6 11:48:29 </span> <span style="HEIGHT: 20px">如何根据名字来动态创建对象</span> </p><p class="content" style="MARGIN: 4px 2px 0px">[问题的提出]:<br /> 我希望根据一个字符串,来创建该类的对象,例如我给定'TButton',那么能在运行的时候,动态创建Button出来?不要告诉我用if来判断或者用case来判断等等~,那样的话,有几百个控件的话,岂不是晕倒?<br /><br />[解决方案]:<br /> 请参考下面的代码,下面的代码演示了三种控件的动态创建,若需要动态创建其他的,请修改那个数组常量即可:<br /><br />function DynCreateControlByName(AClassName: string; AOwner: TWinControl = nil): TControl;<br /><br />const<br />/// You can add any class if you want!<br /> ControlClass : array[0..2] of TPersistentClass = (TButton, TEdit, TLabel);<br /><br />var<br /> Cls : TControlClass;<br /><br />begin<br /> Result := nil;<br /> RegisterClasses(ControlClass);<br /> Cls := TControlClass(GetClass(AClassName));<br /> if Cls = nil then exit;<br /> Result := Cls.Create(AOwner);<br />end;<br /><br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> Control : TControl;<br />begin<br /> Control := DynCreateControlByName(Edit1.Text);<br /> if Control <> nil then<br /> with Control do<br /> begin<br /> Parent := Self;<br /> Left := Random(Self.Width) - Width;<br /> Top := Random(Self.Width) - Height;<br /> Perform(WM_SETTEXT,Length(Edit1.Text),integer(pchar(Edit1.Text)));<br /> Show;<br /> end;<br />end;<br />---------------------------------------<br /><br />procedure TForm1.Button2Click(Sender: TObject);<br />begin<br /> TWinControlClass(FindClass('TQRDBText')).Create(Self);<br />end;<br /><br />initialization<br /><br />RegisterClasses([TQRDBText]);<br /><br />finalization<br /> UnregisterClasses([TQRDBText]);<br />end.</p> 最后修改:2009 年 08 月 16 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 支持就是力量
2 条评论
小县城的伤不起啊,希望老大有空的话帮忙做一个山西省朔州市怀仁县的离线包吧 感激不尽
留个脚印呵呵...