Запрет запуска двух копий wlx

Только для тех, кто пишет плагины под Total Commander. Обмен опытом, решение проблем.

Модераторы: d-view, Моторокер, Avada, CaptainFlint, Nik

Аватара пользователя
Nik
Сообщения: 583
Зарегистрирован: Сб янв 01, 2005 13:00
Откуда: Киров
Контактная информация:

Запрет запуска двух копий wlx

Сообщение Nik »

Кто-нибудь знает как можно запретить запуск двух копий Lister-плагина. Я перепробовал на AmpView-e все известные мне варианты (поиск окна, mutex, file-mapping) и ни один нормально не работает (для плагинов - в обычных программах все работает нормально). Более или менее прилично работает mutex, но и с ним куча проблем (см. AmpView).

PS. Пишу на Delphi 7
Dest
Сообщения: 44
Зарегистрирован: Пт дек 17, 2004 20:58
Откуда: Беларусь(Минск,Барановичи)
Контактная информация:

Сообщение Dest »

А зачем тебе это ?
Аватара пользователя
SCHMaster
Сообщения: 296
Зарегистрирован: Ср дек 15, 2004 02:32
Откуда: Киев
Контактная информация:

Сообщение SCHMaster »

Nik
Можно. Но это извратс.... Идеи таковы
1. Что нужно листеру? Тове окно. Дай, но не рабочее :) И тут-же прибей вместе с листером.
2. Твое окно "прыгает" с одного листера, на другой, при этом прибивая старый (DSView)
3. См. первый вариант+2+еще изврат - Первый вызваный экземпляр "прибивает" все последующие, перехватив предварительно имя файла (SMView).
Аватара пользователя
Nik
Сообщения: 583
Зарегистрирован: Сб янв 01, 2005 13:00
Откуда: Киров
Контактная информация:

Сообщение Nik »

SCHMaster писал(а):Nik
Можно. Но это извратс.... Идеи таковы
1. Что нужно листеру? Тове окно. Дай, но не рабочее :) И тут-же прибей вместе с листером.
2. Твое окно "прыгает" с одного листера, на другой, при этом прибивая старый (DSView)
3. См. первый вариант+2+еще изврат - Первый вызваный экземпляр "прибивает" все последующие, перехватив предварительно имя файла (SMView).
Я уже пытался сделать нечто похожее... Глюк на глюке...
А зачем тебе это ?

Плагины Winamp, которые грузит AmpView при загрузке проверяют handle родительского окна, а в случае с Lister-плагином таковым всегда является окно TC. Поэтому попытка запуска двух копий AmpView приводит к сбою... Так как изменить winamp-плагины я не могу, то приходиться выкручиваться...
Dest
Сообщения: 44
Зарегистрирован: Пт дек 17, 2004 20:58
Откуда: Беларусь(Минск,Барановичи)
Контактная информация:

Сообщение Dest »

Знаеш. Я юзаю плагины винампа только в самом винампе. А другим прогам - не довареяю (сам пытался их использовать - очень всё глючно сделано). Легче использовать winamp api (в проге http://wincmd.ru/plugring/Camp.html юзал - быстро и безглючно :)
Аватара пользователя
SCHMaster
Сообщения: 296
Зарегистрирован: Ср дек 15, 2004 02:32
Откуда: Киев
Контактная информация:

Сообщение SCHMaster »

Nik
Я уже пытался сделать нечто похожее... Глюк на глюке...
Гм... Если давать листеру окно VCL - TForm - точно, глюков необерешься. А дать ему окошко забацанное тут-же на API с уже готовой процедурой окна, (которая и прибъет потом родителя :)) не пробовал??? Попробуй - работает "на раз" и без глюков. Если такой метод тебе подходит, но "застрянешь" с кодом - свисти. Не пишу сразу по одной причине - может тебе (как мне, к примеру) более интересно докапаться самому - в этом весь кайф. Но если с программированием на чистом Win32API проблемы (ткт ничего страшного или "стыдного" нет - значит просто не было надобности), то гадать мона долго... Так что надо будет - свисти. Правда я только по ночам...
Аватара пользователя
Nik
Сообщения: 583
Зарегистрирован: Сб янв 01, 2005 13:00
Откуда: Киров
Контактная информация:

Сообщение Nik »

SCHMaster писал(а):Nik
Я уже пытался сделать нечто похожее... Глюк на глюке...
Гм... Если давать листеру окно VCL - TForm - точно, глюков необерешься. А дать ему окошко забацанное тут-же на API с уже готовой процедурой окна, (которая и прибъет потом родителя :)) не пробовал??? Попробуй - работает "на раз" и без глюков. Если такой метод тебе подходит, но "застрянешь" с кодом - свисти. Не пишу сразу по одной причине - может тебе (как мне, к примеру) более интересно докапаться самому - в этом весь кайф. Но если с программированием на чистом Win32API проблемы (ткт ничего страшного или "стыдного" нет - значит просто не было надобности), то гадать мона долго... Так что надо будет - свисти. Правда я только по ночам...
Тут есть пара проблем: с одной стороны я использую не станадартный компонент (который, в принципе можно заменить); с другой - на чистом WinApi я до сих пор не писал, так что любой помощи буду рад...
В принципе пример того, как работает AmpView можно глянуть в исходниках AmpView Classic (они выложены на wincmd.ru).
Аватара пользователя
SCHMaster
Сообщения: 296
Зарегистрирован: Ср дек 15, 2004 02:32
Откуда: Киев
Контактная информация:

Сообщение SCHMaster »

Nik
Тут есть пара проблем: с одной стороны я использую не станадартный компонент (который, в принципе можно заменить); с другой - на чистом WinApi я до сих пор не писал, так что любой помощи буду рад...
В принципе пример того, как работает AmpView можно глянуть в исходниках AmpView Classic (они выложены на wincmd.ru).
Компоненты тут непричем. А помощь - невопрос. Что непонятно - свисти.

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

// Cтруктура отображенного в память файла - как создать и юзать 
набери в поисковике - CreateFileMapping и MapViewOfFile
  PMainData = ^TMainData;
  TMainData = record
  MainForm:HWND;
  ....
  ....
end;

...
var
DMainData:PMainData; // Глобальная (!!!!) переменная 
wc : TWndClass;
I:Integer = 0

function ListLoad(ParentWin: HWND;  FileToLoad: pchar;  ShowFlags: integer): HWND; stdcall;
var
  WndClass: array [0..255] of Char;
begin
 Result := 0;
 GetClassName(GetParent(ParentWin), WndClass, SizeOf(WndClass));

 if not (WndClass <> 'TTOTAL_CMD') then Exit; //С QuiqView такой фокас не прокатит

if not (.... выполняем проверку - подходит файл млм нет...) then Exit;

 if DMainData^.MainForm = 0 then
 begin
 DMainData^.MainForm:=CreateMyPluginWindow// Твой плагин
 if DMainData^.MainForm = 0 then Exit;
 end
 else
 begin
 I:=SendMessage(DMainData^.MainForm,WM_MAINCOMMAND,MYCMD,0);
 if I = 0 then Exit; // Сообщкние окну плагина о новом файле, можно WM_COPYDATA, можно что-то свое - главное передать имя файла.
 end;

 Result :=CallKiller(ParentWin);
 if Result = 0 then Exit;
 SetWindowPos(ParentWin,0,-100,-100,0,0,SWP_HIDEWINDOW);// Убираем с глаз-долой листер
end;

и "само убийство"

function WindowProc(wnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult; stdcall;
var
 Style:Longint;
 LW:HWND;
Begin
LW:=GetParent(wnd);
          PostMessage(LW,WM_KEYDOWN, 27, 0);
          Result := DefWindowProc(wnd,msg,wparam,lparam);
End;



function CallKiller(aListerWindow:HWND):HWND;
begin
result:=CreateWindowEx(WS_EX_CONTROLPARENT,'LISTER_KILLER','LISTER_KILLER',WS_CHILD or WS_VISIBLE or WS_CLIPSIBLINGS
                                          ,0,0,10,10,aListerWindow,0,Hinstance,nil);

end;


exports
....
begin
....
  WC.lpfnWndProc     := @WindowProc;
  WC.style           := CS_VREDRAW or CS_HREDRAW;
  WC.hInstance       := hInstance;
  WC.hIcon           := 0;
  WC.hCursor         := LoadCursor(0,IDC_ARROW);
  WC.hbrBackground   := CreateSolidBrush( COLOR_BTNFACE+1 );
  WC.lpszMenuName    := nil;
  WC.cbClsExtra      := 0;
  WC.cbWndExtra      := 0;
  wc.lpszClassName   := 'LIST_KILL';
 Windows.RegisterClass(wc);


...

end.
Аватара пользователя
Nik
Сообщения: 583
Зарегистрирован: Сб янв 01, 2005 13:00
Откуда: Киров
Контактная информация:

Сообщение Nik »

SCHMaster писал(а):Nik
Тут есть пара проблем: с одной стороны я использую не станадартный компонент (который, в принципе можно заменить); с другой - на чистом WinApi я до сих пор не писал, так что любой помощи буду рад...
В принципе пример того, как работает AmpView можно глянуть в исходниках AmpView Classic (они выложены на wincmd.ru).
Компоненты тут непричем. А помощь - невопрос. Что непонятно - свисти.

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

// Cтруктура отображенного в память файла - как создать и
(пропущено)
Спасибо. Попробую приладить все это дело к AmpView'у...
Аватара пользователя
Nik
Сообщения: 583
Зарегистрирован: Сб янв 01, 2005 13:00
Откуда: Киров
Контактная информация:

Сообщение Nik »

SCHMaster

При первом обращении к переменной DMainData (при проверке условия) происходит сбой (Access v.)...

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

 if DMainData^.MainForm = 0 then
  begin
   DMainData^.MainForm:=CreateViewer(ParentWin, FileToLoad);
   if DMainData^.MainForm = 0 then Exit;
  end
 else
  begin
   I:=SendMessage(DMainData^.MainForm,WM_COPYDATA,0,0);
   if I = 0 then Exit;
  end;
Я пока не могу понять, в чем проблема...
Остальной код взял из твоего примера.
Аватара пользователя
SCHMaster
Сообщения: 296
Зарегистрирован: Ср дек 15, 2004 02:32
Откуда: Киев
Контактная информация:

Сообщение SCHMaster »

Nik
Ясно... А про отображаемые в память файлы ты прочитал? Ес-сно поисковиком было лень воспользоваться... Прямых ссылок у меня нет - те что были, давно прогорели, а новые... Ну если тебе лень, то мне тем более :). А объяснять здесь не то что неохота (хотя и это), просто смысла нет - это настолько избитая тема, и столько всего написано... Так-что дерзай.
Но без файла в памяти тебе не обойтись, юзая любой из предложенных мною методов - это средство "общения" м-ду листером и твоим окном.
З.Ы.
Постарайся найти инфу сам. Но если все-таки неполучится - свисти. И не обижайся на мои "методы" обучения - профессия у меня такая - преподаватель :). И такой метод - самый действенный - тебе дают зацепку, направление, но "роешь" дальше сам. Тогда уже запомнишь навсегда. А если и не неайдешь, то потратив время на поиски решения ты уже "готов" принять инфу, о том как это сделать. Проверено годами - работает "на-раз".
Будут вопросы - свисти :).
Dest
Сообщения: 44
Зарегистрирован: Пт дек 17, 2004 20:58
Откуда: Беларусь(Минск,Барановичи)
Контактная информация:

Сообщение Dest »

Чесно говоря я не понимаю в чём проблема с subj.
Делается всё очень просто.

Регистрируем свой класс (в стилях стамим - дескать глобальный).
А перед этим - проверям, а не зарегин ли этот клас уже.
Если зарегин - ясное дело что прога/плагин/процесс/... уже запущен.
Если прога запущена:
1) Шлём WM_CLOSE окну листера (hWnd должен передаватся при инициализации плагина)
2) Активируем окно, которое ты нашел при поиске класса.
На дельфе - давно не прогил. Могу показать как на сях.

На счёт отображения файлов:
В MSDN всё хорошо написано (с.м. функцию CreateFileMapping).

2SCHMaster
Мне всегда говорили - из меня полхой учитель. Но я тоже считаю что метод научного тыка - лучший способ изучать что-нибудь новое (главное не забыть после всего этого нормальную инфу по теме прочитать :).
Аватара пользователя
SCHMaster
Сообщения: 296
Зарегистрирован: Ср дек 15, 2004 02:32
Откуда: Киев
Контактная информация:

Сообщение SCHMaster »

Dest
метод научного ...
:)
Вообще-то я как раз и предложил вначале инфу почитать, а потом тыкать (см. примечания в коде)... Но и метод тыка я не отрицаю. Иногда действует... :) Кстати WM_CLOSE не сработает - листер просто "закроется", но уничтожен не будет. С WM_DESTROY та-же хрень, но с другой стороны. По тому самый простой способ послать ESC. По-тому и посылаю. А файл в памяти нужен не только для хранения хендла окна и проверки запущен плагин или нет... Это я дал "намек". Почитает Nik инфу и поймет на что. Найдет другие средства - невопрос. Вариантов - море. :)
Dest
Сообщения: 44
Зарегистрирован: Пт дек 17, 2004 20:58
Откуда: Беларусь(Минск,Барановичи)
Контактная информация:

Сообщение Dest »

SCHMaster
Я для хранения данных (если есть окно) использую доп. байты для окна. А нащёт тыка:
Одно дело когда есть документация и ты ее понимаеш. Совсем другое,если нет либо того либо другого.
Аватара пользователя
SCHMaster
Сообщения: 296
Зарегистрирован: Ср дек 15, 2004 02:32
Откуда: Киев
Контактная информация:

Сообщение SCHMaster »

Dest
Я для хранения данных (если есть окно)
Да можно и так. Я не спорю. Просто мне один черт приходится юзать файл в памяти, по-тому и храню все там-же - ниче искать-доставать ненадо - все под рукой. Тут уже как захочешь.
Одно дело когда есть документация и ты ее понимаеш
Документации в сети хватает. Ну а про конкретный случай - если хватило кумекалки понять как писать плагины, то с файлами в памяти разобраться можно :). Ниче военного тут нет. Вот если уже непонятно - тогда придется "разжовывать".
Ответить