Add window support for Windows.
This commit is contained in:
parent
5d32592126
commit
c05b7b6315
27 changed files with 783 additions and 95 deletions
|
@ -2,72 +2,66 @@
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "MainApplication.h"
|
||||||
|
#include "GuiApplication.h"
|
||||||
|
#include "CommandLineArgs.h"
|
||||||
|
#include "Win32WindowInterface.h"
|
||||||
|
#include "FileLogger.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
|
||||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
void initializeCommandLineArgs(CommandLineArgs* args)
|
||||||
|
{
|
||||||
|
int nArgs{ 0 };
|
||||||
|
auto szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
|
||||||
|
if (szArglist == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> windowsArgs(nArgs);
|
||||||
|
for (int idx = 0; idx < nArgs; idx++)
|
||||||
|
{
|
||||||
|
windowsArgs[idx] = StringUtils::convert(szArglist[idx]);
|
||||||
|
}
|
||||||
|
LocalFree(szArglist);
|
||||||
|
|
||||||
|
args->Process(windowsArgs);
|
||||||
|
}
|
||||||
|
|
||||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
|
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
// Register the window class.
|
std::ofstream out("out.txt");
|
||||||
const wchar_t CLASS_NAME[] = L"Sample Window Class";
|
std::cout.rdbuf(out.rdbuf());
|
||||||
|
|
||||||
WNDCLASS wc = { };
|
auto args = CommandLineArgs::CreateUnique();
|
||||||
|
initializeCommandLineArgs(args.get());
|
||||||
|
args->RecordLaunchPath();
|
||||||
|
|
||||||
wc.lpfnWndProc = WindowProc;
|
// Start the main app
|
||||||
wc.hInstance = hInstance;
|
auto main_app = MainApplication::Create();
|
||||||
wc.lpszClassName = CLASS_NAME;
|
|
||||||
|
|
||||||
RegisterClass(&wc);
|
auto applicationContext = std::make_unique<Win32ApplicationContext>();
|
||||||
|
applicationContext->hInstance = reinterpret_cast<void*>(hInstance);
|
||||||
|
applicationContext->nCmdShow = nCmdShow;
|
||||||
|
|
||||||
HWND hwnd = CreateWindowEx(
|
main_app->Initialize(std::move(args), std::move(applicationContext));
|
||||||
0, // Optional window styles.
|
|
||||||
CLASS_NAME, // Window class
|
|
||||||
L"Learn to Program Windows", // Window text
|
|
||||||
WS_OVERLAPPEDWINDOW, // Window style
|
|
||||||
|
|
||||||
// Size and position
|
MLOG_INFO("Creating GUI Application");
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
||||||
|
|
||||||
NULL, // Parent window
|
// Start the gui application
|
||||||
NULL, // Menu
|
auto gui_app = GuiApplication();
|
||||||
hInstance, // Instance handle
|
gui_app.SetMainApplication(main_app);
|
||||||
NULL // Additional application data
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hwnd == NULL)
|
MLOG_INFO("Running GUI Application");
|
||||||
{
|
gui_app.Run();
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ShowWindow(hwnd, nCmdShow);
|
|
||||||
|
|
||||||
// Run the message loop.
|
main_app->ShutDown();
|
||||||
MSG msg = { };
|
|
||||||
while (GetMessage(&msg, NULL, 0, 0))
|
|
||||||
{
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch (uMsg)
|
|
||||||
{
|
|
||||||
case WM_DESTROY:
|
|
||||||
PostQuitMessage(0);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case WM_PAINT:
|
|
||||||
{
|
|
||||||
PAINTSTRUCT ps;
|
|
||||||
HDC hdc = BeginPaint(hwnd, &ps);
|
|
||||||
|
|
||||||
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
|
|
||||||
|
|
||||||
EndPaint(hwnd, &ps);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
||||||
}
|
|
|
@ -3,17 +3,24 @@ set(platform_HEADERS "")
|
||||||
set(platform_INCLUDES "")
|
set(platform_INCLUDES "")
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
find_package(ALSA REQUIRED)
|
find_package(ALSA REQUIRED)
|
||||||
list(APPEND platform_HEADERS
|
list(APPEND platform_HEADERS
|
||||||
audio_interfaces/AlsaInterface.h
|
audio_interfaces/AlsaInterface.h
|
||||||
${ALSA_INCLUDE_DIRS}
|
${ALSA_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
list(APPEND platform_INCLUDES
|
list(APPEND platform_INCLUDES
|
||||||
audio_interfaces/AlsaInterface.cpp
|
audio_interfaces/AlsaInterface.cpp
|
||||||
)
|
)
|
||||||
list(APPEND platform_LIBS
|
list(APPEND platform_LIBS
|
||||||
${ALSA_LIBRARIES}
|
${ALSA_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
list(APPEND platform_HEADERS
|
||||||
|
audio_interfaces/WasapiInterface.h
|
||||||
|
)
|
||||||
|
list(APPEND platform_INCLUDES
|
||||||
|
audio_interfaces/WasapiInterface.cpp
|
||||||
|
)
|
||||||
endif (UNIX)
|
endif (UNIX)
|
||||||
|
|
||||||
list(APPEND audio_HEADERS
|
list(APPEND audio_HEADERS
|
||||||
|
|
207
src/audio/audio_interfaces/WasapiInterface.cpp
Normal file
207
src/audio/audio_interfaces/WasapiInterface.cpp
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
#include "WasapiInterface.h"
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
#include "AudioSynth.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Audioclient.h>
|
||||||
|
#include <mmdeviceapi.h>
|
||||||
|
#include <Functiondiscoverykeys_devpkey.h>
|
||||||
|
|
||||||
|
WasapiInterface::WasapiInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WasapiInterface::~WasapiInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<WasapiInterface> WasapiInterface::Create()
|
||||||
|
{
|
||||||
|
return std::make_unique<WasapiInterface>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WasapiInterface::OpenDevice(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WasapiInterface::SetAccessType(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WasapiInterface::SetSampleFormat(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WasapiInterface::SetSampleRate(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WasapiInterface::SetPeriod(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WasapiInterface::SetBufferSize(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void WasapiInterface::SetChannelNumber(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// REFERENCE_TIME time units per second and per millisecond
|
||||||
|
#define REFTIMES_PER_SEC 10000000
|
||||||
|
#define REFTIMES_PER_MILLISEC 10000
|
||||||
|
|
||||||
|
#define EXIT_ON_ERROR(hres) \
|
||||||
|
if (FAILED(hres)) { goto Exit; }
|
||||||
|
#define SAFE_RELEASE(punk) \
|
||||||
|
if ((punk) != NULL) \
|
||||||
|
{ (punk)->Release(); (punk) = NULL; }
|
||||||
|
|
||||||
|
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
|
||||||
|
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
|
||||||
|
const IID IID_IAudioClient = __uuidof(IAudioClient);
|
||||||
|
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
|
||||||
|
|
||||||
|
void WasapiInterface::Play(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
std::cout << "Into wasapi play" << std::endl;
|
||||||
|
IMMDeviceEnumerator* pEnumerator = nullptr;
|
||||||
|
auto hr = CoCreateInstance(CLSID_MMDeviceEnumerator,
|
||||||
|
nullptr,
|
||||||
|
CLSCTX_ALL,
|
||||||
|
IID_IMMDeviceEnumerator,
|
||||||
|
(void**)&pEnumerator);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
std::cout << "Failed to create enumerator" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMMDevice* pDevice = nullptr;
|
||||||
|
hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << "Got default endpoint" << std::endl;
|
||||||
|
|
||||||
|
IPropertyStore* pPropertyStore{ nullptr };
|
||||||
|
hr = pDevice->OpenPropertyStore(STGM_READ, &pPropertyStore);
|
||||||
|
|
||||||
|
DWORD propCount{ 0 };
|
||||||
|
pPropertyStore->GetCount(&propCount);
|
||||||
|
|
||||||
|
PROPVARIANT deviceName;
|
||||||
|
PropVariantInit(&deviceName);
|
||||||
|
// hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &deviceName);
|
||||||
|
hr = pPropertyStore->GetValue(PKEY_DeviceInterface_FriendlyName, &deviceName);
|
||||||
|
//PKEY_Device_FriendlyName
|
||||||
|
std::cout << "Device name: " << deviceName.pwszVal << std::endl;
|
||||||
|
|
||||||
|
pPropertyStore->Release();
|
||||||
|
|
||||||
|
|
||||||
|
IAudioClient* pAudioClient = nullptr;
|
||||||
|
hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, (void**)&pAudioClient);
|
||||||
|
std::cout << "Activated audio device" << std::endl;
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WAVEFORMATEX* pwfx = nullptr;
|
||||||
|
hr = pAudioClient->GetMixFormat(&pwfx);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << "formatTag: " << pwfx->wFormatTag << std::endl;
|
||||||
|
std::cout << "nChannels: " << pwfx->nChannels << std::endl;
|
||||||
|
std::cout << "nSamplesPerSec: " << pwfx->nSamplesPerSec << std::endl;
|
||||||
|
std::cout << "nAvgBytesPerSec: " << pwfx->nAvgBytesPerSec << std::endl; // nSamplesPerSec*nBlockAlign
|
||||||
|
std::cout << "nBlockAlign: " << pwfx->nBlockAlign << std::endl; //nChannels *wBitsPerSample/8 (bytes)
|
||||||
|
std::cout << "wBitsPerSample: " << pwfx->wBitsPerSample << std::endl;
|
||||||
|
std::cout << "cbSize: " << pwfx->cbSize << std::endl;
|
||||||
|
|
||||||
|
//REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
|
||||||
|
//hr = pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0,
|
||||||
|
// hnsRequestedDuration,
|
||||||
|
// 0, pwfx, nullptr);
|
||||||
|
//if (FAILED(hr))
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// Tell the audio source which format to use.
|
||||||
|
//// hr = pMySource->SetFormat(pwfx);
|
||||||
|
|
||||||
|
//// Get the actual size of the allocated buffer.
|
||||||
|
//UINT32 bufferFrameCount;
|
||||||
|
//hr = pAudioClient->GetBufferSize(&bufferFrameCount);
|
||||||
|
|
||||||
|
//IAudioRenderClient* pRenderClient = nullptr;
|
||||||
|
//hr = pAudioClient->GetService(IID_IAudioRenderClient, (void**)&pRenderClient);
|
||||||
|
|
||||||
|
//// Grab the entire buffer for the initial fill operation.
|
||||||
|
//BYTE* pData;
|
||||||
|
//hr = pRenderClient->GetBuffer(bufferFrameCount, &pData);
|
||||||
|
|
||||||
|
//// Load the initial data into the shared buffer.
|
||||||
|
//DWORD flags = 0;
|
||||||
|
//// hr = pMySource->LoadData(bufferFrameCount, pData, &flags);
|
||||||
|
|
||||||
|
//hr = pRenderClient->ReleaseBuffer(bufferFrameCount, flags);
|
||||||
|
|
||||||
|
//// Calculate the actual duration of the allocated buffer.
|
||||||
|
//auto hnsActualDuration = (double)REFTIMES_PER_SEC * bufferFrameCount / pwfx->nSamplesPerSec;
|
||||||
|
|
||||||
|
//hr = pAudioClient->Start(); // Start playing.
|
||||||
|
|
||||||
|
//// Each loop fills about half of the shared buffer.
|
||||||
|
//while (flags != AUDCLNT_BUFFERFLAGS_SILENT)
|
||||||
|
//{
|
||||||
|
// // Sleep for half the buffer duration.
|
||||||
|
// Sleep((DWORD)(hnsActualDuration / REFTIMES_PER_MILLISEC / 2));
|
||||||
|
|
||||||
|
// // See how much buffer space is available.
|
||||||
|
// UINT32 numFramesPadding;
|
||||||
|
// hr = pAudioClient->GetCurrentPadding(&numFramesPadding);
|
||||||
|
|
||||||
|
// auto numFramesAvailable = bufferFrameCount - numFramesPadding;
|
||||||
|
|
||||||
|
// // Grab all the available space in the shared buffer.
|
||||||
|
// hr = pRenderClient->GetBuffer(numFramesAvailable, &pData);
|
||||||
|
|
||||||
|
// // Get next 1/2-second of data from the audio source.
|
||||||
|
// // hr = pMySource->LoadData(numFramesAvailable, pData, &flags);
|
||||||
|
|
||||||
|
// hr = pRenderClient->ReleaseBuffer(numFramesAvailable, flags);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// Wait for last data in buffer to play before stopping.
|
||||||
|
//Sleep((DWORD)(hnsActualDuration / REFTIMES_PER_MILLISEC / 2));
|
||||||
|
|
||||||
|
//hr = pAudioClient->Stop(); // Stop playing.
|
||||||
|
|
||||||
|
//CoTaskMemFree(pwfx);
|
||||||
|
//SAFE_RELEASE(pEnumerator)
|
||||||
|
//SAFE_RELEASE(pDevice)
|
||||||
|
//SAFE_RELEASE(pAudioClient)
|
||||||
|
//SAFE_RELEASE(pRenderClient)
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
36
src/audio/audio_interfaces/WasapiInterface.h
Normal file
36
src/audio/audio_interfaces/WasapiInterface.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IAudioInterface.h"
|
||||||
|
#include "AudioDevice.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class WasapiInterface : public IAudioInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WasapiInterface();
|
||||||
|
|
||||||
|
~WasapiInterface();
|
||||||
|
|
||||||
|
static std::unique_ptr<WasapiInterface> Create();
|
||||||
|
|
||||||
|
void OpenDevice(const AudioDevicePtr& device) override;
|
||||||
|
|
||||||
|
void SetAccessType(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetSampleFormat(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetSampleRate(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetPeriod(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetBufferSize(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetChannelNumber(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void Play(const AudioDevicePtr& device) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
using AlsaInterfacePtr = std::shared_ptr<WasapiInterface>;
|
|
@ -1,8 +1,12 @@
|
||||||
#include "GuiApplication.h"
|
#include "GuiApplication.h"
|
||||||
|
|
||||||
#include "Widget.h"
|
#include "Widget.h"
|
||||||
|
#ifdef __linux__
|
||||||
#include "XcbInterface.h"
|
#include "XcbInterface.h"
|
||||||
#include "XcbKeyboard.h"
|
#include "XcbKeyboard.h"
|
||||||
|
#else
|
||||||
|
#include "Win32UiInterface.h"
|
||||||
|
#endif
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "TextElement.h"
|
#include "TextElement.h"
|
||||||
#include "WindowManager.h"
|
#include "WindowManager.h"
|
||||||
|
@ -14,6 +18,7 @@
|
||||||
#include "TopBar.h"
|
#include "TopBar.h"
|
||||||
#include "StatusBar.h"
|
#include "StatusBar.h"
|
||||||
#include "HorizontalSpacer.h"
|
#include "HorizontalSpacer.h"
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -33,6 +38,7 @@ GuiApplication::~GuiApplication()
|
||||||
void GuiApplication::SetMainApplication(MainApplicationPtr app)
|
void GuiApplication::SetMainApplication(MainApplicationPtr app)
|
||||||
{
|
{
|
||||||
mMainApplication = app;
|
mMainApplication = app;
|
||||||
|
mDesktopManager->SetMainApp(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiApplication::SetUpWidget()
|
void GuiApplication::SetUpWidget()
|
||||||
|
@ -75,6 +81,7 @@ void GuiApplication::Run()
|
||||||
auto mainWindow = mDesktopManager->GetWindowManager()->GetMainWindow();
|
auto mainWindow = mDesktopManager->GetWindowManager()->GetMainWindow();
|
||||||
SetUpWidget();
|
SetUpWidget();
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
mDesktopManager->SetKeyboard(XcbKeyboard::Create());
|
mDesktopManager->SetKeyboard(XcbKeyboard::Create());
|
||||||
|
|
||||||
bool useOpenGl = true;
|
bool useOpenGl = true;
|
||||||
|
@ -89,4 +96,17 @@ void GuiApplication::Run()
|
||||||
}
|
}
|
||||||
window_interface.Loop(mDesktopManager.get());
|
window_interface.Loop(mDesktopManager.get());
|
||||||
window_interface.ShutDown();
|
window_interface.ShutDown();
|
||||||
|
#else
|
||||||
|
mDesktopManager->SetKeyboard(Keyboard::Create());
|
||||||
|
|
||||||
|
MLOG_INFO("Creating Window Interface");
|
||||||
|
Win32UIInterface window_interface;
|
||||||
|
window_interface.AddWindow(mainWindow, mDesktopManager.get());
|
||||||
|
|
||||||
|
window_interface.ShowWindow(mainWindow);
|
||||||
|
|
||||||
|
window_interface.Loop(mDesktopManager.get());
|
||||||
|
window_interface.ShutDown();
|
||||||
|
MLOG_INFO("Window Interface Shut Down");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,13 @@ MainApplication::~MainApplication()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainApplication::Initialize(CommandLineArgsUPtr commandLineArgs)
|
void MainApplication::Initialize(CommandLineArgsUPtr commandLineArgs, std::unique_ptr<IApplicationContext> applicationContext)
|
||||||
{
|
{
|
||||||
|
if (applicationContext)
|
||||||
|
{
|
||||||
|
mApplicationContext = std::move(applicationContext);
|
||||||
|
}
|
||||||
|
|
||||||
mCommandLineArgs = std::move(commandLineArgs);
|
mCommandLineArgs = std::move(commandLineArgs);
|
||||||
const auto launch_path = mCommandLineArgs->GetLaunchPath().string();
|
const auto launch_path = mCommandLineArgs->GetLaunchPath().string();
|
||||||
|
|
||||||
|
@ -34,10 +39,13 @@ void MainApplication::Initialize(CommandLineArgsUPtr commandLineArgs)
|
||||||
|
|
||||||
mDatabaseManager = DatabaseManager::Create();
|
mDatabaseManager = DatabaseManager::Create();
|
||||||
mDatabaseManager->CreateDatabase(launch_path + "/database.db");
|
mDatabaseManager->CreateDatabase(launch_path + "/database.db");
|
||||||
|
MLOG_INFO("Created DB");
|
||||||
|
|
||||||
mNetworkManager = NetworkManager::Create();
|
mNetworkManager = NetworkManager::Create();
|
||||||
|
MLOG_INFO("Created Network Manager");
|
||||||
|
|
||||||
mAudioManager = AudioManager::Create();
|
mAudioManager = AudioManager::Create();
|
||||||
|
MLOG_INFO("Created Audio Manager");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainApplication::Run()
|
void MainApplication::Run()
|
||||||
|
|
|
@ -3,28 +3,22 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include "AbstractApp.h"
|
||||||
#include "AudioManager.h"
|
#include "AudioManager.h"
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
#include "DatabaseManager.h"
|
#include "DatabaseManager.h"
|
||||||
#include "NetworkManager.h"
|
#include "NetworkManager.h"
|
||||||
#include "CommandLineArgs.h"
|
#include "CommandLineArgs.h"
|
||||||
|
|
||||||
class MainApplication
|
class MainApplication : public AbstractApp
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
|
|
||||||
CommandLineArgsUPtr mCommandLineArgs;
|
|
||||||
DatabaseManagerPtr mDatabaseManager;
|
|
||||||
NetworkManagerUPtr mNetworkManager;
|
|
||||||
AudioManagerUPtr mAudioManager;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MainApplication();
|
MainApplication();
|
||||||
|
|
||||||
~MainApplication();
|
~MainApplication();
|
||||||
|
|
||||||
void Initialize(CommandLineArgsUPtr commandLineArgs);
|
void Initialize(CommandLineArgsUPtr commandLineArgs, std::unique_ptr<IApplicationContext> applicationContext=nullptr);
|
||||||
|
|
||||||
void Run();
|
void Run();
|
||||||
|
|
||||||
|
@ -40,6 +34,11 @@ private:
|
||||||
void PlayAudio();
|
void PlayAudio();
|
||||||
|
|
||||||
void ConvertDocument(const std::string& inputPath, const std::string& outputPath);
|
void ConvertDocument(const std::string& inputPath, const std::string& outputPath);
|
||||||
|
|
||||||
|
CommandLineArgsUPtr mCommandLineArgs;
|
||||||
|
DatabaseManagerPtr mDatabaseManager;
|
||||||
|
NetworkManagerUPtr mNetworkManager;
|
||||||
|
AudioManagerUPtr mAudioManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
using MainApplicationPtr = std::shared_ptr<MainApplication>;
|
using MainApplicationPtr = std::shared_ptr<MainApplication>;
|
||||||
|
|
26
src/core/AbstractApp.h
Normal file
26
src/core/AbstractApp.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class IApplicationContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IApplicationContext() = default;
|
||||||
|
virtual ~IApplicationContext() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AbstractApp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AbstractApp() = default;
|
||||||
|
|
||||||
|
virtual ~AbstractApp() = default;
|
||||||
|
IApplicationContext* GetApplicationContext() const
|
||||||
|
{
|
||||||
|
return mApplicationContext.get();
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<IApplicationContext> mApplicationContext{ nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
using AbstractAppPtr = std::unique_ptr<AbstractApp>;
|
|
@ -1,4 +1,5 @@
|
||||||
list(APPEND core_HEADERS
|
list(APPEND core_HEADERS
|
||||||
|
AbstractApp.h
|
||||||
Event.h
|
Event.h
|
||||||
Color.h
|
Color.h
|
||||||
CommandLineArgs.h
|
CommandLineArgs.h
|
||||||
|
|
|
@ -30,6 +30,11 @@ void CommandLineArgs::Process(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandLineArgs::Process(const std::vector<std::string>& args)
|
||||||
|
{
|
||||||
|
mArugments = args;
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t CommandLineArgs::GetNumberOfArgs() const
|
std::size_t CommandLineArgs::GetNumberOfArgs() const
|
||||||
{
|
{
|
||||||
return mArugments.size();
|
return mArugments.size();
|
||||||
|
|
|
@ -21,6 +21,8 @@ public:
|
||||||
|
|
||||||
void Process(int argc, char *argv[]);
|
void Process(int argc, char *argv[]);
|
||||||
|
|
||||||
|
void Process(const std::vector<std::string>& args);
|
||||||
|
|
||||||
std::size_t GetNumberOfArgs() const;
|
std::size_t GetNumberOfArgs() const;
|
||||||
|
|
||||||
std::string GetArg(std::size_t index) const;
|
std::string GetArg(std::size_t index) const;
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "Windows.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
bool StringUtils::IsAlphaNumeric(char c)
|
bool StringUtils::IsAlphaNumeric(char c)
|
||||||
{
|
{
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
|
@ -21,3 +25,23 @@ std::string StringUtils::ToLower(const std::string& s)
|
||||||
[](unsigned char c){ return std::tolower(c); });
|
[](unsigned char c){ return std::tolower(c); });
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string StringUtils::convert(const std::wstring& input)
|
||||||
|
{
|
||||||
|
if (input.empty())
|
||||||
|
{
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
const auto size = ::WideCharToMultiByte(CP_UTF8, 0, &input[0],
|
||||||
|
(int)input.size(), nullptr, 0, nullptr, nullptr);
|
||||||
|
|
||||||
|
std::string result(size, 0);
|
||||||
|
::WideCharToMultiByte(CP_UTF8, 0, &input[0], (int)input.size(),
|
||||||
|
&result[0], size, nullptr, nullptr);
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
throw std::logic_error("Not implemented");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -17,4 +17,5 @@ public:
|
||||||
static bool IsAlphaNumeric(char c);
|
static bool IsAlphaNumeric(char c);
|
||||||
static bool IsSpace(char c);
|
static bool IsSpace(char c);
|
||||||
static std::string ToLower(const std::string& s);
|
static std::string ToLower(const std::string& s);
|
||||||
|
static std::string convert(const std::wstring& input);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
FileLogger::~FileLogger()
|
FileLogger::~FileLogger()
|
||||||
{
|
{
|
||||||
|
@ -28,12 +28,12 @@ void FileLogger::Close()
|
||||||
mFileStream.close();
|
mFileStream.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileLogger::LogLine(const std::string& line)
|
void FileLogger::LogLine(const std::ostringstream& line)
|
||||||
{
|
{
|
||||||
mFileStream << line << std::endl;
|
mFileStream << line.str() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileLogger::LogLine(const std::string& logType, const std::string& line, const std::string& fileName, const std::string& functionName, int lineNumber)
|
void FileLogger::LogLine(const std::string& logType, const std::ostringstream& line, const std::string& fileName, const std::string& functionName, int lineNumber)
|
||||||
{
|
{
|
||||||
std::time_t t = std::time(nullptr);
|
std::time_t t = std::time(nullptr);
|
||||||
const std::string cleanedFileName = fileName.substr(fileName.find_last_of("/\\") + 1);
|
const std::string cleanedFileName = fileName.substr(fileName.find_last_of("/\\") + 1);
|
||||||
|
@ -43,5 +43,6 @@ void FileLogger::LogLine(const std::string& logType, const std::string& line, co
|
||||||
#else
|
#else
|
||||||
gmtime_r(&t, &time_buf);
|
gmtime_r(&t, &time_buf);
|
||||||
#endif
|
#endif
|
||||||
mFileStream << logType << "|" << std::put_time(&time_buf, "%T") << "|" << cleanedFileName << "::" << functionName << "::" << lineNumber << "|" << line << std::endl;
|
std::cout << logType << "|" << std::put_time(&time_buf, "%T") << "|" << cleanedFileName << "::" << functionName << "::" << lineNumber << "|" << line.str() << std::endl;
|
||||||
|
mFileStream << logType << "|" << std::put_time(&time_buf, "%T") << "|" << cleanedFileName << "::" << functionName << "::" << lineNumber << "|" << line.str() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define MLOG_INFO(msg) FileLogger::GetInstance().LogLine("Info", msg, __FILE__, __FUNCTION__, __LINE__);
|
|
||||||
#define MLOG_ERROR(msg) FileLogger::GetInstance().LogLine("Error", msg, __FILE__, __FUNCTION__, __LINE__);
|
#define MLOG_ALL(msg, level) {std::ostringstream mt_logstream;\
|
||||||
|
mt_logstream << msg; \
|
||||||
|
FileLogger::GetInstance().LogLine(level, mt_logstream, __FILE__, __FUNCTION__, __LINE__);};
|
||||||
|
|
||||||
|
#define MLOG_INFO(msg) MLOG_ALL(msg, "Info");
|
||||||
|
#define MLOG_ERROR(msg) MLOG_ALL(msg, "Error");
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
class FileLogger
|
class FileLogger
|
||||||
{
|
{
|
||||||
|
@ -41,9 +47,9 @@ public:
|
||||||
|
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
void LogLine(const std::string& line);
|
void LogLine(const std::ostringstream& line);
|
||||||
|
|
||||||
void LogLine(const std::string& logType, const std::string& line, const std::string& fileName = "", const std::string& functionName = "", int lineNumber=-1);
|
void LogLine(const std::string& logType, const std::ostringstream& line, const std::string& fileName = "", const std::string& functionName = "", int lineNumber=-1);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@ list(APPEND ui_elements_LIB_INCLUDES
|
||||||
ui_events/MouseEvent.cpp
|
ui_events/MouseEvent.cpp
|
||||||
ui_events/UiEvent.cpp
|
ui_events/UiEvent.cpp
|
||||||
ui_events/PaintEvent.cpp
|
ui_events/PaintEvent.cpp
|
||||||
|
ui_events/KeyboardEvent.h
|
||||||
|
ui_events/MouseEvent.h
|
||||||
|
ui_events/UiEvent.h
|
||||||
|
ui_events/PaintEvent.h
|
||||||
widgets/Widget.cpp
|
widgets/Widget.cpp
|
||||||
widgets/Button.cpp
|
widgets/Button.cpp
|
||||||
widgets/Label.cpp
|
widgets/Label.cpp
|
||||||
|
|
|
@ -14,7 +14,16 @@ list(APPEND platform_INCLUDES
|
||||||
ui_interfaces/x11/GlxInterface.cpp)
|
ui_interfaces/x11/GlxInterface.cpp)
|
||||||
|
|
||||||
list(APPEND platform_LIBS
|
list(APPEND platform_LIBS
|
||||||
X11 X11-xcb xcb )
|
X11 X11-xcb xcb )
|
||||||
|
else()
|
||||||
|
list(APPEND platform_INCLUDES
|
||||||
|
ui_interfaces/win32/Win32UIInterface.h
|
||||||
|
ui_interfaces/win32/Win32UIInterface.cpp
|
||||||
|
ui_interfaces/win32/Win32WindowInterface.h
|
||||||
|
ui_interfaces/win32/Win32WindowInterface.cpp
|
||||||
|
ui_interfaces/win32/Win32Window.h
|
||||||
|
ui_interfaces/win32/Win32Window.cpp
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND windows_LIB_INCLUDES
|
list(APPEND windows_LIB_INCLUDES
|
||||||
|
@ -29,6 +38,8 @@ target_include_directories(windows PUBLIC
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/managers"
|
"${CMAKE_CURRENT_SOURCE_DIR}/managers"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/ui_interfaces/x11"
|
"${CMAKE_CURRENT_SOURCE_DIR}/ui_interfaces/x11"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/ui_interfaces/win32"
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/core"
|
||||||
"${PROJECT_SOURCE_DIR}/src/geometry"
|
"${PROJECT_SOURCE_DIR}/src/geometry"
|
||||||
"${PROJECT_SOURCE_DIR}/src/graphics"
|
"${PROJECT_SOURCE_DIR}/src/graphics"
|
||||||
"${PROJECT_SOURCE_DIR}/src/ui_elements"
|
"${PROJECT_SOURCE_DIR}/src/ui_elements"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "DesktopManager.h"
|
#include "DesktopManager.h"
|
||||||
|
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
DesktopManager::DesktopManager()
|
DesktopManager::DesktopManager()
|
||||||
: mScreens(),
|
: mScreens(),
|
||||||
mWindowManager(WindowManager::Create()),
|
mWindowManager(WindowManager::Create()),
|
||||||
|
@ -28,6 +30,7 @@ void DesktopManager::ClearEvents()
|
||||||
|
|
||||||
void DesktopManager::OnKeyboardEvent(const KeyboardEvent* event)
|
void DesktopManager::OnKeyboardEvent(const KeyboardEvent* event)
|
||||||
{
|
{
|
||||||
|
MLOG_INFO("Got key event: " << event->GetKeyString());
|
||||||
GetWindowManager()->OnKeyboardEvent(event);
|
GetWindowManager()->OnKeyboardEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,14 +100,14 @@ void DesktopManager::SetKeyboard(KeyboardUPtr keyboard)
|
||||||
mKeyboard = std::move(keyboard);
|
mKeyboard = std::move(keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopManager::SetMainApp(AbstractDesktopAppPtr mainApp)
|
void DesktopManager::SetMainApp(std::shared_ptr<AbstractApp> mainApp)
|
||||||
{
|
{
|
||||||
mMainApplication = mainApp;
|
mMainApplication = mainApp;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractDesktopAppPtr DesktopManager::GetMainApp()
|
AbstractApp* DesktopManager::GetMainApp()
|
||||||
{
|
{
|
||||||
return mMainApplication;
|
return mMainApplication.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopManager::AddScreen(ScreenPtr screen)
|
void DesktopManager::AddScreen(ScreenPtr screen)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "MouseEvent.h"
|
#include "MouseEvent.h"
|
||||||
#include "WindowManager.h"
|
#include "WindowManager.h"
|
||||||
#include "UiEvent.h"
|
#include "UiEvent.h"
|
||||||
#include "AbstractDesktopApp.h"
|
#include "AbstractApp.h"
|
||||||
#include "EventManager.h"
|
#include "EventManager.h"
|
||||||
|
|
||||||
class DesktopManager
|
class DesktopManager
|
||||||
|
@ -25,9 +25,9 @@ public:
|
||||||
|
|
||||||
void SetWindowManager(WindowManagerUPtr windowManager);
|
void SetWindowManager(WindowManagerUPtr windowManager);
|
||||||
|
|
||||||
void SetMainApp(AbstractDesktopAppPtr mainApp);
|
void SetMainApp(std::shared_ptr<AbstractApp> mainApp);
|
||||||
|
|
||||||
AbstractDesktopAppPtr GetMainApp();
|
AbstractApp* GetMainApp();
|
||||||
|
|
||||||
WindowManager* GetWindowManager() const;
|
WindowManager* GetWindowManager() const;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ private:
|
||||||
WindowManagerUPtr mWindowManager;
|
WindowManagerUPtr mWindowManager;
|
||||||
KeyboardUPtr mKeyboard;
|
KeyboardUPtr mKeyboard;
|
||||||
EventManagerUPtr mEventManager;
|
EventManagerUPtr mEventManager;
|
||||||
AbstractDesktopAppPtr mMainApplication;
|
std::shared_ptr<AbstractApp> mMainApplication;
|
||||||
bool mModified;
|
bool mModified;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
40
src/windows/ui_interfaces/win32/Win32UIInterface.cpp
Normal file
40
src/windows/ui_interfaces/win32/Win32UIInterface.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include "Win32UIInterface.h"
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
Win32UIInterface::Win32UIInterface()
|
||||||
|
: mWindowInterface(std::make_unique<Win32WindowInterface>())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UIInterface::Initialize(DesktopManager* desktopManager)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UIInterface::Loop(DesktopManager* desktopManager)
|
||||||
|
{
|
||||||
|
// Run the message loop.
|
||||||
|
MSG msg = { };
|
||||||
|
while (::GetMessage(&msg, NULL, 0, 0))
|
||||||
|
{
|
||||||
|
::TranslateMessage(&msg);
|
||||||
|
::DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UIInterface::ShutDown()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UIInterface::ShowWindow(mt::Window* window)
|
||||||
|
{
|
||||||
|
mWindowInterface->Show(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32UIInterface::AddWindow(mt::Window* window, DesktopManager* desktopManager)
|
||||||
|
{
|
||||||
|
mWindowInterface->Add(window, desktopManager);
|
||||||
|
}
|
29
src/windows/ui_interfaces/win32/Win32UIInterface.h
Normal file
29
src/windows/ui_interfaces/win32/Win32UIInterface.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
|
#include "Win32WindowInterface.h"
|
||||||
|
|
||||||
|
class DesktopManager;
|
||||||
|
|
||||||
|
class Win32UIInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Win32UIInterface();
|
||||||
|
|
||||||
|
~Win32UIInterface() = default;
|
||||||
|
|
||||||
|
void Initialize(DesktopManager* desktopManager);
|
||||||
|
|
||||||
|
void Loop(DesktopManager* desktopManager);
|
||||||
|
|
||||||
|
void ShutDown();
|
||||||
|
|
||||||
|
void ShowWindow(mt::Window* window);
|
||||||
|
|
||||||
|
void AddWindow(mt::Window* window, DesktopManager* desktopManager);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Win32WindowInterfacePtr mWindowInterface;
|
||||||
|
};
|
139
src/windows/ui_interfaces/win32/Win32Window.cpp
Normal file
139
src/windows/ui_interfaces/win32/Win32Window.cpp
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
#include "Win32Window.h"
|
||||||
|
|
||||||
|
#include "Win32WindowInterface.h"
|
||||||
|
|
||||||
|
#include <WinUser.h>
|
||||||
|
#include "FileLogger.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
#include "ui_events\KeyboardEvent.h"
|
||||||
|
#include "DesktopManager.h"
|
||||||
|
|
||||||
|
LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
Win32Window::Win32Window()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Win32Window> Win32Window::Create()
|
||||||
|
{
|
||||||
|
return std::make_unique<Win32Window>();
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND Win32Window::GetHandle() const
|
||||||
|
{
|
||||||
|
return mHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32Window::CreateNative(Win32ApplicationContext* context, DesktopManager* desktopManager)
|
||||||
|
{
|
||||||
|
mDesktopManager = desktopManager;
|
||||||
|
|
||||||
|
const char CLASS_NAME[] = "Sample Window Class";
|
||||||
|
|
||||||
|
auto hInstance = reinterpret_cast<HINSTANCE>(context->hInstance);
|
||||||
|
WNDCLASS wc = { };
|
||||||
|
wc.lpfnWndProc = FreeWindowProc;
|
||||||
|
wc.hInstance = hInstance;
|
||||||
|
wc.lpszClassName = CLASS_NAME;
|
||||||
|
|
||||||
|
RegisterClass(&wc);
|
||||||
|
|
||||||
|
MLOG_INFO("Request window create");
|
||||||
|
mHandle = CreateWindowEx(
|
||||||
|
0, // Optional window styles.
|
||||||
|
CLASS_NAME, // Window class
|
||||||
|
"Media Tool", // Window text
|
||||||
|
WS_OVERLAPPEDWINDOW, // Window style
|
||||||
|
|
||||||
|
// Size and position
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
|
||||||
|
nullptr, // Parent window
|
||||||
|
nullptr, // Menu
|
||||||
|
hInstance, // Instance handle
|
||||||
|
this // Additional application data
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mHandle == nullptr)
|
||||||
|
{
|
||||||
|
LPVOID lpMsgBuf;
|
||||||
|
auto dw = ::GetLastError();
|
||||||
|
|
||||||
|
::FormatMessage(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
nullptr, dw,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
|
||||||
|
|
||||||
|
MLOG_INFO("Request window failed: " << dw);
|
||||||
|
|
||||||
|
LocalFree(lpMsgBuf);
|
||||||
|
}
|
||||||
|
MLOG_INFO("Request window create got handle: " << "0x" << mHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK Win32Window::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_CHAR:
|
||||||
|
{
|
||||||
|
auto key_event = std::make_unique<KeyboardEvent>();
|
||||||
|
key_event->SetAction(KeyboardEvent::Action::Pressed);
|
||||||
|
|
||||||
|
auto keyChar = (wchar_t)wParam;
|
||||||
|
key_event->SetKeyString(StringUtils::convert(std::wstring(1, keyChar)));
|
||||||
|
mDesktopManager->OnUiEvent(std::move(key_event));
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_PAINT:
|
||||||
|
{
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
HDC hdc = BeginPaint(mHandle, &ps);
|
||||||
|
|
||||||
|
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
|
||||||
|
|
||||||
|
auto text = L"Hello World";
|
||||||
|
auto val = DrawText(hdc, (LPCSTR)(&text[0]), -1, &ps.rcPaint, 0);
|
||||||
|
|
||||||
|
EndPaint(mHandle, &ps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DefWindowProc(mHandle, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
Win32Window* window;
|
||||||
|
|
||||||
|
if (uMsg == WM_NCCREATE)
|
||||||
|
{
|
||||||
|
CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
|
||||||
|
window = (Win32Window*)cs->lpCreateParams;
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
if (::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)window) == 0)
|
||||||
|
{
|
||||||
|
if (GetLastError() != 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window = (Win32Window*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
window->SetHandle(hwnd);
|
||||||
|
return window->WindowProc(uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
42
src/windows/ui_interfaces/win32/Win32Window.h
Normal file
42
src/windows/ui_interfaces/win32/Win32Window.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IPlatformWindow.h"
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
class Win32ApplicationContext;
|
||||||
|
class DesktopManager;
|
||||||
|
|
||||||
|
class Win32Window : public IPlatformWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Win32Window();
|
||||||
|
virtual ~Win32Window() = default;
|
||||||
|
|
||||||
|
static std::unique_ptr<Win32Window> Create();
|
||||||
|
|
||||||
|
LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
HWND GetHandle() const;
|
||||||
|
|
||||||
|
void SetHandle(HWND handle)
|
||||||
|
{
|
||||||
|
mHandle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetCmdShow() const
|
||||||
|
{
|
||||||
|
return mCmdShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetCmdShow(int cmdShow)
|
||||||
|
{
|
||||||
|
mCmdShow = cmdShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateNative(Win32ApplicationContext* context, DesktopManager* desktopManager);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HWND mHandle{ 0 };
|
||||||
|
int mCmdShow{ 0 };
|
||||||
|
DesktopManager* mDesktopManager;
|
||||||
|
};
|
32
src/windows/ui_interfaces/win32/Win32WindowInterface.cpp
Normal file
32
src/windows/ui_interfaces/win32/Win32WindowInterface.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "Win32WindowInterface.h"
|
||||||
|
|
||||||
|
#include "Win32Window.h"
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include "DesktopManager.h"
|
||||||
|
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
Win32WindowInterface::Win32WindowInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32WindowInterface::Show(mt::Window* window)
|
||||||
|
{
|
||||||
|
auto platformWindow = dynamic_cast<Win32Window*>(window->GetPlatformWindow());
|
||||||
|
MLOG_INFO("Showing platform window: " << platformWindow->GetHandle());
|
||||||
|
::ShowWindow(platformWindow->GetHandle(), platformWindow->GetCmdShow());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32WindowInterface::Add(mt::Window* window, DesktopManager* desktopManager)
|
||||||
|
{
|
||||||
|
auto context = dynamic_cast<Win32ApplicationContext*>(desktopManager->GetMainApp()->GetApplicationContext());
|
||||||
|
|
||||||
|
auto win32_window = Win32Window::Create();
|
||||||
|
win32_window->CreateNative(context, desktopManager);
|
||||||
|
win32_window->SetCmdShow(context->nCmdShow);
|
||||||
|
window->SetPlatformWindow(std::move(win32_window));
|
||||||
|
}
|
||||||
|
|
29
src/windows/ui_interfaces/win32/Win32WindowInterface.h
Normal file
29
src/windows/ui_interfaces/win32/Win32WindowInterface.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
|
#include "AbstractApp.h"
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class DesktopManager;
|
||||||
|
|
||||||
|
class Win32ApplicationContext : public IApplicationContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void* hInstance{ nullptr };
|
||||||
|
int nCmdShow{ 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
class Win32WindowInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Win32WindowInterface();
|
||||||
|
|
||||||
|
void Add(mt::Window* window, DesktopManager* desktopManager);
|
||||||
|
|
||||||
|
void Show(mt::Window* window);
|
||||||
|
};
|
||||||
|
|
||||||
|
using Win32WindowInterfacePtr = std::unique_ptr<Win32WindowInterface>;
|
|
@ -1,4 +1,4 @@
|
||||||
add_library(test_utils SHARED
|
add_library(test_utils STATIC
|
||||||
test_utils/TestCase.h
|
test_utils/TestCase.h
|
||||||
test_utils/TestCaseRunner.cpp
|
test_utils/TestCaseRunner.cpp
|
||||||
)
|
)
|
||||||
|
@ -18,7 +18,7 @@ list(APPEND TestNames
|
||||||
TestOpenGlRendering)
|
TestOpenGlRendering)
|
||||||
|
|
||||||
foreach(TestFile TestName IN ZIP_LISTS TestFiles TestNames)
|
foreach(TestFile TestName IN ZIP_LISTS TestFiles TestNames)
|
||||||
add_executable(${TestName} ${TestFile})
|
add_executable(${TestName} ${TestFile})
|
||||||
target_link_libraries(${TestName} PUBLIC core network database geometry audio graphics web client test_utils)
|
target_link_libraries(${TestName} PUBLIC core network database geometry audio graphics web client test_utils)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
#include "AudioSample.h"
|
#include "AudioSample.h"
|
||||||
#include "AudioSynth.h"
|
#include "AudioSynth.h"
|
||||||
#include "AudioWriter.h"
|
#include "AudioWriter.h"
|
||||||
|
#include "WasapiInterface.h"
|
||||||
|
|
||||||
#include "TestCase.h"
|
#include "TestCase.h"
|
||||||
#include "TestCaseRunner.h"
|
#include "TestCaseRunner.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
class TestWriteWav : public TestCase
|
class TestWriteWav : public TestCase
|
||||||
{
|
{
|
||||||
|
@ -24,11 +27,30 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TestAudioRender : public TestCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool Run() override
|
||||||
|
{
|
||||||
|
WasapiInterface audio_interface;
|
||||||
|
auto device = AudioDevice::Create();
|
||||||
|
audio_interface.Play(device);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
|
std::cout << "into entry point" << std::endl;
|
||||||
TestCaseRunner runner;
|
TestCaseRunner runner;
|
||||||
runner.AddTestCase("TestWriteNav", std::make_unique<TestWriteWav>());
|
//runner.AddTestCase("TestWriteNav", std::make_unique<TestWriteWav>());
|
||||||
|
runner.AddTestCase("TestAudioRender", std::make_unique<TestAudioRender>());
|
||||||
|
|
||||||
const auto testsPassed = runner.Run();
|
const auto testsPassed = runner.Run();
|
||||||
return testsPassed ? 0 : -1;
|
return testsPassed ? 0 : -1;
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue