【发布时间】:2018-12-24 01:23:16
【问题描述】:
我一直在关注this 线程,了解如何将 wndproc 函数用作成员函数,但我不断收到读取访问冲突(虽然它不会告诉我程序中的确切行,但它在第 120 行xmemory0 const uintptr_t _Ptr_container = _Ptr_user[-1]; 上面写着 Unhandled exception thrown: read access violation. _Ptr_user was 0x7. 我可能正在做一些我不应该做的时髦的事情。有没有人看到任何明显的东西?
代码:
LRESULT CALLBACK wndproc::WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
wndproc* pThis; //wndproc is the class name
bool checked = true;
HWND text, button, selection1, selection2;
//hwnd is parent window
switch (msg) {
case WM_CREATE: {
pThis = static_cast<wndproc*>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);
SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<::LONG_PTR>(pThis));
text = CreateWindow("STATIC", "Please select options from below:", WS_VISIBLE | WS_CHILD, 20, 20, 300, 25, hwnd, NULL, NULL, NULL);
button = CreateWindow("BUTTON", "Submit", WS_VISIBLE | WS_CHILD | WS_BORDER, 500, 500, 80, 25, hwnd, (HMENU)0, NULL, NULL);
selection1 = CreateWindow("button", "Scan?", WS_VISIBLE | WS_CHILD | BS_CHECKBOX | WS_OVERLAPPED, 500, 460, 350, 20, hwnd, (HMENU)1001, NULL, NULL);
CheckDlgButton(hwnd, 1001, BST_CHECKED);
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
vector<string> *strings = reinterpret_cast<vector<string>*>(lpcs->lpCreateParams);
int j = 40;
pThis->checkVectorSize = strings->size();
for (int i = 1; i != strings->size() + 1; i++)
{
CreateWindowA("button", (*strings)[i - 1].c_str(),
WS_VISIBLE | WS_CHILD | BS_CHECKBOX | WS_OVERLAPPED,
20, j, 185, 35, hwnd, (HMENU)i,
NULL, NULL);
CheckDlgButton(hwnd, 0, BST_UNCHECKED);
j = j + 30;
}
//SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<::LONG_PTR>(strings));
break;
}
case WM_COMMAND: {
pThis = reinterpret_cast<wndproc*>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
int i = wParam;
if (i == 0) //LOWORD(wParam)
{
for (int j = 0; j != pThis->checkVectorSize; j++)
{
if (IsDlgButtonChecked(hwnd, j + 1) == true)
{
pThis->check.push_back(j);
}
}
if (IsDlgButtonChecked(hwnd, 1001) == true)
{
pThis->scan = true;
}
else
{
pThis->scan = false;
}
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
checked = IsDlgButtonChecked(hwnd, i);
if (checked) {
CheckDlgButton(hwnd, i, BST_UNCHECKED);
}
else {
CheckDlgButton(hwnd, i, BST_CHECKED);
}
break;
}
case WM_DESTROY: {
PostQuitMessage(0);
break;
}
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
编辑:包装函数:
void wndproc::select(vector<string>& return)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSW wc = { 0 };
MSG msg;
wc.lpszClassName = L"Selection1";
wc.hInstance = hInstance;
wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 255));
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.style = CS_DBLCLKS;
RegisterClassW(&wc);
CreateWindowW(wc.lpszClassName, L"Selection",
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, &return);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
【问题讨论】:
-
lpcs->lpCreateParams指向什么?到pThis,正如您在WM_CREATE或vector<string> *strings中使用的那样? -
请显示 WndProc 的声明(在头文件/类声明中给出)。它是
static函数吗?请提供minimal reproducible example。 -
@WernerHenze 是一个静态函数:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -
@RbMm 两者都有?我不太确定,我认为这可能是我使用了两次的问题
-
请注意 raymond chen 和 i - 首先使用
lpcs->lpCreateParams作为指向wndproc* pThis;的指针,然后将相同的指针解释为vector<string> *strings。最少一个演员是如何错误的
标签: c++ visual-studio winapi member wndproc