第三方相容性

Developer Guide

如果您正在使用 C++ 開發,可以直接使用 Seer SDK 中的 ipchelper.h 輔助標頭檔,它已經封裝了下面描述的所有 Win32 IPC API。

Seer 支援透過 WM_COPYDATA 訊息使用 Win32 IPC 與第三方應用程式和自訂檔案管理器進行整合。

Custom App 整合 (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:註冊類別名稱

%USERPROFILE%/Documents/Seer/explorers/ 目錄下建立一個 JSON 檔案。當 Seer 啟動時,它會載入該目錄下的所有 JSON 檔案。該 JSON 必須包含目標視窗的類別名稱:

{
  "classname": "YourCustomExplorerClass",
  "windowtext": "OptionalWindowTextToMatch",
  "appname": "YourAppName"
}

步驟 2:處理空白鍵按下

當使用者在您的檔案管理器視窗中按下空白鍵時,Seer 會攔截該按鍵並呼叫 GetForegroundWindow 來比對類別名稱。如果符合,Seer 會發送一個 WM_COPYDATA 訊息到您的視窗控制代碼,其中 dwData 設定為 SEER_REQUEST_PATH (4000),cbData = 0lpData = nullptr

Seer 傳送此訊息時使用 SendMessageTimeout 並設定超時時間為 150ms,以防止在您的應用程式無回應時導致介面停頓。

步驟 3:回應所選路徑

您的應用程式必須處理 WM_COPYDATA 訊息,檢查 dwData 是否為 SEER_REQUEST_PATH,並透過向 Seer 傳送一個 WM_COPYDATA 訊息進行回應,其中 dwData 設定為 SEER_RESPONSE_PATH (4001),並包含所選檔案的完整路徑(以 null 結尾的寬字元字串)。

步驟 4:顯示預覽

當 Seer 收到路徑後,它會顯示預覽視窗,流程即告完成。


IPC 指令參考 (SeerCommand)

seer/ipc.h 中定義了以下用於與 Seer 通訊的指令:

指令名稱 數值 說明
SEER_REQUEST_PATH 4000 從 Seer 發送到自訂檔案管理器,請求目前選取檔案的路徑。
SEER_RESPONSE_PATH 4001 從自訂檔案管理器發送回 Seer,包含選取檔案的路徑承載資料。
SEER_INVOKE_W32 5000 從自訂 App 發送到 Seer,以觸發主視窗中的預覽(最小間隔 200ms)。
SEER_INVOKE_W32_SEP 5001 從自訂 App 發送到 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 版本(例如,版本 4.0.1 回傳 40001)。
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,並以唯一的對應名稱作為承載資料
    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;
}