Hello
I have been trying to create a DLL in C++ using Visual Studio 2012. The aim is to convert the BasicPlayback sample which uses the Microsoft Media Foundation to play a video file into a DLL that does the same thing.
The sample can be found in MFSamples.zip at :
http://archive.msdn.microsoft.com/mediafoundation
The BasicPlay sample compiles and runs showing a window with a File Menu. However, when I convert it to a dll and call the relevant function (see later), the window displays without a menu. I use GetLastError after the CreateWindow function and I get "Invalid Menu Handle". The thing is I am not sure what is going wrong.
To create the DLL, I create a empty Win32 DLL project. I copy over the .H, .CPP, .RC files from BasicPlayback folder and add them to the Header Files, Resource Files and Source files in Solution explorer. I then copy the Additional Dependencies using the VS Menu(Project, Properties, Linker, Input) and overwrite the Additional Dependencies of the DLL project.
I change the WinMain function from this:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));
if (!InitInstance(hInstance, nCmdShow))
{
NotifyError(NULL, L"Could not initialize the application.",
HRESULT_FROM_WIN32(GetLastError()));
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (g_pPlayer)
{
g_pPlayer->Shutdown();
g_pPlayer->Release();
}
return 0;
}
To to this (e.g. I change the function name) :
<pre lang="cs">extern "C"
{
__declspec(dllexport) int PlayMovie(HINSTANCE hInstance)
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));
if (!InitInstance(hInstance, 0))
{
NotifyError(NULL, L"Could not initialize the application.",
HRESULT_FROM_WIN32(GetLastError()));
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (g_pPlayer)
{
g_pPlayer->Shutdown();
g_pPlayer->Release();
}
return 0;
}
}
I then call the PlayMovie function from within a c# program by including the following:
[DllImport(@"BasicDll.dll", EntryPoint="PlayMovie", ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]
public static extern int PlayMovie(IntPtr hInstance);
I then call the PlayMovie function as follows:
IntPtr windowHandle = new WindowInteropHelper(this).Handle;
PlayMovie(windowHandle);
The dll project compiles without error or warning. When I call the PlayMovie function from c#, the window opens as expected. However the Menu is missing.
Investigating with GetLastError finds the problem to be here (Maybe??? but I'm not sure) :
BOOL InitInstance(HINSTANCE hInst, int nCmdShow)
{
HWND hwnd;
WNDCLASSEX wcex;
g_hInstance = hInst;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInst;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MFPLAYBACK);
wcex.lpszClassName = szWindowClass;
if (RegisterClassEx(&wcex) == 0)
{
return FALSE;
}
hwnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
if (hwnd == 0)
{
return FALSE;
}
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
return TRUE;
}
Using GetLastError after CreateWindow Gives 1401 Invalid Menu Handle.
Now, since the project work as an exe and given the steps I used to create the dll, I am at a loss to know what has gone wrong. However, I am not experienced with DLLs and Windows programming so it could easily be something silly. I was hoping someone could through me a few clues as to what I've done wrong....I have strggle to find the solution on Google...
Many thanks....