购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.3 技术准备

2.3.1 技术概览

宏技术:宏可以用于定义常量或简单的内联函数,以提高代码的可读性和可维护性。

例如:定义一个宏,代码如下:

#define SQUARE(x) ((x) * (x))

剪贴板操作:需要使用操作系统提供的API或者通过第三方库来实现。在Windows平台下,可以使用Windows API来进行剪贴板操作。

注册表操作:使用注册表来存储和检索应用程序的设置。MFC提供了一些类和函数来简化注册表操作,这些功能主要是通过CWinApp类的成员函数和CRegKey类来实现的。

加密算法:加密算法用于将数据转换为不可读或难以理解的形式,以保护数据的安全性。在C++中,可以使用各种加密算法来加密和解密数据。

系统API应用:用于与操作系统进行交互和控制系统资源。在C++中,系统API可用于执行多种任务,包括文件操作、进程管理、网络通信等。

硬件信息获取:获取硬件信息通常涉及与操作系统进行交互以查询系统资源和设备信息。在Windows平台下,可以使用系统API或WMI来获取硬件信息。本项目采用API获取硬件信息,获取的信息将会在2.3.2节~2.3.4节中进行介绍。

《Visual C++从入门到精通(第5版)》详细地讲解了宏技术、剪贴板操作、注册表操作、加密算法、系统API应用等知识,对这些知识不太熟悉的读者,可以参考该书对应的内容。

2.3.2 获取CPU序列号

在软件注册模块中,注册码是通过硬件信息生成的,其中包括CPU序列号。实现代码如下:

说明

通过使用cpuid指令,我们可以获取CPU序列号以及处理器的详细信息。cpuid指令是自Intel 486处理器以来就被加入支持的功能。

2.3.3 获得磁盘序列号

在软件注册模块中,注册码是通过硬件信息生成的,其中包括磁盘序列号。通过函数GetVolumeInformation,我们可以获取磁盘驱动器的磁盘列号。实现代码如下:

BOOL GetVolumeInformation(
     LPCTSTR lpRootPathName,
     LPTSTR lpVolumeNameBuffer,
     DWORD nVolumeNameSize,
     LPDWORD lpVolumeSerialNumber,
     LPDWORD lpMaximumComponentLength,
     LPDWORD lpFileSystemFlags,
     LPTSTR lpFileSystemNameBuffer,
     DWORD nFileSystemNameSize
);

参数说明如下:

lpRootPathName:指定要获取信息的磁盘的根路径。

lpVolumeNameBuffer:用于存储磁盘名的字符串缓冲区。

nVolumeNameSize:lpVolumeNameBuffer缓冲区的大小。

lpVolumeSerialNumber:用于存储磁盘序列号的变量。

lpMaximumComponentLength:用于存储文件名每一部分的长度。

lpFileSystemFlags:用于存储一个或多个二进制位标志的变量。

lpFileSystemNameBuffer:指定一个缓冲区,用于存储文件系统的名称。

nFileSystemNameSize:lpFileSystemNameBuffer缓冲区的大小。

获得磁盘序列号的实现代码如下:

2.3.4 获得网卡地址

在软件注册模块中,注册码是通过硬件信息生成的,其中包括网卡地址。为了获得网卡的地址,程序需要调用Netbios函数,并在该函数调用时设置NCBASTAT命令。Netbios函数的原型定义如下:

UCHAR
APIENTRY
Netbios(
    PNCB pncb
);

实现代码如下:

2.3.5 生成注册码

在获得了各个硬件的数据之后,我们需要利用这些数据来生成注册码。首先,我们声明一个密钥数组。实现代码如下:

//定义一个密钥数组
CString code[16] = {"ah", "tm", "ib", "nw", "rt", "vx", "zc", "gf",
                    "pn", "xq", "fc", "oj", "wm", "eq", "np", "qw"
                   };

然后,我们将硬件数据转换为十六进制数据,并据此从密钥数组中读取相应的密钥。实现代码如下:

2.3.6 根据注册表中数据限制试用次数

软件注册模块提供了注册和试用两种运行模式供用户选择。如果用户选择试用,系统将首先判断用户是否已经试用过,若用户未曾试用,系统将自动设置允许用户试用30次;如果用户已经试用过,系统将读取注册表中的剩余试用次数,并向用户显示他们可用的剩余试用次数。实现代码如下:

选择试用软件以后,系统会将减少后的试用次数写入注册表中。实现代码如下:

2.3.7 注册快捷键

要为程序设置快捷键,可以使用RegisterHotKey函数来根据用户设置的热键组合进行注册。

RegisterHotKey函数的语法格式如下:

BOOL RegisterHotKey( HWND hWnd, int id,UINT fsModifiers, UINT vk );

参数说明:

hWnd:注册快捷键的窗体句柄。

id:用户的自定义消息ID值。

fsModifiers:设置组合键,取值如下:

MOD_ALT:Alt键。

MOD_CONTROL:Ctrl键。

lMOD_SHIFT:Shift键。

MOD_WIN:Win键。

vk:快捷键的虚拟键代码。

当程序运行结束时,需要注销已经注册的快捷键,这可以通过UnregisterHotKey函数来实现。

UnregisterHotKey函数的语法格式如下:

BOOL UnregisterHotKey( HWND hWnd, int id );

参数说明:

hWnd:注册快捷键的窗体句柄。

id:用户的自定义消息ID值。

注册快捷键的步骤如下。

(1)声明自定义消息。实现代码如下:

#define HOTKEY_PASTE      11111

(2)添加快捷键消息的函数声明。实现代码如下:

afx_msg void OnHotKey(WPARAM wParam,LPARAM lParam);

(3)添加消息映射。实现代码如下:

ON_MESSAGE(WM_HOTKEY,OnHotKey)

(4)添加消息响应函数的实现代码。实现代码如下:

2.3.8 一次性粘贴注册码

在使用软件注册模块时,用户可以一次性粘贴注册码,这一功能是通过剪贴板来实现的。在程序中添加两个消息映射宏ON_WM_CHANGECBCHAIN和ON_WM_DRAWCLIPBOARD,用于实时监测剪贴板中的内容。其中,ON_WM_DRAWCLIPBOARD宏负责显示剪贴板中的内容,而ON_WM_CHANGECBCHAIN宏则用于控制是否继续对剪贴板进行监视。随后,使用OpenClipboard函数来打开剪贴板。剪贴板打开后,可以通过GetClipboardData函数来获取剪贴板中的内容。操作完成后,利用CloseClipboard函数关闭剪贴板。

(1)添加消息映射。实现代码如下:

ON_WM_CHANGECBCHAIN()
ON_WM_DRAWCLIPBOARD()

(2)添加函数声明。实现代码如下:

afx_msg void OnDrawClipboard();
afx_msg void OnChangeEdit1();

(3)添加OnChangeCbChain函数的实现代码,用于停止对剪贴板进行监视。实现代码如下:

void CRegisterNumDlg::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter)
{
    if( hwnd==hWndRemove )
        hwnd=hWndAfter;
    ::SendMessage(hwnd,WM_CHANGECBCHAIN,(WPARAM)hWndRemove,(LPARAM)hWndAfter);
}

(4)添加OnDrawClipboard函数的实现代码,用于获取剪贴板中的数据。实现代码如下:

(5)添加PasteReg方法,用于调用OnChangeCbChain函数和OnDrawClipboard函数。实现代码如下: 8651GVDWumNbydfeQxLVaW0BJe6Yy+1bGg12Zk4cxv2suTxTGEeecjKarlB0iKhU

void CRegisterNumDlg::PasteReg()
{
    hwnd = SetClipboardViewer();                  //设置剪贴板查看器
    Sleep(100);                                   //延时
    ChangeClipboardChain(hwnd);                   //停止检测剪贴板
}
点击中间区域
呼出菜单
上一章
目录
下一章
×