mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
172 lines
4.5 KiB
ObjectPascal
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.
|
|
|