Не получается встроить окно внешней проги
Select messages from
# through # FAQ
[/[Print]\]

Total Commander -> Написание плагинов для Total Commander

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

#2:  Author: AkulaBig PostPosted: Mon Jul 19, 2021 13:59
    —
Решил привести полностью процедуру, может это поможет:
Code:
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);
То-есть проблема явно в этой строке, но как она должна правильно выглядеть - не пойму.

#3:  Author: AkulaBig PostPosted: Thu Jul 22, 2021 09:46
    —
Разобрался и понял, что не каждую прогу можно встроить в листер.

#4:  Author: AkulaBig PostPosted: Fri Jul 30, 2021 21:41
    —
Проблему локализовал. Дело в том, вообще что не удается стандартными методами (через CreateProcessA, либо через ShellExecuteEx) вставить вызов любой программы в дочернее окно. Внешнее приложение всегда запускается в отдельном окне. В SumatrePDF для запуска ее в дочернем окне есть специальный недокументированный ключ -plugin. Вот код этого ключа:
Code:
// 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));
        }

Есть у кого-нибудь идеи, как это использовать из внешнего кода, то-есть который я пишу?

#5:  Author: imig73Location: г. Иркутск PostPosted: Sat Jul 31, 2021 00:00
    —
AkulaBig
Я не такой крутой специалист как вы, но про внешний какой то код вообще ничо не понял. Вам надо напрямую обратиться к MVV или Флинту и они вам подскажут как правильно оформить вызов. Тема созданная вами заведомо гласит быть дохлой.

#6:  Author: AkulaBig PostPosted: Tue Aug 03, 2021 07:31
    —
Вопрос решен. Тему можно закрывать. Огромное спасибо автору AmpView за открытые исходники. Именно на их основе удалось выполнить задуманное.



Total Commander -> Написание плагинов для Total Commander


output generated using printer-friendly topic mod. All times are GMT + 4 Hours

Page 1 of 1

Powered by phpBB © 2001, 2005 phpBB Group