Re[6]: EXE-сервер с GUI
От: IT Россия linq2db.com
Дата: 23.01.02 04:20
Оценка:
Здравствуйте chum, Вы писали:

C>Ну, грубо говоря, "не догоняете". Перечитайте еще раз предыдущее сообщение (22.01 19:08).


Давай я лучше попробую это сообщение переписать

C>СЕРВЕР_GUI нужен, чтобы можно было менять пользовательский интерфейс программы без смены ядра и без изменения КЛИЕНТА_ПЕРЕВОДЧИКА (всех уже написанных КЛИЕНТОВ_ПЕРЕВОДЧИКОВ), которые обращаются к СЕРВЕРУ_ПЕРЕВОДЧИКУ через CLSID ядра! Ему нельзя подсовывать каждый раз новую реализацию GUI с агрегированным ядром и новым CLSID (или ProgID)!


Ok, у нас уже вырисовывается 3 компонента. Ядро, отображалка и некая управляющая программа.
  1. Функции ядра — переводить, искать, загружать, удалять, обновлять, делать любую другую полезную и не очень работу. При возникновении каких-то неординарных событий в ядре, о которых должны знать клиенты, это ярдо должно их информировать, например, посредством генерации событий. Ядро может использоваться управляющей программой, либо любой другой, которя знает его интерфейс. Желательно, что бы ядро не имело понятия о том, что творится вокруг и зачем его пользуют.
  2. Отображалка. Одна или несколько, которая должна отображать то, что ей скажут. Для этого она должна реализовывать некий стандартный интерфейс, за который её будут дёргать и по которому она будет сообщать действия пользователя, который опять нажал какую-то левую кнопку. Она не должна иметь не малейшего понятия, откуда взяты те данные, которые она отображает. Её сказали нарисовать 'A' она должна нарисавать 'A', 'B' — 'B'. Если нажата кнопка anykey, она должна незамедлительно об этом сообщить.
  3. Управляющая программа. Она знаёт всё, но не умеет ни делать что-то полезное, ни даже рисовать. Только управлять... этакий танагер, блин. Манагер, как ему и положено, должен управлять, одному давать команду попереводить чего-нибудь, другому поотображать как-нибудь.

В рузультате имеет модульную архитектуру и теперь уже можно решать как будет реализован каждый модуль. Влад совершенно чётко обрисовал как можно построить ядро и какие получить от этого бонусы. Про скины тоже упомянули, обычно их делают в виде плагинов и здесь тоже можно смело применять COM интерфейсы. Управляющая программа — дело фантазии.
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: EXE-сервер с GUI
От: chum Россия  
Дата: 23.01.02 08:44
Оценка:
Здравствуйте IT, Вы писали:

IT>В рузультате имеет модульную архитектуру и теперь уже можно решать как будет реализован каждый модуль. Влад совершенно чётко обрисовал как можно построить ядро и какие получить от этого бонусы. Про скины тоже упомянули, обычно их делают в виде плагинов и здесь тоже можно смело применять COM интерфейсы. Управляющая программа — дело фантазии.


Все это замечательно. Пускай не ядро общается с GUI, а управляющая программа (manager). Manager (как и в моем случае ядро) будет клиентом компонента, реализующего GUI (можете не называть его сервером, если вам так не нравится, но раз он реализует какие-то интерфейсы, за которые его "дергает" manager, то это и будет сервер). Это не принципиально! Принципиально то, что более или менее сложный пользовательский интерфейс — это не скин! Это не просто "отображалка". Он предполагает обратную связь. Те же вышеупомянутые скины WinAmp'а просто меняют его внешний вид, но все управление (обратная связь) вне их компетенции! WinAmp не дает возможности сторонним разработчикам менять набор операций управления таким простым набором данных, как список песен. Вы не можете подключить к WinAmp'у свой хитрый способ пригрывания мелодий в очередности дат их написания!
Вы спросите меня: а при чем тут GUI? GUI тут не при чем. Здесь проблема вся в том, что нужен некий сервер, к которому присоединяются клиенты и работают с ним совершенно единообразным образом. И этот же сервер использует (уже в качестве клиента!) некий другой компонент с обратной связью.

Вы все говорите: давай поменяем местами сервер (ядро) и этот "другой" компонент. Благо сервер — величина постоянная, а этот "другой" — переменная. Но тогда разрывается связь между нашим первоначальным сервером и его клиентами!

Тут присутствует некая цепочка взаимодействий компонентов. А вы пытаетесь разбить эту цепочку на звенья и каждое отдельное звено реализовать простейшим образом. Проблема же в том, как создать сервер, который может иметь некие подключаемые (заменяемые) компоненты с обратной связью. Ключевое словосочетание здесь "обратная связь". Упомянутые plug-in'ы, насколько я понимаю, такой связи не имеют. Сервер просто сливает в них некие данные и получает результат обработки. Под обратной связью я понимаю возможность получения подключаемым компонентом от сервера некой дополнительной информации, помимо той, что сервер счел достаточным сообщить подключаемому компоненту при подключении. Может ли подключаемый компонент обращаться к серверу через его интерфейсы или это в принципе невозможно?
Если есть возможность отдать человеку все, не прося ничего взамен — отдай. Если тебе один раз из десяти долг отдадут — будешь богатым.
Re[8]: EXE-сервер с GUI
От: Willi  
Дата: 23.01.02 09:17
Оценка:
Здравствуйте chum, Вы писали:

C>Тут присутствует некая цепочка взаимодействий компонентов. А вы пытаетесь разбить эту цепочку на звенья и каждое отдельное звено реализовать простейшим образом. Проблема же в том, как создать сервер, который может иметь некие подключаемые (заменяемые) компоненты с обратной связью. Ключевое словосочетание здесь "обратная связь". Упомянутые plug-in'ы, насколько я понимаю, такой связи не имеют. Сервер просто сливает в них некие данные и получает результат обработки. Под обратной связью я понимаю возможность получения подключаемым компонентом от сервера некой дополнительной информации, помимо той, что сервер счел достаточным сообщить подключаемому компоненту при подключении. Может ли подключаемый компонент обращаться к серверу через его интерфейсы или это в принципе невозможно?


Если я правильно понимаю, то тебе нужно что-то вроде модели взаимодействия инетерфейсов IStorage — IPersistStorage.

Т.е. ты получаешь у сервера некий интерфейс ( IPersistStorage )
и просишь его что-то сделать ( IPersistStorage::Load ),
подсовывая свой интерфейс ( IStorage ),
сервер в процессе выплнения того о чем ты его попросил, вызывает твои методы для выполнения элементарных действий.

Понятное дело названия интерфейсов даны только в качестве примера, чтобы проиллюстрировать механизм взаимодействия.

Если я опять не догнал, то тогда соглашуcь с VladD2, ОЧЕНЬ_ПЛОХО_ОБЪЯСНЯЕШЬ.
\/\/i||i
Re[9]: EXE-сервер с GUI
От: chum Россия  
Дата: 23.01.02 09:40
Оценка:
Здравствуйте Willi, Вы писали:

W>Если я правильно понимаю, то тебе нужно что-то вроде модели взаимодействия инетерфейсов IStorage — IPersistStorage.


W>Т.е. ты получаешь у сервера некий интерфейс ( IPersistStorage )

W>и просишь его что-то сделать ( IPersistStorage::Load ),
W>подсовывая свой интерфейс ( IStorage ),
W>сервер в процессе выплнения того о чем ты его попросил, вызывает твои методы для выполнения элементарных действий.

Ну, вроде того. Только вопрос не в том: сможет ли сервер вызывать методы IStorage клиента. Это не вопрос. Вопрос: сможет ли сервер вызывать методы других интерфейсов сервера? И не только в то время, когда клиент обратился к серверу, а тогда, когда ему это надо. Могут ли два компонента одновременно функционировать меняясь ролями? Обращаясь попеременно друг к другу, как к серверу? При этом, один из этих компонентов создан другим.

По поводу

W>ОЧЕНЬ_ПЛОХО_ОБЪЯСНЯЕШЬ


Я же не спрашиваю: как из указателя на IUnknown получить остальные интерфейсы сервера?
Тут все гораздо сложнее и в двух словах не объяснишь.
Я попытался начать с простого, вы спрашиваете "зачем?" Я нарисовал глобальную картину, вы говорите: "сложно". Я не знаю, как еще объяснять. Как только я упрощаю, вы начинаете мыслить простыми категориями и опять спрашиваете: "зачем?". Замкнутый круг.
Если есть возможность отдать человеку все, не прося ничего взамен — отдай. Если тебе один раз из десяти долг отдадут — будешь богатым.
Re[10]: EXE-сервер с GUI
От: Willi  
Дата: 23.01.02 10:10
Оценка: 18 (2)
Здравствуйте chum, Вы писали:

C>Вопрос: сможет ли сервер вызывать методы других интерфейсов сервера?


Конечно, почему бы и нет.

C>И не только в то время, когда клиент обратился к серверу, а тогда, когда ему это надо.


Запросто, два коспонента обмениваются инерфейсами и взывают их методы тогда когда им это нужно.

C>Могут ли два компонента одновременно функционировать меняясь ролями? Обращаясь попеременно друг к другу, как к серверу? При этом, один из этих компонентов создан другим.


Да. Главное определиться кто из них главнее, чтобы не было путуницы и deadlock-ов.

C>Я попытался начать с простого, вы спрашиваете "зачем?" Я нарисовал глобальную картину, вы говорите: "сложно". Я не знаю, как еще объяснять. Как только я упрощаю, вы начинаете мыслить простыми категориями и опять спрашиваете: "зачем?". Замкнутый круг.


Тогда вернемся к началу.

C>При этом возникают некоторые вопросы:

C>1. Как организовать взаимосвязь между сервером и GUI, когда они одновременно являются серверами и клиентами друг друга?

Тот кто первым создает объект и является клиентом. Он передает сереверу свой интерфейс (интерфейсы) и компоненты начинают взаимодействовать.

C>2. Как, например, реализовать GUI на VB?


Не понятно, что значит как? Садишься и пишешь.

C>Простая тестовая программа показывает, что при такой конфигурации VB не может создать немодальное окно приложения, а модальное окно приведет к deadlock'у сервера.


Ну так не создавай модальных окон.

C>3. Как инициализировать сервер, если он запущен как обычное приложени? Иными словами, если сервер имеет какой-то головной объект (скажем Application), то как и где его при этом создавать и удалять?


Как работате любой EXE COM server. Ты можешь указать что при зоздании нового экземпляра сервера не нужно запускать новы процесс а пользоваться сцществующим. Просто создаваемые экземпляры объектов, могут редиректить вызовы в какой-нить общий объект.

Что-то вроде.

// реальный класс выполняющий работу, создается при запуске приложения
class CServer
{
protected:
    CServer() {}

    static CServer m_instance;

public:
    CServer& GetInstance() { return m_instance; }

    void DoSomething( DWORD dwParam );
};

// класс оболочка, создается при вызове CoCreateInstance
class CServerWrapper
{
public:
    CServerWrapper() {}

    HRESULT DoSomething( DWORD dwParam ) // это метод COM интерфейса
    {
        CServer::GetInstance().DoSomething( dwParam );
        retrun S_OK;
    }
};
\/\/i||i
Re[11]: EXE-сервер с GUI
От: chum Россия  
Дата: 23.01.02 10:47
Оценка:
Здравствуйте Willi, Вы писали:

Ура! Кажется что-то начинает проясняться! Спасибо за терпение. Видимо мне надо было сразу начинать с [9] собощения :)

C>>2. Как, например, реализовать GUI на VB?


W>Не понятно, что значит как? Садишься и пишешь.


C>>Простая тестовая программа показывает, что при такой конфигурации VB не может создать немодальное окно приложения, а модальное окно приведет к deadlock'у сервера.


W>Ну так не создавай модальных окон.


Ну, дело в том, что я не силен в VB. Я просто для проверки своей идеи попробовал написать ActiveX DLL на VB с интерфейсом IGUI. И подсунул ему (этому ActiveX'у) указатель на интерфейс клиента. Из VB ActiveX отлаживается и запускается замечательно. А при попытке использования ее из клиента, VB ругнулся, что из этого хост-приложения не может быть создано немодальное окно, смените тип проекта на ActiveX EXE с модальным окном (не помню, как это сообщение звучит в оригинале). А я просто пытался в методе IGUI::Run() отобразить некую форму (SomeForm.Show()).

Что я делаю неправильно?

W>Как работате любой EXE COM server. Ты можешь указать что при зоздании нового экземпляра сервера не нужно запускать новы процесс а пользоваться сцществующим. Просто создаваемые экземпляры объектов, могут редиректить вызовы в какой-нить общий объект.


W>Что-то вроде.


W>
W>// реальный класс выполняющий работу, создается при запуске приложения
W>class CServer
W>{
W>protected:
W>    CServer() {}

W>    static CServer m_instance;

W>public:
W>    CServer& GetInstance() { return m_instance; }

W>    void DoSomething( DWORD dwParam );
W>};

W>// класс оболочка, создается при вызове CoCreateInstance
W>class CServerWrapper
W>{
W>public:
W>    CServerWrapper() {}

W>    HRESULT DoSomething( DWORD dwParam ) // это метод COM интерфейса
W>    {
W>        CServer::GetInstance().DoSomething( dwParam );
W>        retrun S_OK;
W>    }
W>};
W>


Ну я приблизительно так себе и представлял. Я только не пойму: в каком месте сгенерированного ATL-wizard'ом кода создавать (и удалять) экземпляр CServer? Полагаю, что где-то в _tWinMain(), если EXE-шник запушен без ключей командной строки. Или я ошибаюсь?
Если есть возможность отдать человеку все, не прося ничего взамен — отдай. Если тебе один раз из десяти долг отдадут — будешь богатым.
Re[12]: EXE-сервер с GUI
От: Willi  
Дата: 23.01.02 11:02
Оценка:
Здравствуйте chum, Вы писали:

C>Ура! Кажется что-то начинает проясняться! Спасибо за терпение. Видимо мне надо было сразу начинать с [9] собощения


Я рад.

C>Ну, дело в том, что я не силен в VB. Я просто для проверки своей идеи попробовал написать ActiveX DLL на VB с интерфейсом IGUI. И подсунул ему (этому ActiveX'у) указатель на интерфейс клиента. Из VB ActiveX отлаживается и запускается замечательно. А при попытке использования ее из клиента, VB ругнулся, что из этого хост-приложения не может быть создано немодальное окно, смените тип проекта на ActiveX EXE с модальным окном (не помню, как это сообщение звучит в оригинале). А я просто пытался в методе IGUI::Run() отобразить некую форму (SomeForm.Show()).


C>Что я делаю неправильно?


Дело в том что я тоже не силен в VB.

C>Ну я приблизительно так себе и представлял. Я только не пойму: в каком месте сгенерированного ATL-wizard'ом кода создавать (и удалять) экземпляр CServer? Полагаю, что где-то в _tWinMain(), если EXE-шник запушен без ключей командной строки. Или я ошибаюсь?


Видимо так. На ATL я серьезного ничего не писал, так книжки читал и баловался немного. В проекте на MFC я бы это делал в InitInstance.
\/\/i||i
Re[13]: EXE-сервер с GUI
От: chum Россия  
Дата: 23.01.02 12:52
Оценка:
Здравствуйте Willi, Вы писали:

C>>Ну я приблизительно так себе и представлял. Я только не пойму: в каком месте сгенерированного ATL-wizard'ом кода создавать (и удалять) экземпляр CServer? Полагаю, что где-то в _tWinMain(), если EXE-шник запушен без ключей командной строки. Или я ошибаюсь?


W>Видимо так. На ATL я серьезного ничего не писал, так книжки читал и баловался немного. В проекте на MFC я бы это делал в InitInstance.


Кроме того, если использовать что-то типа предложенных CServer и CServerWrapper и создавать в _tWinMain() экземпляр CServer, то непонятно: а кто будет создавать экземпляр CServerWrapper, чтобы предоставить серверу (подключаемому компоненту) свои интерфейсы? Тогда нужно создавать экземпляр не CServer, а CServerWrapper. Но как тогда сделать, чтобы ATL'евский контейнер компонентов учел этот созданный напрямую компонент? Я имею ввиду счетчик компонентов: его "ручками" увеличивать и уменьшать или это можно автоматизировать?

Ну например: я запустил сервер как обычное приложение, а потом к нему кто-то подключился. Я приложение закрыл, но остался еще подключенный клиент.
Как сделать, чтобы это все работало корректно?
Если есть возможность отдать человеку все, не прося ничего взамен — отдай. Если тебе один раз из десяти долг отдадут — будешь богатым.
Re[14]: EXE-сервер с GUI
От: Willi  
Дата: 23.01.02 13:58
Оценка: 15 (1)
Здравствуйте chum, Вы писали:

C>Здравствуйте Willi, Вы писали:


C>Кроме того, если использовать что-то типа предложенных CServer и CServerWrapper и создавать в _tWinMain() экземпляр CServer, то непонятно: а кто будет создавать экземпляр CServerWrapper,


ClassFactory


C>Тогда нужно создавать экземпляр не CServer, а CServerWrapper.


Нет! CServer — один! CServerWrapper-ов — много.
Более того, помнится в ATL был макрос DECLARE_CLASS_FACTORY_SINGLETON или что-то в этом роде, так вот вместо механизма предложенного мной, можно воспользоваться этим макросом. Но что-то мне подсказывает что это будет некоторым нарушением правил игры.

C>Но как тогда сделать, чтобы ATL'евский контейнер компонентов учел этот созданный напрямую компонент? Я имею ввиду счетчик компонентов: его "ручками" увеличивать и уменьшать или это можно автоматизировать?


Не понимаю о чем ты.

C>Ну например: я запустил сервер как обычное приложение, а потом к нему кто-то подключился. Я приложение закрыл, но остался еще подключенный клиент.

C>Как сделать, чтобы это все работало корректно?

О-о-о-о-й.
Наверняка в ATL есть механизмы которые не позволяют приложеию закрываться пока есть присоединенные клиенты. В крайнем случае ты и сам можешь иметь глобальный счетчик объектов и запрещать закрывать приложение пока он не станет равным нулю.

Прям как в том анекдоте: "Ты, Маугли, кого хочешь достанешь"
Не обижайся. Но у тебя действительно каша в голове. Надо бы почитать что-нить (ну например ATL Internals), примерчики посмотреть.
\/\/i||i
Re[15]: EXE-сервер с GUI
От: chum Россия  
Дата: 23.01.02 14:40
Оценка:
Здравствуйте Willi, Вы писали:

W>Прям как в том анекдоте: "Ты, Маугли, кого хочешь достанешь"


Ну, ответы на вопросы форума — дело сугубо добровольное.

W>Не обижайся. Но у тебя действительно каша в голове. Надо бы почитать что-нить (ну например ATL Internals), примерчики посмотреть.


А ответы в стиле "почитай чего-нибудь" еще и малоинформативны. Если человек задает вопрос в форуме, то это, скорее всего, означает, что он не нашел ни в одной книжке ответа на свои вопросы.

Вы, например, пишете:

C>Кроме того, если использовать что-то типа предложенных CServer и CServerWrapper и создавать в _tWinMain() экземпляр CServer, то непонятно: а кто будет создавать экземпляр CServerWrapper,


W>ClassFactory


А кто ж ClassFactory-то создаст, если сервер запущен не через COM? Или Вы предлагаете в теле сервера создавать с помощью ClassFactory компоненты, которые он сам же и реализует? Сомневаюсь. Подозреваю, что имелось ввиду что-то другое.

Точно также сомневаюсь, что ответ на этот вопрос можно найти в ATL Internals.
Если есть возможность отдать человеку все, не прося ничего взамен — отдай. Если тебе один раз из десяти долг отдадут — будешь богатым.
Re[16]: EXE-сервер с GUI
От: Willi  
Дата: 23.01.02 14:52
Оценка:
Здравствуйте chum, Вы писали:

C>Ну, ответы на вопросы форума — дело сугубо добровольное.


Ну я же просил, не обижайся.

C>А ответы в стиле "почитай чего-нибудь" еще и малоинформативны. Если человек задает вопрос в форуме, то это, скорее всего, означает, что он не нашел ни в одной книжке ответа на свои вопросы.


C>Вы, например, пишете:


C>>Кроме того, если использовать что-то типа предложенных CServer и CServerWrapper и создавать в _tWinMain() экземпляр CServer, то непонятно: а кто будет создавать экземпляр CServerWrapper,


W>>ClassFactory


C>А кто ж ClassFactory-то создаст, если сервер запущен не через COM? Или Вы предлагаете в теле сервера создавать с помощью ClassFactory компоненты, которые он сам же и реализует? Сомневаюсь. Подозреваю, что имелось ввиду что-то другое.


Вот я и говорю, почитай. Из твоих вопросов становится ясно, что ты весьма смутно представляешь как работает COM. А объяснить все это в рамках форума дело крайне сложное.

За сим прощаюсь. Не поминайте лихом
\/\/i||i
Re[17]: EXE-сервер с GUI
От: chum Россия  
Дата: 23.01.02 15:03
Оценка:
Здравствуйте Willi, Вы писали:

W>За сим прощаюсь. Не поминайте лихом


Спасибо за помощь! До свиданья!
Может еще кто поговорить захочет
Если есть возможность отдать человеку все, не прося ничего взамен — отдай. Если тебе один раз из десяти долг отдадут — будешь богатым.
Re[12]: EXE-сервер с GUI
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.01.02 20:55
Оценка:
Здравствуйте chum, Вы писали:

C>Здравствуйте Willi, Вы писали:


C>Ура! Кажется что-то начинает проясняться! Спасибо за терпение. Видимо мне надо было сразу начинать с [9] собощения


Да, вроде, пока ничего путного.

C>Ну, дело в том, что я не силен в VB. Я просто для проверки своей идеи попробовал написать ActiveX DLL на VB с интерфейсом IGUI. И подсунул ему (этому ActiveX'у) указатель на интерфейс клиента. Из VB ActiveX отлаживается и запускается замечательно. А при попытке использования ее из клиента, VB ругнулся, что из этого хост-приложения не может быть создано немодальное окно, смените тип проекта на ActiveX EXE с модальным окном (не помню, как это сообщение звучит в оригинале). А я просто пытался в методе IGUI::Run() отобразить некую форму (SomeForm.Show()).


Для запуска немодальных форм, VB6 должен иметь доступ к очереди приложения. Скорее всего он сможет это сделать если exe-шник из которого загружать длл будет тоже написан на VB6.

Кстати, модальность форм, при правильном проектировании не должна мешать.

C>Что я делаю неправильно?


Честно?

Ты неправильно проектируешь приложение. (Дизайн).

Сервер конечно может иметь обратную связь с клиентом, но такие связи должны быть минимальны и продуманы.

Тебе не даром сказали не мешай GUI и сервер.

Сформулируй какя функциональность должна наращиваться, что должен делать сервер, и что клиент. Причем не смешивая понятий (обратные связи отбрось для простоты).


PS

Про WinAmp. Этот пример подходит здесь как нельзя кстати.

WinAmp не только имеет сменяемые Шкуры, но и имеет интерфейс т.н. плагинов — модулей подключающихся к WinAmp-у и добавляющих к ниму функциональности.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: EXE-сервер с GUI
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.01.02 21:01
Оценка:
Здравствуйте Willi, Вы писали:

W>Видимо так. На ATL я серьезного ничего не писал, так книжки читал и баловался немного. В проекте на MFC я бы это делал в InitInstance.


Может тогда для начала изучить технологию которая выбрана как базавая?

Как можно говорить о дизайне, если общее понимание принципов, концепций и технологий, мягко скажем, не на уровне?


Никакого CServer в ATL нет. Экземпляры классов создаются в фабрике классов, но обо всем этом нужно читать в книгах и статьях, а не в форумах.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.