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;
}