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

SetWindowLongPtr调用失败但GetLastError与errno均为0的问题排查

解决SetWindowLongPtr返回0但无错误码的调试问题

核心错误:错误的调用成功判断逻辑

你当前判断SetWindowLongPtr失败的方式完全错误。该函数的返回值是之前存储在GWLP_USERDATA中的值,如果之前没有设置过,返回0是正常情况,不代表调用失败。正确的判断逻辑应该是:调用函数后,若GetLastError()返回非0值,才说明调用失败。你代码里把返回值当作BOOL处理是完全错误的,因为返回值是LONG_PTR类型,不是布尔值。

64位平台的指针截断问题

你用PtrToUlong(pSimpleText_)转换指针,在64位系统下会导致指针被截断(Ulong是32位类型),这会导致后续GetWindowLongPtr拿到无效的指针值,进而引发访问违规。正确的做法是直接将指针转换为LONG_PTR类型,因为SetWindowLongPtr的第三个参数就是LONG_PTR:

LONG_PTR prevValue = ::SetWindowLongPtr(
    hwnd,
    GWLP_USERDATA,
    reinterpret_cast<LONG_PTR>(pSimpleText_)
);
// 判断失败的正确方式
if (prevValue == 0 && GetLastError() != 0) {
    // 真正的失败处理逻辑
}

关于WM_CREATE未触发的问题

WM_NCCREATE返回1(TRUE)后,系统会正常发送WM_CREATE消息,你没捕获到可能是调试断点设置有误,或者窗口创建流程中其他环节出了问题,但这不是当前崩溃的核心原因。

UIPI权限问题可以排除

你提到的UIPI权限限制是针对跨进程操作的,同一个进程内的窗口和线程不存在权限高低的问题,所以这个因素和你的问题无关。

修复后的WndProc关键部分示例

LRESULT CALLBACK SimpleText::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if (message == WM_NCCREATE)
    {
        LPCREATESTRUCT pcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
        SimpleText* pSimpleText_ = reinterpret_cast<SimpleText*>(pcs->lpCreateParams);

        SetLastError(0);
        LONG_PTR prevValue = ::SetWindowLongPtr(
            hwnd,
            GWLP_USERDATA,
            reinterpret_cast<LONG_PTR>(pSimpleText_)
        );

        // 正确的失败判断:只有当返回0且GetLastError非0时才是失败
        if (prevValue == 0 && GetLastError() != 0) {
            DWORD dwError = GetLastError();
            // 这里处理真正的错误
        }
        return TRUE; // 返回TRUE让系统继续发送WM_CREATE等消息
    }

    SimpleText* pSimpleText = reinterpret_cast<SimpleText*>(
        ::GetWindowLongPtr(hwnd, GWLP_USERDATA));

    if (pSimpleText)
    {
        switch (message)
        {
        case WM_SIZE:
        {
            UINT width = LOWORD(lParam);
            UINT height = HIWORD(lParam);
            if(pSimpleText->pRT_ != nullptr)
                pSimpleText->OnResize(width, height);
            break;
        }
        // 其他消息处理...
        }
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

额外建议

  • 始终在64位项目中使用LONG_PTR/WPARAM/LPARAM这类宽度自适应的类型存储指针,避免截断问题。
  • 查阅Windows API文档时,务必注意函数的返回值类型和错误判断方式,不要想当然地把返回值当作布尔值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:37:12