📄 cncommon.pas
字号:
Result := Tail; Exit; end; end else begin if Copy(ATail, 1, 2) = '.\' then Delete(ATail, 1, 2); AHead := MakeDir(AHead); i := Pos('..\', ATail); while i > 0 do begin AHead := ExtractFileDir(AHead); Delete(ATail, 1, 3); i := Pos('..\', ATail); end; Result := MakePath(AHead) + ATail; end; if HeadIsUrl then Result := StringReplace(Result, '\', '/', [rfReplaceAll]);end;// 运行一个文件procedure RunFile(const FName: string; Handle: THandle; const Param: string);begin ShellExecute(Handle, nil, PChar(FName), PChar(Param), nil, SW_SHOWNORMAL);end;// 打开一个链接procedure OpenUrl(const Url: string);const csPrefix = 'http://';var AUrl: string;begin if Pos(csPrefix, Url) < 1 then AUrl := csPrefix + Url else AUrl := Url; RunFile(AUrl);end;// 发送邮件procedure MailTo(const Addr: string; const Subject: string = '');const csPrefix = 'mailto:'; csSubject = '?Subject=';var Url: string;begin if Pos(csPrefix, Addr) < 1 then Url := csPrefix + Addr else Url := Addr; if Subject <> '' then Url := Url + csSubject + Subject; RunFile(Url);end;// 运行一个文件并立即返回function WinExecute(FileName: string; Visibility: Integer = SW_NORMAL): Boolean;var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation;begin FillChar(StartupInfo, SizeOf(StartupInfo), #0); StartupInfo.cb := SizeOf(StartupInfo); StartupInfo.dwFlags := STARTF_USESHOWWINDOW; StartupInfo.wShowWindow := Visibility; Result := CreateProcess(nil, PChar(FileName), nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);end;// 运行一个文件并等待其结束function WinExecAndWait32(FileName: string; Visibility: Integer; ProcessMsg: Boolean): Integer;var zAppName: array[0..512] of Char; zCurDir: array[0..255] of Char; WorkDir: string; StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation;begin StrPCopy(zAppName, FileName); GetDir(0, WorkDir); StrPCopy(zCurDir, WorkDir); FillChar(StartupInfo, SizeOf(StartupInfo), #0); StartupInfo.cb := SizeOf(StartupInfo); StartupInfo.dwFlags := STARTF_USESHOWWINDOW; StartupInfo.wShowWindow := Visibility; if not CreateProcess(nil, zAppName, { pointer to command line string } nil, { pointer to process security attributes } nil, { pointer to thread security attributes } False, { handle inheritance flag } CREATE_NEW_CONSOLE or { creation flags } NORMAL_PRIORITY_CLASS, nil, { pointer to new environment block } nil, { pointer to current directory name } StartupInfo, { pointer to STARTUPINFO } ProcessInfo) then Result := -1 { pointer to PROCESS_INF } else begin if ProcessMsg then begin repeat Application.ProcessMessages; GetExitCodeProcess(ProcessInfo.hProcess, Cardinal(Result)); until (Result <> STILL_ACTIVE) or Application.Terminated; end else begin WaitforSingleObject(ProcessInfo.hProcess, INFINITE); GetExitCodeProcess(ProcessInfo.hProcess, Cardinal(Result)); end; end;end;// 用管道方式在 Dir 目录执行 CmdLine,Output 返回输出信息,// dwExitCode 返回退出码。如果成功返回 Truefunction WinExecWithPipe(const CmdLine, Dir: string; slOutput: TStrings; var dwExitCode: Cardinal): Boolean;var HOutRead, HOutWrite: THandle; StartInfo: TStartupInfo; ProceInfo: TProcessInformation; sa: TSecurityAttributes; InStream: THandleStream; strTemp: string; PDir: PChar; procedure ReadLinesFromPipe(IsEnd: Boolean); var s: string; ls: TStringList; i: Integer; begin if InStream.Position < InStream.Size then begin SetLength(s, InStream.Size - InStream.Position); InStream.Read(PChar(s)^, InStream.Size - InStream.Position); strTemp := strTemp + s; ls := TStringList.Create; try ls.Text := strTemp; for i := 0 to ls.Count - 2 do slOutput.Add(ls[i]); strTemp := ls[ls.Count - 1]; finally ls.Free; end; end; if IsEnd and (strTemp <> '') then begin slOutput.Add(strTemp); strTemp := ''; end; end;begin dwExitCode := 0; Result := False; try FillChar(sa, sizeof(sa), 0); sa.nLength := sizeof(sa); sa.bInheritHandle := True; sa.lpSecurityDescriptor := nil; InStream := nil; strTemp := ''; HOutRead := INVALID_HANDLE_VALUE; HOutWrite := INVALID_HANDLE_VALUE; try Win32Check(CreatePipe(HOutRead, HOutWrite, @sa, 0)); FillChar(StartInfo, SizeOf(StartInfo), 0); StartInfo.cb := SizeOf(StartInfo); StartInfo.wShowWindow := SW_HIDE; StartInfo.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; StartInfo.hStdError := HOutWrite; StartInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE); StartInfo.hStdOutput := HOutWrite; InStream := THandleStream.Create(HOutRead); if Dir <> '' then PDir := PChar(Dir) else PDir := nil; Win32Check(CreateProcess(nil, //lpApplicationName: PChar PChar(CmdLine), //lpCommandLine: PChar nil, //lpProcessAttributes: PSecurityAttributes nil, //lpThreadAttributes: PSecurityAttributes True, //bInheritHandles: BOOL NORMAL_PRIORITY_CLASS, //CREATE_NEW_CONSOLE, nil, PDir, StartInfo, ProceInfo)); while WaitForSingleObject(ProceInfo.hProcess, 100) = WAIT_TIMEOUT do begin ReadLinesFromPipe(False); Application.ProcessMessages; //if Application.Terminated then break; end; ReadLinesFromPipe(True); GetExitCodeProcess(ProceInfo.hProcess, dwExitCode); CloseHandle(ProceInfo.hProcess); CloseHandle(ProceInfo.hThread); Result := True; finally if InStream <> nil then InStream.Free; if HOutRead <> INVALID_HANDLE_VALUE then CloseHandle(HOutRead); if HOutWrite <> INVALID_HANDLE_VALUE then CloseHandle(HOutWrite); end; except ; end;end;function WinExecWithPipe(const CmdLine, Dir: string; var Output: string; var dwExitCode: Cardinal): Boolean;var slOutput: TStringList;begin slOutput := TStringList.Create; try Result := WinExecWithPipe(CmdLine, Dir, slOutput, dwExitCode); Output := slOutput.Text; finally slOutput.Free; end;end;// 应用程序路径function AppPath: string;begin Result := ExtractFilePath(Application.ExeName);end;// 当前执行模块所在的路径function ModulePath: string;var ModName: array[0..MAX_PATH] of Char;begin SetString(Result, ModName, GetModuleFileName(HInstance, ModName, SizeOf(ModName))); Result := ExtractFilePath(Result);end;const HKLM_CURRENT_VERSION_WINDOWS = 'Software\Microsoft\Windows\CurrentVersion'; HKLM_CURRENT_VERSION_NT = 'Software\Microsoft\Windows NT\CurrentVersion';function RelativeKey(const Key: string): PChar;begin Result := PChar(Key); if (Key <> '') and (Key[1] = '\') then Inc(Result);end;function RegReadStringDef(const RootKey: HKEY; const Key, Name, Def: string): string;var RegKey: HKEY; Size: DWORD; StrVal: string; RegKind: DWORD;begin Result := Def; if RegOpenKeyEx(RootKey, RelativeKey(Key), 0, KEY_READ, RegKey) = ERROR_SUCCESS then begin RegKind := 0; Size := 0; if RegQueryValueEx(RegKey, PChar(Name), nil, @RegKind, nil, @Size) = ERROR_SUCCESS then if RegKind in [REG_SZ, REG_EXPAND_SZ] then begin SetLength(StrVal, Size); if RegQueryValueEx(RegKey, PChar(Name), nil, @RegKind, PByte(StrVal), @Size) = ERROR_SUCCESS then begin SetLength(StrVal, StrLen(PChar(StrVal))); Result := StrVal; end; end; RegCloseKey(RegKey); end;end;procedure StrResetLength(var S: AnsiString);begin SetLength(S, StrLen(PChar(S)));end;// 取Program Files目录function GetProgramFilesDir: string;begin Result := RegReadStringDef(HKEY_LOCAL_MACHINE, HKLM_CURRENT_VERSION_WINDOWS, 'ProgramFilesDir', '');end;// 取Windows目录function GetWindowsDir: string;var Required: Cardinal;begin Result := ''; Required := GetWindowsDirectory(nil, 0); if Required <> 0 then begin SetLength(Result, Required); GetWindowsDirectory(PChar(Result), Required); StrResetLength(Result); end;end;// 取临时文件路径function GetWindowsTempPath: string;var Required: Cardinal;begin Result := ''; Required := GetTempPath(0, nil); if Required <> 0 then begin SetLength(Result, Required); GetTempPath(Required, PChar(Result)); StrResetLength(Result); end;end;// 返回一个临时文件名function CnGetTempFileName(const Ext: string): string;var Path: string;begin Path := MakePath(GetWindowsTempPath); repeat Result := Path + IntToStr(Random(MaxInt)) + Ext; until not FileExists(Result);end;// 取系统目录function GetSystemDir: string;var Required: Cardinal;begin Result := ''; Required := GetSystemDirectory(nil, 0); if Required <> 0 then begin SetLength(Result, Required); GetSystemDirectory(PChar(Result), Required); StrResetLength(Result); end;end;var _Kernel32Handle: HMODULE = HMODULE(0); _GetLongPathName: function (lpszShortPath: PAnsiChar; lpszLongPath: PAnsiChar; cchBuffer: DWORD): DWORD; stdcall;function Kernel32Handle: HMODULE;begin if _Kernel32Handle = HMODULE(0) then _Kernel32Handle := LoadLibrary(kernel32); Result := _Kernel32Handle;end;function ShellGetLongPathName(const Path: string): string;var PIDL: PItemIDList; Desktop: IShellFolder; AnsiName: string; WideName: array [0..MAX_PATH] of WideChar; Eaten, Attr: ULONG;begin Result := Path; if Path <> '' then begin if Succeeded(SHGetDesktopFolder(Desktop)) then begin MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, PChar(Path), -1, WideName, MAX_PATH); if Succeeded(Desktop.ParseDisplayName(0, nil, WideName, Eaten, PIDL, Attr)) then try SetLength(AnsiName, MAX_PATH); if SHGetPathFromIDList(PIDL, PChar(AnsiName)) then StrResetLength(AnsiName); Result := AnsiName; finally CoTaskMemFree(PIDL); end; end; end;end;// 短文件名转长文件名function ShortNameToLongName(const FileName: string): string;begin Result := FileName; if not Assigned(_GetLongPathName) then _GetLongPathName := GetProcAddress(Kernel32Handle, 'GetLongPathNameA'); if Assigned(_GetLongPathName) then begin SetLength(Result, MAX_PATH); SetLength(Result, _GetLongPathName(PChar(FileName), PChar(Result), MAX_PATH)); end else begin Result := ShellGetLongPathName(FileName); end;end;// 长文件名转短文件名function LongNameToShortName(const FileName: string): string;var Buf: PChar; BufSize: Integer;begin BufSize := GetShortPathName(PChar(FileName), nil, 0) + 1; GetMem(Buf, BufSize); try GetShortPathName(PChar(FileName), Buf, BufSize); Result := Buf; finally FreeMem(Buf); end;end;// 取得真实长文件名,包含大小写function GetTrueFileName(const FileName: string): string;var AName: string; FindName: string; function DoFindFile(const FName: string): string; var F: TSearchRec; begin if SysUtils.FindFirst(FName, faAnyFile, F) = 0 then Result := F.Name else Result := ExtractFileName(FName); SysUtils.FindClose(F);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -