using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
static class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
internal struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MSG
{
public IntPtr hwnd;
public int message;
public IntPtr wParam;
public IntPtr lParam;
public int time;
public POINT pt;
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool PeekMessage(out MSG msg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);
}
/*
[DllImport("DLL名", パラメータ)]
DllImportが指定されたメソッドは、指定されたDLLに存在すると解釈される
・パラメータ
EntryPoint:DLL内の関数の名前
CharSet:文字列のマーシャリング方法
SetLastError:Win32エラー情報を維持するか
ExactSpelling:EntryPointの関数名を厳密に一致させるか
PreserveSig:T定義通りのメソッドのシグネチャを維持するか
CallingConvention:EntryPointで使用するモードを指定する
・返値(受け取るとき):
[return: MarshalAs(UnmanagedType.Bool)]
static extern int xxx([MarshalAs(UnmanagedType.LPWStr), Out] StringBuilder lpPathName);
var buff = new StringBuilder(255);
NativeMethods.xxx(buff);
・引数(渡すとき):
static extern bool xxx([MarshalAs(UnmanagedType.LPWStr), In] string xxx);
MarshalAs()
マーシャリングとは、マネージドコードとネイティブコードの間でやり取りするときに型を変換するプロセス。
*/
public class TestContext : ApplicationContext
{
public TestContext()
{
var f = new Form1();
((Button)f.Controls["btn"]).Click += (s, e) =>
{
// バックグラウンドのループ終了
MessageBox.Show("");
Application.Idle -= this.TestLoop;
};
MainForm = f;
// フォームの表示方法。エントリポイントでApplication.Run(new TestContext())とした後、
// MainFormに渡すだけでOK
Application.Idle += this.TestLoop;
}
private void TestLoop(object sender, EventArgs e)
{
while (!NativeMethods.PeekMessage(out NativeMethods.MSG _, IntPtr.Zero, 0, 0, 0))
{
System.Diagnostics.Debug.Print("★" + DateTime.Now.ToString("HH:mm:ss.ff"));
System.Threading.Thread.Sleep(1);
}
}
}
}