├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE-APACHE
├── LICENSE-GPL
├── Misc
├── Logo.png
└── Logo.svg
├── README.md
├── Samples
├── Sample.DirectX
│ ├── App.config
│ ├── Extensions.cs
│ ├── MainWindow.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Sample.DirectX.csproj
│ ├── app.manifest
│ └── packages.config
├── Sample.Native.Atl
│ ├── CAppWindow.cpp
│ ├── CAppWindow.h
│ ├── Sample.Native.Atl.vcxproj
│ ├── Sample.Native.Atl.vcxproj.filters
│ ├── main.cpp
│ └── pch.h
├── Sample.Native.Win32
│ ├── Sample.Native.Win32.vcxproj
│ ├── Sample.Native.Win32.vcxproj.filters
│ └── main.cpp
├── Sample.OpenGL
│ ├── App.config
│ ├── OpenGlWindow.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Sample.OpenGL.csproj
│ ├── app.manifest
│ └── packages.config
├── Sample.SimpleWindow
│ ├── App.config
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Sample.SimpleWindow.csproj
│ ├── app.manifest
│ └── packages.config
├── Sample.SimulateInput
│ ├── App.config
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Sample.SimulateInput.csproj
│ ├── app.manifest
│ └── packages.config
├── Sample.Skia
│ ├── App.config
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Sample.Skia.csproj
│ ├── SkiaWindow.cs
│ ├── app.manifest
│ └── packages.config
├── Sample.Win32
│ ├── App.config
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Sample.Win32.csproj
│ ├── app.manifest
│ └── packages.config
└── WinApi.TestGround
│ ├── App.config
│ ├── DebugLogger.cs
│ ├── Program.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── WinApi.TestGround.csproj
│ ├── app.manifest
│ └── packages.config
├── WinApi.Desktop
├── ApplicationHelpers.cs
├── ConsoleHelpers.cs
└── WinApi.Desktop.csproj
├── WinApi.DxUtils
├── Component
│ ├── ComposedD3DComponent.cs
│ └── Dx11Component.cs
├── Composition
│ ├── CompositionHelper.cs
│ ├── CompositorCore.cs
│ ├── WindowCompositor.cs
│ └── WindowSurfaceCompositor.cs
├── Core
│ ├── DxgiContainerBase.cs
│ └── Interfaces.cs
├── D2D1
│ ├── D2D1Helper.cs
│ ├── D2D1MetaFactory.cs
│ └── D2D1MetaResource.cs
├── D3D11
│ ├── D3D11Container.cs
│ ├── D3D11Dxgi1_2MetaResource.cs
│ ├── D3D11DxgiContainer.cs
│ ├── D3D11MetaFactory.cs
│ └── D3D11MetaResource.cs
├── DxPainter.cs
├── DxVersionInfo.txt
├── DxWindow.cs
├── Helpers.cs
└── WinApi.DxUtils.csproj
├── WinApi.Utils
├── DwmWindow.cs
├── DwmWindowHelper.cs
├── NativePixelBuffer.cs
├── Types.cs
└── WinApi.Utils.csproj
├── WinApi.Windows.Controls
├── Button.cs
├── EditBox.cs
├── Layouts
│ ├── HorizontalStretchLayout.cs
│ └── HorizontalStretchLayoutWithInnerMargin.cs
├── StaticBox.cs
├── WinApi.Windows.Controls.csproj
└── Window.cs
├── WinApi.sln
└── WinApi
├── Core
└── Types.cs
├── DwmApi
├── Helpers.cs
├── Methods.cs
└── Types.cs
├── Gdi32
├── CustomTypes.cs
├── Helpers.cs
├── Methods.cs
└── Types.cs
├── Kernel32
├── Constants.cs
├── Helpers.cs
├── Methods.cs
└── Types.cs
├── KernelBase
└── Methods.cs
├── Properties.cs
├── ShCore
├── Methods.cs
└── Types.cs
├── User32
├── Constants.cs
├── Experimental
│ ├── Helpers.cs
│ ├── Methods.cs
│ └── Types.cs
├── Helpers.cs
├── InputConstants.cs
├── InputTypes.cs
├── Methods.cs
└── Types.cs
├── UxTheme
├── Helpers.cs
├── Methods.cs
└── Types.cs
├── WinApi.csproj
└── Windows
├── ConstructionParams.cs
├── EventLoop.cs
├── EventedWindowCore.cs
├── Helpers
├── MessageBoxHelpers.cs
└── MessageHelpers.cs
├── NativeWindow.cs
├── PacketTypes.cs
├── Packetizer.cs
├── WindowCore.cs
└── WindowFactory.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | .vs/
5 | *.VC.db
6 | *.VC.opendb
7 | *project.lock.json
8 |
9 | # User-specific files
10 | *.suo
11 | *.user
12 | *.sln.docstates
13 | Thumbs.db
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | x64/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Roslyn cache directories
26 | *.ide/
27 |
28 | # MSTest test Results
29 | [Tt]est[Rr]esult*/
30 | [Bb]uild[Ll]og.*
31 |
32 | #NUNIT
33 | *.VisualState.xml
34 | TestResult.xml
35 |
36 | # Build Results of an ATL Project
37 | [Dd]ebugPS/
38 | [Rr]eleasePS/
39 | dlldata.c
40 |
41 | *_i.c
42 | *_p.c
43 | *_i.h
44 | *.ilk
45 | *.meta
46 | *.obj
47 | *.pch
48 | *.pdb
49 | *.pgc
50 | *.pgd
51 | *.rsp
52 | *.sbr
53 | *.tlb
54 | *.tli
55 | *.tlh
56 | *.tmp
57 | *.tmp_proj
58 | *.log
59 | *.vspscc
60 | *.vssscc
61 | .builds
62 | *.pidb
63 | *.svclog
64 | *.scc
65 |
66 | # Chutzpah Test files
67 | _Chutzpah*
68 |
69 | # Visual C++ cache files
70 | ipch/
71 | *.aps
72 | *.ncb
73 | *.opensdf
74 | *.sdf
75 | *.cachefile
76 |
77 | # Visual Studio profiler
78 | *.psess
79 | *.vsp
80 | *.vspx
81 |
82 | # TFS 2012 Local Workspace
83 | $tf/
84 |
85 | # Guidance Automation Toolkit
86 | *.gpState
87 |
88 | # ReSharper is a .NET coding add-in
89 | _ReSharper*/
90 | *.[Rr]e[Ss]harper
91 | *.DotSettings.user
92 |
93 | # JustCode is a .NET coding addin-in
94 | .JustCode
95 |
96 | # TeamCity is a build add-in
97 | _TeamCity*
98 |
99 | # DotCover is a Code Coverage Tool
100 | *.dotCover
101 |
102 | # NCrunch
103 | _NCrunch_*
104 | .*crunch*.local.xml
105 |
106 | # MightyMoose
107 | *.mm.*
108 | AutoTest.Net/
109 |
110 | # Web workbench (sass)
111 | .sass-cache/
112 |
113 | # Installshield output folder
114 | [Ee]xpress/
115 |
116 | # DocProject is a documentation generator add-in
117 | DocProject/buildhelp/
118 | DocProject/Help/*.HxT
119 | DocProject/Help/*.HxC
120 | DocProject/Help/*.hhc
121 | DocProject/Help/*.hhk
122 | DocProject/Help/*.hhp
123 | DocProject/Help/Html2
124 | DocProject/Help/html
125 |
126 | # Click-Once directory
127 | publish/
128 |
129 | # Publish Web Output
130 | *.[Pp]ublish.xml
131 | *.azurePubxml
132 | ## TODO: Comment the next line if you want to checkin your
133 | ## web deploy settings but do note that will include unencrypted
134 | ## passwords
135 | #*.pubxml
136 |
137 | # NuGet Packages Directory
138 | packages/*
139 | *.nupkg
140 | ## TODO: If the tool you use requires repositories.config
141 | ## uncomment the next line
142 | #!packages/repositories.config
143 |
144 | # Enable "build/" folder in the NuGet Packages folder since
145 | # NuGet packages use it for MSBuild targets.
146 | # This line needs to be after the ignore of the build folder
147 | # (and the packages folder if the line above has been uncommented)
148 | !packages/build/
149 |
150 | # Windows Azure Build Output
151 | csx/
152 | *.build.csdef
153 |
154 | # Windows Store app package directory
155 | AppPackages/
156 |
157 | # Others
158 | sql/
159 | *.Cache
160 | ClientBin/
161 | [Ss]tyle[Cc]op.*
162 | ~$*
163 | *~
164 | *.dbmdl
165 | *.dbproj.schemaview
166 | *.pfx
167 | *.publishsettings
168 | node_modules/
169 |
170 | # RIA/Silverlight projects
171 | Generated_Code/
172 |
173 | # Backup & report files from converting an old project file
174 | # to a newer Visual Studio version. Backup files are not needed,
175 | # because we have git ;-)
176 | _UpgradeReport_Files/
177 | Backup*/
178 | UpgradeLog*.XML
179 | UpgradeLog*.htm
180 |
181 | # SQL Server files
182 | *.mdf
183 | *.ldf
184 |
185 | # Business Intelligence projects
186 | *.rdl.data
187 | *.bim.layout
188 | *.bim_*.settings
189 |
190 | # Microsoft Fakes
191 | FakesAssemblies/
192 |
193 | # LightSwitch generated files
194 | GeneratedArtifacts/
195 | _Pvt_Extensions/
196 | ModelManifest.xml
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at pvl@prasannavl.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/Misc/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prasannavl/WinApi/48b583a8e09d39200e71fe5d6a875f862c457744/Misc/Logo.png
--------------------------------------------------------------------------------
/Misc/Logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
58 |
--------------------------------------------------------------------------------
/Samples/Sample.DirectX/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Samples/Sample.DirectX/Extensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Sample.DirectX
4 | {
5 | public static class RandomExtensions
6 | {
7 | public static float NextFloat(this Random random)
8 | {
9 | return (float) random.NextDouble();
10 | }
11 |
12 | public static float NextFloat(this Random random, int min, int max)
13 | {
14 | return (float) random.NextDouble()*(max - min) + min;
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/Samples/Sample.DirectX/MainWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct2D1;
4 | using SharpDX.Mathematics.Interop;
5 | using WinApi.Core;
6 | using WinApi.DxUtils.Component;
7 | using WinApi.User32;
8 | using WinApi.Utils;
9 | using WinApi.Windows;
10 |
11 | namespace Sample.DirectX
12 | {
13 | public sealed class MainWindow : EventedWindowCore
14 | {
15 | private readonly Dx11Component m_dx = new Dx11Component();
16 |
17 | protected override void OnCreate(ref CreateWindowPacket packet)
18 | {
19 | this.m_dx.Initialize(this.Handle, this.GetClientSize());
20 | base.OnCreate(ref packet);
21 | }
22 |
23 | protected override void OnPaint(ref PaintPacket packet)
24 | {
25 | var rand = new Random();
26 |
27 | var size = this.GetClientSize();
28 | var w = size.Width;
29 | var h = size.Height;
30 |
31 | this.m_dx.EnsureInitialized();
32 | try
33 | {
34 | var context = this.m_dx.D2D.Context;
35 |
36 | context.BeginDraw();
37 | context.Clear(new RawColor4(0, 0, 0, 0f));
38 | var b = new SolidColorBrush(context,
39 | new RawColor4(rand.NextFloat(), rand.NextFloat(), rand.NextFloat(), 0.4f));
40 |
41 | context.FillRectangle(new RawRectangleF(200, 200, 500, 700), b);
42 |
43 | for (var i = 0; i < 10; i++)
44 | {
45 | b.Color = new RawColor4(rand.NextFloat(), rand.NextFloat(), rand.NextFloat(), 0.4f);
46 | context.FillEllipse(
47 | new Ellipse(new RawVector2(rand.NextFloat(0, w), rand.NextFloat(0, h)), rand.NextFloat(0, w),
48 | rand.Next(0, h)), b);
49 | context.FillRectangle(
50 | new RawRectangleF(rand.NextFloat(0, w), rand.NextFloat(0, h), rand.NextFloat(0, w),
51 | rand.NextFloat(0, h)), b);
52 | }
53 | b.Dispose();
54 |
55 | context.EndDraw();
56 | this.m_dx.D3D.SwapChain.Present(1, 0);
57 | this.Validate();
58 | }
59 | catch (SharpDXException ex)
60 | {
61 | if (!this.m_dx.PerformResetOnException(ex)) throw;
62 | }
63 | }
64 |
65 | protected override void OnSize(ref SizePacket packet)
66 | {
67 | this.m_dx.Resize(packet.Size);
68 | base.OnSize(ref packet);
69 | }
70 |
71 | protected override void Dispose(bool disposing)
72 | {
73 | this.m_dx.Dispose();
74 | base.Dispose(disposing);
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/Samples/Sample.DirectX/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using WinApi.Core;
4 | using WinApi.Kernel32;
5 | using WinApi.User32;
6 | using WinApi.Desktop;
7 | using WinApi.DwmApi;
8 | using WinApi.Gdi32;
9 | using WinApi.UxTheme;
10 | using WinApi.Windows;
11 | using WinApi.Windows.Helpers;
12 |
13 | namespace Sample.DirectX
14 | {
15 | internal class Program
16 | {
17 | static int Main(string[] args)
18 | {
19 | try
20 | {
21 | ApplicationHelpers.SetupDefaultExceptionHandlers();
22 | var factory = WindowFactory.Create(hBgBrush: IntPtr.Zero);
23 | // Create the window without a dependency on WinApi.Windows.Controls
24 | using (
25 | var win = factory.CreateWindow(() => new MainWindow(), "Hello",
26 | constructionParams: new FrameWindowConstructionParams(),
27 | exStyles: WindowExStyles.WS_EX_APPWINDOW | WindowExStyles.WS_EX_NOREDIRECTIONBITMAP))
28 | {
29 | win.CenterToScreen();
30 | win.Show();
31 | return new EventLoop().Run(win);
32 | }
33 | }
34 | catch (Exception ex)
35 | {
36 | MessageBoxHelpers.ShowError(ex);
37 | return 1;
38 | }
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Samples/Sample.DirectX/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 |
9 | [assembly: AssemblyTitle("Sample.Win32")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Sample.Win32")]
14 | [assembly: AssemblyCopyright("Copyright © 2016")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 |
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 |
26 | [assembly: Guid("d829fa54-0380-43ef-9e49-73addb653019")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 |
39 | [assembly: AssemblyVersion("1.0.0.0")]
40 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/Samples/Sample.DirectX/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
53 |
54 |
55 | true/pm
56 |
57 |
58 |
59 |
60 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/Samples/Sample.DirectX/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Samples/Sample.Native.Atl/CAppWindow.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "CAppWindow.h"
3 |
4 | int CAppWindow::Run()
5 | {
6 | auto hwnd = Create(0, 0, L"Hello");
7 | ShowWindow(SW_SHOWNORMAL);
8 | MSG msg;
9 | BOOL result;
10 | while (result = GetMessage(&msg, 0, 0, 0))
11 | {
12 | if (result == -1)
13 | return GetLastError();
14 | TranslateMessage(&msg);
15 | DispatchMessage(&msg);
16 | }
17 | return 0;
18 | }
19 |
20 | LRESULT CAppWindow::OnCreate(LPCREATESTRUCT lpcreatestruct)
21 | {
22 | return 0;
23 | }
24 |
25 | void CAppWindow::OnDestroy()
26 | {
27 | PostQuitMessage(0);
28 | }
29 |
30 | LRESULT CAppWindow::OnEraseBkgnd(HDC hdc)
31 | {
32 | SetMsgHandled(true);
33 | return 1;
34 | }
35 |
36 | void CAppWindow::OnPaint(HDC hdc)
37 | {
38 | PAINTSTRUCT ps;
39 | BeginPaint(&ps);
40 | FillRect(hdc, &ps.rcPaint, (HBRUSH)COLOR_WINDOW);
41 | EndPaint(&ps);
42 | SetMsgHandled(true);
43 | }
44 |
--------------------------------------------------------------------------------
/Samples/Sample.Native.Atl/CAppWindow.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "pch.h"
4 |
5 | class CAppWindow : public CWindowImpl
6 | {
7 | private:
8 | BEGIN_MSG_MAP(CAppWindow)
9 | MSG_WM_CREATE(OnCreate)
10 | MSG_WM_DESTROY(OnDestroy)
11 | MSG_WM_PAINT(OnPaint)
12 | MSG_WM_ERASEBKGND(OnEraseBkgnd)
13 | END_MSG_MAP()
14 |
15 | public:
16 | DECLARE_WND_CLASS(L"AppWindow")
17 | int Run();
18 |
19 | protected:
20 | LRESULT OnCreate(LPCREATESTRUCT lpcreatestruct);
21 | void OnDestroy();
22 | LRESULT OnEraseBkgnd(HDC hdc);
23 | void OnPaint(HDC hdc);
24 | };
25 |
--------------------------------------------------------------------------------
/Samples/Sample.Native.Atl/Sample.Native.Atl.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 |
26 |
27 | Header Files
28 |
29 |
30 | Header Files
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Samples/Sample.Native.Atl/main.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "CAppWindow.h"
3 |
4 | int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int)
5 | {
6 | CAppWindow win;
7 | return win.Run();
8 | }
9 |
--------------------------------------------------------------------------------
/Samples/Sample.Native.Atl/pch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define WIN32_LEAN_AND_MEAN
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
--------------------------------------------------------------------------------
/Samples/Sample.Native.Win32/Sample.Native.Win32.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Samples/Sample.Native.Win32/main.cpp:
--------------------------------------------------------------------------------
1 | #define WIN32_LEAN_AND_MEAN
2 |
3 | #include
4 | #include
5 |
6 | int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
7 | PWSTR pCmdLine, int nCmdShow);
8 | LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
9 | LPARAM lParam);
10 |
11 | int wmain()
12 | {
13 | wWinMain(nullptr, nullptr, nullptr, 0);
14 | }
15 |
16 | int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
17 | PWSTR pCmdLine, int nCmdShow)
18 | {
19 | WNDCLASSEX wc = {0};
20 | wc.hInstance = hInstance;
21 | wc.lpszClassName = L"MainWindow";
22 | wc.cbSize = sizeof(WNDCLASSEX);
23 | wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
24 | wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
25 | wc.style = CS_HREDRAW | CS_VREDRAW;
26 | wc.lpfnWndProc = WindowProc;
27 | auto regRes = RegisterClassEx(&wc);
28 | if (!regRes)
29 | {
30 | std::cerr << "window registration failed" << std::endl;
31 | return regRes;
32 | }
33 | auto hwnd = CreateWindowEx(0, wc.lpszClassName, L"Hello",
34 | WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
35 | CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
36 | if (hwnd == nullptr)
37 | {
38 | std::cerr << "window couldn't be created" << std::endl;
39 | return -1;
40 | }
41 |
42 | ShowWindow(hwnd, SW_SHOWNORMAL);
43 |
44 | MSG msg = {};
45 | while (GetMessage(&msg, nullptr, 0, 0))
46 | {
47 | TranslateMessage(&msg);
48 | DispatchMessage(&msg);
49 | }
50 | return 0;
51 | }
52 |
53 | LRESULT HandleDestroy(HWND hWnd)
54 | {
55 | PostQuitMessage(0);
56 | return 0;
57 | }
58 |
59 | LRESULT HandlePaint(HWND hwnd)
60 | {
61 | PAINTSTRUCT ps;
62 | auto hdc = BeginPaint(hwnd, &ps);
63 | FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW));
64 | EndPaint(hwnd, &ps);
65 | return 0;
66 | }
67 |
68 | LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
69 | {
70 | switch (uMsg)
71 | {
72 | case WM_ERASEBKGND:
73 | return 1;
74 | case WM_DESTROY:
75 | return HandleDestroy(hwnd);
76 | case WM_PAINT:
77 | return HandlePaint(hwnd);
78 | }
79 | return DefWindowProc(hwnd, uMsg, wParam, lParam);
80 | }
81 |
--------------------------------------------------------------------------------
/Samples/Sample.OpenGL/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Samples/Sample.OpenGL/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 | using OpenGL;
6 | using WinApi.Core;
7 | using WinApi.Desktop;
8 | using WinApi.Gdi32;
9 | using WinApi.User32;
10 | using WinApi.Windows;
11 | using WinApi.Windows.Controls;
12 | using WinApi.Windows.Helpers;
13 |
14 | namespace Sample.OpenGL
15 | {
16 | ///
17 | /// NOTE: This references a modified version of OpenGL.Net, with GitHub PR #13 applied.
18 | /// If it isn't applied, inside the `CreateDeviceContext` method of OpenGlWindowBase
19 | /// the `DeviceContextFactory.Create` should be passed a throw-away `Control` class
20 | /// from Windows.Forms that wraps the Handle IntPtr. Or else, this code will not compile.
21 | /// A patched version of OpenGL.Net with PR #13 applied can be found at
22 | /// https://github.com/prasannavl/OpenGL.Net meanwhile.
23 | ///
24 | class Program
25 | {
26 | static int Main(string[] args)
27 | {
28 | try
29 | {
30 | ApplicationHelpers.SetupDefaultExceptionHandlers();
31 | Gl.Initialize();
32 | var factory = WindowFactory.Create(hBgBrush: Gdi32Helpers.GetStockObject(StockObject.BLACK_BRUSH));
33 | using (var win = Window.Create(factory: factory, text: "Hello"))
34 | {
35 | win.Show();
36 | return new EventLoop().Run(win);
37 | }
38 | }
39 | catch (Exception ex)
40 | {
41 | MessageBoxHelpers.ShowError(ex);
42 | return 1;
43 | }
44 | }
45 | }
46 |
47 | public sealed class AppWindow : OpenGlWindow
48 | {
49 | protected override void OnGlContextCreated()
50 | {
51 | Gl.MatrixMode(MatrixMode.Projection);
52 | Gl.LoadIdentity();
53 | Gl.Ortho(0.0, 1.0f, 0.0, 1.0, 0.0, 1.0);
54 |
55 | Gl.MatrixMode(MatrixMode.Modelview);
56 | Gl.LoadIdentity();
57 | base.OnGlContextCreated();
58 | }
59 |
60 | protected override void OnGlPaint(ref PaintStruct ps)
61 | {
62 | Gl.Clear(ClearBufferMask.ColorBufferBit);
63 | var size = this.GetClientSize();
64 | Gl.Viewport(0, 0, size.Width, size.Height);
65 | Gl.Begin(PrimitiveType.Triangles);
66 | Gl.Color3(1.0f, 0.0f, 0.0f);
67 | Gl.Vertex2(0.0f, 0.0f);
68 | Gl.Color3(0.0f, 1.0f, 0.0f);
69 | Gl.Vertex2(0.5f, 1.0f);
70 | Gl.Color3(0.0f, 0.0f, 1.0f);
71 | Gl.Vertex2(1.0f, 0.0f);
72 | Gl.End();
73 | this.DeviceContext.SwapBuffers();
74 | }
75 | }
76 | }
--------------------------------------------------------------------------------
/Samples/Sample.OpenGL/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 |
9 | [assembly: AssemblyTitle("Sample.OpenGL")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Sample.OpenGL")]
14 | [assembly: AssemblyCopyright("Copyright © 2016")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 |
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 |
26 | [assembly: Guid("d58d8e28-296c-405a-b295-ad13c577d5ae")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 |
39 | [assembly: AssemblyVersion("1.0.0.0")]
40 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/Samples/Sample.OpenGL/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
53 |
54 |
55 | true/pm
56 |
57 |
58 |
59 |
60 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/Samples/Sample.OpenGL/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Samples/Sample.SimpleWindow/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Samples/Sample.SimpleWindow/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using WinApi.Gdi32;
7 | using WinApi.User32;
8 | using WinApi.Windows;
9 | using WinApi.Windows.Controls;
10 |
11 | namespace Sample.SimpleWindow
12 | {
13 | internal class Program
14 | {
15 | static int Main(string[] args)
16 | {
17 | using (var win = Window.Create("Hello"))
18 | {
19 | win.Show();
20 | return new EventLoop().Run(win);
21 | }
22 | }
23 | }
24 |
25 | public class AppWindow : Window
26 | {
27 | protected override void OnPaint(ref PaintPacket packet)
28 | {
29 | PaintStruct ps;
30 | var hdc = this.BeginPaint(out ps);
31 | User32Methods.FillRect(hdc, ref ps.PaintRect,
32 | Gdi32Helpers.GetStockObject(StockObject.WHITE_BRUSH));
33 | this.EndPaint(ref ps);
34 | base.OnPaint(ref packet);
35 | }
36 |
37 | protected override void OnMessage(ref WindowMessage msg)
38 | {
39 | switch (msg.Id)
40 | {
41 | // Note: OnEraseBkgnd method is already available in
42 | // EventedWindowCore, but directly intercepted here
43 | // just for the sake of overriding the
44 | // message loop.
45 | // Also, note that the message loop is
46 | // short-cicuited here.
47 |
48 | case WM.ERASEBKGND:
49 | {
50 | // I can even build the loop only on pay-per-use
51 | // basis, when I need it since all the Packets decoding,
52 | // and encoding are cleanly abstracted away into the Packet
53 | // structs itself.
54 | //
55 | // fixed (var msgPtr = &msg)
56 | // {
57 | // var packet = new EraseBkgndPacket(msg);
58 | // // Do anything you want with the packet.
59 | // }
60 | // return;
61 |
62 | msg.Result = new IntPtr(1);
63 | return;
64 | }
65 | }
66 | base.OnMessage(ref msg);
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/Samples/Sample.SimpleWindow/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 |
9 | [assembly: AssemblyTitle("Sample.SimpleWindow")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Sample.SimpleWindow")]
14 | [assembly: AssemblyCopyright("Copyright © 2016")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 |
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 |
26 | [assembly: Guid("3f1b11ae-9a3d-4523-91fc-7457cad687ab")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 |
39 | [assembly: AssemblyVersion("1.0.0.0")]
40 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/Samples/Sample.SimpleWindow/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
53 |
54 |
55 | true/pm
56 |
57 |
58 |
59 |
60 |
61 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/Samples/Sample.SimpleWindow/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Samples/Sample.SimulateInput/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Samples/Sample.SimulateInput/Program.cs:
--------------------------------------------------------------------------------
1 | using NetCoreEx.Geometry;
2 | using System;
3 | using System.Runtime.ExceptionServices;
4 | using WinApi.Core;
5 | using WinApi.Desktop;
6 | using WinApi.User32;
7 | using WinApi.Windows;
8 | using WinApi.Windows.Controls;
9 | using WinApi.Windows.Controls.Layouts;
10 |
11 | namespace Sample.SimulateInput
12 | {
13 | class Program
14 | {
15 | [HandleProcessCorruptedStateExceptions]
16 | static int Main(string[] args)
17 | {
18 | ApplicationHelpers.SetupDefaultExceptionHandlers();
19 |
20 | try
21 | {
22 | var factory = WindowFactory.Create();
23 | using (var win = Window.Create(factory: factory, text: "Hello"))
24 | {
25 | win.Show();
26 | return new EventLoop().Run(win);
27 | }
28 | }
29 | catch (Exception ex) {
30 | ApplicationHelpers.ShowCriticalError(ex);
31 | }
32 | return 0;
33 | }
34 |
35 | public sealed class SampleWindow : Window
36 | {
37 | private readonly Input[] m_inputs = new Input[11];
38 | private readonly HorizontalStretchLayout m_layout = new HorizontalStretchLayout();
39 | private EditBox m_editBox;
40 | private StaticBox m_textBox;
41 | private IntPtr m_timerId;
42 | private TimerProc m_timerProc;
43 | private int m_timesExecuted;
44 |
45 | protected override void OnCreate(ref CreateWindowPacket packet)
46 | {
47 | this.m_textBox = StaticBox.Create(
48 | "Ahoy!",
49 | hParent: this.Handle);
50 |
51 | this.m_editBox = EditBox.Create(
52 | "Nothing here yet.",
53 | hParent: this.Handle,
54 | controlStyles:
55 | EditBox.EditStyles.ES_MULTILINE | EditBox.EditStyles.ES_WANTRETURN |
56 | (EditBox.EditStyles) WindowStyles.WS_VSCROLL);
57 |
58 | this.m_layout.ClientArea = this.GetClientRect();
59 | this.m_layout.Margin = new Rectangle(10, 10, 10, 10);
60 | this.m_layout.Children.Add(this.m_textBox);
61 | this.m_layout.Children.Add(this.m_editBox);
62 | this.m_layout.PerformLayout();
63 | this.m_timerProc = (wnd, uMsg, eventId, millis) =>
64 | {
65 | try
66 | {
67 | this.m_timesExecuted++;
68 | Input.InitKeyboardInput(out this.m_inputs[0], VirtualKey.H, false);
69 | Input.InitKeyboardInput(out this.m_inputs[1], VirtualKey.H, true);
70 | Input.InitKeyboardInput(out this.m_inputs[3], VirtualKey.E, false);
71 | Input.InitKeyboardInput(out this.m_inputs[4], VirtualKey.E, true);
72 | Input.InitKeyboardInput(out this.m_inputs[5], VirtualKey.L, false);
73 | Input.InitKeyboardInput(out this.m_inputs[6], VirtualKey.L, true);
74 | Input.InitKeyboardInput(out this.m_inputs[7], VirtualKey.L, false);
75 | Input.InitKeyboardInput(out this.m_inputs[8], VirtualKey.L, true);
76 | Input.InitKeyboardInput(out this.m_inputs[9], VirtualKey.O, false);
77 | Input.InitKeyboardInput(out this.m_inputs[10], VirtualKey.O, true);
78 | var x = User32Helpers.SendInput(this.m_inputs);
79 | }
80 | catch (Exception ex) {
81 | this.m_editBox.SetText($"ERROR: {ex.Message}\r\n{ex.StackTrace}");
82 | }
83 | };
84 |
85 | this.m_timerId = User32Methods.SetTimer(this.Handle, IntPtr.Zero, 20, this.m_timerProc);
86 | base.OnCreate(ref packet);
87 | }
88 |
89 | protected override void OnKey(ref KeyPacket packet)
90 | {
91 | var key = packet.Key;
92 | var inputState = packet.InputState;
93 | var str = $"\r\n{DateTime.Now} :" +
94 | $" {key} => {inputState.IsKeyUpTransition}; " +
95 | $"{inputState.RepeatCount}; " +
96 | $"{inputState.ScanCode}; " +
97 | $"{inputState.IsContextual}; " +
98 | $"{inputState.IsExtendedKey}" + "\r\n" +
99 | $"No. of text display changes: {this.m_timesExecuted}" + "\0";
100 | this.m_textBox.SetText(str);
101 | base.OnKey(ref packet);
102 | }
103 |
104 | protected override void OnMouseButton(ref MouseButtonPacket packet)
105 | {
106 | var button = packet.Button;
107 | var isButtonDown = packet.IsButtonDown;
108 | if ((button == MouseButton.Left) && isButtonDown) this.SetFocus();
109 | base.OnMouseButton(ref packet);
110 | }
111 |
112 | protected override void OnSize(ref SizePacket packet)
113 | {
114 | var size = packet.Size;
115 | this.m_layout.SetSize(ref size);
116 | base.OnSize(ref packet);
117 | }
118 | }
119 | }
120 | }
--------------------------------------------------------------------------------
/Samples/Sample.SimulateInput/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 |
9 | [assembly: AssemblyTitle("Sample.SimulateInput")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Sample.SimulateInput")]
14 | [assembly: AssemblyCopyright("Copyright © 2016")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 |
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 |
26 | [assembly: Guid("62b305ba-bd58-48d0-ad77-ef64f987ca5a")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 |
39 | [assembly: AssemblyVersion("1.0.0.0")]
40 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/Samples/Sample.SimulateInput/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
53 |
54 |
55 | true
56 |
57 |
58 |
59 |
60 |
61 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/Samples/Sample.SimulateInput/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Samples/Sample.Skia/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Samples/Sample.Skia/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration;
3 | using System.Runtime.InteropServices;
4 | using System.Text;
5 | using SkiaSharp;
6 | using WinApi.DwmApi;
7 | using WinApi.User32;
8 | using WinApi.UxTheme;
9 | using System.Linq;
10 | using WinApi.Desktop;
11 | using WinApi.Gdi32;
12 | using WinApi.User32.Experimental;
13 | using WinApi.Windows;
14 | using WinApi.Windows.Helpers;
15 | using NetCoreEx.Geometry;
16 |
17 | namespace Sample.Skia
18 | {
19 | class Program
20 | {
21 | static int Main(string[] args)
22 | {
23 | try
24 | {
25 | ApplicationHelpers.SetupDefaultExceptionHandlers();
26 | // Using it without a dependency on WinApi.Windows.Controls
27 | var factory = WindowFactory.Create(hBgBrush: IntPtr.Zero);
28 | using (var win = factory.CreateWindow(() => new SkiaWindow(), "Hello",
29 | constructionParams: new FrameWindowConstructionParams()))
30 | {
31 | win.Show();
32 | return new EventLoop().Run(win);
33 | }
34 | }
35 | catch (Exception ex)
36 | {
37 | MessageBoxHelpers.ShowError(ex);
38 | return 1;
39 | }
40 | }
41 | }
42 |
43 | public sealed class SkiaWindow : SkiaWindowBase
44 | {
45 | protected override void OnSkiaPaint(SKSurface surface)
46 | {
47 | var windowRect = this.GetWindowRect();
48 | var clientRect = new Rectangle(windowRect.Width, windowRect.Height);
49 | var canvas = surface.Canvas;
50 | canvas.Clear(new SKColor(120, 50, 70, 200));
51 | var textPainter = new SKPaint {TextSize = 35, IsAntialias = true};
52 | var str = "Hello there!";
53 | var textBounds = new SKRect();
54 | var m = textPainter.MeasureText(str, ref textBounds);
55 | canvas.DrawText(str, (clientRect.Width - textBounds.Width)/2, (clientRect.Height - textBounds.Height)/2,
56 | textPainter);
57 |
58 | base.OnSkiaPaint(surface);
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/Samples/Sample.Skia/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 |
9 | [assembly: AssemblyTitle("Sample.Skia")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Sample.Skia")]
14 | [assembly: AssemblyCopyright("Copyright © 2016")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 |
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 |
26 | [assembly: Guid("5ff4bac3-d221-4023-9ee9-51c1f5c85d50")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 |
39 | [assembly: AssemblyVersion("1.0.0.0")]
40 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/Samples/Sample.Skia/SkiaWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SkiaSharp;
3 | using WinApi.Core;
4 | using WinApi.Desktop;
5 | using WinApi.DwmApi;
6 | using WinApi.Gdi32;
7 | using WinApi.User32;
8 | using WinApi.User32.Experimental;
9 | using WinApi.Utils;
10 | using WinApi.UxTheme;
11 | using WinApi.Windows;
12 | using NetCoreEx.Geometry;
13 |
14 | namespace Sample.Skia
15 | {
16 | public class SkiaPainter
17 | {
18 | public static void ProcessPaint(ref PaintPacket packet, NativePixelBuffer pixelBuffer,
19 | Action handler)
20 | {
21 | var hwnd = packet.Hwnd;
22 | Rectangle clientRect;
23 | User32Methods.GetClientRect(hwnd, out clientRect);
24 | var size = clientRect.Size;
25 | pixelBuffer.EnsureSize(size.Width, size.Height);
26 | PaintStruct ps;
27 | var hdc = User32Methods.BeginPaint(hwnd, out ps);
28 | var skPainted = false;
29 | try
30 | {
31 | using (var surface = SKSurface.Create(
32 | size.Width,
33 | size.Height,
34 | SKColorType.Bgra8888,
35 | SKAlphaType.Premul,
36 | pixelBuffer.Handle,
37 | pixelBuffer.Stride))
38 | {
39 | if (surface != null)
40 | {
41 | handler(surface);
42 | skPainted = true;
43 | }
44 | }
45 | }
46 | finally
47 | {
48 | if (skPainted) Gdi32Helpers.SetRgbBitsToDevice(hdc, size.Width, size.Height, pixelBuffer.Handle);
49 | User32Methods.EndPaint(hwnd, ref ps);
50 | }
51 | }
52 | }
53 |
54 | public class SkiaWindowBase : EventedWindowCore
55 | {
56 | private readonly NativePixelBuffer m_pixelBuffer = new NativePixelBuffer();
57 |
58 | protected virtual void OnSkiaPaint(SKSurface surface) {}
59 |
60 | protected override void OnPaint(ref PaintPacket packet)
61 | {
62 | SkiaPainter.ProcessPaint(ref packet, this.m_pixelBuffer, this.OnSkiaPaint);
63 | }
64 |
65 | protected override void Dispose(bool disposing)
66 | {
67 | this.m_pixelBuffer.Dispose();
68 | base.Dispose(disposing);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/Samples/Sample.Skia/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
53 |
54 |
55 | true
56 |
57 |
58 |
59 |
60 |
61 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/Samples/Sample.Skia/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Samples/Sample.Win32/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Samples/Sample.Win32/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using WinApi.Gdi32;
8 | using WinApi.Kernel32;
9 | using WinApi.User32;
10 |
11 | namespace Sample.Win32
12 | {
13 | internal class Program
14 | {
15 | static int Main(string[] args)
16 | {
17 | var instanceHandle = Kernel32Methods.GetModuleHandle(IntPtr.Zero);
18 |
19 | var wc = new WindowClassEx
20 | {
21 | Size = (uint) Marshal.SizeOf(),
22 | ClassName = "MainWindow",
23 | CursorHandle = User32Helpers.LoadCursor(IntPtr.Zero, SystemCursor.IDC_ARROW),
24 | IconHandle = User32Helpers.LoadIcon(IntPtr.Zero, SystemIcon.IDI_APPLICATION),
25 | Styles = WindowClassStyles.CS_HREDRAW | WindowClassStyles.CS_VREDRAW,
26 | BackgroundBrushHandle = new IntPtr((int) StockObject.WHITE_BRUSH),
27 | WindowProc = WindowProc,
28 | InstanceHandle = instanceHandle
29 | };
30 |
31 | var resReg = User32Methods.RegisterClassEx(ref wc);
32 | if (resReg == 0)
33 | {
34 | Console.Error.WriteLine("registration failed");
35 | return -1;
36 | }
37 |
38 | var hwnd = User32Methods.CreateWindowEx(WindowExStyles.WS_EX_APPWINDOW,
39 | wc.ClassName, "Hello", WindowStyles.WS_OVERLAPPEDWINDOW,
40 | (int) CreateWindowFlags.CW_USEDEFAULT, (int) CreateWindowFlags.CW_USEDEFAULT,
41 | (int) CreateWindowFlags.CW_USEDEFAULT, (int) CreateWindowFlags.CW_USEDEFAULT,
42 | IntPtr.Zero, IntPtr.Zero, instanceHandle, IntPtr.Zero);
43 |
44 | if (hwnd == IntPtr.Zero)
45 | {
46 | Console.Error.WriteLine("window creation failed");
47 | return -1;
48 | }
49 |
50 | User32Methods.ShowWindow(hwnd, ShowWindowCommands.SW_SHOWNORMAL);
51 | User32Methods.UpdateWindow(hwnd);
52 |
53 | Message msg;
54 | int res;
55 | while ((res = User32Methods.GetMessage(out msg, IntPtr.Zero, 0, 0)) != 0)
56 | {
57 | User32Methods.TranslateMessage(ref msg);
58 | User32Methods.DispatchMessage(ref msg);
59 | }
60 |
61 | return res;
62 | }
63 |
64 | private static IntPtr WindowProc(IntPtr hwnd, uint umsg,
65 | IntPtr wParam, IntPtr lParam)
66 | {
67 | var msg = (WM) umsg;
68 | switch (msg)
69 | {
70 | case WM.ERASEBKGND:
71 | return new IntPtr(1);
72 | case WM.CLOSE:
73 | {
74 | User32Methods.PostQuitMessage(0);
75 | break;
76 | }
77 | case WM.PAINT:
78 | {
79 | PaintStruct ps;
80 | var hdc = User32Methods.BeginPaint(hwnd, out ps);
81 | User32Methods.FillRect(hdc, ref ps.PaintRect,
82 | Gdi32Helpers.GetStockObject(StockObject.WHITE_BRUSH));
83 | User32Methods.EndPaint(hwnd, ref ps);
84 | break;
85 | }
86 | }
87 | return User32Methods.DefWindowProc(hwnd, umsg, wParam, lParam);
88 | }
89 | }
90 | }
--------------------------------------------------------------------------------
/Samples/Sample.Win32/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 |
9 | [assembly: AssemblyTitle("Sample.Win32")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Sample.Win32")]
14 | [assembly: AssemblyCopyright("Copyright © 2016")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 |
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 |
26 | [assembly: Guid("2f8db172-d945-4551-b470-1835ab951ea3")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 |
39 | [assembly: AssemblyVersion("1.0.0.0")]
40 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/Samples/Sample.Win32/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
53 |
54 |
55 | true
56 |
57 |
58 |
59 |
60 |
61 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/Samples/Sample.Win32/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Samples/WinApi.TestGround/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Samples/WinApi.TestGround/DebugLogger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Linq;
4 | using System.Text;
5 | using Newtonsoft.Json;
6 | using WinApi.Desktop;
7 |
8 | namespace WinApi.TestGround
9 | {
10 | public sealed class DebugLogger
11 | {
12 | [Conditional("DEBUG")]
13 | private static void EnsureConsole()
14 | {
15 | ConsoleHelpers.EnsureConsole();
16 | }
17 |
18 | [Conditional("DEBUG")]
19 | public static void Print(string format, params object[] o)
20 | {
21 | EnsureConsole();
22 | var sb = new StringBuilder();
23 | var serializedObjs = o.Select(x => JsonConvert.SerializeObject(x, Formatting.Indented)).ToArray();
24 | sb.AppendFormat(format, serializedObjs);
25 | Console.WriteLine(sb.ToString());
26 | }
27 |
28 | [Conditional("DEBUG")]
29 | public static void Print(string s)
30 | {
31 | EnsureConsole();
32 | Console.WriteLine(s);
33 | }
34 |
35 | [Conditional("DEBUG")]
36 | public static void Print(object o)
37 | {
38 | EnsureConsole();
39 | Console.WriteLine(JsonConvert.SerializeObject(o, Formatting.Indented));
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/Samples/WinApi.TestGround/Program.cs:
--------------------------------------------------------------------------------
1 | using NetCoreEx.Geometry;
2 | using System;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 | using WinApi.Desktop;
6 | using WinApi.User32;
7 | using WinApi.Windows;
8 | using WinApi.Windows.Controls;
9 | using WinApi.Windows.Controls.Layouts;
10 |
11 | namespace WinApi.TestGround
12 | {
13 | class Program
14 | {
15 | static int Main(string[] args)
16 | {
17 | ApplicationHelpers.SetupDefaultExceptionHandlers();
18 | try
19 | {
20 | var factory = WindowFactory.Create();
21 | using (var win = factory.CreateWindow(() => new MainWindow(),
22 | "Hello", constructionParams: new FrameWindowConstructionParams()))
23 | {
24 | win.Show();
25 | return new EventLoop().Run(win);
26 | }
27 | }
28 | catch (Exception ex) {
29 | ApplicationHelpers.ShowCriticalError(ex);
30 | }
31 | return 0;
32 | }
33 |
34 | public sealed class MainWindow : EventedWindowCore
35 | {
36 | private const int Iterations = 100_000;
37 |
38 | private readonly HorizontalStretchLayout m_layout = new HorizontalStretchLayout();
39 | private bool m_done;
40 | private DateTime m_endTime;
41 | private DateTime m_startTime;
42 | private Task m_task;
43 | private StaticBox m_textBox1;
44 | private NativeWindow m_textBox2;
45 | private int m_times;
46 |
47 | protected override void OnCreate(ref CreateWindowPacket packet)
48 | {
49 |
50 | this.m_textBox1 = StaticBox.Create(hParent: this.Handle,
51 | styles: WindowStyles.WS_CHILD | WindowStyles.WS_VISIBLE, exStyles: 0);
52 |
53 | // You can use this to create the static box like this as well.
54 | // But there's rarely any performance benefit in doing so, and
55 | // this doesn't have a WindowProc that's connected.
56 | this.m_textBox2 = WindowFactory.CreateExternalWindow("static", hParent: this.Handle,
57 | styles: WindowStyles.WS_CHILD | WindowStyles.WS_VISIBLE, exStyles: 0);
58 |
59 | this.m_layout.ClientArea = this.GetClientRect();
60 | this.m_layout.Margin = new Rectangle(10, 10, 10, 10);
61 | this.m_layout.Children.Add(this.m_textBox1);
62 | this.m_layout.Children.Add(this.m_textBox2);
63 | this.m_layout.PerformLayout();
64 |
65 | var r = new Random();
66 |
67 | this.m_task = Task.Run(() =>
68 | {
69 | while (this.m_times < Iterations)
70 | {
71 | this.m_times++;
72 | this.SetPosition(50, 50, 1200 - r.Next(0, 1100), 900 - r.Next(0, 800));
73 | }
74 | this.m_endTime = DateTime.Now;
75 | this.m_done = true;
76 | this.SetPosition(50, 50, 700, 500);
77 | });
78 | this.m_startTime = DateTime.Now;
79 | base.OnCreate(ref packet);
80 | }
81 |
82 | protected override void OnSize(ref SizePacket packet)
83 | {
84 | var size = packet.Size;
85 | this.m_layout.SetSize(ref size);
86 |
87 | base.OnSize(ref packet);
88 |
89 | if (!this.m_done) return;
90 |
91 | var str = $"\r\n{DateTime.Now}: No. of changes done: {this.m_times}";
92 | this.m_textBox1.SetText(str);
93 |
94 | var sb = new StringBuilder();
95 |
96 | sb.AppendLine($"Start Time: {this.m_startTime}");
97 | sb.AppendLine($"End Time: {this.m_endTime}");
98 | sb.AppendLine();
99 |
100 | if (this.m_endTime != DateTime.MinValue) sb.AppendLine($"Total Time: {this.m_endTime - this.m_startTime}");
101 | this.m_textBox2.SetText(sb.ToString());
102 | }
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/Samples/WinApi.TestGround/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 |
9 | [assembly: AssemblyTitle("Sample.Simple")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Sample.Simple")]
14 | [assembly: AssemblyCopyright("Copyright © 2016")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 |
22 | [assembly: ComVisible(false)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 |
26 | [assembly: Guid("52271447-963c-4cca-8495-875aa61125ce")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 |
39 | [assembly: AssemblyVersion("1.0.0.0")]
40 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/Samples/WinApi.TestGround/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
53 |
54 |
55 | true/pm
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/Samples/WinApi.TestGround/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/WinApi.Desktop/ApplicationHelpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using WinApi.Windows;
3 |
4 | namespace WinApi.Desktop
5 | {
6 | public static class ApplicationHelpers
7 | {
8 | static ApplicationHelpers()
9 | {
10 | DefaultUnhandledExceptionHandler =
11 | (sender, eventArgs) =>
12 | {
13 | ShowCriticalError(eventArgs.ExceptionObject);
14 | if (eventArgs.IsTerminating)
15 | {
16 | ShowCriticalInfo(
17 | $"{Environment.NewLine}The application will now terminate. Press any key to do so.");
18 | Console.ReadKey();
19 | }
20 | };
21 |
22 | DefaultWindowExceptionHandler = ex =>
23 | {
24 | ShowCriticalError(ex.InnerException);
25 | ex.SetHandled();
26 | };
27 | }
28 |
29 | public static WindowExceptionHandler DefaultWindowExceptionHandler { get; }
30 | public static UnhandledExceptionEventHandler DefaultUnhandledExceptionHandler { get; }
31 |
32 | public static void SetupDefaultExceptionHandlers()
33 | {
34 | AppDomain.CurrentDomain.UnhandledException += DefaultUnhandledExceptionHandler;
35 | WindowCore.UnhandledException += DefaultWindowExceptionHandler;
36 | }
37 |
38 | public static void ShowCriticalError(object exceptionObj, string message = null, string title = null)
39 | {
40 | const string defaultMessage = "Oh snap! Something went wrong.";
41 | if (message == null) message = defaultMessage;
42 |
43 | ConsoleHelpers.EnsureConsole();
44 | if (!string.IsNullOrEmpty(title)) Console.Title = title;
45 | var exception = exceptionObj as Exception;
46 | string msg;
47 | if (exception != null)
48 | {
49 | msg = $"{Environment.NewLine}[CRITICAL] {message}{Environment.NewLine}{Environment.NewLine}" +
50 | $"{exception.Message}{Environment.NewLine}" +
51 | $"{exception.StackTrace}";
52 | }
53 | else
54 | {
55 | msg = $"{Environment.NewLine}[CRITICAL] {message}{Environment.NewLine}{Environment.NewLine}" +
56 | $"{exceptionObj}{Environment.NewLine}";
57 | }
58 | Console.Error.WriteLine(msg);
59 | }
60 |
61 | public static void ShowCriticalInfo(string message, string title = null, bool suffixNewLine = true)
62 | {
63 | ConsoleHelpers.EnsureConsole();
64 | if (!string.IsNullOrEmpty(title)) Console.Title = title;
65 | if (suffixNewLine) Console.Error.WriteLine(message);
66 | else Console.Error.Write(message);
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/WinApi.Desktop/ConsoleHelpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using WinApi.Kernel32;
4 |
5 | namespace WinApi.Desktop
6 | {
7 | public static class ConsoleHelpers
8 | {
9 | public static bool EnsureConsole()
10 | {
11 | if (Kernel32Methods.GetConsoleWindow() != IntPtr.Zero) return true;
12 | if (Kernel32Methods.AllocConsole()) return false;
13 | Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = true});
14 | Console.SetError(new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = true});
15 | Console.SetIn(new StreamReader(Console.OpenStandardInput()));
16 | return true;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/WinApi.Desktop/WinApi.Desktop.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 | Prasanna V. Loganathar
5 | Prasanna V. Loganathar
6 | https://www.apache.org/licenses/LICENSE-2.0.txt
7 | https://github.com/prasannavl/WinApi
8 | https://github.com/prasannavl/WinApi
9 | https://raw.githubusercontent.com/prasannavl/WinApi/master/Misc/Logo.png
10 | Copyright © Prasanna V. Loganathar
11 | Desktop helpers for Win32 API with WinApi
12 | 4.0.0
13 | true
14 | win32 native interop desktop
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/WinApi.DxUtils/Component/ComposedD3DComponent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct3D11;
4 | using WinApi.Core;
5 | using WinApi.DxUtils.Composition;
6 | using WinApi.DxUtils.Core;
7 | using WinApi.DxUtils.D3D11;
8 | using NetCoreEx.Geometry;
9 |
10 | namespace WinApi.DxUtils.Component
11 | {
12 | public class ComposedD3DComponent : IDisposable
13 | {
14 | public WindowSwapChainCompositor Compositor;
15 | public IntPtr Hwnd;
16 | private int m_compVariant;
17 | private ID3D11_1MetaResource m_d3D;
18 | public Size Size;
19 |
20 | public ID3D11MetaResourceCore D3D => this.m_d3D;
21 |
22 | public bool IsInitialized => this.m_d3D?.Device != null;
23 |
24 | public void Dispose()
25 | {
26 | DisposableHelpers.DisposeAndSetNull(ref this.Compositor);
27 | DisposableHelpers.DisposeAndSetNull(ref this.m_d3D);
28 | }
29 |
30 | public void Initialize(IntPtr hwnd, Size size, int directCompositionVariant = -1)
31 | {
32 | if (this.IsInitialized) this.Destroy();
33 | this.Hwnd = hwnd;
34 | this.Size = size;
35 | this.m_compVariant = directCompositionVariant != -1
36 | ? directCompositionVariant
37 | : CompositionHelper.GetVariantForPlatform();
38 | this.Create();
39 | this.InitializeInternal();
40 | }
41 |
42 | public void EnsureInitialized()
43 | {
44 | if (!this.IsInitialized) this.Initialize(this.Hwnd, this.Size, this.m_compVariant);
45 | }
46 |
47 | public void Resize(Size size)
48 | {
49 | if ((this.m_compVariant > 0) && ((size.Width <= 0) || (size.Height <= 0))) return;
50 | this.Size = size;
51 | this.m_d3D?.Resize(size);
52 | }
53 |
54 | private void InitializeInternal()
55 | {
56 | this.m_d3D.Initialize(this.Hwnd, this.Size);
57 | if (this.m_compVariant > 0)
58 | this.Compositor.Initialize(this.m_d3D,
59 | new WindowCompositorOptions(this.Hwnd));
60 | }
61 |
62 | private void Create()
63 | {
64 | var d3dCreationFlags = DeviceCreationFlags.BgraSupport | DeviceCreationFlags.SingleThreaded;
65 | this.m_d3D = this.m_compVariant > 0
66 | ? D3D11MetaFactory.CreateForComposition(creationFlags: d3dCreationFlags)
67 | : D3D11MetaFactory.CreateForWindowTarget(creationFlags: d3dCreationFlags);
68 | this.Compositor = new WindowSwapChainCompositor(this.m_compVariant);
69 | }
70 |
71 | public bool PerformResetOnException(SharpDXException ex)
72 | {
73 | if (ErrorHelpers.ShouldResetDxgiForError(ex.Descriptor))
74 | {
75 | this.m_d3D?.Destroy();
76 | return true;
77 | }
78 | return false;
79 | }
80 |
81 | public void Destroy()
82 | {
83 | this.Compositor?.Destroy();
84 | this.m_d3D?.Destroy();
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/Component/Dx11Component.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct3D11;
4 | using WinApi.Core;
5 | using WinApi.DxUtils.Composition;
6 | using WinApi.DxUtils.Core;
7 | using WinApi.DxUtils.D2D1;
8 | using WinApi.DxUtils.D3D11;
9 | using Factory = SharpDX.DirectWrite.Factory;
10 | using FactoryType = SharpDX.DirectWrite.FactoryType;
11 | using NetCoreEx.Geometry;
12 |
13 | namespace WinApi.DxUtils.Component
14 | {
15 | public class Dx11Component : IDisposable
16 | {
17 | public WindowSwapChainCompositor Compositor;
18 | public IntPtr Hwnd;
19 | private int m_compVariant;
20 | private ID2D1_1MetaResource m_d2D;
21 | private ID3D11_1MetaResource m_d3D;
22 | private Factory m_dWriteFactory;
23 | public Size Size;
24 |
25 | public ID2D1_1MetaResourceCore D2D => this.m_d2D;
26 | public ID3D11MetaResourceCore D3D => this.m_d3D;
27 | public Factory TextFactory => this.m_dWriteFactory;
28 |
29 | public bool IsInitialized => this.m_d3D?.Device != null;
30 |
31 | public void Dispose()
32 | {
33 | DisposableHelpers.DisposeAndSetNull(ref this.Compositor);
34 | DisposableHelpers.DisposeAndSetNull(ref this.m_dWriteFactory);
35 | DisposableHelpers.DisposeAndSetNull(ref this.m_d2D);
36 | DisposableHelpers.DisposeAndSetNull(ref this.m_d3D);
37 | }
38 |
39 | public void Initialize(IntPtr hwnd, Size size, int directCompositionVariant = -1)
40 | {
41 | if (this.IsInitialized) this.Destroy();
42 | this.Hwnd = hwnd;
43 | this.Size = size;
44 | this.m_compVariant = directCompositionVariant != -1
45 | ? directCompositionVariant
46 | : CompositionHelper.GetVariantForPlatform();
47 | this.Create();
48 | this.InitializeInternal();
49 | }
50 |
51 | public void EnsureInitialized()
52 | {
53 | if (!this.IsInitialized)
54 | {
55 | this.Create();
56 | this.InitializeInternal();
57 | }
58 | }
59 |
60 | public void Resize(Size size)
61 | {
62 | if ((this.m_compVariant > 0) && ((size.Width <= 0) || (size.Height <= 0))) return;
63 | this.Size = size;
64 | this.m_d3D?.Resize(size);
65 | }
66 |
67 | private void InitializeInternal()
68 | {
69 | this.m_d3D.Initialize(this.Hwnd, this.Size);
70 | this.m_d2D.Initialize(this.m_d3D);
71 | if (this.m_compVariant > 0)
72 | this.Compositor.Initialize(this.m_d3D,
73 | new WindowCompositorOptions(this.Hwnd));
74 | }
75 |
76 | private void Create()
77 | {
78 | var d3dCreationFlags = DeviceCreationFlags.BgraSupport | DeviceCreationFlags.SingleThreaded;
79 | this.m_d3D = this.m_compVariant > 0
80 | ? D3D11MetaFactory.CreateForComposition(creationFlags: d3dCreationFlags)
81 | : D3D11MetaFactory.CreateForWindowTarget(creationFlags: d3dCreationFlags);
82 | this.m_d2D = D2D1MetaFactory.CreateForSwapChain();
83 | this.m_dWriteFactory = new Factory(FactoryType.Shared);
84 | this.Compositor = new WindowSwapChainCompositor(this.m_compVariant);
85 | }
86 |
87 | public bool PerformResetOnException(SharpDXException ex)
88 | {
89 | if (ErrorHelpers.ShouldResetDxgiForError(ex.Descriptor)
90 | || ErrorHelpers.ShouldResetD2DForError(ex.Descriptor))
91 | {
92 | this.m_d3D?.Destroy();
93 | return true;
94 | }
95 | return false;
96 | }
97 |
98 | public void Destroy()
99 | {
100 | this.Compositor?.Destroy();
101 | this.m_d2D.Destroy();
102 | this.m_d3D.Destroy();
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/Composition/CompositionHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.DirectComposition;
4 | using SharpDX.DXGI;
5 | using WinApi.Core;
6 | using Device = SharpDX.DirectComposition.Device;
7 | using Surface = SharpDX.DirectComposition.Surface;
8 |
9 | namespace WinApi.DxUtils.Composition
10 | {
11 | public static class CompositionHelper
12 | {
13 | public static int GetVariantForPlatform(Version platformVersion = null)
14 | {
15 | if (platformVersion == null) platformVersion = VersionHelpers.GetWindowsVersion();
16 | if (platformVersion.Major > 6) return 2;
17 | if (platformVersion.Major == 6)
18 | {
19 | if (platformVersion.Minor > 2) return 2;
20 | if (platformVersion.Minor > 1) return 1;
21 | }
22 | return 0;
23 | }
24 |
25 | public static ComObject CreateDevice(SharpDX.DXGI.Device dxgiDevice, int variant = -1)
26 | {
27 | if (variant == -1) variant = 2;
28 | if (variant > 1) { return new DesktopDevice(dxgiDevice); }
29 | return variant == 1 ? new Device(dxgiDevice) : null;
30 | }
31 |
32 | public static void Commit(ComObject device, int variant)
33 | {
34 | if (variant > 1) ((DesktopDevice) device).Commit();
35 | else if (variant == 1) ((Device) device).Commit();
36 | }
37 |
38 | public static Surface CreateSurface(ComObject device, int variant, int width, int height, Format pixelFormat,
39 | AlphaMode alphaMode)
40 | {
41 | if (variant > 1) { return new Surface((DesktopDevice) device, width, height, pixelFormat, alphaMode); }
42 | return variant == 1 ? new Surface((Device) device, width, height, pixelFormat, alphaMode) : null;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/Composition/CompositorCore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.DirectComposition;
4 | using WinApi.DxUtils.Core;
5 |
6 | namespace WinApi.DxUtils.Composition
7 | {
8 | public abstract class CompositorCore : IDisposable, INotifyOnInitDestroy
9 | where TDxgiContainer : IDxgi1Container
10 | {
11 | private readonly Action m_onDxgiDestroyedAction;
12 | private readonly Action m_onDxgiInitializedAction;
13 | protected TDxgiContainer DxgiContainer;
14 | private ComObject m_device;
15 | private bool m_disposed;
16 | protected TOptions Options;
17 |
18 | protected CompositorCore(int variant)
19 | {
20 | if (variant == -1) variant = CompositionHelper.GetVariantForPlatform();
21 | this.DeviceVariant = variant;
22 | this.m_onDxgiDestroyedAction = () => this.DestroyInternal(true);
23 | this.m_onDxgiInitializedAction = () => this.InitializeInternal(true);
24 | }
25 |
26 | public int DeviceVariant { get; }
27 |
28 | public ComObject Device { get { return this.m_device; } private set { this.m_device = value; } }
29 |
30 | public void Dispose()
31 | {
32 | this.m_disposed = true;
33 | GC.SuppressFinalize(this);
34 | this.Destroy();
35 | }
36 |
37 | public event Action Initialized;
38 | public event Action Destroyed;
39 |
40 | private void CheckDisposed()
41 | {
42 | if (this.m_disposed) throw new ObjectDisposedException(this.GetType().Name);
43 | }
44 |
45 | ~CompositorCore()
46 | {
47 | this.Dispose();
48 | }
49 |
50 | public void Destroy()
51 | {
52 | this.DestroyInternal(false);
53 | }
54 |
55 | public void Commit()
56 | {
57 | CompositionHelper.Commit(this.Device, this.DeviceVariant);
58 | }
59 |
60 | private void DestroyInternal(bool preserveDxgiSource)
61 | {
62 | if (!preserveDxgiSource) this.DisconnectFromDxgiSource();
63 | this.DestroyResources();
64 | DisposableHelpers.DisposeAndSetNull(ref this.m_device);
65 | this.Destroyed?.Invoke();
66 | }
67 |
68 | protected void EnsureDevice()
69 | {
70 | if (this.Device == null) this.Device = CompositionHelper.CreateDevice(this.DxgiContainer.DxgiDevice, this.DeviceVariant);
71 | }
72 |
73 | public void Initialize(TDxgiContainer dxgiContainer, TOptions opts = default(TOptions))
74 | {
75 | this.CheckDisposed();
76 | if (this.Device != null) this.Destroy();
77 | this.Options = opts;
78 | this.DxgiContainer = dxgiContainer;
79 | this.InitializeInternal(false);
80 | }
81 |
82 | private void InitializeInternal(bool dxgiSourcePreserved)
83 | {
84 | this.InitializeResources();
85 | if (!dxgiSourcePreserved) this.ConnectToDxgiSource();
86 | this.Initialized?.Invoke();
87 | }
88 |
89 | protected abstract void InitializeResources();
90 |
91 | protected abstract void DestroyResources();
92 |
93 | private void ConnectToDxgiSource()
94 | {
95 | this.DxgiContainer.Destroyed += this.m_onDxgiDestroyedAction;
96 | this.DxgiContainer.Initialized += this.m_onDxgiInitializedAction;
97 | }
98 |
99 | private void DisconnectFromDxgiSource()
100 | {
101 | if (this.DxgiContainer == null) return;
102 | this.DxgiContainer.Initialized -= this.m_onDxgiInitializedAction;
103 | this.DxgiContainer.Destroyed -= this.m_onDxgiDestroyedAction;
104 | }
105 |
106 | public void EnsureInitialized()
107 | {
108 | this.CheckDisposed();
109 | if (this.Device == null) this.InitializeInternal(true);
110 | }
111 | }
112 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/Composition/WindowCompositor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct2D1;
4 | using SharpDX.DirectComposition;
5 | using SharpDX.DXGI;
6 | using WinApi.Core;
7 | using WinApi.DxUtils.Core;
8 | using AlphaMode = SharpDX.DXGI.AlphaMode;
9 | using Device = SharpDX.DirectComposition.Device;
10 |
11 | namespace WinApi.DxUtils.Composition
12 | {
13 | public class WindowCompositor :
14 | CompositorCore
15 | where TDxgiContainer : IDxgi1Container
16 | where TOptions : WindowCompositorOptions
17 | {
18 | private Target m_target;
19 | private Visual m_visual;
20 | public WindowCompositor(int variant = -1) : base(variant) {}
21 |
22 | public Target Target { get { return this.m_target; } private set { this.m_target = value; } }
23 |
24 | public Visual Visual { get { return this.m_visual; } private set { this.m_visual = value; } }
25 |
26 | protected override void InitializeResources()
27 | {
28 | this.EnsureDevice();
29 | var opts = this.Options;
30 | if (this.DeviceVariant > 1)
31 | {
32 | var device = (DesktopDevice) this.Device;
33 | this.Target = Target.FromHwnd(device, opts.Hwnd, opts.IsTopMost);
34 | this.Visual = new Visual2(device);
35 | }
36 | if (this.DeviceVariant == 1)
37 | {
38 | var device = (Device) this.Device;
39 | this.Target = Target.FromHwnd(device, opts.Hwnd, opts.IsTopMost);
40 | this.Visual = new Visual(device);
41 | }
42 | }
43 |
44 | public void SetContent(ComObject rootContent)
45 | {
46 | if (this.Target != null)
47 | {
48 | this.Visual.Content = rootContent;
49 | this.Target.Root = this.Visual;
50 | }
51 | }
52 |
53 | protected override void DestroyResources()
54 | {
55 | DisposableHelpers.DisposeAndSetNull(ref this.m_visual);
56 | DisposableHelpers.DisposeAndSetNull(ref this.m_target);
57 | }
58 | }
59 |
60 | public class WindowSwapChainCompositor : WindowCompositor
61 | {
62 | public WindowSwapChainCompositor(int variant = -1) : base(variant) {}
63 |
64 | protected override void InitializeResources()
65 | {
66 | base.InitializeResources();
67 | this.SetContent(this.DxgiContainer.SwapChain);
68 | this.Commit();
69 | }
70 | }
71 |
72 | public class WindowCompositorOptions
73 | {
74 | public IntPtr Hwnd;
75 | public bool IsTopMost;
76 |
77 | public WindowCompositorOptions(IntPtr hwnd, bool isTopMost = false)
78 | {
79 | this.Hwnd = hwnd;
80 | this.IsTopMost = isTopMost;
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/Composition/WindowSurfaceCompositor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX.DirectComposition;
3 | using SharpDX.DXGI;
4 | using WinApi.Core;
5 | using WinApi.DxUtils.Core;
6 | using Device = SharpDX.DirectComposition.Device;
7 | using Surface = SharpDX.DirectComposition.Surface;
8 | using NetCoreEx.Geometry;
9 |
10 | namespace WinApi.DxUtils.Composition
11 | {
12 | public class WindowSurfaceCompositor : WindowCompositor
13 | {
14 | private Surface m_surface;
15 | public WindowSurfaceCompositor(int variant = -1) : base(variant) {}
16 |
17 | public Surface Surface { get { return this.m_surface; } set { this.m_surface = value; } }
18 |
19 | public Size Size { get { return this.Options.Size; } set { this.Options.Size = value; } }
20 |
21 | public void EnsureInitialized(Size size)
22 | {
23 | this.EnsureInitialized();
24 | if (this.Size != size) this.Resize(size);
25 | }
26 |
27 | protected override void InitializeResources()
28 | {
29 | base.InitializeResources();
30 | this.CreateSurface();
31 | }
32 |
33 | public void Resize(Size size)
34 | {
35 | if (this.Options.Size != size)
36 | {
37 | this.Options.Size = size;
38 | this.DestroySurface();
39 | this.CreateSurface();
40 | }
41 | }
42 |
43 | private void CreateSurface()
44 | {
45 | var size = this.Options.Size;
46 | this.Surface = CompositionHelper.CreateSurface(this.Device, this.DeviceVariant, size.Width, size.Height,
47 | this.Options.PixelFormat, this.Options.AlphaMode);
48 | this.SetContent(this.Surface);
49 | }
50 |
51 | private void DestroySurface()
52 | {
53 | DisposableHelpers.DisposeAndSetNull(ref this.m_surface);
54 | }
55 |
56 | protected override void DestroyResources()
57 | {
58 | this.DestroySurface();
59 | base.DestroyResources();
60 | }
61 | }
62 |
63 | public class WindowSurfaceCompositorOptions : WindowCompositorOptions
64 | {
65 | public AlphaMode AlphaMode;
66 | public Format PixelFormat;
67 |
68 | public Size Size;
69 |
70 | public WindowSurfaceCompositorOptions(IntPtr hwnd, Size size, Format format, AlphaMode mode,
71 | bool isTopMost = false) : base(hwnd, isTopMost)
72 | {
73 | this.Size = size;
74 | this.PixelFormat = format;
75 | this.AlphaMode = mode;
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/Core/DxgiContainerBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using SharpDX.DXGI;
5 |
6 | namespace WinApi.DxUtils.Core
7 | {
8 | public abstract class DxgiContainerBase
9 | {
10 | private List m_connectedResources;
11 |
12 | protected List LinkedResources
13 | {
14 | get { return this.m_connectedResources ?? (this.m_connectedResources = new List()); }
15 | set { this.m_connectedResources = value; }
16 | }
17 |
18 | public event Action Initialized;
19 | public event Action Destroyed;
20 |
21 | protected void InvokeInitializedEvent()
22 | {
23 | this.Initialized?.Invoke();
24 | }
25 |
26 | protected void InvokeDestroyedEvent()
27 | {
28 | this.Destroyed?.Invoke();
29 | }
30 |
31 | public void AddLinkedResource(IDxgiConnectable resource)
32 | {
33 | if (this.LinkedResources.Contains(resource)) return;
34 | this.LinkedResources.Add(resource);
35 | }
36 |
37 | public void AddLinkedResources(IEnumerable resources)
38 | {
39 | this.LinkedResources.AddRange(resources.Except(this.LinkedResources));
40 | }
41 |
42 | public void RemoveLinkedResource(IDxgiConnectable resource)
43 | {
44 | this.LinkedResources.Remove(resource);
45 | }
46 |
47 | public void RemoveLinkedResources(IEnumerable resources)
48 | {
49 | foreach (var res in resources) { this.LinkedResources.Remove(res); }
50 | }
51 |
52 | protected void DisconnectLinkedResources()
53 | {
54 | foreach (var res in this.LinkedResources) { res.DisconnectFromDxgi(); }
55 | }
56 |
57 | protected void ConnectLinkedResources()
58 | {
59 | foreach (var res in this.LinkedResources) { res.ConnectToDxgi(); }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/Core/Interfaces.cs:
--------------------------------------------------------------------------------
1 | using NetCoreEx.Geometry;
2 | using System;
3 | using System.Collections.Generic;
4 | using WinApi.Core;
5 |
6 | namespace WinApi.DxUtils.Core
7 | {
8 | public interface IDxgi1
9 | {
10 | SharpDX.DXGI.Device DxgiDevice { get; }
11 | SharpDX.DXGI.Factory DxgiFactory { get; }
12 | SharpDX.DXGI.Adapter Adapter { get; }
13 | }
14 |
15 | public interface IDxgi1WithSwapChain : IDxgi1
16 | {
17 | SharpDX.DXGI.SwapChain SwapChain { get; }
18 | }
19 |
20 | // ReSharper disable once InconsistentNaming
21 | public interface IDxgi1_2
22 | {
23 | SharpDX.DXGI.Device2 DxgiDevice2 { get; }
24 | SharpDX.DXGI.Factory2 DxgiFactory2 { get; }
25 | }
26 |
27 | // ReSharper disable once InconsistentNaming
28 | public interface IDxgi1_2WithSwapChain : IDxgi1_2
29 | {
30 | SharpDX.DXGI.SwapChain1 SwapChain1 { get; }
31 | }
32 |
33 | public interface IDxgi1Container : IDxgiContainerCore, IDxgi1, INotifyOnInitDestroy {}
34 |
35 | public interface IDxgi1ContainerWithSwapChain : IDxgi1Container, IDxgi1WithSwapChain {}
36 |
37 |
38 | // ReSharper disable once InconsistentNaming
39 | public interface IDxgi1_2Container : IDxgi1Container, IDxgi1_2 {}
40 |
41 | // ReSharper disable once InconsistentNaming
42 | public interface IDxgi1_2ContainerWithSwapChain : IDxgi1ContainerWithSwapChain, IDxgi1_2WithSwapChain {}
43 |
44 |
45 | public interface IDxgi1MetaResource : IDxgi1Container
46 | {
47 | void Initialize();
48 | void EnsureInitialized();
49 | void Destroy();
50 | }
51 |
52 | public interface ID3D11MetaResourceCore : IDxgi1ContainerWithSwapChain, IDisposable
53 | {
54 | SharpDX.Direct3D11.Device Device { get; }
55 | SharpDX.Direct3D11.DeviceContext Context { get; }
56 | SharpDX.Direct3D11.RenderTargetView RenderTargetView { get; }
57 | }
58 |
59 | // ReSharper disable once InconsistentNaming
60 | public interface ID3D11_1MetaResourceCore : ID3D11MetaResourceCore, IDxgi1_2ContainerWithSwapChain {}
61 |
62 | public interface ID3D11MetaResource : ID3D11MetaResourceCore
63 | {
64 | void Initialize(IntPtr hwnd, Size size);
65 | void EnsureInitialized();
66 | void Resize(Size size);
67 | void Destroy();
68 | }
69 |
70 | // ReSharper disable once InconsistentNaming
71 | public interface ID3D11_1MetaResource : ID3D11MetaResource, ID3D11_1MetaResourceCore {}
72 |
73 | // ReSharper disable once InconsistentNaming
74 | public interface ID2D1_1MetaResourceCore : IDxgiConnectable, INotifyOnInitDestroy, IDisposable
75 | {
76 | SharpDX.Direct2D1.Device Device { get; }
77 | SharpDX.Direct2D1.DeviceContext Context { get; }
78 | SharpDX.Direct2D1.Factory1 Factory1 { get; }
79 | }
80 |
81 | // ReSharper disable once InconsistentNaming
82 | public interface ID2D1_1MetaResource : ID2D1_1MetaResourceCore
83 | {
84 | void Initialize(TDxgi1Container dxgiContainer, bool autoLink = true);
85 | void EnsureInitialized();
86 | void Destroy();
87 | }
88 |
89 | public interface IDxgiContainerCore
90 | {
91 | void AddLinkedResource(IDxgiConnectable resource);
92 | void AddLinkedResources(IEnumerable resources);
93 | void RemoveLinkedResource(IDxgiConnectable resource);
94 | void RemoveLinkedResources(IEnumerable resources);
95 | }
96 |
97 | public interface IDxgiConnectable
98 | {
99 | void ConnectToDxgi();
100 | void DisconnectFromDxgi();
101 | }
102 |
103 | public interface INotifyOnInitDestroy
104 | {
105 | event Action Initialized;
106 | event Action Destroyed;
107 | }
108 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/D2D1/D2D1Helper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX.Direct2D1;
3 | using SharpDX.DXGI;
4 | using WinApi.DxUtils.Core;
5 |
6 | namespace WinApi.DxUtils.D2D1
7 | {
8 | public static class D2D1Helper
9 | {
10 | public static void ConnectContextToDxgiSwapChain(
11 | D2D1MetaResource d2D1MetaResource)
12 | {
13 | using (var surface = d2D1MetaResource.DxgiContainer.SwapChain1.GetBackBuffer(0))
14 | {
15 | using (var bitmap = new Bitmap1(d2D1MetaResource.Context, surface)) d2D1MetaResource.Context.Target = bitmap;
16 | }
17 | }
18 |
19 | public static void DisconnectContextFromDxgiSwapChain(
20 | D2D1MetaResource d2D1MetaResource)
21 | {
22 | var currentTarget = d2D1MetaResource.Context?.Target;
23 | if (currentTarget == null) return;
24 | currentTarget.Dispose();
25 | d2D1MetaResource.Context.Target = null;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/D2D1/D2D1MetaFactory.cs:
--------------------------------------------------------------------------------
1 | using SharpDX.Direct2D1;
2 | using WinApi.DxUtils.Core;
3 |
4 | namespace WinApi.DxUtils.D2D1
5 | {
6 | public class D2D1MetaFactory
7 | {
8 | public static D2D1MetaResource Create(ref CreationProperties props)
9 | {
10 | return CreateCore(ref props);
11 | }
12 |
13 | public static D2D1MetaResource Create(
14 | ThreadingMode threadingMode = ThreadingMode.SingleThreaded,
15 | DeviceContextOptions contextOptions = DeviceContextOptions.EnableMultithreadedOptimizations,
16 | DebugLevel debugLevel = DebugLevel.None)
17 | {
18 | var props = new CreationProperties
19 | {
20 | DebugLevel = debugLevel,
21 | ThreadingMode = threadingMode,
22 | Options = contextOptions
23 | };
24 | return CreateCore(ref props);
25 | }
26 |
27 | private static D2D1MetaResource CreateCore(
28 | ref CreationProperties props)
29 | {
30 | #if DEBUG
31 | // Note: These have no impact on solution outside
32 | // of this project. This is only for internal testing
33 | // purposes
34 | if (props.DebugLevel == 0) props.DebugLevel = DebugLevel.Information;
35 | #endif
36 | return new D2D1MetaResource(props, null, null);
37 | }
38 |
39 | public static D2D1MetaResource CreateForSwapChain(ref CreationProperties props)
40 | {
41 | return CreateForSwapChainCore(ref props);
42 | }
43 |
44 | public static D2D1MetaResource CreateForSwapChain(
45 | ThreadingMode threadingMode = ThreadingMode.SingleThreaded,
46 | DeviceContextOptions contextOptions = DeviceContextOptions.EnableMultithreadedOptimizations,
47 | DebugLevel debugLevel = DebugLevel.None)
48 | {
49 | var props = new CreationProperties
50 | {
51 | DebugLevel = debugLevel,
52 | ThreadingMode = threadingMode,
53 | Options = contextOptions
54 | };
55 | return CreateForSwapChainCore(ref props);
56 | }
57 |
58 | private static D2D1MetaResource CreateForSwapChainCore(
59 | ref CreationProperties props)
60 | {
61 | #if DEBUG
62 | // Note: These have no impact on solution outside
63 | // of this project. This is only for internal testing
64 | // purposes
65 | if (props.DebugLevel == 0) props.DebugLevel = DebugLevel.Information;
66 | #endif
67 | return new D2D1MetaResource(props, D2D1Helper.ConnectContextToDxgiSwapChain,
68 | D2D1Helper.DisconnectContextFromDxgiSwapChain);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/D3D11/D3D11Container.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX.Direct3D;
3 | using SharpDX.Direct3D11;
4 | using SharpDX.DXGI;
5 | using SharpDX.Mathematics.Interop;
6 | using WinApi.Core;
7 | using WinApi.DxUtils.Core;
8 | using Device = SharpDX.Direct3D11.Device;
9 | using NetCoreEx.Geometry;
10 |
11 | namespace WinApi.DxUtils.D3D11
12 | {
13 | public abstract class D3D11ContainerCore : D3D11Dxgi1_2ContainerCore, IDxgi1ContainerWithSwapChain
14 | {
15 | public virtual DeviceContext Context { get; protected set; }
16 | public virtual RenderTargetView RenderTargetView { get; protected set; }
17 | public virtual SwapChain SwapChain { get; protected set; }
18 |
19 | public static Size GetValidatedSize(ref Size size)
20 | {
21 | var h = size.Height >= 0 ? size.Height : 0;
22 | var w = size.Width >= 0 ? size.Width : 0;
23 | return new Size(w, h);
24 | }
25 |
26 | protected void EnsureSwapChain()
27 | {
28 | if (this.SwapChain == null) this.CreateSwapChain();
29 | }
30 |
31 | protected abstract void CreateSwapChain();
32 |
33 | protected void EnsureContext()
34 | {
35 | if (this.Context == null) this.CreateContext();
36 | }
37 |
38 | protected abstract void CreateContext();
39 |
40 | protected void EnsureRenderTargetView()
41 | {
42 | if (this.RenderTargetView == null) this.CreateRenderTargetView();
43 | }
44 |
45 | protected abstract void CreateRenderTargetView();
46 | }
47 |
48 | // ReSharper disable once InconsistentNaming
49 | public abstract class D3D11_1ContainerCore : D3D11ContainerCore, IDxgi1_2ContainerWithSwapChain
50 | {
51 | public override DeviceContext Context => this.Context1;
52 |
53 | public virtual DeviceContext1 Context1 { get; protected set; }
54 | public override Factory DxgiFactory => this.DxgiFactory2;
55 | public override SharpDX.DXGI.Device DxgiDevice => this.DxgiDevice2;
56 | public override SwapChain SwapChain => this.SwapChain1;
57 | public virtual SwapChain1 SwapChain1 { get; protected set; }
58 | }
59 |
60 | // ReSharper disable once InconsistentNaming
61 | public abstract class D3D11_1Container : D3D11_1ContainerCore
62 | {
63 | protected override void CreateDxgiDevice()
64 | {
65 | this.EnsureDevice();
66 | this.DxgiDevice2 = this.Device1.QueryInterface();
67 | }
68 |
69 | protected override void CreateAdapter()
70 | {
71 | this.EnsureDxgiDevice();
72 | this.Adapter = this.DxgiDevice2.GetParent();
73 | }
74 |
75 | protected override void CreateDxgiFactory()
76 | {
77 | this.EnsureAdapter();
78 | this.DxgiFactory2 = this.Adapter.GetParent();
79 | }
80 |
81 | protected override void CreateContext()
82 | {
83 | this.EnsureDevice();
84 | this.Context1 = this.Device1.ImmediateContext1;
85 | }
86 |
87 | protected override void CreateRenderTargetView()
88 | {
89 | this.EnsureDevice();
90 | this.EnsureSwapChain();
91 | using (var backBuffer = this.SwapChain1.GetBackBuffer(0)) {
92 | this.RenderTargetView = new RenderTargetView(this.Device1, backBuffer);
93 | }
94 | }
95 |
96 | protected void ConnectRenderTargetView()
97 | {
98 | this.EnsureContext();
99 | this.EnsureRenderTargetView();
100 | this.Context1.OutputMerger.SetRenderTargets(this.RenderTargetView);
101 | }
102 |
103 | protected void DisconnectRenderTargetView()
104 | {
105 | if (this.Context == null) return;
106 | this.Context1.OutputMerger.SetRenderTargets((RenderTargetView) null);
107 | }
108 | }
109 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/D3D11/D3D11Dxgi1_2MetaResource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX.DXGI;
3 | using WinApi.DxUtils.Core;
4 | using Device1 = SharpDX.Direct3D11.Device1;
5 |
6 | namespace WinApi.DxUtils.D3D11
7 | {
8 | // ReSharper disable once InconsistentNaming
9 | public class D3D11Dxgi1_2MetaResource : D3D11Dxgi1_2ContainerCore, IDxgi1MetaResource
10 | {
11 | private readonly D3D11DxgiOptions m_opts;
12 | private Adapter m_adapter;
13 | private Device1 m_device;
14 | private Device2 m_dxgiDevice;
15 | private Factory2 m_dxgiFactory;
16 | private bool m_isDisposed;
17 |
18 | public D3D11Dxgi1_2MetaResource(D3D11DxgiOptions opts)
19 | {
20 | this.m_opts = opts;
21 | }
22 |
23 | public override Device1 Device1 { get { return this.m_device; } protected set { this.m_device = value; } }
24 |
25 | public override Device2 DxgiDevice2
26 | {
27 | get { return this.m_dxgiDevice; }
28 | protected set { this.m_dxgiDevice = value; }
29 | }
30 |
31 | public override Factory2 DxgiFactory2
32 | {
33 | get { return this.m_dxgiFactory; }
34 | protected set { this.m_dxgiFactory = value; }
35 | }
36 |
37 | public override Adapter Adapter { get { return this.m_adapter; } protected set { this.m_adapter = value; } }
38 |
39 | public void Initialize()
40 | {
41 | this.CheckDisposed();
42 | if (this.Device1 != null) this.Destroy();
43 | this.InitializeInternal();
44 | }
45 |
46 | public void EnsureInitialized()
47 | {
48 | this.CheckDisposed();
49 | if (this.Device1 == null) this.InitializeInternal();
50 | }
51 |
52 | public void Destroy()
53 | {
54 | this.DisconnectLinkedResources();
55 | DisposableHelpers.DisposeAndSetNull(ref this.m_dxgiFactory);
56 | DisposableHelpers.DisposeAndSetNull(ref this.m_adapter);
57 | DisposableHelpers.DisposeAndSetNull(ref this.m_dxgiDevice);
58 | DisposableHelpers.DisposeAndSetNull(ref this.m_device);
59 | this.InvokeDestroyedEvent();
60 | }
61 |
62 | protected override void CreateDxgiDevice()
63 | {
64 | this.EnsureDevice();
65 | this.DxgiDevice2 = this.Device1.QueryInterface();
66 | }
67 |
68 | protected override void CreateAdapter()
69 | {
70 | this.EnsureDxgiDevice();
71 | this.Adapter = this.DxgiDevice2.GetParent();
72 | }
73 |
74 | protected override void CreateDxgiFactory()
75 | {
76 | this.EnsureAdapter();
77 | this.DxgiFactory2 = this.Adapter.GetParent();
78 | }
79 |
80 | protected override void CreateDevice()
81 | {
82 | this.Device1 = D3D11MetaFactory.CreateD3DDevice1(this.m_opts);
83 | }
84 |
85 | private void InitializeInternal()
86 | {
87 | this.EnsureDxgiDevice();
88 | this.InvokeInitializedEvent();
89 | }
90 |
91 | public void Dispose()
92 | {
93 | this.m_isDisposed = true;
94 | GC.SuppressFinalize(this);
95 | this.Destroy();
96 | this.LinkedResources.Clear();
97 | }
98 |
99 | ~D3D11Dxgi1_2MetaResource()
100 | {
101 | this.Dispose();
102 | }
103 |
104 | private void CheckDisposed()
105 | {
106 | if (this.m_isDisposed) throw new ObjectDisposedException(nameof(D3D11Dxgi1_2MetaResource));
107 | }
108 | }
109 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/D3D11/D3D11DxgiContainer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 | using SharpDX.Direct3D;
6 | using SharpDX.Direct3D11;
7 | using SharpDX.DXGI;
8 | using WinApi.DxUtils.Core;
9 | using Device = SharpDX.Direct3D11.Device;
10 | using Device1 = SharpDX.Direct3D11.Device1;
11 |
12 | namespace WinApi.DxUtils.D3D11
13 | {
14 | public abstract class D3D11Dxgi1ContainerCore : DxgiContainerBase, IDxgi1Container
15 | {
16 | public virtual Device Device { get; protected set; }
17 | public virtual SharpDX.DXGI.Device DxgiDevice { get; protected set; }
18 | public virtual Factory DxgiFactory { get; protected set; }
19 | public virtual Adapter Adapter { get; protected set; }
20 |
21 | protected void EnsureDxgiDevice()
22 | {
23 | if (this.DxgiDevice == null) this.CreateDxgiDevice();
24 | }
25 |
26 | protected abstract void CreateDxgiDevice();
27 |
28 | protected void EnsureAdapter()
29 | {
30 | if (this.Adapter == null) this.CreateAdapter();
31 | }
32 |
33 | protected abstract void CreateAdapter();
34 |
35 | protected void EnsureDxgiFactory()
36 | {
37 | if (this.DxgiFactory == null) this.CreateDxgiFactory();
38 | }
39 |
40 | protected abstract void CreateDxgiFactory();
41 |
42 | protected void EnsureDevice()
43 | {
44 | if (this.Device == null) this.CreateDevice();
45 | }
46 |
47 | protected abstract void CreateDevice();
48 | }
49 |
50 | // ReSharper disable once InconsistentNaming
51 | public abstract class D3D11Dxgi1_2ContainerCore : D3D11Dxgi1ContainerCore, IDxgi1_2Container
52 | {
53 | public override Device Device => this.Device1;
54 | public virtual Device1 Device1 { get; protected set; }
55 | public override Factory DxgiFactory => this.DxgiFactory2;
56 | public override SharpDX.DXGI.Device DxgiDevice => this.DxgiDevice2;
57 |
58 | public virtual Factory2 DxgiFactory2 { get; protected set; }
59 | public virtual SharpDX.DXGI.Device2 DxgiDevice2 { get; protected set; }
60 | }
61 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/DxPainter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SharpDX;
7 | using SharpDX.Direct2D1;
8 | using SharpDX.Mathematics.Interop;
9 | using WinApi.DxUtils.Component;
10 | using WinApi.Windows;
11 |
12 | namespace WinApi.DxUtils
13 | {
14 | public static class DxPainter
15 | {
16 | public static void HandlePaint(EventedWindowCore window, Dx11Component resource,
17 | Action handler)
18 | {
19 | resource.EnsureInitialized();
20 | try
21 | {
22 | handler(resource);
23 | resource.D3D.SwapChain.Present(1, 0);
24 | window.Validate();
25 | }
26 | catch (SharpDXException ex)
27 | {
28 | if (!resource.PerformResetOnException(ex)) throw;
29 | }
30 | }
31 |
32 | public static void HandlePaintD2D(EventedWindowCore window, Dx11Component resource,
33 | Action handler)
34 | {
35 | resource.EnsureInitialized();
36 | try
37 | {
38 | var context = resource.D2D.Context;
39 | context.BeginDraw();
40 | handler(context);
41 | context.EndDraw();
42 | resource.D3D.SwapChain.Present(1, 0);
43 | window.Validate();
44 | }
45 | catch (SharpDXException ex)
46 | {
47 | if (!resource.PerformResetOnException(ex)) throw;
48 | }
49 | }
50 |
51 | public static void HandlePaintD2DClipped(EventedWindowCore window, Dx11Component resource,
52 | Action handler, RawRectangleF clip, RawColor4? clearColorBeforeClip = null)
53 | {
54 | HandlePaintD2DClipped(window, resource, handler, ref clip, clearColorBeforeClip);
55 | }
56 |
57 | public static void HandlePaintD2DClipped(EventedWindowCore window, Dx11Component resource,
58 | Action handler, ref RawRectangleF clip, RawColor4? clearColorBeforeClip = null)
59 | {
60 | resource.EnsureInitialized();
61 | try
62 | {
63 | var context = resource.D2D.Context;
64 | context.BeginDraw();
65 | if (clearColorBeforeClip.HasValue) context.Clear(clearColorBeforeClip.Value);
66 | context.PushAxisAlignedClip(clip,
67 | AntialiasMode.Aliased);
68 | handler(context);
69 | context.PopAxisAlignedClip();
70 | context.EndDraw();
71 | resource.D3D.SwapChain.Present(1, 0);
72 | window.Validate();
73 | }
74 | catch (SharpDXException ex)
75 | {
76 | if (!resource.PerformResetOnException(ex)) throw;
77 | }
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/DxVersionInfo.txt:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * DX Common Interface Versions:
4 | *
5 | * DXGI:
6 | * ====
7 | * Platforms:
8 | * ----
9 | * v1.0 - 1.1 : Win 7+
10 | * v1.2: Win 7 (Platform Update)+, Win 8+
11 | * v1.3: Win 8.1+
12 | * v1.4: Win 10+
13 | * v1.5: Win 10 (2016 Anniversary Update)+
14 | * ----
15 | *
16 | * v1.0: Factory, Adapter, Device, SwapChain, Output, Resource, Surface
17 | * v1.1: Factory1, Adapter1, Device1, Surface1
18 | * v1.2: Factory2, Adapter2, SwapChain1, Device2, Debug, Output1, Resource1, Surface2
19 | * v1.3: Factory3, Adapter3, SwapChain2, Device3, Debug1, Output2, Output3
20 | * v1.4: Factory4, SwapChain3, Output4
21 | * v1.5: Factory5, Device4, SwapChain4, Output5
22 | *
23 | * D3D11:
24 | * ====
25 | * Platforms:
26 | * ----
27 | * v11 - Windows 7+
28 | * v11.1 - Win 7 (Platform Update)+, Win 8+
29 | * v11.2 - Win 8.1+
30 | * v11.3, v12 - Win 10+
31 | * ----
32 | *
33 | * v11 - Device, DeviceContext
34 | * v11.1 - Device1, DeviceContext1
35 | * v11.2 - Device2, DeviceContext2
36 | * v11.3 - Device3, DeviceContext3
37 | * v11.4 - Device4
38 | */
39 |
40 |
41 | /**
42 | * D2D Common Interfaces:
43 | * ====
44 | * Platforms:
45 | * ----
46 | * v1.0 - Win 7+
47 | * v1.1 - Win 7 (Platform Update)+, Win 8+
48 | * v1.2 - Win 8.1+
49 | * v1.3 - Win 10+
50 | * ----
51 | *
52 | * v1.0 - Factory, Bitmap, BitmapBrush
53 | * v1.1 - Factory1, Device, DeviceContext, Bitmap1, BitmapBrush1
54 | * v1.2 - Factory2, Device1, DeviceContext1
55 | * v1.3 - Factory3, Factory4, Factory5, Device2, Device3, Device4, DeviceContext2, DeviceContext3, DeviceContext4
56 | *
57 | */
58 |
59 |
60 | /**
61 | * DirectWrite Interfaces:
62 | * ====
63 | * Platforms:
64 | * ----
65 | * v1.0 - Win 7+
66 | * v1.1 - Win 8+
67 | * v1.2 - Win 8.1+
68 | * v1.3 - Win 10+
69 | * ----
70 | */
71 |
72 |
73 | /**
74 | * DirectComposition Interfaces:
75 | * ====
76 | * Platforms:
77 | * ----
78 | * v1.0 - Win 8+
79 | * v1.1 - Win 8.1+
80 | * ----
81 | */
82 |
--------------------------------------------------------------------------------
/WinApi.DxUtils/DxWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SharpDX.Direct2D1;
7 | using SharpDX.Mathematics.Interop;
8 | using WinApi.Core;
9 | using WinApi.DxUtils.Component;
10 | using WinApi.User32;
11 | using WinApi.Windows;
12 |
13 | namespace WinApi.DxUtils
14 | {
15 | public class DxWindow : EventedWindowCore
16 | {
17 | protected readonly Dx11Component Dx = new Dx11Component();
18 |
19 | private bool m_isFirstBkgdErased;
20 |
21 | protected override void OnCreate(ref CreateWindowPacket packet)
22 | {
23 | this.Dx.Initialize(this.Handle, this.GetClientSize());
24 | base.OnCreate(ref packet);
25 | }
26 |
27 | protected virtual void OnDxPaint(Dx11Component resource) {}
28 |
29 | protected override void OnPaint(ref PaintPacket packet)
30 | {
31 | DxPainter.HandlePaint(this, this.Dx, this.OnDxPaint);
32 | }
33 |
34 | protected override void OnSize(ref SizePacket packet)
35 | {
36 | this.Dx.Resize(packet.Size);
37 | base.OnSize(ref packet);
38 | }
39 |
40 | protected override void OnEraseBkgnd(ref EraseBkgndPacket packet)
41 | {
42 | if (this.m_isFirstBkgdErased)
43 | {
44 | packet.Result = EraseBackgroundResult.DisableDefaultErase;
45 | return;
46 | }
47 | this.m_isFirstBkgdErased = true;
48 | base.OnEraseBkgnd(ref packet);
49 | }
50 |
51 | protected override void Dispose(bool disposing)
52 | {
53 | this.Dx.Dispose();
54 | base.Dispose(disposing);
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/Helpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using WinApi.DxUtils.Core;
4 |
5 | namespace WinApi.DxUtils
6 | {
7 | public static class DisposableHelpers
8 | {
9 | public static void DisposeAndSetNull(ref T obj)
10 | where T : class, IDisposable
11 | {
12 | if (obj != null)
13 | {
14 | obj.Dispose();
15 | obj = null;
16 | }
17 | }
18 | }
19 |
20 | public static class ErrorHelpers
21 | {
22 | public static bool ShouldResetDxgiForError(ResultDescriptor resultDescriptor)
23 | {
24 | return ShouldResetDxgiForError(resultDescriptor.Code);
25 | }
26 |
27 | public static bool ShouldResetDxgiForError(int code)
28 | {
29 | return (code == SharpDX.DXGI.ResultCode.DeviceRemoved.Code) ||
30 | (code == SharpDX.DXGI.ResultCode.DeviceReset.Code);
31 | }
32 |
33 | public static bool ShouldResetD2DForError(ResultDescriptor resultDescriptor)
34 | {
35 | return ShouldResetD2DForError(resultDescriptor.Code);
36 | }
37 |
38 | public static bool ShouldResetD2DForError(int code)
39 | {
40 | return code == SharpDX.Direct2D1.ResultCode.RecreateTarget.Code;
41 | }
42 | }
43 |
44 | internal static class VersionHelpers {
45 | public static Version GetWindowsVersion()
46 | {
47 | var desc = System.Runtime.InteropServices.RuntimeInformation.OSDescription;
48 | if (desc.Contains(" 10."))
49 | {
50 | return new Version(10, 0, 0, 0);
51 | }
52 | else if (desc.Contains(" 6.3"))
53 | {
54 | return new Version(6, 3, 0, 0);
55 | }
56 | else if (desc.Contains(" 6.2"))
57 | {
58 | return new Version(6, 2, 0, 0);
59 | }
60 | return new Version(6, 1, 0, 0);
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/WinApi.DxUtils/WinApi.DxUtils.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard1.4
4 | Prasanna V. Loganathar
5 | Prasanna V. Loganathar
6 | https://www.apache.org/licenses/LICENSE-2.0.txt
7 | https://github.com/prasannavl/WinApi
8 | https://github.com/prasannavl/WinApi
9 | https://raw.githubusercontent.com/prasannavl/WinApi/master/Misc/Logo.png
10 | Copyright © Prasanna V. Loganathar
11 | DirectX helpers and utils to ease directx version management with SharpDx and WinApi.
12 | 4.0.0
13 | true
14 | directx d3d utils win32 native interop
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/WinApi.Utils/DwmWindow.cs:
--------------------------------------------------------------------------------
1 | using NetCoreEx.Geometry;
2 | using System;
3 | using WinApi.Core;
4 | using WinApi.DwmApi;
5 | using WinApi.User32;
6 | using WinApi.User32.Experimental;
7 | using WinApi.UxTheme;
8 | using WinApi.Windows;
9 | using WinApi.Windows.Helpers;
10 |
11 | namespace WinApi.Utils
12 | {
13 | public class DwmWindow : EventedWindowCore
14 | {
15 | protected readonly DwmWindowHelper DwmHelper;
16 |
17 | public DwmWindow()
18 | {
19 | this.DwmHelper = new DwmWindowHelper(this);
20 | }
21 |
22 | protected bool DrawCaptionIcon { get; set; }
23 | protected bool DrawCaptionTitle { get; set; }
24 | protected bool AllowSystemMenu { get; set; }
25 |
26 | protected override void OnCreate(ref CreateWindowPacket packet)
27 | {
28 | this.DwmHelper.Initialize(this.DrawCaptionIcon, this.DrawCaptionTitle, this.AllowSystemMenu);
29 | base.OnCreate(ref packet);
30 | }
31 |
32 | public override void ClientToScreen(ref Rectangle clientRect, out Rectangle screenRect)
33 | {
34 | base.ClientToScreen(ref clientRect, out screenRect);
35 | screenRect.Top += -this.DwmHelper.NcOutsetThickness.Top;
36 | }
37 |
38 | public override void ScreenToClient(ref Rectangle screenRect, out Rectangle clientRect)
39 | {
40 | screenRect.Top -= -this.DwmHelper.NcOutsetThickness.Top;
41 | base.ScreenToClient(ref screenRect, out clientRect);
42 | }
43 |
44 | protected override void OnActivate(ref ActivatePacket packet)
45 | {
46 | this.DwmHelper.ApplyDwmConfig();
47 | base.OnActivate(ref packet);
48 | }
49 |
50 | protected override void OnNcCalcSize(ref NcCalcSizePacket packet)
51 | {
52 | if (this.DwmHelper.TryHandleNcCalcSize(ref packet)) return;
53 | base.OnNcCalcSize(ref packet);
54 | }
55 |
56 | protected override void OnNcHitTest(ref NcHitTestPacket packet)
57 | {
58 | packet.Result = this.DwmHelper.HitTestWithCaptionArea(packet.Point);
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/WinApi.Utils/NativePixelBuffer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using WinApi.Core;
4 |
5 | namespace WinApi.Utils
6 | {
7 | public class NativePixelBuffer : IDisposable
8 | {
9 | public IntPtr Handle { get; private set; }
10 | public int BufferLength { get; private set; }
11 | public int Stride { get; private set; }
12 | public int ImageWidth { get; private set; }
13 | public int ImageHeight { get; private set; }
14 |
15 | public void Dispose()
16 | {
17 | GC.SuppressFinalize(this);
18 | if (this.Handle != IntPtr.Zero)
19 | {
20 | Marshal.FreeHGlobal(this.Handle);
21 | this.Handle = IntPtr.Zero;
22 | this.BufferLength = 0;
23 | this.ImageWidth = this.ImageHeight = 0;
24 | }
25 | }
26 |
27 | ~NativePixelBuffer()
28 | {
29 | this.Dispose();
30 | }
31 |
32 | public bool CheckSize(int imageWidth, int imageHeight)
33 | {
34 | return (imageWidth == this.ImageWidth) && (imageHeight == this.ImageHeight);
35 | }
36 |
37 | public void EnsureSize(int imageWidth, int imageHeight)
38 | {
39 | if (this.CheckSize(imageWidth, imageHeight)) return;
40 | this.Resize(imageWidth, imageHeight);
41 | }
42 |
43 | public void Resize(int imageWidth, int imageHeight)
44 | {
45 | var stride = 4*((imageWidth*32 + 31)/32);
46 | var bufferLength = imageHeight*stride;
47 | if (bufferLength != this.BufferLength)
48 | {
49 | if (this.Handle != IntPtr.Zero) Marshal.FreeHGlobal(this.Handle);
50 | this.Handle = Marshal.AllocHGlobal(bufferLength);
51 | this.BufferLength = bufferLength;
52 | }
53 |
54 | this.Stride = stride;
55 | this.ImageWidth = imageWidth;
56 | this.ImageHeight = imageHeight;
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/WinApi.Utils/Types.cs:
--------------------------------------------------------------------------------
1 | namespace WinApi.Utils
2 | {
3 | public struct CartesianValue
4 | {
5 | public int X;
6 | public int Y;
7 | }
8 | }
--------------------------------------------------------------------------------
/WinApi.Utils/WinApi.Utils.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard1.4
4 | Prasanna V. Loganathar
5 | Prasanna V. Loganathar
6 | https://www.apache.org/licenses/LICENSE-2.0.txt
7 | https://github.com/prasannavl/WinApi
8 | https://github.com/prasannavl/WinApi
9 | https://raw.githubusercontent.com/prasannavl/WinApi/master/Misc/Logo.png
10 | Copyright © Prasanna V. Loganathar
11 | Utility library that supplements WinApi
12 | 4.0.0
13 | true
14 | win32 native interop
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/WinApi.Windows.Controls/Button.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics.CodeAnalysis;
3 | using WinApi.User32;
4 |
5 | namespace WinApi.Windows.Controls
6 | {
7 | public class Button : EventedWindowCore, IConstructionParamsProvider
8 | {
9 | public static Lazy ClassFactory =
10 | new Lazy(() => WindowFactory.CreateForExistingClass("button"));
11 |
12 | protected Button() {}
13 |
14 | IConstructionParams IConstructionParamsProvider.GetConstructionParams() => new ButtonConstructionParams();
15 |
16 | public static Button Create(string text = null,
17 | WindowStyles? styles = null,
18 | WindowExStyles? exStyles = null, int? x = null, int? y = null,
19 | int? width = null, int? height = null, IntPtr? hParent = null, IntPtr? hMenu = null,
20 | WindowFactory factory = null, ButtonStyles? controlStyles = null)
21 | {
22 | return (factory ?? ClassFactory.Value).CreateWindowEx(() => new Button(), text, styles, exStyles, x, y,
23 | width,
24 | height, hParent, hMenu, (uint) (controlStyles ?? 0));
25 | }
26 |
27 | public class ButtonConstructionParams : VisibleChildConstructionParams
28 | {
29 | public override int Width => 200;
30 | public override int Height => 35;
31 | public override WindowExStyles ExStyles => 0;
32 | }
33 |
34 | [SuppressMessage("ReSharper", "InconsistentNaming")]
35 | [Flags]
36 | public enum ButtonStyles
37 | {
38 | BS_PUSHBUTTON = 0x00000000,
39 | BS_DEFPUSHBUTTON = 0x00000001,
40 | BS_CHECKBOX = 0x00000002,
41 | BS_AUTOCHECKBOX = 0x00000003,
42 | BS_RADIOBUTTON = 0x00000004,
43 | BS_3STATE = 0x00000005,
44 | BS_AUTO3STATE = 0x00000006,
45 | BS_GROUPBOX = 0x00000007,
46 | BS_USERBUTTON = 0x00000008,
47 | BS_AUTORADIOBUTTON = 0x00000009,
48 | BS_PUSHBOX = 0x0000000A,
49 | BS_OWNERDRAW = 0x0000000B,
50 | BS_TYPEMASK = 0x0000000F,
51 | BS_LEFTTEXT = 0x00000020,
52 | BS_TEXT = 0x00000000,
53 | BS_ICON = 0x00000040,
54 | BS_BITMAP = 0x00000080,
55 | BS_LEFT = 0x00000100,
56 | BS_RIGHT = 0x00000200,
57 | BS_CENTER = 0x00000300,
58 | BS_TOP = 0x00000400,
59 | BS_BOTTOM = 0x00000800,
60 | BS_VCENTER = 0x00000C00,
61 | BS_PUSHLIKE = 0x00001000,
62 | BS_MULTILINE = 0x00002000,
63 | BS_NOTIFY = 0x00004000,
64 | BS_FLAT = 0x00008000,
65 | BS_RIGHTBUTTON = BS_LEFTTEXT
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/WinApi.Windows.Controls/Layouts/HorizontalStretchLayout.cs:
--------------------------------------------------------------------------------
1 | using NetCoreEx.Geometry;
2 | using System.Collections.Generic;
3 | using WinApi.Core;
4 | using WinApi.User32;
5 |
6 | namespace WinApi.Windows.Controls.Layouts
7 | {
8 | public class HorizontalStretchLayout
9 | {
10 | public List Children;
11 | public Rectangle ClientArea;
12 | public Rectangle Margin;
13 |
14 | public HorizontalStretchLayout(int capacity = 0)
15 | {
16 | this.Children = new List(capacity);
17 | }
18 |
19 | public void SetSize(ref Size size)
20 | {
21 | if (this.ClientArea.Size == size) return;
22 | this.ClientArea.Width = size.Width;
23 | this.ClientArea.Height = size.Height;
24 | this.PerformLayout();
25 | }
26 |
27 | public void PerformLayout()
28 | {
29 | var clientArea = this.ClientArea;
30 | var margin = this.Margin;
31 | var clientRect = clientArea;
32 | Rectangle.Deflate(ref clientRect, ref margin);
33 | var len = this.Children.Count;
34 |
35 | var childSize = clientRect.Size;
36 | childSize.Width = childSize.Width/len;
37 |
38 | var cx = clientRect.Left;
39 | var cy = clientRect.Top;
40 |
41 | foreach (var windowCore in this.Children)
42 | {
43 | windowCore.SetPosition(cx, cy, childSize.Width, childSize.Height);
44 | cx += childSize.Width;
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/WinApi.Windows.Controls/Layouts/HorizontalStretchLayoutWithInnerMargin.cs:
--------------------------------------------------------------------------------
1 | using NetCoreEx.Geometry;
2 | using System.Collections.Generic;
3 | using WinApi.Core;
4 | using WinApi.User32;
5 |
6 | namespace WinApi.Windows.Controls.Layouts
7 | {
8 | public class HorizontalStretchLayoutWithInnerMargin
9 | {
10 | public List Children;
11 | public Rectangle ClientArea;
12 | public Rectangle InnerMargin;
13 | public Rectangle Margin;
14 |
15 | public HorizontalStretchLayoutWithInnerMargin(int capacity = 0)
16 | {
17 | this.Children = new List(capacity);
18 | }
19 |
20 | public void SetSize(ref Size size)
21 | {
22 | if (this.ClientArea.Size == size) return;
23 | this.ClientArea.Width = size.Width;
24 | this.ClientArea.Height = size.Height;
25 | this.PerformLayout();
26 | }
27 |
28 | public void PerformLayout()
29 | {
30 | var clientArea = this.ClientArea;
31 | var margin = this.Margin;
32 | var innerMargin = this.InnerMargin;
33 |
34 | var clientRect = clientArea;
35 | Rectangle.Deflate(ref clientRect, ref margin);
36 | var len = this.Children.Count;
37 |
38 | var childSize = clientRect.Size;
39 | childSize.Width = childSize.Width/len;
40 |
41 | var cx = clientRect.Left + innerMargin.Left;
42 | var cy = clientRect.Top + innerMargin.Top;
43 |
44 | foreach (var windowCore in this.Children)
45 | {
46 | windowCore.SetPosition(cx, cy, childSize.Width - (innerMargin.Left + innerMargin.Right),
47 | childSize.Height - (innerMargin.Top + innerMargin.Bottom));
48 | cx += childSize.Width;
49 | }
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/WinApi.Windows.Controls/StaticBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics.CodeAnalysis;
3 | using WinApi.User32;
4 |
5 | namespace WinApi.Windows.Controls
6 | {
7 | public class StaticBox : EventedWindowCore, IConstructionParamsProvider
8 | {
9 | public static Lazy ClassFactory =
10 | new Lazy(() => WindowFactory.CreateForExistingClass("static"));
11 |
12 | protected StaticBox() {}
13 |
14 | IConstructionParams IConstructionParamsProvider.GetConstructionParams() => new VisibleChildConstructionParams();
15 |
16 | public static StaticBox Create(string text = null,
17 | WindowStyles? styles = null,
18 | WindowExStyles? exStyles = null, int? x = null, int? y = null,
19 | int? width = null, int? height = null, IntPtr? hParent = null, IntPtr? hMenu = null,
20 | WindowFactory factory = null, StaticStyles? controlStyles = null)
21 | {
22 | return (factory ?? ClassFactory.Value).CreateWindowEx(() => new StaticBox(), text, styles, exStyles, x, y,
23 | width,
24 | height, hParent, hMenu, (uint) (controlStyles ?? 0));
25 | }
26 |
27 | [SuppressMessage("ReSharper", "InconsistentNaming")]
28 | [Flags]
29 | public enum StaticStyles
30 | {
31 | SS_LEFT = 0x00000000,
32 | SS_CENTER = 0x00000001,
33 | SS_RIGHT = 0x00000002,
34 | SS_ICON = 0x00000003,
35 | SS_BLACKRECT = 0x00000004,
36 | SS_GRAYRECT = 0x00000005,
37 | SS_WHITERECT = 0x00000006,
38 | SS_BLACKFRAME = 0x00000007,
39 | SS_GRAYFRAME = 0x00000008,
40 | SS_WHITEFRAME = 0x00000009,
41 | SS_USERITEM = 0x0000000A,
42 | SS_SIMPLE = 0x0000000B,
43 | SS_LEFTNOWORDWRAP = 0x0000000C,
44 | SS_OWNERDRAW = 0x0000000D,
45 | SS_BITMAP = 0x0000000E,
46 | SS_ENHMETAFILE = 0x0000000F,
47 | SS_ETCHEDHORZ = 0x00000010,
48 | SS_ETCHEDVERT = 0x00000011,
49 | SS_ETCHEDFRAME = 0x00000012,
50 | SS_TYPEMASK = 0x0000001F,
51 | SS_REALSIZECONTROL = 0x00000040,
52 | SS_NOPREFIX = 0x00000080 /* Don't do "&" character translation */,
53 | SS_NOTIFY = 0x00000100,
54 | SS_CENTERIMAGE = 0x00000200,
55 | SS_RIGHTJUST = 0x00000400,
56 | SS_REALSIZEIMAGE = 0x00000800,
57 | SS_SUNKEN = 0x00001000,
58 | SS_EDITCONTROL = 0x00002000,
59 | SS_ENDELLIPSIS = 0x00004000,
60 | SS_PATHELLIPSIS = 0x00008000,
61 | SS_WORDELLIPSIS = 0x0000C000,
62 | SS_ELLIPSISMASK = 0x0000C000
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/WinApi.Windows.Controls/WinApi.Windows.Controls.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard1.4
4 | Prasanna V. Loganathar
5 | Prasanna V. Loganathar
6 | https://www.apache.org/licenses/LICENSE-2.0.txt
7 | https://github.com/prasannavl/WinApi
8 | https://github.com/prasannavl/WinApi
9 | https://raw.githubusercontent.com/prasannavl/WinApi/master/Misc/Logo.png
10 | Copyright © Prasanna V. Loganathar
11 | Win32 Native Controls
12 | 4.0.0
13 | true
14 | win32 native interop
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/WinApi.Windows.Controls/Window.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using WinApi.User32;
3 |
4 | namespace WinApi.Windows.Controls
5 | {
6 | public class Window : EventedWindowCore, IConstructionParamsProvider
7 | {
8 | public static Lazy ClassFactory = new Lazy(() => WindowFactory.Create());
9 | protected Window() {}
10 |
11 | IConstructionParams IConstructionParamsProvider.GetConstructionParams() => new FrameWindowConstructionParams();
12 |
13 | ///
14 | /// The window creator for standard windows.
15 | /// This is the default methods to create.
16 | ///
17 | public static Window Create(string text = null,
18 | WindowStyles? styles = null,
19 | WindowExStyles? exStyles = null, int? x = null, int? y = null,
20 | int? width = null, int? height = null, IntPtr? hParent = null, IntPtr? hMenu = null,
21 | WindowFactory factory = null)
22 | {
23 | return (factory ?? ClassFactory.Value).CreateWindowEx(() => new Window(), text, styles, exStyles, x, y,
24 | width,
25 | height, hParent, hMenu);
26 | }
27 |
28 | ///
29 | /// The type `Window` is conceptually slightly special, since it forms the base of
30 | /// all fully functional evented windows. So, this is a helper that makes
31 | /// it easy to create any other type of window easily, without the need
32 | /// to create a custom class to provide the protected constructor and
33 | /// IConstructionParamsProvider implementation.
34 | /// This is so that its easy to quickly write other types without having a class for
35 | /// it. But its application's responsibility to make sure that `new` of the Controls
36 | /// aren't called in an attempt to instantiate the window itself, as they'll only
37 | /// create the CLR object and not the actual windows.
38 | ///
39 | public static TWindow Create(string text = null,
40 | WindowStyles? styles = null,
41 | WindowExStyles? exStyles = null, int? x = null, int? y = null,
42 | int? width = null, int? height = null, IntPtr? hParent = null, IntPtr? hMenu = null,
43 | WindowFactory factory = null, uint? controlStyles = null)
44 | where TWindow : WindowCore, IConstructionParamsProvider, new()
45 | {
46 | return (factory ?? ClassFactory.Value).CreateWindowEx(() => new TWindow(), text, styles, exStyles, x, y,
47 | width, height, hParent,
48 | hMenu, controlStyles);
49 | }
50 |
51 | ///
52 | /// Another helper for `Window` class, since its conceptually slightly special.
53 | /// This allows any TWindow type to be created, whether or not they implement the
54 | /// IConstructionParamsProvider to help with construction. This is purely a helper
55 | /// to facilitate such a scenario.
56 | ///
57 | public static TWindow CreateWith(IConstructionParams constructionParams = null, string text = null,
58 | WindowStyles? styles = null,
59 | WindowExStyles? exStyles = null, int? x = null, int? y = null,
60 | int? width = null, int? height = null, IntPtr? hParent = null, IntPtr? hMenu = null,
61 | WindowFactory factory = null, uint? controlStyles = null)
62 | where TWindow : WindowCore, new()
63 | {
64 | return (factory ?? ClassFactory.Value).CreateWindow(() => new TWindow(),
65 | text, styles, exStyles, x, y,
66 | width, height, hParent,
67 | hMenu, controlStyles, constructionParams);
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/WinApi/Core/Types.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | // ReSharper disable InconsistentNaming
4 |
5 | namespace WinApi.Core
6 | {
7 | public enum HResult : uint
8 | {
9 | ///
10 | /// Operation successful
11 | ///
12 | S_OK = 0x00000000,
13 |
14 | ///
15 | /// Not implemented
16 | ///
17 | E_NOTIMPL = 0x80004001,
18 |
19 | ///
20 | /// No such interface supported
21 | ///
22 | E_NOINTERFACE = 0x80004002,
23 |
24 | ///
25 | /// Pointer that is not valid
26 | ///
27 | E_POINTER = 0x80004003,
28 |
29 | ///
30 | /// Operation aborted
31 | ///
32 | E_ABORT = 0x80004004,
33 |
34 | ///
35 | /// Unspecified failure
36 | ///
37 | E_FAIL = 0x80004005,
38 |
39 | ///
40 | /// Unexpected failure
41 | ///
42 | E_UNEXPECTED = 0x8000FFFF,
43 |
44 | ///
45 | /// General access denied error
46 | ///
47 | E_ACCESSDENIED = 0x80070005,
48 |
49 | ///
50 | /// Handle that is not valid
51 | ///
52 | E_HANDLE = 0x80070006,
53 |
54 | ///
55 | /// Failed to allocate necessary memory
56 | ///
57 | E_OUTOFMEMORY = 0x8007000E,
58 |
59 | ///
60 | /// One or more arguments are not valid
61 | ///
62 | E_INVALIDARG = 0x80070057
63 | }
64 | }
--------------------------------------------------------------------------------
/WinApi/DwmApi/Helpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using NetCoreEx.Geometry;
8 | using WinApi.Core;
9 |
10 | // ReSharper disable InconsistentNaming
11 |
12 | namespace WinApi.DwmApi
13 | {
14 | public static class DwmApiHelpers
15 | {
16 | public static unsafe HResult DwmSetWindowAttribute(IntPtr hwnd, DwmWindowAttributeType dwAttribute,
17 | [In] ref int attrValue)
18 | {
19 | fixed (int* ptr = &attrValue) return DwmApiMethods.DwmSetWindowAttribute(hwnd, dwAttribute, new IntPtr(ptr), sizeof(int));
20 | }
21 |
22 | public static unsafe HResult DwmGetWindowAttribute(IntPtr hwnd, DwmWindowAttributeType dwAttribute,
23 | out Rectangle rect)
24 | {
25 | fixed (Rectangle* ptr = &rect) return DwmApiMethods.DwmGetWindowAttribute(hwnd, dwAttribute, new IntPtr(ptr), (uint) sizeof(Rectangle));
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/WinApi/DwmApi/Methods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using NetCoreEx.Geometry;
4 | using WinApi.Core;
5 | using WinApi.UxTheme;
6 |
7 | namespace WinApi.DwmApi
8 | {
9 | public static class DwmApiMethods
10 | {
11 | public const string LibraryName = "dwmapi";
12 |
13 | [DllImport(LibraryName, ExactSpelling = true)]
14 | public static extern HResult DwmSetWindowAttribute(IntPtr hwnd, DwmWindowAttributeType dwAttribute,
15 | IntPtr pvAttribute,
16 | uint attrSize);
17 |
18 | [DllImport(LibraryName, ExactSpelling = true)]
19 | public static extern HResult DwmGetWindowAttribute(IntPtr hwnd, DwmWindowAttributeType dwAttribute,
20 | IntPtr pvAttribute,
21 | uint cbAttribute);
22 |
23 | [DllImport(LibraryName, ExactSpelling = true)]
24 | public static extern HResult DwmIsCompositionEnabled(out bool pfEnabled);
25 |
26 | [DllImport(LibraryName, ExactSpelling = true)]
27 | public static extern HResult DwmExtendFrameIntoClientArea(IntPtr hwnd, [In] ref Margins margins);
28 |
29 | [DllImport(LibraryName, ExactSpelling = true)]
30 | public static extern bool DwmDefWindowProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam,
31 | out IntPtr lResult);
32 |
33 | [DllImport(LibraryName, ExactSpelling = true)]
34 | public static extern HResult DwmGetColorizationColor(out int pcrColorization, out bool pfOpaqueBlend);
35 | }
36 | }
--------------------------------------------------------------------------------
/WinApi/Gdi32/CustomTypes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace WinApi.Gdi32
9 | {
10 | public class NativeBitmapInfoHandle : CriticalHandle
11 | {
12 | public unsafe NativeBitmapInfoHandle(ref BitmapInfo bitmapInfo) : base(new IntPtr(0))
13 | {
14 | var quads = bitmapInfo.Colors;
15 | var quadsLength = quads.Length;
16 | if (quadsLength == 0) { quadsLength = 1; }
17 | var success = false;
18 | var ptr = IntPtr.Zero;
19 | try
20 | {
21 | ptr =
22 | Marshal.AllocHGlobal(Marshal.SizeOf() + Marshal.SizeOf()*quadsLength);
23 | var headerPtr = (BitmapInfoHeader*) ptr.ToPointer();
24 | *headerPtr = bitmapInfo.Header;
25 | var quadPtr = (RgbQuad*) (headerPtr + 1);
26 | var i = 0;
27 | for (; i < quads.Length; i++) { *(quadPtr + i) = quads[i]; }
28 | if (i == 0) { *quadPtr = new RgbQuad(); }
29 | this.SetHandle(ptr);
30 | success = true;
31 | }
32 | finally
33 | {
34 | if (!success)
35 | {
36 | this.SetHandleAsInvalid();
37 | Marshal.FreeHGlobal(ptr);
38 | }
39 | }
40 | }
41 |
42 | public override bool IsInvalid => this.handle == IntPtr.Zero;
43 |
44 | protected override bool ReleaseHandle()
45 | {
46 | Marshal.FreeHGlobal(this.handle);
47 | return true;
48 | }
49 |
50 | public IntPtr GetDangerousHandle() => this.handle;
51 | }
52 | }
--------------------------------------------------------------------------------
/WinApi/Gdi32/Helpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Runtime.InteropServices.ComTypes;
4 | using System.Threading;
5 |
6 | // ReSharper disable InconsistentNaming
7 |
8 | namespace WinApi.Gdi32
9 | {
10 | public static class Gdi32Helpers
11 | {
12 | public static IntPtr GetStockObject(StockObject fnObject)
13 | {
14 | return Gdi32Methods.GetStockObject((int) fnObject);
15 | }
16 |
17 | public static IntPtr CreateDIBSection(IntPtr hdc, ref BitmapInfo bitmapInfo,
18 | DibBmiColorUsageFlag iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset)
19 | {
20 | using (var pbmi = BitmapInfo.NativeAlloc(ref bitmapInfo))
21 | {
22 | return Gdi32Methods.CreateDIBSection(hdc, pbmi.GetDangerousHandle(), iUsage, out ppvBits, hSection,
23 | dwOffset);
24 | }
25 | }
26 |
27 | public static unsafe IntPtr CreateDIBSection(IntPtr hdc, ref BitmapInfoHeader bitmapInfoHeader,
28 | DibBmiColorUsageFlag iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset)
29 | {
30 | fixed (BitmapInfoHeader* bitmapInfoHeaderPtr = &bitmapInfoHeader)
31 | {
32 | return Gdi32Methods.CreateDIBSection(hdc, new IntPtr(bitmapInfoHeaderPtr), iUsage, out ppvBits, hSection,
33 | dwOffset);
34 | }
35 | }
36 |
37 | public static IntPtr CreateDIBitmap(IntPtr hdc, ref BitmapInfoHeader
38 | lpbmih, uint fdwInit, byte[] lpbInit, ref BitmapInfo bitmapInfo,
39 | DibBmiColorUsageFlag fuUsage)
40 | {
41 | using (var pbmi = BitmapInfo.NativeAlloc(ref bitmapInfo))
42 | {
43 | return Gdi32Methods.CreateDIBitmap(hdc, ref lpbmih, fdwInit, lpbInit, pbmi.GetDangerousHandle(),
44 | fuUsage);
45 | }
46 | }
47 |
48 | public static int SetDIBitsToDevice(IntPtr hdc, int xDest, int yDest, uint
49 | dwWidth, uint dwHeight, int xSrc, int ySrc, uint uStartScan, uint cScanLines,
50 | byte[] lpvBits, ref BitmapInfo bitmapInfo, DibBmiColorUsageFlag fuColorUse)
51 | {
52 | using (var pbmi = BitmapInfo.NativeAlloc(ref bitmapInfo))
53 | {
54 | return Gdi32Methods.SetDIBitsToDevice(hdc, xDest, yDest,
55 | dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, pbmi.GetDangerousHandle(),
56 | fuColorUse);
57 | }
58 | }
59 |
60 | public static unsafe int SetDIBitsToDevice(IntPtr hdc, int xDest, int yDest, uint
61 | dwWidth, uint dwHeight, int xSrc, int ySrc, uint uStartScan, uint cScanLines,
62 | byte[] lpvBits, ref BitmapInfoHeader bitmapInfoHeader, DibBmiColorUsageFlag fuColorUse)
63 | {
64 | fixed (BitmapInfoHeader* bitmapInfoHeaderPtr = &bitmapInfoHeader)
65 | {
66 | return Gdi32Methods.SetDIBitsToDevice(hdc, xDest, yDest,
67 | dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, new IntPtr(bitmapInfoHeaderPtr),
68 | fuColorUse);
69 | }
70 | }
71 |
72 | public static unsafe int SetRgbBitsToDevice(IntPtr hdc, int width, int height, byte[] bits, int xSrc = 0,
73 | int ySrc = 0, int xDest = 0, int yDest = 0, bool isRgba = true, bool isImageTopDown = true)
74 | {
75 | fixed (byte* ptr = &bits[0]) {
76 | return SetRgbBitsToDevice(hdc, width, height, (IntPtr) ptr, xSrc, ySrc, xDest, yDest, isRgba);
77 | }
78 | }
79 |
80 | public static unsafe int SetRgbBitsToDevice(IntPtr hdc, int width, int height, IntPtr pixelBufferPtr,
81 | int xSrc = 0,
82 | int ySrc = 0, int xDest = 0, int yDest = 0, bool isRgba = true, bool isImageTopDown = true)
83 | {
84 | var bi = new BitmapInfoHeader
85 | {
86 | Size = (uint) Marshal.SizeOf(),
87 | Width = width,
88 | Height = isImageTopDown ? -height : height,
89 | CompressionMode = BitmapCompressionMode.BI_RGB,
90 | BitCount = isRgba ? (ushort) 32 : (ushort) 24,
91 | Planes = 1
92 | };
93 | return Gdi32Methods.SetDIBitsToDevice(hdc, xDest, yDest, (uint) width, (uint) height, xSrc, ySrc, 0,
94 | (uint) height, pixelBufferPtr, new IntPtr(&bi),
95 | DibBmiColorUsageFlag.DIB_RGB_COLORS);
96 | }
97 |
98 | public static IntPtr CreateSolidBrush(uint r, uint g, uint b)
99 | {
100 | return Gdi32Methods.CreateSolidBrush(Bgr32(r, g, b));
101 | }
102 |
103 | public static uint Bgr32(uint r, uint g, uint b)
104 | {
105 | return r | (g << 8) | (b << 16);
106 | }
107 | }
108 | }
--------------------------------------------------------------------------------
/WinApi/Kernel32/Helpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using NetCoreEx.BinaryExtensions;
8 |
9 | // ReSharper disable InconsistentNaming
10 |
11 | namespace WinApi.Kernel32
12 | {
13 | public static class Kernel32Helpers
14 | {
15 | public static Version GetVersion()
16 | {
17 | var dwVersion = Kernel32Methods.GetVersion();
18 | var build = dwVersion < 0x80000000 ? dwVersion.HighAsUInt() : 0; // (DWORD) (HIWORD(dwVersion))
19 | var v = new Version(
20 | (byte) dwVersion.Low(), // (DWORD)(LOBYTE(LOWORD(dwVersion)))
21 | (dwVersion.Low() >> 8) & 0xff,
22 | (int) build // (DWORD)(HIBYTE(LOWORD(dwVersion)))
23 | );
24 | return v;
25 | }
26 |
27 | public static bool IsWin8OrGreater(Version version = null)
28 | {
29 | if (version == null) version = GetVersion();
30 | if (version.Major > 5)
31 | {
32 | if ((version.Major > 6) || (version.Minor > 1)) return true;
33 | }
34 | return false;
35 | }
36 |
37 | public static bool IsWin8Point1OrGreater(Version version = null)
38 | {
39 | if (version == null) version = GetVersion();
40 | if (version.Major > 5)
41 | {
42 | if ((version.Major > 6) || (version.Minor > 2)) return true;
43 | }
44 | return false;
45 | }
46 |
47 | public static bool IsWin10OrGreater(Version version = null)
48 | {
49 | if (version == null) version = GetVersion();
50 | return version.Major > 6;
51 | }
52 |
53 | public static bool GetIsProcessorAMD64()
54 | {
55 | SystemInfo info;
56 | Kernel32Methods.GetNativeSystemInfo(out info);
57 | return info.ProcessorArchitecture == (uint) ProcessArchitecture.PROCESSOR_ARCHITECTURE_AMD64;
58 | }
59 |
60 | public static class ProcessUserModeExceptionFilter
61 | {
62 | const uint PROCESS_CALLBACK_FILTER_ENABLED = 0x1;
63 |
64 | [DllImport(Kernel32Methods.LibraryName)]
65 | public static extern bool SetProcessUserModeExceptionPolicy(uint dwFlags);
66 |
67 | [DllImport(Kernel32Methods.LibraryName)]
68 | public static extern bool GetProcessUserModeExceptionPolicy(out uint dwFlags);
69 |
70 | private static bool IsApiAvailable()
71 | {
72 | if (GetIsProcessorAMD64())
73 | {
74 | var ver = GetVersion();
75 | return (ver.Major == 6) && (ver.Minor == 1) && (ver.Build >= 7601);
76 | }
77 | return false;
78 | }
79 |
80 | public static bool Disable()
81 | {
82 | if (IsApiAvailable())
83 | {
84 | uint dwFlags;
85 | if (GetProcessUserModeExceptionPolicy(out dwFlags))
86 | {
87 | // Turn off the bit
88 | dwFlags &= ~PROCESS_CALLBACK_FILTER_ENABLED;
89 | return SetProcessUserModeExceptionPolicy(dwFlags);
90 | }
91 | }
92 | return false;
93 | }
94 |
95 | public static bool Enable()
96 | {
97 | if (IsApiAvailable())
98 | {
99 | uint dwFlags;
100 | if (GetProcessUserModeExceptionPolicy(out dwFlags))
101 | {
102 | // Turn off the bit
103 | dwFlags |= PROCESS_CALLBACK_FILTER_ENABLED;
104 | return SetProcessUserModeExceptionPolicy(dwFlags);
105 | }
106 | }
107 | return false;
108 | }
109 | }
110 | }
111 | }
--------------------------------------------------------------------------------
/WinApi/Kernel32/Types.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace WinApi.Kernel32
9 | {
10 | [StructLayout(LayoutKind.Sequential)]
11 | public struct SystemInfo
12 | {
13 | public ushort ProcessorArchitecture;
14 | ushort Reserved;
15 | public uint PageSize;
16 | public IntPtr MinimumApplicationAddress;
17 | public IntPtr MaximumApplicationAddress;
18 | public IntPtr ActiveProcessorMask;
19 | public uint NumberOfProcessors;
20 | public uint ProcessorType;
21 | public uint AllocationGranularity;
22 | public ushort ProcessorLevel;
23 | public ushort ProcessorRevision;
24 | public uint OemId => ((uint) this.ProcessorArchitecture << 8) | this.Reserved;
25 | }
26 |
27 | [StructLayout(LayoutKind.Sequential)]
28 | public struct SecurityAttributes
29 | {
30 | public uint Length;
31 | public IntPtr SecurityDescriptor;
32 | public uint IsHandleInheritedValue;
33 |
34 | public bool IsHandleInherited => this.IsHandleInheritedValue > 0;
35 | }
36 |
37 | [StructLayout(LayoutKind.Sequential)]
38 | public struct FileTime
39 | {
40 | public uint Low;
41 | public uint High;
42 |
43 | public ulong Value => ((ulong) this.High << 32) | this.Low;
44 | }
45 |
46 | [StructLayout(LayoutKind.Sequential)]
47 | public struct SystemTime
48 | {
49 | public ushort Year;
50 | public ushort Month;
51 | public ushort DayOfWeek;
52 | public ushort Day;
53 | public ushort Hour;
54 | public ushort Minute;
55 | public ushort Second;
56 | public ushort Milliseconds;
57 | }
58 |
59 | [StructLayout(LayoutKind.Sequential)]
60 | public struct FileAttributeData
61 | {
62 | public FileAttributes Attributes;
63 | public FileTime CreationTime;
64 | public FileTime LastAccessTime;
65 | public FileTime LastWriteTime;
66 |
67 | public uint FileSizeHigh;
68 | public uint FileSizeLow;
69 |
70 | public ulong FileSize => ((ulong) this.FileSizeHigh << 32) | this.FileSizeLow;
71 | }
72 | }
--------------------------------------------------------------------------------
/WinApi/KernelBase/Methods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace WinApi.KernelBase
9 | {
10 | public static class Kernel32Methods
11 | {
12 | public const string LibraryName = "kernelbase";
13 |
14 | [DllImport(LibraryName, ExactSpelling = true)]
15 | public static extern bool CompareObjectHandles(IntPtr hFirstObjectHandle, IntPtr hSecondObjectHandle);
16 | }
17 | }
--------------------------------------------------------------------------------
/WinApi/Properties.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace WinApi
9 | {
10 | internal static class Properties
11 | {
12 | #if !ANSI
13 | public const CharSet BuildCharSet = CharSet.Unicode;
14 | #else
15 | public const CharSet BuildCharSet = CharSet.Ansi;
16 | #endif
17 | }
18 | }
--------------------------------------------------------------------------------
/WinApi/ShCore/Methods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using WinApi.Core;
4 |
5 | namespace WinApi.ShCore
6 | {
7 | public static class ShCoreMethods
8 | {
9 | public const string LibraryName = "shcore";
10 |
11 | [DllImport(LibraryName, ExactSpelling = true)]
12 | public static extern HResult GetDpiForMonitor(IntPtr hmonitor, MonitorDpiType dpiType, out uint dpiX,
13 | out uint dpiY);
14 | }
15 | }
--------------------------------------------------------------------------------
/WinApi/ShCore/Types.cs:
--------------------------------------------------------------------------------
1 | // ReSharper disable InconsistentNaming
2 |
3 | namespace WinApi.ShCore
4 | {
5 | public enum MonitorDpiType
6 | {
7 | ///
8 | /// The effective DPI. This value should be used when determining the correct scale factor for scaling UI elements.
9 | /// This incorporates the scale factor set by the user for this specific display.
10 | ///
11 | MDT_EFFECTIVE_DPI = 0,
12 |
13 | ///
14 | /// The angular DPI. This DPI ensures rendering at a compliant angular resolution on the screen. This does not include
15 | /// the scale factor set by the user for this specific display.
16 | ///
17 | MDT_ANGULAR_DPI = 1,
18 |
19 | ///
20 | /// The raw DPI. This value is the linear DPI of the screen as measured on the screen itself. Use this value when you
21 | /// want to read the pixel density and not the recommended scaling setting. This does not include the scale factor set
22 | /// by the user for this specific display and is not guaranteed to be a supported DPI value.
23 | ///
24 | MDT_RAW_DPI = 2,
25 | MDT_DEFAULT = MDT_EFFECTIVE_DPI
26 | }
27 | }
--------------------------------------------------------------------------------
/WinApi/User32/Experimental/Helpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace WinApi.User32.Experimental
5 | {
6 | public static class User32ExperimentalHelpers
7 | {
8 | public static void EnableBlurBehind(IntPtr hwnd)
9 | {
10 | var accent = new AccentPolicy();
11 | var accentStructSize = Marshal.SizeOf();
12 | accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
13 | var accentPtr = Marshal.AllocHGlobal(accentStructSize);
14 | try
15 | {
16 | Marshal.StructureToPtr(accent, accentPtr, false);
17 | var data = new WindowCompositionAttributeData
18 | {
19 | Attribute = WindowCompositionAttributeType.WCA_ACCENT_POLICY,
20 | DataSize = accentStructSize,
21 | Data = accentPtr
22 | };
23 | User32ExperimentalMethods.SetWindowCompositionAttribute(hwnd, ref data);
24 | }
25 | finally { Marshal.FreeHGlobal(accentPtr); }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/WinApi/User32/Experimental/Methods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace WinApi.User32.Experimental
5 | {
6 | public static class User32ExperimentalMethods
7 | {
8 | [DllImport(User32Methods.LibraryName, CharSet = Properties.BuildCharSet)]
9 | internal static extern bool SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
10 | }
11 | }
--------------------------------------------------------------------------------
/WinApi/User32/Experimental/Types.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | // ReSharper disable InconsistentNaming
5 |
6 | namespace WinApi.User32.Experimental
7 | {
8 |
9 | #region Constants
10 |
11 | public enum WindowCompositionAttributeType
12 | {
13 | WCA_ACCENT_POLICY = 19
14 | }
15 |
16 | public enum AccentState
17 | {
18 | ACCENT_DISABLED = 0,
19 | ACCENT_ENABLE_GRADIENT = 1,
20 | ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
21 | ACCENT_ENABLE_BLURBEHIND = 3,
22 | ACCENT_INVALID_STATE = 4
23 | }
24 |
25 | [Flags]
26 | public enum AccentFlags
27 | {
28 | AF_LEFTBORDER = 0x20,
29 | AF_TOPBORDER = 0x40,
30 | AF_RIGHTBORDER = 0x80,
31 | AF_BOTTOMBORDER = 0x100,
32 | AF_ALLBORDERS = AF_LEFTBORDER | AF_TOPBORDER | AF_RIGHTBORDER | AF_BOTTOMBORDER
33 | }
34 |
35 | #endregion
36 |
37 | [StructLayout(LayoutKind.Sequential)]
38 | public struct WindowCompositionAttributeData
39 | {
40 | public WindowCompositionAttributeType Attribute;
41 | public IntPtr Data;
42 | public int DataSize;
43 | }
44 |
45 | [StructLayout(LayoutKind.Sequential)]
46 | public struct AccentPolicy
47 | {
48 | public AccentState AccentState;
49 | public AccentFlags AccentFlags;
50 | public int GradientColor;
51 | public int AnimationId;
52 | }
53 | }
--------------------------------------------------------------------------------
/WinApi/UxTheme/Helpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using WinApi.Core;
8 |
9 | namespace WinApi.UxTheme
10 | {
11 | public static class UxThemeHelpers
12 | {
13 | public static unsafe HResult SetWindowThemeNonClientAttributes(IntPtr hwnd,
14 | WindowThemeNcAttributeFlags mask,
15 | WindowThemeNcAttributeFlags attributes)
16 | {
17 | var opts = new WindowThemeAttributeOptions
18 | {
19 | Mask = (uint) mask,
20 | Flags = (uint) attributes
21 | };
22 | return UxThemeMethods.SetWindowThemeAttribute(hwnd, WindowThemeAttributeType.WTA_NONCLIENT,
23 | new IntPtr(&opts), (uint) Marshal.SizeOf());
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/WinApi/WinApi.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard1.4
5 | Prasanna V. Loganathar
6 | Prasanna V. Loganathar
7 | https://www.apache.org/licenses/LICENSE-2.0.txt
8 | https://github.com/prasannavl/WinApi
9 | https://github.com/prasannavl/WinApi
10 | https://raw.githubusercontent.com/prasannavl/WinApi/master/Misc/Logo.png
11 | Copyright © Prasanna V. Loganathar
12 | A simple, direct, ultra-thin CLR library for high-performance Win32 Native Interop
13 | 4.0.0
14 | true
15 | win32 native interop
16 |
17 |
18 |
19 | true
20 | TRACE;RELEASE;NETSTANDARD1_4
21 |
22 |
23 |
24 | true
25 | TRACE;DEBUG;NETSTANDARD1_4
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/WinApi/Windows/ConstructionParams.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using WinApi.User32;
3 |
4 | namespace WinApi.Windows
5 | {
6 | public interface IConstructionParamsProvider
7 | {
8 | IConstructionParams GetConstructionParams();
9 | }
10 |
11 | public interface IConstructionParams
12 | {
13 | WindowStyles Styles { get; }
14 | WindowExStyles ExStyles { get; }
15 | uint ControlStyles { get; }
16 | int Width { get; }
17 | int Height { get; }
18 | int X { get; }
19 | int Y { get; }
20 | IntPtr ParentHandle { get; }
21 | IntPtr MenuHandle { get; }
22 | }
23 |
24 | public class ConstructionParams : IConstructionParams
25 | {
26 | public virtual int X => (int) CreateWindowFlags.CW_USEDEFAULT;
27 | public virtual int Y => (int) CreateWindowFlags.CW_USEDEFAULT;
28 | public virtual int Width => (int) CreateWindowFlags.CW_USEDEFAULT;
29 | public virtual int Height => (int) CreateWindowFlags.CW_USEDEFAULT;
30 | public virtual IntPtr ParentHandle => IntPtr.Zero;
31 | public virtual IntPtr MenuHandle => IntPtr.Zero;
32 | public virtual WindowStyles Styles => 0;
33 | public virtual uint ControlStyles => 0;
34 | public virtual WindowExStyles ExStyles => 0;
35 | }
36 |
37 | public class FrameWindowConstructionParams : ConstructionParams
38 | {
39 | public override WindowStyles Styles
40 | => WindowStyles.WS_OVERLAPPEDWINDOW | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_CLIPSIBLINGS;
41 |
42 | public override WindowExStyles ExStyles
43 | => WindowExStyles.WS_EX_APPWINDOW | WindowExStyles.WS_EX_WINDOWEDGE;
44 | }
45 |
46 | public class VisibleChildConstructionParams : ConstructionParams
47 | {
48 | public override WindowStyles Styles
49 | => WindowStyles.WS_VISIBLE | WindowStyles.WS_CHILD;
50 |
51 | public override WindowExStyles ExStyles
52 | => WindowExStyles.WS_EX_STATICEDGE;
53 | }
54 | }
--------------------------------------------------------------------------------
/WinApi/Windows/EventLoop.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using WinApi.User32;
3 | using WinApi.Windows.Helpers;
4 |
5 | namespace WinApi.Windows
6 | {
7 | public interface IEventLoop
8 | {
9 | int Run(WindowCore mainWindow = null);
10 | }
11 |
12 | public abstract class EventLoopCore : IEventLoop
13 | {
14 | protected object State;
15 |
16 | protected EventLoopCore(object state)
17 | {
18 | this.State = state;
19 | }
20 |
21 | public int Run(WindowCore mainWindow = null)
22 | {
23 | Action destroyHandler = () => { MessageHelpers.PostQuitMessage(); };
24 | if (mainWindow != null) mainWindow.Destroyed += destroyHandler;
25 | var res = this.RunCore();
26 | // Technically, this can be avoided by setting the handler to auto disconnect.
27 | // However, this helps keep the mainWindow alive, and use this instead of
28 | // GC.KeepAlive pattern.
29 | if (mainWindow != null) mainWindow.Destroyed -= destroyHandler;
30 | return res;
31 | }
32 |
33 | public abstract int RunCore();
34 | }
35 |
36 |
37 | public class EventLoop : EventLoopCore
38 | {
39 | public EventLoop(object state = null) : base(state) {}
40 |
41 | public override int RunCore()
42 | {
43 | Message msg;
44 | int res;
45 | while ((res = User32Methods.GetMessage(out msg, IntPtr.Zero, 0, 0)) > 0)
46 | {
47 | User32Methods.TranslateMessage(ref msg);
48 | User32Methods.DispatchMessage(ref msg);
49 | }
50 | return res;
51 | }
52 | }
53 |
54 | public class RealtimeEventLoop : EventLoopCore
55 | {
56 | public RealtimeEventLoop(object state = null) : base(state) {}
57 |
58 | public override int RunCore()
59 | {
60 | Message msg;
61 | var quitMsgId = (uint) WM.QUIT;
62 | do
63 | {
64 | if (User32Helpers.PeekMessage(out msg, IntPtr.Zero, 0, 0, PeekMessageFlags.PM_REMOVE))
65 | {
66 | User32Methods.TranslateMessage(ref msg);
67 | User32Methods.DispatchMessage(ref msg);
68 | }
69 | } while (msg.Value != quitMsgId);
70 | return 0;
71 | }
72 | }
73 |
74 | public abstract class InterceptableEventLoopCore : EventLoopCore
75 | {
76 | protected InterceptableEventLoopCore(object state) : base(state) {}
77 | protected virtual bool Preprocess(ref Message msg) => true;
78 | protected virtual bool PostTranslate(ref Message msg) => true;
79 | protected virtual void PostProcess(ref Message msg) {}
80 | }
81 |
82 | public abstract class InterceptableEventLoopBase : InterceptableEventLoopCore
83 | {
84 | protected InterceptableEventLoopBase(object state) : base(state) {}
85 |
86 | public override int RunCore()
87 | {
88 | Message msg;
89 | int res;
90 | while ((res = User32Methods.GetMessage(out msg, IntPtr.Zero, 0, 0)) > 0)
91 | {
92 | if (this.Preprocess(ref msg))
93 | {
94 | User32Methods.TranslateMessage(ref msg);
95 | if (this.PostTranslate(ref msg)) User32Methods.DispatchMessage(ref msg);
96 | this.PostProcess(ref msg);
97 | }
98 | }
99 | return res;
100 | }
101 | }
102 |
103 | public abstract class InterceptableRealtimeEventLoopBase : InterceptableEventLoopCore
104 | {
105 | protected InterceptableRealtimeEventLoopBase(object state) : base(state) {}
106 |
107 | public override int RunCore()
108 | {
109 | Message msg;
110 | var quitMsg = (uint) WM.QUIT;
111 | do
112 | {
113 | if (User32Helpers.PeekMessage(out msg, IntPtr.Zero, 0, 0, PeekMessageFlags.PM_REMOVE))
114 | if (this.Preprocess(ref msg))
115 | {
116 | User32Methods.TranslateMessage(ref msg);
117 | if (this.PostTranslate(ref msg)) User32Methods.DispatchMessage(ref msg);
118 | this.PostProcess(ref msg);
119 | }
120 | } while (msg.Value != quitMsg);
121 | return 0;
122 | }
123 | }
124 | }
--------------------------------------------------------------------------------
/WinApi/Windows/Helpers/MessageBoxHelpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using WinApi.User32;
3 |
4 | namespace WinApi.Windows.Helpers
5 | {
6 | public class MessageBoxHelpers
7 | {
8 | public static MessageBoxResult ShowError(object errorObject, string infoMessage = null, string title = null,
9 | IntPtr parentHwnd = default(IntPtr),
10 | MessageBoxFlags flags =
11 | MessageBoxFlags.MB_OK | MessageBoxFlags.MB_ICONERROR | MessageBoxFlags.MB_SYSTEMMODAL)
12 | {
13 | const string defaultTitle = "Error";
14 | const string defaultInfoMessage = "Oh snap! Something went wrong.";
15 |
16 | title = title ?? defaultTitle;
17 | var ex = errorObject as Exception;
18 | if (ex == null)
19 | {
20 | return User32Helpers.MessageBox(parentHwnd,
21 | infoMessage ?? defaultInfoMessage +
22 | $"\n\n{errorObject?.ToString() ?? "No additional information available."}",
23 | title, flags);
24 | }
25 | var exMessage = ex.Message ?? "No information message available.";
26 | string msg;
27 | if (infoMessage != null) { msg = infoMessage + "\n\n" + exMessage; }
28 | else
29 | { msg = defaultInfoMessage + "\n\n" + exMessage; }
30 | return User32Helpers.MessageBox(parentHwnd,
31 | $"{msg}" +
32 | $"\n\nStackTrace:\n\n{ex.StackTrace}",
33 | title, flags);
34 | }
35 |
36 | public static MessageBoxResult Show(string message, string title = null,
37 | IntPtr parentHwnd = default(IntPtr),
38 | MessageBoxFlags flags =
39 | MessageBoxFlags.MB_OK | MessageBoxFlags.MB_ICONINFORMATION)
40 | {
41 | const string defaultTitle = "Information";
42 | title = title ?? defaultTitle;
43 | return User32Helpers.MessageBox(parentHwnd,
44 | message, title, flags);
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/WinApi/Windows/Helpers/MessageHelpers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using WinApi.DwmApi;
3 | using WinApi.User32;
4 |
5 | namespace WinApi.Windows.Helpers
6 | {
7 | public static class MessageHelpers
8 | {
9 | public static bool RunDwmDefWindowProc(ref WindowMessage msg)
10 | {
11 | return DwmApiMethods.DwmDefWindowProc(msg.Hwnd, (uint) msg.Id, msg.WParam, msg.LParam, out msg.Result);
12 | }
13 |
14 | public static void PostQuitMessage(int exitCode = 0)
15 | {
16 | User32Methods.PostQuitMessage(exitCode);
17 | }
18 |
19 | public static void RunWindowProc(WindowCore coreWindow, ref WindowMessage msg)
20 | {
21 | msg.SetResult(coreWindow.WindowProc(msg.Hwnd, (uint) msg.Id, msg.WParam, msg.LParam));
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------