HINSTANCE& HWND在传递函数时损坏

时间:2016-04-16 23:24:47

标签: c++ winapi

我在运行时发生了一个有趣的错误,我的HINSTANCEHWND变量已损坏。我已经发布了下面的调试输出和发生运行时错误的代码行。 *注意:即使屏幕捕获类型显示HWND没有损坏,它也不再指向右侧/有效窗口

为什么会出现此问题以及如何解决?

  

WindowTiler.exe!WindowLayoutComponent :: init(const IEventArgs& evtArgs)第26行C ++
    [外部代码]
    WindowTiler.exe!EventDelegate :: operator()(const IEventArgs& evtArgs)第21行C ++
    WindowTiler.exe!IApp :: eventHandler(const int& evtId,const IEventArgs& evtArgs)第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)第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;
}

enter image description here

修改:涉及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);
    ...

1 个答案:

答案 0 :(得分:0)

经过大量调试后,我发现了问题并解决了问题。我很惊讶编译器没有发现这个错误。出了什么问题,实际上非常有趣。问题出在这里......

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