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

Python叠加层调用SetWindowDisplayAffinity无效问题求助

解决方案

1. 修复C++ DLL的实现问题

错误码998(内存访问无效)大概率是DLL函数的调用约定或参数类型不匹配导致的内存读写错误,以下是正确的DLL代码示例:

#include <windows.h>

// 使用__stdcall调用约定,匹配Python ctypes默认调用规则
extern "C" __declspec(dllexport) BOOL __stdcall SetWindowDisplayAffinityWrapper(HWND hWnd, DWORD dwAffinity) {
    return SetWindowDisplayAffinity(hWnd, dwAffinity);
}

extern "C" __declspec(dllexport) BOOL __stdcall GetWindowDisplayAffinityWrapper(HWND hWnd, LPDWORD pdwAffinity) {
    if (pdwAffinity == nullptr) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    return GetWindowDisplayAffinity(hWnd, pdwAffinity);
}

编译注意事项:

  • 选择与Python版本匹配的架构编译(32位Python对应32位DLL,64位对应64位)
  • 确保链接user32.lib(多数编译器会自动处理,若报错需手动添加)

2. Python端的正确调用方式

用ctypes调用DLL,确保HWND传递和参数类型完全匹配:

import tkinter as tk
import ctypes
from ctypes import wintypes

# 加载编译好的DLL,替换为你的DLL路径
display_affinity_dll = ctypes.WinDLL("DisplayAffinity.dll")

# 声明函数参数与返回值类型,避免类型不匹配
display_affinity_dll.SetWindowDisplayAffinityWrapper.argtypes = [wintypes.HWND, wintypes.DWORD]
display_affinity_dll.SetWindowDisplayAffinityWrapper.restype = wintypes.BOOL

display_affinity_dll.GetWindowDisplayAffinityWrapper.argtypes = [wintypes.HWND, ctypes.POINTER(wintypes.DWORD)]
display_affinity_dll.GetWindowDisplayAffinityWrapper.restype = wintypes.BOOL

# 定义Windows API常量
WDA_EXCLUDEFROMCAPTURE = 0x00000011
WDA_MONITOR = 0x00000022
WDA_NONE = 0x00000000

root = tk.Tk()
root.title("防截图窗口")
root.geometry("400x300")

# 获取正确的顶层窗口HWND:winfo_id()直接返回有效句柄,无需额外转换
hwnd = root.winfo_id()

# 设置窗口捕获属性
set_result = display_affinity_dll.SetWindowDisplayAffinityWrapper(hwnd, WDA_EXCLUDEFROMCAPTURE)
print(f"Set调用结果:{'成功' if set_result else f'失败,错误码{ctypes.GetLastError()}'}")

# 验证设置结果
affinity = wintypes.DWORD()
get_result = display_affinity_dll.GetWindowDisplayAffinityWrapper(hwnd, ctypes.byref(affinity))
if get_result:
    print(f"当前窗口捕获属性:{hex(affinity.value)}")
else:
    print(f"Get调用失败,错误码:{ctypes.GetLastError()}")

root.mainloop()

3. 关键排查点

  • 系统版本限制:SetWindowDisplayAffinity仅支持Windows 10 1809(10.0.17763)及以上版本,低版本系统调用会直接失败。
  • HWND正确性:tkinter的root.frame()返回的是内部框架句柄,不是顶层窗口的HWND,必须用winfo_id()获取。
  • DLL架构匹配:DLL和Python必须同为32位或64位,否则会出现参数传递混乱或加载失败。
  • 截图工具测试:OBS需选择“窗口捕获”模式,Discord用默认截图功能,若设置成功,窗口会显示为黑色或无法被捕获。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:57:09