Zgodność firm trzecich
Developer Guide
Jeśli tworzysz oprogramowanie w C++, możesz bezpośrednio użyć pliku nagłówkowego ipchelper.h z Seer SDK, który hermetyzuje wszystkie opisane poniżej interfejsy API Win32 IPC.
Seer obsługuje integrację z aplikacjami firm trzecich i niestandardowymi menedżerami plików za pomocą Win32 IPC za pośrednictwem komunikatów WM_COPYDATA.
Integracja z niestandardową aplikacją (ACustomApp)
Niestandardowa aplikacja może wyzwolić Seer w celu wyświetlenia podglądu dla określonej ścieżki pliku.
Krok 1: Znalezienie uchwytu okna Seer
Znajdź uchwyt okna za pomocą FindWindowW :
HWND seer = FindWindowW(L"SeerWindowClass", nullptr);
Krok 2: Wysłanie ścieżki absolutnej wybranego pliku
Wyślij ścieżkę absolutną pliku do uchwytu okna 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);
}
Integracja z niestandardowym menedżerem plików (ACustomExplorer)
Niestandardowe menedżery plików mogą zarejestrować nazwę klasy swojego okna (classname), dzięki czemu Seer nasłuchuje naciśnięcia spacji (Spacebar) w tym oknie i żąda ścieżki aktualnie wybranego pliku w celu wyświetlenia podglądu.
Krok 1: Rejestracja nazwy klasy
Utwórz plik JSON w folderze %USERPROFILE%/Documents/Seer/explorers/. Po uruchomieniu Seer ładuje wszystkie pliki JSON z tego katalogu. Plik JSON musi zawierać nazwę klasy docelowego okna:
{
"classname": "YourCustomExplorerClass",
"windowtext": "OptionalWindowTextToMatch",
"appname": "YourAppName"
}
Krok 2: Obsługa naciśnięcia spacji
Gdy użytkownik naciśnie spację w oknie menedżera plików, Seer przechwytuje naciśnięcie klawisza i wywołuje GetForegroundWindow w celu dopasowania nazwy klasy. Jeśli pasuje, Seer wysyła komunikat WM_COPYDATA do uchwytu okna z dwData ustawionym na SEER_REQUEST_PATH (4000), cbData = 0 i lpData = nullptr.
Seer wysyła ten komunikat za pomocą SendMessageTimeout z limitem czasu 150ms, aby zapobiec zawieszeniu interfejsu, jeśli aplikacja nie odpowiada.
Krok 3: Odpowiedź z wybraną ścieżką
Aplikacja musi obsłużyć komunikat WM_COPYDATA, sprawdzić, czy dwData to SEER_REQUEST_PATH, i odpowiedzieć wysyłając komunikat WM_COPYDATA z powrotem do Seer z dwData ustawionym na SEER_RESPONSE_PATH (4001), zawierający pełną ścieżkę wybranego pliku jako ciąg znaków szerokich zakończony znakiem null.
Krok 4: Wyświetlenie podglądu
Gdy Seer otrzyma ścieżkę, wyświetla okno podglądu i proces się kończy.
Słownik poleceń IPC (SeerCommand)
Następujące polecenia są zdefiniowane w seer/ipc.h do komunikacji z Seer:
| Nazwa polecenia | Wartość | Opis |
|---|---|---|
SEER_REQUEST_PATH |
4000 |
Wysyłane z Seer do niestandardowego eksploratora z żądaniem ścieżki aktualnie wybranego pliku. |
SEER_RESPONSE_PATH |
4001 |
Wysyłane z niestandardowego eksploratora z powrotem do Seer, zawierające ścieżkę wybranego pliku. |
SEER_INVOKE_W32 |
5000 |
Wysyłane z niestandardowej aplikacji do Seer w celu wyzwolenia podglądu w oknie głównym (minimalny odstęp 200 ms). |
SEER_INVOKE_W32_SEP |
5001 |
Wysyłane z niestandardowej aplikacji do Seer w celu wyzwolenia podglądu w osobnym oknie. |
SEER_IS_VISIBLE |
5004 |
Sprawdza, czy główne okno podglądu jest widoczne. Zwraca VISIBLE_TRUE (1) lub VISIBLE_FALSE (0). |
SEER_HIDE |
5005 |
Ukrywa główne okno podglądu, jeśli jest widoczne. |
SEER_GET_CURRENT_FILE |
5006 |
Zapytuje Seer o ścieżkę aktualnie podglądanego pliku (poprzez nazwaną pamięć współdzieloną). |
SEER_GET_VERSION |
5007 |
Zapytuje o wersję Seer (np. zwraca 40001 dla wersji 4.0.1). |
SEER_IS_TRACKING_ENABLED |
5008 |
Zapytuje, czy tryb śledzenia plików jest włączony. |
Żądanie aktualnie podglądanego pliku
Ponieważ WM_COPYDATA nie może bezpośrednio zwracać ciągów znaków o zmiennej długości, zapytanie o aktualnie podglądany plik (SEER_GET_CURRENT_FILE) korzysta z nazwanego protokołu mapowania plików (pamięci współdzielonej).
Przykładowa implementacja w C++
#include <windows.h>
#include <string>
std::wstring getSeerCurrentFile(HWND seer_hwnd)
{
if (!seer_hwnd) return L"";
// Utwórz unikalną nazwę dla mapowania plików
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';
// Wyślij polecenie do Seer z unikalną nazwą mapowania jako danymi
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;
}