【Visual BASIC 2008】で、禁断のCalc呼出し電卓プログラムを作りました。下記コードでは、MsgBoxを使って、Calcが終了するのを待っていますが、Calcが終了するのを自分で待ってOKボタンを押さなければなりません。これをMsgBoxを使わずに自動で待ってCalc終了後、クリップボックスの内容を取得するように変えるにはどうすればいいでしょうか。

 問題の電卓プログラムは、Form1.vb[デザイン]にボタン1つと入力用TextBox1と出力用TextBox2をつけて下記コードで作りました。
※質問が長すぎるとのことで、コードはコメント欄にあります。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/11/07 07:58:16
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:makeworld No.2

回答回数75ベストアンサー獲得回数23

ポイント100pt

こんな感じでしょうか?

(なぜか%{F4}を取りこぼす場合があるようなので、%{F4}のリトライ処理を入れています)

Public Class Form1
    Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As Integer) As Integer

    'お約束のボタン
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        TextBox2.Text = CCalc(TextBox1.Text)
        TextBox1.Focus()
    End Sub

    'Windowsアクセサリの電卓Calcを呼出して計算結果を文字列で取得する関数
    Private Function CCalc(ByVal expr As String) As String
        Dim res As String = ""
        Dim newProc As Diagnostics.Process

        If Microsoft.VisualBasic.Right(expr, 1) <> "=" Then expr += "="
        'クリップボードに文字列をコピー
        Clipboard.SetDataObject(expr)

        'Windowsアクセサリの電卓Calcを呼出す
        newProc = Diagnostics.Process.Start("C:\WINDOWS\system32\Calc.exe")

        newProc.WaitForInputIdle(1000)
        SetForegroundWindow(newProc.MainWindowHandle)

        'SendKeysで計算式を送って計算結果をクリップボードにコピーしてCalcを終了
        My.Computer.Keyboard.SendKeys("^v^c%{F4}", True)

        'Calcが計算終了するのを待つ
        'MsgBox("Ready ?", MsgBoxStyle.Question)
        While newProc.WaitForExit(500) = False
            SetForegroundWindow(newProc.MainWindowHandle)
            My.Computer.Keyboard.SendKeys("%{F4}", True)
        End While

        'クリップボードに文字列データがあるか確認して文字列データがあれば取得
        If Clipboard.ContainsText() Then res = Clipboard.GetText()

        CCalc = res
    End Function

End Class
id:rsc96074

回答ありがとうございます。試してみたら、実際、動作しました。ちょっと欲張りですが、Calcを使っていることが分からないように隠して使うのはやっぱり無理でしょうか。(^_^;

2009/11/07 01:42:33

その他の回答2件)

id:ohmix1 No.1

回答回数235ベストアンサー獲得回数14

ポイント10pt

[VB] Shell 関数で起動したプログラムの終了を待つ方法

http://ameblo.jp/archive-redo-blog/entry-10033356292.html

VB2008でもたぶんいけると思うのですが...

id:rsc96074

回答ありがとうございました。試してみましたが、駄目でした。

「1+1」を入力してボタンを押したらたら、「1+1=」と返してきました。MsgBoxを復活させたら、「2」を返してします。

2009/11/06 23:28:05
id:makeworld No.2

回答回数75ベストアンサー獲得回数23ここでベストアンサー

ポイント100pt

こんな感じでしょうか?

(なぜか%{F4}を取りこぼす場合があるようなので、%{F4}のリトライ処理を入れています)

Public Class Form1
    Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As Integer) As Integer

    'お約束のボタン
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        TextBox2.Text = CCalc(TextBox1.Text)
        TextBox1.Focus()
    End Sub

    'Windowsアクセサリの電卓Calcを呼出して計算結果を文字列で取得する関数
    Private Function CCalc(ByVal expr As String) As String
        Dim res As String = ""
        Dim newProc As Diagnostics.Process

        If Microsoft.VisualBasic.Right(expr, 1) <> "=" Then expr += "="
        'クリップボードに文字列をコピー
        Clipboard.SetDataObject(expr)

        'Windowsアクセサリの電卓Calcを呼出す
        newProc = Diagnostics.Process.Start("C:\WINDOWS\system32\Calc.exe")

        newProc.WaitForInputIdle(1000)
        SetForegroundWindow(newProc.MainWindowHandle)

        'SendKeysで計算式を送って計算結果をクリップボードにコピーしてCalcを終了
        My.Computer.Keyboard.SendKeys("^v^c%{F4}", True)

        'Calcが計算終了するのを待つ
        'MsgBox("Ready ?", MsgBoxStyle.Question)
        While newProc.WaitForExit(500) = False
            SetForegroundWindow(newProc.MainWindowHandle)
            My.Computer.Keyboard.SendKeys("%{F4}", True)
        End While

        'クリップボードに文字列データがあるか確認して文字列データがあれば取得
        If Clipboard.ContainsText() Then res = Clipboard.GetText()

        CCalc = res
    End Function

End Class
id:rsc96074

回答ありがとうございます。試してみたら、実際、動作しました。ちょっと欲張りですが、Calcを使っていることが分からないように隠して使うのはやっぱり無理でしょうか。(^_^;

2009/11/07 01:42:33
id:an_shoku_panman No.3

回答回数14ベストアンサー獲得回数0

ポイント10pt

まだまだVBは勉強中なので的外れだったら済みません。

 ↓が参考になれば幸いです。

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1015045...

id:rsc96074

回答ありがとうございます。うーん、ちょっと違うような。(^_^;

2009/11/07 07:51:39
  • id:rsc96074
    Public Class Form1
    'お約束のボタン
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    TextBox2.Text = CCalc(TextBox1.Text)
    TextBox1.Focus()
    End Sub

    'Windowsアクセサリの電卓Calcを呼出して計算結果を文字列で取得する関数
    Private Function CCalc(ByVal expr As String) As String
    Dim res As String = ""

    If Microsoft.VisualBasic.Right(expr, 1) <> "=" Then expr += "="
    'クリップボードに文字列をコピー
    Clipboard.SetDataObject(expr)

    'Windowsアクセサリの電卓Calcを呼出す
    Shell("Calc")
    'SendKeysで計算式を送って計算結果をクリップボードにコピーしてCalcを終了
    My.Computer.Keyboard.SendKeys("^v^c%{F4}", True)

    'Calcが計算終了するのを待つ
    MsgBox("Ready ?", MsgBoxStyle.Question)

    'クリップボードに文字列データがあるか確認して文字列データがあれば取得
    If Clipboard.ContainsText() Then res = Clipboard.GetText()

    CCalc = res
    End Function

    End Class
  • id:taknt
    禁断なんだ・・・
  • id:kn1967
    .NET の SendKeys.SendWait は禁断?
    http://msdn.microsoft.com/ja-jp/library/ms171548(VS.80).aspx
    http://msdn.microsoft.com/ja-jp/library/system.windows.forms.sendkeys.sendwait(VS.80).aspx
  • id:rsc96074
    >禁断
     電卓ソフトを作るのに、Calcを呼び出すのは反則かなと。(^_^;

  • id:HALSPECIAL
    HALSPECIAL 2009/11/07 09:40:47
    「SendKeys」は苦肉の策、最終手段と思っているのですが、
    私でしたらまずトライしてみるのは、Calc.exeのウィンドやテキストボックスのハンドルやクラス名を取得して直接操作できないだろうかということです。
    少し検索するとDelphiのサンプルがありました。
    FindWindow
    SetForegroundWindow
    FindWindowEx
    のAPIを叩けばいけるような気がします。
    http://www.wwlnk.com/boheme/delphi/tips/tec0440.htm
  • id:makeworld
    Calcは最小化起動をサポートしていないようなので、非表示は難しいと思います。

    プロジェクトの参照に「Microsoft.Jscript」と「Microsoft.Vsa」を追加して、Evaluateしてしまう方法もあります。
    Private Function CCalc2(ByVal expr As String) As String
    Dim ve As Microsoft.JScript.Vsa.VsaEngine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
    CCalc2 = Microsoft.JScript.Eval.JScriptEvaluate(expr, ve)
    End Function

    http://dobon.net/vb/dotnet/programing/eval.html
  • id:HALSPECIAL
    HALSPECIAL 2009/11/07 14:24:01
    SendKeys って、
    アクティブなウィンドウに対して行うものなので、
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    非表示では無理ですよね?
    http://msdn.microsoft.com/ja-jp/library/system.windows.forms.sendkeys(VS.80).aspx
    http://msdn.microsoft.com/ja-jp/library/fx2k26ca.aspx


    直接非表示での起動が駄目な場合でも、
    非表示自体はWIN32APIの
    ShowWindow hWnd, SW_HIDE
    でいけます。
  • id:rsc96074
    コメント有難うございます。おかげさまでうまくいきました。(^_^)
  • id:HALSPECIAL
    HALSPECIAL 2009/11/07 17:49:35
    VBA+WIN32API ですが、似たような事を考えている方がいらっしゃいました。
    http://www.excel.studio-kazu.jp/kw/20060409151555.html

この質問への反応(ブックマークコメント)

トラックバック

  • 無駄に電卓を利用して計算値を取得してみる &lt;&lt;下書き中&gt;&gt; 【Visual BASIC 2008】で、禁断のCalc呼出し電卓プログラムを作りました。下記コードでは、MsgBoxを使って、Calcが終了するのを
  • 簡易関数電卓 Visual Basic 2010  Visual Basic の WebBrowser コントロールを使って、簡単な関数電卓を作ってみました。 JScript の eval 関数を使ってちょっと手抜きしてみました。(^_^;  もともとは
「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません