2010-04-05 4 views
13

나는 달성하고자하는 것을 상세하게 설명하기 위해 최선을 다할 것입니다.C#에서 시스템 클립 보드를 어떻게 백업하고 복원합니까?

내 C# 응용 프로그램에서 외부 응용 프로그램에 CTRL-C 복사 작업을 수행하기 위해 IntPtr 창 핸들과 함께 C#을 사용하고 있습니다. GET_TEXT를 사용하여 텍스트에 직접 액세스 할 수있는 방법이 없기 때문에이 작업을 수행해야했습니다. 그런 다음 응용 프로그램 내에서 해당 사본의 텍스트 내용을 사용하고 있습니다. 여기서 문제는 클립 보드를 덮어 썼다는 것입니다. 내가 할 수 있도록하고 싶습니다 무엇

은 다음과 같습니다

  1. 백업 내 자신 이외의 다른 응용 프로그램에서 설정 한 수있는 클립 보드의 원래 내용.
  2. 그런 다음 복사를 수행하고 값을 내 응용 프로그램에 저장하십시오.
  3. 그런 다음 사용자가 원래 클립 보드 데이터에 계속 액세스 할 수 있도록 클립 보드의 원래 내용을 복원하십시오.

    private void GetClipboardText() 
    { 
    
        text = ""; 
    
        IDataObject backupClipboad = Clipboard.GetDataObject(); 
    
        KeyboardInput input = new KeyboardInput(this); 
        input.Copy(dialogHandle); // Performs a CTRL-C (copy) operation 
    
        IDataObject clipboard = Clipboard.GetDataObject(); 
        if (clipboard.GetDataPresent(DataFormats.Text)) 
        { 
         // Retrieves the text from the clipboard 
         text = clipboard.GetData(DataFormats.Text) as string; 
        } 
    
        if (backupClipboad != null) 
        { 
         Clipboard.SetDataObject(backupClipboad, true); // throws exception 
        } 
    } 
    

    나는 System.Windows.Clipboard 아닌 System.Windows.Forms.Clipboard을 사용하고 있습니다 :

이는 지금까지 시도 코드입니다. 그 이유는 CTRL-C를 수행했을 때 System.Windows.Forms의 Clipboard 클래스가 데이터를 반환하지 않았지만 시스템 클립 보드가 그랬기 때문입니다.

OpenClipboard, EmptyClipboard 및 CloseClipboard와 같은 저수준 user32 호출을 살펴 보았습니다.하지만이 방법을 사용하면 도움이 될 수 있기를 기대했지만 복원 할 때 COM 예외가 계속 발생합니다.

아마도 이것은 클립 보드를 제어하려는 응용 프로그램의 IntPtr 창 핸들을 예상하는 OpenClipboard 매개 변수와 관련이 있다고 생각했습니다. 내 응용 프로그램에는 GUI가 없다고 언급 한 이래로 이것이 도전 과제입니다. 나는 여기서 무엇을 통과해야할지 확신하지 못했습니다. 어쩌면 누군가 그걸 밝힐 수 있을까요?

클립 보드 클래스를 잘못 사용하고 있습니까? GUI가없는 응용 프로그램의 IntPtr 창 핸들을 얻는 명확한 방법이 있습니까? 누구든지 시스템 클립 보드를 백업하고 복원하는 더 좋은 방법을 알고 있습니까?

+0

동일한 오류가 발생하여이 게시물을 발견했습니다. 그러나, 나는 Clipboard.GetDataObject(). SetData (myData)를 호출 할 때만이 오류가 발생합니다. Clipboard.SetDataObject (myData)를 호출하면 정상적으로 작동합니다. 이유가 뭐예요? 중요한 경우 내 응용 프로그램은 WPF 기반입니다. – newman

답변

6

당신은 사전에 클립 보드의 내용을 저장하고 나중에 복원 할 수 :

public IDictionary<string, object> GetClipboardData() 
{ 
    var dict = new Dictionary<string, object>(); 
    var dataObject = Clipboard.GetDataObject(); 
    foreach(var format in dataObject.GetFormats()) 
    { 
     dict.Add(format, dataObject.GetData(format)); 
    } 
    return dict; 
} 

public void SetClipboardData(IDictionary<string, object> dict) 
{ 
    var dataObject = Clipboard.GetDataObject(); 
    foreach(var kvp in dict) 
    { 
     dataObject.SetData(kvp.Key, kvp.Value); 
    } 
} 

... 

var backup = GetClipboardData(); 
// Do something with the clipboard... 
... 
SetClipboardData(backup); 
+0

내가 겪고있는 문제는 클립 보드를 여는 데 실패했기 때문에 수행하는 SetData 또는 SetDataObject에서 COM 예외가 발생한다는 것입니다. 나는 그 방법을 시도 할 것이지만 근본적인 문제는 클립 보드가 잠긴 것처럼 보인다는 것이다. – gtaborga

+1

이 루프의 첫 번째 SetData 호출에 대한 예외입니다. "고정 OLE 데이터 개체에서 SetData를 사용할 수 없습니다" – gtaborga

+0

IDataObject.SetData 대신 Clipboard.SetData를 시도한 다음 ... –

17

그것의 어리 석음이 작업을 수행하려고 할 수 있습니다. 클립 보드를 이전 상태로 충실하게 복원 할 수는 없습니다. "렌더링 지연"을 사용하여 수십 개의 렌더링되지 않은 데이터 형식이 존재할 수 있으며, 모두 렌더링하려고하면 소스 앱의 리소스가 부족해질 수 있습니다. 그것은 resturaunt에 들어가고 "나에게 모든 것을 줘"라고 말하는 것과 같습니다.

사용자가 Excel에서 500 행 × 100 열을 선택하고이를 클립 보드에 복사했다고 가정합니다. Excel은 비트 맵을 포함하여 약 25 가지 형식으로이 데이터를 생성 할 수 있다고 "광고"합니다. 비트 맵으로 붙여 넣으면 Excel에서 강제로 비트 맵으로 렌더링합니다. 그것은 50000 개의 셀이며 약 10,000 x 15,000 픽셀의 비트 맵입니다. 엑셀이 24 가지 포맷과 함께 그 동안 기침을하는 동안 사용자는 기다릴 것으로 기대하십니까? 가능하지 않다.

또한, 다른 클립 보드 뷰어에 영향을주는 WM_DrawClipboard 이벤트가 트리거됩니다.

포기하십시오.

+5

"프로그램에서 사용자가 명시 적으로 지시하지 않아도 클립 보드 밖으로 데이터를 전송하지 않아야합니다." - Charles Petzold, 프로그래밍 Windows 3.1, Microsoft Press 1992 –

+0

그 이유는 클립 보드 처리를 작성한 유일한 시간이었습니다. 코드는 .NET 응용 프로그램의 메뉴에서 잘라 내기, 복사 및 붙여 넣기를 구현할 때 사용되었습니다. – Powerlord

+0

나는 백업되는 모든 데이터를 렌더링하려하지 않았습니다. CTRL-C를 사용하여 검색된 데이터의 양은 텍스트의 문장 길이에 관한 것입니다. 필자는 자신의 필요에 따라 클립 보드를 사용한 후에 클립 보드의 원래 내용을 되돌릴 수있는 방법을 찾고있었습니다. 이 시나리오에서 '클립 보드를 열 수 없습니다'라는 오류 메시지없이 클립 보드를 복원 할 수 있습니까? – gtaborga

관련 문제