【问题标题】:How to copy string to clipboard in C?如何在C中将字符串复制到剪贴板?
【发布时间】:2010-11-18 20:18:27
【问题描述】:

SetClipboardData 函数需要HANDLE 引用;我在转换我的字符串以在函数中使用时遇到问题。

这是我的代码:

char* output = "Test";
HLOCAL hMem =  LocalAlloc( LHND,1024);
char* cptr = (char*) LocalLock(hMem);
memcpy( cptr, output, 500 );
SetClipboardData(CF_TEXT, hMem);
LocalUnlock( hMem );
LocalFree( hMem );
CloseClipboard();

我在这里做错了什么以及正确的方法是什么?

谢谢。

【问题讨论】:

    标签: c windows winapi clipboard


    【解决方案1】:

    阅读 SetClipboardData 函数的 MSDN 文档。您似乎缺少一些步骤并过早释放内存。首先,你必须打电话 OpenClipboard 才能使用 SetClipboardData。其次,系统拥有传递给剪贴板的内存的所有权,并且必须将其解锁。此外,内存必须是可移动的,这需要与 GlobalAlloc 一起使用的 GMEM_MOVEABLE 标志(而不是 LocalAlloc)。

    const char* output = "Test";
    const size_t len = strlen(output) + 1;
    HGLOBAL hMem =  GlobalAlloc(GMEM_MOVEABLE, len);
    memcpy(GlobalLock(hMem), output, len);
    GlobalUnlock(hMem);
    OpenClipboard(0);
    EmptyClipboard();
    SetClipboardData(CF_TEXT, hMem);
    CloseClipboard();
    

    【讨论】:

    • 对我也有用...有两个更正:GMEM_MOVEABLE 和 OpenClipboard() 中没有传递参数;
    • 为什么还要复制空字节终止符?
    • 因为 SetClipboardData 不接受长度参数,所以当你使用 CF_TEXT 时,它必须找出字符串的结尾在哪里。请参阅msdn.microsoft.com/en-us/library/windows/desktop/… 了解更多信息
    • 如果对 SetClipboardData 的调用成功,系统会为您调用 free(hMem),我理解正确吗?
    • 根据documentation,这个答案是错误的。您必须将有效的HWND 传递给OpenClipboard。 Quote: "如果应用程序调用 OpenClipboard 并将 hwnd 设置为 NULL,EmptyClipboard 会将剪贴板所有者设置为 NULL;这会导致 SetClipboardData 失败"
    【解决方案2】:

    我在 Windows 中编写了一个开源命令行工具来执行此操作:

    http://coffeeghost.net/2008/07/25/ccwdexe-copy-current-working-directory-command/

    ccwd.exe 将当前工作目录复制到剪贴板。当我深入到源代码库并需要复制路径时,它很方便。

    这是完整的源代码:

    #include "stdafx.h"
    #include "windows.h"
    #include "string.h"
    #include <direct.h>
    
    int main()
    {
        LPWSTR cwdBuffer;
    
        // Get the current working directory:
        if( (cwdBuffer = _wgetcwd( NULL, 0 )) == NULL )
            return 1;
    
        DWORD len = wcslen(cwdBuffer);
        HGLOBAL hdst;
        LPWSTR dst;
    
        // Allocate string for cwd
        hdst = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (len + 1) * sizeof(WCHAR));
        dst = (LPWSTR)GlobalLock(hdst);
        memcpy(dst, cwdBuffer, len * sizeof(WCHAR));
        dst[len] = 0;
        GlobalUnlock(hdst);
    
        // Set clipboard data
        if (!OpenClipboard(NULL)) return GetLastError();
        EmptyClipboard();
        if (!SetClipboardData(CF_UNICODETEXT, hdst)) return GetLastError();
        CloseClipboard();
    
        free(cwdBuffer);
        return 0;
    }
    

    【讨论】:

    • +1 是的,它易于阅读、复制并且可以正常工作,正是我想要的。而 CF_UNICODETEXT 是一个没有得到的恐怖。 CF_TEXT 在普通美国 ASCII 中只生成一个字母。 DWORD len 应该是 size_t len(不会收到编译器投诉)。
    【解决方案3】:

    看看Microsoft's Documentation on using the clipboard。这要求您使用 WinAPI,但这应该不是问题,因为您在 Windows 上。请注意,除非您使用非常高级的语言,否则对 Windows API 进行编程绝非易事。

    【讨论】:

    • 好吧,我已经看过了,并想出了不起作用的代码。
    • 您可以尝试复制确切的代码,看看它是否有效。然后你可以从那里去。
    猜你喜欢
    • 1970-01-01
    • 2013-11-21
    • 2010-10-09
    • 2010-10-28
    • 2018-10-12
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    相关资源
    最近更新 更多