استخدام دلفي لكتابة ملحقات Windows Shell
سيعرف الأصدقاء الذين هم على دراية بمبادئ أنظمة التشغيل أن نظام التشغيل الكامل سيوفر غلافًا لتسهيل المستخدمين العاديين.
استخدم الوظائف المختلفة التي يوفرها نظام التشغيل. لا يوفر غلاف Windows (يشير هنا إلى نظام التشغيل Windows 95 أو Windows NT4.0 أو أعلى) فقط
فهو لا يوفر واجهة رسومية مريحة وجميلة لواجهة المستخدم الرسومية فحسب، بل يوفر أيضًا وظائف امتداد shell قوية. قد ترى امتدادات shell هذه في العديد من البرامج. على سبيل المثال في الخاص بك
إذا تم تثبيت Winzip في النظام، فعند النقر بزر الماوس الأيمن فوق مجلد أو ملف في Windows Explorer، سيظهر ملف Winzip في القائمة المنبثقة.
القائمة المختصرة. أو مجلد موقع FTP الذي يظهر في Windows Explorer في Bullet FTP.
يدعم Windows سبعة أنواع من امتدادات الصدفة (تسمى المعالجات)، ويتم وصف وظائفها المقابلة باختصار على النحو التالي:
(1) معالجات قائمة السياق: إضافة قوائم حساسة للسياق إلى أنواع محددة من كائنات الملفات؛
(2) تُستخدم معالجات السحب والإفلات لدعم نقل بيانات OLE عندما يقوم المستخدمون بإجراء عمليات السحب والإفلات على أنواع معينة من كائنات الملفات؛
(3) تُستخدم معالجات الأيقونات لتوفير رمز فريد لكائن ملف معين، ويمكنها أيضًا تحديد رمز لنوع معين من كائن الملف؛
(4) تضيف معالجات ورقة PROperty صفحات خصائص إلى كائنات الملف (أي انقر بزر الماوس الأيمن فوق كائن الملف أو كائن المجلد وحدد خصائص في القائمة المنبثقة
مربع الحوار الذي يظهر بعد العنصر)، يمكن مشاركة صفحات الخصائص بواسطة كائنات ملف من نفس النوع، أو يمكن تعيين صفحة خصائص فريدة لكائن ملف؛
(5) سيتم استدعاء معالجات خطاف النسخ بواسطة النظام عند نسخ كائن المجلد أو كائن الطابعة أو نقله أو حذفه أو إعادة تسميته من خلال Windows
إضافة معالجات Copy-hook للسماح أو حظر عمليات معينة؛
(6) سيتم استدعاء معالجات هدف الإسقاط من قبل النظام عند سحب كائن وإسقاطه على كائن آخر؛
(7) سيتم استدعاء معالجات كائن البيانات من قبل النظام عند سحب الملفات أو إسقاطها أو نسخها أو لصقها.
تعتمد جميع ملحقات shell الخاصة بنظام Windows على نموذج مكون COM (Component Object Model)، وتصل الصدفة إلى الكائنات من خلال الواجهات.
تم تصميم امتدادات Shell كبرامج خادم قيد التشغيل 32 بت وتوفر خدمات لنظام التشغيل في شكل مكتبات ارتباطات ديناميكية. لذلك، إذا كنت ترغب في استخدام Windows
إذا تم توسيع واجهة المستخدم، فمن الضروري جدًا أن يكون لديك بعض المعرفة بكتابة كائنات COM. نظرًا لضيق المساحة، لن يتم تقديم COM هنا
وفقًا لمكتبة MSDN الخاصة بشركة Microsoft أو مستندات المساعدة ذات الصلة، يمكن اعتبار الواجهة بمثابة فئة خاصة تحتوي على مجموعة من الوظائف والإجراءات التي يمكن استخدامها لتشغيل كائن ما.
بعد كتابة ملحقات الصدفة الخاصة بك، يجب عليك تسجيلها لتصبح نافذة المفعول. يجب أن تكون جميع ملحقات shell موجودة في سجل Windows ضمن المفتاح HKEY_CLASSES_ROOTCLSID
سجل أدناه. ضمن هذا المفتاح، يمكنك العثور على العديد من المفاتيح بأسماء مثل {0000002F-0000-0000-C000-000000000046}. هذه المفاتيح عبارة عن معرفات فئة فريدة عالميًا.
دليل. يجب أن يكون لكل ملحق shell معرف فئة فريد عالميًا، وهذه هي الطريقة التي يعثر بها Windows على معالج ملحق shell.
يتم تسجيل موقع مكتبة الارتباط الديناميكي لامتداد Shell في النظام ضمن المفتاح الفرعي InProcServer32 ضمن معرف الفئة. يتم تسجيل ملحقات Shell المرتبطة بنوع الملف في
تحت المفتاح الأساسي shellex من النوع المقابل. إذا كان نظام التشغيل Windows هو Windows NT، فيجب أن يكون ملحق shell موجودًا أيضًا في السجل.
سجل تحت المفتاح الأساسي HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionShellExtensionsApproved.
بعد تجميع برنامج DLL لملحق shell، يمكنك استخدام regsvr32.exe الذي يوفره Windows نفسه لتسجيل برنامج خادم DLL. إذا كنت تستخدم دلفي، يمكنك أيضا
للتسجيل، حدد تسجيل خادم ActiveX في قائمة التشغيل.
لنقدم أولاً تطبيق ملحق Shell الأكثر استخدامًا: القائمة الحساسة للسياق، والتي تنبثق عند النقر بزر الماوس الأيمن فوق ملف أو مجلد في Windows.
تسمى هذه القائمة قائمة حساسة للسياق. لإضافة عناصر القائمة ديناميكيًا إلى قائمة حساسة للسياق، يمكنك كتابة معالج قائمة السياق. على سبيل المثال، الجميع
تضيف البرامج المألوفة مثل WinZip وUltraEdit عناصر القائمة ديناميكيًا إلى القائمة عن طريق كتابة معالج قائمة السياق. إذا تم تثبيته في النظام
WinZip، فعند النقر بزر الماوس الأيمن فوق ملف (مجلد) يسمى Windows، ستحتوي قائمته الحساسة للسياق على عنصر قائمة يسمى Add to Windows.zip.
يشبه معالج قائمة السياق الذي سيتم تنفيذه في هذه المقالة قائمة السياق التي يوفرها WinZip. وسوف تضيف أ
عنصر قائمة تشغيل الملف، عند النقر عليه، سيظهر برنامج الواجهة نافذة تشغيل ملف لإجراء نسخ الملف ونقله وعمليات أخرى.
يجب أن يقوم معالج قائمة سياق الكتابة بتنفيذ ثلاث واجهات: IShellExtInit وIContextMenu وTComObjectFactory. تنفيذ IShellExtInit
عند تهيئة الواجهة، يقوم كائن واجهة IContextMenu بتنفيذ القائمة الحساسة للسياق، وتقوم واجهة IComObjectFactory بتنفيذ إنشاء الكائن.
يتم تقديم تنفيذ البرنامج المحدد أدناه. أولاً، انقر فوق ملف|عنصر جديد من القائمة في دلفي، وحدد DLL في نافذة عنصر جديد لإنشاء ملف مشروع DLL.
ثم انقر فوق ملف | عنصر جديد في القائمة، وحدد وحدة في نافذة عنصر جديد لإنشاء ملف وحدة، وانقر فوق ملف|عنصر جديد في القائمة، وحدد وحدة في نافذة عنصر جديد.
حدد النموذج لإنشاء نافذة جديدة. احفظ ملف المشروع باسم contextmenu.dpr، وUnit1 باسم contextmenuhandle.pas، واحفظ النموذج باسم
OpWindow.pas.
قائمة برامج contextmenu.dpr هي كما يلي:
قائمة سياق المكتبة؛
الاستخدامات
كوم سيرف,
contextmenuhandle في "contextmenuhandle.pas"،
النافذة المقابلة في 'opwindow.pas' {Form2}؛
صادرات
دللجيتكلاسوبجيكت،
دلكان أنلود ناو،
دللريجسترسيرفر,
DllUnregisterServer;
{$R *.TLB}
{$R *.RES}
يبدأ
نهاية.
قائمة برامج contextmenuhandle هي كما يلي:
Unit contextMenuHandle;
واجهة
يستخدم Windows، ActiveX، ComObj، ShlObj، Classes؛
يكتب
TContextMenu = فئة (TComObject، IShellExtInit، IContextMenu)
خاص
FFileName: صفيف [0..MAX_PATH] من Char؛
محمي
وظيفة IShellExtInit.Initialize = SEIInitialize؛ // تجنب تحذير المترجم
وظيفة SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult;
وظيفة QueryContextMenu (القائمة: HMENU؛ قائمة الفهرس، idCmdFirst، idCmdLast،
uFlags: UINT): HResult;
دالة InvocationCommand(var lpici: TCMInvocmandInfo): HResult;
وظيفة GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszName: LPSTR; cchMax: UINT): HResult;
نهاية؛
ثابت
Class_ContextMenu: TGUID = '{19741013-C829-11D1-8233-0020AF3E97A0}';
{المعرف الفريد العمومي (GUID) هو قيمة مكونة من 16 بايت (128 بايت) تحدد الواجهة بشكل فريد}
فار
قائمة الملفات: TStringList؛
تطبيق
يستخدم ComServ، SysUtils، ShellApi، Registry، UnitForm؛
وظيفة TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult;
فار
ستجميديوم: تستجميديوم؛
فورماتإتك: فورماتإتك؛
رقم الملف، ط: عدد صحيح؛
يبدأ
file://If lpdobj يساوي Nil، يفشل هذا الاستدعاء
إذا (lpdobj = nil) فابدأ
النتيجة := E_INVALIDARG;
مخرج؛
نهاية؛
يقوم file:// أولاً بتهيئة FileList ومسحه لإضافة الملفات
FileList:=TSTringList.Create;
FileList.Clear;
الملف: // تهيئة ملف تنسيق الحافظة
مع FormatEtc تبدأ
cfFormat := CF_HDROP;
ptd := لا شيء;
dwaspect := DVASPECT_CONTENT;
ليندكس := -1;
tymed := TYMED_HGLOBAL;
نهاية؛
النتيجة := lpdobj.GetData(FormatEtc, StgMedium);
إذا فشل (النتيجة) ثم الخروج؛
file://الاستعلام الأول عن عدد الملفات التي حددها المستخدم
FileNumber := DragQueryFile(StgMedium.hGlobal,$FFFFFFFF,nil,0);
يقرأ file:// في حلقة ويحفظ جميع الملفات التي حددها المستخدم في FileList
لأني:=0 إلى FileNumber-1 تبدأ
DragQueryFile(StgMedium.hGlobal, i, FFileName, SizeOf(FFileName));
FileList.Add(FFileName);
النتيجة := NOERROR؛
نهاية؛
ReleaseStgMedium(StgMedium);
نهاية؛
وظيفة TContextMenu.QueryContextMenu (القائمة: HMENU؛ فهرس القائمة، idCmdFirst،
idCmdLast, uFlags: UINT): HResult;
يبدأ
النتيجة := 0;
إذا ((uFlags و$0000000F) = CMF_NORMAL) أو
((uFlags وCMF_EXPLORE) <> 0) ثم ابدأ
// أضف عنصر قائمة إلى قائمة السياق، عنوان عنصر القائمة هو عرض ملف الصورة النقطية
إدراج القائمة (القائمة، قائمة الفهرس، MF_STRING أو MF_BYPOSITION، idCmdFirst،
PChar('عملية الملف'));
// إرجاع عدد عناصر القائمة المضافة
النتيجة := 1;
نهاية؛
نهاية؛
الدالة TContextMenu.InspokeCommand(var lpici: TCMInspokeCommandInfo): HResult;
فار
frmOP:TForm1;
يبدأ
// تأكد أولاً من استدعاء العملية بواسطة النظام وليس بواسطة البرنامج
إذا (HiWord(Integer(lpici.lpVerb)) <> 0) ثم
يبدأ
النتيجة :=E_FAIL;
مخرج؛
نهاية؛
// تحديد صحة المعلمات التي تم تمريرها
إذا (LoWord(lpici.lpVerb) <> 0) ثم ابدأ
النتيجة := E_INVALIDARG;
مخرج؛
نهاية؛
ملف: // إنشاء نافذة تشغيل الملف
frmOP:=TForm1.Create(nil);
file:// يضيف قائمة بجميع الملفات إلى القائمة في نافذة تشغيل الملف
frmOP.ListBox1.Items := FileList;
النتيجة := NOERROR؛
نهاية؛
الدالة TContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszName: LPSTR; cchMax: UINT): HRESULT;
يبدأ
إذا (idCmd = 0) ثم ابدأ
إذا (uType = GCS_HELPTEXT) ثم
{يقوم بإرجاع معلومات المساعدة الخاصة بعنصر القائمة هذا، وسيتم عرض معلومات المساعدة هذه عندما يقوم المستخدم بتحريك الماوس
يظهر على شريط الحالة عند الانتقال إلى عنصر القائمة هذا. }
StrCopy(pszName, PChar('النقر فوق عنصر القائمة هذا سيؤدي إلى إجراء عمليات الملف'));
النتيجة := NOERROR؛
نهاية
آخر
النتيجة := E_INVALIDARG;
نهاية؛
يكتب
TContextMenuFactory = فئة (TComObjectFactory)
عام
الإجراء UpdateRegistry(Register: Boolean override);
نهاية؛
الإجراء TContextMenuFactory.UpdateRegistry(Register: Boolean);
فار
معرف الفئة: سلسلة؛
يبدأ
إذا سجل ثم ابدأ
UpdateRegistry الموروثة(Register);
ClassID := GUIDToString(Class_ContextMenu);
file://عند تسجيل ملف مكتبة ملحق، قم بإضافة المكتبة إلى السجل
CreateRegKey('*shellex', ', ');
CreateRegKey('*shellexContextMenuHandlers', ', ');
CreateRegKey('*shellexContextMenuHandlersFileOpreation', ', ClassID);
الملف://إذا كان نظام التشغيل هو Windows NT
إذا (Win32Platform = VER_PLATFORM_WIN32_NT) ثم
مع TRegistry.Create القيام به
يحاول
مفتاح الجذر := HKEY_LOCAL_MACHINE;
OpenKey('SOFTWAREMicrosoftWindowsCurrentVersionShell Extensions', True);
OpenKey('Approved', True);
WriteString(ClassID, 'ملحق Shell لقائمة السياق');
أخيراً
حر؛
نهاية؛
نهاية
آخر تبدأ
DeleteRegKey('*shellexContextMenuHandlersFileOpreation');
UpdateRegistry الموروثة(Register);
نهاية؛
نهاية؛
التهيئة
TContextMenuFactory.Create(ComServer، TContextMenu، Class_ContextMenu،
'، 'ملحق Shell لقائمة السياق'، ciMultiInstance،tmApartment)؛
نهاية.
أضف عنصر تحكم TListBox وعنصري تحكم TButton إلى نافذة OpWindow. قائمة برامج OpWindows.pas هي كما يلي:
نافذة الوحدة؛
واجهة
الاستخدامات
Windows، الرسائل، SysUtils، الفئات، الرسومات، عناصر التحكم، النماذج، مربعات الحوار،
ExtCtrls, StdCtrls,shlobj,shellapi,ActiveX;
يكتب
TForm1 = الفئة (TForm)
ListBox1: TListBox؛
Button1: TButton؛
Button2: TButton؛
الإجراء FormCreate(Sender: TObject);
الإجراء FormClose(Sender: TObject; var Action: TCloseAction);
الإجراء Button1Click(Sender: TObject);
الإجراء Button2Click(Sender: TObject);
خاص
{تصريحات خاصة}
عام
قائمة الملفات: TStringList؛
{التصريحات العامة}
نهاية؛
فار
Form1: TForm1؛
تطبيق
{$R *.DFM}
الإجراء TForm1.FormCreate(Sender: TObject);
يبدأ
FileList:=TSTringList.Create;
Button1.Caption :='نسخ الملف';
Button2.Caption :='نقل الملفات';
عرض ذاتي؛
نهاية؛
الإجراء TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
يبدأ
FileList.Free;
نهاية؛
الإجراء TForm1.Button1Click(Sender: TObject);
فار
sPath:string;
fsTemp:SHFILEOPSTRUCT;
أنا: عدد صحيح؛
يبدأ
sPath:=InputBox('عملية الملف','مسار نسخ الإدخال','c:windows');
إذا كان sPath<>'ثم ابدأ
fsTemp.Wnd := Self.Handle;
الملف: // تعيين نوع عملية الملف
fsTemp.wFunc :=FO_COPY;
file:// يسمح بالتراجع عن العمليات
fsTemp.fFlags :=FOF_ALLOWUNDO;
لأني:=0 إلى ListBox1.Items.Count-1 تبدأ
الملف: // اسم المسار الكامل للملف المصدر
fsTemp.pFrom := PChar(ListBox1.Items.Strings[i]);
الملف: // المسار للنسخ إليه
fsTemp.pTo := PChar(sPath);
fsTemp.lpszProgressTitle:='نسخ الملف';
إذا كان SHFileOperation(fsTemp)<>0 ثم
ShowMessage("فشل نسخ الملف");
نهاية؛
نهاية؛
نهاية؛
الإجراء TForm1.Button2Click(Sender: TObject);
فار
sPath:string;
fsTemp:SHFILEOPSTRUCT;
أنا: عدد صحيح؛
يبدأ
sPath:=InputBox('عملية الملف','مسار حركة الإدخال','c:windows');
إذا كان sPath<>'ثم ابدأ
fsTemp.Wnd := Self.Handle;
fsTemp.wFunc :=FO_MOVE;
fsTemp.fFlags :=FOF_ALLOWUNDO;
لأني:=0 إلى ListBox1.Items.Count-1 تبدأ
fsTemp.pFrom := PChar(ListBox1.Items.Strings[i]);
fsTemp.pTo := PChar(sPath);
fsTemp.lpszProgressTitle:='نقل الملفات';
إذا كان SHFileOperation(fsTemp)<>0 إذن
ShowMessage("فشل نسخ الملف");
نهاية؛
نهاية؛
نهاية؛
نهاية.
انقر فوق المشروع |. قم ببناء عنصر contextMenu في القائمة، وستقوم دلفي بإنشاء ملف contextmenu.dll. هذا هو برنامج القائمة الحساس للسياق.
استخدم Regsvr32.exe لتسجيل البرنامج، ثم انقر بزر الماوس الأيمن على أي ملف واحد أو عدة ملفات في Windows Explorer، وسيظهر في قائمة السياق.
يوجد عنصر قائمة إضافي لعمليات الملف. انقر فوق هذا العنصر وسيتم إدراج أسماء الملفات لجميع الملفات التي حددتها في القائمة في النافذة المنبثقة. يمكنك اختيار زر نسخ الملف أو
يقوم زر نقل الملف بتنفيذ عمليات الملف.