ConstMethodUnit.pas 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478
  1. unit ConstMethodUnit;
  2. interface
  3. uses windows, Forms, Variants, ConstVarUnit, Classes, Math;
  4. // 判断当前系统是否是64位 GiLi
  5. function IsWin64: Boolean;
  6. // 警告
  7. function MessageWarning(AHandle: THandle; AText: string;
  8. ACaption: string = '警告'; AButtons: Cardinal = MB_OK): Cardinal;
  9. // 提示
  10. function MessageHint(AHandle: THandle; AText: string;
  11. ACaption: string = '提示'; AButtons: Cardinal = MB_OK): Cardinal;
  12. // 询问
  13. function MessageQuest(AHandle: THandle; AText: string;
  14. ACaption: string = '询问'; AButtons: Cardinal = MB_OKCANCEL): Cardinal; overload;
  15. function MessageQuest(AText: string; ACaption: string = '询问'): Boolean; overload;
  16. // 错误
  17. function MessageError(AHandle: THandle; AText: string;
  18. ACaption: string = '错误'; AButtons: Cardinal = MB_OK): Cardinal;
  19. function CheckFileExists(const FileName: string): Boolean;
  20. function CheckSpecialChar(const aText: string): Boolean;
  21. function CheckFileEnabled(const AFullFileName: string): Boolean;
  22. function ScRoundTo(const AValue: Double; const ADigit: Integer = -2): Double;
  23. function GetSaveFile: string;
  24. function OpenFileDialog(const aTitle, aDefaultExt, aFileName, aFilter: string; var aNewFileName: string): Boolean;
  25. function SaveFileDialog(const aTitle, aDefaultExt, aFileName, aFilter: string; var aNewFileName: string): Boolean;
  26. function ProcessIsRunning(const aProcessName: string): Integer;
  27. // 获得本机Mac地址
  28. function MacAddress: string;
  29. function LoadServiceQQ: string;
  30. // 输入对话框(返回输入结果)
  31. function ScInputBox(const ACaption, APrompt, ADefault: string): string;
  32. // 输入对话框(返回是否确认)
  33. function ScInputQuery(const ACaption, APrompt: string;
  34. var Value: string; ANeedMark: Boolean = False): Boolean;
  35. // 输入密码
  36. function InputPassWord(var APwd: string): Boolean;
  37. // 修改或设置密码
  38. function SetupPassWord(var APwd: string): Boolean;
  39. function GetLocalGUID: TGUID;
  40. function IsLocalGUID(AGUID: TGUID): Boolean;
  41. {get parent code}
  42. function GetPreCode(const ACode: string): string;
  43. function FixPathByAppPath(const AFileName: string): string;
  44. function ExtractFileNameWithoutExt(const AFileName: string): string;
  45. function ScVarToCurrency(const V: Variant): Currency;
  46. function ScVarToFloat(const V: Variant): Double;
  47. function ScVarToFloatDef(const V: Variant; Def: Double): Double;
  48. {set progress}
  49. procedure IncProgressUI(const Step: Integer);
  50. {display stdbillslib}
  51. procedure DisplayStdBillsLib;
  52. {get a random string, 10}
  53. function GetRandomName: string;
  54. function ConvertUnitStr(aUnitStr: string): string;
  55. //获取文件版本号
  56. function GetFileVersion: string;
  57. // 获得文件版本(转换成四个整数形式)
  58. function ScDecodeFileVer(AVersion: string; var V1, V2, V3, V4: Integer): Boolean;
  59. // 比较版本大小,大于0表示AVersion1新,等于0一样,小于0表示AVersion2新
  60. function ScCompareFileVer(AVersion1: string; AVersion2: string; APartCount: Integer = 4): Integer;
  61. {template method}
  62. procedure ExcuteTemplateMethod(aMethod: Pointer; Owner: TObject = nil);
  63. {Get locatebills strings}
  64. function GetLocateBillsStrings: Integer;
  65. {Auto Save Projects}
  66. procedure AutoSaveProjects(const aAutoSave: Boolean; const aSaveInterval: Integer);
  67. function CheckProjectOpened(ASelect: Integer; const AFileName: string): Integer;
  68. function CompareCodes(ACode1, ABCode1, AName1, ACode2, ABCode2, AName2: string): Integer;
  69. function CompareCode(const Code1, Code2: string): Integer;
  70. function CompareCodeWithChar(const ACode1, ACode2: string; ADelimiter: Char = '-'): Integer;
  71. // 清空内容为指针的List
  72. procedure ClearPointerList(AList: TList);
  73. procedure ClearObjectList(aList: TList);
  74. // 获得临时文件路径
  75. function GetTempFilePath: string;
  76. // 获得临时文件名
  77. function GetTempFileName(AExt: string = ''): string;
  78. // 随机生成名称
  79. function GetTempName(ALength: Integer = 8): string;
  80. // 自动替换或添加后缀
  81. procedure FixFileExt(var AFileName: string; const AExt: string; AutoReplace: Boolean = False);
  82. // 创建全部层次路径
  83. function CreateFullDir(ADir: string): Boolean;
  84. function SystemDateTime: TDateTime;
  85. function CompileDateTime: TDateTime;
  86. function BillCategory(ACode, AB_Code: string): TBillCategory;
  87. function FormatBCodeAlpha(AB_Code: string): String;
  88. var
  89. NumStrToAlpha: Array[0..29] of TIdentMapEntry = (
  90. (Value: 10; Name: 'A'), (Value: 11; Name: 'B'), (Value: 12; Name: 'C'),
  91. (Value: 13; Name: 'D'), (Value: 14; Name: 'E'), (Value: 15; Name: 'F'),
  92. (Value: 16; Name: 'G'), (Value: 17; Name: 'H'), (Value: 18; Name: 'I'),
  93. (Value: 19; Name: 'J'),
  94. (Value: 20; Name: 'K'), (Value: 21; Name: 'L'), (Value: 22; Name: 'M'),
  95. (Value: 23; Name: 'N'), (Value: 24; Name: 'O'), (Value: 25; Name: 'P'),
  96. (Value: 26; Name: 'Q'), (Value: 27; Name: 'R'), (Value: 28; Name: 'S'),
  97. (Value: 29; Name: 'T'),
  98. (Value: 30; Name: 'U'), (Value: 31; Name: 'V'), (Value: 32; Name: 'W'),
  99. (Value: 33; Name: 'X'), (Value: 34; Name: 'Y'), (Value: 35; Name: 'Z'),
  100. (Value: 36; Name: 'ZA'), (Value: 37; Name: 'ZB'), (Value: 38; Name: 'ZC'),
  101. (Value: 39; Name: 'ZD')
  102. );
  103. var
  104. _ServerDateTime: TDateTime = 0;
  105. implementation
  106. uses
  107. SysUtils, Dialogs, Controls, StdCtrls, Graphics,
  108. IniFiles, TLHelp32;
  109. function IsWin64: Boolean;
  110. var
  111. Kernel32Handle: THandle;
  112. IsWow64Process: function(Handle: Windows.THandle; var Res: Windows.BOOL): Windows.BOOL; stdcall;
  113. GetNativeSystemInfo: procedure(var lpSystemInfo: TSystemInfo); stdcall;
  114. isWoW64: Bool;
  115. SystemInfo: TSystemInfo;
  116. const
  117. PROCESSOR_ARCHITECTURE_AMD64 = 9;
  118. PROCESSOR_ARCHITECTURE_IA64 = 6;
  119. begin
  120. Kernel32Handle := GetModuleHandle('KERNEL32.DLL');
  121. if Kernel32Handle = 0 then
  122. Kernel32Handle := LoadLibrary('KERNEL32.DLL');
  123. if Kernel32Handle <> 0 then
  124. begin
  125. IsWOW64Process := GetProcAddress(Kernel32Handle,'IsWow64Process');
  126. GetNativeSystemInfo := GetProcAddress(Kernel32Handle,'GetNativeSystemInfo');
  127. if Assigned(IsWow64Process) then
  128. begin
  129. IsWow64Process(GetCurrentProcess,isWoW64);
  130. Result := isWoW64 and Assigned(GetNativeSystemInfo);
  131. if Result then
  132. begin
  133. GetNativeSystemInfo(SystemInfo);
  134. Result := (SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64) or
  135. (SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64);
  136. end;
  137. end
  138. else Result := False;
  139. end
  140. else Result := False;
  141. end;
  142. function MessageWarning(AHandle: THandle; AText: string;
  143. ACaption: string = '警告'; AButtons: Cardinal = MB_OK): Cardinal;
  144. var
  145. Hdl: THandle;
  146. begin
  147. if AHandle = 0 then
  148. // Hdl := Application.Handle
  149. begin
  150. if (Screen.ActiveForm <> nil) and Screen.ActiveForm.HandleAllocated then
  151. Hdl := Screen.ActiveForm.Handle
  152. else
  153. Hdl := 0;
  154. end
  155. else
  156. Hdl := AHandle;
  157. Result := MessageBox(Hdl, PChar(AText), PChar(ACaption), AButtons or MB_ICONWARNING);
  158. end;
  159. function MessageHint(AHandle: THandle; AText: string;
  160. ACaption: string = '提示'; AButtons: Cardinal = MB_OK): Cardinal;
  161. var
  162. Hdl: THandle;
  163. begin
  164. if AHandle = 0 then
  165. // Hdl := Application.Handle
  166. begin
  167. if (Screen.ActiveForm <> nil) and Screen.ActiveForm.HandleAllocated then
  168. Hdl := Screen.ActiveForm.Handle
  169. else
  170. Hdl := 0;
  171. end
  172. else
  173. Hdl := AHandle;
  174. Result := MessageBox(Hdl, PChar(AText), PChar(ACaption), AButtons or MB_ICONINFORMATION);
  175. end;
  176. function MessageQuest(AHandle: THandle; AText: string;
  177. ACaption: string = '询问'; AButtons: Cardinal = MB_OKCANCEL): Cardinal;
  178. var
  179. Hdl: THandle;
  180. begin
  181. if AHandle = 0 then
  182. // Hdl := Application.Handle
  183. begin
  184. if (Screen.ActiveForm <> nil) and Screen.ActiveForm.HandleAllocated then
  185. Hdl := Screen.ActiveForm.Handle
  186. else
  187. Hdl := 0;
  188. end
  189. else
  190. Hdl := AHandle;
  191. Result := MessageBox(Hdl, PChar(AText), PChar(ACaption), AButtons or MB_ICONQUESTION);
  192. end;
  193. function MessageQuest(AText: string; ACaption: string = '询问'): Boolean;
  194. var
  195. Hdl: THandle;
  196. begin
  197. Hdl := Screen.ActiveForm.Handle;
  198. Result := MessageBox(Hdl, PChar(AText), PChar(ACaption),
  199. MB_OKCANCEL or MB_ICONQUESTION) = IDOK;
  200. end;
  201. function MessageError(AHandle: THandle; AText: string;
  202. ACaption: string = '错误'; AButtons: Cardinal = MB_OK): Cardinal;
  203. var
  204. Hdl: THandle;
  205. begin
  206. if AHandle = 0 then
  207. // Hdl := Application.Handle
  208. begin
  209. if (Screen.ActiveForm <> nil) and Screen.ActiveForm.HandleAllocated then
  210. Hdl := Screen.ActiveForm.Handle
  211. else
  212. Hdl := 0;
  213. end
  214. else
  215. Hdl := AHandle;
  216. Result := MessageBox(Hdl, PChar(AText), PChar(ACaption), AButtons or MB_ICONERROR);
  217. end;
  218. function CheckFileExists(const FileName: string): Boolean;
  219. var
  220. strFilePath: string;
  221. begin
  222. strFilePath := Format('%s\我的清单\%s.smb', [(ExtractFileDir(ParamStr(0))), FileName]);
  223. Result := FileExists(strFilePath);
  224. strFilePath := ExtractFileDir(strFilePath);
  225. if not Result and not DirectoryExists(strFilePath) then
  226. begin
  227. ForceDirectories(strFilePath);
  228. end;
  229. end;
  230. function CheckSpecialChar(const aText: string): Boolean;
  231. const
  232. SpecialArray: array [0..8] of Char = ('/', '\', ':', '*', '?', '"', '<', '>', '|');
  233. var
  234. I, J: Integer;
  235. begin
  236. Result := False;
  237. for I := 1 to Length(aText) do
  238. begin
  239. for J := Low(SpecialArray) to High(SpecialArray) do
  240. if aText[I] = SpecialArray[J] then
  241. begin
  242. Result := True;
  243. Break;
  244. end;
  245. end;
  246. end;
  247. function ExtractFileNameWithoutExt(const AFileName: string): string;
  248. var
  249. sFileName, Ext: string;
  250. begin
  251. Result := '';
  252. if AFileName = '' then Exit;
  253. sFileName := AFileName;
  254. if sFileName[Length(sFileName)] = '\' then
  255. Delete(sFileName, Length(sFileName), 1);
  256. Result := ExtractFileName(sFileName);
  257. Ext := ExtractFileExt(sFileName);
  258. Delete(Result, Length(Result) - Length(Ext) + 1, Length(Ext));
  259. end;
  260. function ScVarToCurrency(const V: Variant): Currency;
  261. begin
  262. if VarIsNull(V) then
  263. Result := 0.0
  264. else if VarToStr(V) = '' then
  265. Result := 0.0
  266. else
  267. Result := V;
  268. end;
  269. function ScVarToFloat(const V: Variant): Double;
  270. begin
  271. if VarIsNull(V) then
  272. Result := 0.0
  273. else if VarToStr(V) = '' then
  274. Result := 0.0
  275. else
  276. Result := V;
  277. end;
  278. function ScVarToFloatDef(const V: Variant; Def: Double): Double;
  279. begin
  280. if VarIsNull(V) then
  281. Result := Def
  282. else if VarToStr(V) = '' then
  283. Result := Def
  284. else
  285. Result := V;
  286. end;
  287. procedure IncProgressUI(const Step: Integer);
  288. begin
  289. SendMessage(Application.MainForm.Handle, SM_ProgressInc, Step, 0);
  290. end;
  291. procedure DisplayStdBillsLib;
  292. begin
  293. SendMessage(Application.MainForm.Handle, SM_StdBillsLib, 0, 0);
  294. end;
  295. function GetRandomName: string;
  296. var
  297. I: Integer;
  298. arrStr: array [0..35] of Char;
  299. begin
  300. arrStr[1]:='0'; arrStr[2]:='1'; arrStr[3]:='2'; arrStr[4]:='3';
  301. arrStr[5]:='4'; arrStr[6]:='5'; arrStr[7]:='6'; arrStr[8]:='7';
  302. arrStr[9]:='8'; arrStr[10]:='9'; arrStr[11]:='A'; arrStr[12]:='B';
  303. arrStr[13]:='C'; arrStr[14]:='D'; arrStr[15]:='E'; arrStr[16]:='F';
  304. arrStr[17]:='G'; arrStr[18]:='H'; arrStr[19]:='I'; arrStr[20]:='J';
  305. arrStr[21]:='K'; arrStr[22]:='L'; arrStr[23]:='M'; arrStr[24]:='N';
  306. arrStr[25]:='O'; arrStr[26]:='P'; arrStr[27]:='Q'; arrStr[28]:='R';
  307. arrStr[29]:='S'; arrStr[30]:='T'; arrStr[31]:='U'; arrStr[32]:='V';
  308. arrStr[33]:='W'; arrStr[34]:='X'; arrStr[35]:='Y'; arrStr[0]:='Z';
  309. Result := '';
  310. for I := 1 to 15 do
  311. begin
  312. Randomize;
  313. Result := Result + Trim(arrStr[Random(36)]);
  314. end;
  315. end;
  316. function ConvertUnitStr(aUnitStr: string): string;
  317. const
  318. Patt1: string = 'M2';
  319. NewPattern1: string = '㎡';
  320. Patt2: string = 'M3';
  321. NewPattern2: string = WideChar($00E0);
  322. var
  323. SearchStr, NewStr, NewPattern, OldPattern: string;
  324. Offset, os1, os2: Integer;
  325. begin
  326. SearchStr := AnsiUpperCase(aUnitStr);
  327. NewStr := aUnitStr;
  328. Result := '';
  329. while SearchStr <> '' do
  330. begin
  331. os1 := AnsiPos(Patt1, SearchStr);
  332. os2 := AnsiPos(Patt2, SearchStr);
  333. if os2 > os1 then
  334. begin
  335. if os1 <> 0 then
  336. Offset := os1
  337. else
  338. Offset := os2;
  339. end
  340. else
  341. begin
  342. if os2 <> 0 then
  343. Offset := os2
  344. else
  345. Offset := os1;
  346. end;
  347. if Offset = 0 then
  348. begin
  349. Result := Result + NewStr;
  350. Break;
  351. end;
  352. if Offset = os1 then
  353. begin
  354. NewPattern := NewPattern1;
  355. OldPattern := Patt1;
  356. end
  357. else
  358. begin
  359. NewPattern := NewPattern2;
  360. OldPattern := Patt2;
  361. end;
  362. // 遇到M20, M25, M30等混凝土需要剔除
  363. if not (NewStr[Offset + Length(OldPattern)] in ['0'..'9']) then
  364. Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern
  365. else
  366. Result := Result + Copy(NewStr, 1, Offset + Length(OldPattern) - 1);
  367. NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt);
  368. SearchStr := Copy(SearchStr, Offset + Length(OldPattern), MaxInt);
  369. end;
  370. end;
  371. function GetFileVersion:string;
  372. var
  373. S: string;
  374. iBufSize, iLen: DWord;
  375. Buf: PChar;
  376. Value: PChar;
  377. begin
  378. Result := '';
  379. S := ParamStr(0);
  380. {判断容纳文件版本信息需要一个多大的缓冲区}
  381. iBufSize := GetFileVersionInfoSize(PChar(S), iBufSize);
  382. if iBufSize > 0 then
  383. begin
  384. Buf := AllocMem(iBufSize);
  385. {获取文件版本信息}
  386. GetFileVersionInfo(PChar(S), 0, iBufSize, Buf);
  387. if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\FileVersion'), Pointer(Value), iLen) then
  388. Result := Value;
  389. FreeMem(Buf, iBufSize);
  390. end;
  391. end;
  392. procedure ExcuteTemplateMethod(aMethod: Pointer; Owner: TObject = nil);
  393. begin
  394. Screen.Cursor := crHourGlass;
  395. try
  396. asm
  397. mov EDX, Owner;
  398. cmp EDX, 0;
  399. jz @NotObjectMethod;
  400. mov EAX, Owner;
  401. @NotObjectMethod: call aMethod;
  402. end;
  403. finally
  404. Screen.Cursor := crDefault;
  405. end;
  406. end;
  407. function GetLocateBillsStrings: Integer;
  408. begin
  409. Result := SendMessage(Application.MainForm.Handle, SM_LocateBills, 0, 0);
  410. end;
  411. procedure AutoSaveProjects(const aAutoSave: Boolean; const aSaveInterval: Integer);
  412. begin
  413. SendMessage(Application.MainForm.Handle, SM_AutoSaveProjects, Integer(aAutoSave), aSaveInterval)
  414. end;
  415. function CheckProjectOpened(ASelect: Integer; const AFileName: string): Integer;
  416. begin
  417. Result := SendMessage(Application.MainForm.Handle, SM_CheckProject, ASelect, LongInt(AFileName));
  418. end;
  419. function CompareCodes(ACode1, ABCode1, AName1, ACode2, ABCode2, AName2: string): Integer;
  420. function CompareDiagitCode(AsCode, ACode: string): Integer;
  421. var
  422. s1, s2: string;
  423. p1, p2: Integer;
  424. v1, v2, e1, e2: Integer;
  425. begin
  426. p1 := pos('-', AsCode);
  427. p2 := pos('-', ACode);
  428. while (p1 <> 0) and (p2 <> 0) do
  429. begin
  430. s1 := copy(AsCode, 1, p1 - 1);
  431. s2 := copy(ACode, 1, p2 - 1);
  432. if SameText(s1, s2) then
  433. begin
  434. AsCode := copy(AsCode, p1 + 1, Length(AsCode));
  435. ACode := copy(ACode, p2 + 1, Length(ACode));
  436. p1 := pos('-', AsCode);
  437. p2 := pos('-', ACode);
  438. end
  439. else
  440. begin
  441. Val(s1, v1, e1);
  442. Val(s2, v2, e2);
  443. if (e1 = 0) and (e2 = 0) then
  444. Result := v1 - v2
  445. else Result := CompareText(s1, s2);
  446. Exit;
  447. end;
  448. end;
  449. if (p1 = 0) and (p2 = 0) then
  450. begin
  451. Val(AsCode, v1, e1);
  452. Val(ACode, v2, e2);
  453. if (e1 = 0) and (e2 = 0) then
  454. Result := v1 - v2
  455. else Result := CompareText(AsCode, ACode);
  456. end
  457. else
  458. begin
  459. Result := CompareText(AsCode, ACode);
  460. end;
  461. end;
  462. function TranslateChineseToALB(AWord: WideString): Integer;
  463. const
  464. chaArr: array [0..9] of WideString = ('十', '一', '二', '三', '四',
  465. '五', '六', '七', '八', '九');
  466. function ChnToNum(ANum: WideString): Integer;
  467. var
  468. J: Integer;
  469. begin
  470. Result := -1;
  471. for J := 0 to 9 do
  472. begin
  473. if SameText(ANum, chaArr[J]) then
  474. begin
  475. Result := J;
  476. if Result = 0 then Result := 10;
  477. Break;
  478. end;
  479. end;
  480. end;
  481. var
  482. I, len, icha: Integer;
  483. begin
  484. Result := 0;
  485. len := Length(AWord);
  486. for I := 1 to Len do
  487. begin
  488. icha := ChnToNum(AWord[I]);
  489. if icha = 10 then
  490. begin
  491. if Result = 0 then Result := 10
  492. else Result := Result * 10;
  493. end
  494. else
  495. begin
  496. if Result = 0 then Result := icha
  497. else Result := Result + icha;
  498. end;
  499. end;
  500. end;
  501. function CompareNodeCode(const ASCode, ACode: string; var AResult: Integer): Boolean;
  502. var
  503. l1, l2: Integer;
  504. begin
  505. if SameText(ASCode, ACode) then
  506. begin
  507. Result := False;
  508. Exit;
  509. end;
  510. Result := True;
  511. l1 := -1;
  512. l2 := -1;
  513. if not SameText(ASCode, '') and not SameText(ACode, '') then
  514. begin
  515. if Length(ASCode) - Length(WideString(ASCode)) > 0 then
  516. l1 := TranslateChineseToALB(ASCode);
  517. if Length(ACode) - Length(WideString(ACode)) > 0 then
  518. l2 := TranslateChineseToALB(ACode);
  519. if (l1 = -1) and (l2 = -1) then
  520. AResult := CompareDiagitCode(ASCode, ACode)
  521. else AResult := l1 - l2;
  522. end
  523. else if SameText(ASCode, '') then AResult := -1
  524. else if SameText(ACode, '') then AResult := 1
  525. else Result := False;
  526. end;
  527. function CompareNodeBCode(const ASBCode, ABCode: string; var AResult: Integer): Boolean;
  528. begin
  529. if SameText(ASBCode, ABCode) then
  530. begin
  531. Result := False;
  532. Exit;
  533. end;
  534. Result := True;
  535. if (ASBCode <> '') and (ABCode <> '') then
  536. AResult := CompareDiagitCode(ASBCode, ABCode)
  537. else if ASBCode = '' then AResult := -1
  538. else if ABCode = '' then AResult := 1
  539. else Result := False;
  540. end;
  541. function CompareNodeName(const ASName, AName: string; var AResult: Integer): Boolean;
  542. begin
  543. if (pos('…', ASName) <> 0) or (pos('…', AName) <> 0) then
  544. AResult := CompareText(ASName, AName) * -1
  545. else AResult := CompareText(ASName, AName);
  546. end;
  547. begin
  548. Result := 0;
  549. if CompareNodeCode(ACode1, ACode2, Result) then Exit;
  550. if CompareNodeBCode(ABCode1, ABCode2, Result) then Exit;
  551. CompareNodeName(AName1, AName2, Result);
  552. end;
  553. function CheckFileEnabled(const AFullFileName: string): Boolean;
  554. begin
  555. Result := False;
  556. if AFullFileName = '' then Exit;
  557. if FileExists(AFullFileName) then
  558. begin
  559. if MessageBox(0, pChar('该文件已存在,是否替换?'), PChar('提示'), MB_YESNO) = IDYES then
  560. begin
  561. DeleteFile(AFullFileName);
  562. end
  563. else Exit;
  564. end;
  565. Result := True;
  566. end;
  567. function ScRoundTo(const AValue: Double; const ADigit: Integer = -2): Double;
  568. var
  569. LFactor, Offset, FixOS: Double;
  570. begin
  571. LFactor := IntPower(10, ADigit);
  572. // 修正偏移量
  573. FixOS := 0;
  574. if LFactor < 1 then
  575. FixOS := IntPower(10, ADigit - 2);
  576. if AValue >= 0 then
  577. Offset := 0.5 + FixOS
  578. else
  579. Offset := -0.5 - FixOS;
  580. Result := Trunc((AValue / LFactor) + Offset) * LFactor;
  581. end;
  582. function GetSaveFile: string;
  583. begin
  584. Result := '';
  585. with TSaveDialog.Create(nil) do
  586. begin
  587. InitialDir := ExtractFilePath(ParamStr(0));
  588. Filter := '(*.xls)|*.xls';
  589. DefaultExt := '.xls';
  590. if Execute then
  591. begin
  592. Result := FileName;
  593. end;
  594. Free;
  595. end;
  596. end;
  597. function OpenFileDialog(const aTitle, aDefaultExt, aFileName, aFilter: string; var aNewFileName: string): Boolean;
  598. var
  599. odImport: TOpenDialog;
  600. begin
  601. odImport := TOpenDialog.Create(nil);
  602. try
  603. odImport.Title := aTitle;
  604. odImport.DefaultExt := aDefaultExt;
  605. odImport.FileName := aFileName;
  606. odImport.Filter := aFilter;
  607. odImport.InitialDir := ExtractFilePath(ParamStr(0));
  608. if odImport.Execute then
  609. begin
  610. Result := True;
  611. aNewFileName := odImport.FileName;
  612. end
  613. else
  614. Result := False;
  615. finally
  616. odImport.Free;
  617. end;
  618. end;
  619. function SaveFileDialog(const aTitle, aDefaultExt, aFileName, aFilter: string; var aNewFileName: string): Boolean;
  620. var
  621. odExport: TSaveDialog;
  622. begin
  623. odExport := TSaveDialog.Create(nil);
  624. try
  625. odExport.Title := aTitle;
  626. odExport.DefaultExt := aDefaultExt;
  627. odExport.FileName := aFileName;
  628. odExport.Filter := aFilter;
  629. if odExport.Execute then
  630. begin
  631. Result := True;
  632. aNewFileName := odExport.FileName;
  633. end
  634. else
  635. Result := False;
  636. finally
  637. odExport.Free;
  638. end;
  639. end;
  640. function ProcessIsRunning(const aProcessName: string): Integer;
  641. var
  642. Flag: Bool;
  643. Hadl: THandle;
  644. strProcName, strFullName: string;
  645. ProcessStruct: TProcessEntry32;
  646. begin
  647. Result := 0;
  648. Hadl := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  649. ProcessStruct.dwSize := SizeOf(TProcessEntry32);
  650. Flag := Process32First(Hadl, ProcessStruct);
  651. while Flag do
  652. begin
  653. if ((UpperCase(ExtractFileName(ProcessStruct.szExeFile)) = UpperCase(aProcessName))
  654. or (UpperCase(ProcessStruct.szExeFile) = UpperCase(aProcessName))) then
  655. begin
  656. Inc(Result);
  657. Flag := False;
  658. end
  659. else
  660. Flag := Process32Next(Hadl, ProcessStruct);
  661. end;
  662. CloseHandle(Hadl);
  663. end;
  664. function MacAddress: string;
  665. var
  666. Lib: Cardinal;
  667. Func: function(GUID: PGUID): Longint; stdcall;
  668. GUID1, GUID2: TGUID;
  669. begin
  670. Result := '';
  671. Lib := LoadLibrary('rpcrt4.dll');
  672. if Lib <> 0 then
  673. begin
  674. if Win32Platform <>VER_PLATFORM_WIN32_NT then
  675. @Func := GetProcAddress(Lib, 'UuidCreate')
  676. else @Func := GetProcAddress(Lib, 'UuidCreateSequential');
  677. if Assigned(Func) then
  678. begin
  679. if (Func(@GUID1) = 0) and
  680. (Func(@GUID2) = 0) and
  681. (GUID1.D4[2] = GUID2.D4[2]) and
  682. (GUID1.D4[3] = GUID2.D4[3]) and
  683. (GUID1.D4[4] = GUID2.D4[4]) and
  684. (GUID1.D4[5] = GUID2.D4[5]) and
  685. (GUID1.D4[6] = GUID2.D4[6]) and
  686. (GUID1.D4[7] = GUID2.D4[7]) then
  687. begin
  688. Result :=
  689. IntToHex(GUID1.D4[2], 2) + '-' +
  690. IntToHex(GUID1.D4[3], 2) + '-' +
  691. IntToHex(GUID1.D4[4], 2) + '-' +
  692. IntToHex(GUID1.D4[5], 2) + '-' +
  693. IntToHex(GUID1.D4[6], 2) + '-' +
  694. IntToHex(GUID1.D4[7], 2);
  695. end;
  696. end;
  697. FreeLibrary(Lib);
  698. end;
  699. end;
  700. function LoadServiceQQ: string;
  701. var
  702. sFileName, sServiceQQ: string;
  703. Ini: TIniFile;
  704. begin
  705. sFileName := FixPathByAppPath('pInfo.ini');
  706. {$IFDEF _ScGanSu}
  707. sServiceQQ := '942560844';
  708. {$ElSE}
  709. sServiceQQ := '942560844';
  710. {$ENDIF}
  711. if FileExists(sFileName) then
  712. begin
  713. Ini := TIniFile.Create(sFileName);
  714. Result := Ini.ReadString('ProductInfo', 'ServiceQQ', sServiceQQ);
  715. Ini.Free;
  716. end
  717. else
  718. Result := sServiceQQ;
  719. end;
  720. function GetAveCharSize(Canvas: TCanvas): TPoint;
  721. var
  722. I: Integer;
  723. Buffer: array[0..51] of Char;
  724. begin
  725. for I := 0 to 25 do Buffer[I] := Chr(I + Ord('A'));
  726. for I := 0 to 25 do Buffer[I + 26] := Chr(I + Ord('a'));
  727. GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result));
  728. Result.X := Result.X div 52;
  729. end;
  730. function ScInputBox(const ACaption, APrompt, ADefault: string): string;
  731. begin
  732. Result := ADefault;
  733. ScInputQuery(ACaption, APrompt, Result);
  734. end;
  735. function ScInputQuery(const ACaption, APrompt: string;
  736. var Value: string; ANeedMark: Boolean): Boolean;
  737. var
  738. Form: TForm;
  739. Prompt: TLabel;
  740. Edit: TEdit;
  741. DialogUnits: TPoint;
  742. ButtonTop, ButtonWidth, ButtonHeight: Integer;
  743. begin
  744. Result := False;
  745. Form := TForm.Create(Application);
  746. with Form do
  747. try
  748. Canvas.Font := Font;
  749. DialogUnits := GetAveCharSize(Canvas);
  750. BorderStyle := bsDialog;
  751. Caption := ACaption;
  752. ClientWidth := MulDiv(180, DialogUnits.X, 4);
  753. Position := poScreenCenter;
  754. Prompt := TLabel.Create(Form);
  755. Font.Name := 'smartSimSun';
  756. Font.Size := 9;
  757. with Prompt do
  758. begin
  759. Parent := Form;
  760. Caption := APrompt;
  761. Left := MulDiv(8, DialogUnits.X, 4);
  762. Top := MulDiv(8, DialogUnits.Y, 8);
  763. Font.Name := 'smartSimSun';
  764. Font.Size := 9;
  765. Constraints.MaxWidth := MulDiv(164, DialogUnits.X, 4);
  766. WordWrap := True;
  767. end;
  768. Edit := TEdit.Create(Form);
  769. with Edit do
  770. begin
  771. Parent := Form;
  772. Left := Prompt.Left;
  773. Top := Prompt.Top + Prompt.Height + 5;
  774. Width := MulDiv(164, DialogUnits.X, 4);
  775. Font.Name := 'smartSimSun';
  776. Font.Size := 9;
  777. if ANeedMark then
  778. PasswordChar := '*';
  779. MaxLength := 255;
  780. Text := Value;
  781. SelectAll;
  782. end;
  783. ButtonTop := Edit.Top + Edit.Height + 15;
  784. ButtonWidth := MulDiv(50, DialogUnits.X, 4);
  785. ButtonHeight := MulDiv(14, DialogUnits.Y, 8);
  786. with TButton.Create(Form) do
  787. begin
  788. Parent := Form;
  789. Caption := '确定(&O)';
  790. ModalResult := mrOk;
  791. Default := True;
  792. Font.Name := 'smartSimSun';
  793. Font.Size := 9;
  794. SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth,
  795. ButtonHeight);
  796. end;
  797. with TButton.Create(Form) do
  798. begin
  799. Parent := Form;
  800. Caption := '取消(&C)';
  801. ModalResult := mrCancel;
  802. Cancel := True;
  803. Font.Name := 'smartSimSun';
  804. Font.Size := 9;
  805. SetBounds(MulDiv(92, DialogUnits.X, 4), Edit.Top + Edit.Height + 15,
  806. ButtonWidth, ButtonHeight);
  807. Form.ClientHeight := Top + Height + 13;
  808. end;
  809. if ShowModal = mrOk then
  810. begin
  811. Value := Edit.Text;
  812. Result := True;
  813. end;
  814. finally
  815. Form.Free;
  816. end;
  817. end;
  818. // 输入密码
  819. function InputPassWord(var APwd: string): Boolean;
  820. begin
  821. Result := ScInputQuery('验证密码', '请输入当前文件的密码', APwd, True);
  822. end;
  823. // 修改或设置密码
  824. function SetupPassWord(var APwd: string): Boolean;
  825. var
  826. NewPwd1, NewPwd2: string;
  827. begin
  828. Result := ScInputQuery('设置密码', '请输入新密码'#13#10'(密码长度不得超过32个字符,区分大小写)', NewPwd1, True);
  829. if Result then
  830. begin
  831. Result := ScInputQuery('确认密码', '请再输入一遍新密码', NewPwd2, True);
  832. if Result then
  833. begin
  834. Result := CompareStr(NewPwd1, NewPwd2) = 0;
  835. if Result then
  836. APwd := NewPwd1
  837. else
  838. MessageHint(0, '两次输入的密码不同,无法设置密码。');
  839. end;
  840. end;
  841. end;
  842. const
  843. LocalIDFile = 'LocalID.dat';
  844. function GetLocalGUID: TGUID;
  845. var
  846. strFileName: string;
  847. stmGUIDFile: TFileStream;
  848. begin
  849. strFileName := ExtractFilePath(ParamStr(0)) + LocalIDFile;
  850. if FileExists(strFileName) then
  851. begin
  852. stmGUIDFile := TFileStream.Create(strFileName, fmOpenRead);
  853. stmGUIDFile.Seek(0, soFromBeginning);
  854. stmGUIDFile.Read(Result, SizeOf(TGUID));
  855. stmGUIDFile.Free;
  856. end
  857. else
  858. begin
  859. CreateGUID(Result);
  860. stmGUIDFile := TFileStream.Create(strFileName, fmCreate);
  861. stmGUIDFile.Seek(0, soFromBeginning);
  862. stmGUIDFile.Write(Result, SizeOf(TGUID));
  863. stmGUIDFile.Free;
  864. end;
  865. end;
  866. function IsLocalGUID(AGUID: TGUID): Boolean;
  867. var
  868. LocalGUID: TGUID;
  869. begin
  870. Result := False;
  871. LocalGUID := GetLocalGUID;
  872. if (LocalGUID.D1 = AGUID.D1) and (LocalGUID.D2 = AGUID.D2)
  873. and (LocalGUID.D3 = AGUID.D3) and (Int64(LocalGUID.D4) = Int64(AGUID.D4)) then
  874. Result := True;
  875. end;
  876. function FixPathByAppPath(const AFileName: string): string;
  877. begin
  878. Result := AFileName;
  879. if AnsiPos(':\', Result) = 0 then
  880. begin
  881. if (Result <> '') and (Result[1] = '\') then
  882. Delete(Result, 1, 1);
  883. Result := ExtractFilePath(ParamStr(0)) + Result;
  884. end;
  885. end;
  886. function GetPreCode(const ACode: string): string;
  887. var
  888. bFlag: Boolean;
  889. I, iLen: Integer;
  890. begin
  891. bFlag := True;
  892. Result := ACode;
  893. iLen := Length(ACode);
  894. for I := iLen downto 1 do
  895. begin
  896. if ACode[I] = '-' then
  897. begin
  898. Delete(Result, I, iLen);
  899. bFlag := False;
  900. Break;
  901. end;
  902. end;
  903. if bFlag then Result := '';
  904. end;
  905. procedure ClearPointerList(AList: TList);
  906. var
  907. I: Integer;
  908. begin
  909. for I := 0 to AList.Count - 1 do
  910. begin
  911. if Assigned(AList[I]) then
  912. Dispose(AList[I]);
  913. end;
  914. AList.Clear;
  915. end;
  916. procedure ClearObjectList(aList: TList);
  917. var
  918. I: Integer;
  919. begin
  920. for I := 0 to aList.Count - 1 do
  921. begin
  922. if Assigned(aList.List^[I]) then
  923. TObject(aList.List^[I]).Free;
  924. end;
  925. aList.Clear;
  926. end;
  927. function CompareCode(const Code1, Code2: string): Integer;
  928. var
  929. iPos1 : Integer;
  930. iPos2 : Integer;
  931. iError : Integer;
  932. iValue1: Integer;
  933. iValue2: Integer;
  934. sCode1: string;
  935. sCode2: string;
  936. begin
  937. if Code1 = Code2 then
  938. begin
  939. Result := 0;
  940. Exit;
  941. end;
  942. sCode1 := Code1;
  943. sCode2 := Code2;
  944. iPos1 := Pos('-', sCode1);
  945. iPos2 := Pos('-', sCode2);
  946. while (iPos1 <> 0) and (iPos2 <> 0) do
  947. begin
  948. Val(sCode1, iValue1, iError);
  949. Val(sCode2, iValue2, iError);
  950. if iValue1 > iValue2 then
  951. begin
  952. Result := 1;
  953. Exit;
  954. end
  955. else if iValue1 < iValue2 then
  956. begin
  957. Result := -1;
  958. Exit;
  959. end
  960. else
  961. Result := 0;
  962. sCode1 := Copy(sCode1, iPos1 + 1, Length(sCode1));
  963. sCode2 := Copy(sCode2, iPos2 + 1, Length(sCode2));
  964. iPos1 := Pos('-', sCode1);
  965. iPos2 := Pos('-', sCode2);
  966. end;
  967. Val(sCode1, iValue1, iError);
  968. Val(sCode2, iValue2, iError);
  969. if iValue1 > iValue2 then
  970. Result := 1
  971. else if iValue1 < iValue2 then
  972. Result := -1
  973. else
  974. begin
  975. { if iPos1 = 0 then
  976. Result := -1
  977. else if iPos2 = 0 then
  978. Result := 1; }
  979. // 比较最后一节,如2A和2B、A和B等 chenshilong, 2013-08-20
  980. if sCode1 > sCode2 then
  981. Result := 1
  982. else if sCode1 < sCode2 then
  983. Result := -1
  984. else
  985. Result := 0;
  986. end;
  987. end;
  988. {
  989. function CompareCodeWithChar(const ACode1, ACode2: string; ADelimiter: Char = '-'): Integer;
  990. var
  991. sgs1, sgs2: TStrings;
  992. I, iError1, iError2: Integer;
  993. iV1, iV2: Integer;
  994. begin
  995. Result := 0;
  996. if (ACode1 = '') and (ACode2 = '') then Exit;
  997. sgs1 := TStringList.Create;
  998. sgs2 := TStringList.Create;
  999. sgs1.Delimiter := ADelimiter;
  1000. sgs2.Delimiter := ADelimiter;
  1001. sgs1.DelimitedText := ACode1;
  1002. sgs2.DelimitedText := ACode2;
  1003. for I := 0 to Min(sgs1.Count, sgs2.Count) - 1 do
  1004. begin
  1005. Val(sgs1[I], iV1, iError1);
  1006. val(sgs2[I], iV2, iError2);
  1007. if (iError1 = 0) and (iError2 = 0) then
  1008. Result := iV1 - iV2
  1009. else
  1010. Result := CompareText(sgs1[I], sgs2[I]);
  1011. if Result <> 0 then Break;
  1012. end;
  1013. if Result = 0 then
  1014. Result := sgs1.Count - sgs2.Count;
  1015. sgs1.Free;
  1016. sgs2.Free;
  1017. end; }
  1018. // 补0算法 chenshilong, 2014-04-28
  1019. function CompareCodeWithChar(const ACode1, ACode2: string; ADelimiter: Char = '-'): Integer;
  1020. function FormatCodeSort(ACode: string; ALength: Integer = 3): string;
  1021. var vSL, vSL2: TStringList;
  1022. i: Integer;
  1023. s: string;
  1024. begin
  1025. vSL := TStringList.Create;
  1026. vSL2 := TStringList.Create;
  1027. try
  1028. vSL.Delimiter := '-';
  1029. vSL.DelimitedText := ACode;
  1030. vSL2.Clear;
  1031. for i := 0 to vSL.Count - 1 do
  1032. begin
  1033. s := vSL[i];
  1034. while Length(s) < ALength do
  1035. s := '0' + s;
  1036. // 3要排在1A的后面,结果003排到01A的前面了,所以改成:003,001A,即带字母的要多加一个0
  1037. s := UpperCase(s);
  1038. if (Pos('A', s) > 0) or (Pos('B', s) > 0) or (Pos('C', s) > 0) or
  1039. (Pos('D', s) > 0) then
  1040. s := '0' + s;
  1041. vSL2.Add(s);
  1042. end;
  1043. vSL2.Delimiter := '-';
  1044. Result := vSL2.DelimitedText;
  1045. finally
  1046. vSL.Free;
  1047. vSL2.Free;
  1048. end;
  1049. end;
  1050. var sCode1, sCode2: String;
  1051. begin
  1052. sCode1 := FormatCodeSort(ACode1);
  1053. sCode2 := FormatCodeSort(ACode2);
  1054. if (sCode1 > sCode2) then
  1055. Result := 1
  1056. else if (sCode1 = sCode2) then
  1057. Result := 0
  1058. else
  1059. Result := -1;
  1060. end;
  1061. function ScCompareFileVer(AVersion1: string; AVersion2: string; APartCount: Integer = 4): Integer;
  1062. var
  1063. aVer1, aVer2: array [1..4] of Integer;
  1064. I: Integer;
  1065. begin
  1066. if SameText(AVersion1, AVersion2) then
  1067. begin
  1068. Result := 0;
  1069. Exit;
  1070. end;
  1071. if ScDecodeFileVer(AVersion1, aVer1[1], aVer1[2], aVer1[3], aVer1[4]) and
  1072. ScDecodeFileVer(AVersion2, aVer2[1], aVer2[2], aVer2[3], aVer2[4]) then
  1073. begin
  1074. Result := 0;
  1075. for I := 1 to APartCount do
  1076. begin
  1077. if aVer1[I] > aVer2[I] then
  1078. begin
  1079. Result := I;
  1080. Exit;
  1081. end
  1082. else if aVer1[I] < aVer2[I] then
  1083. begin
  1084. Result := -I;
  1085. Exit;
  1086. end
  1087. end;
  1088. end
  1089. else
  1090. raise Exception.Create('无法比较文件版本!');
  1091. end;
  1092. function ScDecodeFileVer(AVersion: string; var V1, V2, V3, V4: Integer): Boolean;
  1093. var
  1094. strVer: string;
  1095. function GetFirstVerPart(var AVer: string): Integer;
  1096. var
  1097. iPos, iValue, iCode: Integer;
  1098. sFirstVer: string;
  1099. begin
  1100. Result := -1;
  1101. iPos := Pos('.', AVer);
  1102. if iPos > 0 then
  1103. begin
  1104. sFirstVer := Copy(AVer, 1, iPos - 1);
  1105. Delete(AVer, 1, iPos);
  1106. end
  1107. else
  1108. begin
  1109. sFirstVer := AVer;
  1110. AVer := '';
  1111. end;
  1112. Val(sFirstVer, iValue, iCode);
  1113. if iCode = 0 then
  1114. Result := iValue;
  1115. end;
  1116. begin
  1117. Result := False;
  1118. strVer := AVersion;
  1119. V1 := GetFirstVerPart(strVer);
  1120. if V1 < 0 then Exit;
  1121. V2 := GetFirstVerPart(strVer);
  1122. if V2 < 0 then Exit;
  1123. V3 := GetFirstVerPart(strVer);
  1124. if V3 < 0 then Exit;
  1125. V4 := GetFirstVerPart(strVer);
  1126. if V4 < 0 then Exit;
  1127. Result := True;
  1128. end;
  1129. function GetTempFilePath: string;
  1130. var
  1131. TempPath: string;
  1132. begin
  1133. TempPath := GetEnvironmentVariable('TMP');
  1134. if TempPath = '' then
  1135. TempPath := GetEnvironmentVariable('TEMP');
  1136. if TempPath = '' then
  1137. begin
  1138. if not DirectoryExists(ExtractFileDir(Application.ExeName) + '\Temp') then
  1139. CreateDir(ExtractFileDir(Application.ExeName) + '\Temp');
  1140. TempPath := ExtractFileDir(Application.ExeName) + '\Temp';
  1141. end;
  1142. Result := TempPath + '\';
  1143. // Test
  1144. // } Result := 'D:\TestTemp\';
  1145. end;
  1146. function GetTempFileName(AExt: string): string;
  1147. var
  1148. Ext: string;
  1149. begin
  1150. if AExt = '' then
  1151. Ext := STempFileExt
  1152. else
  1153. Ext := AExt;
  1154. Result := GetTempFilePath + GetTempName + Ext;
  1155. while FileExists(Result) do
  1156. begin
  1157. Result := GetTempFilePath + GetTempName + Ext;
  1158. end;
  1159. end;
  1160. function GetTempName(ALength: Integer): string;
  1161. const
  1162. CodedBuf: array[0..35] of Char = ('0', '1', '2', '3', '4', '5',
  1163. '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
  1164. 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
  1165. 'W', 'X', 'Y', 'Z');
  1166. var
  1167. Temp: string;
  1168. Num: Integer;
  1169. begin
  1170. Randomize;
  1171. Temp := '';
  1172. while Length(Temp) < ALength do
  1173. begin
  1174. Num := Random(37);
  1175. If Num <> 36 Then
  1176. Temp := Temp + CodedBuf[Num]; // 0..35
  1177. end;
  1178. Result := Temp;
  1179. end;
  1180. function CreateFullDir(ADir: string): Boolean;
  1181. var
  1182. strTemp, strDir: string;
  1183. iPos: Integer;
  1184. bInit, bResult: Boolean;
  1185. begin
  1186. Result := False;
  1187. bInit := False;
  1188. strTemp := ADir;
  1189. iPos := Pos(':\', strTemp);
  1190. if iPos = 0 then
  1191. begin
  1192. //if strTemp[1] <> '\' then
  1193. // strTemp := '\' + strTemp;
  1194. if strTemp[1] = '\' then
  1195. Delete(strTemp, 1, 1);
  1196. strTemp := ExtractFilePath(Application.ExeName) + strTemp;
  1197. end;
  1198. strDir := Copy(strTemp, 1, 3);
  1199. Delete(strTemp, 1, 3);
  1200. while strTemp <> '' do
  1201. begin
  1202. iPos := Pos('\', strTemp);
  1203. if (iPos = 0) and (strTemp <> '') then
  1204. begin
  1205. strDir := strDir + strTemp;
  1206. strTemp := '';
  1207. end
  1208. else
  1209. begin
  1210. strDir := strDir + Copy(strTemp, 1, iPos);
  1211. Delete(strTemp, 1, iPos);
  1212. end;
  1213. bResult := DirectoryExists(strDir);
  1214. if not bResult then
  1215. bResult := CreateDir(strDir);
  1216. if (not bInit) and bResult then
  1217. begin
  1218. bInit := True;
  1219. Result := True;
  1220. end;
  1221. if (not bResult) and Result then
  1222. Result := False;
  1223. end;
  1224. end;
  1225. procedure FixFileExt(var AFileName: string; const AExt: string; AutoReplace: Boolean);
  1226. var
  1227. OldExt: string;
  1228. OldExtLen: Integer;
  1229. begin
  1230. OldExt := ExtractFileExt(AFileName);
  1231. if not SameText(OldExt, AExt) then
  1232. begin
  1233. if AutoReplace then
  1234. begin
  1235. OldExtLen := Length(OldExt);
  1236. Delete(AFileName, Length(AFileName) - OldExtLen + 1, OldExtLen);
  1237. AFileName := AFileName + AExt;
  1238. end
  1239. else
  1240. AFileName := AFileName + AExt;
  1241. end;
  1242. end;
  1243. function SystemDateTime: TDateTime;
  1244. begin
  1245. Result := Now;
  1246. if _ServerDateTime > 0 then
  1247. Result := _ServerDateTime;
  1248. end;
  1249. function CompileDateTime: TDateTime;
  1250. const
  1251. SmartCostCompileDate = '2009-10-19';
  1252. begin
  1253. try
  1254. Result := StrToDate(SmartCostCompileDate);
  1255. except
  1256. Result := 40105;
  1257. end;
  1258. end;
  1259. function BillCategory(ACode, AB_Code: string): TBillCategory;
  1260. begin
  1261. ACode := Trim(ACode);
  1262. AB_Code := Trim(AB_Code);
  1263. // 预算项目节 (只要Code不为空皆认为是)
  1264. if (ACode <> '') then
  1265. Result := bcYSXMJ
  1266. // 清单子目号 (Code为空B_Code不为空)
  1267. else if (AB_Code <> '') then
  1268. Result := bcQDZMH
  1269. // Code、B_Code都为空
  1270. else
  1271. Result := bcTZGCL;
  1272. end;
  1273. {-------------------------------------------------------------------------------
  1274. 方法: FormatBCodeAlpha
  1275. 说明: 将B_Code值中含“10”、“11”的替换成“A”、“B”等字母,便于排序。
  1276. 最前头的数字不要替换,因为报表中需要取第一位数字分章。
  1277. B_Code形如“205-1-20-1”。
  1278. 作者: Chenshilong, 2010-5-6 16:10:34
  1279. -------------------------------------------------------------------------------}
  1280. function FormatBCodeAlpha(AB_Code: string): String;
  1281. var
  1282. vSL: TStringList;
  1283. i, iTemp: Integer;
  1284. sTemp, sValue: string;
  1285. procedure SplitString(Source, Separator: string; AStringList: TStringList);
  1286. var
  1287. Po: byte;
  1288. begin
  1289. while Pos(Separator, Source) > 0 do
  1290. begin
  1291. Po := Pos(Separator, Source);
  1292. AStringList.add(Copy(Source, 1, Po - 1));
  1293. Source := Copy(Source, Po + length(Separator), length(Source) - Po);
  1294. end;
  1295. AStringList.Add(source);
  1296. end;
  1297. begin
  1298. if Trim(AB_Code) = '' then
  1299. begin
  1300. Result := '';
  1301. Exit;
  1302. end;
  1303. sTemp := '';
  1304. sValue := '';
  1305. vSL := TStringList.Create;
  1306. SplitString(AB_Code, '-', vSL);
  1307. // 如果B_Code不含“-”,则直接返回AB_Code值。
  1308. if vSL.Count < 2 then
  1309. sValue := AB_Code
  1310. else
  1311. begin
  1312. for i := 0 to vSL.Count - 1 do
  1313. begin
  1314. // 只替换两位数
  1315. if Length(vSL[i]) = 2 then
  1316. begin
  1317. try
  1318. iTemp := StrToInt(vSL[i]);
  1319. if not IntToIdent(iTemp, sTemp, NumStrToAlpha) then
  1320. sTemp := vSL[i];
  1321. except
  1322. sTemp := vSL[i];
  1323. end;
  1324. end
  1325. else
  1326. begin
  1327. sTemp := vSL[i];
  1328. end;
  1329. if sValue <> '' then
  1330. sValue := sValue + '-' + sTemp
  1331. else
  1332. sValue := sTemp;
  1333. end;
  1334. end;
  1335. Result := sValue;
  1336. end;
  1337. end.