Страница 1 из 1

Не получается встроить окно внешней проги

Добавлено: Чт июл 15, 2021 17:53
AkulaBig
Решил написать плагин WLX с внешним просмотрщиком. За основу взял исходники sLister, также использовал исходники TCPlayer. На Visual C++. И никак не получается встроить внешнюю прогу в листер, а тем более в быстрый просмотр. Прога запускается отдельно в своем окне, чтобы я не делал. Меняю в этом-же коде все на данные суматры, опять все работает правильно. Изменяю детект-строку, название проги и название класса ее окна. Собственно именно эти данные и меняются в коде плага. Но не получается встроить прогу в листер и все.
Может кто может поподробнее объяснить, как встроить окно внешней проги в листер?

Добавлено: Пн июл 19, 2021 12:59
AkulaBig
Решил привести полностью процедуру, может это поможет:

Код: Выделить всё

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;

}
Вот эту строку я не могу понять. Если убрать -plugin, то и суматра выводится отдельным окном.
swprintf_s(cmd,4096,L"%s -plugin %d \"%s\"",rpath,WLXPluginsClass,FileToLoad);
То-есть проблема явно в этой строке, но как она должна правильно выглядеть - не пойму.

Добавлено: Чт июл 22, 2021 08:46
AkulaBig
Разобрался и понял, что не каждую прогу можно встроить в листер.

Добавлено: Пт июл 30, 2021 20:41
AkulaBig
Проблему локализовал. Дело в том, вообще что не удается стандартными методами (через 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));
        }
Есть у кого-нибудь идеи, как это использовать из внешнего кода, то-есть который я пишу?

Добавлено: Пт июл 30, 2021 23:00
imig73
AkulaBig
Я не такой крутой специалист как вы, но про внешний какой то код вообще ничо не понял. Вам надо напрямую обратиться к MVV или Флинту и они вам подскажут как правильно оформить вызов. Тема созданная вами заведомо гласит быть дохлой.

Добавлено: Вт авг 03, 2021 06:31
AkulaBig
Вопрос решен. Тему можно закрывать. Огромное спасибо автору AmpView за открытые исходники. Именно на их основе удалось выполнить задуманное.