[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/01/29(Sat) 17:26
投稿者名:おじん
Eメール:
URL :
タイトル:
処理を続けるには?
教えていただきたい「こと」がうまく表現できなくて、表記のタイトルになりました。
質問の意味が通じましたら、教えてください。

例えば、下記のソースのように、エンドレスに実行している場合、Command1を
クリックすると、その処理は一時中断されます。

前もって、Commandボタンを一つ、Labelを一つ配置し、
メニューに、テスト−mnuPopup、その下位に、おわり−mnuExitを
エディットしておきます。
テスト実行の開始はFormをクリックします。そして、Commandボタンを押すと
Labelの数値は一時停止します。

質問は、Commandボタンが押されても(他のイベントが発生しても)処理が
続行するようにするには、どうしたらよいのでしょうか、です。

Option Explicit
Dim done As Boolean

Private Sub Command1_Click()
PopupMenu mnuPopup
End Sub

Private Sub Form_Click()
Dim n&
Do
DoEvents
    n = n + 1: Label1.Caption = n
Loop Until done = True
End Sub

Private Sub mnuExit_Click()
done = True
End Sub

よろしくお願いいたします。

投稿時間:2005/01/29(Sat) 17:35
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: 処理を続けるには?
1. ' DoEvents にする
(そもそも他のイベントを取得するために(割り込みを有効)DoEvents を使っているのでは)

2. No.1768 の質問と同様の処理をする(3方法)

3.Command1.Enabled = False のようにイベントを発生さない

何がしたいかよく解りませんが素直に 実行ボタン と キャンセルボタン で
処理した方がよいかと思います。

しかし、どうやって止めるのですか。
それに実際はこんな処理がしたい訳じゃないと思うのですが、変な例題を出されても
解決を引き延ばすだけかと思いますよ。

投稿時間:2005/01/29(Sat) 18:17
投稿者名:おじん
Eメール:
URL :
タイトル:
Re^2: 処理を続けるには?
ありがとうございました。しかし、やはり質問の内容が十分に伝わらなかったようです。
この例で期待していることは、実行を開始して、Commandボタンが押されても(メニュー
が表示されても)、Labelのカウントが続行しつづけてほしいのです。

> 1. ' DoEvents にする
> (そもそも他のイベントを取得するために(割り込みを有効)DoEvents を使っているのでは)
こうしないと、この例でCommandクリックイベントをつかむことができなくなります。

> 2. No.1768 の質問と同様の処理をする(3方法)
内容が難しく、理解するまでには時間がかかりそうです。が、しっかり読ませていただきます。

> 3.Command1.Enabled = False のようにイベントを発生さない
これ(True)が「重要」です。この処理をしても、、、(上述)。

> しかし、どうやって止めるのですか。
この例の場合は、Commandボタンを押し,その中の「おわり」を押せば正常に停止します。
終了はしませんが、、、。終了は「X」ボタンです(テストですから)。

いつも「理解しにくい質問」で申し訳ありません。2.No.1768を読んでから、、、。

投稿時間:2005/01/29(Sat) 18:53
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^3: 処理を続けるには?
>質問は、Commandボタンが押されても(他のイベントが発生しても)処理が
>続行するようにするには、どうしたらよいのでしょうか、です。

そもそもイベントうんぬん以前に矛盾した処理をする事が間違っているのでは
処理を中断したくなかったらモーダルで表示するような処理をしない事です。
MsgBox を表示するのと同じ事かと。
矛盾その1.割り込ませたく処理のループ中に割り込み処理を求める処理をしている
     (結構使うけどね)
矛盾その2.処理を停止させる処理中に処理を続行させたい。
     (現状では、Commandボタンには停止機能しかない)
矛盾その3.処理を続行させたいのに、モーダル表示の物を表示させて中断させている
      (自分で中断するようにしておいて続行させたい)
それにこのコードを実行して、実行中の CPU 使用率を確認して見て下さい。
本当に実際の場面でこのコードが必要なはずはないのでは。
Commandボタンをクリックしてポップアップメニューを表示させてキャンセルする
ような処理は。

投稿時間:2005/01/30(Sun) 06:28
投稿者名:おじん
Eメール:
URL :
タイトル:
Re^4: 処理を続けるには?
> そもそもイベントうんぬん以前に矛盾した処理をする事が間違っているのでは
はい。しかし、Do 〜 Loop Until done=True (このサンプル)で、何があろうと
〜の処理を「中断(イベント発生時)」することなく続行させたい、というのが質問です。
VBでは「できない」というのも一つの答えと思っています。

> 矛盾その1.割り込ませたく処理のループ中に割り込み処理を求める処理をしている
> 矛盾その2.処理を停止させる処理中に処理を続行させたい。
> 矛盾その3.処理を続行させたいのに、モーダル表示の物を表示させて中断させている
処理を終了させるための方法は必須です。他の方法でもよいのです。
また、Do〜Loop中の処理の状況(条件)を変えるために必要です。処理を止めて条件を
変えてもよいのですが、止めずに条件を変えたい場合はどうすればよいか、ということ
です。

> それにこのコードを実行して、実行中の CPU 使用率を確認して見て下さい。
CPU使用率の確認方法を忘れてしまいました。
> 本当に実際の場面でこのコードが必要なはずはないのでは。
> Commandボタンをクリックしてポップアップメニューを表示させてキャンセルする
> ような処理は。
実際のソースコードは非常に長いため、一部分を、書き換えて投稿しました。

NO.1768は難しすぎて理解できませんでした。
「一時中断可」とすれば、解決ですが、、、。もう少し拘って頑張ってみます。
ご指導、ありがとうございました。

投稿時間:2005/01/29(Sat) 22:40
投稿者名:Starfish
Eメール:
URL :
タイトル:
Re: 処理を続けるには?

> 質問は、Commandボタンが押されても(他のイベントが発生しても)処理が
> 続行するようにするには、どうしたらよいのでしょうか、です。

DoEvents で他のイベントが動いた場合は、そのイベントが終わった時点で
DoEventsの次の処理が動きます。割り込むイベントの中で PopupMenu を
使っているので、ポップアップメニューを閉じるまでは、DoEventsの次の
処理は動きません。

 ポップアップメニューの変わりに、フォームに変更するのが一番簡単な
対応方法ではないでしょうか?

投稿時間:2005/01/30(Sun) 07:17
投稿者名:おじん
Eメール:
URL :
タイトル:
Re^2: 処理を続けるには?解決
>  DoEvents で他のイベントが動いた場合は、そのイベントが終わった時点で
> DoEventsの次の処理が動きます。割り込むイベントの中で PopupMenu を
> 使っているので、ポップアップメニューを閉じるまでは、DoEventsの次の
> 処理は動きません。
はい、そのように理解していました。しかし、最近手にしたフリーソフトで
ポップアップメニューが開いている間も、「動作」が止まることなく動いて
いるものを発見しました。使用言語は分かりませんが、これまでの知識が覆
されました。それで、
たまたま作成していたソフトにそれを適用しようとしてうまくいかず、質問
なった次第です。あたりまえの疑問!!です。

>  ポップアップメニューの変わりに、フォームに変更するのが一番簡単な
> 対応方法ではないでしょうか?
はい、このことはすでに確認済みで、第二のFormをvbModelessで開けば処理
が中断することなく、「条件」などを設定できます。データのやり取りは少し
面倒ですが、、、。
しかし、Form上で、メニューと類似したツリー(?)リストを作るには、と
新しい疑問が発生します。

「VBではできない」ということを結論(ペンディング)にし「解決」とします。
花ちゃん様、Starfish様、ありがとうございました。

投稿時間:2005/01/30(Sun) 07:50
投稿者名:Starfish
Eメール:
URL :
タイトル:
Re^3: 処理を続けるには?解決
> はい、そのように理解していました。しかし、最近手にしたフリーソフトで
> ポップアップメニューが開いている間も、「動作」が止まることなく動いて
> いるものを発見しました。使用言語は分かりませんが、これまでの知識が覆
> されました。それで、
> たまたま作成していたソフトにそれを適用しようとしてうまくいかず、質問
> なった次第です。あたりまえの疑問!!です。

 マルチスレッドにすれば、対応はできます。
 VB.net では、マルチスレッドに正式に対応していますが、VBでは
対応をしていません。ただし、VB5.0であればマルチスレッド系のAPI
は使えるようですが、VB6.0では動かないようです。

投稿時間:2005/01/30(Sun) 08:37
投稿者名:おじん
Eメール:
URL :
タイトル:
Re^4: 処理を続けるには?解決
>  マルチスレッドにすれば、対応はできます。
>  VB.net では、マルチスレッドに正式に対応していますが、VBでは
> 対応をしていません。ただし、VB5.0であればマルチスレッド系のAPI
> は使えるようですが、VB6.0では動かないようです。
重ねてありがとうございます。
ただ、アドバイスもあまりに高度で、手におえません。相応な工夫で
やっていこうと思います。(使用はVB6です)
縁ありましたら、今後ともよろしくお願いいたします。

投稿時間:2005/01/30(Sun) 10:39
投稿者名:ガッ
Eメール:
URL :
タイトル:
Re^5: 処理を続けるには?解決
> 重ねてありがとうございます。
> ただ、アドバイスもあまりに高度で、手におえません。相応な工夫で
> やっていこうと思います。(使用はVB6です)
> 縁ありましたら、今後ともよろしくお願いいたします。

よく分からんが、
下のテキストを1.frmでも名前を付けて保存してみる。
俺の家だと、TimerイベントはPopupmenuを表示しているときでも動いているみたいだ。
…題意が「Popupmenuを呼び出しても処理を続けている」という風に感じたから、こういうのを作ってみ
たんだが。

VERSION 5.00
Begin VB.Form Form1
   Caption         =   "Form1"
   ClientHeight    =   3195
   ClientLeft      =   165
   ClientTop       =   735
   ClientWidth     =   4680
   LinkTopic       =   "Form1"
   ScaleHeight     =   3195
   ScaleWidth      =   4680
   StartUpPosition =   3  'Windows の既定値
   Begin VB.CommandButton Command1
      Caption         =   "Command1"
      Height          =   375
      Left            =   1320
      TabIndex        =   1
      Top             =   240
      Width           =   2055
   End
   Begin VB.ListBox List1
      Height          =   2220
      Left            =   1320
      TabIndex        =   0
      Top             =   720
      Width           =   2055
   End
   Begin VB.Timer Timer1
      Interval        =   100
      Left            =   600
      Top             =   360
   End
   Begin VB.Menu PM1
      Caption         =   "PM"
      Begin VB.Menu PM2
         Caption         =   "PM2"
      End
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Private Sub Command1_Click()
    Me.PopupMenu PM1
End Sub

Private Sub Form_Load()
    Command1.Caption = "Popup"
End Sub

Private Sub Timer1_Timer()
    List1.AddItem "a"
End Sub

投稿時間:2005/01/30(Sun) 12:27
投稿者名:おじん
Eメール:
URL :
タイトル:
Re^6: 解決
> …題意が「Popupmenuを呼び出しても処理を続けている」という風に感じたから、
早速コピー&ペーストしてテストしました。見事に解決です。ありがとうございました。
(一行目、VERSION 5.00をVERSION 6.00に直したところエラーが発生しました。
これって、バージョンには関係ないんですね。何のまじないでしょう)
Timerコントロールは”独立”して動作することを思い出せばよかったのでしょう。
疑似、マルチスレッドです。いろいろやってみます。
ありがとうございました。

投稿時間:2005/01/30(Sun) 12:36
投稿者名:Say
Eメール:
URL :
タイトル:
Re^5: 処理を続けるには?解決
マルチスレッドが無理なら
マルチプロセスでやる、という手もありますが・・・。

たとえばこんなかんじ
(Exe間のデータ受け渡しサンプルとしても使えそう。)

'●よびだし側   Project1.Exe
Option Explicit
Dim done As Boolean

Private Sub Command1_Click()
    PopupMenu mnuPopup
End Sub

Private Sub Form_Click()
    Dim n&
    Shell App.Path & "\prjPopUp.exe " & Hex(Text1.hwnd)
    Do
        DoEvents
        n = n + 1: Label1.Caption = n
    Loop Until done = True
End Sub

Private Sub Text1_Change()
    If Text1.Text <> "" Then
        done = True
    End If
End Sub

'●よびだされ側  prjPopUp.Exe
Option Explicit
Dim mlngHWnd As Long
Private Declare Function SendMessage Lib _
            "user32" Alias "SendMessageA" _
            (ByVal hwnd As Long, _
            ByVal wMsg As Long, _
            ByVal wParam As Long, _
            ByVal lParam As String) As Long
Private Const WM_SETTEXT = &HC&

Private Sub Form_Load()
    Me.Hide
    mlngHWnd = Val("&H" & Command())
    PopupMenu mnuPopup
End Sub

Private Sub mnuExit_Click()
    SendMessage mlngHWnd, WM_SETTEXT, 0&, "Q" & Chr(0)
    Unload Me
End Sub

投稿時間:2005/01/30(Sun) 17:44
投稿者名:おじん
Eメール:
URL :
タイトル:
Re^6: 処理を続けるには?解決
> マルチスレッドが無理なら
> マルチプロセスでやる、という手もありますが・・・。
>
> たとえばこんなかんじ
> (Exe間のデータ受け渡しサンプルとしても使えそう。)
Say様、ありがとうございます。段々と難しくなり、すぐには理解できません。
今回件は、何か実行中に、
1、その処理の変数を、それを止めずに変更したい、
2、欲張ばって、同一のアプリ内で、他の処理も同時にしたい
ことが、できるのだろうか、ということでした。(質問は1だけでしたが、、、)
1については、皆さんのご指導で、Timerコントロール内で実行すればよいと
わかりました。そして、
2については、まず、なぜ、そんなことをするのですか?と問われます。
もう一つ起動すればよいのですから。しかし、アプリ間のデータのやり取り
ということが問題になります。まだ、テストしていませんでした。
明日、コピー&ペーストして、勉強します。
ご指導のこと大いに参考にさせていただきます。ありがとうございました。