繁体   English   中英

HINSTANCE&HWND在传递函数时损坏

[英]HINSTANCE & HWND Corrupted when passed around functions

我的HINSTANCEHWND变量损坏时,在运行时发生了一个有趣的错误。 我在下面发布了调试输出以及发生运行时错误的代码行。 *注意:即使屏幕截图显示HWND并未损坏,也不再指向右侧/有效窗口

为什么会出现此问题,我该如何解决?

WindowTiler.exe!WindowLayoutComponent :: init(const IEventArgs&evtArgs)第26行C ++
[外部代码]
WindowTiler.exe!EventDelegate :: operator()(const IEventArgs&evtArgs)Line 21 C ++
WindowTiler.exe!IApp :: eventHandler(const int&evtId,const IEventArgs&evtArgs)Line 20 C ++
WindowTiler.exe!Win32App :: wndProc(HWND__ * hwnd,unsigned int message,unsigned int wParam,long lParam)第18行C ++
[外部代码]
[以下框架可能不正确和/或丢失,没有为user32.dll加载符号]
WindowTiler.exe!Win32App :: initInstance(const Win32AppInit&evtArgs)Line 154 C ++
WindowTiler.exe!Win32App :: init(const IEventArgs&evtArgs)Line 100 C ++
WindowTiler.exe!App :: init(const IEventArgs&evtArgs)第45行C ++
WindowTiler.exe!WinMain(HINSTANCE__ * hInstance,HINSTANCE__ * hPrevInstance,char * lpCmdLine,int nCmdShow)第16行C ++
[外部代码]

Status WindowLayoutComponent::init(const IEventArgs& evtArgs)
{
    auto args = (const WinEventArgs&)evtArgs;

    HWND btn = CreateWindowEx(WS_EX_TRANSPARENT, _T("Button"), _T("Test"), WS_VISIBLE | WS_CHILD | WS_EX_TRANSPARENT,
        30, 30, 50, 50, args.hwnd, NULL, args.hinstance, 0); // LINE 26

    return S_SUCCESS;
}

在此处输入图片说明

编辑:有2个IEventArgs对象。 一个传递给App::init(const IEventArgs & evtArgs) ,另一个传递给Win32App::wndProc创建的对象,然后传递给IApp::eventHandler(const int & evtId, const IEventArgs & evtArgs)

LRESULT CALLBACK Win32App::wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    WinEventArgs args { hinstance, hwnd, wParam, lParam };
    eventHandler(message, args);
    ...

经过广泛的调试,我发现了问题并解决了。 我很惊讶编译器没有捕获到此错误。 出了什么问题实际上很有趣。 问题在这里...

struct IEventArgs
{

};

struct WinEventArgs : public IEventArgs
{
    WinEventArgs() = delete; 
    WinEventArgs(const HINSTANCE& hinstance, const HWND& hwnd, const WPARAM& wParam, const LPARAM& lParam) :
        hinstance(hinstance), hwnd(hwnd), wParam(wParam), lParam(lParam)
    {}

    const HINSTANCE& hinstance;
    const HWND& hwnd;
    const WPARAM& wParam;
    const LPARAM& lParam;
};

class EventDelegate
{
public:
        // the problem is here: the parameter should be 'const IEventArgs&'
    typedef std::function<Status(IEventArgs)> EDelegate;

    EventDelegate(EDelegate delegate, GUID gUidContext);

    Status operator()(const IEventArgs& evtArgs)
    {
        return delegate(evtArgs);
    }

private:
    GUID gUidContext;
    EDelegate delegate;
};

我已经给出了人们可以重现的问题的简单示例。 虽然我已修复它,但到底出了什么问题,是否正在制作一个副本而没有实现一个副本构造函数?

struct IEventArgs {  };

struct WinEventArgs : public IEventArgs
{
    WinEventArgs(const int& a, const int& b) : a(a), b(b) { }
    const int& a;
    const int& b;
};

class Component
{
public:
    void test(const IEventArgs& evtArgs)
    {
        const WinEventArgs& args = static_cast<const WinEventArgs&>(evtArgs);
        printf("a=1 is: %d, b=2 is: %d\n", args.a, args.b);
    }
};

int main()
{
    WinEventArgs args(1,2);
    Component cmp;

    // Note Component::test's parameter is 'const IEventArgs&' and that the std::function parameter is just 'IEventArgs'
    std::function<void(IEventArgs)> func = std::bind(&Component::test, cmp, std::placeholders::_1);
    func(args);

    // When std::function parameter is 'const IEventArgs&' the cast inside Component::test succeeds
    std::function<void(const IEventArgs&)> func2 = std::bind(&Component::test, cmp, std::placeholders::_1);
    func2(args);

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM