You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向LPARAM传递的对象属性赋值时触发读取访问违例

问题分析与解决方案

核心原因

你遇到的访问违例,本质是在IDOK分支中使用了无效的pState指针:DialogBoxParam传入的LPARAM仅在WM_INITDIALOG消息的lParam中有效,后续消息(如WM_COMMAND对应IDOK)的lParam是该消息的专属参数,并非初始传入的StateInfo指针。直接在IDOK分支中错误获取指针,自然会触发内存访问错误。

解决方案:将指针绑定到对话框窗口

无需全局变量,只需在WM_INITDIALOG时把pState指针存入对话框的窗口关联数据,IDOK分支再取出使用即可,有两种常用方式:


方式1:使用对话框专用额外数据(DWLP_USER)

操作简单,适合单数据存储场景:

BOOL CALLBACK NumberInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_INITDIALOG:
        {
            // 保存StateInfo指针到对话框窗口数据
            StateInfo* pState = reinterpret_cast<StateInfo*>(lParam);
            SetWindowLongPtr(hwndDlg, DWLP_USER, reinterpret_cast<LONG_PTR>(pState));
            
            // 初始化控件值
            SetDlgItemText(hwndDlg, IDC_EDIT_NUMBER, pState->N);
            return TRUE;
        }
        case WM_COMMAND:
        {
            if (LOWORD(wParam) == IDOK)
            {
                // 取出保存的指针
                StateInfo* pState = reinterpret_cast<StateInfo*>(GetWindowLongPtr(hwndDlg, DWLP_USER));
                if (!pState) break;

                // 读取对话框输入并更新状态
                wchar_t inputBuf[256] = {0};
                GetDlgItemText(hwndDlg, IDC_EDIT_NUMBER, inputBuf, _countof(inputBuf));
                pState->N = inputBuf; // 若N是CString直接赋值即可

                EndDialog(hwndDlg, IDOK);
                return TRUE;
            }
            else if (LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hwndDlg, IDCANCEL);
                return TRUE;
            }
            break;
        }
    }
    return FALSE;
}

方式2:使用窗口属性(SetProp/GetProp)

适合需要存储多个关联数据的场景,记得在对话框销毁时清理:

BOOL CALLBACK NumberInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_INITDIALOG:
        {
            StateInfo* pState = reinterpret_cast<StateInfo*>(lParam);
            // 用自定义属性名绑定指针
            SetProp(hwndDlg, L"AppStateInfo", reinterpret_cast<HANDLE>(pState));
            
            SetDlgItemText(hwndDlg, IDC_EDIT_NUMBER, pState->N);
            return TRUE;
        }
        case WM_COMMAND:
        {
            if (LOWORD(wParam) == IDOK)
            {
                StateInfo* pState = reinterpret_cast<StateInfo*>(GetProp(hwndDlg, L"AppStateInfo"));
                if (!pState) break;

                wchar_t inputBuf[256] = {0};
                GetDlgItemText(hwndDlg, IDC_EDIT_NUMBER, inputBuf, _countof(inputBuf));
                pState->N = inputBuf;

                EndDialog(hwndDlg, IDOK);
                return TRUE;
            }
            else if (LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hwndDlg, IDCANCEL);
                return TRUE;
            }
            break;
        }
        case WM_DESTROY:
        {
            // 清理绑定的属性,避免内存泄漏
            RemoveProp(hwndDlg, L"AppStateInfo");
            break;
        }
    }
    return FALSE;
}

额外注意事项

  • 确保pState指向的StateInfo对象在对话框生命周期内始终有效(比如是堆分配的对象,或父窗口的成员变量),若对象提前销毁,即使存了指针也会触发访问违例。
  • 使用reinterpret_cast进行指针类型转换时,确保类型匹配,避免强制转换错误。

内容的提问来源于stack exchange,提问作者Lovro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:29:55