#include "WinDirect2DApplication.h"
#include "..\..\..\GraphicsElement\WindowsDirect2D\GuiGraphicsWindowsDirect2D.h"
#include <ShellScalingApi.h>
#pragma comment(lib,
"d2d1.lib"
)
#pragma comment(lib,
"dxguid.lib"
)
#pragma comment(lib,
"dwrite.lib"
)
#pragma comment(lib,
"d3d11.lib"
)
namespace
{
namespace
{
using
namespace
elements
;
namespace
{
using
namespace
vl
::
collections
;
class
Direct2DWindowsNativeWindowListener
:
public
,
public
{
protected
:
*
;
*
;
bool
=
false
;
bool
=
false
;
virtual
void
(
) =
0
;
public
:
Direct2DWindowsNativeWindowListener
(
*
,
*
)
:window(
)
,d2dFactory(
)
{
}
void
()
override
{
if
(
)
{
=
true
;
}
else
{
();
}
}
void
()
{
(
->
());
}
void
()
{
=
true
;
}
void
()
{
=
false
;
}
bool
RetrieveAndResetMovedWhileRendering
()
{
bool
=
;
=
false
;
return
result
;
}
virtual
*
() =
0
;
virtual
void
() =
0
;
virtual
bool
() =
0
;
};
class
Direct2DWindowsNativeWindowListener_1_0
:
public
Direct2DWindowsNativeWindowListener
{
protected
:
<
>
;
;
void
(
)
override
{
if
(
.
1
)
.
1
;
if
(
.
1
)
.
1
;
if
(!
)
{
*
=
0
;
*
=
(
);
D2D1_RENDER_TARGET_PROPERTIES
=
D2D1
::
();
{
=
0
;
=
0
;
DpiAwared_GetDpiForWindow
(
form
->
(), &
dpiX
, &
dpiY
);
tp
.
= (
)
dpiX
;
tp
.
= (
)
dpiY
;
}
=
->
(
tp
,
D2D1
::
HwndRenderTargetProperties
(
form
->
(),
D2D1
::
((
int
)
.
.
, (
int
)
.
.
)
),
&
renderTarget
);
{
renderTarget
;
(
D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE
);
}
}
else
if
(
)
{
(
D2D1
::
((
int
)
.
.
, (
int
)
.
.
));
}
;
}
public
:
Direct2DWindowsNativeWindowListener_1_0
(
*
,
*
)
:
Direct2DWindowsNativeWindowListener
(
,
)
{
}
*
()
override
{
if
(!
)
();
return
.
();
}
void
()
override
{
if
(
)
{
0
;
}
}
bool
()
override
{
return
true
;
}
};
class
Direct2DWindowsNativeWindowListener_1_1
:
public
Direct2DWindowsNativeWindowListener
{
protected
:
<
>
;
*
;
<
>
;
<
>
;
<
>
;
;
<
>
()
{
*
=
nullptr
;
=
->
(&
device
);
if (!SUCCEEDED(hr)) return 0;
if
(!(((
)(
hr
)) >=
0
))
return
0
;
return
device
;
}
<
>
(
*
)
{
<
>
;
{
*
=
nullptr
;
=
->
(&
adapter
);
if (!SUCCEEDED(hr)) return 0;
if
(!(((
)(
hr
)) >=
0
))
return
0
;
dxgiAdapter
adapter
;
}
<
>
;
{
*
=
nullptr
;
=
dxgiAdapter
(__uuidof(
), (
void
**)&
factory
);
if (!SUCCEEDED(hr)) return 0;
if
(!(((
)(
hr
)) >=
0
))
return
0
;
dxgiFactory
factory
;
}
*
=
(
);
<
>
;
{
= {};
props
.
=
DXGI_FORMAT_B8G8R8A8_UNORM
;
props
.
.
=
1
;
props.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
props
.
=
2
;
*
=
nullptr
;
=
dxgiFactory
(
,
form
->
(), &
props
,
nullptr
,
nullptr
, &
swapChain
);
if (!SUCCEEDED(hr)) return 0;
if
(!(((
)(
hr
)) >=
0
))
return
0
;
dxgiSwapChain
swapChain
;
}
return
dxgiSwapChain
;
}
<
>
(
*
)
{
<
>
;
{
*
=
nullptr
;
=
(
, &
device
);
if (!SUCCEEDED(hr)) return 0;
if
(!(((
)(
hr
)) >=
0
))
return
0
;
d2d1Device
device
;
}
<
>
;
{
*
=
nullptr
;
=
d2d1Device
(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE
, &
deviceContext
);
if (!SUCCEEDED(hr)) return 0;
if
(!(((
)(
hr
)) >=
0
))
return
0
;
d2dDeviceContext
deviceContext
;
}
return
d2dDeviceContext
;
}
<
>
(
*
,
*
)
{
<
>
;
{
*
=
nullptr
;
=
->
(
0
, __uuidof(
), (
void
**)&
surface
);
if (!SUCCEEDED(hr))return 0;
if
(!(((
)(
hr
)) >=
0
))
return
0
;
dxgiSurface
surface
;
}
<
>
;
{
auto
=
D2D1
::
(
D2D1_BITMAP_OPTIONS_TARGET
|
D2D1_BITMAP_OPTIONS_CANNOT_DRAW
,
D2D1
::
(
DXGI_FORMAT_B8G8R8A8_UNORM
,
));
*
=
nullptr
;
=
->
CreateBitmapFromDxgiSurface
(
dxgiSurface
.
(),
props
, &
bitmap
);
if (!SUCCEEDED(hr)) return 0;
if
(!(((
)(
hr
)) >=
0
))
return
0
;
d2dBitmap
bitmap
;
}
return
d2dBitmap
;
}
void
(
)
override
{
if
(
.
1
)
.
1
;
if
(
.
1
)
.
1
;
if
(!
)
{
if
(!
)
{
();
}
if
(!
)
{
(
.
());
}
(
.
());
auto
=
(
.
(),
.
());
(
d2dBitmap
.
());
*
=
(
);
{
=
0
;
=
0
;
DpiAwared_GetDpiForWindow
(
form
->
(), &
dpiX
, &
dpiY
);
((
)
dpiX
, (
)
dpiY
);
}
}
else
if
(
)
{
(
nullptr
);
=
(
0
,
0
,
0
,
,
0
);
{
auto
=
(
.
(),
.
());
(
d2dBitmap
.
());
}
}
;
}
public
:
Direct2DWindowsNativeWindowListener_1_1
(
*
,
<
>
,
*
)
:
Direct2DWindowsNativeWindowListener
(
,
.
())
,d2dFactory1(
)
,d3d11Device(
)
{
}
*
()
override
{
if
(!
)
();
return
.
();
}
void
()
override
{
if
(
)
{
0
;
0
;
}
}
bool
()
override
{
if
(
)
{
if
(
)
{
= {
0
};
=
(
1
,
0
, &
parameters
);
return hr == S_OK || hr == DXGI_STATUS_OCCLUDED;
return
hr
== ((
)
0L
) ||
hr
== ((
)
0x087A0001L
);
}
}
return
false
;
}
};
class
Direct2DWindowsNativeControllerListener
:
public
,
public
INativeControllerListener
{
public
:
<
*,
<
Direct2DWindowsNativeWindowListener
>>
;
<
>
;
<
>
;
<
>
;
Direct2DWindowsNativeControllerListener
()
{
{
= {};
#ifdef _DEBUG
fo
.
=
D2D1_DEBUG_LEVEL_INFORMATION
;
#endif
*
=
0
;
=
(
D2D1_FACTORY_TYPE_SINGLE_THREADED
,
fo
, &
factory
);
{
factory
;
}
}
{
*
=
0
;
=
(
DWRITE_FACTORY_TYPE_ISOLATED
, __uuidof(
),
reinterpret_cast
<
**>(&
factory
));
{
factory
;
}
}
}
~
Direct2DWindowsNativeControllerListener
()
{
for
(
=
0
;
i
<
.
();
i
++)
{
auto
=
.
()
i
];
auto
=
.
()
i
];
window
->
(
listener
.
());
}
}
<
>
(
)
{
=
D3D11_CREATE_DEVICE_BGRA_SUPPORT
;
#ifdef _DEBUG
flags
|=
D3D11_CREATE_DEVICE_DEBUG
;
#endif
[] =
{
,
,
,
,
,
,
};
*
=
nullptr
;
=
(
nullptr
,
,
nullptr
,
flags
,
featureLevels
,
sizeof
(
featureLevels
) /
sizeof
(*
featureLevels
),
&
device
,
nullptr
,
nullptr
);
{
return
device
;
}
else
if
(
device
)
{
device
->
();
}
return
0
;
}
void
(
*
)
{
<
>
;
{
*
=
nullptr
;
=
windows
::
()->
(&
factory
);
{
d2dfactory1
factory
;
}
}
<
Direct2DWindowsNativeWindowListener
>
;
if
(
d2dfactory1
)
{
if
(!
)
{
(
);
if
(!
)
{
(
);
}
}
#if _DEBUG
CHECK_ERROR(d3d11Device,
L"Direct2DWindowsNativeControllerListener::NativeWindowCreated(INativeWindow*)#"
L"Failed to create Direct3D 11 Device. "
L"If you are running in Debug mode on Windows 10, please ensure the optional feature [Graphics Tools] is correctly installed. "
L"This error will be skipped in Release mode and GacUI will fallback to use Direct2D 1.0, but you still need to check your Windows SDK Installation."
);
#endif
do
{
if
(!(
))
throw
(
L"Direct2DWindowsNativeControllerListener::NativeWindowCreated(INativeWindow*)#"
L"Failed to create Direct3D 11 Device. "
L"If you are running in Debug mode on Windows 10, please ensure the optional feature [Graphics Tools] is correctly installed. "
L"This error will be skipped in Release mode and GacUI will fallback to use Direct2D 1.0, but you still need to check your Windows SDK Installation."
);}
while
(
0
);
}
if
(
d2dfactory1
&&
)
{
listener
new
Direct2DWindowsNativeWindowListener_1_1
(
,
d2dfactory1
,
.
());
}
else
{
listener
new
Direct2DWindowsNativeWindowListener_1_0
(
,
.
());
}
->
(
listener
.
());
.
(
,
listener
);
}
void
(
*
)
{
<
Direct2DWindowsNativeWindowListener
>
=
];
.
(
);
->
(
listener
.
());
}
};
Direct2DWindowsNativeControllerListener
*
=
0
;
*
()
{
return
direct2DListener
->
.
();
}
*
()
{
return
direct2DListener
->
.
();
}
*
()
{
return
direct2DListener
->
.
();
}
}
namespace
{
class
WinDirect2DApplicationDirect2DObjectProvider
:
public
IWindowsDirect2DObjectProvider
{
protected
:
windows
::
Direct2DWindowsNativeWindowListener
*
(
*
)
{
=
windows
::
direct2DListener
->
.
().
(
);
return
index
== -
1
?
nullptr
:
windows
::
direct2DListener
->
.
().
(
index
).
();
}
public
:
void
(
*
)
override
{
if
(
auto
=
(
))
{
return
listener
->
();
}
}
void
(
*
)
override
{
if
(
auto
=
(
))
{
return
listener
->
();
}
}
*
GetNativeWindowDirect2DRenderTarget
(
*
)
override
{
if
(
auto
=
(
))
{
return
listener
->
();
}
return
nullptr
;
}
void
(
*
)
override
{
if
(
auto
=
(
))
{
listener
->
();
if
(
auto
=
listener
->
())
{
renderTarget
->
();
renderTarget
->
(
D2D1
::
(
D2D1
::
::
));
}
}
}
(
*
)
override
{
if
(
auto
=
(
))
{
listener
->
();
bool
=
listener
->
RetrieveAndResetMovedWhileRendering
();
if
(
auto
=
listener
->
())
{
=
renderTarget
->
();
{
if
(
moved
)
{
return
::
;
}
else
if
(
listener
->
())
{
return
::
;
}
}
}
}
return
::
;
}
*
()
override
{
return
vl
::
presentation
::
windows
::
();
}
*
()
override
{
return
vl
::
presentation
::
windows
::
();
}
IWindowsDirect2DRenderTarget
*
(
*
)
override
{
return
dynamic_cast
<
IWindowsDirect2DRenderTarget
*>(
vl
::
presentation
::
windows
::
(
)->
());
}
void
(
*
,
IWindowsDirect2DRenderTarget
*
)
override
{
vl
::
presentation
::
windows
::
(
)->
(
);
}
*
()
override
{
return
vl
::
presentation
::
windows
::
();
}
*
(
*
)
override
{
return
vl
::
presentation
::
windows
::
(
);
}
};
}
}
}
using
namespace
vl
;
using
namespace
vl
::
presentation
;
using
namespace
vl
::
presentation
::
windows
;
using
namespace
vl
::
presentation
::
elements_windows_d2d
;
int
(
,
void
(*
)())
{
EnableCrossKernelCrashing
();
*
=
CreateWindowsNativeController
(
);
(
controller
);
{
Direct2DWindowsNativeControllerListener
;
controller
->
()->
(&
listener
);
direct2DListener
=&
listener
;
();
direct2DListener
=
0
;
controller
->
()->
(&
listener
);
}
DestroyWindowsNativeController
(
controller
);
return
0
;
}
int
SetupWindowsDirect2DRenderer
()
{
(
true
);
CoInitializeEx(NULL, COINIT_MULTITHREADED);
HINSTANCE hInstance=(HINSTANCE)GetModuleHandle(NULL);
WinDirect2DApplicationDirect2DObjectProvider
;
SetWindowsDirect2DObjectProvider
(&
objectProvider
);
return
(
hInstance
, &
);
}