eme*_*son 3 c++ clipboard text clipboarddata
我是C++的初学者,但我设法修改了其他人的代码,最后整理了一个程序,将Windows剪贴板写入文本文件,在代码页中编码的文本指定为命令行参数程序(例如,MyProg.exe 437)将在代码页437中写入文本.如果未指定代码页,则程序在标准Windows代码页1252中写入文本文件.
问题是如果剪贴板包含(例如)快捷方式或文件而不包含文本,程序将崩溃.如果CF_TEXT剪贴板中没有数据,有人能告诉我如何优雅地退出吗?(或者我完全误解了这个问题?)
我找到了一个没有成功的答案.这是我的VC2010代码(我不完全理解,但它似乎工作,当剪贴板包含CF_TEXT;它不起作用CF_UNICODETEXT,顺便说一下 - 输出只是几个字节.):
#include <stdafx.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <codecvt> // for wstring_convert
#include <locale> // for codecvt_byname
using namespace std;
void BailOut(char *msg)
{
fprintf(stderr, "Exiting: %s\n", msg);
exit(1);
}
int main(int argc, char* argv[])
{
std::string codepage = ".1252";
if (argc > 1) {
std::string cpnum = argv[1];
codepage = "."+cpnum;
}
HANDLE clip;
string clip_text = "";
// exit if clipboard not available
if (!OpenClipboard(NULL))
BailOut("Can't open clipboard");
clip = GetClipboardData(CF_TEXT);
clip_text = (char*)clip;
CloseClipboard();
// create conversion routines
typedef std::codecvt_byname<wchar_t,char,std::mbstate_t> codecvt;
std::wstring_convert<codecvt> cp1252(new codecvt(".1252"));
std::wstring_convert<codecvt> outpage(new codecvt(codepage));
std::string OutFile = "#clip.txt"; // output file name
ofstream OutStream; // open an output stream
OutStream.open(OutFile, ios::out | ios::trunc);
// make sure file is successfully opened
if(!OutStream)
{
cout << "Error opening file " << OutFile << " for writing.\n";
return 1;
}
// convert to DOS/Win codepage number in "outpage"
OutStream << outpage.to_bytes(cp1252.from_bytes(clip_text)).c_str();
OutStream << endl;
OutStream.close(); // close output stream
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果有关于如何解决这个问题的建议,我将不胜感激.
在使用该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.
}
Run Code Online (Sandbox Code Playgroud)
然后你必须打开剪贴板并获得剪贴板缓冲区的句柄,如下所示(假设剪贴板包含ANSI字符串):
if(!OpenClipboard(NULL)) return;
HGLOBAL hglb = GetClipboardData(CF_TEXT);
Run Code Online (Sandbox Code Playgroud)
然后,您必须使用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();
Run Code Online (Sandbox Code Playgroud)
返回类型GlobalLock是void指针.因此,根据您已经确定使用的数据格式IsClipboardFormatAvailable,您必须将其强制转换为相应的类型.Windows数据类型在此处记录.