C ++(VC):如何检测Windows剪贴板是否包含CF_TEXT数据?

时间:2015-06-29 14:41:19

标签: c++ text clipboard clipboarddata

我是C ++的初学者,但我设法修改了其他人的代码,最后整理了一个程序,将Windows剪贴板写入文本文件,在代码页中编码的文本被指定为命令行程序的参数(例如,MyProg.exe 437)将在代码页437中写入文本。如果未指定代码页,程序将在标准Windows代码页1252中写入文本文件。

问题是如果剪贴板包含(例如)快捷方式或文件而不包含文本,程序会崩溃。如果剪贴板中没有from multiprocessing import Process, freeze_support def f(): print 'hello world!' if __name__ == '__main__': freeze_support() Process(target=f).start() 数据,有人可以告诉我如何优雅退出吗? (或者我完全误解了这个问题?)

我找到了一个没有成功的答案。这是我的VC2010代码(我不完全理解,但它似乎工作,当剪贴板包含CF_TEXT;它不适用于CF_TEXT,顺便说一句 - 输出只是几个字节。):

CF_UNICODETEXT

如果有任何关于如何解决这个问题的建议,我将不胜感激。

2 个答案:

答案 0 :(得分:5)

在使用GetClipboardData功能从剪贴板获取数据之前,您必须检查剪贴板是否包含您期望的格式的数据。这可以使用IsClipboardFormatAvailable函数完成,如下所示:

if(IsClipboardFormatAvailable(CF_TEXT))
{
    // The clipboard contains null-terminated ANSI string.
}
else if (IsClipboardFormatAvailable(CF_UNICODETEXT))
{
    // The clipboard contains null-terminated Unicode string.
}

然后你必须打开剪贴板并获得剪贴板缓冲区的句柄,如下所示(假设剪贴板包含ANSI字符串):

if(!OpenClipboard(NULL)) return;
HGLOBAL hglb = GetClipboardData(CF_TEXT);

然后,您必须使用GlobalLock功能获得对数据的独占访问权限。只有在成功时您才能安全地访问数据

if (hglb != NULL)
{
    LPTSTR lptstr = GlobalLock(hglb); 
    if (lptstr != NULL) 
    {
        // Read the contents of lptstr which just a pointer to the string.

        // Don't forget to release the lock after you are done.
        GlobalUnlock(hglb);
    }
}
CloseClipboard(); 

GlobalLock的返回类型是void指针。因此,根据您使用IsClipboardFormatAvailable确定的数据格式,您必须将其强制转换为相应的类型。 Windows数据类型记录为here

答案 1 :(得分:0)

感谢您的回答,这比我在看到您的帖子之前提出的答案要有用得多。这是我的尴尬和不安全的解决方案(它取代了我的问题中的相应代码)。我将使用你更好的解决方案!

HANDLE clip;
std::string clip_text = "";
// exit if clipboard not available
if (!OpenClipboard(NULL))
        BailOut("Can't open clipboard"); 

UINT textOK = 0;
UINT currentFormat = 0;
    while(currentFormat = EnumClipboardFormats(currentFormat)) 
{
    if(currentFormat == 1) 
        textOK = 1;
}
// only get text if text exists in clipboard
if (textOK == 1)
{
    clip = GetClipboardData(CF_TEXT);
    clip_text = (char*)clip;
}
CloseClipboard();

由于各种原因(启动它的程序希望找到#CLIP.TXT文件),我已经使我的代码生成一个空文件而不是退出。再次感谢你!