doublecmd/src/ffileunlock.pas

172 lines
4.5 KiB
ObjectPascal

unit fFileUnlock;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
Grids, uFileUnlock;
type
{ TfrmFileUnlock }
TfrmFileUnlock = class(TForm)
btnUnlockAll: TButton;
btnUnlock: TButton;
btnClose: TButton;
btnTerminate: TButton;
stgFileHandles: TStringGrid;
procedure btnTerminateClick(Sender: TObject);
procedure btnUnlockAllClick(Sender: TObject);
procedure btnUnlockClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure stgFileHandlesDblClick(Sender: TObject);
procedure stgFileHandlesSelection(Sender: TObject; aCol, aRow: Integer);
private
procedure ShowThread;
procedure UnlockRow(Index: Integer);
public
end;
function ShowUnlockForm(ProcessInfo: TProcessInfoArray): Boolean;
implementation
{$R *.lfm}
uses
Windows, Math, LCLStrConsts, DCConvertEncoding, fMain, uMyWindows, uLng;
function ShowUnlockForm(ProcessInfo: TProcessInfoArray): Boolean;
var
Index: Integer;
UnlockEnabled: Boolean = False;
begin
with TfrmFileUnlock.Create(frmMain) do
try
stgFileHandles.RowCount:= Length(ProcessInfo) + 1;
for Index:= 1 to stgFileHandles.RowCount - 1 do
begin
if (ProcessInfo[Index - 1].FileHandle <> 0) then begin
UnlockEnabled:= True;
stgFileHandles.Cells[0, Index]:= IntToStr(ProcessInfo[Index - 1].FileHandle);
end;
stgFileHandles.Cells[1, Index]:= IntToStr(ProcessInfo[Index - 1].ProcessId);
stgFileHandles.Cells[2, Index]:= ProcessInfo[Index - 1].ExecutablePath;
end;
btnUnlockAll.Enabled:= UnlockEnabled;
btnTerminate.Enabled:= Length(ProcessInfo) > 0;
stgFileHandles.Row:= IfThen(UnlockEnabled, 1, 0);
btnUnlock.Enabled:= UnlockEnabled and (Length(stgFileHandles.Cells[0, 1]) > 0);
TThread.Synchronize(nil, @ShowThread);
Result:= (ModalResult = mrOK);
finally
Free;
end;
end;
{ TfrmFileUnlock }
procedure TfrmFileUnlock.stgFileHandlesSelection(Sender: TObject; aCol, aRow: Integer);
begin
btnUnlock.Enabled:= (aRow > 0) and (Length(stgFileHandles.Cells[0, aRow]) > 0);
end;
procedure TfrmFileUnlock.btnUnlockClick(Sender: TObject);
begin
UnlockRow(stgFileHandles.Row);
if (stgFileHandles.RowCount = 1) then
begin
Close;
ModalResult:= mrOK;
end;
end;
procedure TfrmFileUnlock.FormShow(Sender: TObject);
var
Index: Integer;
begin
for Index:= 0 to stgFileHandles.Columns.Count - 1 do
begin
stgFileHandles.Columns[Index].Width:= stgFileHandles.Canvas.TextWidth(stgFileHandles.Columns[Index].Title.Caption + 'W');
end;
end;
procedure TfrmFileUnlock.stgFileHandlesDblClick(Sender: TObject);
var
AHandle: HWND;
ProcessId: DWORD;
begin
if (stgFileHandles.Row > 0) then
begin
ProcessId:= StrToDWord(stgFileHandles.Cells[1, stgFileHandles.Row]);
AHandle:= FindMainWindow(ProcessId);
if AHandle <> 0 then ShowWindowEx(AHandle);
end;
end;
procedure TfrmFileUnlock.btnUnlockAllClick(Sender: TObject);
var
Index: Integer;
begin
for Index:= stgFileHandles.RowCount - 1 downto 1 do
begin
UnlockRow(Index);
end;
if (stgFileHandles.RowCount = 1) then
begin
Close;
ModalResult:= mrOK;
end;
end;
procedure TfrmFileUnlock.btnTerminateClick(Sender: TObject);
var
Index: Integer;
ProcessId: DWORD;
begin
if (stgFileHandles.Row > 0) then
begin
if MessageBoxW(Handle, PWideChar(CeUtf8ToUtf16(rsMsgTerminateProcess)), PWideChar(CeUtf8ToUtf16(rsMtWarning)), MB_YESNO or MB_ICONWARNING) = IDYES then
begin
ProcessId:= StrToDWord(stgFileHandles.Cells[1, stgFileHandles.Row]);
if uFileUnlock.TerminateProcess(ProcessId) then
begin
for Index:= stgFileHandles.RowCount - 1 downto 1 do
begin
if (ProcessId = StrToDWord(stgFileHandles.Cells[1, Index])) then
stgFileHandles.DeleteRow(Index);
end;
if (stgFileHandles.RowCount = 1) then
begin
Close;
ModalResult:= mrOK;
end;
end;
end;
end;
end;
procedure TfrmFileUnlock.ShowThread;
begin
ShowModal;
end;
procedure TfrmFileUnlock.UnlockRow(Index: Integer);
var
ProcessId: DWORD;
FileHandle: HANDLE;
begin
ProcessId:= StrToDWord(stgFileHandles.Cells[1, Index]);
FileHandle:= StrToQWord(stgFileHandles.Cells[0, Index]);
if FileUnlock(ProcessId, FileHandle) then stgFileHandles.DeleteRow(Index);
end;
end.