- PR -

C#でForm内で他アプリケーションを使う方法

1
投稿者投稿内容
knights
会議室デビュー日: 2003/03/16
投稿数: 8
投稿日時: 2003-08-04 23:28
自作したForm内で他のアプリケーションを実行する方法はないですか?

うまくいえないのですが、IEでpdfを開くとIEのなかにAcrobatが開くような感じにしたいんですけど。

また、C#ではなくMFCでのやり方でも構いません。

よろしくお願いします。
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-08-05 01:03
こんばんは、meiです。

引用:

knightsさんの書き込み (2003-08-04 23:28) より:
自作したForm内で他のアプリケーションを実行する方法はないですか?



実行したい「他のアプリケーション」次第という回答になります。
呼び出すアプリケーションがActiveXコントロール化されていれば可能ですが、
そうで無ければ、ちょっと厳しいと思います。
#起動だけなら出来るでしょうが、コントロール出来ないと・・・

因みに例で挙がってるAcrobatは実行可能です。
↓ツールバーのOpenボタンでPDFファイルをFormに表示する簡単な例

コード:
// Adobe Acrobat Control for ActiveXへの参照が必要

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

public class Form1 : Form {
	private AxPdfLib.AxPdf axPdf1;
	private ToolBar toolBar1;
	private ToolBarButton toolBarButton1;
	private Container components = null;

	public Form1() {
		InitializeComponent();
	}

	protected override void Dispose( bool disposing ) {
		if( disposing ) {
			if (components != null) {
				components.Dispose();
			}
		}
		base.Dispose( disposing );
	}

	private void InitializeComponent() {
		System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
		this.axPdf1 = new AxPdfLib.AxPdf();
		this.toolBar1 = new ToolBar();
		this.toolBarButton1 = new ToolBarButton();
		((ISupportInitialize)(this.axPdf1)).BeginInit();
		this.SuspendLayout();
		// 
		// axPdf1
		// 
		this.axPdf1.Anchor = ((AnchorStyles)((((AnchorStyles.Top | AnchorStyles.Bottom) 
			| AnchorStyles.Left) 
			| AnchorStyles.Right)));
		this.axPdf1.Enabled = true;
		this.axPdf1.Location = new Point(8, 48);
		this.axPdf1.Name = "axPdf1";
		this.axPdf1.OcxState = ((AxHost.State)(resources.GetObject("axPdf1.OcxState")));
		this.axPdf1.Size = new Size(616, 392);
		this.axPdf1.TabIndex = 0;
		// 
		// toolBar1
		// 
		this.toolBar1.BorderStyle = BorderStyle.Fixed3D;
		this.toolBar1.Buttons.AddRange(new ToolBarButton[] {this.toolBarButton1});
		this.toolBar1.ButtonSize = new Size(32, 32);
		this.toolBar1.DropDownArrows = true;
		this.toolBar1.Location = new Point(0, 0);
		this.toolBar1.Name = "toolBar1";
		this.toolBar1.ShowToolTips = true;
		this.toolBar1.Size = new Size(632, 40);
		this.toolBar1.TabIndex = 1;
		this.toolBar1.ButtonClick += new ToolBarButtonClickEventHandler(this.toolBar1_ButtonClick);
		// 
		// toolBarButton1
		// 
		this.toolBarButton1.Tag = "Open";
		this.toolBarButton1.Text = "Open";
		// 
		// Form1
		// 
		this.AutoScaleBaseSize = new Size(5, 12);
		this.ClientSize = new Size(632, 446);
		this.Controls.Add(this.toolBar1);
		this.Controls.Add(this.axPdf1);
		this.Name = "Form1";
		this.Text = "Form1";
		((ISupportInitialize)(this.axPdf1)).EndInit();
		this.ResumeLayout(false);

	}
	[STAThread]
	static void Main() {
		Application.Run(new Form1());
	}

	private void toolBar1_ButtonClick(object sender, ToolBarButtonClickEventArgs e) {
		if (e.Button.Tag == "Open") {
			OpenFileDialog dlg = new OpenFileDialog();
			dlg.Filter = "pdf files (*.pdf)|*.pdf|All files (*.*)|*.*";
			if (dlg.ShowDialog() == DialogResult.OK) {
				axPdf1.LoadFile(dlg.FileName);
			}
		}
	}
}



knights
会議室デビュー日: 2003/03/16
投稿数: 8
投稿日時: 2003-08-05 19:33
回答ありがとうございます。

以下の点でもう一度質問があります。

引用:
meiさんの書き込み (2003-08-05 01:03) より:
呼び出すアプリケーションがActiveXコントロール化されていれば可能ですが、


ActiveX化されているかどうかはどうやって調べれるのでしょうか?

引用:
#起動だけなら出来るでしょうが、コントロール出来ないと・・・


Form内で起動ができるということですか?
できるようでしたら、どのようにしたしたらできるか教えていただけませんか?

よろしくお願いします。
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-08-05 20:39
こんばんは、meiです。

引用:

knightsさんの書き込み (2003-08-05 19:33) より:
ActiveX化されているかどうかはどうやって調べれるのでしょうか?


VisualStudioのメニューから、
プロジェクト(P)->参照の追加(R)でダイアログを表示して、
COMタブを開けば調べられると思います。
ただし、使い方のドキュメント等はおそらく無いと思いますので、
関数名で機能を想像しながらの試行錯誤になると思います。

引用:

Form内で起動ができるということですか?
できるようでしたら、どのようにしたしたらできるか教えていただけませんか?


Form内で起動するというより、一緒に動作するって感じです。
例えば、デスクトップアクセサリーで、マスコットが他のアプリケーションのウィンドウに乗っているようなのがあります。

私は実際に作ったことはないので想像ですが、相手アプリケーションのウィンドウメッセージをフックしたりするのではないでしょうか。
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-08-05 22:45
試しにフックを実験してみましたが、上手くいきませんでした。
C#ではなく、C/C++でDLLを作る必要があるかも知れません。

↓C#のLibraryとして以下のようにやってみたけど、失敗・・・
コード:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class MyHookClass {
const int WM_MOVE = 0x0003;
const int WH_CALLWNDPROC = 4;
delegate IntPtr CallBack(int id, IntPtr wParam, IntPtr lParam);
private static IntPtr hhk;
private static Form form;

[DllImport("user32.dll")]
public extern static IntPtr SetWindowsHookEx(int idHook, IntPtr lpfn, IntPtr hMod, long dwThreadId);
[DllImport("user32.dll")]
public extern static IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
public extern static long GetLastError();

private static IntPtr MyCallBack(int id, IntPtr wParam, IntPtr lParam) {
if (id > 0) {
CWPSTRUCT cwp = (CWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPSTRUCT));
// フックウィンドウが移動したら
if (cwp.message == WM_MOVE) {
int x = (int)cwp.lParam & 0x0000ffff;
int y = (int)cwp.lParam >> 16;
form.Text = String.Format("x={0}, y={1}", x, y);
}
}
return CallNextHookEx(hhk, id, wParam, lParam);
}

// parent : アプリケーションフォーム
// hwnd : フックするウィンドウハンドル
public static bool Hook(Form parent, IntPtr hwnd) {
form = parent;
CallBack call = new CallBack(MyCallBack);
// hhkがNULLになってしまう・・・
hhk = SetWindowsHookEx(WH_CALLWNDPROC,
call.Method.MethodHandle.GetFunctionPointer(), hwnd, 0);
// GetLastErrorの戻り値もおかしい・・・
long n = GetLastError();
return hhk != IntPtr.Zero;
}
}

public struct CWPSTRUCT {
public IntPtr lParam;
public IntPtr wParam;
public uint message;
public IntPtr hwnd;
}




[ メッセージ編集済み 編集者: mei 編集日時 2003-08-05 22:54 ]
knights
会議室デビュー日: 2003/03/16
投稿数: 8
投稿日時: 2003-08-06 01:05
引用:
C#ではなく、C/C++でDLLを作る必要があるかも知れません。


C/C++はあまり使ったことがないのでDLLを作る手間を考えたら、他アプリケーションに頼らず、必要な機能だけ自分で実装した方が早そうですね。多分・・・

実験までしていただき、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)