在这个文章中,我们已经初步完成了小黑子键盘的制作
也许有人会想使用自己制作的音频,也许有人会想增加更多的音频,所以我增加了自定义音频和自定义按键组合的功能

只需按照 字母:音频 的格式将组合添加到配置文件中,然后将音频和配置文件放到同一个目录下,即可完成自定义按键。
接下来就是代码了:
我已将代码和工程以及一个可用的程序上传至百度网盘,喜欢的可以下载:
链接:https://pan.baidu.com/s/1KG5YhmN92MBus_6ys7OgVw
提取码:JNTM
音频配置管理类:
#pragma once
#include<map>
#include<string>
class SoundFileManager
{
public:
SoundFileManager();
std::wstring GetSoundFileName();
void Init();
void KeyDown(char c);
void SetCurrentDic(wchar_t* dic);
private:
std::map<std::wstring, std::wstring>soundmap;
std::map<std::wstring, int>soundNum;
std::wstring currentSoundFileName;
std::wstring currentDic;
};
#include "SoundFileManager.h"
#include<Windows.h>
#include<string>
#include<cstring>
#include<fstream>
using namespace std;
wchar_t* char2wchar(const char* cchar)
{
wchar_t* m_wchar;
int len = MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), NULL, 0);
m_wchar = new wchar_t[len + 1];
MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), m_wchar, len);
m_wchar[len] = '\0';
return m_wchar;
}
SoundFileManager::SoundFileManager()
{
currentSoundFileName = L"";
}
wstring SoundFileManager::GetSoundFileName()
{
return currentSoundFileName;
}
void SoundFileManager::Init()
{
wstring setting = L"";
setting += currentDic.c_str();
setting+= L"setting\\";
wstring filename = L"setting.txt";
ifstream ifs;
ifs.open(setting + filename, ios::in);
char buff[1024] = { 0 };
while (ifs.getline(buff, sizeof(buff))) {
wstring keyStr = L"";
wstring valueStr = L"";
wstring buffw = char2wchar(buff);
bool isValue = false;
for (int i = 0; i < buffw.length(); i++) {
if (buffw[i] == ':')
{
isValue = true;
continue;
}
if (isValue) {
valueStr += buffw[i];
}
else {
keyStr += buffw[i];
}
}
if (!keyStr.empty() && !valueStr.empty()) {
soundmap[keyStr] = setting+valueStr;
if (keyStr.size() >= 2) {
soundNum[keyStr] = 0;
}
}
}
ifs.close();
}
void SoundFileManager::KeyDown(char c)
{
//string setting = "setting\\";
std::wstring keyStr = L"";
keyStr += c;
currentSoundFileName = soundmap[keyStr];
map<wstring, int>::iterator it;
for (it = soundNum.begin(); it != soundNum.end(); it++)
{
if (it->first[it->second] == c)
{
soundNum[it->first]++;
}
else
{
soundNum[it->first] = 0;
}
if (it->second == it->first.size())
{
currentSoundFileName = soundmap[it->first];
soundNum[it->first] = 0;
}
}
}
void SoundFileManager::SetCurrentDic(wchar_t* dic)
{
currentDic = dic;
}
主程序:
// XiaoHeiZi.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "resource.h"
#include <iostream>
#include<thread>
#include <conio.h>
#include<stdlib.h>
#include<windows.h>
#include<iostream>
#include <Mmsystem.h>
#include "SoundFileManager.h"
#pragma comment(lib, "Winmm.lib")
#define KEY_DOWN(key_name) ((GetAsyncKeyState(key_name)& 0x8000)?1:0)
#define KEY_UP(key_name) ((GetAsyncKeyState(key_name)&0x8000)?0:1)
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
using namespace std;
SoundFileManager manager;
bool ModifyRegedit(bool bAutoRun)
{
char pFileName[MAX_PATH] = { 0 };
DWORD dwRet = GetModuleFileNameA(NULL, (LPSTR)pFileName, MAX_PATH);
std::cout << pFileName;
HKEY hKey;
LPCSTR lpRun = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
long lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpRun, 0, KEY_WRITE, &hKey);
if (lRet != ERROR_SUCCESS)
{
std::cout << "failed";
return false;
}
if (bAutoRun)
RegSetValueA(hKey, "XiaoHeizi", (DWORD)REG_SZ, (LPCSTR)pFileName, MAX_PATH);
else
RegDeleteValueA(hKey, "XiaoHeizi");
RegCloseKey(hKey);
return true;
}
void PlaySoundFromFile(char c)
{
manager.KeyDown(c);
std::wstring fileName = manager.GetSoundFileName();
wcout << fileName << endl;
if (!fileName.empty()) {
PlaySoundW(fileName.c_str(), NULL, SND_FILENAME | SND_SYNC);
}
}
void SetKeyDownUp(bool* hasKeyDown,int num, bool isDown)
{
hasKeyDown[num] = isDown;
}
int main()
{
/*设置工作路径*/
wchar_t chpath[MAX_PATH];
GetModuleFileNameW(NULL, (LPWSTR)chpath, sizeof(chpath));
wchar_t currentPath[] = L"";
wstring cp = chpath;
int lastL = 0;
for (int i = 0; i < cp.length(); i++) {
if (chpath[i] == '\\') {
lastL = i;
}
}
for (int i = 0; i <= lastL; i++)
{
currentPath[i] = chpath[i];
}
currentPath[lastL + 1] = '\0';
SetCurrentDirectoryW(currentPath);
manager.SetCurrentDic(currentPath);
/*初始化配置文件*/
manager.Init();
/*尝试开机启动*/
ModifyRegedit(true);
/*循环检测按键*/
bool hasKeyDown[26] = { false };
for (;;)
{
for (int i = 0; i < 26; i++)
{
if (KEY_DOWN('A' + i))
{
SetKeyDownUp(hasKeyDown, i, true);
}
}
for (int i = 0; i < 26; i++)
{
if (KEY_UP('A'+i) && hasKeyDown[i] == true) {
//cout << "key_up" << endl;
SetKeyDownUp(hasKeyDown, i, false);
std::thread t1(PlaySoundFromFile, 'A' + i);
t1.detach();
}
}
}
}