首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

自製序號填寫神器 SNPaste:Shift+V 一鍵自動分段貼上

     編輯:關於VC++

安裝軟體時常需輸入序號(Serial Number),許多序號採用「XXXX-XXXX-XXXX-XXXX」分段格式,導致無法一次貼上,必須手動分段複製貼上,極為繁瑣。網路上有現成工具 SNCopy 解決此問題,但原理不複雜,筆者決定自行開發一款輕量級替代品 —— SNPaste。

核心功能

  • 將完整序號複製到剪貼簿
  • 游標定位到第一個輸入框
  • 按下 Shift+V 熱鍵
  • 程式自動依 - 分割,或依預設長度分段
  • 依序模擬 Ctrl+V 貼上 → Tab 切換欄位
  • 完成後自動還原剪貼簿原始內容

技術實作重點

1. 熱鍵註冊與註銷

// OnInitDialog 中註冊 Shift+V (0x56)
if (!::RegisterHotKey(this->GetSafeHwnd(), 0x3333, MOD_SHIFT, 0x56)) {
    AfxMessageBox(_T("熱鍵註冊失敗!"));
    this->CloseWindow();
}

// OnClose 中註銷
::UnregisterHotKey(this->GetSafeHwnd(), 0x3333);

2. 熱鍵訊息處理 OnHotKey

LRESULT 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;
}

3. 鍵盤模擬與剪貼簿操作

// 模擬 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();
}

執行畫面

SNPaste 程式介面

編譯環境與心得

  • VC++ 7.1 (VS 2003) 編譯通過
  • 關鍵細節:Sleep(100) 延遲不可省略,否則剪貼簿讀寫競爭會導致資料錯亂
  • 良好的創意是成功的一半 —— 這個小工具雖簡單,卻解決了實際痛點

完整原始碼已附上,歡迎下載修改、二次開發!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved