我在运行时发生了一个有趣的错误,我的HINSTANCE
和HWND
变量已损坏。我已经发布了下面的调试输出和发生运行时错误的代码行。 *注意:即使屏幕捕获类型显示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;
}
修改:涉及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);
...
答案 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;
}