SetWindowsHookEx, CBTProc и g ++ 3.4.5 (mingw) - PullRequest
       9

SetWindowsHookEx, CBTProc и g ++ 3.4.5 (mingw)

0 голосов
/ 28 сентября 2010

Я сейчас работаю над приложением, которому нужно добавить меню в системное меню каждого приложения. Я могу сделать это для существующих окна с функцией EnumWindows. Для новых окон (приложения запускаются после моего) Я пытаюсь сделать это с помощью оконных хуков. Более конкретно с CBTProc. Вот где я застрял. Я разобрался во всем возможном в приложении, но у меня сложилось впечатление, что процедура в моей DLL просто не позвонить вообще.

Вот код для DLL:

#include <string>
using std::string;

#include <fstream>
using std::ofstream;

#include <windows.h>

// ---------------------------------------------------
extern "C"
{
  void log(const string & msg)
  {
    ofstream out("out.log", std::ios_base::app);
    out << msg;
    out.flush();
    out.close();
  }
  // ---------------------------------------------------  
  LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
  {
    log("CBTProc");
    return CallNextHookEx(0, nCode, wParam, lParam);
  }
  // ---------------------------------------------------  
}

Я компилирую это с g ++ 3.4.5 на 32-битной машине с Windows XP SP3:

g++ -shared -otest.dll test_dll.cpp

А вот и код приложения

#include <iostream>
using std::cout;
using std::cin;
using std::cerr;
using std::endl;

#include <string>
using std::string;

#include <windows.h>

typedef void (*func)();

void run()
{
  cout << "press enter to exit" << endl;
  cin.get();
}

void * loadProc(HMODULE mod, const char * procname)
{
  void * retval = (void *)GetProcAddress(mod, procname);
  if (retval == NULL)
    cerr << "GetProcAddress(" << procname << ") failed" << endl;
  return retval;
}

int main(int argc, char ** argv)
{
  HMODULE dll = LoadLibrary("test.dll");
  if (dll == NULL)
    {
      cerr << "LoadLibrary failed" << endl;
      return 1;
    }

  HOOKPROC proc = (HOOKPROC)loadProc(dll, "CBTProc@12");
  if (!proc)
    return 1;

  HHOOK callwnd = SetWindowsHookEx(WH_CBT, proc, dll, 0);
  if (callwnd == NULL)
    {
      cerr << "SetWindowsHookEx failed for CBTProc" << endl;
      return 1;
    }

  run();
  UnhookWindowsHookEx(callwnd);

  return 0;
}

Я компилирую это с той же настройкой:

g++ -otest.exe test.cpp

Когда я запускаю, я не получаю ошибок, но когда я запускаю новые приложения, я ничего не получаю в моем лог-файле.

Есть идеи?

г, LDX

Редактировать: орфографические ошибки

1 Ответ

1 голос
/ 08 октября 2010

Я бы посоветовал вам проверить следующее:

  • убедитесь, что ваша DLL имеет экспорт (может быть проверено с помощью инструмента dumpbin). я не знаю о g ++, но в MSVC это необходимо либо использовать __declspec (dllexport) или явное указание экспорта в файле DEF.

  • убедитесь, что ваше хост-приложение использует правильное имя экспортируемая функция (такая же как "dumpbin / EXPORTS test.dll" дисплеи)

  • имейте в виду, что вы используете относительное имя файла out.log - когда DLL загружается в другие процессы, она записывает данные относительно текущего каталога хост-процесса. В целях тестирования лучше использовать API OutputDebugString и проверять результаты с помощью инструмента DbgView.

Скорее всего, ваше решение уже работает.

PS: обычно не очень хорошая идея использовать STL во внедренной DLL. Убедитесь, что вы осведомлены о рисках.

...