// HarlinnWindowsTest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "hwinapplication.h"
#include "hwinform.h"
#include "hwinmenu.h"
#include "hwindatetime.h"
#include "hwingraphics.h"
#include "hwinimaging.h"
#include "hwinperlinnoice.h"
#include "hwinstdctrls.h"
#include <iostream>
#include "AnimatedPoint.h"
using namespace harlinn::windows;
class MyForm : public Form
{
graphics::Factory factory;
graphics::WriteFactory writeFactory;
graphics::WriteTextFormat textFormat;
graphics::WriteTextLayout textLayout;
graphics::ControlRenderTarget renderTarget;
graphics::SolidColorBrush blackBrush;
graphics::WriteTypography typography;
graphics::LinearGradientBrush backgroundBrush;
float dpiScaleX;
float dpiScaleY;
String text;
String titleText;
std::shared_ptr<Timer> timer;
bool showingTime;
public:
typedef Form Base;
MyForm();
protected:
virtual void DoOnInitialize();
virtual void DoOnShown();
virtual void DoOnDestroy(Message& message);
virtual void DoOnDisplayChange(Message& message);
virtual void DoOnPaint(Message& message);
virtual void DoOnSize(Message& message);
private:
void UpdateScale( );
void InitializeMenuBar();
};
MyForm::MyForm()
: Base(),
factory(D2D1_FACTORY_TYPE_SINGLE_THREADED),
writeFactory(DWRITE_FACTORY_TYPE_SHARED),
dpiScaleX(0),dpiScaleY(0),
titleText(L"Windows Development in C++ - working with menus"),
showingTime(0)
{
text = titleText;
timer = make_component<Timer>();
timer->OnTick.connect([&](Timer* sender)
{
if(showingTime)
{
DateTime now = DateTime::Now();
if(now.IsDaylightSavingTime())
{
text = now.ToString() + L" Daylight saving time";
}
else
{
text = now.ToString() + L" Standard time";
}
InvalidateRect();
}
} );
timer->SetInterval(TimeSpan::FromMilliseconds(500));
timer->SetEnabled();
}
void MyForm::DoOnInitialize()
{
SetText(titleText); //
textFormat = writeFactory.CreateTextFormat(L"Gabriola",72);
textFormat.SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
textFormat.SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
typography = writeFactory.CreateTypography();
DWRITE_FONT_FEATURE fontFeature = {DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7,1};
typography.AddFontFeature(fontFeature);
UpdateScale( );
InitializeMenuBar();
}
void MyForm::InitializeMenuBar()
{
auto self = As<MyForm>();
auto fileNewMenuItem = make_component<TextMenuItem>(self,L"&New");
auto fileOpenMenuItem = make_component<TextMenuItem>(self,L"&Open");
auto fileSaveMenuItem = make_component<TextMenuItem>(self,L"&Save");
auto fileSeparator = make_component<SeparatorMenuItem>(self);
auto fileExitMenuItem = make_component<TextMenuItem>(self,L"E&xit");
fileNewMenuItem->OnClick.connect([&](MenuItem*){ showingTime = false; text = L"New selected"; InvalidateRect(); });
fileOpenMenuItem->OnClick.connect([&](MenuItem*){ showingTime = false; text = L"Open selected"; InvalidateRect(); });
fileSaveMenuItem->OnClick.connect([&](MenuItem*){ showingTime = false; text = L"Save selected"; InvalidateRect(); });
fileExitMenuItem->OnClick.connect([&](MenuItem*){ Close(); });
auto fileSubMenu = make_component<SubMenuItem>(self,L"&File");
fileSubMenu->Add(fileNewMenuItem);
fileSubMenu->Add(fileOpenMenuItem);
fileSubMenu->Add(fileSaveMenuItem);
fileSubMenu->Add(fileSeparator);
fileSubMenu->Add(fileExitMenuItem);
auto editSubMenu = make_component<SubMenuItem>(self,L"&Edit");
auto editCutMenuItem = editSubMenu->AddMenuItem(L"Cu&t");
auto editCopyMenuItem = editSubMenu->AddMenuItem(L"&Copy");
auto editPasteMenuItem = editSubMenu->AddMenuItem(L"&Paste");
editCutMenuItem->OnClick.connect([&](MenuItem*){ showingTime = false; text = L"Cut selected"; InvalidateRect(); });
editCopyMenuItem->OnClick.connect([&](MenuItem*){ showingTime = false; text = L"Copy selected"; InvalidateRect(); });
editPasteMenuItem->OnClick.connect([&](MenuItem*){ showingTime = false; text = L"Paste selected"; InvalidateRect(); });
auto viewSubMenu = make_component<SubMenuItem>(self,L"&View");
auto viewTime = viewSubMenu->AddMenuItem(L"&Time");
viewTime->OnClick.connect([&](MenuItem*)
{
showingTime = true;
DateTime now = DateTime::Now();
if(now.IsDaylightSavingTime())
{
text = now.ToString() + L" Daylight saving time";
}
else
{
text = now.ToString() + L" Standard time";
}
InvalidateRect();
});
auto menuBar = make_component<MenuBar>(self);
menuBar->Add(fileSubMenu);
menuBar->Add(editSubMenu);
menuBar->Add(viewSubMenu);
SetMenu(menuBar);
}
void MyForm::DoOnShown()
{
Base::DoOnShown();
renderTarget = factory.CreateControlRenderTarget(As<Control>());
blackBrush = renderTarget.CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black));
D2D1_GRADIENT_STOP gradientStops[2];
gradientStops[0].color = D2D1::ColorF(D2D1::ColorF::White, 1);
gradientStops[0].position = 0.0f;
gradientStops[1].color = D2D1::ColorF(D2D1::ColorF::DeepSkyBlue, 1);
gradientStops[1].position = 1.0f;
graphics::GradientStopCollection gradientStopCollection = renderTarget.CreateGradientStopCollection(gradientStops,2,D2D1_GAMMA_2_2,D2D1_EXTEND_MODE_MIRROR);
backgroundBrush = renderTarget.CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2D1::Point2F(0, 0),D2D1::Point2F(150, 150)),gradientStopCollection);
}
void MyForm::DoOnDestroy(Message& message)
{
Base::DoOnDestroy(message);
blackBrush.Reset();
renderTarget.Reset();
}
void MyForm::DoOnDisplayChange(Message& message)
{
UpdateScale( );
InvalidateRect();
}
void MyForm::DoOnPaint(Message& message)
{
Base::DoOnPaint(message);
ValidateRect();
RECT rc = GetClientRect();
renderTarget.BeginDraw();
renderTarget.SetTransform(D2D1::IdentityMatrix());
renderTarget.Clear(D2D1::ColorF(D2D1::ColorF::White));
D2D1_RECT_F layoutRect = D2D1::RectF(rc.top * dpiScaleY,rc.left * dpiScaleX,
(rc.right - rc.left) * dpiScaleX,(rc.bottom - rc.top) * dpiScaleY);
renderTarget.FillRectangle(layoutRect, backgroundBrush);
D2D1_POINT_2F origin = {layoutRect.left,layoutRect.top};
textLayout = writeFactory.CreateTextLayout(text.c_str(),UINT(text.length()),textFormat,layoutRect.right - layoutRect.left,layoutRect.bottom - layoutRect.top);
DWRITE_TEXT_RANGE textRange = {0, UINT(text.length())};
textLayout.SetTypography(typography,textRange);
auto found = text.IndexOf(L"C++");
if(found != String::npos)
{
textRange.startPosition = UINT(found);
textRange.length = 3;
textLayout.SetFontSize(144.0,textRange);
}
renderTarget.DrawTextLayout(origin,textLayout,blackBrush);
renderTarget.EndDraw();
}
void MyForm::DoOnSize(Message& message)
{
Base::DoOnSize(message);
if(renderTarget)
{
D2D1_SIZE_U size;
size.width = LOWORD(message.lParam);
size.height = HIWORD(message.lParam);
renderTarget.Resize(size);
}
}
void MyForm::UpdateScale( )
{
factory.GetDesktopDpi(dpiScaleX,dpiScaleY);
dpiScaleX /= 96.0f;
dpiScaleY /= 96.0f;
}
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
try
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
auto application = make_component<Application>();
auto form = make_control<MyForm>();
auto result = application->Run(form);
return result;
}
catch(std::exception& exc)
{
std::cout << exc.what() << std::endl;
}
catch(...)
{
}
return 0;
}