Blog/Parallels/Solution

From kJams Wiki
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;
}