Delphi的“动态窗体”技术实际应用

  1. 在Delphi可视化设计环境中,允许程序员在代码编辑器中以文本的方式浏览和修改DFM文件内容。当用File/Open命令直接打开DFM文件或者选择窗体设计窗口的弹出式菜单上的View as Text命令时,就会在编辑器中出现文本形式的信息。在一些资料中将这种文本形式称之为窗体设计脚本。Delphi提供的这种脚本编辑功能是对Delphi可视化设计的一大补充。当然这个脚本编辑能力是有限制的,比方说不能在脚本任意地添加和删除部件,因为代码和DFM脚本是紧密相连的,任意添加和修改会导致不一致性。但在动态生成的DFM文件中,就不存在这一限制。
  2.   实际上,DFM文件内容是二进制数据,它的脚本是经过Delphi开发环境自动转化的,而且Delphi VCL中的Classes库单元提供了在二进制流中的文件DFM和它的脚本之相互转化的过程。它们是ObjectBinaryToText和ObjectTextToBinary、ObjectResourceToText和ObjectTextToResource。
  3.   ObjectBinaryToText过程将二进制流中存储的部件转化为基于文本的表现形式,这样就可以用文本处理函数进行处理,还可以用文本编辑器进行查找和替代操作,最后可以将文本再转化成二进制流中的部件。
  4.   ObjectTextToBinary过程执行的功能与ObjectBinaryToText相反,将TXT文件转换为二进制流中的部件,而且只要TXT文件内容的书写符合DFM脚本语法,ObjectTextToBinary可将任何程序生成的TXT文件转换为部件,这一功能也为DFM文件的动态生成和编辑奠定了基础。
  5. 如何在运行过程中将本窗体保存成一个文本格式的.dfm文件?
  6. zswang(伴水) (2001-11-21 9:52:59) 得0
  7. function ComponentToString(Component: TComponent): string;
  8. var
  9. BinStream: TMemoryStream;
  10. StrStream: TStringStream;
  11. s: string;
  12. begin
  13. BinStream := TMemoryStream.Create;
  14. try
  15. StrStream := TStringStream.Create(s);
  16. try
  17. BinStream.WriteComponent(Component);
  18. BinStream.Seek(0, soFromBeginning);
  19. ObjectBinaryToText(BinStream, StrStream);
  20. StrStream.Seek(0, soFromBeginning);
  21. Result := StrStream.DataString;
  22. finally
  23. StrStream.Free;
  24. end;
  25. finally
  26. BinStream.Free
  27. end;
  28. end{ ComponentToString }
  29. function StringToComponent(Value: string; Instance: TComponent): TComponent;
  30. var
  31. StrStream: TStringStream;
  32. BinStream: TMemoryStream;
  33. begin
  34. StrStream := TStringStream.Create(Value);
  35. try
  36. BinStream := TMemoryStream.Create;
  37. try
  38. ObjectTextToBinary(StrStream, BinStream);
  39. BinStream.Seek(0, soFromBeginning);
  40. Result := BinStream.ReadComponent(Instance);
  41. finally
  42. BinStream.Free;
  43. end;
  44. finally
  45. StrStream.Free;
  46. end;
  47. end{ StringToComponent }
  48.  
  49. 回复人: zswang(伴水) (2001-11-21 9:54:28) 得0
  50. procedure TForm1.Button1Click(Sender: TObject);
  51. begin
  52. Memo1.Text := ComponentToString(Self);
  53. end;
  54.  
  55. 回复人: zswang(伴水) (2001-11-21 9:58:13) 得0
  56. procedure TForm1.Button2Click(Sender: TObject);
  57. begin
  58. StringToComponent(
  59. 'object Label1: TLabel'#13#10 +
  60. ' Left = 232'#13#10 +
  61. ' Top = 56'#13#10 +
  62. ' Width = 26'#13#10 +
  63. ' Height = 13'#13#10 +
  64. ' Caption = #20320#22909'#13#10 +
  65. ' Font.Charset = GB2312_CHARSET'#13#10 +
  66. ' Font.Color = clRed'#13#10 +
  67. ' Font.Height = -13'#13#10 +
  68. ' Font.Name = #23435#20307'#13#10 +
  69. ' Font.Style = []'#13#10 +
  70. ' ParentFont = False'#13#10 +
  71. 'end'#13#10, Label1);
  72. end;
  73. //要注册类
  74. ==end=================================
  75. 好了,理解了上面的这段文字,一些朋友就会自然想到,利用这几个函数应该可以弄出点有用的东西出来,我就弄出了一点应用,并全面应用到了项目中,现在我来给大家完整描述出来:
  76. 首先我要求我的程序有如下能力:
  77. 1. 我的程序的窗体是可以动态替换的,不用编译Exe,只要替换一个DFM窗体设计脚本就可以了(当然,你可以重新包装一下这个DFM文件,比如换成txt后缀名等)。
  78. 2. 我可以预览所有的DFM文件,让它变成实际的Form察看。
  79. 不要小看这两点,在很多情况下,这意义非常重大,举几个例子①开发阶段,可以把界面设计和程序设计完全分开,分工进行②现场维护时,有些界面的调整和功能设置不需要再找源代码到Delphi下去编译一遍了,老出差做Mis类的朋友应该能从这点体会出好处③某些功能界面的升级简单了不少,只要让用户下载一个DFM文件覆盖原来的就可以了。
  80. 好,不费话了,下面详细说明怎么达到以上两点要求。
  81. 显然我们要让一段文本变成一个Form,那么就用这个函数:
  82. function StringToComponent(Value: string; Instance:TComponent): TComponent;
  83. var
  84. StrStream:TStringStream;
  85. BinStream: TMemoryStream;
  86. begin
  87. StrStream := TStringStream.Create(Value);
  88. try
  89. BinStream := TMemoryStream.Create;
  90. try
  91. ObjectTextToBinary(StrStream, BinStream);
  92. BinStream.Seek(0, soFromBeginning);
  93. Result := BinStream.ReadComponent(Instance);
  94. finally
  95. BinStream.Free;
  96. end;
  97. finally
  98. StrStream.Free;
  99. end;
  100. end;
  101. 但是,所有的Class必须是注册过的,例如,如下的Form1FRM.DFM文件
  102. object Form1: TForm1
  103. Left = 222
  104. Top = 168
  105. Width = 485
  106. Height = 290
  107. Caption = 'Form1'
  108. Color = clBtnFace
  109. Font.Charset = DEFAULT_CHARSET
  110. Font.Color = clWindowText
  111. Font.Height = -11
  112. Font.Name = 'MS Sans Serif'
  113. Font.Style = []
  114. OldCreateOrder = False
  115. PixelsPerInch = 96
  116. TextHeight = 13
  117. object Panel1: TPanel
  118. Left = 0
  119. Top = 0
  120. Width = 477
  121. Height = 33
  122. Align = alTop
  123. TabOrder = 0
  124. object BitBtn1: TBitBtn
  125. Left = 4
  126. Top = 4
  127. Width = 75
  128. Height = 25
  129. Caption = 'OK'
  130. TabOrder = 0
  131. end
  132. end
  133. object Memo1: TMemo
  134. Left = 0
  135. Top = 33
  136. Width = 477
  137. Height = 230
  138. Align = alClient
  139. TabOrder = 1
  140. end
  141. end
  142. 你应该这么使用,
  143. var list:TstringList;form:TForm
  144. list.Lines.LoadFromFile(‘Form1FRM.DFM’);
  145. RegisterClass(TForm1);
  146. RegisterClass(TPanel);
  147. RegisterClass(TBitBtn);
  148. RegisterClass(TMemo);
  149. form := StringToComponent(list.Lines.Text,nil);
  150. form.ShowModal();
  151. 这样就能显示出一个窗体了。
  152. 但是这有个问题,Delphi自带的VCL控件是固定的,用RegisterClass(…)注册一遍没有问题,可TForm1不是,如果连TForm1都要注册的话,就无法达成第2点要求。我们可以变通一下,因为所有的Form都是从Tform继承的,所以,应该都可以用注册Tform来取代,因此,有了下面这样一个函数:
  153. function LoadTextForm(FileName:String):TForm;
  154. var
  155. list:TStrings;
  156. FirstLine:String;
  157. iPos : Integer;
  158. Form : TForm;
  159. begin
  160. Result := nil;
  161. if FileExists(FileName)=False then
  162. Exit;
  163. Form := TForm.Create(Application);
  164. list := TStringList.Create;
  165. try
  166. list.LoadFromFile(FileName);
  167. if list.Count=0 then
  168. Exit;
  169. FirstLine := list[0];
  170. iPos := Pos(': ',FirstLine);
  171. if iPos = 0 then //找不到': ',格式不对
  172. Exit;
  173. list[0]:=Copy(FirstLine,1,iPos)+' TForm';
  174. DeleteErrorLines(list);
  175. StringToComponent(list.Text,Form);
  176. Result := Form;
  177. except
  178. Form.Free;
  179. Result := nil;
  180. end;
  181. list.Free;
  182. end;
  183. 原理就是读入DFM文件后把窗体的类别偷换成Tform。其中还有一个函数:
  184. procedure DeleteErrorLines(list:TStrings);
  185. var
  186. i:Integer;
  187. line:String;
  188. begin
  189. if list.Count=0 then
  190. Exit;
  191. i:=0;
  192. while i<list.Count do
  193. begin
  194. line := Trim(list[i]);
  195. if Copy(line,1,2)='On' then
  196. list.Delete(i)
  197. else
  198. Inc(i);
  199. end;
  200. end;
  201. 这个函数是把凡是含有“On”开头的行删除,应为在Delphi中,所有控件的事件都是以“On”开头,删除了这样的行,就能保证StringToComponent(list.Text,Form);不出错,用以上的两个函数就可以写一个DFM窗体察看器了,到目前为止,我还没有搜到哪个人发布了DFM窗体察看器。这样我们就完成了第2个要求。
  202. 实际应用中,一个窗体几乎肯定会有事件处理函数,所以我们要达成第1个要求。我这儿提供了两个方案,各有优缺点:
  203. 方案一:
  204. 程序员在开发时,在窗体的FormCreate(…)中,用LoadTextForm(…)生成窗体文件,然后把窗体上的控件全部移到本窗体上,最后查找窗体上的控件,动态设置事件处理函数。这个方法要求有一套好的控件命名规则,而且开发比较烦琐,享受不到Delphi的IDE所见即所得,自动生成事件关联代码的好处了。不过对Form文件的制作人员限制很小,他们可以直接用Delphi来制作窗体。
  205. 方案二:
  206. 用这个函数
  207. procedure ReadForm(aFrom : TComponent;aFileName :string='');
  208. var
  209. FrmStrings : TStrings;
  210. begin
  211. RegisterClass(TPersistentClass(aFrom.ClassType));
  212. FrmStrings:=TStringlist.Create ;
  213. try
  214. if trim(aFileName)='' then FrmStrings.LoadFromFile( gsPathInfo+'/'+aFrom.Name+'.txt')
  215. else FrmStrings.LoadFromFile(aFileName);
  216. while aFrom.ComponentCount>0 do aFrom.Components[0].Destroy ;
  217. aFrom:=StringToComponent(FrmStrings.Text,aFrom)
  218. finally
  219. FrmStrings.Free;
  220. end;
  221. UnRegisterClass(TPersistentClass(aFrom.ClassType));
  222. end;
  223. 在FormCreate中调用ReadForm(self,…)。
  224. 这个方案没有第一个方案的限制,但是要求开发人员必须先完成一个完整的Form文件交给Form文件制作人员, Form文件的制作人员不能修改控件的name,不能添加或删除控件,而且必须保留开发人员给定所有事件处理函数,不能修改函数名。不过很多问题可以写一个Form编辑器来保证不出问题。
  225. 具体代码就不写了。
  226. 我想,肯定还有跟好的方案来解决动态窗体的问题,希望大家讨论。
  227. (以上代码使用Delphi6编写)
  228. 最后,我给出一个我实际项目中的有关动态窗体的函数的Unit
  229. {*****************************************
  230. 模块编号:J001DfmFunc
  231. 模块名称:Dfm窗体函数集单元
  232. 作者:刘爱军
  233. 建立日期:2002年12月2日
  234. 最后修改日期:
  235. 说明:本Unit包含了一些函数,用于根据Delphi窗体文件格式的文件动态创建窗体
  236. *******************************************}
  237. unit J001DfmFunc;
  238. interface
  239. uses
  240. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  241. Dialogs, ExtCtrls, DBCtrls, Grids, DBGrids, Buttons, StdCtrls,
  242. ComCtrls,dbcgrids, buttonComps,Tabs,QryGlobal;
  243. type
  244. TAllComponentClass = Array of TPersistentClass;
  245. procedure InitClassType(ClassArray:TAllComponentClass);
  246. function ComponentToString(Component: TComponent): string;
  247. function StringToComponent(Value: string; Instance:TComponent): TComponent;
  248. procedure RegisterAllClasses(aAllCmpClass:TAllComponentClass);
  249. procedure UnRegisterAllClasses(aAllCmpClass:TAllComponentClass);
  250. function GetObjectString(list:TStrings;BegLine:Integer=0;TypeString:string=''):string;
  251. function LoadTextForm(FileName:String):TForm;
  252. function LoadTextForm2(FileName:String;out ErrMsg:string):TForm;
  253. procedure DeleteErrorLines(list:TStrings);
  254. procedure ReadForm(aFrom : TComponent;aFileName :string='');
  255. const
  256. RegisteredCompoentClassCount = 32;//数组大小
  257. var
  258. AllCmpClass : TAllComponentClass; //存放控件类
  259. implementation
  260. //初始化可以解析的类,可随需要增加
  261. procedure InitClassType(ClassArray:TAllComponentClass);
  262. begin
  263. SetLength(AllCmpClass,RegisteredCompoentClassCount);
  264. AllCmpClass[0] := TForm;
  265. AllCmpClass[1] := TGroupBox;
  266. AllCmpClass[2] := TPanel;
  267. AllCmpClass[3] := TScrollBox;
  268. AllCmpClass[4] := TLabel;
  269. AllCmpClass[5] := TButton;
  270. AllCmpClass[6] := TBitBtn;
  271. AllCmpClass[7] := TSpeedButton;
  272. AllCmpClass[8] := TStringGrid;
  273. AllCmpClass[9] := TImage;
  274. AllCmpClass[10] := TBevel;
  275. AllCmpClass[11] := TStaticText;
  276. AllCmpClass[12] := TTabControl;
  277. AllCmpClass[13] := TPageControl;
  278. AllCmpClass[14] := TTabSheet;
  279. AllCmpClass[15] := TDBNavigator;
  280. AllCmpClass[16] := TDBText;
  281. AllCmpClass[17] := TDBEdit;
  282. AllCmpClass[18] := TDBMemo;
  283. AllCmpClass[19] := TDBGrid;
  284. AllCmpClass[20] := TDBCtrlGrid;
  285. AllCmpClass[21] := TMemo;
  286. AllCmpClass[22] := TSplitter;
  287. AllCmpClass[23] := TCheckBox;
  288. AllCmpClass[24] := TEdit;
  289. AllCmpClass[25] := TListBox;
  290. AllCmpClass[26] := TComboBox;
  291. AllCmpClass[27] := TDateTimePicker;
  292. AllCmpClass[28] := TImageButton;
  293. AllCmpClass[29] := TTabSet;
  294. AllCmpClass[30] := TTreeView;
  295. AllCmpClass[31] := TListView;
  296. end;
  297. procedure RegisterAllClasses(aAllCmpClass:TAllComponentClass);
  298. var
  299. i:Integer;
  300. begin
  301. for i:=0 to RegisteredCompoentClassCount-1 do
  302. RegisterClass(aAllCmpClass[i]);
  303. end;
  304. procedure UnRegisterAllClasses(aAllCmpClass:TAllComponentClass);
  305. var
  306. i:Integer;
  307. begin
  308. for i:=0 to RegisteredCompoentClassCount-1 do
  309. UnRegisterClass(aAllCmpClass[i]);
  310. end;
  311. function ComponentToString(Component: TComponent): string;
  312. var
  313. BinStream:TMemoryStream;
  314. StrStream: TStringStream;
  315. s: string;
  316. begin
  317. BinStream := TMemoryStream.Create;
  318. try
  319. StrStream := TStringStream.Create(s);
  320. try
  321. BinStream.WriteComponent(Component);
  322. BinStream.Seek(0, soFromBeginning);
  323. ObjectBinaryToText(BinStream, StrStream);
  324. StrStream.Seek(0, soFromBeginning);
  325. Result:= StrStream.DataString;
  326. finally
  327. StrStream.Free;
  328. end;
  329. finally
  330. BinStream.Free
  331. end;
  332. end;
  333. function StringToComponent(Value: string; Instance:TComponent): TComponent;
  334. var
  335. StrStream:TStringStream;
  336. BinStream: TMemoryStream;
  337. begin
  338. StrStream := TStringStream.Create(Value);
  339. try
  340. BinStream := TMemoryStream.Create;
  341. try
  342. ObjectTextToBinary(StrStream, BinStream);
  343. BinStream.Seek(0, soFromBeginning);
  344. Result := BinStream.ReadComponent(Instance);
  345. finally
  346. BinStream.Free;
  347. end;
  348. finally
  349. StrStream.Free;
  350. end;
  351. end;
  352. function GetObjectString(list:TStrings;BegLine:Integer=0;TypeString:string=''):string;
  353. var
  354. i,iBegCount,iEndCount:Integer;
  355. ObjString,Line,ClassStr:String;
  356. begin
  357. iBegCount:=0;
  358. iEndCount:=0;
  359. ClassStr := Trim(UpperCase(TypeString));
  360. for i:=BegLine to list.Count-1 do
  361. begin
  362. line := UpperCase(list[i]);
  363. if Pos('OBJECT',line)>0 then
  364. begin
  365. if (TypeString=''or (Pos(': '+ClassStr,line)>0then
  366. Inc(iBegCount);
  367. end
  368. else if (iBegCount>iEndCount) and (trim(line)='END'then
  369. Inc(iEndCount);
  370. if iBegCount>0 then
  371. Result := Result + list[i] + #13#10;
  372. if (iBegCount>0and (iBegCount=iEndCount) then
  373. Exit;
  374. end;
  375. end;
  376. procedure DeleteErrorLines(list:TStrings);
  377. var
  378. i:Integer;
  379. line:String;
  380. begin
  381. if list.Count=0 then
  382. Exit;
  383. i:=0;
  384. while i<list.Count do
  385. begin
  386. line := Trim(list[i]);
  387. if Copy(line,1,2)='On' then
  388. list.Delete(i)
  389. else
  390. Inc(i);
  391. end;
  392. end;
  393. procedure ReadForm(aFrom : TComponent;aFileName :string='');
  394. var
  395. FrmStrings : TStrings;
  396. begin
  397. RegisterClass(TPersistentClass(aFrom.ClassType));
  398. FrmStrings:=TStringlist.Create ;
  399. try
  400. if trim(aFileName)='' then FrmStrings.LoadFromFile( gsPathInfo+'/'+aFrom.Name+'.txt')
  401. else FrmStrings.LoadFromFile(aFileName);
  402. while aFrom.ComponentCount>0 do aFrom.Components[0].Destroy ;
  403. aFrom:=StringToComponent(FrmStrings.Text,aFrom)
  404. finally
  405. FrmStrings.Free;
  406. end;
  407. UnRegisterClass(TPersistentClass(aFrom.ClassType));
  408. end;
  409. function LoadTextForm(FileName:String):TForm;
  410. var
  411. list:TStrings;
  412. FirstLine:String;
  413. iPos : Integer;
  414. Form : TForm;
  415. begin
  416. Result := nil;
  417. if FileExists(FileName)=False then
  418. Exit;
  419. Form := TForm.Create(Application);
  420. list := TStringList.Create;
  421. try
  422. list.LoadFromFile(FileName);
  423. if list.Count=0 then
  424. Exit;
  425. FirstLine := list[0];
  426. iPos := Pos(': ',FirstLine);
  427. if iPos = 0 then //找不到': ',格式不对
  428. Exit;
  429. list[0]:=Copy(FirstLine,1,iPos)+' TForm';
  430. DeleteErrorLines(list);
  431. StringToComponent(list.Text,Form);
  432. Result := Form;
  433. except
  434. Form.Free;
  435. Result := nil;
  436. end;
  437. list.Free;
  438. end;
  439. function LoadTextForm2(FileName:String;out ErrMsg:string):TForm;
  440. var
  441. list:TStrings;
  442. FirstLine:String;
  443. iPos : Integer;
  444. Form : TForm;
  445. begin
  446. Result := nil;
  447. if FileExists(FileName)=False then
  448. begin
  449. ErrMsg := '无效的文件名!';
  450. Exit;
  451. end;
  452. Form := TForm.Create(Application);
  453. list := TStringList.Create;
  454. try
  455. list.LoadFromFile(FileName);
  456. if list.Count=0 then
  457. Exit;
  458. FirstLine := list[0];
  459. iPos := Pos(': ',FirstLine);
  460. if iPos = 0 then //找不到': ',格式不对
  461. begin
  462. ErrMsg := '找不到'': '',文件格式不对';
  463. Exit;
  464. end;
  465. list[0]:=Copy(FirstLine,1,iPos)+' TForm';
  466. DeleteErrorLines(list);
  467. StringToComponent(list.Text,Form);
  468. Result := Form;
  469. except
  470. on e:exception do
  471. begin
  472. Form.Free;
  473. Result := nil;
  474. ErrMsg := '读入文件错误:'+e.Message;
  475. end;
  476. end;
  477. list.Free;
  478. end;
  479. initialization
  480. begin
  481. InitClassType(AllCmpClass);
  482. RegisterAllClasses(AllCmpClass);
  483. end;
  484. finalization
  485. UnRegisterAllClasses(AllCmpClass);
  486. end
已标记关键词 清除标记
相关推荐
Delphi 深度编程及其项目应用开发》 作 者: 李存斌 汪兵 编著 丛书名: 万水软件项目应用与实例开发丛书 出版社: 中国水利水电出版社 出 版: 2002-9----------简 介 本书是在总结作者多年Delphi开发经验的基础上编著而成。 全书分为基础篇和应用篇。基础篇结合示例论述了Delphi的深度编程技术,其中包括9章,分别为:理解Windows消息、进程与线程、自定义组件的编写、文件操作、创建DLL应用程序、两层数据库应用程序、多层数据库应用程序、Socket编程、串口编程;应用篇结合物资管理信息系统项目应用开发技术和经验,详细阐述了一般管理信息系统软件通用模块的开发,其中包括10章,分别为:物资管理信息系统概述及其总体框架设计、物资管理信息系统后台数据库设计、应用服务器的实现、客户端应用程序的设计、动态连接应用服务器的实现、通用权限管理模块的设计、通用查询组件和报表模块的制作、通用基础数据维护模块的设计、物资管理信息系统业务操作模块的设计、综合查询模块的设计。读者在具有一定Delphi知识的基础上,通过本书的学习,可快速提高Delphi的编程能力和实际开发水平。 本书适用于具有初步编程能力的读者,也可作为高校高年级学生毕业设计的指导书。中国水利水电出版社网站(www.waterpub.com.cn)上包括了书中示例和较为完整的物资管理信息系统的源代码文件,为读者的学习提供方便,同时也为相关软件开发人员的实际应用开发提供捷径和参考。 ----------目 录 丛书前言 前言 基础篇:Delphi深度编程技术 第1章 理解Windows消息 1.1 消息概述 1.2 Windows消息工作机理 1.3 Delphi的VCL消息系统处理原理 1.4 发送消息 1.4.1 Perform() 1.4.2 SendMessage()和PostNessage() 1.4.3 消息的发送 1.5 消息处理 1.6 消息过滤 第2章 进程与线程 2.1 进程与线程 2.1.1 进程概述 2.1.2 进程的直接创建 2.1.3 列举系统打开的进程 2.1.4 线程概述 2.2 进程间通讯(IPC) 2.2.1 利用WM_COPYDATA消息实现进程间通讯 2.2.2 利用内存映射文件实现进程间通讯 2.3 TThread对象 2.3.1 线程的创建 2.3.2 线程的挂起和恢复 2.3.3 线程的终止 2.3.4 与VCL同步 2.4 线程同步 2.4.1 临界区(CriticalSection) 2.4.2 互斥(Mutex) 2.4.3 信号量(Semaphore) 2.5 进程的优先级别 2.5.1 进程的优先级类 2.5.2 相对优先级 2.6 后台多线程数据查询实例 第3章 自定义组件的编写 3.1 组件的基本概念 3.1.1 属性 3.1.2 方法 3.1.3 事件 3.1.4 拥有关系 3.1.5 父子关系 3.2 组件创建实例 3.3 组件的高级技术--属性编辑器和组件编辑器 3.3.1 组件的属性编辑器 3.3.2 组件的组件编辑器 3.3.3 带有属性编辑器和组件编辑器的自定义组件实例 3.4 创建对话框组件 第4章 文件操作 4.1 文件的基本操作 4.1.1 文本文件 4.1.2 有类型文件 4.1.3 INI文件 4.1.4 无类型文件 4.1.5 文件的复制 4.2 内存映射文件 4.2.1 内存映射文件的应甩 4.2.2 映射文件的使用 4.3 内存映射文件的应用 第5章 创建DLL应用程序 5.1 DLL概述 5.2 DLL的创建 5.2.1 DLL项目文件 5.2.2 Exports关键字的使用 5.2.3 DLL中的变量 5.2.4 DLL实例:动态DLL中的窗体 5.3 DLL的调用 5.3.1 静态调用 5.3.2 动态调用 5.4 DLL的入口函数和出口函数 5.4.1 进程/线程的初始化和例程的终止 5.4.2 DLL入口/出口示例 5.5 利用DLL创建插件程序 5.5.1 插件程序的设计思想 5.5.2 插件应用程序的创建 5.5.3 创建调用插件程序的主程序 第6章 两层数据库应用程序 6.1 关系型数据库 6.1.1 关系型数据库概述 6.1.2 结构化查询语言(SQL) 6.2 数据库的连接 6.2.1 基于BDE的数据库连接 6.2.2 基于0DBC的数据库连接 6.2.3 基于AD0的数据库连接技术 6.3 TSession元件 6.4 1 DahBase组件 6.4.1 TDataBase组件的使用 6.4.2 用配置文件动态设置BDE 6.5 数据访问组件 6.5.1 TTable组件 6.5.2 TQuery组件 6.5.3 TStoredProc过程 6.6 数据感知组件 6.7 事务 第7章 多层数据库应用程序 7.1 一个简单的多层应用系统 7.1.1 服务器端应用程序的建立 7.1.2 客户端应用程序的建立 7.2 多层应用系统处理数据的原理 7.2.1 多层应用系统的结构 7.2.2 存取数据的运作原理 7.2.3 更新数据的运作原理 7.3 容错处理和负载平衡 7.4 Active Form 第8章 Socket编程 8.1 WinSock基础 8.1.1 TCP、UDP和IP协议 8.1.2 套接字(Socket) 8.1.3 客户/服务器模式 8.1.4 面向连接的协议套接字的调用 8.1.5 面向无连接协议的套接字的调用 8.2 利用Winsock API实现Socket编程 8.2.1 常用WinSockAPI函数 8.2.2 利用WinSockAPI实现Socket编程 8.3 利用组件实现Socket编程 8.3.1 TClientSocket组件 8.3.2 TServerSocket组件 8.3.3 远程抓屏示例 8.4 通讯中间件的制作 8.4.1 磁盘队列的实现 8.4.2 客户端和服务器端发送接收磁盘队列数据的套接字的建立 8.4.3 中间件的简单应用 第9章 串口编程 9.1 串口通信的基础知识 9.1.1 同步通信和异步通信 9.1.2 波特率和数据传输率 9.2 串口通信API 9.2.1 DCB数据结构 9.2.2 与串口通信相关的函数 9.3 利用API函数创建串口通信示例 9.3.1 发送数据部分设计(向串口写数据) 9.3.2 数据部分设计(从串口读数据) 9.3.3 程序的具体设计和实现 9.4 利用SPC0MM组件实现串口通信编程 9.4.1 SPCOMM组件的安装 9.4.2 SPCOMM组件的属性、方法和事件 9.4.3 利用SPCOMM通讯组件实现串口通讯的实例 应用篇:物资管理信息系统项目应用开发 第10章 物资管理信息系统概述及其总体框架设计 10.1 系统总体结构设计 10.2 物资管理信息系统需求定义和业务流程图 10.2.1 仓储管理 10.2.2 计划管理 10.2.3 合同管理 10.2.4 物资管理系统的业务流程 第11章 物资管理信息系统后台数据库设计 11.1 关系型数据库概述 11.1.1 关系型数据库 11.1.2 物资管理信息系统数据库的建立 11.2 物资管理信息系统数据结构的设计 11.2.1 权限管理数据结构的设计 11.2.2 仓储管理数据结构的设计 11.2.3 计划管理数据结构的设计 11.2.4 合同管理数据结构的设计 11.2.5 基础设置数据结构的设计 第12章 应用服务器的实现 12.1 创建应用服务器的实例 12.2 状态区编程 12.3 动态数据库的连接 12.4 远程数据模块的建立 第13章 客户端应用程序的设计 13.1 客户端应用程序系统流程和系统功能 13.1.1 系统流程 13.1.2 系统功能 13.2 构建客户端应用程序框架 第14章 动态连接应用服务器的实现 第15章 通用权限管理模块的设计 15.1 系统登录的设计 15.2 权限设计表中数据的维护 第16章 通用查询和报表组件的制作 16.1 通用查询组件的创建 16.2 通用报表模块的制作 第17章 通用基础数据维护模块的设计 17.1 界面设计 17.2 代码实现 17.2.1 以目录树的格式显示部门档案数据 17.2.2 利用目录树导航数据 17.2.3 利用目录树操作数据 17.2.4 按表格的标题排序 17.2.5 打印部门档案 第18章 物资管理信息系统业务操作模块的设计 18.1 数据表的设置 18.2 收料单据主表显示区 18.3 具体的材料明细表显示区 18.4 数据操作区 第19章 综台查询模块的设计 19.1 数据源的设置 19.2 窗体样式设计 19.3 代码实现 19.3.1 查询数据 19.3.2 打印数据 19.3.3 全部浏览----------
<p> <strong><span style="font-size:20px;color:#FF0000;">本课程主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者</span></strong> </p> <p> <span style="color:#FF0000;"><strong><span style="font-size:18px;">1. 包含:<span style="color:#FFFF00;background-color:#FF0000;">项目源码、</span><span style="color:#FFFF00;background-color:#FF0000;">项目文档、数据库脚本、软件工具</span>等所有资料</span></strong></span> </p> <p> <span style="color:#FF0000;"><strong><span style="font-size:18px;">2. 手把手的带你从零开始部署运行本套系统</span></strong></span> </p> <p> <span style="color:#FF0000;"><strong><span style="font-size:18px;">3. 该项目附带的源码资料可作为毕设使用</span></strong></span> </p> <p> <span style="color:#FF0000;"><strong><span style="font-size:18px;">4. 提供技术答疑和远程协助指导</span></strong></span><strong><span style="font-size:18px;"></span></strong> </p> <p> <br /> </p> <p> <span style="font-size:18px;"><strong>项目运行截图:</strong></span> </p> <p> <strong><span style="font-size:18px;">1)系统登陆界面</span></strong> </p> <p> <strong><span style="font-size:18px;"><img src="https://img-bss.csdn.net/202002241015433522.png" alt="" /><br /> </span></strong> </p> <p> <strong><span style="font-size:18px;"><strong><span style="font-size:18px;">2)学生模块</span></strong></span></strong> </p> <p> <strong><span style="font-size:18px;"><img src="https://img-bss.csdn.net/202002241015575966.png" alt="" /></span></strong> </p> <p> <strong><span style="font-size:18px;"><strong><span style="font-size:18px;">3)教师模块</span></strong></span></strong> </p> <p> <strong><span style="font-size:18px;"><img src="https://img-bss.csdn.net/202002241016127898.png" alt="" /></span></strong> </p> <p> <strong><span style="font-size:18px;"><strong><span style="font-size:18px;">4)系统管理员</span></strong></span></strong> </p> <p> <strong><span style="font-size:18px;"><img src="https://img-bss.csdn.net/202002241016281177.png" alt="" /></span></strong> </p> <p> <strong><span style="font-size:18px;"><img src="https://img-bss.csdn.net/202002241016369884.png" alt="" /></span></strong> </p> <p> <strong><span style="font-size:18px;"><br /> </span></strong> </p> <p> <strong><span style="font-size:18px;"><strong><span style="font-size:18px;">更多Java毕设项目请关注我的毕设系列课程 <a href="https://edu.csdn.net/lecturer/2104">https://edu.csdn.net/lecturer/2104</a></span></strong></span></strong> </p> <p> <strong><span style="font-size:18px;"><br /> </span></strong> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页