C#
Form デザイン
Form の表示
// Form を表示する
public class Form1
{
Form2 form2 = new Form2() ;
form2.Show() ;
}
public class Form2
{
/* Form1 と並行操作できる処理 */
}
Form のダイアログ表示
// Form を「モーダル ダイアログ」表示する
public class Form1
{
Form2 form2 = new Form2() ;
form2.ShowDialog() ;
:
:
form2.Dispose() ;
}
public class Form2
{
/* Form1 とは並行操作できない処理 */
}
// Note: 開いた Form2 を閉じない限り、Form1 へフォーカスを移動できない!
// Note: Form2 で、プロパティ DialogResult が設定されている Button をクリックする
// と、Form2 は 自動的に Close する。
// Note: ShowDialog() で呼ばれた Form は、Close() しても Dispose されない!
// 一方、Show() で呼ばれた Form は、Close() すると 自動的に Dispose される。
Form の多重起動を防ぐ
// Form の多重起動を防ぐ
Form2 form2 = null ;
private void button1_Click(object sender, System.EventArgs e)
{
if ((form2 == null) || form2.IsDisposed)
{
form2 = new Form2() ;
form2.Show() ;
}
}
Form を閉じる
// Form を閉じる( 閉じるボタン
を押したのと同じ動作)
this.Close() ; // Form 内で作成されたすべてのリソースを閉じる
// Note: 閉じた Form が、アプリケーション の スタートアップ フォーム(親 Form)
// である場合、アプリケーションが終了する(すべての 子 Form を閉じる)。
// Note: また、親 Form の Form_Closed() イベントが終了するまでは、子 Form は
// Dispose されない。ただし、子 Form の Form_Closing(), Form_Closed()
// イベントは、発生しない。・・・実験結果より(仕様かどうかは未調査)
Form を閉じる確認
// 閉じるボタン
が押された時、MessageBox で確認する
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel =
MessageBox.Show(
"本当に終了しますか?",
"タイトルバー文字列",
MessageBoxButtons.YesNo, // ボタンの一覧は MessageBoxButtons 参照
MessageBoxIcon.Question // アイコンの一覧は MessageBoxIcon 参照
)
== DialogResult.No ; // [いいえ] が選択された場合、Form は閉じない
}
// Note: Application.Exit() で Form を閉じた場合、この Form.Closing イベントと
// Form.Closed イベントは発生しない!
// Note: ログオフ または シャットダウン でも、Form.Closing イベントは発生する!
// 閉じるボタン
が押された時、MessageBox で確認する
// ただし、ログオフ または シャットダウン の時は、確認しない
bool system_shutdown = false ;
const int WM_QUERYENDSESSION = 0x11 ;
protected override void WndProc(ref Message m)
{
// ログオフ/シャットダウンの検出
if (m.Msg == WM_QUERYENDSESSION)
{
system_shutdown = true ;
}
base.WndProc (ref m) ;
}
private void Form1Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (system_shutdown)
{
// ログオフ/シャットダウンなので、確認の MessageBox は表示しない
return ;
}
e.Cancel =
MessageBox.Show(
"本当に終了しますか?",
"タイトルバー文字列",
MessageBoxButtons.YesNo, // ボタンの一覧は MessageBoxButtons 参照
MessageBoxIcon.Question // アイコンの一覧は MessageBoxIcon 参照
)
== DialogResult.No ; // [いいえ] が選択された場合、Form は閉じない
}
親 Form を参照/操作
// 親 Form を参照/操作 する
// 子 Form2 の button1 のクリックで、親 Form1 の textBox1 にメッセージを表示する
public class Form1 : System.Windows.Forms.Form
{
public System.Windows.Forms.TextBox textBox1 ; // 他 Form からの参照を許可
private void Form1_Load(object sender, System.EventArgs e)
{
Form2 form2 = new Form2() ; // 子 Form2 を生成
form2.form1 = this ; // 子 Form2 の参照ポインタを設定
form2.Show() ;
}
}
public class Form2 : System.Windows.Forms.Form
{
public Form1 form1 ; // 親 Form1 への参照ポインタ
private void button1_Click(object sender, System.EventArgs e)
{
form1.textBox1.Text = "button1 was clicked !" ; // 親 Form1 を操作
}
}
複数の Form を連動
// 複数の Form を連動させる(Form の「所有」機能を使う)
// (1) どれかの Form が アクティブ になったら、他の Form も 画面の前面に出す
// (2) 親 Form を最小化すると、全ての 子 Form も最小化する
// (3) 親 Form から、全ての 子 Form に アクセスする
Form2 form2 ; // 子 Form
Form3 form3 ; // 子 Form
private void button1_Click(object sender, System.EventArgs e)
{
form2 = new Form2() ;
this.AddOwnedForm(form2) ; // 親 Form が form2 を所有する
form2.Show() ;
}
private void button2_Click(object sender, System.EventArgs e)
{
form3 = new Form3() ;
this.AddOwnedForm(form3) ; // 親 Form が form3 を所有する
form3.Show() ;
}
private void button3_Click(object sender, System.EventArgs e)
{
foreach (Form form in this.OwnedForms) // 全ての 子 Form にアクセス
{
// 子 Form の背景色を黄色にする例
form.BackColor = Color.Yellow ;
}
}
// Note: 親 Form を最小化すると、その期間、子 Form も最小化するが、同時に、
// 子 Form は、タスクバーからも消える。
// Note: 子 Form は、必ず 親 Form より前面に表示される。
// Note: どれかの Form が アクティブ になったら、他の Form も 画面の前面に出す
// 別の方法:
// ShowInTaskbar を False にする。False になっている Form を アクティブ
// にすると、その他の False になっている Form も前面に表示される。
// なお、True になっている Form はそのまま。
スプラッシュウィンドウ
// アプリ起動直後、Form2 を 5秒間 表示した後、それを閉じて、Form1 を表示する
using System.Threading ; // for Thread
private void Form1_Load(object sender, System.EventArgs e)
{
Form2 form2 = new Form2() ;
form2.Show() ;
Thread.Sleep(5000) ; // 5000ms 一時停止
form2.Close() ;
}
Form の初期設定
// Form の初期設定を、初回表示の時に行う
private void Form1_Load(object sender, System.EventArgs e)
{
/* Form が(初めて)表示される時に実行させたい処理を記述 */
}
// Note: これは、一度だけ実行される。
// 実行タイミングは、Form のインスタンス化の時ではなく、初回表示の時(直前)!
Form の最小化/最大化
// Form を最小化する( 最小化ボタン
を押したのと同じ動作 )
this.WindowState = FormWindowState.Minimized ;
// Form を最大化する( 最大化ボタン
を押したのと同じ動作 )
this.WindowState = FormWindowState.Maximized ;
// Note: プロパティ MaximizeBox を、False に設定(既定値は True)していると、
// 最大化した時、タスクバーも隠してしまう!
// Form を元に戻す
this.WindowState = FormWindowState.Normal ;
Form を隠す
// Form を非表示状態にする
this.Hide() ; // ← タスクバーに表示されているフォームも非表示状態になる!
// Note: 元に戻すには Show() を実行する。
// Note: Form の Load イベント処理の中では、Hide() は無効!
Form を最前面に配置
// Form が常に最前面に表示されるように設定する
this.TopMost = true ;
// Note: TopMost を false に「再」設定すると、ToolTip が最前面に表示されなくなる
// 不具合がある?
Form がアクティブか判定
// Form がアクティブか判定する
if (Form.ActiveForm == this)
{
// Form がアクティブ
}
Form をアクティブにする
// Form を最前面に移動し、その Form にフォーカスを移動する
this.Activate() ;
// Note: Activate() 以外にも、Form を Activate する例(3種類)。
// (1) form2.Focus() ;
// (2) form2.BringToFront() ;
// (3) form2.TopMost = true ;
Form を必ずアクティブにする
// Form を「必ず」最前面に移動し、その Form にフォーカスを移動する
// this.Activate() だけでは、うまく Form が前面に移動しない場合がある。
// これは既に前面にある「アプリ」が、これを拒否するからである(windows の仕様)。
// 必ず前面に移動させるには、下記のようにスレッドのアタッチが必要である。
using System.Runtime.InteropServices ; // for DllImport
[DllImport("user32.dll")]
extern static int GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId) ;
[DllImport("user32.dll")]
extern static IntPtr GetForegroundWindow() ;
[DllImport("user32.dll")]
extern static bool AttachThreadInput(int idAttach, int idAttachTo, bool fAttach) ;
void this_activate()
{
// Thread のアタッチ
int fore_thread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero) ;
int this_thread = AppDomain.GetCurrentThreadId() ;
AttachThreadInput(this_thread, fore_thread, true) ;
// this をアクティブ
this.Activate() ;
// Thread のデタッチ
AttachThreadInput(this_thread, fore_thread, false) ;
}
他のアプリをアクティブにする
// textBox1 で指定した「クラス名」「ウィンドウ名」の Window をアクティブにする
using System.Runtime.InteropServices ; // for DllImport
[DllImport("user32.dll")]
extern static IntPtr FindWindow(string lpClassName, string lpWindowName) ;
[DllImport("user32.dll")]
extern static bool IsWindowVisible(IntPtr hWnd) ;
[DllImport("user32.dll")]
extern static bool SetForegroundWindow(IntPtr hWnd) ;
private void button1_Click(object sender, System.EventArgs e)
{
// textBox1 で指定した「クラス名」の Window をアクティブにする
IntPtr hwnd = FindWindow(textBox1.Text, null) ;
if (hwnd != IntPtr.Zero)
{
if (IsWindowVisible(hwnd))
{
SetForegroundWindow(hwnd) ; // アクティブにする
}
}
}
private void button2_Click(object sender, System.EventArgs e)
{
// textBox1 で指定した「ウィンドウ名」の Window をアクティブにする
IntPtr hwnd = FindWindow(null, textBox1.Text) ;
if (hwnd != IntPtr.Zero)
{
if (IsWindowVisible(hwnd))
{
SetForegroundWindow(hwnd) ; // アクティブにする
}
}
}
// textBox1 で指定したキーワードを含む「ウィンドウ名」の Window をアクティブにする
using System.Runtime.InteropServices ; // for DllImport
using System.Text ; // for StringBuilder
[DllImport("user32.dll")]
extern static IntPtr GetWindow(IntPtr hWnd, uint uCmd) ;
[DllImport("user32.dll")]
extern static IntPtr GetForegroundWindow() ;
[DllImport("user32.dll")]
extern static int GetWindowText(IntPtr hWnd, StringBuilder lpStr, int nMaxCount) ;
[DllImport("user32.dll")]
extern static bool IsWindowVisible(IntPtr hWnd) ;
[DllImport("user32.dll")]
extern static bool SetForegroundWindow(IntPtr hWnd) ;
private void button3_Click(object sender, System.EventArgs e)
{
const int GW_HWNDNEXT = 2 ;
StringBuilder sb = new StringBuilder(100) ;
IntPtr hwnd = GetForegroundWindow() ; // 最前面ウィンドウの hwnd を取得
while (hwnd != IntPtr.Zero)
{
if (IsWindowVisible(hwnd))
{
GetWindowText(hwnd, sb, sb.Capacity) ; // タイトルバー文字列を取得
if (sb.ToString().IndexOf(textBox1.Text) != -1)
{
// 見つかった
SetForegroundWindow(hwnd) ; // アクティブにする
break ;
}
}
hwnd = GetWindow(hwnd, GW_HWNDNEXT) ; // Zオーダーが1つ下の hwnd を取得
}
}
Form をフラッシュする
// Form の背景色を1秒間だけ反転する
using System.Threading ; // for Thread
Color color_org = this.BackColor ; // 元の背景色を保存
int color_inv = color_org.ToArgb() ^ 0xffffff ; // 反転色を計算する
this.BackColor = Color.FromArgb(color_inv) ; // 背景色を反転する
this.Refresh() ; // すぐ再描画する
Thread.Sleep(1000) ; // 1秒間 待つ
this.BackColor = color_org ; // 元の背景色に戻す
Form を半透明にする
// Form を半透明にする
| ⇒ |
|
配置 Button, TextBox ;
private void button1_Click(object sender, System.EventArgs e)
{
this.
Opacity = 0.5 ; // 不透明度を 50% に設定
}
Form を固定サイズにする
// Form のサイズを変更できないように、固定する
| ⇒ |
|
配置 Button, TextBox ;
private void button1_Click(object sender, System.EventArgs e)
{
this.
FormBorderStyle =
FormBorderStyle.FixedSingle ; //
FormBorderStyle 参照
}
Form の枠を消す
// Form の枠(キャプションバーと境界線)を消す
| ⇒ |
|
配置 Button, TextBox ;
private void button1_Click(object sender, System.EventArgs e)
{
this.
FormBorderStyle =
FormBorderStyle.None ; //
FormBorderStyle 参照
}
// Note: この設定を行うと、タスクバーに表示されるフォームに対するマウスボタンの
// 右クリックが無視される。つまり、最小化、閉じる等が、できなくなる!
// また、マウスドラッグによる Form のリサイズも、できなくなる。
// Note: 枠を消す別の方法として「 this.ControlBox = false ; this.Text = "" ; 」
// が存在する(マウスドラッグによる Form のリサイズも可能)。
// ただし、タスクバーにアイコンは表示されるが、そのタイトル文字は空白^^;
Form のサイズ変更グリップ
// Form の右下隅にサイズ変更グリップを表示する
| ⇒ |
|
配置 Button ;
private void button1_Click(object sender, System.EventArgs e)
{
this.
SizeGripStyle = System.Windows.Forms.
SizeGripStyle.Show ;
}
// Note: Form の プロパティ FormBorderStyle が、Sizable または SizableToolWindow
// のものだけが、サイズ変更グリップの表示が可能。
// なお、FormBorderStyle が None でも、サイズ変更グリップを表示させた
// FormBorderStyle 状態から None へ変更した場合に限り、表示の継続が可能。
Form の位置と大きさを取得
// 個別に取得
int form1_X = this.Left ; // X位置
int form1_Y = this.Top ; // Y位置
int form1_W = this.Width ; // 幅
int form1_H = this.Height ; // 高さ
// Point, Size 構造体を使って取得
Point form1_XY = this.Location ; // XとY位置
Size form1_WH = this.Size ; // 幅と高さ
Form の位置と大きさを設定
// 個別に設定
this.Left = 200 ; // X位置
this.Top = 100 ; // Y位置
this.Width = 640 ; // 幅
this.Height = 480 ; // 高さ
// Point, Size 構造体を使って設定
Point form1_XY = new Point(200, 100) ;
Size form1_WH = new Size(640, 480) ;
this.Location = form1_XY ; // XとY位置
this.Size = form1_WH ; // 幅と高さ
Form のセンタリング
// Form をセンタリング(スクリーンの中央に移動)する
this.Top = (Screen.PrimaryScreen.WorkingArea.Height - this.Height) / 2 ;
this.Left = (Screen.PrimaryScreen.WorkingArea.Width - this.Width ) / 2 ;
// Note: Form の起動時にセンタリングする場合は、プロパティ StartPosition を
// CenterScreen に設定しても、同様のことが可能。
// Note: スクリーンについては、スクリーンのサイズを取得 を参照。
Form のドラッグ移動
// Form をドラッグ移動できるように設定する(方法その1)
// マウスのイベントを監視し、マウスが移動する度に、Form の位置を再設定する
int mouse_X ;
int mouse_Y ;
int form_move_start = 0 ;
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) // マウスの左ボタンかチェックする
{
form_move_start = 1 ;
mouse_X = e.X ;
mouse_Y = e.Y ;
}
}
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (form_move_start == 1)
{
this.Left += e.X - mouse_X ;
this.Top += e.Y - mouse_Y ;
}
}
private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
form_move_start = 0 ;
}
// Form をドラッグ移動できるように設定する(方法その2)
// "Client" の Click Message を、"Caption" の Click Message に偽装する
protected override void WndProc(ref Message m)
{
base.WndProc(ref m) ;
if ((m.Msg == 0x84) && // WM_NCHITTEST (Click) ?
(m.Result == (IntPtr)1)) // HTCLIENT (Client) ?
{
m.Result = (IntPtr)2 ; // HTCAPTION (Caption) を設定
}
}
Form を型紙画像の形にする
// Form を型紙画像の形にして、ドラッグ移動もできるように設定する
 [ 型紙 ]
| ⇒ |
|
配置 Button, TextBox ;
private void Form1_Load(object sender, System.EventArgs e)
{
this.
FormBorderStyle = FormBorderStyle.None ; //
Formの枠を消す
this.
TransparencyKey = Color.Blue; // Formの透明色を設定
this.BackColor = Color.Blue;
Bitmap bit_map1 = new Bitmap("D:\\TMP\\form.gif") ; // 型紙の画像をロード
bit_map1.
MakeTransparent(Color.Blue) ; // 型紙の透明色を設定
this.Size = bit_map1.Size ;
this.
BackgroundImage = bit_map1 ;
}
protected override void WndProc(ref Message m)
{
//
Form のドラッグ移動 処理
base.WndProc(ref m) ;
if ((m.Msg == 0x84) && (m.Result == (IntPtr)1)) m.Result = (IntPtr)2 ;
}
// Note: 型紙の画像形式は、BMP/GIF/PNG/TIFF のいずれかであること。JPEG はダメ!
スクリーンのサイズを取得
// スクリーンのサイズを取得し TextBox に表示する
// 下記は プライマリ=1280px×1024px、セカンダリ=1024px×768px 環境での実行結果
 @プライマリ画面でクリック
|
|
 @セカンダリ画面でクリック
|
private void button1_Click(object sender, System.EventArgs e)
{
string M = "" ;
M += "スクリーン数 = " +
Screen.AllScreens.Length + "\r\n" ;
M += "プライマリ幅 = " +
Screen.PrimaryScreen.Bounds.Width + "\r\n" ;
M += "プライマリ高 = " +
Screen.PrimaryScreen.Bounds.Height + "\r\n" ;
if (Screen.AllScreens.Length == 2)
{
int secondary = (Screen.AllScreens[0].Primary) ? 1 : 0 ;
M += "セカンダリ幅 = " +
Screen.AllScreens[secondary].Bounds.Width + "\r\n" ;
M += "セカンダリ高 = " +
Screen.AllScreens[secondary].Bounds.Height + "\r\n" ;
}
M += "プライマリワーク幅 = " +
Screen.PrimaryScreen.WorkingArea.Width + "\r\n" ;
M += "プライマリワーク高 = " +
Screen.PrimaryScreen.WorkingArea.Height + "\r\n" ;
M += "現Formのある幅 = " +
Screen.GetBounds(this).Width + "\r\n" ;
M += "現Formのある高 = " +
Screen.GetBounds(this).Height + "\r\n" ;
M += "現Formのあるワーク幅 = " +
Screen.GetWorkingArea(this).Width + "\r\n" ;
M += "現Formのあるワーク高 = " +
Screen.GetWorkingArea(this).Height + "\r\n" ;
textBox1.Text = M ;
}
Windows XP スタイルにする
// Windows XP スタイル("Luna"インターフェース)にする
| ⇒ |
|
// マニフェストファイル(*.manifest)なしに、XP スタイルを実現する
static void Main()
{
Application.
EnableVisualStyles() ; // Windows XP スタイルに設定
Application.Run(new Form1()) ;
}
// Note: EnableVisualStyles() は .NET Framework
1.1 以降 で使用可能 !
// ただし、ImageList がらみで
不具合が発生 することがあるようなので、
// マニフェストファイルを使う方が安全かも・・・。
// Note: コントロール Button / CheckBox / RadioButton / GroupBox は、プロパティ
//
FlatStyle を
System に設定する必要あり!
// Note: 当然ながら、XP スタイル にすると、Button 等の色は、XP スタイルで固定さ
// れた色になる。後で、色を変更することは、できない!
// .NET Framework 1.0 で、XP スタイルを実現する方法
下記に示すテキストを、
実行ファイル名.manifest というファイル名で保存し、
実行ファイルと同じフォルダに置く。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="
アプリの名前"
type="win32"
/>
<description>
アプリの概要</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
// Note: 上記の「アプリの名前」と「アプリの概要」は、適当な文字列で良い。
// Note: 上記の manifest ファイルを、実行ファイルに埋め込む方法
// (1) Visual Studio の [ファイル]→[開く]→[ファイル] で、実行ファイルを開く。
// (2) 表示された実行ファイル名を右クリックし、[リソースの追加] を選択する。
// (3) [インポート] ボタンをクリックする。
// (4) manifest ファイルを選択する。
// (5) リソースの種類に、
RT_MANIFEST と入力する。
// (6) プロパティの ID 欄に、
1 を入力する。
// (7) ファイルの保存を行う。
コントロールにフォーカス
// button1 にフォーカスする
| ⇒ |
|
配置 Button, Button ;
private void button0_Click(object sender, System.EventArgs e)
{
button1.
Focus() ;
}
// Note: フォーカスできないコントロールも存在する。次のとおり。
// GroupBox, Label, LinkLabel, Panel, PictureBox, ProgressBar, Splitter.
コントロールの無効化
// button1 を、ユーザに対し応答しない(イベントを発生しない)ようにする
| ⇒ |
|
配置 Button, TextBox ;
private void button1_Click(object sender, System.EventArgs e)
{
button1.
Enabled =
false ;
}
// Note: 元に戻すには true に設定する。
コントロールを隠す
// button1 を、非表示状態にする
| ⇒ |
|
配置 Button, TextBox ;
private void button1_Click(object sender, System.EventArgs e)
{
button1.
Hide() ;
}
// Note: 元に戻すには Show() を実行する。
コントロールを背面に移動
// button2 を、他のコントロールより背面に移動する
| ⇒ |
|
配置 Button, Button, TextBox ;
private void button1_Click(object sender, System.EventArgs e)
{
button2.
SendToBack() ;
}
// Note: これと似た機能に Hide() があるが、Hide() 後は プログラムコード側から
// でも、その機能のアクセス(たとえば Button のクリック)が不可能になるが
// SendToBack() では、SendToBack() 後でも、アクセスが可能!
// 用途として、ESC キーの対応 Button を、ユーザに見えないよう配置する等。
コントロールの再描画
// button1 を、今すぐ表示(再描画)する
private void Event_X()
{
button1.Show() ;
button1.Refresh() ;
/* 長時間 の処理 */
} // ←----------------- Refresh() がない場合の表示(再描画)ポイント
// Note: Hide() は Refresh() しなくても、今すぐ有効(非表示状態)になる。
コントロールの位置を取得
// textBox1 の位置を取得する
配置 Button, TextBox, TextBox ;
private void button1_Click(object sender, System.EventArgs e)
{
Point Z = new Point(0, 0) ;
textBox2.Text =
"--- textBox1 の位置 ---" + "\r\n" +
"Left = " + textBox1.Left + "\r\n" +
"Top = " + textBox1.Top + "\r\n" +
"PointToScreen(Z).X = " + textBox1.PointToScreen(Z).X + "\r\n" +
"PointToScreen(Z).Y = " + textBox1.PointToScreen(Z).Y + "\r\n" +
"PointToClient(Z).X = " + textBox1.PointToClient(Z).X + "\r\n" +
"PointToClient(Z).Y = " + textBox1.PointToClient(Z).Y + "\r\n" ;
}
// Note: Left と Top は、Form を基準としたコントロールの位置を返す。
// PointToScreen は、スクリーンを基準としたコントロールの位置を返す。
// PointToClient は、PointToScreen の逆。
// Note: Left と Top は、Form の枠(タイトルバーとウィンドウ境界線)を除いた
// クライアント領域の左上を基準座標にして、位置を返す。
コントロールのセンタリング
// button1 を、Form がリサイズされた時、センタリング(中央に配置)する
private void Form1_Resize(object sender, System.EventArgs e)
{
button1.Left = (this.ClientSize.Width - button1.Width ) / 2 ; // 左右中央
button1.Top = (this.ClientSize.Height - button1.Height ) / 2 ; // 上下中央
}
// Note: プロパティ Anchor を None に設定すると、適当に自動再配置される。
// プロパティ Anchor を Left / Top / Right / Bottom に設定すると、
// それぞれの初期値(絶対距離)が保たれるように自動再配置される。
ToolTip の表示
// button1 の上にマウスカーソルが来た時、ToolTip を表示する
配置 ToolTip, Button, TextBox ;
toolTip1.AutoPopDelay = 7000 ; // 表示時間 [ms] (既定値 5000)
toolTip1.InitialDelay = 500 ; // 表示するまでの遅延時間 [ms] (既定値 500)
toolTip1.ReshowDelay = 500 ; // 再表示するまでの遅延時間 [ms](既定値 100)
toolTip1.ShowAlways = true ; // Form が active でなくても表示(既定値 非表示)
toolTip1.SetToolTip(this.button1, "ボタンの機能を説明") ; // 表示文の設定
// Note: ToolTip 表示文の設定は、デザイナで、各コントロールの ToolTip 入力欄
// からも出来る。
// Note: AutoPopDelay 設定最大値は 32767 [ms]。これより大きい値に設定すると、
// 5000 [ms] として機能する。(仕様?)
// Note: ToolTip に「&」を表示する時は「&&&」を設定する。
文字列の表示サイズを取得
// label1 に表示される文字列の表示領域サイズ[px]を取得する(1行に限る)
int W = label1.PreferredWidth ; // 幅 を取得
int H = label1.PreferredHeight ; // 高さを取得
// または、
int H = (int)Math.Ceiling(label1.Font.GetHeight()) ; // 高さを取得
// Note: PreferredWidth は、稀なケースで、値が「小さめ」になることがある!
// たとえば、文字列が MS UI ゴシック(9pt) "iiiiiiiiiiiiiiiiiiz" の場合。
// Note: PreferredHeight は、.NET Framework 1.1 環境では、常に 3 だけ、値が
// 「大きめ」になる。Font.GetHeight() の方は、ピッタリの値が取得できる。
// label1 の大きさを調整し 文字列がピッタリ収まるようにする(複数行に対応)
label1.Text = "これは\nテスト用の文字列です" ;
const int w = 200 ; // 横幅 制限値 [px]
Graphics g = label1.CreateGraphics() ;
SizeF size = g.MeasureString(label1.Text, label1.Font, w) ;
label1.Width = (int)Math.Ceiling(size.Width) ;
label1.Height = (int)Math.Ceiling(size.Height) ;
g.Dispose() ;
// Note: 1行の対応でよい場合、Label.AutoSize プロパティを true にする方法がある。
// ただし、横幅制限の設定は、できない。
// textBox1 の大きさを調整し 文字列がピッタリ収まるようにする(複数行に対応)
// TextBox に対し、MeasureString では 正しい横幅が取得できない (少し大きめの値を
// 取得してしまう) ので、Label の場合とは違う方法で、横幅を求める。
Graphics g = textBox1.CreateGraphics() ;
SizeF size = g.MeasureString(textBox1.Text, textBox1.Font) ;
textBox1.Height = (int)Math.Ceiling(size.Height) + 6 ; // 6 は余白部分の補正値
g.Dispose() ;
int font_W = (int)Math.Ceiling(
textBox1.Font.SizeInPoints * 2.0F / 3.0F) ; // フォント幅を取得
int width = 0 ;
foreach (string A in textBox1.Lines)
{
// 各行の文字バイト長から「横幅」を算出し、その最大値を求める
int len = System.Text.Encoding.GetEncoding("Shift_JIS").GetByteCount(A) ;
width = Math.Max(width, len * font_W) ;
}
textBox1.Width = width + 6 ; // 6 は余白部分の補正値
// Note: このコードは、等幅フォント、MSゴシック、DPI = 通常のサイズ(96DPI) の
// 場合を、想定している。
// 非等幅フォントの場合、 textBox1 にピッタリ収める方法は・・・不明 (^^;
ショートカットキー
メインメニュー
// Form の上部に表示される「メインメニュー」の設定を行う
// (1) Form の中に MainMenu を貼り付け、各メニューの名前を入力する
配置 MainMenu ;
MainMenu を配置後、各メニューの名前を設定する。
メニューの名前の末尾に、「&」と 英大文字 を付けると、アクセスキーとなる。
また、Shortcut プロパティにより、ショートカットキーの設定ができる。
// (2) それぞれのメニューが選択された場合の処理を記述する
private void menuItem1_Click(object sender, System.EventArgs e)
{
/* menuItem1 が選択された場合の処理 */
}
// Note: デザインでメニューの区分線を挿入するには、表示したい場所で 右クリック
// して、「区分線を挿入」を選ぶ。
// Note: メニューを多列表示する場合、改列したい MenuItem の Break プロパティを
// True に設定する(デザイナからは設定できない)。
// Note: チェックマークを表示したい場合、MenuItem の Checked プロパティを True
// に設定する。
メニューにアイコンも表示
// メニューに、アイコンとテキストを表示する
// 標準では、テキスト(とチェックマーク)しか表示できないが、メニューの
// OwnerDraw 機能を使って、アイコンも表示する
配置 MainMenu, ImageList ;
using System.Drawing.Text ; // for HotkeyPrefix
int image_height = 16 ; // アイコンのサイズ(高さ)
int image_width = 16 ; // アイコンのサイズ(横幅)
private void menuItem_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
{
// *** メニューが表示される直前に呼び出される ***
// 前準備
StringFormat sf = new StringFormat() ;
sf.HotkeyPrefix = HotkeyPrefix.Show ; // アクセスキー'&'対応
// メニューの描画サイズの設定
SizeF text_size = e.Graphics.MeasureString(
((MenuItem)sender).Text, SystemInformation.MenuFont, 1024, sf) ;
// 上記、1024 = 文字列の最大幅
e.ItemWidth = image_width + (int)text_size.Width ; // 横幅の設定
e.ItemHeight = Math.Max(image_height, (int)text_size.Height) ; // 高さの設定
// 後始末
sf.Dispose() ;
}
private void menuItem_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
// *** メニューが表示される時に呼び出される ***
// 前準備
StringFormat sf = new StringFormat() ;
sf.HotkeyPrefix = HotkeyPrefix.Show ; // アクセスキー'&'対応
// 背景を描画
Brush brush_back = ((e.State & DrawItemState.Selected) != 0) ?
SystemBrushes.Highlight : // 選択時の背景色
SystemBrushes.Menu ; // 非選択時の背景色
e.Graphics.FillRectangle(brush_back, e.Bounds) ;
// アイコンを描画
imageList1.Draw(
e.Graphics,
e.Bounds.X, // 描画位置 X = 左隅
e.Bounds.Y, // 描画位置 Y = 上隅
image_width,
image_height,
((MenuItem)sender).Index) ; // アイコンの指定
// テキストを描画
Brush brush_text =
!((MenuItem)sender).Enabled ?
new SolidBrush(SystemColors.GrayText) : // 非 Enable 時の文字色
((e.State & DrawItemState.Selected) != 0) ?
new SolidBrush(SystemColors.HighlightText) : // 選択時の文字色
new SolidBrush(SystemColors.MenuText) ; // 非選択時の文字色
e.Graphics.DrawString(
((MenuItem)sender).Text,
e.Font,
brush_text,
image_width, // 描画位置 X
e.Bounds.Y + 2, // 描画位置 Y (上マージン2px)
sf) ;
// 後始末
sf.Dispose() ;
brush_text.Dispose() ;
}
// Note: 各 MenuItem の
// MeasureItem イベントハンドラを、上記(共通の) menuItem_MeasureItem() に、
// DrawItem イベントハンドラを、上記(共通の) menuItem_DrawItem() に、
// 設定しておくこと。
// Note: 各 MenuItem の OwnerDraw プロパティを True に設定しておくこと。
// Note: imageList1 に、アイコンを登録しておくこと。
// n番目のメニューが imageList1 のn番目の画像に対応する。
// Note: 本サンプルでは、MenuItem の Checked プロパティの情報は、表示しない。
// Note: NotifyIcon の ContextMenu では、うまく OwnerDraw できない! バグ?
コンテキストメニュー
// マウスの右ボタンのクリックで表示される「メニュー」の設定を行う
// (1) Form の中に ContextMenu を貼り付け、各メニューの名前を入力する
配置 ContextMenu, Button, Label ;
ContextMenu 配置後、各メニューの名前を設定する。
メニューの名前の末尾に、「&」と 英大文字 を付けると、アクセスキーとなる。
また、Shortcut プロパティにより、ショートカットキーの設定ができる(ただし、
組み入れ対象が Form の時のみ機能する)。
// (2) メニューを、コントロールに組み入れる
コントロール(または Form)を選択し、その ContextMenu プロパティに、(1) の
ContextMenu 名を設定する。
// (3) それぞれのメニューが選択された場合の処理を記述する
private void menuItem1_Click(object sender, System.EventArgs e)
{
/* menuItem1 が選択された場合の処理 */
}
// (4) メニューのイベント発生(この記述は必須ではない)
private void contextMenu1_Popup(object sender, System.EventArgs e)
{
/* メニューが表示される直前に実行したい処理 */
}
// Note: 特定のメニュー項目を隠したい場合、下の例のようにする。
// 「 contextMenu1.MenuItems[1].Visible = false ; 」
// Note: 特定のメニューの名前を変更したい場合、下の例のようにする。
// 「 contextMenu1.MenuItems[1].Text = "機能B++" ; 」
// Note: 区分線の挿入、メニューの多列表示、チェックマーク については、
// 「メインメニュー」の Note と同じ。
左クリックでもメニュー表示
// マウスの左ボタンのクリックでも、メニューを表示させる
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
contextMenu1.Show(this, new Point(e.X, e.Y)) ;
}
}
ツールバー
// ツールバーの設定を行う
// (1) アイコンを登録する
配置 ImageList ;
Images プロパティの [...] ボタンを押して、Image コレクション エディタ を開く。
その中で、追加ボタンを押して、使用するアイコンを登録する。
// (2) ToolBar を貼り付け、各ボタンの設定をする
配置 ToolBar ;
ImageList プロパティに、(1) の ImageList 名を設定する。
次に、Buttons プロパティの [...] ボタンを押して、ToolBarButton コレクション
エディタ を開き、その中で、追加ボタンを押して、ツールバーボタンを登録し、(3)
で必要となる Tag プロパティも設定する。
// (3) ツールバーボタンを押した場合の処理を記述する
private void toolBar1_ButtonClick(object sender,
System.Windows.Forms.ToolBarButtonClickEventArgs e)
{
/* ToolBarButton の Tag プロパティで、どのボタンが */
/* 押されたか判別し、それぞれの処理を記述する。 */
switch (e.Button.Tag.ToString())
{
case "tag1" : /* toolBarButton1 の処理 */ ; break ;
case "tag2" : /* toolBarButton2 の処理 */ ; break ;
case "tag3" : /* toolBarButton3 の処理 */ ; break ;
case "tag4" : /* toolBarButton4 の処理 */ ; break ;
case "tag5" : /* toolBarButton5 の処理 */ ; break ;
}
}
// Note: ボタンのスタイルは、Style プロパティで設定する。
// PushButton = 標準型 (既定値)
// ToggleButton = トグルボタン (Pushed プロパティで状態を 取得/設定 可)
// Separator = ボタン間に隙間を作る
// DropDownButton = メニューも表示できるボタン
タスクトレイ常駐アプリ
// タスクトレイにアイコンが表示されるアプリを作る
// (1) アイコンを設定する
配置 NotifyIcon ;
Icon プロパティに、アイコンのファイル名を設定する。
private void Form1_Closed(object sender, System.EventArgs e)
{
// 終了時、「すぐに」アイコンを消す (念のため)
this.notifyIcon1.Visible = false ;
}
// (2) ツールチップの設定
アイコンの上にマウスカーソルが来た時に表示する文字を、Text プロパティで設定する。
// (3) メニューの設定
アイコンを右クリックした時に表示するメニューを、ContextMenu プロパティで設定する。
// (4) 起動後、Form を隠し、タスクバーのアイコンも消したい場合
using System.Threading ; // for Thread
private void Form1_Load(object sender, System.EventArgs e)
{
(new Thread(new ThreadStart(hideForm))).Start() ;
}
private void hideForm()
{
Thread.Sleep(3000) ; // Form (起動画面)が消えるまでの時間[ms]の設定
this.Hide() ; // Form1_Load() 中での直接実行は無効!
// Form の Hide で、タスクバーのアイコンも消える
}
// (5) Form は表示させるが、タスクバーのアイコンは消したい場合
// ( Form は、最小化ボタンで Hide、タスクトレイのアイコンのクリックで Show )
this.ShowInTaskbar = false ; // タスクバーにアイコンを表示しない
private void Form1_Deactivate(object sender, System.EventArgs e)
{
// Form の「最小化ボタン」のクリックで、Form を Hide
if (this.WindowState == FormWindowState.Minimized)
{
this.Hide();
}
// Note: この方法では、最小化の「後」に Form を Hide しているので、
// 一瞬、最小化後の「姿」が見えてしまう !! 少し格好悪い(^^;
}
// または、
protected override void WndProc(ref Message m)
{
// Form の「最小化ボタン」のクリックで、Form を Hide
const int WM_SYSCOMMAND = 0x0112 ; // システムコマンド
const int SC_MINIMIZE = 0xf020 ; // ウィンドウ最小化
if ((m.Msg == WM_SYSCOMMAND) &&
(((int)m.WParam & 0xfff0) == SC_MINIMIZE))
{
//「最小化」メッセージなら、Hide
this.Hide() ;
}
else
{
base.WndProc(ref m) ;
}
// Note: この方法では、最小化メッセージを無効にして Form を Hide して
// いるので、前記の方法よりは、格好が良い(^^;
// これらの方法がイヤなら、専用の Hide ボタンを配置するのも一手。
}
private void notifyIcon1_Click(object sender, System.EventArgs e)
{
// タスクトレイの「アイコン」のクリックで、Form を Show
this.Show() ;
this.WindowState = FormWindowState.Normal ;
// Note: ↑ Form の Hide 方法が Form1_Deactivate() でなく WndProc()
// 方式なら、上記1行は不要。
}