【最大10000ポイント】当たる!!質問投稿キャンペーン!

vbからshellを使って、cで書いた実行ファイルを起動しています。

その起動した実行ファイルの表示位置を指定したいのですが、どうしたらよいのかわかりません。
もしかしてshellでは無理なのでしょうか?

それともcのコードに変更を加えるべきなのでしょうか?
cの方はOpenCVで、ウィンドウ生成が「cvNamedWindow(windowName名前)」で行っているので、
これもどう位置を指定したらよいのかわかりません。。。

どなたかわかる方よろしくお願いします。

A 回答 (1件)

お礼率 14% が気になりますのでヒントだけ。


ウィンドウのハンドルを取得して、そのハンドルを使って、SetWindowPos API で位置と
サイズを指定して下さい。

# 回答には一言お礼を言いましょう。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
ヒントを元に頑張ってみます♪

お礼日時:2010/11/27 16:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QVB6.0 SHELLで起動したプログラムを終了さしたいのですが

(1)メインプログラムから電卓を実行します。
 Shell("C:\WINNT\system32\CALC.EXE", 1)
(2)メインプログラムで電卓を終了させるにわ、どうすればいいのですか
 教えてください。

Aベストアンサー

(今会社なのですが、、、)サンプルありました。奥深く眠ってました。
Microsoftの終了方法と、定数が違いますが、こちらでも終了ができます。


コメントを見たら、処理の流れがわかると思いますが、処理の流れを記します。

Shellで電卓を起動します。Shell関数は起動したアプリのプロセスIDを返します。
次に Call EnumWindows(AddressOf EnumWinProc, 0&)を実行します。
これはたった一文で、FOR文/DO~LOOP文を使用してませんが、EnumWinProc関数内を何度も実行します。実行回数はWindowsに存在するハンドルの数だけ実行されます。
そしてその関数内で電卓のプロセスと同じハンドルを探し、電卓に終了の命令を送ってます。



EnumWinProc内を詳しく説明します。
GetParentが'0'ゼロの時、未処理としています。

これは何を意味するかというと、フォームだけでなく、フォームの中に存在するボタン、リストボックス、ラベル、それぞれのコントロールにハンドルが存在します。
しかしフォームとその中のコントロールには親子の関係があります。
GetParent(子のハンドル)の時 → '0以外'の数値を返します。基本的にフォーム(親)のハンドルのを返します。
GetParent(フォームのハンドル)の時 → '0'を返します。親が存在しないためです。

電卓にも多くのボタンが存在してます。そのボタンのハンドルはチェックする必要がないのでGoto文で未処理にさせています。必要なのは電卓本体が必要で、GetParentで0を返すものが、チェックの候補となるわけです。

あとは電卓のプロセスと比較し、一致するハンドルを取得するだけです。



Option Explicit

' ウィンドウのプロセスIDとスレッドIDを取得する関数の宣言
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" _
  (ByVal hwnd As Long, lpdwProcessId As Long) As Long

'親ハンドルを取得する関数の宣言
Private Declare Function GetParent Lib "user32" _
  (ByVal hwnd As Long) As Long

'ウィンドウを列挙する関数の宣言
Public Declare Function EnumWindows Lib "user32" _
  (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

'ウィンドウにメッセージ定数を送る関数の宣言
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
  (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long

Public Const WM_CLOSE = &H10

'見つかったウィンドウハンドル
Private FindWinWnd As Long
'探すべきプロセス
Private FindPrs   As Long


Sub Main()
  Dim lngSts As Long

  '初期化を行う
  FindWinWnd = 0
  FindPrs = 0

  'とりあえず電卓を起動と同時に、電卓のプロセスを得る
  FindPrs = Shell("Calc.exe")
  
  'プロセス=0のとき起動失敗
  If FindPrs = 0 Then
    MsgBox "電卓の起動失敗"
    GoTo PGMEND
  End If
  
  'Windowsに存在する全部のハンドルから、電卓のプロセスの一緒のハンドルを探す
  Call EnumWindows(AddressOf EnumWinProc, 0&)
  
  '電卓を終了します。
  If (FindWinWnd <> 0&) Then
    MsgBox "電卓が見つかりませた。終了します。"
    Call SendMessage(FindWinWnd, WM_CLOSE, 0&, 0&)
  Else
    MsgBox "電卓が見つかりませんでした。"
  End If
  
PGMEND:
End Sub

'Windowsの全ハンドルを得ることができる関数
'内部処理は、
'(1)指定のプロセスを探す
'(2)見つかったプロセスのハンドルを記憶
Public Function EnumWinProc(ByVal hwnd As Long, lParam As Long) As Boolean
  Dim lngTrd As Long 'スレッド
  Dim lngPrs As Long 'プロセス
  
  'Trueの間は、Windowsに存在するハンドルを最後まで取得しようとする
  EnumWinProc = True
  
  '子ウィンドウは未処理
  If Not (GetParent(ByVal hwnd) = 0) Then GoTo PGMEND
  
  'スレッドとプロセスを取得する
  lngTrd = GetWindowThreadProcessId(hwnd, lngPrs)
  
  '同じプロセスだとしたら
  If lngPrs = FindPrs Then
    '取得してきたハンドルを記憶
    FindWinWnd = hwnd
    'これ以上のハンドルは取得しないでもいいので、Falseをセット
    EnumWinProc = False
  End If
  
PGMEND:
End Function

(今会社なのですが、、、)サンプルありました。奥深く眠ってました。
Microsoftの終了方法と、定数が違いますが、こちらでも終了ができます。


コメントを見たら、処理の流れがわかると思いますが、処理の流れを記します。

Shellで電卓を起動します。Shell関数は起動したアプリのプロセスIDを返します。
次に Call EnumWindows(AddressOf EnumWinProc, 0&)を実行します。
これはたった一文で、FOR文/DO~LOOP文を使用してませんが、EnumWinProc関数内を何度も実行します。実行回数はWindowsに存在する...続きを読む

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

QDoEvents関数って何?

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そこで「EXCEL VBA パーフェクトマスター」という本を見たら

for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
DoEvents
next i
unload userform1
と入力すれば解決することがわかりました。

しかし「DoEvents」についてあまり詳しく書いていなかったのでDoEvents関数をヘルプで見ると、
「発生したイベントがオペレーティング システムによって処理されるように、プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。」

と書いてあるのですが正直、書いてあることがよくわかりません。

どなたかDoEvents関数について、
もう少しわかりやすく教えていただけませんか。
それから、最初に書いたコードで実行すると
ユーザーフォームの背景が真っ白になってしまう原因も
教えていただけませんか?

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

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そ...続きを読む

Aベストアンサー

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
    DoEvents
    Cells(i,1) = ""
  Next i
End Sub

Private Sub CommandButton2_Click()
  MsgBox "hoge"
End Sub

っていうフォームのコードがあった場合、
DoEvents を入れることによって、ループ中にユーザーがCommandButton2 を押すことによって CommandButton2 のクリック イベントも動いちゃいます。
CommandButton1 のクリック イベントではループの前に
CommandButton1.Enabled = False
CommandButton2.Enabled = False
を書いてフォーム上の CommandButton を無効にしておき、ループが終わったら
CommandButton1.Enabled = True
CommandButton2.Enabled = True
と書いて CommandButton を有効に戻してください。

これを工夫すれば、CommandButton2 で CommandButton1 のループを途中キャンセルする処理もすることができます。

Private Canceled As Boolean

Private Sub CommandButton1_Click()

  CommandButton2.Enabled = False

  Dim i As Long
  For i = 1 To 50000
    DoEvents

    If Canceled = True Then
      MsgBox "キャンセルしました"
      Exit Sub
    End If

    Cells(i, 1).Value = ""
  Next i
End Sub

Private CommandButton2_Click()
  Canceled = True
End Sub



コードの行頭にあるスペースは見易さのために全角スペースで作成していますので、これをこのままコピペするとエラーになるかもしれません。
コピペするなら行頭の全角スペースを半角スペースに直してください。

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
...続きを読む

QエクセルVBAでマウスの操作はできますか?

エクセルVBAで、マウスのポインタを画面の中央にもってきたり、左クリックを押すという操作をさせたいのですが、無理ですか?
sendkeyなんでしょうか…。画面の中央にマウスのポインタを持ってくるというのも、使用しているモニタによって座標が違うような気もしますが…。不勉強ですいません。
VBAの本を見ても、VBAのヘルプを見てもわかりませんでした。もともと無理な話なのでしょうか?
教えて下さい。よろしくお願い致します。

Aベストアンサー

こんにちは。

いただいた内容は、OKWave の当初質問からは独立した新しい内容と思います。UWSC 自身、開発者によるサポート掲示板をコミュニケーション・ツールとして提供していますので、そちらに投函するのがよいでしょう。(参考URLに念のため URL を記録しておきました。)

OKWave への質問で当初得られたかった目的が達成されたとお考えであれば、ひとまず質問自身は区切りを付けたほうがよいと回答者は考えます。

(回答者のコメント)

記録機能で得られたプログラムは KBD, MMV, ACW, BTN の四つの低レベルウインドウ関数で構成されているため、一つ一つファイルとして格納していくとファイル数があっという間に増えていきます。

Launch Menu (ランチメニュー) から一つづつ起動を指示するアプローチはすでに気付かれたように 10 ファイルしか登録できないために具合が悪いです。かわりに、UWSC スクリプトの起動を指示するスクリプトを UWSC で書くことができます。

起動の指示には、EXEC による UWSC.exe プロセスを新規に作成する方法、CALL による方法、それぞれのファイルを procedure/function として括りだして一つのファイルにまとめ、そのファイルで該当 procedure/function を呼びだす方法など、いくつかアプローチがあります。

参考URL:http://www3.bigcosmic.com/board/s/board.cgi?id=umiumi

こんにちは。

いただいた内容は、OKWave の当初質問からは独立した新しい内容と思います。UWSC 自身、開発者によるサポート掲示板をコミュニケーション・ツールとして提供していますので、そちらに投函するのがよいでしょう。(参考URLに念のため URL を記録しておきました。)

OKWave への質問で当初得られたかった目的が達成されたとお考えであれば、ひとまず質問自身は区切りを付けたほうがよいと回答者は考えます。

(回答者のコメント)

記録機能で得られたプログラムは KBD, MMV, ACW, BTN の四つ...続きを読む

QVBAにおいて、ファイルの移動にMoveFileを使っていますが、

VBAにおいて、ファイルの移動にMoveFileを使っていますが、
移動先に移動元と同じ名前が存在する時、エラーが発生してしま
います。これを回避して、移動することはできないのでしょうか。
(移動先に移動元と同じ名前が存在しても、上書きで移動。)
また、MoveFile以外の方法はないのでしょうか。
教えて下さい。

Aベストアンサー

こんにちは
#1のHirorin_20さんと同意見です。

方法1:
dir関数で、同名Fileのチェック
あれば削除

方法2:
On Error Resume Next
Kill パス&ファイル名
On Error GoTo 0

ただし、どちらの場合でも、対象のファイルが開いているなど、Windowsがロックしている場合には対応できません。

Qエクセル マクロで指定フォルダを開く

エクセルにて
指定フォルダを開く、マクロがあれば教えて頂けないでしょうか。
よろしくお願いいたします。

Aベストアンサー

こんにちは。

こういうものですか?
開くフォルダを変えたいときは targ に与えるパスを変更します。

Sub OpenFolders()
Dim targ As String
targ = "C:\"
Shell "C:\Windows\Explorer.exe " & targ, vbNormalFocus
End Sub

QVBAで任意のウインドウのサイズを変更する方法

Excel VBAを使ってIEなどのプログラムのクライアント領域の
ウインドウのサイズを指定・変更したいと考えています。

http://www.excel-vba.net/excel-api-020.html

このページのコードを使ってサイズの取得だけはできるようになりました。

次に設定を行いたいのですが

http://home.att.ne.jp/zeta/gen/excel/c04p58.htm

このページにあるように


Dim window1 As Window
Set window1 = Windows("Google - Internet Explorer") 'アプリケーションウィンドウを対象
window1.WindowState = xlNormal '通常表示に設定します。
window1.Width = 800 'ウィンドウ幅を800に設定
window1.Height = 300 'ウィンドウの高さを300に設定



とやってみましたが
インデックスが有効範囲にありません
というエラーが出てしまいます。

どうすれば良いでしょうか?

あと気になっているのですが
幅及び高さの単位はポイントです。(ピクセルでは無いので注意して下さい)。
と書かれてありますが、
ピクセルからポイントへはどのように換算すれば良いのでしょうか?

Excel VBAを使ってIEなどのプログラムのクライアント領域の
ウインドウのサイズを指定・変更したいと考えています。

http://www.excel-vba.net/excel-api-020.html

このページのコードを使ってサイズの取得だけはできるようになりました。

次に設定を行いたいのですが

http://home.att.ne.jp/zeta/gen/excel/c04p58.htm

このページにあるように


Dim window1 As Window
Set window1 = Windows("Google - Internet Explorer") 'アプリケーションウィンドウを対象
...続きを読む

Aベストアンサー

2つ目のリンクの説明はExcel内のウィンドウを扱うものですから、質問の件の参考にはなりません。
1つ目のリンクの例のように、WindowsAPIを呼び出す必要あります。
WindowsAPIはC言語の関数の体裁をしていますので、理解するには若干のC言語の知識が必要です。

ウィンドウのサイズ変更は SetWindowPos 関数でできました。関数の説明はここにあります。
https://msdn.microsoft.com/ja-jp/library/cc411206.aspx

-----------------------------------------------------
Option Explicit

'ウィンドウ位置を維持する
Public Const SWP_NOMOVE = &H2&
'ウィンドウのZオーダーを維持する
Public Const SWP_NOZORDER = &H4&

Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String _
) As Long

Private Declare Function SetWindowPos Lib "user32.dll" ( _
ByVal hWnd As Long, _
ByVal hWndInsetAfter As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal cx As Long, _
ByVal cy As Long, _
ByVal uFlags As Long _
) As Long

'メモ帳のウィンドウサイズを変更するサンプル
Public Sub ChangeRect()
Dim hWnd As Long
hWnd = FindWindow(vbNullString, "無題 - メモ帳")

Call SetWindowPos(hWnd, -1, -1, -1, 400, 300, SWP_NOMOVE Or SWP_NOZORDER)
End Sub

2つ目のリンクの説明はExcel内のウィンドウを扱うものですから、質問の件の参考にはなりません。
1つ目のリンクの例のように、WindowsAPIを呼び出す必要あります。
WindowsAPIはC言語の関数の体裁をしていますので、理解するには若干のC言語の知識が必要です。

ウィンドウのサイズ変更は SetWindowPos 関数でできました。関数の説明はここにあります。
https://msdn.microsoft.com/ja-jp/library/cc411206.aspx

-----------------------------------------------------
Option Explicit

'ウィンドウ位置を維...続きを読む


人気Q&Aランキング