2011-10-21 24 views
2

我有一些代碼複製並粘貼:我錯誤地使用Windows剪貼板嗎?

void WinClipboard::copy(const std::string& input) 
    { 
     LPWSTR lptstrCopy; 
     HGLOBAL hglbCopy; 
     std::wstring text; 

     text = _winUTF8ToUTF16(input); 

     // Open the clipboard, and empty it. 

     if (!OpenClipboard(NULL)) 
      return; 

     EmptyClipboard(); 

     // Allocate a global memory object for the text. 
     hglbCopy = GlobalAlloc(GMEM_MOVEABLE, 
      ((text.length() + 1) * sizeof(WCHAR))); 

     if (hglbCopy == NULL) 
     { 
      CloseClipboard(); 
      return; 
     } 

     // Lock the handle and copy the text to the buffer. 
     lptstrCopy = (LPWSTR)GlobalLock(hglbCopy); 
     memcpy(lptstrCopy, text.c_str(), 
      (text.length() + 1) * sizeof(WCHAR)); 
     lptstrCopy[(text.length() + 1) * sizeof(WCHAR)] = (WCHAR) 0; // null character 
     GlobalUnlock(hglbCopy); 

     // Place the handle on the clipboard. 

     SetClipboardData(CF_UNICODETEXT, hglbCopy); 


     // Close the clipboard. 

     CloseClipboard(); 
    } 

    std::string WinClipboard::paste() 
    { 
     HGLOBAL hglb; 
     LPWSTR lptstr; 

     std::string result; 
     std::wstring input; 

     // get the clipboard text. 

     if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) 
      return result; 

     if (!OpenClipboard(NULL)) 
      return result; 

     hglb = GetClipboardData(CF_UNICODETEXT); 
     if (hglb != NULL) 
     { 
      lptstr = (LPWSTR)GlobalLock(hglb); 


      if (lptstr != NULL) 
      { 
       GlobalUnlock(hglb); 
       input = lptstr; 
       result = _winUTF16ToUTF8(input); 
      } 
      CloseClipboard(); 
     } 
     return result; 
    } 

除,當我快做CTRL C,然後CTRL-V(實質上調用上面的複製和粘貼功能),它的偉大工程的整個應用程序凍結。

我是否忘記檢查某些內容或忘記釋放資源?

+4

行'lptstrCopy [(text.length()+ 1)* sizeof(WCHAR)]'是緩衝區溢出。 –

+0

@RaymondChen我也嘗試過使用這段代碼,並在調用SetClipboardData()時崩潰。我從來沒有見過另一個明確試圖設置空字符的例子。 –

+0

MSDN指出:...如果應用程序在打開剪貼板時指定了NULL窗口句柄,EmptyClipboard會成功,但會將剪貼板所有者設置爲NULL。請注意,這會導致SetClipboardData失敗。 – Orwellophile

回答

5

我看到你paste()功能兩個問題:

1)它被調用GlobalUnlock()剪貼板數據分配給您的std::wstring變量之前。您需要反轉這些操作 - 複製數據後調用GlobalUnlock(),而不是之前。

2)如果GetClipboardData()失敗,它不會調用CloseClipboard()

+0

謝謝,這樣做! – jmasterx

1

另一個「問題」。

copy功能:

lptstrCopy[(text.length() + 1) * sizeof(WCHAR)] = (WCHAR) 0;

應該是

lptstrCopy[text.length() + 1] = (WCHAR) 0;

,以避免上溢/堆損壞。