在下面的代码中,按住“x”会导致绘制的立方体旋转。按“alt”会导致“x”的 KeyUp 事件跳过,并且立方体继续旋转,直到再次按“x”。这让我认为 Alt 键导致表单失去焦点。
我尝试使用预览按键事件来捕获 Alt 键按下事件,但这并没有解决问题。我不想检查 IsKeyDown。
我不一定要禁用 Alt+F4 等功能。我故意不在我的应用程序中将 Alt 键用于任何目的。但用户可能会按 Alt 键并遇到此问题。
public partial class Form1 : Form
{
private float rotationAngle = 0;
private bool rotationKeyDown = false;
public Form1()
{
InitializeComponent();
timer1.Interval = 32;
timer1.Start();
}
public struct Point3D
{
public float X, Y, Z;
public Point3D(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
}
public class Matrix4x4
{
private float[,] matrix = new float[4, 4];
public static Matrix4x4 CreateRotationY(float angle)
{
Matrix4x4 result = new Matrix4x4();
result.matrix[0, 0] = result.matrix[2, 2] = (float)Math.Cos(angle);
result.matrix[0, 2] = (float)Math.Sin(angle);
result.matrix[2, 0] = -(float)Math.Sin(angle);
result.matrix[1, 1] = result.matrix[3, 3] = 1;
return result;
}
public Point3D MultiplyPoint(Point3D p)
{
return new Point3D(
p.X * matrix[0, 0] + p.Y * matrix[0, 1] + p.Z * matrix[0, 2],
p.X * matrix[1, 0] + p.Y * matrix[1, 1] + p.Z * matrix[1, 2],
p.X * matrix[2, 0] + p.Y * matrix[2, 1] + p.Z * matrix[2, 2]
);
}
}
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.X && Control.ModifierKeys == Keys.Alt)
{
e.IsInputKey = true;
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.X)
{
rotationKeyDown = true;
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.X)
{
rotationKeyDown = false;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (rotationKeyDown == true)
{
rotationAngle += 10;
this.Invalidate();
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
DrawCube(e.Graphics, this.ClientSize.Width / 2, this.ClientSize.Height / 2);
}
private void DrawCube(Graphics g, int cx, int cy)
{
int side = 100;
Point3D[] vertices = {
new Point3D(-1, -1, -1),
new Point3D(1, -1, -1),
new Point3D(1, 1, -1),
new Point3D(-1, 1, -1),
new Point3D(-1, -1, 1),
new Point3D(1, -1, 1),
new Point3D(1, 1, 1),
new Point3D(-1, 1, 1)
};
Matrix4x4 rotationMatrix = Matrix4x4.CreateRotationY(rotationAngle * (float)Math.PI / 180);
Point[] projectedPoints = new Point[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
Point3D rotated = rotationMatrix.MultiplyPoint(vertices[i]);
projectedPoints[i] = IsoProject(rotated, cx, cy, side);
}
int[] edges = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
for (int i = 0; i < edges.Length; i += 2)
{
g.DrawLine(Pens.Black, projectedPoints[edges[i]], projectedPoints[edges[i + 1]]);
}
}
private Point IsoProject(Point3D p, int cx, int cy, int scale)
{
float x = p.X - p.Y;
float y = p.X + p.Y - 2 * p.Z;
return new Point((int)(cx + x * scale / 2), (int)(cy + y * scale / 2));
}
}
尝试使用条件来检查在 Form1_KeyUp 事件中是否按下了 alt 键:
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyValue == 18)
return;
if (e.KeyCode == Keys.X)
{
rotationKeyDown = false;
}
}