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 は、プロパティ // FlatStyleSystem に設定する必要あり! // 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 にピッタリ収める方法は・・・不明 (^^;

ショートカットキー
// メインメニュー機能をキー操作で呼び出せる「ショートカットキー」の設定を行う

(1) 設定は、メインメニュー、または、コンテキストメニュー で行う。

(2) 推奨するキーの組み合わせは、Windows ショートカットキー を参照。

メインメニュー
// 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行は不要。
}

(C)緑のバイク