吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2130|回复: 8
收起左侧

[C&C++ 原创] 使用c++SDK写个钢琴,加上自动演奏外挂

[复制链接]
hudaoyuan163 发表于 2022-8-22 20:42
本帖最后由 hudaoyuan163 于 2022-8-23 08:35 编辑

钢琴买不起,可以自己码一个。
来个C++ Piano,码砖累了还可以即兴演奏一首。
主要用到SDK知识,文件流,字符转,程序之间消息传送,window运行程序遍历等
音源和乐谱在压缩包中,一并奉上,望大佬多多指教
1.实现播放本地音乐:
  • 在项目中添加音乐文件,如果在vs中运行即以main数所在文件夹为当前文件夹,如果运行的是exe文件,则是以exe文件所在的文件夹为当前文件夹。

  • 导入Windows.h头文件,#pragma comment(lib,"winmm.lib"),需要使用micString(),该函数用于将mci(媒体控制设备)有关指令发送到设备上。该函数有两种版本A版和W版,是否可以使用通用版?函数如果成功返回0失败则返回其他。

  • MCIERROR mciSendString(
     LPCTSTR lpszCommand,       //发送给MCI的指令
     LPTSTR  lpszReturnString,  //返回的结果
     UINT    cchReturn,         //返回结果大小
     HANDLE  hwndCallback       //如果在命令字符串中指定了“通知”标志,则返回回调窗口的hwndCallback句柄
    );
  • 新建一个loadmusic函数导入所有音乐并设置别名mciSendStringA(("open sound\start.mp3 alias START"), temp, 255, 0);这里alias是别名指令,将start.mp3打开为别名START。

  • 新建一个PlayMusic函数用于播放已经打开的音乐,mciSendStringA("seek START to start", NULL, 0, 0);mciSendStringA("play START", NULL, 0, 0);               

2.实现窗口对按键的反应
  • 在窗口的回调函数中判断 Msg 如果是WM_CHAR消息,则获取wParam的值,以该值作为索引找出对应的音乐。
  • 按下不同的按键就会打开对应音乐。
3.实现外挂读取文件
  • 包含windows,使用GetDesktopWindow()得到桌面句柄,使用GetWindow得到屏幕上第一个子窗口句柄,通过while循环和GetNextWindow遍历所有窗口,找到Piano程序,得到其句柄。
  • 创建SendOpern函数发送曲谱,参数为句柄,第一步打开文件获取数据,使用ofstream读取文本文件。(无法读取空格)
  • 将读取到的字符通过sendmessage发送给Pinao窗口,第一个参数为句柄,第二个参数为发送消息类型,第三个参数为wParam,第四个参数为lParam。 SendMessage( hd,WM_CHAR,k, 0)。

贴上源代码

Piano

#include<Windows.h>
#include<tchar.h>//为通用提供映射
#include< conio.h >
#include<stdio.h>
//该链接库用于音乐播放
#pragma comment(lib,"winmm.lib")

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void LoadMusic();
int APIENTRY _tWinMain(
        HINSTANCE hinstance, //实例句柄
        HINSTANCE hPrevInstance,
        LPTSTR lpCmdLine,  //命令行参数
        int nCmdShow        //显示方式
)
{
        //1.设计窗口类
        WNDCLASS ws = {};
        //窗口类名
        ws.lpszClassName = _T("Music");
        //窗口回调函数
        ws.lpfnWndProc = WndProc;
        //背景颜色
        ws.hbrBackground = CreateSolidBrush(RGB(255, 180, 255));
        //光标图标菜单,
        ws.hInstance = hinstance;

        //2.注册窗口类
        RegisterClass(&ws);
        //3.创建窗口
        HWND hWnd = CreateWindow(
                _T("Music"),                 //窗口类名
                _T("Piano"),  //窗口名
                WS_OVERLAPPEDWINDOW,//窗口风格
                100, 100,   //窗口左上角的位置,以屏幕左上角为参考点
                600, 800,   //窗口的宽度和高度
                NULL,         //父窗口句柄
                NULL,          //菜单句柄
                hinstance,   //实例句柄
                NULL            //附加参数
        );
        //4.更新显示窗口
        ShowWindow(hWnd, SW_SHOW);
        UpdateWindow(hWnd);
        LoadMusic();

        //5.消息循环
        MSG msg = {};
        //GetMessage
        //第一个是消息结构体
        //第二个是窗口句柄,如果填0就是所有窗口的消息
        //第三个是最小消息数量
        //第四个是最大消息数量

        while (GetMessage(&msg, 0, 0, 0))
        {
                //将消息分发给回调函数
                TranslateMessage(&msg);
                DispatchMessage(&msg);

        }
        return 0;
}

LRESULT CALLBACK  WndProc(HWND hWnd, UINT Msg, WPARAM wParam,
        LPARAM lParam)
{
        switch (Msg)
        {
        case WM_CHAR:
        {
                char szBuf[100] = { 0 };
                char szBuf1[100] = { 0 };
                sprintf_s(szBuf, sizeof(szBuf), "seek %c to start", wParam);
                sprintf_s(szBuf1, sizeof(szBuf1), "play %c", wParam);
                mciSendStringA(szBuf, NULL, 0, 0);
                mciSendStringA(szBuf1, NULL, 0, 0);
        }break;
        case WM_KEYDOWN:
        {
                //MessageBox(0, buff, 0, 0);
        }break;
        case WM_CLOSE:
                PostQuitMessage(0);
                break;
        default:
                break;
        }
        //如果不想要处理的消息类型,就让他返回默认的处理函数
        return DefWindowProc(hWnd, Msg, wParam, lParam);
}

void LoadMusic()
{
        char A = 'A';
        for (int i = 1; i < 26; i++)
        {
                char szBuf[100] = { 0 };
                sprintf_s(szBuf, sizeof(szBuf), "open sound\\Sound_%c.wav alias %c", A, A);//写入
                A++;
                mciSendStringA(szBuf, NULL, 0, 0);
        }
}

辅助,读取琴谱自动演奏

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <iostream>
#include<fstream>
void SendOpern(HWND hd);
void SendOpern2(HWND hd);
using namespace std;

int main()
{
    HWND hd = GetDesktopWindow();        //得到桌面窗口
    hd = GetWindow(hd, GW_CHILD);        //得到屏幕上第一个子窗口
    char s[200] = {0};
    int num = 1;
    while (hd != NULL)                    //循环得到所有的子窗口
    {
        //memset(s, 0,200);
        GetWindowTextA(hd, s, 200);
        //cout << num++ << ": " << s <<sizeof(s) << endl;
        //由于字符串数组之间无法比较,所以需要转换为字符串
        std::string a(&s[0], &s[strlen(s)]);
        if (a == "Piano") {
            SendOpern2(hd);
            printf("演奏成功");
            break;
        }

        hd = GetNextWindow(hd, GW_HWNDNEXT);
    }
    SendOpern(hd);
    getchar();
    return 0;
}

void SendOpern(HWND hd)
{
    ifstream Opern;
    Opern.open("Sound.txt", ios::in);
    char k;
    while (Opern >> k) {
        Sleep(800);
        //此处空格和"\n"都被>>吃掉了
        SendMessage(
            hd,
            WM_CHAR,
            k, 0
        );
        printf("%c\n", k);
    }

}

void SendOpern2(HWND hd)
{
    ifstream Opern;
    Opern.open("Sound.txt", ios::in);
    string k;
    while (Opern >> k) {
        for (auto ele : k) {
            Sleep(1000);
            SendMessage(
                hd,
                WM_CHAR,
                ele, 0
            );
            printf("%c\n", ele);
        }
        Sleep(1000);
    }

}

sound.zip

1.2 MB, 下载次数: 44, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
mrtwzchi + 1 + 1 谢谢@Thanks!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

losingstars 发表于 2022-8-23 00:54
需要音源和乐谱
DRLLL 发表于 2022-8-23 06:27
 楼主| hudaoyuan163 发表于 2022-8-23 08:37
virsnow 发表于 2022-10-8 16:07
看起来有点复杂,收藏先,有空研究一下
mrtwzchi 发表于 2022-11-18 19:31
学习学习
曙光牛 发表于 2022-11-18 22:39
对于我目前来说很复杂,先放收藏夹吃灰
mrtwzchi 发表于 2022-11-24 23:13
有成品视频吗,看看效果
tianbail 发表于 2022-11-25 14:39

学习学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 02:37

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表