Решил написать плагин WLX с внешним просмотрщиком. За основу взял исходники sLister, также использовал исходники TCPlayer. На Visual C++. И никак не получается встроить внешнюю прогу в листер, а тем более в быстрый просмотр. Прога запускается отдельно в своем окне, чтобы я не делал. Меняю в этом-же коде все на данные суматры, опять все работает правильно. Изменяю детект-строку, название проги и название класса ее окна. Собственно именно эти данные и меняются в коде плага. Но не получается встроить прогу в листер и все.
Может кто может поподробнее объяснить, как встроить окно внешней проги в листер?
Не получается встроить окно внешней проги
Модераторы: d-view, Моторокер, Avada, CaptainFlint, Nik
Решил привести полностью процедуру, может это поможет:
Вот эту строку я не могу понять. Если убрать -plugin, то и суматра выводится отдельным окном.
swprintf_s(cmd,4096,L"%s -plugin %d \"%s\"",rpath,WLXPluginsClass,FileToLoad);
То-есть проблема явно в этой строке, но как она должна правильно выглядеть - не пойму.
Код: Выделить всё
extern "C" __declspec(dllexport) HWND __stdcall ListLoadW(HWND ParentWin,wchar_t* FileToLoad,int ShowFlags) {
bool sf = false;
if (WS_CHILD & GetWindowLong((HWND)ParentWin, GWL_STYLE))sf = true;
HWND ppp = GetFocus();
PROCESS_INFORMATION pi = { 0 };
STARTUPINFOW si = { 0 };
wchar_t path[MAX_PATH] = L"";
wchar_t rpath[MAX_PATH] = L"";
wchar_t spath[MAX_PATH] = L"";
GetModuleFileNameW(hInst, path, MAX_PATH);
//PathRemoveFileSpecW((LPWSTR)path);
if (wcsrchr(path, L'\\'))*wcsrchr(path, L'\\') = L'\0';
wcscat_s(path, MAX_PATH, L"\\");
wcscpy_s(spath, MAX_PATH, path);
wcscpy_s(rpath, MAX_PATH, path);
wcscat_s(spath, MAX_PATH, PROGRAMNAME);
wcscat_s(rpath, MAX_PATH, PROGRAMNAME);
wchar_t cmd[4096]=L"";
WNDCLASSA wc = {};
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.style=CS_DBLCLKS;
wc.hInstance = hInst;
wc.lpfnWndProc = WLXPluginsWindowProc;
wc.lpszClassName = "WLXPluginsClass";
RegisterClassA(&wc);
RECT r;
GetClientRect(ParentWin,&r);
HWND WLXPluginsClass = CreateWindowExA(0, "WLXPluginsClass", NULL, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN, r.left, r.top, r.right-r.left,r.bottom-r.top, ParentWin, NULL, hInst, NULL);
swprintf_s(cmd,4096,L"%s -plugin %d \"%s\"",rpath,WLXPluginsClass,FileToLoad);
si.cb = sizeof(si);
if (CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
HWND swnd = NULL;
for (int i = 0; swnd == NULL && i < 5000; i++) {
Sleep(10);
swnd = FindWindowEx(WLXPluginsClass, NULL, NULL, NULL);
}
if (sf)SetWindowLongPtr(WLXPluginsClass, GWLP_USERDATA, (LONG)SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)SpyProcQ, hInst, pi.dwThreadId));
else
SetWindowLongPtr(WLXPluginsClass, GWLP_USERDATA, (LONG)SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)SpyProcN, hInst, pi.dwThreadId));
if (sf) {
for (int i = 0; GetFocus() == ppp && i < 5000; i++)Sleep(10);
SetFocus(ppp);
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return WLXPluginsClass;
}
else DestroyWindow(WLXPluginsClass);
return NULL;
}swprintf_s(cmd,4096,L"%s -plugin %d \"%s\"",rpath,WLXPluginsClass,FileToLoad);
То-есть проблема явно в этой строке, но как она должна правильно выглядеть - не пойму.
Проблему локализовал. Дело в том, вообще что не удается стандартными методами (через CreateProcessA, либо через ShellExecuteEx) вставить вызов любой программы в дочернее окно. Внешнее приложение всегда запускается в отдельном окне. В SumatrePDF для запуска ее в дочернем окне есть специальный недокументированный ключ -plugin. Вот код этого ключа:
Есть у кого-нибудь идеи, как это использовать из внешнего кода, то-есть который я пишу?
Код: Выделить всё
// in order to host SumatraPDF as a plugin, create a (child) window and
// handle the following messages for it:
LRESULT CALLBACK PluginParentWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
if (WM_CREATE == msg) {
// run SumatraPDF.exe with the -plugin command line argument
PluginStartData* data = (PluginStartData*)((CREATESTRUCT*)lp)->lpCreateParams;
AutoFreeWstr cmdLine(str::Format(L"-plugin %d \"%s\"", hwnd, data->filePath));
if (data->fileOriginUrl) {
cmdLine.Set(str::Format(L"-plugin \"%s\" %d \"%s\"", data->fileOriginUrl, hwnd, data->filePath));
}