Hello
I have been trying to create a DLL in C++ using Visual Studio 2012. The aim is to convert the MFPLayer sample which uses the Microsoft Media Foundation to play a video file into a DLL that does the same thing. The MFPlayer samples is a win32 application and it compiles and runs.
The sample can be found in MFSamples.zip at :
http://archive.msdn.microsoft.com/mediafoundation
Previously I successfully created a Dll version of the BasicPlayback sample which also plays videos. I managed to call the dll functions from a c# application. I use the same procedure for this new dll.
However, MFPlayer sample doesn't work. The dll calls the following function
BOOL MainDialog::ShowDialog(HINSTANCE hinst)
{
INT_PTR ret = DialogBoxParam(
hinst,
MAKEINTRESOURCE(m_nID),
NULL,
DialogProc,
(LPARAM)this
);
if (ret == 0 || ret == -1)
{
MessageBox( NULL, L"Could not create dialog", L"Error", MB_OK | MB_ICONERROR );
return FALSE;
}
return (IDOK == ret);
}
After calling DialogBoxParam the DialogProc is called to handle several messages but the WM_INITDIALOG message is never sent.
Here's some of the other relevant code....
BOOL APIENTRY DllMain (HINSTANCE hInstance, DWORD reason, LPVOID reserved)
{
g_hInstance = hInstance;
return TRUE;
}
extern "C"
{
__declspec(dllexport) int PlayMovie()
{
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr))
{
MessageBox(NULL, L"CoInitialize failed.", NULL, MB_ICONSTOP);
return 0;
}
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_STANDARD_CLASSES | ICC_BAR_CLASSES;
if (!InitCommonControlsEx(&icc))
{
MessageBox(NULL, L"InitCommonControlsEx failed.", NULL, MB_ICONSTOP);
CoUninitialize();
return 0;
}
hr = Slider_Init();
if (FAILED(hr))
{
MessageBox(NULL, L"Slider_Init failed.", NULL, MB_ICONSTOP);
CoUninitialize();
return 0;
}
MainDialog *pDlg = new (std::nothrow) MainDialog();
if (pDlg == NULL)
{
MessageBox(NULL, L"Out of memory.", NULL, MB_ICONSTOP);
}
else
{
pDlg->ShowDialog(g_hInstance);
delete pDlg;
}
CoUninitialize();
return 0;
}
You will notice that I capture the HINSTANCE sent to DllMain and use this for the API calls. Play PlayMovie function is called from C#.
I have to say that I am completely new to windows programming and I might be missing something simple. However, I was hoping someone could give me some clues as to where to look.
In summary, the dll compiles. It is called from a c# application. It runs without error but the WM_INITDIALOG message is never sent to DialogProc. Any ideas..
Here's some additional information...
I put a breakpoint in DialogProc and get the following messages:
48 = WM_SETFONT
85 = WM_NOTIFYFORMAT
297 = WM_QUERYUISTATE
144 = Not Defined
2 = WM_DESTROY
130 = WM_NCDESTROY
INT_PTR CALLBACK MainDialog::DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
MainDialog *pDlg = 0;
LRESULT lresult = 0;
if (msg == WM_INITDIALOG)
{
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)lParam);
pDlg = (MainDialog*)lParam;
if (pDlg)
{
pDlg->m_hDlg = hDlg;
HRESULT hr = pDlg->OnInitDialog();
if (FAILED(hr))
{
pDlg->EndDialog(0);
}
}
return FALSE;
}
pDlg = (MainDialog*)(DWORD_PTR) GetWindowLongPtr(hDlg, DWLP_USER);
if (pDlg != NULL)
{
switch (msg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
pDlg->EndDialog(LOWORD(wParam));
return TRUE;
default:
return pDlg->OnCommand((HWND)lParam, LOWORD(wParam), HIWORD(wParam));
}
break;
case WM_NOTIFY:
lresult = pDlg->OnNotify((NMHDR*)lParam);
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LONG_PTR)lresult);
return TRUE;
default:
return pDlg->OnReceiveMsg(msg, wParam, lParam);
}
}
else
{
return FALSE;
}
}
The DialogBoxParam returns -1 but a call to GetLastError() gives 0 signifying that there has not been an error.
Many thanks....