Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Создание плагина в виде DLL на основе кода от EXE


Автор: Dem_max 12.1.2010, 14:54
ИМЕЕМ:
1. Имеется код для EXE.
2. При запуске EXE запускается окно приложения с параметром SW_HIDE и сразу сворачивается в трей.
3. Имеются 2 проекта (DLL и EXE) которые используют один и тот же код EXE (совместное использование одних и тех же файлов).Это нужно чтобы ошибки и исправления сразу изменялись в 2 проетах, без всяких там копирований файлов и вставок кода Ctrl+V.
4. Приложение использует системный трей.
5. в EXE обязательно присутствует манифест XP, который делает интерфейс программы правильным.

НУЖНО:
Нужно создать плагин в виде DLL на основе кода от EXE.
Функция DLL по инициализации плагина должна запускать код от EXE в основном процессе DLL, а не отдельный файл EXE !!!
И при выгрузке DLL код от EXE должен тоже выгружаться. Пока работает основная программа загрузившая плагин - DLL, код от EXE работает и отображает свое состояние в трее, как только основная программа вызвавшая плагин закрывается все выгружается.

собственно попробовал таким способом все реализовать код DLL (код привел упрощенный):

Код
 #define DLL_PLUG


#ifdef DLL_PLUG
HANDLE hThreadShow;

DWORD WINAPI ShowThread(LPVOID lpParameter);

HINSTANCE hDLL;

extern "C" __declspec(dllexport) int __stdcall LoadPlug(void);
extern "C" __declspec(dllexport) int __stdcall ShowSettings(void);
extern "C" __declspec(dllexport) int __stdcall ClosePlug(void);

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
    switch (fwdreason)
    {
      case DLL_PROCESS_ATTACH: hDLL = hinstDLL;
            break;
      case DLL_PROCESS_DETACH :
            break;
    }
    return 1;
}

int __stdcall LoadPlug(void)
{
   hThreadShow = CreateThread(NULL, 0, ShowThread, NULL, 0, NULL);
   return 0;
}

int __stdcall ShowSettings(void)
{
   ShowWindow(hWndMain, SW_SHOW);
   SetForegroundWindow(hWndMain);
   return 0;
}

int __stdcall ClosePlug(void)
{
   CloseAllResource(); // в этой функции Destroy главного окна приложения.
   return 0;
}

DWORD WINAPI ShowThread(LPVOID lpParameter)
{
   WinMain(hDLL, NULL, NULL, NULL);
   return 0;
}

#endif


int WINAPI WinMain(HINSTANCE HInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   CreateInterface(HInstance);

   MSG  msg;
   while(GetMessage(&msg, NULL, 0, 0))
   {
      if(!IsDialogMessage(hWndMain, &msg))
      {
         TranslateMessage(&msg);
         DispatchMessage (&msg);
      }
   }

   return 0;
}


в общем то так то работает но есть одно НО !!!

поскольку это DLL то манифест XP в процессе не участвует и вместо нужного интерфейса:
user posted image
получается так:
user posted image
Если основная программа имеет этот самый манифест XP то проблем таких нету.
Но в качестве этой основной программы могут быть разные приложения в том числе и без манифеста XP.
Тогда получается как на 2 рисунке.
Есть пути решения данной проблемы ?

Или есть другие пути создания DLL ? из готового кода EXE с помощью модификаций исходного кода директивами
#ifdef DLL_PLUG
#endif
наподобии такого


Код
      case IDB_CLOSE:
      {
         #ifdef DLL_PLUG
         ShowWindow(hwnd, SW_HIDE);
         #else
         CloseAllResource();
         #endif
      }

Автор: GremlinProg 13.1.2010, 03:40
Цитата(Dem_max @  12.1.2010,  16:54 Найти цитируемый пост)
Если основная программа имеет этот самый манифест XP то проблем таких нету.Но в качестве этой основной программы могут быть разные приложения в том числе и без манифеста XP.Тогда получается как на 2 рисунке.Есть пути решения данной проблемы

не надо так заморачиваться, DLL на то и нужна, чтобы "дополнять", а не "заменять"
если кому-то потребуется подгрузить GUI без манифеста, пусть грузит,

ты же не хочешь, чтобы от твоего GUI кто-либо отказался по причине того,
что он на фоне остальных компонентов выделяется "белой вороной"

Автор: Dem_max 13.1.2010, 05:37
Ну хорошо, раз "дополнять", как мне тогда отследить что при вызове моего плагина вызвавшая программа имеет манифест, чтобы изменить поведение интерфейса ? какой нить вариант без учета поиска этого манифеста в ресурсах EXE.

Автор: GremlinProg 13.1.2010, 05:52
искать в ресурсах - не совсем корректно, т.к. манифест может лежать рядом,
можно пробовать Theme API, например: IsThemeActive или OpenThemeData

проверяй сам (XP под рукой не имею)

Автор: Dem_max 13.1.2010, 07:55
GremlinProg, 
Не эти функции не канают, что есть манифест EXE что нету, все равно функции выдают положительный результат активности и включенности темы. 
В голове возник один подлый вариант, к программе вызывающей DLL подкладывать манифест отдельным файлом.   smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)