211 lines
5.8 KiB
C++
211 lines
5.8 KiB
C++
|
#include "SDLWindow.h"
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
#include <irrKlang.h>
|
||
|
|
||
|
// include console I/O methods (conio.h for windows, our wrapper in linux)
|
||
|
#if defined(WIN32)
|
||
|
#include <conio.h>
|
||
|
#else
|
||
|
#include "../common/conio.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#include "serial/serial.h"
|
||
|
|
||
|
|
||
|
constexpr char kWindowClassName[] = "Playsound";
|
||
|
constexpr char kWindowName[] = "Playsound";
|
||
|
|
||
|
SDLWindow::SDLWindow()
|
||
|
{
|
||
|
// 创建窗口
|
||
|
WNDCLASS wc = { 0 };
|
||
|
wc.lpfnWndProc = StaticWindowProcedure;
|
||
|
wc.hInstance = GetModuleHandle(NULL);
|
||
|
wc.lpszClassName = kWindowClassName;
|
||
|
RegisterClass(&wc);
|
||
|
|
||
|
hWnd = CreateWindow(wc.lpszClassName, kWindowName, 0, CW_USEDEFAULT, CW_USEDEFAULT,
|
||
|
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, wc.hInstance, (LPVOID)this);
|
||
|
}
|
||
|
|
||
|
SDLWindow::~SDLWindow()
|
||
|
{
|
||
|
// 移除托盘图标
|
||
|
Shell_NotifyIcon(NIM_DELETE, &trayIconData);
|
||
|
}
|
||
|
|
||
|
int32_t SDLWindow::Run()
|
||
|
{
|
||
|
// 创建托盘图标
|
||
|
CreateTrayIcon();
|
||
|
|
||
|
// 初始化SDL音频设备
|
||
|
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
|
||
|
std::cerr << "SDL initialization failed: " << SDL_GetError() << std::endl;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
SDL_AtomicSet(&Quit, 0);
|
||
|
|
||
|
SDL_zero(audioSpec);
|
||
|
audioSpec.freq = 44100;
|
||
|
audioSpec.format = AUDIO_S16SYS;
|
||
|
audioSpec.channels = 2;
|
||
|
audioSpec.samples = 4096;
|
||
|
audioSpec.callback = AudioCallback;
|
||
|
|
||
|
audioDeviceID = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
|
||
|
if (audioDeviceID == 0) {
|
||
|
std::cerr << "Failed to open audio device: " << SDL_GetError() << std::endl;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// 创建串口监听线程
|
||
|
HANDLE hSerialListenerThread = CreateThread(NULL, 0, SerialListenerThread, this, 0, NULL);
|
||
|
|
||
|
// 主消息循环
|
||
|
MSG msg;
|
||
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
|
||
|
// 等待串口监听线程结束
|
||
|
WaitForSingleObject(hSerialListenerThread, INFINITE);
|
||
|
CloseHandle(hSerialListenerThread);
|
||
|
|
||
|
// 停止音频设备
|
||
|
SDL_PauseAudioDevice(audioDeviceID, 1);
|
||
|
SDL_CloseAudioDevice(audioDeviceID);
|
||
|
SDL_Quit();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void SDLWindow::CreateTrayIcon()
|
||
|
{
|
||
|
ZeroMemory(&trayIconData, sizeof(NOTIFYICONDATA));
|
||
|
trayIconData.cbSize = sizeof(NOTIFYICONDATA);
|
||
|
trayIconData.hWnd = hWnd;
|
||
|
trayIconData.uID = TRAY_ICON_ID;
|
||
|
trayIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
|
||
|
trayIconData.uCallbackMessage = WM_TRAYICON;
|
||
|
trayIconData.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APPLICATION));
|
||
|
strcpy_s(trayIconData.szTip, sizeof(trayIconData.szTip), kWindowName);
|
||
|
|
||
|
Shell_NotifyIcon(NIM_ADD, &trayIconData);
|
||
|
}
|
||
|
|
||
|
void SDLWindow::QuitApplication()
|
||
|
{
|
||
|
// 在这里添加退出逻辑
|
||
|
SDL_AtomicSet(&Quit, 1);
|
||
|
|
||
|
// 终止应用程序消息循环
|
||
|
PostQuitMessage(0);
|
||
|
}
|
||
|
|
||
|
LRESULT SDLWindow::WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if (uMsg == WM_TRAYICON && wParam == TRAY_ICON_ID) {
|
||
|
if (lParam == WM_RBUTTONDOWN) {
|
||
|
// 创建右键退出菜单
|
||
|
HMENU hMenu = CreatePopupMenu();
|
||
|
AppendMenu(hMenu, MF_STRING, 1, "Exit");
|
||
|
|
||
|
// 获取鼠标位置
|
||
|
POINT pt;
|
||
|
GetCursorPos(&pt);
|
||
|
|
||
|
// 显示右键退出菜单
|
||
|
SetForegroundWindow(hWnd);
|
||
|
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hWnd, NULL);
|
||
|
|
||
|
// 销毁菜单
|
||
|
DestroyMenu(hMenu);
|
||
|
}
|
||
|
} else if (uMsg == WM_COMMAND && LOWORD(wParam) == 1) {
|
||
|
// 退出菜单被点击
|
||
|
QuitApplication();
|
||
|
}
|
||
|
|
||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
LRESULT CALLBACK SDLWindow::StaticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
SDLWindow* pWindow = nullptr;
|
||
|
|
||
|
if (uMsg == WM_NCCREATE) {
|
||
|
CREATESTRUCT* pCreateStruct = (CREATESTRUCT*)lParam;
|
||
|
pWindow = (SDLWindow*)pCreateStruct->lpCreateParams;
|
||
|
|
||
|
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pWindow);
|
||
|
} else {
|
||
|
pWindow = (SDLWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||
|
}
|
||
|
|
||
|
if (pWindow) {
|
||
|
return pWindow->WindowProcedure(hWnd, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
DWORD WINAPI SDLWindow::SerialListenerThread(LPVOID lpParam) {
|
||
|
SDLWindow* pWindow = (SDLWindow*)lpParam;
|
||
|
|
||
|
TCHAR path[MAX_PATH] = { 0 };
|
||
|
GetModuleFileName(NULL, path, sizeof(path));
|
||
|
std::string exeDir = path;
|
||
|
std::size_t pos = exeDir.find_last_of("\\/");
|
||
|
if (pos != std::string::npos) {
|
||
|
exeDir = exeDir.substr(0, pos);
|
||
|
}
|
||
|
|
||
|
const std::string configPath = exeDir + "\\playsound.ini";
|
||
|
const TCHAR* iniFile = configPath.c_str();
|
||
|
TCHAR section[] = TEXT("Settings");
|
||
|
|
||
|
TCHAR port[256];
|
||
|
DWORD code = GetPrivateProfileString(section, TEXT("port"), TEXT(""), port, sizeof(port), iniFile);
|
||
|
DWORD errorCode = GetLastError();
|
||
|
int baudrate = GetPrivateProfileInt(section, TEXT("baudrate"), 9600, iniFile);
|
||
|
uint32_t timeout = GetPrivateProfileInt(section, TEXT("timeout"), 1000, iniFile);
|
||
|
|
||
|
irrklang::ISoundEngine* soundEngine = irrklang::createIrrKlangDevice();
|
||
|
if (nullptr == soundEngine) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// 此处添加串口监听线程代码
|
||
|
serial::Serial serialPort(port, baudrate, serial::Timeout::simpleTimeout(timeout));
|
||
|
if (!serialPort.isOpen()) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
constexpr int32_t bufferSize = 1024;
|
||
|
while (0 == SDL_AtomicGet(&pWindow->Quit)) {
|
||
|
std::string result = serialPort.read(bufferSize);
|
||
|
if (result.empty()) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// 此处添加串口数据处理代码
|
||
|
|
||
|
//soundEngine->play2D()
|
||
|
const std::string mediaPath = exeDir + "\\media\\getout.ogg";
|
||
|
soundEngine->play2D(mediaPath.c_str());
|
||
|
}
|
||
|
|
||
|
soundEngine->drop();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void SDLWindow::AudioCallback(void* userdata, Uint8* stream, int len)
|
||
|
{
|
||
|
// 此处添加音频处理代码
|
||
|
}
|