C# プログラムでいくつかの問題が発生しました。特定のキーが押されたときに開始されるストップウォッチ(特定の値からのカウントダウン)を作成したい。キーを処理するには、低レベルのキーボード フックを使用します。しかし、このクラスには静的メソッドがあるため、静的ではない別のクラスからメソッドを呼び出したい場合は、新しいインスタンスを作成する必要があります。カウントダウンで、ティック(秒)ごとText
に要素のプロパティを変更したい。問題は、静的メソッドでクラスの新しいインスタンスを作成する必要があるときに、(クラス内の) すべてのティックTextBox
のプロパティを変更する方法です。そのため、 は以前の に応答しなくなります。私のコードは完全に正常に動作し、キーが認識され、タイマーがカウントダウンし、秒の値が個別に表示されますTextBox
Countdown
Countdown
TextBox
TextBox
MessageBox
'es (デバッグ用) ですが、フォーム内のテキストは変更されません。
私が上に書いたことを理解するのに役立つなら、私のコードをあげることができます。コメントでそう言ってください。
事前に助けてくれてありがとう。
コード:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace stopwatch2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
InterceptKeys.InterceptInit();
}
private void Form1_Closing(object sender, CancelEventArgs e)
{
InterceptKeys.Unhook();
}
public void changeText(string text)
{
MessageBox.Show(text); //for debug
textBox1.Text = text;
}
class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void InterceptInit()
{
_hookID = SetHook(_proc);
}
public static void Unhook()
{
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelKeyboardProc(
int nCode, IntPtr wParam, IntPtr lParam);
public static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Countdown timer = new Countdown(); //creating new instance
if ((Keys)vkCode == Keys.Home)
{
timer.StartTimer();
}
if ((Keys)vkCode == Keys.End)
{
timer.StopTimer();
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
public partial class Countdown : Form1
{
public System.Windows.Forms.Timer timer1;
public int counter = 60;
public void StartTimer()
{
timer1 = new System.Windows.Forms.Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000; // 1 second
timer1.Start();
changeText(counter.ToString());
}
public void timer1_Tick(object sender, EventArgs e)
{
counter--;
if (counter == 0)
counter = 60;
changeText(counter.ToString());
}
public void StopTimer()
{
timer1.Stop();
}
}
}
}