UtilMethods.pas 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  1. unit UtilMethods;
  2. interface
  3. uses
  4. Controls, ZhAPI, ActnList, ZjIDTree, DB, ZjGridDBA, ZjGrid, Windows, Messages,
  5. sdDB, VCLZip, VCLUnZip, Dialogs, Forms, ShlObj, Classes, StrUtils, Math, ADODB,
  6. IdGlobal;
  7. type
  8. TRoundMode = (rmNearest, rmUp, rmDown);
  9. TBookmarkRefreshEvent = procedure (AExpandFrame: Boolean) of object;
  10. {RoundTo}
  11. function GetCompareDigitValue(ADigit: Integer): Double;
  12. function QuantityRoundTo(AValue: Double): Double;
  13. function PriceRoundTo(AValue: Double): Double;
  14. function TotalPriceRoundTo(AValue: Double): Double;
  15. function CommonRoundTo(AValue: Double; ADigit: Integer; RoundMode: TRoundMode = rmNearest): Double;
  16. {Interface Control}
  17. procedure AlignControl(AControl, AParent: TWinControl; AAlign: TAlign);
  18. procedure SetDxBtnAction(AAction: TAction; ADxBtn: TObject);
  19. {DataBase Rela}
  20. function GetsdDataSetNewID(ADataSet: TsdDataSet; const AIndex: string): Integer;
  21. procedure ExecuteSql(AConnection: TADOConnection; const ASql: string);
  22. function QueryData(AConnection: TADOConnection; const ASql: string): TADOQuery;
  23. {Message}
  24. procedure WarningMessage(const AMsg: string; AHandle: THandle = 0);
  25. procedure ErrorMessage(const AMsg: string; AHandle: THandle = 0);
  26. function QuestMessage(const AMsg: string; AHandle: THandle = 0): Boolean;
  27. function QuestMessageYesNo(const AMsg: string; AHandle: THandle = 0): Boolean;
  28. procedure TipMessage(const AMsg: string; AHandle: THandle = 0);
  29. procedure DataSetErrorMessage(var Allow: Boolean; const AMsg: string);
  30. {Get Common Path}
  31. function GetAppFilePath: string;
  32. function GetMyProjectsFilePath: string;
  33. function GetEmptyDataBaseFileName: string;
  34. function GetTemplateBillsFileName: string;
  35. function GetTemplateXlsFileName: string;
  36. function GetBackupFilePath: string;
  37. function GetReportTemplatePath: string;
  38. function GetAppTempPath: string;
  39. {Select & Save File Choose}
  40. function GetFilter(AExt: string): string;
  41. function SelectFile(var AFileName: string; const AExt: string): Boolean;
  42. function SelectFiles(AFiles: TStrings; const AExt: string): Boolean;
  43. function SaveFile(var FileName: string; const AExt: string): Boolean;
  44. function SaveExcelFile(var FileName: string): Boolean;
  45. function SelectOutputDirectory(const ATitle: string; var ADirectory: string;
  46. AParentHandle: THandle = 0; AHasNewFolderBtn: Boolean = True): Boolean;
  47. function FixPathByAppPath(AFileName: string): string;
  48. function BrowseFolder(var APath: string; const ATitle: string;
  49. AParentHandle: THandle; AHasNewFolderBtn: Boolean = True): Boolean;
  50. {CheckStrings}
  51. function CheckPeg(const AStr: string): Boolean;
  52. function CheckValidPassword(APassword: string): Boolean;
  53. function ValidInteger(var AKey: Char): Boolean;
  54. {MergeStrings}
  55. function MergeRelaBGL(const ABGLCode1, ABGLCode2: string): string;
  56. procedure MergeRelaBGLAndNum(var ABGLCode1, ABGLNum1: string; const ABGLCode2, ABGLNum2: string);
  57. {CodeTransform}
  58. function B_CodeToIndexCode(const AB_Code: string): string;
  59. function ChinessNum(const ADigitNum: Integer): string;
  60. function Num2Peg(ANum: Double): string;
  61. {Compare Code}
  62. //function CompareCodeWithChar(const ACode1, ACode2: string): Integer;
  63. {Tree Relative}
  64. function CreateTree: TZjIDTree;
  65. procedure DisConnectTree(ATree: TZjIDTree);
  66. procedure ConnectTree(ATree: TZjIDTree; ADataset: TDataSet);
  67. procedure InitGridHead(AGridDBA: TZjGridDBA; AGrid: TZJGrid);
  68. {Generate Name/Directory/Path}
  69. function GetTempFileDir: string;
  70. function GetTempFilePath: string;
  71. function GetTempName(ALength: Integer = 8): string;
  72. function GetTempFileName: string; overload;
  73. function GetTempFileName(const APath, AExt: string): string; overload;
  74. function GenerateTempFolder(AGeneratePath: string): string;
  75. function GetNewGUIDFileName(const AGeneratePath: string): string;
  76. {Progress bar Control}
  77. procedure UpdateSysProgress(APosition: Integer; const AHint: string);
  78. procedure UpdateProgress(APosition: Integer; const AHint: string);
  79. procedure DisableSysProgress;
  80. procedure EnableSysProgress;
  81. {Interface RePaint Control}
  82. procedure BeginUpdateWindow(AHandle: THandle);
  83. procedure EndUpdateWindow(AHandle: THandle);
  84. {Zip}
  85. procedure ZipFolder(AFileFolder, AFileName: string; ACheckMode: Integer = 0);
  86. function UnZipFile(AFileName, AFileFolder: string): Boolean;
  87. {Copy By Stream}
  88. procedure CopyFileByStream(const ASourceFile, ADestFile: string);
  89. procedure AppendTestLog(const AFileName, ALog: string);
  90. // Add by chenshilong, 2014-04-11
  91. function GetVersion(APartCount: Integer = 4): string;
  92. function ExtractFileNameWithoutExt(const AFileName: string): string;
  93. function ShortText(AText: string; AWidth: Integer): string; // 文本缩略显示
  94. function CustomWidthText(AText: string; AWidth: Integer): string;
  95. function ReplaceCharsForJson(AText: string): string; // 替换Json文本中的特殊字符
  96. function RecoverCharsFromJson(AText: string): string; // 下载得到的Json文本恢复成用户需要的文本
  97. procedure FindFiles(APath, AExtName: string; AFileList: TStrings);
  98. function DeleteFolder(const FolderStr: string): Boolean;
  99. function HasExt(const AFileName: string): Boolean;
  100. function CopyFolder(const SrcFolder, DstFolder: string): Boolean;
  101. function FileCount(APath: string): Integer;
  102. implementation
  103. uses
  104. SysUtils, dxBar, MainFrm, ConstUnit, Globals, StdCtrls, ShellAPI;
  105. var
  106. SysProgressDisabled: Boolean;
  107. {RoundTo}
  108. function InnerRoundTo(const AValue: Extended; const ADigit: Integer; RoundMode: TRoundMode): Extended;
  109. var
  110. LFactor, Offset, HFactor: Extended;
  111. begin
  112. LFactor := IntPower(10, ADigit);
  113. HFactor := IntPower(10, abs(ADigit));
  114. Result := AValue;
  115. case RoundMode of
  116. rmNearest:
  117. begin
  118. if AValue >= 0 then
  119. Offset := 0.5
  120. else
  121. Offset := -0.5;
  122. Result := Trunc((AValue * HFactor) + Offset) * LFactor;
  123. end;
  124. rmUP:
  125. begin
  126. if Frac(AValue / LFactor) > 0 then
  127. Result := Trunc(AValue * HFactor + 1) * LFactor
  128. else
  129. Result := Trunc(AValue * HFactor) * LFactor;
  130. end;
  131. rmDown:
  132. begin
  133. Result := Trunc(AValue * HFactor) * LFactor;
  134. end;
  135. end;
  136. end;
  137. function GetCompareDigitValue(ADigit: Integer): Double;
  138. begin
  139. if ADigit < 0 then
  140. Result := IntPower(10, ADigit - 1)
  141. else
  142. Result := 0.1;
  143. end;
  144. function QuantityRoundTo(AValue: Double): Double;
  145. begin
  146. if Assigned(OpenProjectManager.CurProjectData) then
  147. Result := CommonRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.QuantityDigit)
  148. else
  149. Result := CommonRoundTo(AValue, iQuantityDigit);
  150. end;
  151. function PriceRoundTo(AValue: Double): Double;
  152. begin
  153. if Assigned(OpenProjectManager.CurProjectData) then
  154. Result := CommonRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.PriceDigit)
  155. else
  156. Result := CommonRoundTo(AValue, iPriceDigit);
  157. end;
  158. function TotalPriceRoundTo(AValue: Double): Double;
  159. begin
  160. if Assigned(OpenProjectManager.CurProjectData) then
  161. Result := CommonRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.TotalPriceDigit)
  162. else
  163. Result := CommonRoundTo(AValue, iTotalPriceDigit);
  164. end;
  165. function GetTrueDigit(AValue: Double): Integer;
  166. const
  167. sFormat12 = '0.############';
  168. var
  169. sValue, sDigitValue: string;
  170. iPointPos: Integer;
  171. begin
  172. sValue := FormatFloat(sFormat12, AValue);
  173. iPointPos := Pos('.', sValue);
  174. Result := Min(0, -(Length(sValue) - iPointPos));
  175. end;
  176. function CommonRoundTo(AValue: Double; ADigit: Integer; RoundMode: TRoundMode = rmNearest): Double;
  177. var
  178. X: Double;
  179. P: Pointer;
  180. I: Integer;
  181. Buf: array [0..7] of Byte;
  182. begin
  183. P := @AValue;
  184. CopyMemory(@Buf[0], P, SizeOf(AValue));
  185. // 进位处理,从后往前,如果当前byte为$FF,则往前一byte进1
  186. // 注意到尾数开始的位置停止
  187. // 这里说的前后是二进制串,实际存储前后相反
  188. for I := 0 to 6 do
  189. if (I < 6) and (Buf[I] = $FF) then
  190. Buf[I] := 0
  191. else
  192. begin
  193. Buf[I] := Buf[I] + 1;
  194. Break;
  195. end;
  196. P := @X;
  197. CopyMemory(P, @Buf[0], SizeOf(X));
  198. if (ADigit < 0) and (ADigit < GetTrueDigit(AValue)) then
  199. Result := AValue
  200. else
  201. Result := InnerRoundTo(X, ADigit, RoundMode);
  202. end;
  203. {Interface Control}
  204. procedure AlignControl(AControl, AParent: TWinControl; AAlign: TAlign);
  205. begin
  206. if Assigned(AControl) then
  207. begin
  208. if Assigned(AControl.Parent) then
  209. AControl.Parent.RemoveControl(AControl);
  210. AControl.Parent := AParent;
  211. AControl.Align := AAlign;
  212. end;
  213. end;
  214. procedure SetDxBtnAction(AAction: TAction; ADxBtn: TObject);
  215. begin
  216. if Assigned(ADxBtn) then
  217. if ADxBtn is TdxBarButton then
  218. TdxBarButton(ADxBtn).Action := AAction;
  219. end;
  220. {DataBase Rela}
  221. function GetsdDataSetNewID(ADataSet: TsdDataSet; const AIndex: string): Integer;
  222. var
  223. idx: TsdIndex;
  224. begin
  225. idx := ADataSet.FindIndex(AIndex);
  226. if idx.RecordCount > 0 then
  227. Result := idx.Records[idx.RecordCount - 1].ValueByName('ID').AsInteger + 1
  228. else
  229. Result := 1;
  230. end;
  231. procedure ExecuteSql(AConnection: TADOConnection; const ASql: string);
  232. var
  233. vQuery: TADOQuery;
  234. begin
  235. vQuery := TADOQuery.Create(nil);
  236. try
  237. vQuery.Connection := AConnection;
  238. vQuery.SQL.Add(ASql);
  239. vQuery.ExecSQL;
  240. finally
  241. vQuery.Free;
  242. end;
  243. end;
  244. function QueryData(AConnection: TADOConnection; const ASql: string): TADOQuery;
  245. begin
  246. Result := TADOQuery.Create(nil);
  247. Result.Connection := AConnection;
  248. Result.SQL.Clear;
  249. Result.SQL.Add(ASql);
  250. Result.Open;
  251. end;
  252. {Message}
  253. function GetValidHandle(AHandle: THandle = 0): THandle;
  254. begin
  255. if AHandle = 0 then
  256. begin
  257. if (Screen.ActiveForm <> nil) and (Screen.ActiveForm.HandleAllocated) then
  258. Result := Screen.ActiveForm.Handle
  259. else
  260. Result := Application.Handle;
  261. end
  262. else
  263. Result := AHandle;
  264. end;
  265. procedure WarningMessage(const AMsg: string; AHandle: THandle = 0);
  266. begin
  267. MessageBox(GetValidHandle(AHandle), PChar(AMsg), PChar('警告'), MB_OK or MB_ICONWARNING);
  268. end;
  269. procedure ErrorMessage(const AMsg: string; AHandle: THandle = 0);
  270. begin
  271. MessageBox(GetValidHandle(AHandle), PChar(AMsg), PChar('错误'), MB_OK or MB_ICONERROR);
  272. end;
  273. function QuestMessage(const AMsg: string; AHandle: THandle = 0): Boolean;
  274. begin
  275. Result := MessageBox(GetValidHandle(AHandle), PChar(AMsg), PChar('询问'), MB_OKCANCEL or MB_ICONQUESTION) = IDOK;
  276. end;
  277. function QuestMessageYesNo(const AMsg: string; AHandle: THandle = 0): Boolean;
  278. begin
  279. Result := MessageBox(GetValidHandle(AHandle), PChar(AMsg), PChar('询问'), MB_YESNO or MB_ICONQUESTION) = IDYes;
  280. end;
  281. procedure TipMessage(const AMsg: string; AHandle: THandle = 0);
  282. begin
  283. MessageBox(GetValidHandle(AHandle), PChar(AMsg), PChar('提示'), MB_OK or MB_ICONINFORMATION);
  284. end;
  285. procedure DataSetErrorMessage(var Allow: Boolean; const AMsg: string);
  286. begin
  287. Allow := False;
  288. ErrorMessage(AMsg);
  289. end;
  290. {Get Common Path}
  291. function GetAppFilePath: string;
  292. begin
  293. Result := ExtractFilePath(ParamStr(0));
  294. end;
  295. function GetMyProjectsFilePath: string;
  296. begin
  297. Result := GetAppFilePath + '我的项目\';
  298. end;
  299. function GetEmptyDataBaseFileName: string;
  300. begin
  301. Result := GetAppFilePath + 'Data\Base.dat';
  302. end;
  303. function GetTemplateBillsFileName: string;
  304. begin
  305. Result := GetAppFilePath + 'Data\Template.xls';
  306. end;
  307. function GetTemplateXlsFileName: string;
  308. begin
  309. Result := GetAppFilePath + 'Data\Basic.xls';
  310. end;
  311. function GetBackupFilePath: string;
  312. begin
  313. Result := GetAppFilePath + 'TenderBackup\';
  314. end;
  315. function GetReportTemplatePath: string;
  316. begin
  317. Result := GetAppFilePath + 'ReportTemplates\';
  318. end;
  319. function GetAppTempPath: string;
  320. begin
  321. Result := GetAppFilePath + 'Temp\';
  322. if DirectoryExists(Result) then
  323. CreateDirectoryInDeep(Result);
  324. end;
  325. {Select & Save File Choose}
  326. function GetFilter(AExt: string): string;
  327. begin
  328. if AExt = '' then
  329. Result := '所有文件(*.*)|*.*'
  330. else
  331. begin
  332. if AExt[1] <> '.' then
  333. AExt := '.' + AExt;
  334. Result := Format('(*%s)|*%s', [AExt, AExt]);
  335. end;
  336. end;
  337. function SelectFile(var AFileName: string; const AExt: string): Boolean;
  338. var
  339. odFile: TOpenDialog;
  340. begin
  341. odFile := TOpenDialog.Create(nil);
  342. try
  343. odFile.Filter := GetFilter(AExt);
  344. if odFile.Execute then
  345. begin
  346. Application.ProcessMessages;
  347. AFileName := odFile.FileName;
  348. Result := True;
  349. end
  350. else
  351. Result := False;
  352. finally
  353. odFile.Free;
  354. end;
  355. end;
  356. function SelectFiles(AFiles: TStrings; const AExt: string): Boolean;
  357. var
  358. odFile: TOpenDialog;
  359. begin
  360. odFile := TOpenDialog.Create(nil);
  361. try
  362. odFile.Options := odFile.Options + [ofAllowMultiSelect];
  363. odFile.Filter := GetFilter(AExt);
  364. if odFile.Execute then
  365. begin
  366. Application.ProcessMessages;
  367. AFiles.Assign(odFile.Files);
  368. Result := True;
  369. end
  370. else
  371. Result := False;
  372. finally
  373. odFile.Free;
  374. end;
  375. end;
  376. function SaveFile(var FileName: string; const AExt: string): Boolean;
  377. var
  378. sdFile: TSaveDialog;
  379. begin
  380. sdFile := TSaveDialog.Create(nil);
  381. try
  382. sdFile.FileName := FileName;
  383. sdFile.DefaultExt := AExt;
  384. sdFile.Filter := GetFilter(AExt);
  385. Result := sdFile.Execute;
  386. if Result then
  387. FileName := sdFile.FileName;
  388. Application.ProcessMessages;
  389. finally
  390. sdFile.Free;
  391. end;
  392. end;
  393. function SaveExcelFile(var FileName: string): Boolean;
  394. function CheckFileName(AFileName: string; AExt: string): string;
  395. begin
  396. if SameText(ExtractFileExt(AFileName), AExt) then
  397. Result := AFileName
  398. else
  399. Result := ExtractFilePath(AFileName) + ExtractFileName(AFileName) + AExt;
  400. end;
  401. var
  402. sdFile: TSaveDialog;
  403. begin
  404. sdFile := TSaveDialog.Create(nil);
  405. try
  406. sdFile.FileName := FileName;
  407. sdFile.Filter := 'Excel文件(*.xls)|*.xls;|Excel文件(*.xlsx)|*.xlsx;';
  408. Result := sdFile.Execute;
  409. if Result then
  410. begin
  411. case sdFile.FilterIndex of
  412. 1: FileName := CheckFileName(sdFile.FileName, '.xls');
  413. 2: FileName := CheckFileName(sdFile.FileName, '.xlsx');
  414. end;
  415. end;
  416. (*
  417. if sdFile.FilterIndex = 1 then
  418. if not SameText(ExtractFileExt(sdFile.FileName), sdFile.DefaultExt) then
  419. FileName := ExtractFileName(sdFile.FileName) + sdFile.DefaultExt
  420. else
  421. FileName := sdFile.FileName;
  422. *)
  423. finally
  424. sdFile.Free;
  425. end;
  426. end;
  427. function SelectOutputDirectory(const ATitle: string; var ADirectory: string;
  428. AParentHandle: THandle; AHasNewFolderBtn: Boolean): Boolean;
  429. var
  430. pID: PItemIDList;
  431. bInfo: TBrowseInfo;
  432. AHandle: THandle;
  433. PStr: array[0..1023] of Char;
  434. sPath: string;
  435. function BFCallBack(Hwnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer; stdcall;
  436. begin
  437. if uMsg = BFFM_INITIALIZED then
  438. begin
  439. SendMessage(Hwnd, BFFM_SETSELECTION, 1, lpData);
  440. end;
  441. Result := 0;
  442. end;
  443. begin
  444. Result := False;
  445. if AParentHandle = 0 then
  446. AHandle := Screen.ActiveForm.Handle
  447. else
  448. AHandle := AParentHandle;
  449. if ADirectory = '' then
  450. sPath := GetAppFilePath
  451. else
  452. sPath := ADirectory;
  453. with bInfo do
  454. begin
  455. hwndOwner := AParentHandle;
  456. iImage := 0;
  457. lParam := Integer(PChar(sPath));
  458. lpszTitle := PChar(ATitle);
  459. pidlRoot := nil;
  460. pszDisplayName := nil;
  461. if AHasNewFolderBtn then
  462. ulFlags := BIF_RETURNONLYFSDIRS or BIF_USENEWUI
  463. else
  464. ulFlags := BIF_RETURNONLYFSDIRS;
  465. lpfn := @BFCallBack;
  466. end;
  467. pID := SHBrowseForFolder(bInfo);
  468. if pID <> nil then
  469. begin
  470. SHGetPathFromIDList(pID, PStr);
  471. ADirectory := StrPas(PStr);
  472. if (ADirectory <> '') and (ADirectory[Length(ADirectory)] <> '\') then
  473. ADirectory := ADirectory + '\';
  474. Result := True;
  475. end;
  476. end;
  477. function FixPathByAppPath(AFileName: string): string;
  478. begin
  479. Result := AFileName;
  480. if AnsiPos(':\', Result) = 0 then
  481. begin
  482. if (Result <> '') and (Result[1] = '\') then
  483. Delete(Result, 1, 1);
  484. Result := ExtractFilePath(Application.ExeName) + Result;
  485. end;
  486. end;
  487. var
  488. PathStr: string;
  489. function BrowseFolder(var APath: string; const ATitle: string; AParentHandle: THandle;
  490. AHasNewFolderBtn: Boolean): Boolean;
  491. function BFCallBackFunc(hwnd: HWND; uMsg: UINT; lParam: LPARAM; lpData: LPARAM): Integer; stdcall;
  492. begin
  493. Result := 0;
  494. case uMsg of
  495. BFFM_INITIALIZED : // 初始化设置目录。
  496. begin
  497. SendMessage(Hwnd,BFFM_SETSELECTION,-1,Integer(PathStr));
  498. end;
  499. end;
  500. end;
  501. var
  502. pID: PItemIDList;
  503. bInfo: TBrowseInfo;
  504. PStr: array[0..1023] of Char;
  505. sPath: string;
  506. Hdl: THandle;
  507. begin
  508. Result := False;
  509. PathStr := '';
  510. if AParentHandle = 0 then
  511. Hdl := Screen.ActiveForm.Handle
  512. else
  513. Hdl := AParentHandle;
  514. sPath := FixPathByAppPath(APath);
  515. if DirectoryExists(sPath) then
  516. PathStr := sPath;
  517. bInfo.hwndOwner := Hdl;
  518. bInfo.iImage := 0;
  519. bInfo.lParam := 0;
  520. bInfo.lpszTitle := PChar(ATitle);
  521. bInfo.pidlRoot := nil;
  522. bInfo.pszDisplayName := nil;
  523. if (not AHasNewFolderBtn) then
  524. bInfo.ulFlags := BIF_RETURNONLYFSDIRS
  525. else
  526. bInfo.ulFlags := BIF_RETURNONLYFSDIRS or BIF_USENEWUI;
  527. bInfo.lpfn := @BFCallBackFunc;
  528. pID := SHBrowseForFolder(bInfo);
  529. if pID <> nil then
  530. begin
  531. SHGetPathFromIDList(pID,pStr);
  532. APath := StrPas(pStr);
  533. if (APath <> '') and (APath[Length(APath)] <> '\') then
  534. APath := APath + '\';
  535. Result := True;
  536. end;
  537. end;
  538. {CheckStrings}
  539. function CheckPeg(const AStr: string): Boolean;
  540. function GetPosition(const AName, AStr, AStrSpare: string): Integer;
  541. begin
  542. Result := Pos(AStr, AName);
  543. if Result = 0 then
  544. Result := Pos(AStrSpare, AName);
  545. end;
  546. var
  547. iPosK, iPosPlus: Integer;
  548. fNum: Double;
  549. begin
  550. Result := False;
  551. iPosK := GetPosition(AStr, 'K', 'k');
  552. iPosPlus := GetPosition(AStr, '+', '+');
  553. if (iPosK = 0) or (iPosPlus = 0) or (iPosPlus < iPosK) then Exit;
  554. Result := TryStrToFloat(Copy(AStr, iPosK + 1, iPosPlus - iPosK - 1), fNum);
  555. end;
  556. function CheckValidPassword(APassword: string): Boolean;
  557. var
  558. iIndex, iLength: Integer;
  559. begin
  560. Result := True;
  561. if APassword = '' then Exit;
  562. iIndex := 1;
  563. iLength := Length(APassword);
  564. Result := (iLength >= 6) and (iLength <= 16);
  565. while Result and (iIndex < iLength) do
  566. begin
  567. Result := APassword[iIndex] in ['A'..'Z', 'a'..'z', '0'..'9'];
  568. Inc(iIndex);
  569. end;
  570. end;
  571. function ValidInteger(var AKey: Char): Boolean;
  572. begin
  573. if AKey in ['+', '-', '0'..'9', #8, #13, #35, #36,
  574. #37, #38, #39, #40, #46] then
  575. begin
  576. Result := True;
  577. end
  578. else
  579. begin
  580. AKey := #0;
  581. Result := False;
  582. end;
  583. end;
  584. {MergeStrings}
  585. function MergeRelaBGL(const ABGLCode1, ABGLCode2: string): string;
  586. var
  587. sgs1, sgs2: TStrings;
  588. i1, i2: Integer;
  589. bExist: Boolean;
  590. begin
  591. Result := ABGLCode1;
  592. sgs1 := TStringList.Create;
  593. sgs2 := TStringList.Create;
  594. try
  595. sgs1.Delimiter := ';';
  596. sgs2.Delimiter := ';';
  597. sgs1.DelimitedText := ABGLCode1;
  598. sgs2.DelimitedText := ABGLCode2;
  599. for i2 := 0 to sgs2.Count - 1 do
  600. begin
  601. bExist := False;
  602. for i1 := 0 to sgs1.Count - 1 do
  603. if SameText(sgs2[i2], sgs1[i1]) then
  604. begin
  605. bExist := True;
  606. Break;
  607. end;
  608. if not bExist then
  609. sgs1.Add(sgs2[i2]);
  610. end;
  611. Result := sgs1.DelimitedText;
  612. finally
  613. sgs1.Free;
  614. sgs2.Free;
  615. end;
  616. end;
  617. procedure MergeRelaBGLAndNum(var ABGLCode1, ABGLNum1: string; const ABGLCode2, ABGLNum2: string);
  618. var
  619. sgsC1, sgsC2, sgsN1, sgsN2: TStrings;
  620. i1, i2: Integer;
  621. bExist: Boolean;
  622. begin
  623. sgsC1 := TStringList.Create;
  624. sgsC2 := TStringList.Create;
  625. sgsN1 := TStringList.Create;
  626. sgsN2 := TStringList.Create;
  627. try
  628. sgsC1.Delimiter := ';';
  629. sgsC2.Delimiter := ';';
  630. sgsC1.DelimitedText := ABGLCode1;
  631. sgsC2.DelimitedText := ABGLCode2;
  632. sgsN1.Delimiter := ';';
  633. sgsN2.Delimiter := ';';
  634. sgsN1.DelimitedText := ABGLNum1;
  635. sgsN2.DelimitedText := ABGLNum2;
  636. for i2 := 0 to sgsC2.Count - 1 do
  637. begin
  638. bExist := False;
  639. for i1 := 0 to sgsC1.Count - 1 do
  640. if SameText(sgsC2[i2], sgsC1[i1]) then
  641. begin
  642. bExist := True;
  643. Break;
  644. end;
  645. if bExist then
  646. begin
  647. sgsN1[i1] := FloatToStr(StrToFloatDef(sgsN1[i1], 0) + StrToFloatDef(sgsN2[i2], 0))
  648. end
  649. else
  650. begin
  651. sgsC1.Add(sgsC2[i2]);
  652. sgsN1.Add(sgsN2[i2]);
  653. end;
  654. end;
  655. ABGLCode1 := sgsC1.DelimitedText;
  656. ABGLNum1 := sgsN1.DelimitedText;
  657. finally
  658. sgsC1.Free;
  659. sgsC2.Free;
  660. sgsN1.Free;
  661. sgsN2.Free;
  662. end;
  663. end;
  664. function B_CodeToIndexCode(const AB_Code: string): string;
  665. var
  666. sgs: TStrings;
  667. i, iNum, iError: Integer;
  668. sError: string;
  669. begin
  670. sgs := TStringList.Create;
  671. try
  672. Result := '';
  673. sgs.Delimiter := '-';
  674. sgs.DelimitedText := AB_Code;
  675. for i := 0 to sgs.Count - 1 do
  676. begin
  677. Val(sgs[i], iNum, iError);
  678. if iError = 0 then
  679. sError := ''
  680. else
  681. sError := Copy(sgs[i], iError, Length(sgs[i])-iError+1);
  682. if iError = 0 then
  683. Result := Result + Format('%4d', [iNum]) + Format('%-4s', [sError])
  684. else if iNum = 0 then
  685. Result := Result + '9999' + Format('%-4s', [sError])
  686. else
  687. Result := Result + Format('%4d', [iNum]) + Format('%-4s', [sError]);
  688. end;
  689. finally
  690. sgs.Free;
  691. end;
  692. end;
  693. function ChinessNum(const ADigitNum: Integer): string;
  694. function TransChineseNum(const ANum, AZeroNum: Integer): string;
  695. begin
  696. Result := '';
  697. case ANum of
  698. 1: if AZeroNum <> 1 then Result := '一';
  699. 2: Result := '二';
  700. 3: Result := '三';
  701. 4: Result := '四';
  702. 5: Result := '五';
  703. 6: Result := '六';
  704. 7: Result := '七';
  705. 8: Result := '八';
  706. 9: Result := '九';
  707. end;
  708. if (Result = '') and ((AZeroNum <> 1) or (ANum = 0)) then Exit;
  709. case AZeroNum of
  710. 0: Result := Result;
  711. 1: Result := Result + '十';
  712. 2: Result := Result + '百';
  713. 3: Result := Result + '千';
  714. 4: Result := Result + '万';
  715. end;
  716. end;
  717. var
  718. iBai, iShi, iGe: Integer;
  719. begin
  720. Result := '';
  721. if (ADigitNum < 0) and (ADigitNum > 10000) then Exit;
  722. iBai := ADigitNum div 100;
  723. iShi := (ADigitNum mod 100) div 10;
  724. iGe := (ADigitNum mod 100) mod 10;
  725. Result := TransChineseNum(iBai, 2) + TransChineseNum(iShi, 1) + TransChineseNum(iGe, 0);
  726. end;
  727. function CheckDigit(ANum: Double): Integer;
  728. begin
  729. if abs(ANum - advRoundTo(ANum, -2)) > 0.0001 then
  730. Result := 3
  731. else if abs(ANum - advRoundTo(ANum, -1)) > 0.001 then
  732. Result := 2
  733. else if abs(ANum - AdvRoundTo(ANum, 0)) > 0.01 then
  734. Result := 1
  735. else
  736. Result := 0;
  737. end;
  738. function Num2Peg(ANum: Double): string;
  739. var
  740. fMod: Double;
  741. iK, iDigit: Integer;
  742. sDigit: string;
  743. begin
  744. iK := Trunc(ANum/1000);
  745. fMod := Frac(ANum/1000)*1000;
  746. iDigit := CheckDigit(fMod);
  747. case iDigit of
  748. 3: sDigit := FormatFloat('000.000', AdvRoundTo(fMod, -3));
  749. 2: sDigit := FormatFloat('000.00', AdvRoundTo(fMod, -2));
  750. 1: sDigit := FormatFloat('000.0', AdvRoundTo(fMod, -1));
  751. 0: sDigit := FormatFloat('000', Trunc(AdvRoundTo(fMod, 0)));
  752. end;
  753. { case iDigit of
  754. 3: Result := Format('K%d+%3.3f', [iK, ]);
  755. 2: Result := Format('K%d+%3.2f', [iK, AdvRoundTo(fMod, -2)]);
  756. 1: Result := Format('K%d+%3.1f', [iK, AdvRoundTo(fMod, -1)]);
  757. 0: Result := Format('K%d+%s', [iK, FormatFloat('000', [])]);
  758. end; }
  759. Result := Format('K%d+%s', [iK, sDigit]);
  760. end;
  761. {Tree Relative}
  762. function CreateTree: TZjIDTree;
  763. begin
  764. Result := TZjIDTree.Create;
  765. Result.KeyFieldName := 'ID';
  766. Result.ParentFieldName := 'ParentID';
  767. Result.NextSiblingFieldName := 'NextSiblingID';
  768. Result.AutoCreateKeyID := True;
  769. Result.AutoExpand := True;
  770. end;
  771. procedure DisConnectTree(ATree: TZjIDTree);
  772. begin
  773. ATree.DataSet := nil;
  774. ATree.Active := False;
  775. end;
  776. procedure ConnectTree(ATree: TZjIDTree; ADataset: TDataSet);
  777. begin
  778. ATree.DataSet := ADataset;
  779. ATree.Active := True;
  780. end;
  781. procedure InitGridHead(AGridDBA: TZjGridDBA; AGrid: TZJGrid);
  782. var
  783. I: Integer;
  784. begin
  785. for I := 0 to AGridDBA.Columns.Count - 1 do
  786. AGrid.Cells[I + 1, 0].Text := AGridDBA.Columns[I].Title.Caption;
  787. end;
  788. {Generate Name/Path}
  789. function GetTempFileDir: string;
  790. var
  791. TempPath: string;
  792. begin
  793. TempPath := GetEnvironmentVariable('TMP');
  794. if TempPath = '' then
  795. TempPath := GetEnvironmentVariable('TEMP');
  796. if TempPath = '' then
  797. begin
  798. if not DirectoryExists(ExtractFileDir(ParamStr(0)) + '\Temp') then
  799. CreateDir(ExtractFileDir(ParamStr(0)) + '\Temp');
  800. TempPath := ExtractFileDir(ParamStr(0)) + '\Temp';
  801. end;
  802. Result := TempPath;
  803. end;
  804. function GetTempFilePath: string;
  805. begin
  806. Result := GetTempFileDir + '\';
  807. end;
  808. function GetTempName(ALength: Integer): string;
  809. const
  810. CodedBuf: array[0..35] of Char = ('0', '1', '2', '3', '4', '5',
  811. '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
  812. 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
  813. 'W', 'X', 'Y', 'Z');
  814. var
  815. Temp: string;
  816. Num: Integer;
  817. begin
  818. Randomize;
  819. Temp := '';
  820. while Length(Temp) < ALength do
  821. begin
  822. Num := Random(37);
  823. If Num <> 36 Then
  824. Temp := Temp + CodedBuf[Num]; // 0..35
  825. end;
  826. Result := Temp;
  827. end;
  828. function GetTempFileName: string;
  829. var
  830. TempExt: string;
  831. begin
  832. Result := GetTempFilePath + GetTempName;
  833. TempExt := '.' + GetTempName(3);
  834. while SameText(TempExt, '.mdb') or SameText(TempExt, '.db') or
  835. SameText(TempExt, '.ldb') do
  836. TempExt := '.' + GetTempName(3);
  837. Result := Result + TempExt;
  838. while FileExists(Result) do
  839. begin
  840. Result := GetTempFilePath + GetTempName;
  841. TempExt := '.' + GetTempName(3);
  842. while SameText(TempExt, '.mdb') or SameText(TempExt, '.db') or
  843. SameText(TempExt, '.ldb') do
  844. TempExt := '.' + GetTempName(3);
  845. Result := Result + TempExt;
  846. end;
  847. end;
  848. function GetTempFileName(const APath, AExt: string): string;
  849. begin
  850. Result := APath + GetTempName + AExt;
  851. while FileExists(Result) do
  852. Result := APath + GetTempName + AExt;
  853. end;
  854. function GenerateTempFolder(AGeneratePath: string): string;
  855. begin
  856. Result := AGeneratePath + GetTempName;
  857. while DirectoryExists(Result) do
  858. Result := AGeneratePath + GetTempName;
  859. CreateDirectoryInDeep(Result);
  860. end;
  861. function GetNewGUIDFileName(const AGeneratePath: string): string;
  862. var
  863. gFile: TGUID;
  864. begin
  865. repeat
  866. CreateGUID(gFile);
  867. Result := AGeneratePath + GUIDToString(gFile);
  868. until not FileExists(Result);
  869. end;
  870. {Progress bar Control}
  871. procedure UpdateSysProgress(APosition: Integer; const AHint: string);
  872. begin
  873. if not SysProgressDisabled then
  874. UpdateProgress(APosition, AHint);
  875. end;
  876. procedure UpdateProgress(APosition: Integer; const AHint: string);
  877. begin
  878. MainForm.UpdateProgress(APosition, AHint);
  879. end;
  880. procedure DisableSysProgress;
  881. begin
  882. SysProgressDisabled := True;
  883. end;
  884. procedure EnableSysProgress;
  885. begin
  886. SysProgressDisabled := False;
  887. end;
  888. {Interface RePaint Control}
  889. procedure BeginUpdateWindow(AHandle: THandle);
  890. begin
  891. SendMessage(AHandle, WM_SETREDRAW, 0, 0);
  892. end;
  893. procedure EndUpdateWindow(AHandle: THandle);
  894. begin
  895. SendMessage(AHandle, WM_SETREDRAW, 1, 0);
  896. end;
  897. {Zip}
  898. function ZipComplete(const AFileName: string; ACheckMode: Integer): Boolean;
  899. const
  900. i4k = 4096;
  901. var
  902. iSize1, iSize2: Integer;
  903. begin
  904. iSize1 := FileSizeByName(AFileName);
  905. Sleep(300);
  906. iSize2 := FileSizeByName(AFileName);
  907. Result := (iSize1 = iSize2);
  908. if ACheckMode = 0 then
  909. Result := Result and (iSize1 > i4k);
  910. end;
  911. procedure ZipFolder(AFileFolder, AFileName: string; ACheckMode: Integer = 0);
  912. procedure AppendLog(const ALog: string);
  913. begin
  914. if SupportManager.ConfigInfo.IsLog then
  915. MeasureLog.AppendLogTo(ALog);
  916. end;
  917. var
  918. sTempFile: string;
  919. vZip: TVCLZip;
  920. iCount: Integer;
  921. begin
  922. AppendLog('Zip');
  923. sTempFile := GetTempFileName;
  924. vZip := TVCLZip.Create(nil);
  925. iCount := 0;
  926. try
  927. vZip.FilesList.Clear;
  928. vZip.ZipName := sTempFile;
  929. vzip.RootDir := AFileFolder;
  930. vZip.OverwriteMode := Always;
  931. //vZip.AddDirEntriesOnRecurse:=True;
  932. vZip.RelativePaths := True;
  933. //vZip.RecreateDirs := True;
  934. vZip.FilesList.Add(AFileFolder + '\*.*');
  935. vZip.Zip;
  936. AppendLog(Format('Check Zip File, FileSize - %d', [FileSizeByName(sTempFile)]));
  937. while not ZipComplete(sTempFile, ACheckMode) and (iCount < 10) do
  938. begin
  939. Sleep(200);
  940. Inc(iCount);
  941. AppendLog(Format('Check Zip File - %d, FileSize - %d', [iCount + 1, FileSizeByName(sTempFile)]));
  942. end;
  943. AppendLog('Check Zip File --> Pass');
  944. CopyFileOrFolder(sTempFile, AFileName);
  945. AppendLog('Zip --> Pass');
  946. finally
  947. vZip.Free;
  948. if FileExists(sTempFile) then
  949. DeleteFile(sTempFile);
  950. end;
  951. end;
  952. function UnZipFile(AFileName, AFileFolder: string): Boolean;
  953. var
  954. vUnZip: TVCLZip;
  955. begin
  956. Result := True;
  957. vUnZip := TVCLZip.Create(nil);
  958. try
  959. vUnZip.FilesList.Clear;
  960. vUnZip.ZipName := AFileName;
  961. vUnZip.ReadZip;
  962. vUnZip.DestDir := AFileFolder;
  963. vUnZip.OverwriteMode := Always;
  964. vUnZip.RecreateDirs := True;
  965. vUnZip.RelativePaths := True;
  966. vUnZip.DoAll := True;
  967. vUnZip.FilesList.Add('*.*');
  968. try
  969. vUnZip.UnZip;
  970. except
  971. Result := False;
  972. end;
  973. finally
  974. vUnZip.Free;
  975. end;
  976. end;
  977. {Copy By Stream}
  978. procedure CopyFileByStream(const ASourceFile, ADestFile: string);
  979. var
  980. MS: TMemoryStream;
  981. begin
  982. MS := TMemoryStream.Create;
  983. try
  984. MS.LoadFromFile(ASourceFile);
  985. if FileExists(ADestFile) then
  986. DeleteFile(ADestFile);
  987. MS.SaveToFile(ADestFile);
  988. finally
  989. MS.Free;
  990. end;
  991. end;
  992. procedure AppendTestLog(const AFileName, ALog: string);
  993. var
  994. f: TextFile;
  995. begin
  996. try
  997. if FileExists(AFileName) then
  998. begin
  999. AssignFile(f, AFileName);
  1000. Append(f);
  1001. Writeln(f, ALog);
  1002. end
  1003. else
  1004. begin
  1005. AssignFile(f, AFileName);
  1006. Rewrite(f);
  1007. Writeln(f, ALog);
  1008. end;
  1009. finally
  1010. CloseFile(f);
  1011. end;
  1012. end;
  1013. function GetVersion(APartCount: Integer = 4): string;
  1014. var
  1015. V1, V2, V3, V4: Word;
  1016. FInfoSize, FF: Cardinal;
  1017. FInfo: Pointer;
  1018. FFixed: PVSFIXEDFILEINFO;
  1019. begin
  1020. FInfoSize := GetFileVersionInfoSize(PChar(Application.ExeName), FF);
  1021. FInfo := AllocMem(FInfoSize);
  1022. try
  1023. GetFileVersionInfo(PChar(Application.ExeName), FF, FInfoSize, FInfo);
  1024. VerQueryValue(FInfo, '\', Pointer(FFixed), FInfoSize);
  1025. V1 := FFixed.dwFileVersionMS shr 16;
  1026. V2 := FFixed.dwFileVersionMS and $FFFF;
  1027. V3 := FFixed.dwFileVersionLS shr 16;
  1028. V4 := FFixed.dwFileVersionLS and $FFFF;
  1029. finally
  1030. Dispose(FInfo);
  1031. end;
  1032. Result := '';
  1033. case APartCount of
  1034. 1:
  1035. Result := Format('%d', [V1]);
  1036. 2:
  1037. Result := Format('%d.%d', [V1, V2]);
  1038. 3:
  1039. Result := Format('%d.%d.%d', [V1, V2, V3]);
  1040. 4:
  1041. Result := Format('%d.%d.%d.%d', [V1, V2, V3, V4]);
  1042. end;
  1043. end;
  1044. function ExtractFileNameWithoutExt(const AFileName: string): string;
  1045. var
  1046. sFileName, Ext: string;
  1047. begin
  1048. Result := '';
  1049. if AFileName = '' then
  1050. Exit;
  1051. sFileName := AFileName;
  1052. if sFileName[Length(sFileName)] = '\' then
  1053. Delete(sFileName, Length(sFileName), 1);
  1054. Result := ExtractFileName(sFileName);
  1055. Ext := ExtractFileExt(sFileName);
  1056. Delete(Result, Length(Result) - Length(Ext) + 1, Length(Ext));
  1057. end;
  1058. function ShortText(AText: string; AWidth: Integer): string;
  1059. var vMM: TMemo;
  1060. begin
  1061. if Trim(AText) = '' then
  1062. begin
  1063. Result := '';
  1064. Exit;
  1065. end;
  1066. vMM := TMemo.Create(nil);
  1067. try
  1068. vMM.Visible := False;
  1069. vMM.WordWrap := True;
  1070. vMM.parent := Application.MainForm;
  1071. vMM.Width := AWidth - 10; // 10像素留给3个小点
  1072. vMM.Text := AText;
  1073. if vMM.Lines.Count > 1 then
  1074. Result := vMM.Lines[0] + '...'
  1075. else
  1076. Result := AText;
  1077. finally
  1078. vMM.Free;
  1079. end;
  1080. end;
  1081. function CustomWidthText(AText: string; AWidth: Integer): string;
  1082. var vMM: TMemo;
  1083. i: Integer;
  1084. begin
  1085. if Trim(AText) = '' then
  1086. begin
  1087. Result := '';
  1088. Exit;
  1089. end;
  1090. vMM := TMemo.Create(nil);
  1091. try
  1092. vMM.Visible := False;
  1093. vMM.WordWrap := True;
  1094. vMM.parent := Application.MainForm;
  1095. vMM.Width := AWidth;
  1096. vMM.Text := AText;
  1097. for i := 0 to vMM.Lines.Count - 1 do
  1098. begin
  1099. if i = 0 then
  1100. Result := vMM.Lines[i]
  1101. else
  1102. Result := Result + #10#13 + vMM.Lines[i];
  1103. end;
  1104. finally
  1105. vMM.Free;
  1106. end;
  1107. end;
  1108. function ReplaceCharsForJson(AText: string): string;
  1109. const
  1110. BefChar: array [0..7] of Char = ('{', '}', ',', ':', '"', '[', ']', '%');
  1111. AftChar: array [0..7] of string = ('{', '}', ',', ':', '"', '【', '】', '♂');
  1112. var I: Integer;
  1113. begin
  1114. AText := Trim(AText);
  1115. Result := AText;
  1116. if AText = '' then Exit;
  1117. for I := low(BefChar) to High(BefChar) do
  1118. begin
  1119. if Pos(BefChar[I], AText) > 0 then
  1120. AText := StringReplace(AText, BefChar[I], AftChar[I], [rfReplaceAll]);
  1121. end;
  1122. Result := AText;
  1123. end;
  1124. function RecoverCharsFromJson(AText: string): string;
  1125. const
  1126. BefStr: array [0..3] of string = ('♂', '\r\n', '\r', '\n');
  1127. AftStr: array [0..3] of string = ('%', '', '', '');
  1128. var I: Integer;
  1129. begin
  1130. AText := Trim(AText);
  1131. Result := AText;
  1132. if AText = '' then Exit;
  1133. for I := low(BefStr) to High(BefStr) do
  1134. begin
  1135. if Pos(BefStr[I], AText) > 0 then
  1136. AText := StringReplace(AText, BefStr[I], AftStr[I], [rfReplaceAll]);
  1137. end;
  1138. Result := AText;
  1139. end;
  1140. procedure FindFiles(APath, AExtName: string; AFileList: TStrings);
  1141. var
  1142. SRec: TSearchRec;
  1143. retval: Integer;
  1144. begin
  1145. AFileList.Clear;
  1146. retval := FindFirst(APath + AExtName, faAnyFile, sRec);
  1147. try
  1148. while retval = 0 do
  1149. begin
  1150. if (SRec.Attr and faDirectory) = 0 then
  1151. AFileList.Add(Srec.Name);
  1152. retval := FindNext(SRec);
  1153. end;
  1154. finally
  1155. FindClose(SRec);
  1156. end;
  1157. end;
  1158. function DeleteFolder(const FolderStr: string): Boolean;
  1159. var
  1160. fos: SHFILEOPSTRUCT;
  1161. begin
  1162. ZeroMemory(@fos, SizeOf(fos));
  1163. fos.Wnd := HWND_DESKTOP;
  1164. fos.wFunc := FO_DELETE;
  1165. fos.fFlags := FOF_SILENT OR FOF_ALLOWUNDO OR FOF_NOCONFIRMATION;
  1166. fos.pFrom := PChar(FolderStr + #0);
  1167. Result := SHFileOperation(fos) <> 0;
  1168. end;
  1169. function HasExt(const AFileName: string): Boolean;
  1170. begin
  1171. Result := ExtractFileExt(AFileName) <> '';
  1172. end;
  1173. function CopyFolder(const SrcFolder, DstFolder: string): Boolean;
  1174. var
  1175. fos: SHFILEOPSTRUCT;
  1176. begin
  1177. ZeroMemory(@fos, SizeOf(fos));
  1178. fos.Wnd := HWND_DESKTOP;
  1179. fos.wFunc := FO_COPY;
  1180. fos.fFlags := FOF_SILENT OR FOF_ALLOWUNDO;
  1181. fos.pFrom := PChar(SrcFolder + #0);
  1182. fos.pTo := PChar(DstFolder + #0);
  1183. Result := SHFileOperation(fos) <> 0;
  1184. end;
  1185. function FileCount(APath: string): Integer;
  1186. var
  1187. vSR: TSearchRec;
  1188. iRetval: Integer;
  1189. vSL: TStringList;
  1190. begin
  1191. vSL := TStringList.Create;
  1192. iRetval := FindFirst(APath + '*.*', faAnyFile, vSR);
  1193. try
  1194. while iRetval = 0 do
  1195. begin
  1196. if (vSR.Attr and faDirectory) = 0 then
  1197. vSL.Add(vSR.Name);
  1198. iRetval := FindNext(vSR);
  1199. end;
  1200. Result := vSL.Count;
  1201. finally
  1202. FindClose(vSR);
  1203. vSL.Free;
  1204. end;
  1205. end;
  1206. end.