Blog/Parallels/Solution
Jump to navigation
Jump to search
#if OPT_WINOS && defined(kDEBUG) static HWND s_prevChainH = NULL; wchar_t s_invisibleWindClass[] = L"invisible"; namespace yaaf { extern HINSTANCE _GInstance; // instance pointer }; static LRESULT CALLBACK InvisibleWindowProc(HWND w, UINT msg, WPARAM wp, LPARAM lp) { return ::DefWindowProc(w,msg,wp,lp); } static void RegisterInvisibleWindow() { WNDCLASSW wc; wc.style = 0; wc.lpfnWndProc = InvisibleWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = yaaf::_GInstance; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = s_invisibleWindClass; ATOM resultI = RegisterClassW(&wc); CF_ASSERT(resultI); } static HWND CreateInvisibleWindow() { RegisterInvisibleWindow(); HWND wndH = ::CreateWindowExW( WS_EX_DLGMODALFRAME, s_invisibleWindClass, _T("temp"), WS_POPUP, 0, 0, 1, 1, NULL, NULL, yaaf::_GInstance, NULL); if (wndH == NULL) { HRESULT lastErr = GetLastError(); CF_ASSERT(0); } return wndH; } BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { WCharVec classCharVec(256); if (::GetClassName(hWnd, &classCharVec[0], classCharVec.size())) { SStringSet& stringSet(*reinterpret_cast<SStringSet *>(lParam)); SuperString classStr(classCharVec); stringSet.insert(classStr); } return TRUE; } #define kLogClassNames 0 SuperString Get_QTIdle_ClassName() { SuperString className; SStringSet classSet; ::EnumWindows( EnumWindowsProc, reinterpret_cast<LPARAM>(&classSet)); #if kLogClassNames ::OutputDebugString(SuperString("Classes BEGIN ------------").w_str()); #endif BOOST_FOREACH(SuperString& str, classSet) { if (str.StartsWith("QTIdle")) { className = str; break; } #if kLogClassNames str.append('\r'); ::OutputDebugString(str.w_str()); #endif } #if kLogClassNames ::OutputDebugString(SuperString("Classes END --------------").w_str()); #endif return className; } #endif void QuickTime_SavePreviousCliboardChain() { #if OPT_WINOS && defined(kDEBUG) HWND wndH = CreateInvisibleWindow(); if (wndH) { s_prevChainH = ::SetClipboardViewer(wndH); CF_ASSERT(s_prevChainH); CF_ASSERT(ChangeClipboardChain(wndH, s_prevChainH)); ::DestroyWindow(wndH); } #endif } void QuickTime_RestorePreviousCliboardChain() { #if OPT_WINOS && defined(kDEBUG) if (s_prevChainH) { SuperString idleClassStr(Get_QTIdle_ClassName()); if (!idleClassStr.empty()) { HWND qtIdleWindowH = ::FindWindow(idleClassStr.w_str(), NULL); CF_ASSERT(qtIdleWindowH); if (qtIdleWindowH) { CF_ASSERT(ChangeClipboardChain(qtIdleWindowH, s_prevChainH)); } } } #endif } void QuickTime_Unload() { TerminateQTML(); } bool QuickTime_Load(OSErr *errP0) { static bool s_availB = true; #if OPT_WINOS static OSErr s_qtErr = noErr; static bool s_askedB = false; if (!s_askedB) { QuickTime_SavePreviousCliboardChain(); if (QTLoadLibrary("QTCF.dll") == NULL) { s_qtErr = qtmlDllLoadErr; } else { s_qtErr = InitializeQTML(0); } QuickTime_RestorePreviousCliboardChain(); s_askedB = true; if (s_qtErr) { LogErr("$$$ Loading Quicktime Failed", s_qtErr); s_availB = false; } } if (errP0) { *errP0 = s_qtErr; } #endif return s_availB; }