Menggunakan Delphi untuk menulis ekstensi shell Windows
Teman-teman yang paham dengan prinsip-prinsip sistem operasi pasti tahu bahwa sistem operasi yang lengkap akan menyediakan shell untuk memudahkan pengguna awam.
Gunakan berbagai fungsi yang disediakan oleh sistem operasi. Shell Windows (di sini mengacu pada sistem operasi Windows 95, Windows NT4.0 atau lebih tinggi) tidak hanya menyediakan
Ini tidak hanya menyediakan antarmuka grafis GUI yang nyaman dan indah, tetapi juga menyediakan fungsi ekstensi shell yang kuat. Anda mungkin melihat ekstensi shell ini di banyak perangkat lunak. Misalnya di Anda
Jika Winzip terinstal di sistem, saat Anda mengklik kanan folder atau file di Windows Explorer, file Winzip akan muncul di menu pop-up.
menu yang disingkat. Atau folder situs FTP yang muncul di Windows Explorer di Bullet FTP.
Windows mendukung tujuh jenis ekstensi shell (disebut Handler), dan fungsi terkaitnya dijelaskan secara singkat sebagai berikut:
(1) Pengendali menu konteks: Tambahkan menu peka konteks ke tipe objek file tertentu;
(2) Pengendali drag-and-drop digunakan untuk mendukung transmisi data OLE ketika pengguna melakukan operasi drag-and-drop pada tipe objek file tertentu;
(3) Penangan ikon digunakan untuk memberikan ikon unik pada objek file tertentu, dan juga dapat menentukan ikon untuk tipe objek file tertentu;
(4) Pengendali lembar properti menambahkan halaman properti ke objek file (yaitu, klik kanan objek file atau objek folder dan pilih Properti di menu pop-up
kotak dialog yang muncul setelah item), halaman properti dapat dibagikan oleh objek file dengan tipe yang sama, atau halaman properti unik dapat ditetapkan ke objek file;
(5) Penangan copy-hook akan dipanggil oleh sistem ketika objek folder atau objek printer disalin, dipindahkan, dihapus, atau diganti namanya, melalui Windows
Tambahkan penangan Copy-hook untuk mengizinkan atau melarang operasi tertentu;
(6) Penangan target jatuh akan dipanggil oleh sistem ketika suatu objek diseret dan dijatuhkan ke objek lain;
(7) Pengendali objek data akan dipanggil oleh sistem ketika file diseret, dijatuhkan, disalin, atau ditempel.
Semua ekstensi shell Windows didasarkan pada model komponen COM (Component Object Model), dan shell mengakses objek melalui antarmuka.
Ekstensi Shell dirancang sebagai program server dalam proses 32-bit dan menyediakan layanan ke sistem operasi dalam bentuk perpustakaan tautan dinamis. Oleh karena itu, jika Anda ingin menggunakan Windows
Jika antarmuka pengguna diperluas, sangat diperlukan pengetahuan tentang penulisan objek COM. Karena keterbatasan ruang, COM tidak akan diperkenalkan di sini
Menurut perpustakaan MSDN Microsoft atau dokumen bantuan terkait, antarmuka dapat dianggap sebagai kelas khusus, yang berisi sekumpulan fungsi dan prosedur yang dapat digunakan untuk mengoperasikan suatu objek.
Setelah Anda menulis ekstensi shell, Anda harus mendaftarkannya agar dapat diterapkan. Semua ekstensi shell harus ada di registri Windows dengan kunci HKEY_CLASSES_ROOTCLSID
Daftar di bawah. Di bawah kunci ini, Anda dapat menemukan banyak kunci dengan nama seperti {0000002F-0000-0000-C000-000000000046}. Kunci tersebut adalah pengidentifikasi kelas unik secara global.
Panduan. Setiap ekstensi shell harus memiliki pengidentifikasi kelas unik secara global, yang merupakan cara Windows menemukan pengendali ekstensi shell.
Lokasi perpustakaan tautan dinamis ekstensi shell dalam sistem dicatat di bawah subkunci InProcServer32 di bawah pengidentifikasi kelas. Ekstensi shell yang terkait dengan jenis file didaftarkan
Di bawah kunci utama shellex dari tipe yang sesuai. Jika sistem operasi Windows adalah Windows NT, ekstensi shell juga harus ada di registri.
Daftarkan dengan kunci utama HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionShellExtensionsApproved.
Setelah mengkompilasi program DLL ekstensi shell, Anda dapat menggunakan regsvr32.exe yang disediakan oleh Windows sendiri untuk mendaftarkan program server DLL. Kalau pakai Delphi juga bisa
Untuk mendaftar, pilih Daftarkan Server ActiveX di menu Jalankan.
Pertama-tama mari kita perkenalkan aplikasi ekstensi shell yang lebih umum digunakan: menu peka konteks, yang muncul saat Anda mengklik kanan file atau folder di Windows.
Menu ini disebut menu peka konteks. Untuk menambahkan item menu secara dinamis ke menu peka konteks, Anda dapat menulis Pengendali Menu Konteks. Misalnya, semua orang
Perangkat lunak yang familiar seperti WinZip dan UltraEdit secara dinamis menambahkan item menu ke menu dengan menulis Context Menu Handler. Jika dipasang di sistem
WinZip, lalu ketika Anda mengklik kanan file (folder) bernama Windows, menu peka konteksnya akan memiliki item menu bernama Tambahkan ke Windows.zip.
Pengendali Menu Konteks yang akan diterapkan dalam artikel ini mirip dengan menu konteks yang disediakan oleh WinZip. Ini akan menambah a
Item menu operasi file. Ketika item ini diklik, program antarmuka akan memunculkan jendela operasi file untuk melakukan operasi seperti menyalin dan memindahkan file.
Penulisan Context Menu Handler harus mengimplementasikan tiga antarmuka: IShellExtInit, IContextMenu dan TComObjectFactory. Implementasi IShellExtInit
Inisialisasi antarmuka, objek antarmuka IContextMenu mengimplementasikan menu peka konteks, dan antarmuka IComObjectFactory mengimplementasikan pembuatan objek.
Implementasi program spesifik diperkenalkan di bawah ini. Pertama, klik item File|New pada menu di Delphi, pilih DLL di jendela New Item untuk membuat file proyek DLL.
Kemudian klik item File|New pada menu, pilih Unit di jendela New Item untuk membuat file Unit, klik item File|New pada menu, dan pilih Unit di jendela New Item.
Pilih Formulir untuk membuat jendela baru. Simpan file proyek sebagai Contextmenu.dpr, Unit1 sebagai Contextmenhandle.pas, dan Simpan Formulir sebagai
OpWindow.pas.
Daftar program Contextmenu.dpr adalah sebagai berikut:
menu konteks perpustakaan;
kegunaan
ComServ,
konteksmenangani di 'konteksmenangani.pas',
opwindow di 'opwindow.pas' {Form2};
ekspor
DllGetClassObject,
DllDapat BongkarSekarang,
DllDaftarServer,
DllBatalkan RegistrasiServer;
{$R *.TLB}
{$R *.RES}
mulai
akhir.
Daftar program Contextmenhandle adalah sebagai berikut:
satuan KonteksMenuHandle;
antarmuka
menggunakan Windows,ActiveX,ComObj,ShlObj,Kelas;
jenis
TContextMenu = kelas(TComObject,ISellExtInit,IContextMenu)
pribadi
FFileName: array[0..MAX_PATH] dari Char;
terlindung
function IShellExtInit.Initialize = SEIInitialize; // Hindari peringatan kompiler
fungsi SEIInisialisasi(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HHasil;
fungsi QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,
uBendera: UINT): HHasil;
fungsi InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
fungsi GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszNama: LPSTR; cchMax: UINT): HHasil;
akhir;
konstanta
Class_ContextMenu: TGUID = '{19741013-C829-11D1-8233-0020AF3E97A0}';
{Pengidentifikasi Unik Global (GUID) adalah nilai 16-byte (128-byte) yang secara unik mengidentifikasi antarmuka}
var
Daftar File:TStringList;
pelaksanaan
menggunakan ComServ, SysUtils, ShellApi, Registry, UnitForm;
fungsi TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HHasil;
var
StgMedium: TStgMedium;
FormatDll: TFormatEtc;
Nomor File,i:Integer;
mulai
file://Jika lpdobj sama dengan Nil, panggilan ini gagal
jika (lpdobj = nihil) maka mulailah
Hasil := E_INVALIDARG;
KELUAR;
akhir;
file:// pertama menginisialisasi dan menghapus FileList untuk menambahkan file
FileList:=TStringList.Buat;
FileList.Hapus;
file://Inisialisasi file format clipboard
dengan FormatEtc dimulai
cfFormat := CF_HDROP;
ptd := nihil;
dwaspect := DVASPECT_CONTENT;
lindex := -1;
diketik := TYMED_HGLOBAL;
akhir;
Hasil := lpdobj.GetData(FormatEtc, StgMedium);
jika Gagal(Hasil) maka Keluar;
file://Pertama menanyakan jumlah file yang dipilih oleh pengguna
Nomor File := DragQueryFile(StgMedium.hGlobal,$FFFFFFFF,nihil,0);
file:// membaca dalam satu lingkaran dan menyimpan semua file yang dipilih pengguna ke FileList
untuk i:=0 hingga FileNumber-1 dimulai
DragQueryFile(StgMedium.hGlobal, i, FFileName, SizeOf(FFileName));
FileList.Tambahkan(FFileName);
Hasil := NOERROR;
akhir;
RilisStgMedium(StgMedium);
akhir;
fungsi TContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
idCmdLast, uFlags: UINT): HHasil;
mulai
Hasil := 0;
jika ((uFlags dan $0000000F) = CMF_NORMAL) atau
((uFlags dan CMF_EXPLORE) <> 0) lalu mulai
//Tambahkan item menu ke Menu Konteks, judul item menu adalah Lihat File Bitmap
SisipkanMenu(Menu, indexMenu, MF_STRING atau MF_BYPOSITION, idCmdFirst,
PChar('operasi file'));
// Mengembalikan jumlah item menu yang ditambahkan
Hasil := 1;
akhir;
akhir;
fungsi TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
var
darimOP:TForm1;
mulai
// Pertama-tama pastikan prosesnya dipanggil oleh sistem dan bukan oleh program
jika (HiWord(Bilangan Bulat(lpici.lpVerb)) <> 0) maka
mulai
Hasil := E_FAIL;
KELUAR;
akhir;
// Tentukan validitas parameter yang diteruskan
if (LoWord(lpici.lpVerb) <> 0) maka mulailah
Hasil := E_INVALIDARG;
KELUAR;
akhir;
file://Buat jendela operasi file
frmOP:=TForm1.Create(nil);
file://menambahkan daftar semua file ke daftar di jendela operasi file
frmOP.ListBox1.Item := Daftar File;
Hasil := NOERROR;
akhir;
fungsi TContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszNama: LPSTR; cchMax: UINT): HRESULT;
mulai
jika (idCmd = 0) maka mulai
jika (uType = GCS_HELPTEXT) maka
{Mengembalikan informasi bantuan dari item menu ini. Informasi bantuan ini akan ditampilkan ketika pengguna menggerakkan mouse
Muncul di bilah status saat berpindah ke item menu ini. }
StrCopy(pszName, PChar('Mengklik item menu ini akan menjalankan operasi file'));
Hasil := NOERROR;
akhir
kalau tidak
Hasil := E_INVALIDARG;
akhir;
jenis
TContextMenuFactory = kelas(TComObjectFactory)
publik
prosedur UpdateRegistry(Daftar: Boolean override);
akhir;
procedure TContextMenuFactory.UpdateRegistry(Daftar: Boolean);
var
ID Kelas: string;
mulai
jika Daftar kemudian mulai
UpdateRegistry yang diwarisi(Daftar);
ClassID := GUIDToString(Class_ContextMenu);
file://Saat mendaftarkan file perpustakaan ekstensi, tambahkan perpustakaan ke registri
CreateRegKey('*shellex', ', ');
CreateRegKey('*shellexContextMenuHandlers', ', ');
CreateRegKey('*shellexContextMenuHandlersFileOpreation', ', ClassID);
file://jika sistem operasinya adalah Windows NT
jika (Win32Platform = VER_PLATFORM_WIN32_NT) maka
dengan TRegistry.Create lakukan
mencoba
Kunci Akar := HKEY_LOCAL_MACHINE;
OpenKey('SOFTWAREMicrosoftWindowsCurrentVersionShell Extensions', Benar);
OpenKey('Disetujui', Benar);
WriteString(ClassID, 'Ekstensi Shell Menu Konteks');
Akhirnya
Bebas;
akhir;
akhir
yang lain dimulai
DeleteRegKey('*shellexContextMenuHandlersFileOpreation');
UpdateRegistry yang diwarisi(Daftar);
akhir;
akhir;
inisialisasi
TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,
', 'Ekstensi Shell Menu Konteks', ciMultiInstance,tmApartment);
akhir.
Tambahkan kontrol TListBox dan dua kontrol TButton ke jendela OpWindow Daftar program OpWindows.pas adalah sebagai berikut:
jendela terbuka unit;
antarmuka
kegunaan
Windows, Pesan, SysUtils, Kelas, Grafik, Kontrol, Formulir, Dialog,
ExtCtrls, StdCtrls,shlobj,shellapi,ActiveX;
jenis
TForm1 = kelas(TForm)
Kotak Daftar1: TListBox;
Tombol1: Tombol T;
Tombol2: Tombol T;
prosedur FormCreate(Pengirim: TObject);
procedure FormClose(Pengirim: TObject; var Action: TCloseAction);
prosedur Button1Click(Pengirim: TObject);
prosedur Button2Click(Pengirim: TObject);
pribadi
{Deklarasi pribadi}
publik
Daftar File:TStringList;
{Pernyataan publik}
akhir;
var
Formulir1: TForm1;
pelaksanaan
{$R *.DFM}
prosedur TForm1.FormCreate(Pengirim: TObject);
mulai
FileList:=TStringList.Buat;
Button1.Caption :='Salin file';
Button2.Caption :='Pindahkan file';
Diri.Tunjukkan;
akhir;
procedure TForm1.FormClose(Pengirim: TObject; var Action: TCloseAction);
mulai
Daftar File.Gratis;
akhir;
prosedur TForm1.Button1Click(Pengirim: TObject);
var
jalur s: string;
fsTemp:SHFILEOPSTRUCT;
saya: bilangan bulat;
mulai
sPath:=InputBox('Operasi file','Jalur penyalinan masukan','c:windows');
jika sPath<>'lalu mulai
fsTemp.Wnd := Self.Handle;
file://set jenis operasi file
fsTemp.wFunc :=FO_COPY;
file:// memungkinkan pembatalan operasi
fsTemp.fFlags :=FOF_ALLOWUNDO;
untuk i:=0 hingga ListBox1.Items.Count-1 dimulai
file://nama path lengkap file sumber
fsTemp.pFrom := PChar(ListBox1.Items.Strings[i]);
file://path untuk disalin
fsTemp.pTo := PChar(sPath);
fsTemp.lpszProgressTitle:='Salin berkas';
jika SHFileOperation(fsTemp)<>0 lalu
ShowMessage('Penyalinan file gagal');
akhir;
akhir;
akhir;
prosedur TForm1.Button2Click(Pengirim: TObject);
var
jalur s: string;
fsTemp:SHFILEOPSTRUCT;
saya: bilangan bulat;
mulai
sPath:=InputBox('Operasi file','Jalur pergerakan masukan','c:windows');
jika sPath<>'lalu mulai
fsTemp.Wnd := Self.Handle;
fsTemp.wFunc :=FO_MOVE;
fsTemp.fBendera :=FOF_ALLOWUNDO;
untuk i:=0 hingga ListBox1.Items.Count-1 dimulai
fsTemp.pFrom := PChar(ListBox1.Items.Strings[i]);
fsTemp.pTo := PChar(sPath);
fsTemp.lpszProgressTitle:='Pindahkan file';
jika SHFileOperation(fsTemp)<>0 maka
ShowMessage('Penyalinan file gagal');
akhir;
akhir;
akhir;
akhir.
Klik item Project |. Build ContextMenu di menu, dan Delphi akan membuat file Contextmenu.dll. Ini adalah program menu peka konteks.
Gunakan Regsvr32.exe untuk mendaftarkan program, lalu klik kanan pada satu atau beberapa file di Windows Explorer, dan itu akan muncul di menu konteks.
Ada item menu tambahan untuk pengoperasian file. Klik item ini dan nama file dari semua file yang Anda pilih akan dicantumkan dalam daftar di jendela pop-up
Tombol Pindahkan File melakukan operasi file.