调用SetWindowLongPtr时出现未处理的异常

时间:2018-06-05 22:51:39

标签: c++ winapi

void IronmanMap::CommandLine()
{
     mode = 1;
    InvalidateRect(storedhwnd, NULL, 1);

    HWND hmmitem;
    hmmitem = GetDlgItem(storedhwnd, ID_EDITBOX1);

    backupproc = (WNDPROC)SetWindowLongPtr(hmmitem, GWLP_WNDPROC,     (LONG)EditProc);

    SetFocus(hmmitem);

}

当此函数到达右括号时,它表示存在未处理的异常。

1 个答案:

答案 0 :(得分:2)

这行代码应为:

backupproc = (WNDPROC)SetWindowLongPtr(hmmitem, GWLP_WNDPROC,(LONG_PTR)EditProc);

但雷蒙德是如此! :)

编辑:Jonathon Potter在上面评论说,有更好的方法可以做到这一点(这是微软推荐的方式)。所以请忽略上面的内容并将窗口子类化为:

SetWindowSubclass (hmmitem, EditProc, EditProcSubclassID, EditProcReferenceData);

其中:

  • EditProcSubclassID是您选择的唯一ID(只需填一个)。
  • 无论何时调用,
  • EditProcReferenceData都会传递给EditProc。你可以将它用于任何你喜欢的东西(或者只是传递0)。

然后你像这样实现EditProc(注意那里的两个额外参数):

LRESULT CALLBACK EditProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    ...
}

那么backupproc发生了什么?好吧,你不再需要了。相反,要调用链中的下一个WndProc,请在DefSubclassProc()结束时调用EditProc(或者,如果您想要吞下该消息)。

最后,如果您要从窗口中分离EditProc,请致电RemoveWindowSubclass()

这种方法的主要优点是,如果其他人在您执行之后将窗口子类化(或者实际上,之前,如果他们想要在您执行之前删除其WndProc),则它可以正常工作。这就是你应该使用它的原因。

阅读MSDN上的SetWindowSubclass文档,并在Safer subclassing上查看Raymond的博客。