[2018/03/26] フォームの表示をモジュールのMain関数から行う(エントリポイントの変更) (No.36)
[2018/03/22] フォームが閉じるのをキャンセルする方法 (No.19)
[2018/03/22] 親フォームのコントロールを子フォームからアクセスする方法 (No.18)
[2018/03/22] フォームクラスにプロパティ宣言し外部からアクセスする方法 (No.17)
[2018/03/22] フォームの位置設定を行う (No.16)
-
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
-
VB.NETの場合、フォームを表示する場合にはプロジェクトプロパティの中の設定でスタートアップオブジェクトを 対象となるフォームを選択して実行すれば、そのフォームが最初に表示されます。 以下の図は、スタートアップオブジェクトをForm1に設定したところを示します。
簡単なプログラムであればこの方法で良いのですが、いきなりフォームが表示されては困ることもあります。 フォームが表示される前に行いたい処理がいろいろあったりします。 そこで、プログラムの開始位置であるエントリポイントを変更することで、 フォームの表示前に処理が出来る様になります。
以下のソースを見て下さい。Main関数を定義したモジュールファイルを作成します。 先ほどのスタートアップオブジェクトをこのMain関数に設定することで プログラムのエントリポイントがMain関数になります。 つまり、プログラムはMain関数から開始されることになります。エントリポイントをSub Mainにする
Module MdlMain <STAThread()> _ Sub Main() '===== '初期処理... '===== 'フォーム表示 Dim frmForm1 As New Form1 Application.Run(frmForm1) End Sub End Module
もしフォーム表示前の処理を行いたい場合には、Application.Runの前までに記述します。 私が組んだプログラムでは、以下の様な処理を行ったりしました。
- プログラムの二重起動を抑制する。
- プログラム起動の引数の取得とチェックを行う。
- ログ出力の初期処理を行う。
- データベースのオープン処理を行い、エラーの場合は処理を中断する。
尚、以下の図はプロジェクトプロパティの中の設定でスタートアップオブジェクトを Sub Mainに設定したところを示します。
VB.NETでは、Mainメソッド(またはプロシージャ)がエントリポイントです。ところが、Windowsフォームアプリケーションプロジェクトのどこを探してもMainメソッドがありません。エントリポイントとなるMainメソッドは、コンパイラによって自動的に作成されます。 補足:Visual Studio 2005以降では、「アプリケーションフレームワークを有効にする」を無効にしないと、本当のエントリポイントを変更することはできません。「アプリケーションフレームワークを有効にする」を有効にしたときのエントリポイントは、MyApplicationクラスのMainメソッドとなるようです。
モジュールでファイルではなく、クラスファイルに以下の様にShared Sub Main関数を宣言しても同じことができます。エントリポイントをクラスのSub Mainにする
Public Class ClsMain <STAThread()> _ Shared Sub Main() Application.Run(New Form1) End Sub End Class
関連する記事
⇒フォームの位置設定を行う処理 :[Screen.PrimaryScreen.WorkingArea]
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒親フォームのコントロールを子フォームからアクセスする方法
⇒フォームが閉じるのをキャンセルする方法:[FormClosingEventArgs,Cancel]
⇒フォームの表示をモジュールのMain関数から行う(エントリポイントの変更)
⇒フォームがKeyDownなどのキーイベントを受取り、ファンクションキー処理をする
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について
PR -
フォームが閉じる方法としては、自分のプログラムの中で Close を呼出すか、 またはウインドウの右上に表示された「X」をクリックするか、「Alt + F4」を押下するかになります。
この場合にフォームのイベントとしては FormClosing と FormClosed がその順番に発生します。
FormClosing は呼び出された関数の引数として FormClosingEventArgs を持ち、 その中のプロパティである CloseReason を調べることで、閉じられた原因が分かります。
MSDNの説明によれば以下の様になっています。FormClosingEventArgsについて
・CloseReason :フォームの終了理由を示す値 ApplicationExitCall :Application.Exitによる FormOwnerClosing :所有側のフォームが閉じられようとしている MdiFormClosing :MDIの親フォームが閉じられようとしている TaskManagerClosing :タスクマネージャによる UserClosing :ユーザーインターフェイスによる WindowsShutDown :OSのシャットダウンによる None :未知の理由 ・Cancel:イベントをキャンセルする必要があるかどうかを示す値を設定します。 True :フォームを閉じない False :フォームを閉じる
以下のソースは、フォームの中に「ボタンでのクローズ指示フラグ」を宣言し、 ボタン押下時にはそのフラグをONして自分のフォームを Close しています。
フォーム右上「X」を押下したり、「Alt+F4」でウインドウを閉じる時にも フォームFormClosingイベントが発生しますが、ボタンでのクローズなのかを上記のフラグで区別しています。
フォームFormClosingイベントで CloseReason.UserClosing の場合しか処理しない様にしていますので、 その他のシャットダウン時等のクローズでは、素通りとなり、次のフォームFormClosedイベントへと移ります。フォームが閉じるのをキャンセルする方法
Public Class frmClose 'ボタンでのクローズ指示フラグ Private mblnButtonClose As Boolean = False '''
''' ボタンクリックイベント ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Me.mblnButtonClose = True Me.Close() End Sub '''''' フォームFormClosingイベント ''' Private Sub frmClose_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing If e.CloseReason = CloseReason.UserClosing Then 'ボタンでのクローズかチェック If mblnButtonClose = False Then 'ボタンでは無い場合 Dim strDsp As String = "ウインドウ右上の[X]または[Alt + F4]で閉じようとしています。" _ & vbCrLf & "よろしいですか?" If MsgBox(strDsp, MsgBoxStyle.YesNo, "クローズテスト") = MsgBoxResult.No Then '「いいえ」⇒閉じるのを止める e.Cancel = True End If End If End If End Sub '''''' フォームFormClosedイベント ''' Private Sub frmClose_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed 'ここで通常はオブジェクトの廃棄等を行う End Sub End Class以下の画像は、フォーム右上「X」を押下した時の様子です。
関連する記事
⇒フォームの位置設定を行う処理 :[Screen.PrimaryScreen.WorkingArea]
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒親フォームのコントロールを子フォームからアクセスする方法
⇒フォームが閉じるのをキャンセルする方法:[FormClosingEventArgs,Cancel]
⇒フォームの表示をモジュールのMain関数から行う(エントリポイントの変更)
⇒フォームがKeyDownなどのキーイベントを受取り、ファンクションキー処理をする
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について
-
ある親フォームから別の子フォームを表示し、その子フォームから親のフォームのコントロールをアクセスしたい場合があります。 親フォームに公開プロパティ及び公開メソッドを持ち、それを介してデータのやり取りを行います。
以下の例では、親フォームから子フォームを呼出した時に、子フォームから親フォームのテキストボックスの 「Text」を取得し、子フォームのテキストボックスの「Text」に初期設定します。
その後、子フォームのボタンを押下することで、親フォームのテキストボックスの「Text」に 子フォームのテキストボックスの「Text」を再設定します。
以下の画像は、親フォームのテキストボックスに「aaaaa」を入力し、子フォームを表示した子フォームを表示した様子です。その後、子フォームのテキストボックスを「bbbbbbbb」と入力し、子フォームのボタンを押下し親フォームに戻った時を表示した画像です。
以下のソースは、親フォームのクラスの宣言ですが、子フォームから直接テキストボックスにアクセスせずに プロパティを介して行う様にしています。
また、プロパティではなくメソッドからアクセスできる様にもしてあります。 (内容的には自分自身のプロパティを利用してはいますが)親フォームのクラス
'''
''' 子フォームを呼出す親フォーム ''' Public Class frmPropTextMain '''''' TextBox1の「Text」プロパティ ''' '''設定文字列 '''TextBox1の文字列を返す Public Property TextBoxVal As String Set(value As String) Me.TextBox1.Text = value 'TextBox1に設定 End Set Get Return Me.TextBox1.Text 'TextBox1の値を返す End Get End Property '''''' TextBox1への設定メソッド ''' ''' <param name="astrText">設定文字列</param> Public Sub SetTextBox(ByVal astrText As String) '自分のプロパティを利用する Me.TextBoxVal = astrText End Sub '''''' 「サブフォーム表示」ボタンクリックイベント ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'プロパティテストウインドウ生成 Dim frmPropSub As New frmPropTextSub(Me) 'ウインドウ表示 frmPropSub.ShowDialog() 'プロパティテストウインドウ廃棄 frmPropSub.Dispose() frmPropSub = Nothing End Sub End Class子フォームの処理は以下の様になります。
子フォームのクラス
'''
''' フォーム生成時にメインフォームが必要な子フォーム ''' Public Class frmPropTextSub 'メインフォームオブジェクト Private mfrmMain As frmPropTextMain '''''' このフォームのコンストラクタ ''' ''' <param name="afrm">メインフォームオブジェクト</param> Sub New(ByVal afrm As frmPropTextMain) ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 'メインフォームオブジェクトの退避 Me.mfrmMain = afrm End Sub '''''' フォームロードイベント ''' Private Sub frmPropTextSub_Load(sender As Object, e As EventArgs) Handles Me.Load 'メイン側のプロパティでメイン側のTextBox1の内容を取得し、サブ側に設定 Me.TextBox1.Text = Me.mfrmMain.TextBoxVal End Sub '''''' 「設定(プロパティ)」ボタンクリックイベント ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'メイン側のプロパティを使用し、サブのTextBox1の内容を設定 Me.mfrmMain.TextBoxVal = Me.TextBox1.Text '自分を閉じる Me.Close() End Sub '''''' 「設定(メソッド)」ボタンクリックイベント ''' Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 'メイン側のメソッドを使用し、サブのTextBox1の内容を設定 Me.mfrmMain.SetTextBox(Me.TextBox1.Text) '自分を閉じる Me.Close() End Sub End Classこの子ウインドウのコンストラクタでは、引数の親フォームのオブジェクト参照を プライベート変数に退避しています。 この変数を介して親フォームクラスのプロパティ及び、メソッドにアクセスします。
フォームロード時には親フォームのテキストボックスの内容を、 自分自身のテキストボックスに設定しています。
「設定(プロパティ)」ボタンクリックイベントでは 自分自身のテキストボックスの内容を、親フォームのプロパティに設定し、 それにより親フォームのテキストボックスの内容が変更されます。 「設定(メソッド)」ボタンクリックイベントでは、 親フォームのメソッドを呼び出すことで 親フォームのテキストボックスの内容を変更しています。通常ではコンストラクタを変更することは無いのですが、 コンストラクタに引数を持たせるための方法を説明します。
最初に子フォームのソース上で Sub New と入力した時点で 以下のソースまでは自動で生成されますので、あとは「呼び出しの後で初期化を追加します。」の 後に必要な処理を追加します。Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 End Sub
今回の例ではクラス生成の時の引数として親フォームの参照を渡しますので、 ソースは以下の様になります。
'メインフォームオブジェクト ← ここの変数を追加する Private mfrmMain As frmPropTextMain Sub New(ByVal afrm As frmPropTextMain) ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 'メインフォームオブジェクトの退避 ← ここの処理を追加する Me.mfrmMain = afrm End Sub
関連する記事
⇒親フォームのコントロールを子フォームからアクセスする方法その2(DirectCast)
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒フォームがKeyDownなどのキーイベントを受取り、ファンクションキー処理をする
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について
⇒フォームクラス生成時に設定値を同時に渡す方法
おすすめ本
-
あるフォームから別のフォームを表示し、その子フォームでの情報を親のフォームからアクセスしたい場合に、 子フォームにプロパティを持ち、それを介してデータのやり取りを行います。
以下の例では、親フォーム上のチェックボックスのチェック状態を、子フォームのチェックボックスに設定し、 子フォームを閉じた後で、子フォーム上のチェックボックスのチェック状態を親フォームに再度表示します。
以下の画像は、親のフォームでチェックボックスをONにして、子フォームを表示した様子です。以下のソースは、子フォームの中に「チェック状態プロパティ」を宣言し、 処理的には「チェック状態退避値」に値を設定・取得しています。
フォームロード時に「チェック状態退避値」の値をフォーム上のチェックボックスに設定し、 「終了」ボタン押下時にはチェックボックスの状態を「チェック状態退避値」に退避しています。プロパティを持つ子フォームのクラス
'''
''' プロパティを持つ子フォーム ''' Public Class frmProperty 'チェック状態退避値 Private mblnChkStatus As Boolean = False '''''' チェック状態プロパティ ''' '''チェック状態の設定値 '''チェック状態を返す Public Property ChkStatus As Boolean Set(value As Boolean) mblnChkStatus = value '退避値に設定 End Set Get Return mblnChkStatus '退避値を返す End Get End Property '''''' ボタンクリックイベント ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'チェックボックスの状態を退避 Me.mblnChkStatus = Me.CheckBox1.Checked '自分を閉じる Me.Close() End Sub '''''' フォームロードイベント ''' Private Sub fomProperty_Load(sender As Object, e As EventArgs) Handles Me.Load 'チェックボックスの初期状態設定 Me.CheckBox1.Checked = Me.mblnChkStatus End Sub End Classこの子フォームを呼出す親フォームの処理が以下の様になります。
子フォームを呼出す親フォームの処理
'''
''' 子フォームを呼出す親フォーム ''' Public Class frmPropMain '''''' ボタンクリックイベント ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'プロパティテストウインドウ生成 Dim frmProp As New frmProperty 'プロパティに自分のチェックボックスの値を設定 frmProp.ChkStatus = Me.CheckBox1.Checked 'ウインドウ表示 frmProp.ShowDialog() 'プロパティ値を自分のチェックボックスの値に設定 Me.CheckBox1.Checked = frmProp.ChkStatus 'プロパティテストウインドウ廃棄 frmProp.Dispose() frmProp = Nothing End Sub End Classボタンクリックイベントでは、子ウインドウのオブジェクトを生成し、 子ウインドウのプロパティに自分自身の上のチェックボックスの状態を設定し、 ダイアログウインドウとして子ウインドウを表示します。
子ウインドウの表示終了後、子ウインドウを廃棄せずにプロパティを取得し、 自分自身の上のチェックボックスの状態に設定し直しています。
ここで重要なのは、子ウインドウのオブジェクトを廃棄する前にプロパティにアクセスすることです。 子ウインドウのオブジェクトを廃棄するとアクセスは不可能になります。関連する記事
⇒フォームの位置設定を行う処理 :[Screen.PrimaryScreen.WorkingArea]
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒親フォームのコントロールを子フォームからアクセスする方法
⇒フォームが閉じるのをキャンセルする方法:[FormClosingEventArgs,Cancel]
⇒フォームの表示をモジュールのMain関数から行う(エントリポイントの変更)
⇒フォームがKeyDownなどのキーイベントを受取り、ファンクションキー処理をする
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について
-
今回はフォームの位置を画面上のどの位置に表示するかを行う処理になります。
フォーム位置設定の関数内では、Screen.PrimaryScreen.WorkingArea プロパティによりディスプレイの大きさを取得し 計算に使っています。この関数では Screen.PrimaryScreen を使っているので、ディスプレイが一台のみと想定しています。
尚、Screen.PrimaryScreen.WorkingArea プロパティにより、ディスプレイの作業領域が取得できますが、 作業領域とは、ディスプレイのデスクトップ領域からタスクバー、 ドッキングされたウィンドウ、およびドッキングされたツール バーを除いた部分のことをいいます。フォームの位置設定を行う関数と実行例
Public Class frmPosition 'フォーム位置宣言 Enum enmWindowPos Center = 0 '中央 TopLeft '左上 TopRight '右上 BottomLeft '左下 BottomRight '右下 End Enum ''' <summary> ''' フォームの位置設定 ''' </summary> ''' <param name="frmDes">対象のフォーム</param> ''' <param name="pos">位置</param> Private Sub SetWindowPosition(ByVal frmDes As Form, ByVal pos As enmWindowPos) With Screen.PrimaryScreen.WorkingArea Select Case pos Case enmWindowPos.Center '中央 frmDes.Left = (.Width / 2) - (frmDes.Width / 2) + .Left frmDes.Top = (.Height / 2) - (frmDes.Height / 2) + .Top Case enmWindowPos.TopLeft '左上 frmDes.Left = 0 frmDes.Top = 0 Case enmWindowPos.TopRight '右上 frmDes.Left = .Width - frmDes.Width frmDes.Top = 0 Case enmWindowPos.BottomLeft '左下 frmDes.Left = 0 frmDes.Top = .Height - frmDes.Height Case enmWindowPos.BottomRight '左下 frmDes.Left = .Width - frmDes.Width frmDes.Top = .Height - frmDes.Height End Select End With End Sub ''' <summary> ''' ボタンクリックイベント ''' </summary> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'チェックするラジオボタン Dim arrRdo As RadioButton() = {Me.rdoTopLeft, Me.rdoTopRight, Me.rdoCenter, Me.rdoBottomLeft, Me.rdoBottomRight} For Each rdo As RadioButton In arrRdo If rdo.Checked = True Then 'Tagより位置設定指示を取得 Dim enmPos As enmWindowPos = CType(rdo.Tag, enmWindowPos) 'ウインドウ設定 Call Me.SetWindowPosition(Me, enmPos) Exit For End If Next End Sub ''' <summary> ''' フォームロードイベント ''' </summary> Private Sub frmPosition_Load(sender As Object, e As EventArgs) Handles Me.Load 'ラジオボタンのTagにウインドウ位置Enum設定 Me.rdoTopLeft.Tag = enmWindowPos.TopLeft Me.rdoTopRight.Tag = enmWindowPos.TopRight Me.rdoCenter.Tag = enmWindowPos.Center Me.rdoBottomLeft.Tag = enmWindowPos.BottomLeft Me.rdoBottomRight.Tag = enmWindowPos.BottomRight End Sub End Class
このプログラムは、各ラジオボタンをチェックし、「フォーム位置設定」ボタンを押下することで、 自分自身のフォームの位置が移動します。
関連する記事
⇒フォームの位置設定を行う処理 :[Screen.PrimaryScreen.WorkingArea]
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒親フォームのコントロールを子フォームからアクセスする方法
⇒フォームが閉じるのをキャンセルする方法:[FormClosingEventArgs,Cancel]
⇒フォームの表示をモジュールのMain関数から行う(エントリポイントの変更)
⇒フォームがKeyDownなどのキーイベントを受取り、ファンクションキー処理をする
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について