安裝軟體時常需輸入序號(Serial Number),許多序號採用「XXXX-XXXX-XXXX-XXXX」分段格式,導致無法一次貼上,必須手動分段複製貼上,極為繁瑣。網路上有現成工具 SNCopy 解決此問題,但原理不複雜,筆者決定自行開發一款輕量級替代品 —— SNPaste。
- 分割,或依預設長度分段// OnInitDialog 中註冊 Shift+V (0x56)
if (!::RegisterHotKey(this->GetSafeHwnd(), 0x3333, MOD_SHIFT, 0x56)) {
AfxMessageBox(_T("熱鍵註冊失敗!"));
this->CloseWindow();
}
// OnClose 中註銷
::UnregisterHotKey(this->GetSafeHwnd(), 0x3333);
OnHotKeyLRESULT CsnpasteDlg::OnHotKey(WPARAM wParam, LPARAM lParam) {
if (!OpenClipboard()) { AfxMessageBox(_T("無法開啟剪貼簿!")); return -1; }
CString str = (char*)::GetClipboardData(CF_TEXT);
CString oldstr = str; // 備份原始內容
CloseClipboard();
str.Trim();
int find_i = str.Find('-');
if (find_i != -1) { // 含分隔符 '-'
while (find_i != -1) {
CString strtemp = str.Left(find_i);
str = str.Mid(find_i + 1);
find_i = str.Find('-');
Sleep(100); // 關鍵延遲,避免剪貼簿操作過快導致資料錯誤
SendStrToClipboard(strtemp);
PerformCtrlV();
PerformClickTab();
}
if (!str.IsEmpty()) { // 最後一段
SendStrToClipboard(str);
PerformCtrlV();
PerformClickTab();
}
} else { // 無分隔符,依 Spin Control 設定的固定長度分段
while (!str.IsEmpty()) {
CString strtemp = str.Left(m_spinctrl.GetPos());
str = str.Mid(m_spinctrl.GetPos());
Sleep(100);
SendStrToClipboard(strtemp);
PerformCtrlV();
PerformClickTab();
}
}
Sleep(100);
SendStrToClipboard(oldstr); // 還原剪貼簿
return 1;
}
// 模擬 Ctrl+V
void CsnpasteDlg::PerformCtrlV() {
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event(0x56, 0, 0, 0); // V key down
keybd_event(0x56, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
}
// 模擬 Tab
void CsnpasteDlg::PerformClickTab() {
keybd_event(VK_TAB, 0, 0, 0);
keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);
}
// 字串寫入剪貼簿
void CsnpasteDlg::SendStrToClipboard(CString str) {
if (!OpenClipboard()) { AfxMessageBox(_T("無法開啟剪貼簿!")); return; }
EmptyClipboard();
HGLOBAL hglo = GlobalAlloc(GPTR, str.GetLength() + 1);
if (!hglo) { AfxMessageBox(_T("記憶體配置失敗!")); return; }
LPBYTE pbyte = (LPBYTE)GlobalLock(hglo);
memcpy(pbyte, str.GetBuffer(), str.GetLength());
str.ReleaseBuffer();
GlobalUnlock(hglo);
SetClipboardData(CF_TEXT, hglo);
CloseClipboard();
}

Sleep(100) 延遲不可省略,否則剪貼簿讀寫競爭會導致資料錯亂完整原始碼已附上,歡迎下載修改、二次開發!