本文介绍了DLL中的对话框窗口缺少WM_INITDIALOG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hello



我一直在尝试使用Visual Studio 2012在C ++中创建DLL。目的是将使用Microsoft Media Foundation的MFPLayer示例转换为将视频文件播放到执行相同操作的DLL中。 MFPlayer示例是一个win32应用程序,它编译并运行。



样本可以在MFSamples.zip中找到:





之前我成功创建了一个同时播放视频的BasicPlayback示例的Dll版本。我设法从c#应用程序调用dll函数。我对这个新的dll使用相同的程序。



但是,MFPlayer样本不起作用。 dll调用以下函数



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)
{
    // Show the dialog. Pass a pointer to ourselves as the LPARAM
    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);
}





调用DialogBoxParam后,调用DialogProc处理多条消息,但永远不会发送WM_INITDIALOG消息。



这里有一些其他相关代码....





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

    // Initialize the COM library.
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    if (FAILED(hr))
    {
        MessageBox(NULL, L"CoInitialize failed.", NULL, MB_ICONSTOP);
        return 0;
    }

    // Initialize the common control library.
    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;
    }

    // Initialize our custom slider class.
    hr = Slider_Init();
    if (FAILED(hr))
    {
        MessageBox(NULL, L"Slider_Init failed.", NULL, MB_ICONSTOP);
        CoUninitialize();
        return 0;
    }

    // Create and show the dialog.
    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;
}





您会注意到我捕获了发送给DllMain的HINSTANCE并将其用于API调用。播放PlayMovie函数是从C#调用的。



我不得不说我是Windows编程的新手,我可能会遗漏一些简单的东西。但是,我希望有人可以给我一些关于在哪里看的线索。





总之,dll编译。它是从c#应用程序调用的。它运行没有错误,但WM_INITDIALOG消息永远不会发送到DialogProc。任何想法..



这里有一些额外的信息...



我放了一个断点在DialogProc中并获取以下消息:



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;  // Pointer to the dialog class that manages the dialog 

    LRESULT lresult = 0;

    if (msg == WM_INITDIALOG)
    {
        // Get the pointer to the dialog object and store it in 
        // the window's user data

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

    // Get the dialog object from the window's user data
    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);

            // The LRESULT from WM_NOTIFY can be meaningful. Store the result in DWLP_MSGRESULT.
            SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LONG_PTR)lresult);
            return TRUE;

        default:
            return pDlg->OnReceiveMsg(msg, wParam, lParam);
        }
    }
    else
    {
        return FALSE;
    }
}





DialogBoxParam返回-1但是对GetLastError()的调用给出0表示那里不是一个错误。



非常感谢....



The DialogBoxParam returns -1 but a call to GetLastError() gives 0 signifying that there has not been an error.

Many thanks....

推荐答案



<pre lang="cs">extern "C"
{
__declspec(dllexport) int PlayMovie()
{





到此



to this

<pre lang="cs">int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)





我复制其他依赖项。现在应用程序编译并运行没有错误或警告..对话框成功显示.exe。



这表明原始问题必须是转换为DLL。最初,为了创建Dll,我创建了一个空的win32 dll项目。我复制相同的文件并将它们添加到项目中。我添加了DllMain函数并将WinMain函数转换为PlayMovie()(但是,我将函数体保持不变。



我从c#应用程序调用PlayMovie。函数被调用,但WM_INITDIALOG永远不会被发送。



任何想法,我可能会看到... ????



I copy over the additional dependencies. Now the application compiles and runs without error or warning..The dialog is displayed successfully for the .exe.

This suggests that the original problem must be with the conversion to Dll. Originally, to create the Dll I create an empty win32 dll project. I copy the same files over and add them to project. I add the DllMain function and convert the WinMain function to the PlayMovie() (however, I leave the function body the same.

I call PlayMovie from c# application. The function is called but the WM_INITDIALOG is never sent.

Any ideas as to where I might look...????


这篇关于DLL中的对话框窗口缺少WM_INITDIALOG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 14:33