WIN32 IsClipboardFormatAvailable 函数未设置最后一个错误代码

问题描述 投票:0回答:1

在文档中

如果剪贴板格式不可用,则返回值为零。要获取扩展错误信息,请调用 GetLastError。 IsClipboardFormatAvailable 函数 (winuser.h)

但是这段代码的输出是0:

#include <Windows.h>
#include <cstdio>
#include <winerror.h>
int main()
{
    //I copied an image to the clipboard before running the program
    if(!IsClipboardFormatAvailable(CF_UNICODETEXT))
    {

        printf("%lu", GetLastError());
    }
}

为什么IsClipboardFormatAvailable函数没有设置最后一个错误?

c winapi
1个回答
0
投票

内核中的

IsClipboardFormatAvailable
调用
NtUserIsClipboardFormatAvailable

功能如下

WINDOWSTATION * CheckClipboardAccess();
CLIP * FindClipFormat(WINDOWSTATION * pWinSta, UINT format, ULONG);

BOOLEAN NtUserIsClipboardFormatAvailable(_In_ UINT format)
{
    BOOLEAN fOk = FALSE;
    EnterSharedCrit();
    if (WINDOWSTATION * pWinSta = CheckClipboardAccess())
    {
        if (pWinSta == <some global data>)
        {
            if (grpdeskLogon != <thread desktop>)
            {
                fOk = (0 != FindClipFormat(pWinSta, format, 1));
            }
        }
    }
    UserSessionSwitchLeaveCrit();
    
    return fOk;
}

CheckClipboardAccess
在某些情况下有设置最后一个错误的迹象 - 它调用
NTSTATUS ReferenceWindowStation(..)
并且如果api失败 - 调用

status = ReferenceWindowStation(..)
if (0 > status) UserSetLastError(RtlNtStatusToDosError(status))

但如果线程桌面也等于

grpdeskLogon
(这是Winlogon桌面)可见,现在设置了任何错误。如果查找
FindClipFormat
也可见,如果未找到格式,该函数不会设置任何错误。

因此,如果我们在返回时得到 0 (FALSE) - 我们无法知道真正的原因 - 或者因为在剪贴板中找不到请求的格式,或者因为我们在 winlogon 桌面上,或者错误的窗口站,或者其他原因。

以及 Windows 的工作原理。

如果我们请求某个对象(或检查它是否存在)但它不存在 - 这是设计错误。当然可以做另一种设计。但窗户是按设计设计的。如果没有返回请求的对象(或检查) - 这是错误,错误代码必须解释原因 - 访问被拒绝,或未找到对象,或共享冲突,或其他原因。这是任何 Windows 对象的通用规则 - 文件、注册表项、命名事件等。

如果我们尝试打开对象(或检查)但不能 - 这是错误,它必须是直接或间接(通过最后一个错误)返回。 windows 对于这种情况有特殊的状态。例如

STATUS_OBJECT_NAME_NOT_FOUND
STATUS_OBJECT_PATH_NOT_FOUND
STATUS_NOT_FOUND
STATUS_OBJECTID_NOT_FOUND
... 

所以在当前情况下我们只是有一些小的 Windows 错误

© www.soinside.com 2019 - 2024. All rights reserved.