-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Port Checker Petzold sample from WInterop
- Loading branch information
1 parent
26657f4
commit 4ff4549
Showing
12 changed files
with
1,604 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<OutputType>WinExe</OutputType> | ||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="..\..\..\..\thirtytwo\thirtytwo.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Drawing; | ||
using Windows; | ||
using Windows.Win32; | ||
using Windows.Win32.Foundation; | ||
|
||
namespace Checker; | ||
|
||
public class Checker1 : MainWindow | ||
{ | ||
private const int DIVISIONS = 5; | ||
private readonly bool[,] _fState = new bool[DIVISIONS, DIVISIONS]; | ||
private int _cxBlock, _cyBlock; | ||
|
||
public Checker1(string title) : base(title) | ||
{ | ||
} | ||
|
||
protected override LRESULT WindowProcedure(HWND window, MessageType message, WPARAM wParam, LPARAM lParam) | ||
{ | ||
switch (message) | ||
{ | ||
case MessageType.Size: | ||
_cxBlock = lParam.LOWORD / DIVISIONS; | ||
_cyBlock = lParam.HIWORD / DIVISIONS; | ||
return (LRESULT)0; | ||
case MessageType.LeftButtonDown: | ||
int x = lParam.LOWORD / _cxBlock; | ||
int y = lParam.HIWORD / _cyBlock; | ||
if (x < DIVISIONS && y < DIVISIONS) | ||
{ | ||
_fState[x, y] ^= true; | ||
Rectangle rect = Rectangle.FromLTRB | ||
( | ||
x * _cxBlock, | ||
y * _cyBlock, | ||
(x + 1) * _cxBlock, | ||
(y + 1) * _cyBlock | ||
); | ||
window.InvalidateRectangle(rect, false); | ||
} | ||
else | ||
{ | ||
Interop.MessageBeep(0); | ||
} | ||
|
||
return (LRESULT)0; | ||
case MessageType.Paint: | ||
using (DeviceContext dc = window.BeginPaint()) | ||
{ | ||
for (x = 0; x < DIVISIONS; x++) | ||
for (y = 0; y < DIVISIONS; y++) | ||
{ | ||
dc.Rectangle(new Rectangle( | ||
x * _cxBlock, y * _cyBlock, (x + 1) * _cxBlock, (y + 1) * _cyBlock)); | ||
|
||
if (_fState[x, y]) | ||
{ | ||
dc.MoveTo(new Point(x * _cxBlock, y * _cyBlock)); | ||
dc.LineTo(new Point((x + 1) * _cxBlock, (y + 1) * _cyBlock)); | ||
dc.MoveTo(new Point(x * _cxBlock, (y + 1) * _cyBlock)); | ||
dc.LineTo(new Point((x + 1) * _cxBlock, y * _cyBlock)); | ||
} | ||
} | ||
} | ||
|
||
return (LRESULT)0; | ||
} | ||
|
||
return base.WindowProcedure(window, message, wParam, lParam); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Drawing; | ||
using Windows; | ||
using Windows.Win32; | ||
using Windows.Win32.Foundation; | ||
using Windows.Win32.System.SystemServices; | ||
using Windows.Win32.UI.Input.KeyboardAndMouse; | ||
|
||
namespace Checker; | ||
|
||
internal class Checker2 : MainWindow | ||
{ | ||
private const int DIVISIONS = 5; | ||
private readonly bool[,] _state = new bool[DIVISIONS, DIVISIONS]; | ||
private int _cxBlock, _cyBlock; | ||
|
||
public Checker2(string title) : base(title) | ||
{ | ||
} | ||
|
||
protected override LRESULT WindowProcedure(HWND window, MessageType message, WPARAM wParam, LPARAM lParam) | ||
{ | ||
switch (message) | ||
{ | ||
case MessageType.Size: | ||
_cxBlock = lParam.LOWORD / DIVISIONS; | ||
_cyBlock = lParam.HIWORD / DIVISIONS; | ||
return (LRESULT)0; | ||
case MessageType.SetFocus: | ||
_ = Interop.ShowCursor(true); | ||
return (LRESULT)0; | ||
case MessageType.KillFocus: | ||
_ = Interop.ShowCursor(false); | ||
return (LRESULT)0; | ||
case MessageType.KeyDown: | ||
Interop.GetCursorPos(out Point point); | ||
window.ScreenToClient(ref point); | ||
int x = Math.Max(0, Math.Min(DIVISIONS - 1, point.X / _cxBlock)); | ||
int y = Math.Max(0, Math.Min(DIVISIONS - 1, point.Y / _cyBlock)); | ||
switch ((VIRTUAL_KEY)(ushort)(uint)wParam) | ||
{ | ||
case VIRTUAL_KEY.VK_UP: | ||
y--; | ||
break; | ||
case VIRTUAL_KEY.VK_DOWN: | ||
y++; | ||
break; | ||
case VIRTUAL_KEY.VK_LEFT: | ||
x--; | ||
break; | ||
case VIRTUAL_KEY.VK_RIGHT: | ||
x++; | ||
break; | ||
case VIRTUAL_KEY.VK_HOME: | ||
x = y = 0; | ||
break; | ||
case VIRTUAL_KEY.VK_END: | ||
x = y = DIVISIONS - 1; | ||
break; | ||
case VIRTUAL_KEY.VK_RETURN: | ||
case VIRTUAL_KEY.VK_SPACE: | ||
window.SendMessage( | ||
MessageType.LeftButtonDown, | ||
(WPARAM)(uint)MODIFIERKEYS_FLAGS.MK_LBUTTON, | ||
LPARAM.MAKELPARAM(y * _cyBlock, x * _cxBlock)); | ||
break; | ||
} | ||
x = (x + DIVISIONS) % DIVISIONS; | ||
y = (y + DIVISIONS) % DIVISIONS; | ||
|
||
point = new Point(x * _cxBlock + _cxBlock / 2, y * _cyBlock + _cyBlock / 2); | ||
window.ClientToScreen(ref point); | ||
Interop.SetCursorPos(point.X, point.Y); | ||
return (LRESULT)0; | ||
case MessageType.LeftButtonDown: | ||
x = lParam.LOWORD / _cxBlock; | ||
y = lParam.HIWORD / _cyBlock; | ||
if (x < DIVISIONS && y < DIVISIONS) | ||
{ | ||
_state[x, y] ^= true; | ||
Rectangle rect = Rectangle.FromLTRB | ||
( | ||
x * _cxBlock, | ||
y * _cyBlock, | ||
(x + 1) * _cxBlock, | ||
(y + 1) * _cyBlock | ||
); | ||
window.InvalidateRectangle(rect, false); | ||
} | ||
else | ||
{ | ||
Interop.MessageBeep(0); | ||
} | ||
|
||
return (LRESULT)0; | ||
case MessageType.Paint: | ||
using (DeviceContext dc = window.BeginPaint()) | ||
{ | ||
for (x = 0; x < DIVISIONS; x++) | ||
for (y = 0; y < DIVISIONS; y++) | ||
{ | ||
dc.Rectangle(new Rectangle(x * _cxBlock, y * _cyBlock, (x + 1) * _cxBlock, (y + 1) * _cyBlock)); | ||
if (_state[x, y]) | ||
{ | ||
dc.MoveTo(new Point(x * _cxBlock, y * _cyBlock)); | ||
dc.LineTo(new Point((x + 1) * _cxBlock, (y + 1) * _cyBlock)); | ||
dc.MoveTo(new Point(x * _cxBlock, (y + 1) * _cyBlock)); | ||
dc.LineTo(new Point((x + 1) * _cxBlock, y * _cyBlock)); | ||
} | ||
} | ||
} | ||
|
||
return (LRESULT)0; | ||
} | ||
|
||
return base.WindowProcedure(window, message, wParam, lParam); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright (c) Jeremy W. Kuhne. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Drawing; | ||
using Windows; | ||
using Windows.Win32; | ||
using Windows.Win32.Foundation; | ||
using Windows.Win32.UI.WindowsAndMessaging; | ||
|
||
namespace Checker; | ||
|
||
internal class Checker3 : MainWindow | ||
{ | ||
private const int DIVISIONS = 5; | ||
private readonly HWND[,] _hwndChild = new HWND[DIVISIONS, DIVISIONS]; | ||
private int _cxBlock, _cyBlock; | ||
private readonly Checker3Child _childClass = (Checker3Child)(new Checker3Child().Register()); | ||
|
||
public Checker3(string title) : base(title) | ||
{ | ||
} | ||
|
||
protected override LRESULT WindowProcedure(HWND window, MessageType message, WPARAM wParam, LPARAM lParam) | ||
{ | ||
switch (message) | ||
{ | ||
case MessageType.Create: | ||
for (int x = 0; x < DIVISIONS; x++) | ||
for (int y = 0; y < DIVISIONS; y++) | ||
_hwndChild[x, y] = _childClass.CreateWindow( | ||
style: WindowStyles.ChildWindow | WindowStyles.Visible, | ||
parentWindow: window); | ||
return (LRESULT)0; | ||
case MessageType.Size: | ||
_cxBlock = lParam.LOWORD / DIVISIONS; | ||
_cyBlock = lParam.HIWORD / DIVISIONS; | ||
for (int x = 0; x < DIVISIONS; x++) | ||
for (int y = 0; y < DIVISIONS; y++) | ||
_hwndChild[x, y].MoveWindow( | ||
new Rectangle(x * _cxBlock, y * _cyBlock, _cxBlock, _cyBlock), | ||
repaint: true); | ||
return (LRESULT)0; | ||
case MessageType.LeftButtonDown: | ||
Interop.MessageBeep(MESSAGEBOX_STYLE.MB_OK); | ||
return (LRESULT)0; | ||
} | ||
|
||
return base.WindowProcedure(window, message, wParam, lParam); | ||
} | ||
} | ||
|
||
internal unsafe class Checker3Child : WindowClass | ||
{ | ||
public Checker3Child() : base(windowExtraBytes: sizeof(void*)) | ||
{ | ||
} | ||
|
||
protected override LRESULT WindowProcedure(HWND window, MessageType message, WPARAM wParam, LPARAM lParam) | ||
{ | ||
switch (message) | ||
{ | ||
case MessageType.Create: | ||
window.SetWindowLong(0, 0); // on/off flag | ||
return (LRESULT)0; | ||
case MessageType.LeftButtonDown: | ||
window.SetWindowLong(0, 1 ^ (int)window.GetWindowLong(0)); | ||
window.Invalidate(false); | ||
return (LRESULT)0; | ||
case MessageType.Paint: | ||
using (DeviceContext dc = window.BeginPaint()) | ||
{ | ||
Rectangle rect = window.GetClientRectangle(); | ||
dc.Rectangle(rect); | ||
|
||
if (window.GetWindowLong(0) != 0) | ||
{ | ||
dc.MoveTo(default); | ||
dc.LineTo(new Point(rect.Right, rect.Bottom)); | ||
dc.MoveTo(new Point(0, rect.Bottom)); | ||
dc.LineTo(new Point(rect.Right, 0)); | ||
} | ||
} | ||
|
||
return (LRESULT)0; | ||
} | ||
|
||
return base.WindowProcedure(window, message, wParam, lParam); | ||
} | ||
} |
Oops, something went wrong.