:: MVP ::
|
|
:: RSS ::
|
|
|
Интересно, много ли осталось людей, использующих Explorer в качестве
основного файлового менеджера. Лично я уже забыл, когда последний
раз пользовался им. Эта статья заинтересует в первую очередь тех
людей, которые хотя бы иногда используют проводник. Сегодня я расскажу,
каким образом можно скрывать в проводнике "ненужные" диски. Кстати, из
этого вполне может получиться неплохая программа-прикол: включает друг
компьютер, запускает Explorer, а дисков нет, испарились.
Этот нехитрый трюк можно выполнить, воспользовавшись реестром.
Все, что для этого нужно, просто добавить к ветви реестра
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer
двоичный ключ с именем 'NoDrives' и значением из соответствующей строки
(значения строк приведены ниже). А если надо "спрятать" несколько дисков,
то достаточно сложить строки. Только учтите, что значения шестнадцатеричные!
{A:\} 01 00 00 00 {N:\} 00 20 00 00
{B:\} 02 00 00 00 {O:\} 00 40 00 00
{C:\} 04 00 00 00 {P:\} 00 80 00 00
{D:\} 08 00 00 00 {Q:\} 00 00 01 00
{E:\} 10 00 00 00 {R:\} 00 00 02 00
{F:\} 20 00 00 00 {S:\} 00 00 04 00
{G:\} 40 00 00 00 {T:\} 00 00 08 00
{H:\} 80 00 00 00 {U:\} 00 00 10 00
{I:\} 00 01 00 00 {V:\} 00 00 20 00
{J:\} 00 02 00 00 {W:\} 00 00 40 00
{K:\} 00 04 00 00 {X:\} 00 00 80 00
{L:\} 00 08 00 00 {Y:\} 00 00 00 01
{M:\} 00 10 00 00 {Z:\} 00 00 00 02
|
Так как работать нам предстоит с реестром, добавим в uses
модуль Registry, и определим ключ реестра. А чтобы иметь
возможность перезагрузить Explorer, добавим модуль ShellAPI.
uses
{...}, Registry, ShellAPI;
{...}
const
HKEY = 'Software\Microsoft\Windows\CurrentVersion\Policies\Explorer';
|
Числовые значения для каждого диска от A:\ до Z:\ принадлежат
диапазону от 20 до 225 соответственно.
В приведенной ниже таблице показано, каким образом получается
эта последовательность чисел, и как этот процесс можно
автоматизировать.
{A:\} $00000001 = ( 1 shl 0 ) {N:\} $00002000 = ( 1 shl 13 )
{B:\} $00000002 = ( 1 shl 1 ) {O:\} $00004000 = ( 1 shl 14 )
{C:\} $00000004 = ( 1 shl 2 ) {P:\} $00008000 = ( 1 shl 15 )
{D:\} $00000008 = ( 1 shl 3 ) {Q:\} $00010000 = ( 1 shl 16 )
{E:\} $00000010 = ( 1 shl 4 ) {R:\} $00020000 = ( 1 shl 17 )
{F:\} $00000020 = ( 1 shl 5 ) {S:\} $00040000 = ( 1 shl 18 )
{G:\} $00000040 = ( 1 shl 6 ) {T:\} $00080000 = ( 1 shl 19 )
{H:\} $00000080 = ( 1 shl 7 ) {U:\} $00100000 = ( 1 shl 20 )
{I:\} $00000100 = ( 1 shl 8 ) {V:\} $00200000 = ( 1 shl 21 )
{J:\} $00000200 = ( 1 shl 9 ) {W:\} $00400000 = ( 1 shl 22 )
{K:\} $00000400 = ( 1 shl 10 ) {X:\} $00800000 = ( 1 shl 23 )
{L:\} $00000800 = ( 1 shl 11 ) {Y:\} $01000000 = ( 1 shl 24 )
{M:\} $00001000 = ( 1 shl 12 ) {Z:\} $02000000 = ( 1 shl 25 )
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to 25 do
ShowMessage( Format( '%.8x', [1 shl i] ) );
end;
|
Теперь все, что нам остается, это выбрать диски, которые мы хотим отключить,
высчитать результатирующее число и записать его в реестр. Выбор дисков в моем
примере осуществляется путем включения или отключения соответствующих
CheckBox'ов. Чтобы изменения вступили в силу без перезагрузки компьютера,
установите соответствующий флажок внизу формы.
procedure TForm1.ApplyClick(Sender: TObject);
var
i: integer;
d: DWord;
hwndShell: HWND;
begin
d := 0;
for i := 0 to 25 do
if TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Checked then
d := d + ( 1 shl i );
Reg := TRegistry.Create;
Reg.RootKey := HKEY_CURRENT_USER;
Reg.OpenKey( HKEY, false );
Reg.WriteBinaryData( 'NoDrives', d, SizeOf( d ) );
Reg.Free;
// Если установлен флажок, перегружаем Explorer
if RestartExplorer.Checked then
begin
hwndShell := FindWindow( 'Progman', nil );
PostMessage( hwndShell, WM_QUIT, 0, 0 );
ShellExecute( 0, 'open', 'Explorer', nil, nil, SW_SHOWNORMAL );
end;
Apply.Enabled := false;
end;
|
Чтобы при старте приложения знать, какие диски являются скрытыми
в Explorer'е, напишем в событии OnCreate формы следующий код:
procedure TForm1.FormCreate(Sender: TObject);
var
d: DWORD;
i: byte;
begin
d := 0;
Reg := TRegistry.Create;
Reg.RootKey := HKEY_CURRENT_USER;
Reg.OpenKey( HKEY, true );
if not Reg.ValueExists( 'NoDrives' ) then
Reg.WriteBinaryData( 'NoDrives', d, SizeOf( d ) )
else
Reg.ReadBinaryData( 'NoDrives', d, SizeOf( d ) );
if d <> 0 then
begin
for i := 0 to 25 do
if ( d and ( 1 shl i ) ) = ( 1 shl i ) then
TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Checked := true;
end;
Reg.Free;
end;
|
Вот в принципе и все, что нужно сделать. Дальше программу можно
усовершенствовать, наделив ее возможностью отображения только
тех дисков, которые физически присутствуют в системе. Вот как
это можно сделать.
(* Показать только существующие диски *)
procedure TForm1.ShowAllReallyDiskClick(Sender: TObject);
function DriveExists( Drive: Byte ): boolean;
begin
Result := ( GetLogicalDrives and ( 1 shl Drive ) ) <> 0;
end;
var
i: byte;
begin
for i := 0 to 25 do
if not DriveExists( i ) then
begin
TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Checked := false;
TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Enabled := false;
end;
end;
(* Показать все диски *)
procedure TForm1.ShowAllDiskClick(Sender: TObject);
var
i: byte;
begin
for i := 0 to 25 do
TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Enabled := true;
end;
|
Также можно порадовать пользователя несколькими функциями,
облегчающими процесс выбора дисков. Реализуем следующие
возможности: "Выделить все", "Инвертировать выделение",
"Снять выделение".
(* Выделить все *)
procedure TForm1.SelectAllClick(Sender: TObject);
var
i: byte;
begin
for i := 0 to 25 do
if TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Enabled then
TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Checked := true;
end;
(* Инвертировать выделение *)
procedure TForm1.InvertSelectClick(Sender: TObject);
var
i: byte;
begin
for i := 0 to 25 do
if TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Enabled then
TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Checked :=
not TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Checked;
end;
(* Снять выделение *)
procedure TForm1.UnSelectAllClick(Sender: TObject);
var
i: byte;
begin
for i := 0 to 25 do
TCheckBox( FindComponent( Format( 'Check%s', [Chr( i+65 )] ) ) ).Checked := false;
end;
|
Надеюсь, вы поняли принцип, и теперь у вас в арсенале станет
на один прикол больше. Кроме того, этот принцип вы можете
использовать и в своих программах, тем более что областей,
где его можно применить, много. На этом сегодня все.
Удачи в программировании.
.: Пример к данной статье :.
|
При использовании материала - ссылка на сайт обязательна
|
|