在窗口过程包装器中阅读访问违规
Read Access Violation in window procedure wrapper
我正在编写Windows API包装库。但是我正在遇到问题:每当我尝试在"包装"窗口过程中使用this
指针(从静态版本中调用(时,就会丢弃读取访问违规行为。这是库接口
class widget {
protected:
HWND hwnd;
public: // instinfo is class that represents WNDCLASS structure
widget(instinfo ii, const WCHAR *text,
DWORD styles = WS_OVERLAPPEDWINDOW,
point ul = DEFUL,
int cx = CW_USEDEFAULT,
int cy = CW_USEDEFAULT,
HWND parent = NULL,
HMENU hm = NULL);
};
class olwindow : public widget {
// static window proc: It registered by WNDCLASS structure
static LRESULT CALLBACK baseWinProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);
LRESULT CALLBACK winproc(UINT wm, WPARAM wp, LPARAM lp);
protected:
virtual void LButtonDown(int, int) { } // an example event, is override by classes that inherit and wanna customize
public:
friend class instinfo;
olwindow(instinfo ii, const WCHAR *cap, point ul = DEFUL,
int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT);
};
相关功能是baseWinProc
和winproc
,我在下面显示:
LRESULT olwindow::baseWinProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
{
olwindow *w;
if (wm == WM_NCCREATE)
SetWindowLong(hwnd, GWL_USERDATA, (LONG) ((CREATESTRUCT *) lp)->lpCreateParams);
w = (olwindow *) GetWindowLong(hwnd, GWL_USERDATA);
if (w)
w->winproc(wm, wp, lp);
return DefWindowProc(hwnd, wm, wp, lp);
}
LRESULT olwindow::winproc(UINT wm, WPARAM wp, LPARAM lp)
{
switch (wm) {
case WM_LBUTTONDOWN:
// on line below is crash
this->LButtonDown(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return 0;
}
错误消息是
异常抛出:阅读访问违规。
this->是0x12a07e0。
这可能是什么意思?
编辑:这是widget
类的构造函数,由olwindow
widget::widget(instinfo ii, const WCHAR * text, DWORD styles, point ul,
int cx, int cy, HWND parent, HMENU hm)
{
this->hwnd = CreateWindow(ii.getClassName(), text, styles,
ul.x, ul.y, cx, cy, parent, hm, ii.getHinst(), this);
if (this->hwnd == NULL)
MessageBox(NULL, getErrMsg(), L"", 0);
ShowWindow(this->hwnd, SW_SHOW);
}
olwindow::olwindow(instinfo ii, const WCHAR * cap, point ul, int cx, int cy) :
widget(ii, cap, WS_OVERLAPPEDWINDOW, ul, cx, cy)
{ }
问题是由两个因素组合引起的:
- 派生类型的建设顺序。
- 事实,CreateWindow在返回之前将许多消息发送到窗口过程。从文档中:
返回之前,CreateWindow将WM_Create消息发送到窗口过程。对于重叠,弹出和儿童窗口,CreateWindow将WM_Create,WM_GetMinMaxinfo和WM_NCcreate消息发送到窗口。
由于CreateWindow
是在基类(widget
(构造函数中执行的,因此当WM_NCCREATE
消息处理程序运行时,尚未构造派生类'(olwindow
(实例。施放指针通过CREATESTRUCT
到派生类的类型是错误的。
要解决这个问题,您需要将指针归还其原始类型,即widget*
。如果您需要访问窗口过程中的派生对象,则需要将窗口创建移至已完全构造的点。
作为替代方案,您可以继续从基类构造函数调用CreateWindow
,但只有一旦完全构造就可以施放到派生对象,例如通过从派生类构造函数中存储一个布尔值。
相关文章:
- Qt:从另一个窗口访问公共对象
- 在类 12.exe 中0x7B37FF80 (ucrtbased.dll) 引发异常: 0xC0000005:访问冲突读
- Qt5 ui,多个窗口:如何从窗口 1 访问窗口 2 中的 UI 对象
- 错误访问 读入对象后
- 在窗口过程包装器中阅读访问违规
- 读取访问违规当前为0xCDCDCDCD,链接列表窗口
- 将WM_CHANGEUISTATE发送到窗口应用程序后,当用鼠标访问菜单时,助记符不会显示在系统菜单上
- SFML FPS访问窗口事件的问题
- 从QT中的对话框访问主窗口
- C++:重载 [ ] 运算符以进行读写访问
- 如何从窗口功能外部访问wm_command
- 如何从另一个窗口访问窗口的小部件
- 多读访问一个std::map,将导致不安全的行为
- Qt C++从另一个类访问窗口方法
- 检查用户名是否有权访问窗口上的文件夹
- c++ LinkedList读访问冲突错误
- 在Lua中跟踪变量以进行读访问,以启动用户定义的c++方法/函数
- c++ Vector读访问冲突Mylast返回0x8
- 这个读访问违反异常是由什么引起的?
- 如何访问窗口的内部位图