Hello,
I've been trying to add a now playing display to my app, I downloaded the WMSDK and samples and they seem to work fine for MFC apps. I tried porting it to win32 and it keeps crashing on:
AtlAxWinInit();
The class I created works fine in an MFC app, but whenever i try to use it in win32 it just crashes on start. Heres the code I use:
CMediaPlayer.cpp
Code:
#include "stdafx.h"
#include "RemoteHost.h"
#include "CMediaPlayer.h"
// converts a BSTR to a std::string
string bstr2s(const BSTR &cmd)
{
int n = SysStringLen(cmd);
char sTemp[2] = {0};
string sRet = "";
for (int i = 0; i < n; ++i)
{
sTemp[0] = (char)cmd[i];
sRet.append(sTemp);
}
return sRet;
}
CMediaPlayer::CMediaPlayer(void)
{
m_bInitialized = false;
m_pView = NULL;
}
CMediaPlayer::~CMediaPlayer(void)
{
Release();
}
bool CMediaPlayer::Initialize(HWND hWnd)
{
CComPtr<IAxWinHostWindow> spHost;
CComPtr<IObjectWithSite> spHostObject;
CComObject<CRemoteHost> *pRemoteHost = NULL;
HRESULT hr = S_OK;
AtlAxWinInit(); // crashes here, on the .lock() line to be specific
m_pView = new CAxWindow(); // crashes here if above is commented out
hr = m_pView ? S_OK : E_OUTOFMEMORY;
if (FAILED(hr))
{
Release();
return false;
}
m_pView->Create(hWnd, NULL, NULL, 0);
hr = IsWindow(m_pView->m_hWnd) ? S_OK : E_FAIL;
if (FAILED(hr))
{
Release();
return false;
}
hr = m_pView->QueryHost(IID_IObjectWithSite, (void **)&spHostObject);
hr = spHostObject.p ? hr : E_FAIL;
if (FAILED(hr))
{
Release();
return false;
}
hr = CComObject<CRemoteHost>::CreateInstance(&pRemoteHost);
if (pRemoteHost)
pRemoteHost->AddRef();
else
hr = E_POINTER;
if (FAILED(hr))
{
Release();
return false;
}
hr = spHostObject->SetSite((IWMPRemoteMediaServices *)pRemoteHost);
if (FAILED(hr))
{
Release();
return false;
}
hr = m_pView->QueryHost(&spHost);
hr = spHost.p ? hr : E_FAIL;
if (FAILED(hr))
{
Release();
return false;
}
// Create WMP control using its CLSID
hr = spHost->CreateControl(CComBSTR(L"{6BF52A52-394A-11d3-B153-00C04F79FAA6}"), m_pView->m_hWnd, 0);
if (FAILED(hr))
{
Release();
return false;
}
hr = m_pView->QueryControl(&m_pWMPlayer);
hr = m_pWMPlayer.p ? hr : E_FAIL;
if (FAILED(hr))
{
Release();
return false;
}
SafeRelease(pRemoteHost);
m_bInitialized = true;
return true;
}
void CMediaPlayer::Release()
{
if (!m_bInitialized)
return;
m_pWMPlayer = NULL;
SafeDelete(m_pView);
m_bInitialized = false;
}
map<string, string> CMediaPlayer::NowPlaying()
{
map<string, string> mapReturn;
if (!m_bInitialized)
return mapReturn;
CComPtr<IWMPMedia> spMedia;
CComBSTR bstrRet;
HRESULT hr = S_OK;
// get current song playing info
hr = m_pWMPlayer->get_currentMedia(&spMedia);
hr = spMedia.p ? hr : E_FAIL;
if (SUCCEEDED(hr))
{
// get song name
hr = spMedia->get_name(&bstrRet);
hr = bstrRet.m_str ? hr : E_FAIL;
if (SUCCEEDED(hr))
{
mapReturn["Name"] = bstr2s(bstrRet);
bstrRet.Empty();
}
// get all meta tags
long lCount = 0;
hr = spMedia->get_attributeCount(&lCount);
if (SUCCEEDED(hr))
{
CComBSTR bstrName;
for (uint i = 0; i < lCount; ++i)
{
// Use getAttributeName and getItemInfo pair to list metadata
hr = spMedia->getAttributeName(i, &bstrName);
hr = bstrName.m_str ? hr : E_FAIL;
if (SUCCEEDED(hr))
{
hr = spMedia->getItemInfo(bstrName, &bstrRet);
hr = bstrRet.m_str ? hr : E_FAIL;
// add meta tag to map
if (SUCCEEDED(hr))
{
mapReturn[bstr2s(bstrName)] = bstr2s(bstrRet);
bstrName.Empty();
bstrRet.Empty();
}
}
}
}
}
return mapReturn;
}
CMediaPlayer.h
Code:
#ifndef MEDIAPLAYER_H
#define MEDIAPLAYER_H
#if _MSC_VER > 1000
#pragma once
#endif
#include <atlhost.h>
#include <wmp.h>
#include <wmpids.h>
#include "common.h"
class CMediaPlayer
{
public:
CMediaPlayer(void);
~CMediaPlayer(void);
bool Initialize(HWND hWnd);
void Release();
map<string, string> NowPlaying();
private:
bool m_bInitialized;
CAxWindow *m_pView; // IE control to hold WMP OCX
CComPtr<IWMPPlayer4> m_pWMPlayer; // WMPlayer
};
#endif
stdafx.h
Code:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#if !defined(AFX_STDAFX_H__4AF68A18_AE4D_44BE_BC5B_EFC0332CFAE3__INCLUDED_)
#define AFX_STDAFX_H__4AF68A18_AE4D_44BE_BC5B_EFC0332CFAE3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED
#include <atlbase.h>
#include <atlwin.h>
#include <atlcom.h>
#include <commctrl.h>
#include <stdio.h>
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__4AF68A18_AE4D_44BE_BC5B_EFC0332CFAE3__INCLUDED)