WindowsHookEnumerationTrigger::WindowsHookEnumerationTrigger( bool doCreateInvisibleWindow ) : mCreateInvisibleWindow( doCreateInvisibleWindow ), mInvisibleWindow(NULL), mEnumerationNeeded(false) { if ( mCreateInvisibleWindow ) { bool ret = createInvisibleWindow(); assert( ret ); } // We initialize mEnumerationNeeded to true so a first enumeration is triggered immediately // (i.e. the first time enumerationNeeded() is called), rather than having to wait // for a first system-wide WM_DEVICECHANGE message mEnumerationNeeded = true; if ( mTriggerInstances.empty() ) { DWORD threadID = GetCurrentThreadId(); HINSTANCE hInstance = GetModuleHandle(NULL) ; mHookHandle = SetWindowsHookEx( WH_CALLWNDPROC, wndProcHook, hInstance, threadID ); assert( mHookHandle ); } mTriggerInstances.push_back(this); }
unsigned int __stdcall Twinamp2dsp::threadProc(void *self0) { Twinamp2dsp *self = (Twinamp2dsp*)self0; static const char_t *FFDSHOW_WINAMP_CLASS = _l("ffdshow_winamp_class"); randomize(); setThreadName(DWORD(-1), "winamp2"); HINSTANCE hi = self->mod->hDllInstance; char_t windowName[80]; tsnprintf_s(windowName, countof(windowName), _TRUNCATE, _l("%s_window%i"), FFDSHOW_WINAMP_CLASS, rand()); HWND h = createInvisibleWindow(hi, FFDSHOW_WINAMP_CLASS, windowName, wndProc, self, NULL); self->mod->hwndParent = h; if (self->mod->Init(self->mod) == 0) { { boost::unique_lock<boost::mutex> lock(self->mut); self->h = h; } self->cond.notify_one(); if (self->h) { SetWindowLongPtr(self->h, GWLP_USERDATA, LONG_PTR(self)); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } else { self->h = (HWND) - 1; DestroyWindow(h); } if (self->mod->Quit) { self->mod->Quit(self->mod); } UnregisterClass(FFDSHOW_WINAMP_CLASS, hi); _endthreadex(0); return 0; }