Heres my whole source :
#include <Windows.h>
#include <vector>
#include <string>
#include <sstream>
#include <map>
#include "fmod.hpp"
#include <thread>
#include <iostream>
FMOD::System* system2;
FMOD::Sound* notehE;
FMOD::Sound* notehB;
FMOD::Sound* notehG;
FMOD::Sound* notehD;
FMOD::Sound* notehA;
FMOD::Sound* noteLE;
FMOD::Channel* channel1;
FMOD::Channel* channel2;
FMOD::Channel* channel3;
FMOD::Channel* channel4;
FMOD::Channel* channel5;
FMOD::Sound* currentNote;
FMOD::Sound* currentNote2;
FMOD::ChannelGroup* masterGroup = nullptr;
FMOD::DSP* dspPitchShift;
HWND hBackground;
HWND hOverlay;
HINSTANCE hInst;
float pitchMultiplier = 1;
float pitchMultiplier1 = 2;
float pitchMultiplier2 = 0;
const int PLAYBACK_TIMER_ID = 105; // Unique timer ID
int currentFret = 0; // Global variable to track the current fret being played
bool isPlaying = false;
const int IDplay1 = 301; // Unique identifier for the first play button
const int IDplay2 = 302;
const int IDplay3 = 310;
std::vector<std::vector<int>> harmony(6, std::vector<int>(16, -1));
int fretNumber;
std::wistringstream iss(input);
int bString = 1;
int gString = 2;
// Function to validate the fret input
std::vector<std::vector<int>> CalculateHarmony(const std::vector<std::vector<int>>& inputFretNumbers) {
// Map fret numbers on the high E string to the B string for the C Major scale
std::map<int, int> eToBMapping = {
{0, 1}, // E to C
{1, 3}, // F to D
{3, 5}, // G to E
{5, 6}, // A to F
{7, 8}, // B to G
{8, 10}, // C to A
{10, 12},// D to B
{12, 13}, // E c
{13, 15}, // F to D
{15, 17}, // G to E
{17, 18}, // A to F
{19, 20}, // B to G
{20, 22}, // C to A
{22, 24}// D to B
};
std::map<int, int> bToGMapping = {
{0, 0}, // b g
{1, 2}, // c a
{3, 4}, // d b
{5, 5}, // e c
{6, 7}, // f d
{8, 9}, // g e
{10, 10},// a f
{12, 12}, // b g
{13, 14}, // c a
{15, 16}, // d b
{17, 17}, // e c
{18, 19}, // f d
{20, 21}, // g e
{22, 22},// a f
{24, 24} // b g
};
std::map<int, int> gToDMapping = {
{0, 2}, // g e
{2, 3}, // a f
{4, 5}, // b g
{5, 7}, // c a
{7, 9}, // d b
{8, 10}, // e c
{10, 12},// f d
{12, 13}, // g e
{14, 15}, // a f
{16, 17}, // b g
{17, 19}, // c a
{19, 21}, // d b
{20, 22}, // e c
{22, 24}// f d
};
std::map<int, int> dToAMapping = {
{0, 2}, // d b
{2, 3}, // e c
{3, 5}, // f d
{5, 7}, // g e
{7, 8}, // a f
{9, 10}, // b g
{10, 12},// c a
{12, 14}, // d b
{14, 15}, // e c
{15, 17}, // f d
{17, 19}, // g e
{19, 20}, // a f
{21, 22}, // b g
{22, 24}// c a
};
std::map<int, int> aToEMapping = {
{0, 1}, // a f
{2, 3}, // b g
{3, 5}, // c a
{5, 7}, // d b
{7, 8}, // e c
{8, 10}, // f d
{10, 12},// g e
{12, 13}, // a f
{14, 15}, // b g
{15, 17}, // c a
{17, 19}, // d b
{19, 20}, // e c
{20, 22}, // f d
{22, 24}// g e
};
std::map<int, int> eToEMapping = {
{3, 0}, // g e
{5, 1}, // a f
{7, 3}, // b g
{8, 5}, // c a
{10, 7}, // d b
{12, 8}, // e c
{13, 10},// f d
{15, 12}, // g e
{17, 13}, // a f
{19, 15}, // b g
{20, 17}, // c a
{22, 19}, // d b
{24, 20} // e c
};
//std::vector<std::vector<int>> harmony(6, std::vector<int>(16, -1)); // Initialize with -1 for unplayed strings
// High E string is the 0th string in this context
for (int string = 0; string < 6; ++string) {
for (int fret = 0; fret < 16; ++fret) {
int inputFret = inputFretNumbers[string][fret];
std::map<int, int>* currentMapping = nullptr;
// Select the appropriate mapping based on the string
switch (string) {
case 0: currentMapping = &eToBMapping; break;
case 1: currentMapping = &bToGMapping; break;
case 2: currentMapping = &gToDMapping; break;
case 3: currentMapping = &dToAMapping; break;
case 4: currentMapping = &aToEMapping; break;
case 5: currentMapping = &eToEMapping; break;
// Add cases for other strings...
}
// Validate inputFret and apply mapping
if (inputFret >= 0 && currentMapping && currentMapping->find(inputFret) != currentMapping->end()) {
harmony[string][fret] = (*currentMapping)[inputFret];
}
}
}
return harmony;
}
HWND hwndInput[6][16]; // Input edit boxes (6 strings, 16 frets)
HWND hwndOutput[6][16]; // Output edit boxes (for displaying harmony notes)
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
const int fGrp = 4;
const int spaceG = 10;
InitializeFretboard();
FMOD::System_Create(&system2);
system2->init(1024, FMOD_INIT_NORMAL, 0);
system2->createSound("he.wav", FMOD_DEFAULT, 0, ¬ehE);
system2->createSound("b.wav", FMOD_DEFAULT, 0, ¬ehB);
system2->createSound("g.wav", FMOD_DEFAULT, 0, ¬ehG);
system2->createSound("d.wav", FMOD_DEFAULT, 0, ¬ehD);
system2->createSound("a.wav", FMOD_DEFAULT, 0, ¬ehA);
system2->createSound("lowE.wav", FMOD_DEFAULT, 0, ¬eLE);
for (int string = 0; string < 6; ++string)
{
for (int fret = 0; fret < 16; ++fret)
{
hwndInput[string][fret] = CreateWindowEx(0, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER, 20 + fret * 40, 20 + string * 20, 20, 20, hwnd, NULL, NULL, NULL);
hwndOutput[string][fret] = CreateWindowEx(0, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY, 20 + fret * 40, 300 + string * 20, 20, 20, hwnd, NULL, NULL, NULL);
}
}
CreateWindow(L"BUTTON", L"Generate", WS_CHILD | WS_VISIBLE, 20, 500, 80, 30, hwnd, (HMENU)IDOK, NULL, NULL);
CreateWindow(L"BUTTON", L"play #1", WS_CHILD | WS_VISIBLE, 670, 70, 80, 30, hwnd, (HMENU)IDplay1, NULL, NULL);
CreateWindow(L"BUTTON", L"play #2", WS_CHILD | WS_VISIBLE, 670, 350, 80, 30, hwnd, (HMENU)IDplay2, NULL, NULL);
CreateWindow(L"BUTTON", L"together", WS_CHILD | WS_VISIBLE, 100, 500, 80, 30, hwnd, (HMENU)IDplay3, NULL, NULL);
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HBITMAP hOverlay = static_cast<HBITMAP>(LoadImageW(nullptr, L"guitar1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
HBITMAP hBackground = static_cast<HBITMAP>(LoadImageW(nullptr, L"cMaj.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
// Create compatible DCs
BITMAP bmBackground, bmOverlay;
HDC hdcMemBackground = CreateCompatibleDC(hdc);
HDC hdcMemOverlay = CreateCompatibleDC(hdc);
GetObjectW(hBackground, sizeof(bmBackground), &bmBackground);
GetObjectW(hOverlay, sizeof(bmOverlay), &bmOverlay);
// Select the bitmaps into the DCs
SelectObject(hdcMemBackground, hBackground);
SelectObject(hdcMemOverlay, hOverlay);
// Get the dimensions of the bitmaps
// BITMAP bmBackground;
// GetObject(hBackground, sizeof(bmBackground), &bmBackground);
// Create a destination DC for displaying the final image
HDC hdcDest = CreateCompatibleDC(hdc);
HDC hdcDestGO = CreateCompatibleDC(hdc);
HBITMAP hFinalBitmap = CreateCompatibleBitmap(hdc, bmBackground.bmWidth, bmBackground.bmHeight);
HBITMAP hFinalBitmapGO = CreateCompatibleBitmap(hdc, bmOverlay.bmWidth, bmOverlay.bmHeight);
SelectObject(hdcDest, hFinalBitmap);
// HBITMAP hFinalBitmapGO = CreateCompatibleBitmap(hdc, bmOverlay.bmWidth, bmOverlay.bmHeight);
SelectObject(hdcDestGO, hFinalBitmapGO);
// Draw the background bitmap
// BitBlt(hdcDestGO, 0, 0, bmOverlay.bmWidth, bmOverlay.bmHeight, hdcMemBackground, 0, 0, SRCCOPY);
BitBlt(hdcDest, 0, 0, bmBackground.bmWidth, bmBackground.bmHeight, hdcMemBackground, 0, 0, SRCCOPY);
BitBlt(hdcDestGO, 0, 0, bmOverlay.bmWidth, bmOverlay.bmHeight, hdcMemOverlay, 0, 0, SRCCOPY);
BitBlt(hdcDestGO, 0, 0, bmOverlay.bmWidth, bmOverlay.bmHeight, hdcMemOverlay, 0, 0, SRCCOPY);
// Inside your game loop
// Draw the overlay bitmap on top of the background
// Display the final image
// HWND hWnd = CreateWindowEx(0, L"STATIC", nullptr, WS_VISIBLE | WS_POPUP, 0, 0, bmBackground.bmWidth, bmBackground.bmHeight, nullptr, nullptr, hInst, nullptr);
HDC hwndDC = GetDC(hwnd);
HDC hwndDCGO = GetDC(hwnd);
BitBlt(hwndDC, 0, 550, bmBackground.bmWidth, bmBackground.bmHeight, hdcDest, 0, 0, SRCCOPY);
BitBlt(hwndDCGO, 0, 0, bmOverlay.bmWidth, bmOverlay.bmHeight, hdcDestGO, 0, 0, SRCCOPY);
BitBlt(hwndDCGO, 0, 280, bmOverlay.bmWidth, bmOverlay.bmHeight, hdcDestGO, 0, 0, SRCCOPY);
// Clean up
DeleteDC(hdcDest);
DeleteDC(hdcDestGO);
DeleteObject(hFinalBitmap);
DeleteObject(hFinalBitmapGO);
DeleteDC(hdcMemBackground);
DeleteDC(hdcMemOverlay);
DeleteObject(hBackground);
DeleteObject(hOverlay);
ReleaseDC(hwnd, hwndDC);
ReleaseDC(hwnd, hwndDCGO);
ReleaseDC(nullptr, hdc);
EndPaint(hwnd, &ps);
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDM_C_MAJOR:
{
HMENU hSubMenu = GetSubMenu(GetMenu(hwnd), 0);
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STATE;
GetMenuItemInfo(hSubMenu, IDM_C_MAJOR, FALSE, &mii);
mii.fState = (mii.fState & MFS_CHECKED) ? MFS_UNCHECKED : MFS_CHECKED;
SetMenuItemInfo(hSubMenu, IDM_C_MAJOR, FALSE, &mii);
break;
}
case IDOK:
{
std::vector<std::vector<int>> inputFretNumbers(6, std::vector<int>(16, -1));
for (int fret = 0; fret < 16; ++fret)
{
WCHAR buffer[256];
GetWindowText(hwndInput[0][fret], buffer, 256);
std::wstring inputStr(buffer);
if (!ValidateFretInput(inputStr))
{
MessageBox(hwnd, L"Invalid input detected. Please enter fret numbers between 0 and 24.", L"Input Error", MB_ICONERROR);
return 0;
}
inputFretNumbers[0][fret] = inputStr.empty() ? -1 : _wtoi(buffer);
}
for (int fret = 0; fret < 16; ++fret)
{
WCHAR buffer[256];
GetWindowText(hwndInput[1][fret], buffer, 256);
std::wstring inputStr(buffer);
if (!ValidateFretInput(inputStr))
{
MessageBox(hwnd, L"Invalid input detected. Please enter fret numbers between 0 and 24.", L"Input Error", MB_ICONERROR);
return 0;
}
inputFretNumbers[1][fret] = inputStr.empty() ? -1 : _wtoi(buffer);
}
for (int fret = 0; fret < 16; ++fret)
{
WCHAR buffer[256];
GetWindowText(hwndInput[2][fret], buffer, 256);
std::wstring inputStr(buffer);
if (!ValidateFretInput(inputStr))
{
MessageBox(hwnd, L"Invalid input detected. Please enter fret numbers between 0 and 24.", L"Input Error", MB_ICONERROR);
return 0;
}
inputFretNumbers[2][fret] = inputStr.empty() ? -1 : _wtoi(buffer);
}
for (int fret = 0; fret < 16; ++fret)
{
WCHAR buffer[256];
GetWindowText(hwndInput[3][fret], buffer, 256);
std::wstring inputStr(buffer);
if (!ValidateFretInput(inputStr))
{
MessageBox(hwnd, L"Invalid input detected. Please enter fret numbers between 0 and 24.", L"Input Error", MB_ICONERROR);
return 0;
}
inputFretNumbers[3][fret] = inputStr.empty() ? -1 : _wtoi(buffer);
}
for (int fret = 0; fret < 16; ++fret)
{
WCHAR buffer[256];
GetWindowText(hwndInput[4][fret], buffer, 256);
std::wstring inputStr(buffer);
if (!ValidateFretInput(inputStr))
{
MessageBox(hwnd, L"Invalid input detected. Please enter fret numbers between 0 and 24.", L"Input Error", MB_ICONERROR);
return 0;
}
inputFretNumbers[4][fret] = inputStr.empty() ? -1 : _wtoi(buffer);
}
for (int fret = 0; fret < 16; ++fret)
{
WCHAR buffer[256];
GetWindowText(hwndInput[5][fret], buffer, 256);
std::wstring inputStr(buffer);
if (!ValidateFretInput(inputStr))
{
MessageBox(hwnd, L"Invalid input detected. Please enter fret numbers between 0 and 24.", L"Input Error", MB_ICONERROR);
return 0;
}
inputFretNumbers[5][fret] = inputStr.empty() ? -1 : _wtoi(buffer);
}
std::vector<std::vector<int>> harmony = CalculateHarmony(inputFretNumbers);
for (int fret = 0; fret < 16; ++fret)
{
if (harmony[0][fret] >= 0)
{
WCHAR buffer[10];
wsprintf(buffer, L"%d", harmony[0][fret]);
SetWindowText(hwndOutput[1][fret], buffer);
}
else
{
SetWindowText(hwndOutput[1][fret], L"");
}
}
for (int fret = 0; fret < 16; ++fret)
{
if (harmony[1][fret] >= 0)
{
WCHAR buffer[10];
wsprintf(buffer, L"%d", harmony[1][fret]);
SetWindowText(hwndOutput[2][fret], buffer);
}
else
{
SetWindowText(hwndOutput[2][fret], L"");
}
}
for (int fret = 0; fret < 16; ++fret)
{
if (harmony[2][fret] >= 0)
{
WCHAR buffer[10];
wsprintf(buffer, L"%d", harmony[2][fret]);
SetWindowText(hwndOutput[3][fret], buffer);
}
else
{
SetWindowText(hwndOutput[3][fret], L"");
}
}
for (int fret = 0; fret < 16; ++fret)
{
if (harmony[3][fret] >= 0)
{
WCHAR buffer[10];
wsprintf(buffer, L"%d", harmony[3][fret]);
SetWindowText(hwndOutput[4][fret], buffer);
}
else
{
SetWindowText(hwndOutput[4][fret], L"");
}
}
for (int fret = 0; fret < 16; ++fret)
{
if (harmony[4][fret] >= 0)
{
WCHAR buffer[10];
wsprintf(buffer, L"%d", harmony[4][fret]);
SetWindowText(hwndOutput[5][fret], buffer);
}
else if (harmony[5][fret] >= 0)
{
WCHAR buffer[10];
wsprintf(buffer, L"%d", harmony[5][fret]);
SetWindowText(hwndOutput[5][fret], buffer);
}
else
{
SetWindowText(hwndOutput[5][fret], L"");
}
}
break;
}
case IDplay1:
{
WCHAR buffer[256];
for (int fret = 0; fret < 16; ++fret)
{
system2->update(); // Move the update outside of the loop to ensure proper system handling
for (int stringIndex = 0; stringIndex < 6; ++stringIndex)
{
GetWindowText(hwndInput[stringIndex][fret], buffer, 256);
std::wstring inputStr(buffer);
if (!inputStr.empty())
{
int interval = _wtoi(buffer);
pitchMultiplier = std::pow(2.0f, static_cast<float>(interval) / 12.0f);
// Adjust the note based on the current string
FMOD::Sound* currentNote;
switch (stringIndex)
{
case 0: currentNote = notehE; break;
case 1: currentNote = notehB; break;
case 2: currentNote = notehG; break;
case 3: currentNote = notehD; break;
case 4: currentNote = notehA; break;
case 5: currentNote = noteLE; break;
default: currentNote = noteLE; break;
// Default to high E if an invalid stringIndex is provided
}
system2->playSound(currentNote, nullptr, false, &channel1);
channel1->setPitch(pitchMultiplier);
Sleep(500); // Adjust the delay as needed
}
}
}
break;
}
case IDplay3:
{
/*
WCHAR buffer[256], buffer2[256];
unsigned long long dspclock_start, dspclock_end;
// Initial DSP Clock retrieval
unsigned long long initialDSPClock, currentDSPClock;
system2->getMasterChannelGroup(&masterGroup);
masterGroup->getDSPClock(¤tDSPClock, &initialDSPClock);
unsigned long long delayTicksPerSecond = 48000; // 48 kHz
unsigned long long noteDurationTicks = delayTicksPerSecond * 1; // 1 second note duration
for (int fret = 0; fret < 16; ++fret)
{
for (int stringIndex = 0; stringIndex < 6; ++stringIndex)
{
dspclock_start = initialDSPClock + (fret * 6 + stringIndex) * noteDurationTicks;
dspclock_end = dspclock_start + noteDurationTicks;
// Schedule and play the first set of notes
GetWindowText(hwndInput[stringIndex][fret], buffer, 256);
if (!std::wstring(buffer).empty())
{
switch (stringIndex)
{
case 0: currentNote = notehE; break;
case 1: currentNote = notehB; break;
case 2: currentNote = notehG; break;
case 3: currentNote = notehD; break;
case 4: currentNote = notehA; break;
case 5: currentNote = noteLE; break;
default: currentNote = noteLE; break;
// Default to high E if an invalid stringIndex is provided
}
system2->playSound(currentNote, nullptr, true, &channel1);
channel1->setPitch(pitchMultiplier);
channel1->setDelay( dspclock_start, dspclock_end, true);
channel1->setPaused(false);
}
// Schedule and play the second set of notes
GetWindowText(hwndOutput[stringIndex][fret], buffer2, 256);
if (!std::wstring(buffer2).empty())
{
switch (stringIndex)
{
case 0: currentNote2 = notehE; break;
case 1: currentNote2 = notehB; break;
case 2: currentNote2 = notehG; break;
case 3: currentNote2 = notehD; break;
case 4: currentNote2 = notehA; break;
case 5: currentNote2 = noteLE; break;
default: currentNote2 = noteLE; break;
// Default to high E if an invalid stringIndex is provided
}
system2->playSound(currentNote2, nullptr, true, &channel2);
channel2->setPitch(pitchMultiplier2);
channel2->setDelay(dspclock_start, dspclock_end, true);
channel2->setPaused(false);
}
}
}
*/
unsigned long long dspClockStart, dspClockEnd;
unsigned long long delayBetweenPlays = 48000 * 2; // 2 seconds delay in ticks, assuming a sample rate of 48 kHz
unsigned long long playDuration = 48000; // Duration of the sound to play, assuming it lasts for 1 second
// Retrieve the initial DSP clock values
unsigned long long initialDSPClock, currentDSPClock;
system2->getMasterChannelGroup(&masterGroup);
masterGroup->getDSPClock(¤tDSPClock, &initialDSPClock);
// Play the sound 5 times every 2 seconds
for (int i = 0; i < 5; ++i)
{
// Calculate the DSP clock start time for the current iteration
dspClockStart = initialDSPClock + i * delayBetweenPlays;
// Calculate the end time, assuming the note plays for its entire duration
dspClockEnd = dspClockStart + playDuration;
// system2->update();
FMOD_RESULT result = system2->playSound(notehE, nullptr, true, &channel1);
channel1->setPitch(pitchMultiplier);
FMOD_RESULT result2 = system2->playSound(notehB, nullptr, true, &channel2);
// system2->update();
// channel2->setPitch(pitchMultiplier2);
// system2->update();
if (result == FMOD_OK && result2 == FMOD_OK) {
// Set the channel to start and end at the specific times calculated
channel1->setDelay(dspClockStart, dspClockEnd, false);
channel2->setDelay(dspClockStart, dspClockEnd, false);
// Unpause the channel to start playing
channel1->setPaused(false);
channel2->setPaused(false);
}
else {
// Handle error
std::cerr << "Failed to play sound: " << result << std::endl;
}
// Note: In a real application, you would not usually use a loop like this to schedule future plays
// because it assumes the play duration and does not dynamically adjust for the actual duration of the sound.
// Additionally, FMOD manages timing and playback internally, and looping like this without delays or
// synchronization primitives can lead to unpredictable results.
}
// Update FMOD system regularly to process sound playback
break;
}
case IDplay2:
{
WCHAR buffer[256];
for (int fret = 0; fret < 16; ++fret)
{
system2->update(); // Move the update outside of the loop to ensure proper system handling
for (int stringIndex = 0; stringIndex < 6; ++stringIndex)
{
GetWindowText(hwndOutput[stringIndex][fret], buffer, 256);
std::wstring inputStr(buffer);
if (!inputStr.empty())
{
int interval = _wtoi(buffer);
pitchMultiplier = std::pow(2.0f, static_cast<float>(interval) / 12.0f);
// Adjust the note based on the current string
FMOD::Sound* currentNote;
switch (stringIndex)
{
case 0: currentNote = notehE; break;
case 1: currentNote = notehB; break;
case 2: currentNote = notehG; break;
case 3: currentNote = notehD; break;
case 4: currentNote = notehA; break;
case 5: currentNote = noteLE; break;
default: currentNote = noteLE; break;
// Default to high E if an invalid stringIndex is provided
}
system2->playSound(currentNote, nullptr, false, &channel1);
channel1->setPitch(pitchMultiplier);
Sleep(500); // Adjust the delay as needed
}
}
}
}
}
break;
}
/*
case WM_TIMER:
{
if (wParam == PLAYBACK_TIMER_ID && isPlaying)
{
if (currentFret < 16)
{
WCHAR bufferE[256], bufferB[256];
GetWindowText(hwndInput[0][currentFret], bufferE, 256);
GetWindowText(hwndOutput[bString][currentFret], bufferB, 256);
if (std::wstring(bufferE) != L"")
{
int intervalE = _wtoi(bufferE);
float pitchMultiplierE = std::pow(2.0f, static_cast<float>(intervalE) / 12.0f);
system2->playSound(notehE, nullptr, false, &channel1);
channel1->setPitch(pitchMultiplierE);
}
if (std::wstring(bufferB) != L"")
{
int intervalB = _wtoi(bufferB);
float pitchMultiplierB = std::pow(2.0f, static_cast<float>(intervalB) / 12.0f);
system2->playSound(notehB, nullptr, false, &channel2);
channel2->setPitch(pitchMultiplierB);
}
currentFret++;
}
else
{
isPlaying = false;
KillTimer(hwnd, PLAYBACK_TIMER_ID);
}
}
break;
}
*/
case WM_DESTROY:
{
if (masterGroup) {
masterGroup->release();
}
notehE->release();
notehB->release();
notehG->release();
notehD->release();
notehA->release();
noteLE->release();
system2->close();
system2->release();
PostQuitMessage(0);
break;
}
default:
{
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
return 0;
}
// ... [Rest of your code]
// ... [Earlier parts of your code, including global variables and function definitions]
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Register window class
WNDCLASSEX wc = {};
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = L"ScaleHarmonyApp";
if (!RegisterClassEx(&wc)) {
MessageBox(nullptr, L"Window Registration Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hInst = hInstance;
// Create main window
HWND hwnd = CreateWindowEx(
0,
L"ScaleHarmonyApp",
L"Scale Harmony Calculator",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 900,
nullptr, nullptr, hInstance, nullptr
);
if (hwnd == nullptr) {
MessageBox(nullptr, L"Window Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Show and update the main window
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Initialize the fretboard
// Create the menu
HMENU hMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();
// Add the "Key" menu item and its submenu
AppendMenu(hMenu, MF_STRING | MF_POPUP, reinterpret_cast<UINT_PTR>(hSubMenu), L"Key");
AppendMenu(hSubMenu, MF_STRING | MF_CHECKED, IDM_C_MAJOR, L"C Major");
// Set the menu to the window
SetMenu(hwnd, hMenu);
// Message loop
MSG msg = {};
while (GetMessage(&msg, nullptr, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return static_cast<int>(msg.wParam);
}