ボタンを押して処理の間にメッセージを表示するには?

解決


  2006-08-09 04:00:33  No: 132721

こんにちは良です。
いつもお世話になっております。
ボタンがありましてボタンを押して
結果が出力するまでメッセージを表示
して結果が出力する少し前にメッセージボックス
を閉じたいんですがどういう処理をすればよろしいでしょうか?

Progress Bar と  DoEventsを使えば
いいのまでは調べたんですが実際にコードにどう
入れていいのかわかりません。
すみませんがご教授のほうよろしくお願いいたします。


特攻隊長まるるう  2006-08-09 18:42:54  No: 132722

開発環境を毎スレッド明記するようにお願いします。
[VB.NET2003]

ProgressBar の使い方程度ならヘルプに載っています。
(ローカルのヘルプを見る場合は ProgressBar のコードを
選択して[F1]キー押下です。)
http://msdn.microsoft.com/library/ja/cpref/html/frlrfSystemWindowsFormsProgressBarClassTopic.asp
自分のアプリだけの制御なら DoEvents は使わない方が
いいかもしれません。

メッセージボックスを表示すると処理が中断しますので、
(マルチスレッドにするという手もあるかもしれませんが、難易度 高)
まずはメッセージボックスに似せたフォームを自作して表示して
みてください。


  2006-08-09 19:08:35  No: 132723

こんにちは良です。

>特攻隊長まるるうさん

お返事ありがとうございます。
すみません。気をつけいないと開発環境書き忘れちゃいますね。
開発環境はVB.NET2003 WinXPです。
早速新しくメッセージボックスに似たフォームを作ってみます!


  2006-08-10 00:57:22  No: 132724

こんにちは良です。
メッセージボックスに似せた新しいフォームを作り
モードレスで表示したんですが処理が重くなってしまい、
フォームの画面が全部表示しないままでした。
処理自体はできていました。

http://jeanne.wankuma.com/tips/form/show.html

ここをみて作りましたがモードレスの場合は開放(フォームの破棄)
は必要ないのでしょうか?
モーダルの場合は開放(フォームの破棄)必要みたいなんですが。

フォームが重くなってしまったのでフォームを軽くすることは
できるのでしょうか?
ご教授のほうよろしくお願いいたします。


特攻隊長まるるう  2006-08-10 01:55:31  No: 132725

>モードレスで表示したんですが処理が重くなってしまい、
>フォームの画面が全部表示しないままでした。
重くなったと言えばそうなんですが、再描画処理が
後回しになったと言うか。。。再描画処理が重くなって
内部の演算処理は通常実行されたと言うか。。。
 # 全て自分のアプリ内の話なので、軽くするという
 # 表現はボクにはしっくりきませんが。。。

ProgressBar は使いました?使うのだったら結局、Value の
変更時に表示更新の処理を入れることになります。
フォームか ProgressBar の Refresh メソッドを使ってみてください。

>モードレスの場合は開放(フォームの破棄)は必要ないのでしょうか?
普通はユーザの操作などにより、モードレスフォームは自分で
閉じることになります。その際に Dispose されますので必要ありません。
心配であれば Disposed イベントに Debug.WriteLine を書くなどして
破棄されていることを確認してください。

ただし、今回の場合、
>結果が出力する少し前にメッセージボックスを閉じたいんですが
ですので、フォームの終了処理もプログラムから命令することに
なります。
また、ユーザの操作により、×ボタンなどで擬似メッセージボックス
(フォーム)が閉じられないようにしておく必要があります。


  2006-08-10 02:19:43  No: 132726

こんにちは良です

>特攻隊長まるるうさん

お返事ありがとうございます。
そうですね。私の作っているアプリが結構重いので
それを軽くするのは確かに厳しいですね。

ProgressBarはまだ使っていないのでこれから使って
試してみようかと思います。

いつもありがとうございます。


  2006-08-10 02:59:52  No: 132727

こんばんは良です。
>フォームか ProgressBar の Refresh メソッドを使ってみてください。

新しくフォームを作ってそこにProgressBarコントロールをつくり
「処理中、しばらくお待ちください」みたいな文言をつけて
Refresh(再描画する)みたいな事をしたいんですが、
新しくフォームを作った場合にどうやってValueの値を渡して
あげればいいですか?


  2006-08-10 03:14:05  No: 132728

すみません。

とりあえず自分が実現できそうなところから始めてみます。

フォームにProgressBarコントロールを配置して
そこでRefreshかけようと思います。


特攻隊長まるるう  2006-08-10 03:20:26  No: 132729

>新しくフォームを作った場合にどうやってValueの値を渡して
>あげればいいですか?

フォーム上のコントロールはデフォルトで Friend 定義されるので、
同じプロジェクト内なら直接指定することもできるでしょう。
しかし、カプセル化の考え方から専用のプロパティを用意して
やって設定する手法を覚えることをお勧めします。
[VBレスキュー(花ちゃん) Form1 からForm2 のテキストボックスの内容を読み書きする]
http://hanatyan.sakura.ne.jp/dotnet/form09.htm


  2006-08-10 23:28:14  No: 132730

こんにちは良です。

特攻隊長まるるさんのリンクの内容とProgressBarについて自分なりに
ソースを組んでみました。

’フォーム1に記述

 'フォームの宣言
    Private f2 As New Form2
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        'フォーム2を表示
        f2.Show()
        f2.Refresh()
        Call f2.ProgressBar(20)
        
    End Sub

’フォーム2に記述
 Public Sub ProgressBar(ByVal intCnt As Integer)
        'プログレスバーの設定
        ProgressBar1.Maximum = 20
        ProgressBar1.Minimum = 0
        Dim i As Integer
        For i = 0 To intCnt
            Me.Label1.Text = "しばらくお待ちください"
            ProgressBar1.Value = i

            '1秒間待機する(何らかの処理を行う)
            System.Threading.Thread.Sleep(1000)

        Next
    End Sub
とやるとうまくいくんですが
プロパティ専用の設定してやると(フォーム1は内容が同じなので割愛します)

’フォーム1に記述

 'フォームの宣言
    Private f2 As New Form2
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        'フォーム2を表示
        f2.Show()
        f2.Refresh()
      f2.MyForm2ProgressBar = 20
        
    End Sub

 'ProgressBarのプロパティの値を設定及び取得するためのプロパティ
    Public Property MyForm2ProgressBar() As Integer
        'プログレスバーの設定
       ProgressBar1.Maximum = 20'←ここで「ステートメントは'GET'または'SET'メソッドを宣言しません」とエラーが出ます。
        ProgressBar1.Minimum = 0’ここでも同様のエラーが出ます。
        Get 'ProgressBar.Text の内容を取得
            Return me.ProgressBar1.Value
        End Get
        'ProgressBar.Text に書き込み
        Set(ByVal Value As String)’←ここで「'Set'パラメータには
それを含むプロパティと同じ型を指定しなければなりません」とエラーが出ます。
            Me.ProgressBar1.Value = Value
        End Set
 
    End Property

プロパティはどう設定したらよろしいでしょうか?


  2006-08-10 23:30:05  No: 132731

すみません

>Set(ByVal Value As String)’←ここで「'Set'パラメータには
>それを含むプロパティと同じ型を指定しなければなりません」とエラーが>出ます。

↑ここのエラーはただ単に型の整合性が取れないだけでした。
String型をInteger型にしたら消えました。


特攻隊長まるるう  2006-08-11 00:09:15  No: 132732

…自動で書いてもらったらいいんじゃないでしょうか?

>Public Property MyForm2ProgressBar() As Integer
ここまで書いたら Return キーを押してみてください。

その後、Property の記述の仕方はヘルプで確認してください。
[Property ステートメント]
http://msdn.microsoft.com/library/ja/vblr7/html/vastmProperty.asp
解説以降を読んでください。

処理は Set ブロックと Get ブロックの内部に書きます。
ReadOnly と WriteOnly を使って別の名前のプロパティを作ってみて
ください。2つのブロックの意味が分かると思います。どちらも指定しない
(読み書きできる)プロパティは、2つのブロックがまとめられている形に
なっているのです。


  2006-08-11 01:45:25  No: 132733

こんにちは良です。

>特攻隊長まるるうさん

ありがとうございました。
できました!
>Public Property MyForm2ProgressBar() As Integer

でReturnを押すと自動的にGet とSetブロックが生成されるんですね。

でもって

>ReadOnly

だとGetブロックのみ自動で生成されて

>WriteOnly

だとSetブロックのみ自動で生成されるんですね。

今回はSetブロックのみの使用なので
WriteOnlyProperty
を使用させていただきました。

ソースはこんな感じになりました
’フォーム1に記入
 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim i As Integer
        'フォームの生成
        Dim f2 As New Form2
        'フォーム2を表示
        f2.Show()
        f2.Refresh()
        'ループカウント
        For i = 0 To 20
            f2.MyForm2ProgressBar = i
        Next
        'フォームを閉じる
        f2.Close()
        'フォームを破棄する
        f2.Dispose()
    End Sub

’フォーム2に記入
  'プログレスバーのプロパティ
    Public WriteOnly Property MyForm2ProgressBar() As Integer

        Set(ByVal Value As Integer)
            'プログレスバーの設定
            ProgressBar1.Maximum = 20
            ProgressBar1.Minimum = 0
            'プログレスバーに値をセットする
            Me.ProgressBar1.Value = Value

            '1秒間待機する(本来なら何らかの処理を行う)
            System.Threading.Thread.Sleep(1000)
        End Set
    End Property

ありがとうございましたm(__)m


特攻隊長まるるう  2006-08-11 02:48:04  No: 132734

ちょっと添削してみたw。
まぁ、このままだと処理中にユーザが操作しようとすると
応答なしのエラーが出たりするかもしれないけど、まぁ、
それは別スレでも立ててください。
[VB.NET2003]
    'フォーム1に記入
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim i As Integer
        'フォームの生成
        Dim f2 As New ProgressBarForm
        'フォーム2を表示
        f2.Show()
        'f2.Refresh() 'Show された時に描画処理が走るので必要ない。
        'Max値設定
        f2.SetMyForm2ProgressBarRange(20)
        'ループカウント
        For i = 0 To 20
            f2.MyForm2ProgressBar = i
            '1秒間待機する(本来なら何らかの処理を行う)
            System.Threading.Thread.Sleep(1000)
        Next
        'フォームを閉じる
        f2.Close()
        ''フォームを破棄する
        'f2.Dispose() 'Close したら Dispose されるので必要ない
    End Sub

    'フォーム2に記入
    'Max値設定メソッド
    Public Sub SetMyForm2ProgressBarRange(ByVal Maximum As Integer, Optional ByVal Minimum As Integer = 0)
        With Me.ProgressBar1
            .Maximum = Maximum
            .Minimum = Minimum
        End With
    End Sub
    'プログレスバーのプロパティ
    Public WriteOnly Property MyForm2ProgressBar() As Integer
        Set(ByVal Value As Integer)
            ''プログレスバーの設定
            'ProgressBar1.Maximum = 20 'Value の変更のたびに設定するのは無駄なので移動。
            'ProgressBar1.Minimum = 0
            'プログレスバーに値をセットする
            Me.ProgressBar1.Value = Value
            '処理中に他の Window を重ねてみれば分かるけど、ProgressBar しか再描画されない。
            Me.Refresh() 'のでここでフォームの再描画

            ''1秒間待機する(本来なら何らかの処理を行う)’実際に処理を実行したいのはフォーム1になると思うので移動。
            'System.Threading.Thread.Sleep(1000)
        End Set
    End Property


  2006-08-11 03:41:43  No: 132735

こんばんは良です。

>特攻隊長まるるうさん

添削ありがとうございます。
早速実行してみたら
「応答なし」って出てきましたね。

でもどれだけ余分な処理が多いのかってわかりました。
ありがとうございました。

「応答なし」の問題はしばらく考えてから
わからないときはまた質問させていただきます。

ネットで調べてみたいんですがもしよろしければどういう単語で
調べれば見つかると思いますか?


特攻隊長まるるう  2006-08-11 18:36:59  No: 132736

>ネットで調べてみたいんですがもしよろしければどういう単語で
>調べれば見つかると思いますか?
そりゃもう『応答なし』に決まってるやん。。。(  _)_

ここの過去ログ検索すれば、マルチスレッドにするか、DoEvents
入れるか?というような話はすぐに見つかります。


  2006-08-11 18:42:20  No: 132737

おはようございます。良です。

>特攻隊長まるるうさん

お返事ありがとうございます。
そのままでいいんですね。
メソッド名で調べないといけないのかなと
思ったので。
了解いたしました!
いろいろありがとうございました!
またどうしようもなくなってしまったら
質問してしまうと思いますの
お手数ですがそのときは
またよろしくお願いいたします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加