توافق الطرف الثالث
Developer Guide
إذا كنت تقوم بالتطوير باستخدام لغة C++، فيمكنك استخدام ملف الترويسة ipchelper.h مباشرة من Seer SDK والذي يغلف جميع واجهات برمجة تطبيقات Win32 IPC الموضحة أدناه.
يدعم Seer التكامل مع تطبيقات الطرف الثالث ومديري الملفات المخصصين باستخدام Win32 IPC عبر رسائل WM_COPYDATA.
التكامل مع التطبيقات المخصصة (ACustomApp)
يمكن للتطبيق المخصص مطالبة Seer بعرض معاينة لمسار ملف معين.
الخطوة 1: العثور على مقبض نافذة Seer
ابحث عن مقبض النافذة باستخدام FindWindowW :
HWND seer = FindWindowW(L"SeerWindowClass", nullptr);
الخطوة 2: إرسال المسار المطلق للملف المحدد
أرسل المسار المطلق للملف إلى مقبض نافذة Seer:
void sendPath2Seer(HWND seer, LPCWSTR path)
{
COPYDATASTRUCT cd;
cd.cbData = (wcslen(path) + 1) * sizeof(wchar_t);
cd.lpData = (LPVOID)path;
cd.dwData = SEER_INVOKE_W32; // 5000
SendMessageW(seer, WM_COPYDATA, 0, (LPARAM)&cd);
}
التكامل مع مدير ملفات مخصص (ACustomExplorer)
يمكن لمديري الملفات المخصصين تسجيل اسم فئة النافذة الخاصة بهم (classname) حتى يستمع Seer للضغط على مفتاح المسافة (Spacebar) داخلها، ويطلب مسار الملف المحدد حاليًا لعرض المعاينة.
الخطوة 1: تسجيل اسم الفئة
أنشئ ملف JSON في المسار %USERPROFILE%/Documents/Seer/explorers/. عند بدء تشغيل Seer، يقوم بتحميل جميع ملفات JSON في هذا الدليل. يجب أن يحتوي ملف JSON على اسم فئة النافذة المستهدفة:
{
"classname": "YourCustomExplorerClass",
"windowtext": "OptionalWindowTextToMatch",
"appname": "YourAppName"
}
الخطوة 2: معالجة الضغط على مفتاح المسافة
عندما يضغط المستخدم على مفتاح المسافة in نافذة مدير الملفات الخاص بك، يعترض Seer هذه الضغطة ويستدعي GetForegroundWindow لمطابقة classname. إذا كانت متطابقة، يرسل Seer رسالة WM_COPYDATA إلى مقبض نافذتك مع تعيين dwData إلى SEER_REQUEST_PATH (4000) و cbData = 0 و lpData = nullptr.
يرسل Seer هذه الرسالة باستخدام SendMessageTimeout مع مهلة قدرها 150ms لمنع واجهة المستخدم من التعليق في حال لم يستجب تطبيقك.
الخطوة 3: الاستجابة بالمسار المحدد
يجب أن يتعامل تطبيقك مع رسالة WM_COPYDATA ويتحقق مما إذا كانت dwData هي SEER_REQUEST_PATH ويستجيب بإرسال رسالة WM_COPYDATA إلى Seer مع تعيين dwData إلى SEER_RESPONSE_PATH (4001) تحتوي على المسار الكامل للملف المحدد كـ null-terminated wide string.
الخطوة 4: عرض المعاينة
بمجرد أن يتلقى Seer المسار، يتم عرض نافذة المعاينة وتنتهي العملية.
مرجع أوامر IPC (SeerCommand)
تم تعريف الأوامر التالية في seer/ipc.h للتواصل مع Seer:
| اسم الأمر | القيمة | الوصف |
|---|---|---|
SEER_REQUEST_PATH |
4000 |
يتم إرسالها من Seer إلى المستكشف المخصص لطلب مسار الملف المحدد حاليًا. |
SEER_RESPONSE_PATH |
4001 |
يتم إرسالها من المستكشف المخصص مرة أخرى إلى Seer محملة بمسار الملف المحدد. |
SEER_INVOKE_W32 |
5000 |
يتم إرسالها من تطبيق مخصص إلى Seer لبدء المعاينة في النافذة الرئيسية (الحد الأدنى للفاصل الزمني هو 200 مللي ثانية). |
SEER_INVOKE_W32_SEP |
5001 |
يتم إرسالها من تطبيق مخصص إلى Seer لبدء المعاينة في نافذة منفصلة. |
SEER_IS_VISIBLE |
5004 |
يتحقق مما إذا كانت نافذة المعاينة الرئيسية مرئية. يعيد VISIBLE_TRUE (1) أو VISIBLE_FALSE (0). |
SEER_HIDE |
5005 |
يخفي نافذة المعاينة الرئيسية إذا كانت مرئية. |
SEER_GET_CURRENT_FILE |
5006 |
يستعلم من Seer عن مسار الملف الذي تتم معاينته حاليًا (عبر الذاكرة المشتركة المسماة). |
SEER_GET_VERSION |
5007 |
يستعلم عن إصدار Seer (على سبيل المثال، يعيد 40001 للإصدار 4.0.1). |
SEER_IS_TRACKING_ENABLED |
5008 |
يستعلم عما إذا كان وضع تتبع الملفات ممكناً. |
طلب الملف الذي تتم معاينته حاليًا
نظراً لأن WM_COPYDATA لا يمكنه إرجاع سلاسل نصية متغيرة الطول مباشرة، فإن الاستعلام عن الملف الذي تتم معاينته حالياً (SEER_GET_CURRENT_FILE) يستخدم بروتوكول تخطيط الملف (الذاكرة المشتركة المسماة).
مثال على التطبيق بلغة C++
#include <windows.h>
#include <string>
std::wstring getSeerCurrentFile(HWND seer_hwnd)
{
if (!seer_hwnd) return L"";
// إنشاء اسم فريد لتخطيط الملف
wchar_t map_name[MAX_PATH] = {0};
swprintf_s(map_name, L"SeerCurFile_%u_%llu", GetCurrentProcessId(), GetTickCount64());
constexpr size_t buf_bytes = MAX_PATH * sizeof(wchar_t);
HANDLE map = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, buf_bytes, map_name);
if (!map) return L"";
auto view = static_cast<wchar_t*>(MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, buf_bytes));
if (!view) {
CloseHandle(map);
return L"";
}
view[0] = L'\0';
// إرسال الأمر إلى Seer مع اسم التخطيط الفريد كـ payload
COPYDATASTRUCT cds;
cds.dwData = 5006; // SEER_GET_CURRENT_FILE
cds.cbData = buf_bytes;
cds.lpData = map_name;
SendMessageW(seer_hwnd, WM_COPYDATA, 0, reinterpret_cast<LPARAM>(&cds));
std::wstring current_file;
if (view[0] != L'\0') {
current_file = view;
}
UnmapViewOfFile(view);
CloseHandle(map);
return current_file;
}