簡體   English   中英

C ++(VC):如何檢測Windows剪貼板是否包含CF_TEXT數據?

[英]C++ (VC): How to detect whether Windows clipboard contains CF_TEXT data?

我是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;
} 

如果有關於如何解決這個問題的建議,我將不勝感激。

在使用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確定的數據格式,您必須將其IsClipboardFormatAvailable轉換為相應的類型。 Windows數據類型在此處記錄

謝謝你的答案,這比我在看到你的帖子之前提出的答案要有用得多。 這是我的尷尬和不安全的解決方案(它取代了我的問題中的相應代碼)。 我將使用你更好的解決方案!

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文件),我已經使我的代碼生成一個空文件而不是退出。 再次感謝你!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM