File Index Symbol Index

#include "..\..\Resources\GuiResource.h"
#include "WinNativeWindow.h"
#include "ServicesImpl\WindowsResourceService.h"
#include "ServicesImpl\WindowsClipboardService.h"
#include "ServicesImpl\WindowsImageService.h"
#include "ServicesImpl\WindowsAsyncService.h"
#include "ServicesImpl\WindowsScreenService.h"
#include "ServicesImpl\WindowsCallbackService.h"
#include "ServicesImpl\WindowsInputService.h"
#include "ServicesImpl\WindowsDialogService.h" #include <CommCtrl.h>
#pragma comment(lib,
"Imm32.lib"
) #pragma comment(lib,
"Shlwapi.lib"
) #pragma comment(lib,
"Comctl32.lib"
)
namespace
vl
{
namespace
presentation
{
namespace
windows
{
using
namespace
collections
;
LPCWSTR
defaultIconResourceName
=
nullptr
;
HICON
CreateWindowDefaultIcon
(
vint
size
=
0
) { }
void
SetWindowDefaultIcon
(
UINT
resourceId
) { }
HWND
GetHWNDFromNativeWindowHandle
(
INativeWindow
*
window
) {
IWindowsForm
*
form
=
GetWindowsForm
(
window
);
return
form
->
GetWindowHandle
(); }
/*********************************************************************** WindowsClass ***********************************************************************/
class
WinClass
:
public
Object
{
protected
:
WString
name
;
WNDCLASSEX
windowClass
;
ATOM
windowAtom
;
public
:
WinClass
(
WString
_name
,
bool
shadow
,
bool
ownDC
,
WNDPROC
procedure
,
HINSTANCE
hInstance
) {
name
=
_name
;
windowClass
.
cbSize
=
sizeof
(
windowClass
);
windowClass
.
lpfnWndProc
=
procedure
;
windowClass
.
cbClsExtra
=
0
;
windowClass
.
cbWndExtra
=
0
;
windowClass
.
hInstance
=
hInstance
;
if
(
defaultIconResourceName
) {
windowClass
.
hIcon
=
CreateWindowDefaultIcon
(); }
windowClass
.
lpszClassName
=
name
.
Buffer
(); }
bool
IsAvailable
() {
return
windowAtom
!=
0
; }
WString
GetName
() {
return
name
; }
ATOM
GetClassAtom
() {
return
windowAtom
; } };
/*********************************************************************** WindowsForm ***********************************************************************/
class
WindowsForm
:
public
Object
,
public
INativeWindow
,
public
IWindowsForm
{
protected
:
LONG_PTR
InternalGetExStyle
() { }
void
InternalSetExStyle
(
LONG_PTR
exStyle
) { }
LONG_PTR
InternalGetStyle
() { }
void
InternalSetStyle
(
LONG_PTR
style
) { }
LONG_PTR
TurnOnStyle
(
LONG_PTR
combination
,
LONG_PTR
style
) {
return
combination
|
style
; }
LONG_PTR
TurnOffStyle
(
LONG_PTR
combination
,
LONG_PTR
style
) {
return
combination
& (~
style
); }
bool
GetExStyle
(
LONG_PTR
exStyle
) {
return
(
InternalGetExStyle
() &
exStyle
) !=
0
; }
void
SetExStyle
(
LONG_PTR
exStyle
,
bool
available
) {
if
(
available
) {
InternalSetExStyle
(
TurnOnStyle
(
InternalGetExStyle
(),
exStyle
)); }
else
{
InternalSetExStyle
(
TurnOffStyle
(
InternalGetExStyle
(),
exStyle
)); } }
bool
GetStyle
(
LONG_PTR
style
) {
return
(
InternalGetStyle
() &
style
) !=
0
; }
void
SetStyle
(
LONG_PTR
style
,
bool
available
) {
if
(
available
) {
InternalSetStyle
(
TurnOnStyle
(
InternalGetStyle
(),
style
)); }
else
{
InternalSetStyle
(
TurnOffStyle
(
InternalGetStyle
(),
style
)); } }
#pragma push_macro("_CONTROL")
#if defined _CONTROL
#undef _CONTROL #endif
NativeWindowMouseInfo
ConvertMouse
(
WPARAM
wParam
,
LPARAM
lParam
,
bool
wheelMessage
,
bool
nonClient
) {
NativeWindowMouseInfo
info
;
info
.
nonClient
=
false
;
if
(
nonClient
) {
switch
(
wParam
) {
break
;
default
:
info
.
nonClient
=
true
;
break
; } }
if
(
wheelMessage
) { }
else
{
info
.
wheel
=
0
; }
if
(
nonClient
) {
info
.
ctrl
=
WinIsKeyPressing
(
VKEY
::_CONTROL);
info
.
shift
=
WinIsKeyPressing
(
VKEY
::
_SHIFT
);
info
.
left
=
WinIsKeyPressing
(
VKEY
::
_LBUTTON
);
info
.
middle
=
WinIsKeyPressing
(
VKEY
::
_MBUTTON
);
info
.
right
=
WinIsKeyPressing
(
VKEY
::
_RBUTTON
);
NativePoint
offset
=
GetClientBoundsInScreen
().
LeftTop
();
info
.
x
=
point
.
x
-
offset
.
x
.
value
;
info
.
y
=
point
.
y
-
offset
.
y
.
value
; }
else
{
info
.
ctrl
=((
VKEY
)
wParam
&
VKEY
::_CONTROL)!=(
VKEY
)
0
;
info
.
shift
=((
VKEY
)
wParam
&
VKEY
::
_SHIFT
)
!
=
(
VKEY
)
0
;
info
.
left
=((
VKEY
)
wParam
&
VKEY
::
_LBUTTON
)
!
=
(
VKEY
)
0
;
info
.
middle
=((
VKEY
)
wParam
&
VKEY
::
_MBUTTON
)
!
=
(
VKEY
)
0
;
info
.
right
=((
VKEY
)
wParam
&
VKEY
::
_RBUTTON
)
!
=
(
VKEY
)
0
;
if
(
wheelMessage
) {
NativePoint
offset
=
GetClientBoundsInScreen
().
LeftTop
();
info
.
x
=
point
.
x
-
offset
.
x
.
value
;
info
.
y
=
point
.
y
-
offset
.
y
.
value
; }
else
{
info
.
x
=
point
.
x
;
info
.
y
=
point
.
y
; } }
return
info
; }
NativeWindowKeyInfo
ConvertKey
(
WPARAM
wParam
,
LPARAM
lParam
) {
NativeWindowKeyInfo
info
;
info
.
code
=(
VKEY
)
wParam
;
info
.
ctrl
=
WinIsKeyPressing
(
VKEY
::_CONTROL);
info
.
shift
=
WinIsKeyPressing
(
VKEY
::
_SHIFT
);
info
.
alt
=
WinIsKeyPressing
(
VKEY
::
_MENU
);
info
.
capslock
=
WinIsKeyToggled
(
VKEY
::
_CAPITAL
);
info
.
autoRepeatKeyDown
= (((
vuint32_t
)
lParam
) >>
30
) %
2
==
1
;
return
info
; }
NativeWindowCharInfo
ConvertChar
(
WPARAM
wParam
) {
NativeWindowCharInfo
info
;
info
.
code
=(
wchar_t
)
wParam
;
info
.
ctrl
=
WinIsKeyPressing
(
VKEY
::_CONTROL);
info
.
shift
=
WinIsKeyPressing
(
VKEY
::
_SHIFT
);
info
.
alt
=
WinIsKeyPressing
(
VKEY
::
_MENU
);
info
.
capslock
=
WinIsKeyToggled
(
VKEY
::
_CAPITAL
);
return
info
; }
#pragma pop_macro("_CONTROL")
void
TrackMouse
(
bool
enable
) {
TRACKMOUSEEVENT
trackMouseEvent
;
trackMouseEvent
.
cbSize
=
sizeof
(
trackMouseEvent
);
trackMouseEvent
.
hwndTrack
=
handle
;
TrackMouseEvent
(&
trackMouseEvent
); }
void
UpdateCompositionForContent
() {
HIMC
imc
=
ImmGetContext
(
handle
);
COMPOSITIONFORM
cf
;
cf
.
ptCurrentPos
.
x
= (
int
)
caretPoint
.
x
.
value
;
cf
.
ptCurrentPos
.
y
= (
int
)
caretPoint
.
y
.
value
;
ImmSetCompositionWindow
(
imc
, &
cf
);
ImmReleaseContext
(
handle
,
imc
); }
bool
supressClosePopups
=
false
;
static
void
ClosePopupsOf
(
WindowsForm
*
owner
,
SortedList
<
WindowsForm
*>&
exceptions
) {
for
(
vint
i
=
0
;
i
<
owner
->
childWindows
.
Count
();
i
++) {
auto
popup
=
owner
->
childWindows
[
i
];
if
(
popup
->
windowMode
!=
Normal
&&
popup
->
IsVisible
()) {
if
(!
exceptions
.
Contains
(
popup
)) {
popup
->
Hide
(
false
); } }
ClosePopupsOf
(
popup
,
exceptions
); } }
bool
HandleMessageInternal
(
HWND
hwnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
,
LRESULT
&
result
) {
if
(!
supressClosePopups
) {
bool
closePopups
=
false
;
WindowsForm
*
activatedWindow
=
nullptr
;
WindowsForm
*
rootWindow
=
nullptr
;
SortedList
<
WindowsForm
*>
exceptions
;
switch
(
uMsg
) { {
closePopups
=
true
; }
break
; {
activatedWindow
=
this
;
closePopups
=
true
;
break
; }
break
;
activatedWindow
=
this
;
closePopups
=
true
;
break
; }
if
(
activatedWindow
) {
rootWindow
=
activatedWindow
;
exceptions
.
Add
(
rootWindow
);
while
(
auto
parentWindow
=
rootWindow
->
parentWindow
) {
rootWindow
=
parentWindow
;
exceptions
.
Add
(
parentWindow
); } }
if
(
closePopups
) {
List
<
IWindowsForm
*>
allRootWindows
;
GetAllCreatedWindows
(
allRootWindows
,
true
);
for
(
vint
i
=
0
;
i
<
allRootWindows
.
Count
();
i
++) {
if
(
auto
windowsForm
=
dynamic_cast
<
WindowsForm
*>(
allRootWindows
[
i
])) {
ClosePopupsOf
(
windowsForm
,
exceptions
); } } } }
bool
nonClient
=
false
;
switch
(
uMsg
) {
// ************************************** moving and sizing
{
LPRECT
rawBounds
=(
LPRECT
)
lParam
;
NativeRect
bounds
(
rawBounds
->
left
,
rawBounds
->
top
,
rawBounds
->
right
,
rawBounds
->
bottom
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) { }
if
(
rawBounds
->
left
!=
bounds
.
Left
().
value
||
rawBounds
->
top
!=
bounds
.
Top
().
value
||
rawBounds
->
right
!=
bounds
.
Right
().
value
||
rawBounds
->
bottom
!=
bounds
.
Bottom
().
value
) {
rawBounds
->
left
=(
int
)
bounds
.
Left
().
value
;
rawBounds
->
top
=(
int
)
bounds
.
Top
().
value
;
rawBounds
->
right
=(
int
)
bounds
.
Right
().
value
;
rawBounds
->
bottom
=(
int
)
bounds
.
Bottom
().
value
; } }
break
; {
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
Moved
(); } }
break
; {
UpdateDpiAwaredFields
(
false
);
auto
newRect
= (
RECT
*)
lParam
;
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
DpiChanged
(); } }
break
;
// ************************************** state
{
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) { {
listeners
[
i
]->
Enabled
(); }
else
{
listeners
[
i
]->
Disabled
(); } } }
break
; {
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
GotFocus
(); } }
break
; {
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
LostFocus
(); } }
break
;
if
(!
enabledActivate
) {
return
true
; }
break
; {
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) { {
listeners
[
i
]->
Activated
(); }
else
{
listeners
[
i
]->
Deactivated
(); } } }
break
;
if
(
lParam
==
0
) { {
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
Opened
(); } }
else
{
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
Closed
(); } } }
break
; {
bool
cancel
=
false
;
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
Closing
(
cancel
); }
return
cancel
; }
break
;
// ************************************** mouse
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
LeftButtonDown
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
LeftButtonUp
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
LeftButtonDoubleClick
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
RightButtonDown
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
RightButtonUp
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
RightButtonDoubleClick
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
MiddleButtonDown
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
MiddleButtonUp
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
MiddleButtonDoubleClick
(
info
); } }
break
;
if
(!
customFrameMode
)
break
;
nonClient
=
true
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
false
,
nonClient
);
if
(
info
.
x
!
=
mouseLastX
||
info
.
y
!=
mouseLastY
) {
if
(!
mouseHoving
) {
mouseHoving
=
true
;
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
MouseEntered
(); }
TrackMouse
(
true
); }
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
MouseMoving
(
info
); } } }
break
;
// ************************************** wheel
{
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
true
,
false
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
HorizontalWheel
(
info
); } }
break
; {
NativeWindowMouseInfo
info
=
ConvertMouse
(
wParam
,
lParam
,
true
,
false
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
VerticalWheel
(
info
); } }
break
;
// ************************************** mouse state
nonClient
=
true
;
if
(
customFrameMode
==
nonClient
) {
mouseLastX
=-
1
;
mouseLastY
=-
1
;
mouseHoving
=
false
;
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
MouseLeaved
(); } }
break
; {
TrackMouse
(
true
); }
break
;
// ************************************** key
{
NativeWindowKeyInfo
info
=
ConvertKey
(
wParam
,
lParam
);
info
.
autoRepeatKeyDown
=
false
;
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
KeyUp
(
info
); } }
break
; {
NativeWindowKeyInfo
info
=
ConvertKey
(
wParam
,
lParam
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
KeyDown
(
info
); } }
break
; {
NativeWindowKeyInfo
info
=
ConvertKey
(
wParam
,
lParam
);
info
.
autoRepeatKeyDown
=
false
;
if
(
supressingAlt
&& !
info
.
ctrl
&& !
info
.
shift
&&
info
.
code
==
VKEY
::
_MENU
) {
supressingAlt
=
false
;
break
; }
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
SysKeyUp
(
info
); } }
break
; {
NativeWindowKeyInfo
info
=
ConvertKey
(
wParam
,
lParam
);
if
(
supressingAlt
&& !
info
.
ctrl
&& !
info
.
shift
&&
info
.
code
==
VKEY
::
_MENU
) {
break
; }
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
SysKeyDown
(
info
); } }
break
; {
NativeWindowCharInfo
info
=
ConvertChar
(
wParam
);
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
Char
(
info
); } }
break
;
// ************************************** painting
{
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
Paint
(); } }
break
;
result
=
0
;
return
true
;
if
(
customFrameMode
) {
result
=
0
;
return
true
; }
break
;
// ************************************** IME
{
HIMC
imc
=
ImmGetContext
(
handle
);
ImmAssociateContext
(
hwnd
,
imc
);
ImmReleaseContext
(
handle
,
imc
); }
break
;
UpdateCompositionForContent
();
break
;
// ************************************** hit test
{
NativePoint
windowLocation
=
GetBounds
().
LeftTop
();
location
.
x
-=(
SHORT
)
windowLocation
.
x
.
value
;
location
.
y
-=(
SHORT
)
windowLocation
.
y
.
value
;
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
switch
(
listeners
[
i
]->
HitTest
(
NativePoint
(
location
.
x
,
location
.
y
))) {
case
INativeWindowListener
::
BorderNoSizing
:
return
true
;
case
INativeWindowListener
::
BorderLeft
:
return
true
;
case
INativeWindowListener
::
BorderRight
:
return
true
;
case
INativeWindowListener
::
BorderTop
:
return
true
;
case
INativeWindowListener
::
BorderBottom
:
return
true
;
case
INativeWindowListener
::
BorderLeftTop
:
return
true
;
case
INativeWindowListener
::
BorderRightTop
:
return
true
;
case
INativeWindowListener
::
BorderLeftBottom
:
return
true
;
case
INativeWindowListener
::
BorderRightBottom
:
return
true
;
case
INativeWindowListener
::
Title
:
return
true
;
case
INativeWindowListener
::
ButtonMinimum
:
return
true
;
case
INativeWindowListener
::
ButtonMaximum
:
return
true
;
case
INativeWindowListener
::
ButtonClose
:
return
true
;
case
INativeWindowListener
::
Client
:
return
true
;
case
INativeWindowListener
::
Icon
:
return
true
; } } }
break
;
// ************************************** MISC
{ {
HCURSOR
cursorHandle
=
cursor
->
GetCursorHandle
();
if
(
GetCursor
()!=
cursorHandle
) {
SetCursor
(
cursorHandle
); }
return
true
; } }
break
;
if
((
BOOL
)
wParam
&&
customFrameMode
) {
result
=
0
;
return
true
; }
break
;
if
(
customFrameMode
) { { }
else
{ }
return
true
; }
break
; }
// handling custom frame
if
(
customFrameMode
) {
switch
(
uMsg
) {
switch
(
wParam
) {
result
=
0
;
return
true
; }
break
; {
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
switch
(
listeners
[
i
]->
HitTest
(
NativePoint
(
location
.
x
,
location
.
y
))) {
case
INativeWindowListener
::
ButtonMinimum
:
ShowMinimized
();
return
false
;
case
INativeWindowListener
::
ButtonMaximum
:
if
(
GetSizeState
() ==
INativeWindow
::
Maximized
) {
ShowRestored
(); }
else
{
ShowMaximized
(); }
return
false
;
case
INativeWindowListener
::
ButtonClose
:
Hide
(
true
);
return
false
; } } }
break
; } }
return
false
; }
protected
:
HWND
handle
;
WString
title
;
WindowsCursor
*
cursor
=
nullptr
;
NativePoint
caretPoint
;
WindowsForm
*
parentWindow
=
nullptr
;
List
<
WindowsForm
*>
childWindows
;
WindowMode
windowMode
;
List
<
INativeWindowListener
*>
listeners
;
vint
mouseLastX
= -
1
;
vint
mouseLastY
= -
1
;
bool
mouseHoving
=
false
;
Interface
*
graphicsHandler
=
nullptr
;
bool
customFrameMode
=
false
;
bool
enabledActivate
=
true
;
List
<
Ptr
<
INativeMessageHandler
>>
messageHandlers
;
bool
supressingAlt
=
false
;
Ptr
<
bool
>
flagDisposed
=
new
bool
(
false
);
NativeMargin
customFramePadding
;
Ptr
<
GuiImageData
>
defaultIcon
;
Ptr
<
GuiImageData
>
replacementIcon
;
UINT
dpiX
=
0
;
UINT
dpiY
=
0
;
void
UpdateDpiAwaredFields
(
bool
refreshDpiXY
) {
if
(
refreshDpiXY
) {
DpiAwared_GetDpiForWindow
(
handle
, &
dpiX
, &
dpiY
); }
customFramePadding
=
NativeMargin
(
padding
,
padding
,
padding
,
padding
); }
public
:
WindowsForm
(
HWND
parent
,
WString
className
,
HINSTANCE
hInstance
,
INativeWindow
::
WindowMode
_windowMode
) :windowMode(
_windowMode
) { { }
if
(
windowMode
==
INativeWindow
::
Normal
) {
// use WS_POPUP in CreateWindowEx, because CW_USERDEFAULT is interpreted as 0, unlike WS_OVERLAPPED
// if this is not a popup window, replace WS_POPUP with WS_OVERLAPPED
auto
style
=
InternalGetStyle
();
InternalSetStyle
(
style
); }
UpdateDpiAwaredFields
(
true
); }
~
WindowsForm
() {
if
(
parentWindow
) {
parentWindow
->
childWindows
.
Remove
(
this
); }
for
(
vint
i
=
childWindows
.
Count
() -
1
;
i
>=
0
;
i
--) {
childWindows
[
i
]->
SetParent
(
parentWindow
); } *
flagDisposed
.
Obj
() =
true
;
List
<
INativeWindowListener
*>
copiedListeners
;
CopyFrom
(
copiedListeners
,
listeners
);
for
(
vint
i
=
0
;
i
<
copiedListeners
.
Count
();
i
++) {
INativeWindowListener
*
listener
=
copiedListeners
[
i
];
if
(
listeners
.
Contains
(
listener
)) {
listener
->
Destroyed
(); } }
DestroyWindow
(
handle
); }
void
InvokeDestroying
() {
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
Destroying
(); } }
bool
HandleMessage
(
HWND
hwnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
,
LRESULT
&
result
) {
#define CHECK_DISPOSED if (*flag.Obj()) return skip
auto
flag
=
flagDisposed
;
bool
skip
=
false
; { {
handler
-
>
BeforeHandle
(
hwnd
,
uMsg
,
wParam
,
lParam
,
skip
); }
if
(
skip
) {
return
true
; } }
skip
=
HandleMessageInternal
(
hwnd
,
uMsg
,
wParam
,
lParam
,
result
);
if
(
GetWindowsFormFromHandle
(
hwnd
)) { {
handler
-
>
AfterHandle
(
hwnd
,
uMsg
,
wParam
,
lParam
,
skip
,
result
); } }
return
skip
;
#undef CHECK_DISPOSED
}
HWND
GetWindowHandle
()
override
{
return
handle
; }
Interface
*
GetGraphicsHandler
()
override
{
return
graphicsHandler
; }
void
SetGraphicsHandler
(
Interface
*
handler
)
override
{
graphicsHandler
=
handler
; }
bool
InstallMessageHandler
(
Ptr
<
INativeMessageHandler
>
handler
)
override
{
if
(
messageHandlers
.
Contains
(
handler
.
Obj
())) {
return
false
; }
messageHandlers
.
Add
(
handler
);
return
true
; }
bool
UninstallMessageHandler
(
Ptr
<
INativeMessageHandler
>
handler
)
override
{
vint
index
=
messageHandlers
.
IndexOf
(
handler
.
Obj
());
if
(
index
== -
1
)
return
false
;
messageHandlers
.
RemoveAt
(
handler
);
return
true
; }
Point
Convert
(
NativePoint
value
)
override
{
return
Point
((
vint
)
value
.
x
.
value
*
96
/
dpiX
, (
vint
)
value
.
y
.
value
*
96
/
dpiY
); }
NativePoint
Convert
(
Point
value
)
override
{
return
NativePoint
(
value
.
x
*
dpiX
/
96
,
value
.
y
*
dpiY
/
96
); }
Size
Convert
(
NativeSize
value
)
override
{
return
Size
((
vint
)
value
.
x
.
value
*
96
/
dpiX
, (
vint
)
value
.
y
.
value
*
96
/
dpiY
); }
NativeSize
Convert
(
Size
value
)
override
{
return
NativeSize
(
value
.
x
*
dpiX
/
96
,
value
.
y
*
dpiY
/
96
); }
Margin
Convert
(
NativeMargin
value
)
override
{
return
Margin
( (
vint
)
value
.
left
.
value
*
96
/
dpiX
, (
vint
)
value
.
top
.
value
*
96
/
dpiY
, (
vint
)
value
.
right
.
value
*
96
/
dpiX
, (
vint
)
value
.
bottom
.
value
*
96
/
dpiY
); }
NativeMargin
Convert
(
Margin
value
)
override
{
return
NativeMargin
( (
vint
)
value
.
left
*
dpiX
/
96
, (
vint
)
value
.
top
*
dpiY
/
96
, (
vint
)
value
.
right
*
dpiX
/
96
, (
vint
)
value
.
bottom
*
dpiY
/
96
); }
NativeRect
GetBounds
()
override
{
RECT
rect
;
GetWindowRect
(
handle
, &
rect
);
return
NativeRect
(
rect
.
left
,
rect
.
top
,
rect
.
right
,
rect
.
bottom
); }
void
SetBounds
(
const
NativeRect
&
bounds
)
override
{
NativeRect
newBounds
=
bounds
;
for
(
vint
i
=
0
;
i
<
listeners
.
Count
();
i
++) {
listeners
[
i
]->
Moving
(
newBounds
,
true
,
false
); } }
NativeSize
GetClientSize
()
override
{
return
GetClientBoundsInScreen
().
GetSize
(); }
void
SetClientSize
(
NativeSize
size
)
override
{
RECT
required
={
0
,
0
,(
int
)
size
.
x
.
value
,(
int
)
size
.
y
.
value
};
RECT
bounds
;
GetWindowRect
(
handle
, &
bounds
);
DpiAwared_AdjustWindowRect
(&
required
,
handle
,
dpiX
);
SetBounds
(
NativeRect
(
NativePoint
(
bounds
.
left
,
bounds
.
top
),
NativeSize
(
required
.
right
-
required
.
left
,
required
.
bottom
-
required
.
top
))); }
NativeRect
GetClientBoundsInScreen
()
override
{
if
(
customFrameMode
) {
return
GetBounds
(); }
else
{
RECT
required
={
0
,
0
,
0
,
0
};
RECT
bounds
;
GetWindowRect
(
handle
, &
bounds
);
DpiAwared_AdjustWindowRect
(&
required
,
handle
,
dpiX
);
return
NativeRect
(
NativePoint
( (
bounds
.
left
-
required
.
left
), (
bounds
.
top
-
required
.
top
) ),
NativeSize
( (
bounds
.
right
-
bounds
.
left
)-(
required
.
right
-
required
.
left
), (
bounds
.
bottom
-
bounds
.
top
)-(
required
.
bottom
-
required
.
top
) ) ); } }
WString
GetTitle
()
override
{
return
title
; }
void
SetTitle
(
WString
_title
)
override
{
title
=
_title
; }
INativeCursor
*
GetWindowCursor
()
override
{
return
cursor
; }
void
SetWindowCursor
(
INativeCursor
*
_cursor
)
override
{
WindowsCursor
*
newCursor
=
dynamic_cast
<
WindowsCursor
*>(
_cursor
);
if
(
newCursor
&&
cursor
!=
newCursor
) {
cursor
=
newCursor
;
if
(
mouseHoving
&&
IsVisible
()) {
SetCursor
(
cursor
->
GetCursorHandle
()); } } }
NativePoint
GetCaretPoint
()
override
{
return
caretPoint
; }
void
SetCaretPoint
(
NativePoint
point
)
override
{
caretPoint
=
point
;
UpdateCompositionForContent
(); }
INativeWindow
*
GetParent
()
override
{
return
parentWindow
; }
void
SetParent
(
INativeWindow
*
parent
)
override
{
if
(
parentWindow
) {
parentWindow
->
childWindows
.
Remove
(
this
); }
if
((
parentWindow
=
dynamic_cast
<
WindowsForm
*>(
parent
))) {
parentWindow
->
childWindows
.
Add
(
this
);
// ::SetParent(handle, parentWindow->handle);
}
else
{
// ::SetParent(handle, NULL);
} }
WindowMode
GetWindowMode
()
override
{
return
windowMode
; }
void
EnableCustomFrameMode
()
override
{
customFrameMode
=
true
; }
void
DisableCustomFrameMode
()
override
{
customFrameMode
=
false
; }
bool
IsCustomFrameModeEnabled
()
override
{
return
customFrameMode
; }
NativeMargin
GetCustomFramePadding
()
override
{
if
(
GetSizeBox
() ||
GetTitleBar
()) {
return
customFramePadding
; }
else
{
return
NativeMargin
(
0
,
0
,
0
,
0
); } }
Ptr
<
GuiImageData
>
GetIcon
()
override
{
if
(
replacementIcon
&&
replacementIcon
-
>
GetImage
()) {
return
replacementIcon
; }
else
{
if
(!
defaultIcon
) {
auto
icon
=
CreateWindowDefaultIcon
(
16
); { } {
defaultIcon
=
new
GuiImageData
(
CreateImageFromHICON
(
icon
),
0
); } }
return
defaultIcon
; } }
static
double
GetSizeScore
(
vint
size
) {
if
(
size
>
32
) {
return
32.0
/
size
; }
else
if
(
size
<
32
) {
return
size
/
32.0
-
1
; }
else
{
return
1.0
; } }
static
vint
GetBppFromFormat
(
const
WICPixelFormatGUID
&
format
) {
if
(
format
==
GUID_WICPixelFormat1bppIndexed
)
return
1
;
if
(
format
==
GUID_WICPixelFormat2bppIndexed
)
return
2
;
if
(
format
==
GUID_WICPixelFormat4bppIndexed
)
return
4
;
if
(
format
==
GUID_WICPixelFormat8bppIndexed
)
return
8
;
if
(
format
==
GUID_WICPixelFormatBlackWhite
)
return
1
;
if
(
format
==
GUID_WICPixelFormat2bppGray
)
return
2
;
if
(
format
==
GUID_WICPixelFormat4bppGray
)
return
4
;
if
(
format
==
GUID_WICPixelFormat8bppGray
)
return
8
;
if
(
format
==
GUID_WICPixelFormat8bppAlpha
)
return
8
;
if
(
format
==
GUID_WICPixelFormat16bppBGR555
)
return
16
;
if
(
format
==
GUID_WICPixelFormat16bppBGR565
)
return
16
;
if
(
format
==
GUID_WICPixelFormat16bppBGRA5551
)
return
16
;
if
(
format
==
GUID_WICPixelFormat16bppGray
)
return
16
;
if
(
format
==
GUID_WICPixelFormat24bppBGR
)
return
24
;
if
(
format
==
GUID_WICPixelFormat24bppRGB
)
return
24
;
if
(
format
==
GUID_WICPixelFormat32bppBGR
)
return
32
;
if
(
format
==
GUID_WICPixelFormat32bppBGRA
)
return
32
;
if
(
format
==
GUID_WICPixelFormat32bppPBGRA
)
return
32
;
return
-
1
; }
void
SetIcon
(
Ptr
<
GuiImageData
>
icon
)
override
{
replacementIcon
=
icon
;
if
(
replacementIcon
&&
replacementIcon
-
>
GetImage
()) {
stream
::
MemoryStream
memoryStream
;
replacementIcon
-
>
GetImage
()
-
>
SaveToStream
(
memoryStream
,
INativeImage
::
Icon
);
if
(
memoryStream
.
Size
() >
0
) { {
goto
SKIP; } }
INativeImageFrame
*
selectedFrame
=
nullptr
;
for
(
vint
i
=
0
;
i
<
replacementIcon
-
>
GetImage
()
-
>
GetFrameCount
();
i
++) {
auto
frame
=
replacementIcon
-
>
GetImage
()
-
>
GetFrame
(
i
);
auto
size
=
frame
->
GetSize
();
if
(
size
.
x
==
size
.
y
) {
auto
bitmap
=
GetWICBitmap
(
frame
);
WICPixelFormatGUID
format
;
HRESULT
hr
=
bitmap
->
GetPixelFormat
(&
format
);
if
(!
selectedFrame
) {
selectedFrame
=
frame
; }
else
{
auto
score
=
GetSizeScore
(
size
.
x
);
auto
scoreSelected
=
GetSizeScore
(
selectedFrame
->
GetSize
().
x
);
if
(
score
>
scoreSelected
) {
selectedFrame
=
frame
; }
else
if
(
score
==
scoreSelected
) {
WICPixelFormatGUID
selectedFormat
;
auto
selectedBitmap
=
GetWICBitmap
(
selectedFrame
);
hr
=
selectedBitmap
->
GetPixelFormat
(&
selectedFormat
);
auto
bpp
=
GetBppFromFormat
(
format
);
auto
bppSelected
=
GetBppFromFormat
(
selectedFormat
);
if
(
bpp
>
bppSelected
) {
selectedFrame
=
frame
; } } } } }
if
(
selectedFrame
) {
bool
succeeded
=
false
;
WindowsBitmapImage
newBitmap
(
replacementIcon
-
>
GetImage
()
-
>
GetImageService
(),
GetWICBitmap
(
selectedFrame
),
replacementIcon
-
>
GetImage
()
-
>
GetFormat
());
newBitmap
.
SaveToStream
(
memoryStream
,
INativeImage
::
Bmp
);
if
(
memoryStream
.
Size
() >
0
) {
auto
pBuffer
= (
char
*)
memoryStream
.
GetInternalBuffer
();
tagBITMAPFILEHEADER
bfh
= *(
tagBITMAPFILEHEADER
*)
pBuffer
;
tagBITMAPINFOHEADER
bih
= *(
tagBITMAPINFOHEADER
*)(
pBuffer
+
sizeof
(
tagBITMAPFILEHEADER
));
RGBQUAD
rgb
= *(
RGBQUAD
*)(
pBuffer
+
sizeof
(
tagBITMAPFILEHEADER
) +
sizeof
(
tagBITMAPINFOHEADER
));
BITMAPINFO
bi
;
bi
.
bmiColors
[
0
]
=
rgb
;
bi
.
bmiHeader
=
bih
;
char
*
pPixels
= (
pBuffer
+
bfh
.
bfOffBits
);
char
*
ppvBits
; { {
ImageList_Destroy
(
himl
); }
DeleteObject
(
hBitmap
); } } } } SKIP: {
HICON
hAppIcon
=
newReplacementHIcon
;
bool
isVisible
=
IsVisible
();
if
(
this
==
GetCurrentController
()->
WindowService
()->
GetMainWindow
()) { } } {
DestroyIcon
(
replacementHIcon
); }
replacementHIcon
=
newReplacementHIcon
; }
WindowSizeState
GetSizeState
()
override
{
if
(
IsIconic
(
handle
)) {
return
INativeWindow
::
Minimized
; }
else
if
(
IsZoomed
(
handle
)) {
return
INativeWindow
::
Maximized
; }
else
{
return
INativeWindow
::
Restored
; } }
void
Show
()
override
{ }
void
ShowDeactivated
()
override
{ }
void
ShowRestored
()
override
{ }
void
ShowMaximized
()
override
{ }
void
ShowMinimized
()
override
{ }
void
Hide
(
bool
closeWindow
)
override
{
if
(
closeWindow
) { }
else
{ } }
bool
IsVisible
()
override
{
return
IsWindowVisible
(
handle
)!=
0
; }
void
Enable
()
override
{ }
void
Disable
()
override
{ }
bool
IsEnabled
()
override
{
return
IsWindowEnabled
(
handle
)!=
0
; }
void
SetFocus
()
override
{ ::
SetFocus
(
handle
); }
bool
IsFocused
()
override
{
return
GetFocus
()==
handle
; }
void
SetActivate
()
override
{
SetActiveWindow
(
handle
); }
bool
IsActivated
()
override
{
return
GetActiveWindow
()==
handle
; }
void
ShowInTaskBar
()
override
{ }
void
HideInTaskBar
()
override
{ }
bool
IsAppearedInTaskBar
()
override
{ }
void
EnableActivate
()
override
{
enabledActivate
=
true
; }
void
DisableActivate
()
override
{
enabledActivate
=
false
; }
bool
IsEnabledActivate
()
override
{
return
enabledActivate
; }
bool
RequireCapture
()
override
{
SetCapture
(
handle
);
return
true
; }
bool
ReleaseCapture
()
override
{ ::
ReleaseCapture
();
return
true
; }
bool
IsCapturing
()
override
{
return
GetCapture
()==
handle
; }
bool
GetMaximizedBox
()
override
{ }
void
SetMaximizedBox
(
bool
visible
)
override
{ }
bool
GetMinimizedBox
()
override
{ }
void
SetMinimizedBox
(
bool
visible
)
override
{ }
bool
GetBorder
()
override
{ }
void
SetBorder
(
bool
visible
)
override
{ }
bool
GetSizeBox
()
override
{ }
void
SetSizeBox
(
bool
visible
)
override
{ }
bool
GetIconVisible
()
override
{ }
void
SetIconVisible
(
bool
visible
)
override
{ }
bool
GetTitleBar
()
override
{ }
void
SetTitleBar
(
bool
visible
)
override
{ }
bool
GetTopMost
()
override
{ }
void
SetTopMost
(
bool
topmost
)
override
{ }
void
SupressAlt
()
override
{
if
(!
supressingAlt
) {
supressingAlt
=
true
; } }
bool
InstallListener
(
INativeWindowListener
*
listener
)
override
{
if
(
listeners
.
Contains
(
listener
)) {
return
false
; }
else
{
listeners
.
Add
(
listener
);
return
true
; } }
bool
UninstallListener
(
INativeWindowListener
*
listener
)
override
{
if
(
listeners
.
Contains
(
listener
)) {
listeners
.
Remove
(
listener
);
return
true
; }
else
{
return
false
; } }
void
RedrawContent
()
override
{
if
(
graphicsHandler
) { } } };
/*********************************************************************** WindowsController ***********************************************************************/
class
WindowsController
:
public
Object
,
public
virtual
INativeController
,
public
virtual
INativeWindowService
{
protected
:
WinClass
windowClass
;
WinClass
godClass
;
HINSTANCE
hInstance
;
HWND
godWindow
;
Dictionary
<
HWND
,
WindowsForm
*>
windows
;
INativeWindow
*
mainWindow
;
HWND
mainWindowHandle
;
WindowsCallbackService
callbackService
;
WindowsResourceService
resourceService
;
WindowsAsyncService
asyncService
;
WindowsClipboardService
clipboardService
;
WindowsImageService
imageService
;
WindowsScreenService
screenService
;
WindowsInputService
inputService
;
WindowsDialogService
dialogService
;
public
:
WindowsController
(
HINSTANCE
_hInstance
) :hInstance(
_hInstance
) ,windowClass(
L"VczhWindow"
,
false
,
false
,
WndProc
,
_hInstance
) ,godClass(
L"GodWindow"
,
false
,
false
,
GodProc
,
_hInstance
) ,mainWindow(
0
) ,mainWindowHandle(
0
) ,screenService(&
GetHWNDFromNativeWindowHandle
) ,dialogService(&
GetHWNDFromNativeWindowHandle
) {
clipboardService
.
SetOwnerHandle
(
godWindow
);
inputService
.
SetOwnerHandle
(
godWindow
); }
~
WindowsController
() {
inputService
.
StopTimer
();
DestroyWindow
(
godWindow
); }
WindowsForm
*
GetWindowsFormFromHandle
(
HWND
hwnd
) {
vint
index
=
windows
.
Keys
().
IndexOf
(
hwnd
);
if
(
index
== -
1
)
return
0
;
return
windows
.
Values
()
[
index
]; }
void
GetAllCreatedWindows
(
collections
::
List
<
IWindowsForm
*>&
createdWindows
,
bool
rootWindowOnly
) {
if
(
rootWindowOnly
) { {
if
(
window
->
GetWindowMode
() ==
INativeWindow
::
Normal
) {
createdWindows
.
Add
(
window
); } } }
else
{
CopyFrom
(
createdWindows
,
windows
.
Values
()); } }
bool
HandleMessage
(
HWND
hwnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
,
LRESULT
&
result
) {
bool
skipDefaultProcedure
=
false
; {
vint
index
=
windows
.
Keys
().
IndexOf
(
hwnd
);
if
(
index
!= -
1
) {
WindowsForm
*
window
=
windows
.
Values
().
Get
(
index
);
skipDefaultProcedure
=
window
->
HandleMessage
(
hwnd
,
uMsg
,
wParam
,
lParam
,
result
);
switch
(
uMsg
) {
if
(!
skipDefaultProcedure
) {
if
(
window
!=
mainWindow
) {
skipDefaultProcedure
=
true
; } }
break
;
DestroyNativeWindow
(
window
);
break
; } } } { { {
if
(
window
->
IsVisible
()) {
window
->
Hide
(
true
); } }
List
<
WindowsForm
*>
normalWindows
;
CopyFrom
(
normalWindows
,
From
(
windows
.
Values
()) .
Where
([](
WindowsForm
*
window
) {
return
window
->
GetWindowMode
() ==
INativeWindow
::
Normal
; }) ); {
DestroyNativeWindow
(
window
); }
for
(
vint
i
=
windows
.
Count
() -
1
;
i
>=
0
;
i
--) {
auto
window
=
windows
.
Values
()
[
i
];
DestroyNativeWindow
(
window
); }
PostQuitMessage
(
0
); } }
return
skipDefaultProcedure
; }
//=======================================================================
INativeWindow
*
CreateNativeWindow
(
INativeWindow
::
WindowMode
windowMode
)
override
{
WindowsForm
*
window
=
new
WindowsForm
(
godWindow
,
windowClass
.
GetName
(),
hInstance
,
windowMode
);
windows
.
Add
(
window
->
GetWindowHandle
(),
window
);
callbackService
.
InvokeNativeWindowCreated
(
window
);
window
->
SetWindowCursor
(
resourceService
.
GetDefaultSystemCursor
());
return
window
; }
void
DestroyNativeWindow
(
INativeWindow
*
window
)
override
{
WindowsForm
*
windowsForm
=
dynamic_cast
<
WindowsForm
*>(
window
);
windowsForm
->
InvokeDestroying
();
if
(
windowsForm
!=
0
&&
windows
.
Keys
().
Contains
(
windowsForm
->
GetWindowHandle
())) {
callbackService
.
InvokeNativeWindowDestroyed
(
window
);
windows
.
Remove
(
windowsForm
->
GetWindowHandle
());
delete
windowsForm
; } }
INativeWindow
*
GetMainWindow
()
override
{
return
mainWindow
; }
void
Run
(
INativeWindow
*
window
)
override
{
mainWindow
=
window
;
mainWindowHandle
=
GetWindowsForm
(
window
)->
GetWindowHandle
();
mainWindow
->
Show
();
MSG
message
; {
TranslateMessage
(&
message
);
asyncService
.
ExecuteAsyncTasks
(); } }
INativeWindow
*
GetWindow
(
NativePoint
location
)
override
{
POINT
p
;
p
.
x
=(
int
)
location
.
x
.
value
;
p
.
y
=(
int
)
location
.
y
.
value
;
HWND
handle
=
WindowFromPoint
(
p
);
vint
index
=
windows
.
Keys
().
IndexOf
(
handle
);
if
(
index
==-
1
) {
return
0
; }
else
{
return
windows
.
Values
().
Get
(
index
); } }
//=======================================================================
INativeCallbackService
*
CallbackService
() {
return
&
callbackService
; }
INativeResourceService
*
ResourceService
() {
return
&
resourceService
; }
INativeAsyncService
*
AsyncService
() {
return
&
asyncService
; }
INativeClipboardService
*
ClipboardService
() {
return
&
clipboardService
; }
INativeImageService
*
ImageService
() {
return
&
imageService
; }
INativeScreenService
*
ScreenService
() {
return
&
screenService
; }
INativeWindowService
*
WindowService
() {
return
this
; }
INativeInputService
*
InputService
() {
return
&
inputService
; }
INativeDialogService
*
DialogService
() {
return
&
dialogService
; }
WString
GetExecutablePath
() {
Array
<
wchar_t
>
buffer
(
65536
);
return
&
buffer
[
0
]; }
//=======================================================================
void
InvokeGlobalTimer
() {
callbackService
.
InvokeGlobalTimer
(); }
void
InvokeClipboardUpdated
() {
callbackService
.
InvokeClipboardUpdated
(); } };
/*********************************************************************** Windows Procedure ***********************************************************************/
{
WindowsController
*
controller
=
dynamic_cast
<
WindowsController
*>(
GetCurrentController
());
if
(
controller
) {
LRESULT
result
=
0
;
if
(
controller
->
HandleMessage
(
hwnd
,
uMsg
,
wParam
,
lParam
,
result
)) {
return
result
; } } } {
WindowsController
*
controller
=
dynamic_cast
<
WindowsController
*>(
GetCurrentController
());
if
(
controller
) {
switch
(
uMsg
) {
controller
->
InvokeGlobalTimer
();
break
;
controller
->
InvokeClipboardUpdated
();
break
; } } }
/*********************************************************************** Windows Platform Native Controller ***********************************************************************/
INativeController
*
CreateWindowsNativeController
(
HINSTANCE
hInstance
) {
return
new
WindowsController
(
hInstance
); }
IWindowsForm
*
GetWindowsFormFromHandle
(
HWND
hwnd
) {
auto
controller
=
dynamic_cast
<
WindowsController
*>(
GetCurrentController
());
if
(
controller
) {
return
controller
->
GetWindowsFormFromHandle
(
hwnd
); }
return
nullptr
; }
IWindowsForm
*
GetWindowsForm
(
INativeWindow
*
window
) {
return
dynamic_cast
<
WindowsForm
*>(
window
); }
void
GetAllCreatedWindows
(
collections
::
List
<
IWindowsForm
*>&
windows
,
bool
rootWindowOnly
) {
auto
controller
=
dynamic_cast
<
WindowsController
*>(
GetCurrentController
());
if
(
controller
) {
controller
->
GetAllCreatedWindows
(
windows
,
rootWindowOnly
); } }
void
DestroyWindowsNativeController
(
INativeController
*
controller
) {
delete
controller
; }
void
EnableCrossKernelCrashing
() {
/* "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options" DWORD DisableUserModeCallbackFilter = 1 "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\TestCppCodegen.exe" DWORD DisableUserModeCallbackFilter = 1 */
const
DWORD
EXCEPTION_SWALLOWING
=
0x1
;
tGetPolicy
pGetPolicy
= (
tGetPolicy
)
GetProcAddress
(
kernel32
,
"GetProcessUserModeExceptionPolicy"
);
tSetPolicy
pSetPolicy
= (
tSetPolicy
)
GetProcAddress
(
kernel32
,
"SetProcessUserModeExceptionPolicy"
);
if
(
pGetPolicy
&&
pSetPolicy
) {
DWORD
dwFlags
;
if
(
pGetPolicy
(&
dwFlags
)) {
// Turn off the filter
pSetPolicy
(
dwFlags
& ~
EXCEPTION_SWALLOWING
); } } } } } }