65.9K
CodeProject 正在变化。 阅读更多。
Home

序列号粘贴器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (4投票s)

2012年8月9日

CPOL

3分钟阅读

viewsIcon

29650

downloadIcon

419

一个自动粘贴分段序列号的工具。

引言

当我们想要安装一个应用程序时,有时我们需要分别复制和粘贴序列号。SNP(序列号粘贴器)是一个可以自动粘贴序列号的工具。

例如,假设你有一个激活表单,需要单独复制和粘贴序列号。SNP 只需一次复制和粘贴操作即可完成。 你应该复制整个序列号,例如 (XXXX-XXXX-XXXX-XXXX),然后点击第一个文本框,然后按 Ctrl+F11。

背景

模拟用户的鼠标/键盘输入对我来说很有趣 - 也许对你也是如此。可以通过 Win23 API 按下键盘按钮。我使用了 keybd_event。 你可以使用 DllImport 属性导入这些 API。请看下面的定义

[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, long dwFlags, ulong dwExtraInfo);

DllImport 的参数是一个 Windows dll 名称,它包含下一行中的函数 (keybd_event)。所有我们想要在 .NET 中导入的 API 都必须以 static extern 关键字开头。函数名称必须与 API 名称完全相同。参数应转换为 .NET 中的适当数据类型。 更多信息请查看这篇文章

实现

按下和释放一个按键 

我已经在 KeyboardApi 类中添加了所有必要的 API。 因此,要按下 control 键,我们应该像这样调用 keybd_event: 

KeyboardAPI.keybd_event((byte)Keys.ControlKey, 0, KeyboardAPI.KEYDOWN, 0);

要释放 control 键: 

KeyboardAPI.keybd_event((byte)Keys.ControlKey, 0, KeyboardAPI.KEYUP, 0);

为了按下和释放一个按键,我写了这个函数: 

public void PressKey(Keys key)
{
    // Pressing down the key
    KeyboardAPI.keybd_event((byte)key, 0, KeyboardAPI.KEYDOWN, 0);
    // Pressing up the key
    KeyboardAPI.keybd_event((byte)key, 0, KeyboardAPI.KEYUP, 0);            
}

按下修饰键 

PressModKey 函数将帮助你按下和释放指定的修饰键。我将修饰符定义为: 

public enum MODKEY { None, Ctrl, Alt, Shift, RWin, LWIN };

定义 MODKEY 只是为了简化编码。

public void PressModKey(MODKEY modkey, bool PressDown)
{
    switch(modkey)
    {
        case MODKEY.None :
                break;
        case MODKEY.Ctrl :
                        KeyboardAPI.keybd_event((byte)Keys.ControlKey, 0, PressDown ? 
                        KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
                break;
        case MODKEY.Alt :
                        KeyboardAPI.keybd_event((byte)Keys.Menu, 0, PressDown ? 
                        KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
            break;
        case MODKEY.Shift :
                        KeyboardAPI.keybd_event((byte)Keys.ShiftKey, 0, 
                        PressDown ? KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
            break;
        case MODKEY.LWIN : 
                        KeyboardAPI.keybd_event((byte)Keys.LWin, 0, 
                        PressDown ? KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
            break;
        case MODKEY.RWin :
                        KeyboardAPI.keybd_event((byte)Keys.RWin, 0, 
                        PressDown ? KeyboardAPI.KEYDOWN : KeyboardAPI.KEYUP, 0);
            break;
    }            
}

热键 

如果你想注册一个全局键盘组合,该组合能够在任何地方被调用,你可以使用热键。要注册它们,你应该调用 RegisterHotKey API。原型是

[DllImport("User32.dll")]
public static extern int RegisterHotKey(
    int hwnd,
    int id,
    uint fsModifiers, 
    uint vk);

hwnd:你的表单的句柄。

id:你分配给你的热键的数字,用于追踪它。

fsModifiers:键盘修饰符,如:Ctrl, Alt, Shift

vk:来自 此页面 的键码。 

注册热键 

为了注册一个热键,我编写了 RegHotKey 函数,它将注册 Ctrl+F11

public void RegHotKey()
{
    if (KeyboardAPI.RegisterHotKey((int)Handle, HotKey_F11, KeyboardAPI.MOD_CONTROL, KeyboardAPI.VK_F11) == 0)
    {
        MessageBox.Show("Error = " + KeyboardAPI.GetLastError());
    }
} 

注意:大多数 Apis 将使用 GetLastError 函数返回它们的异常消息。

实现的最重要部分:WndProc

Windows 操作系统中的所有窗口都有 WndProc 函数,它负责接收消息。这些消息包含我们的窗口需要的所有东西才能工作。例如鼠标/键盘事件。你应该在你的主表单类中重写它。该函数有一个 Message 参数类型。它有 WParam 参数,在我们的例子中,它将指示我们的热键的 id(你通过 RegisterHotKey 函数注册了它)。 

protected override void WndProc(ref Message m)
{
    if ((int)m.WParam == HotKey_F11)
    {
        if( Clipboard.GetDataObject().GetDataPresent(DataFormats.Text, true) )
        {
            string sn = (string)Clipboard.GetDataObject().GetData(DataFormats.Text, true);
            sn = sn.Trim();
            string[] split = sn.Split(new char[] {'-',' ',}, 
                     StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0; i < split.Length; i++)
            {
                try
                {
                    Clipboard.SetDataObject(split[i], true, 5, 100);
                }
                catch
                {
                    // we have to ignore it!
                }

                PressModKey(MODKEY.Ctrl, true);
                PressKey(Keys.V);
                PressModKey(MODKEY.Ctrl, false);
                Thread.Sleep(100);
                if (i < split.Length - 1 && ch_UseTab.Checked)
                {
                    PressKey(Keys.Tab);
                    Thread.Sleep(100);
                }
            }
            Clipboard.SetDataObject(sn , true);
        }
    }
    base.WndProc (ref m);
}

正如你所看到的,我读取了剪贴板,其中包含序列号(由用户复制)。然后,我通过一些标记('-',' ')分割了序列号,并在一个 for 循环中将段复制到剪贴板,并使用按下 Ctrl+V 键粘贴它们。如果用户设置了 UseTab 选项,将按下 tab 键。Sleeps 用于给 UI 时间将段粘贴到另一个应用程序。 更改 Sleep 函数的参数以查看结果。 

历史

  • 1.0 版本:2012 年 8 月 8 日,首次发布。
© . All rights reserved.