博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#通过WIN32 API实现嵌入程序窗体
阅读量:6247 次
发布时间:2019-06-22

本文共 4478 字,大约阅读时间需要 14 分钟。

本文实例讲述了C#通过WIN32 API实现嵌入程序窗体的方法,分享给大家供大家参考。具体如下:

这是一个不使用COM,而是通过WIN32 API实现的示例, 它把写字板程序嵌在了自己的一个面板中。

这么做可能没有实际意义, 因为两个程序之前没有进行有价值的交互, 这里仅仅是为了演示这么做到, 以下是详细注释过的主要源代码。

我们把它封装到一个类中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Diagnostics;
using
System.Runtime.InteropServices;
using
System.Windows.Forms;
namespace
System.Windows.Forms
{
  
class
InsertWindow
  
{
    
/// <summary>
    
/// 将程序嵌入窗体
    
/// </summary>
    
/// <param name="pW">容器</param>
    
/// <param name="appname">程序名</param>
    
public
InsertWindow(Panel pW,
string
appname)
    
{
      
this
.pan = pW;
      
this
.LoadEvent(appname);
      
pane();
    
}
    
~InsertWindow()
    
{
      
if
(m_innerProcess!=
null
)
      
{
        
m_innerProcess.Dispose();
      
}
    
}
    
#region 函数和变量声明
    
/*
    
* 声明 Win32 API
    
*/
    
[DllImport(
"user32.dll"
)]
    
static
extern
IntPtr SetParent(IntPtr hWndChild,
      
IntPtr hWndNewParent
    
);
    
[DllImport(
"user32.dll"
)]
    
static
extern
Int32 GetWindowLong(IntPtr hWnd,
      
Int32 nIndex
    
);
    
[DllImport(
"user32.dll"
)]
    
static
extern
Int32 SetWindowLong(IntPtr hWnd,
      
Int32 nIndex,
      
Int32 dwNewLong
    
);
    
[DllImport(
"user32.dll"
)]
    
static
extern
Int32 SetWindowPos(IntPtr hWnd,
      
IntPtr hWndInsertAfter,
      
Int32 X,
      
Int32 Y,
      
Int32 cx,
      
Int32 cy,
      
UInt32 uFlags
    
);
    
/*
     
* 定义 Win32 常数
     
*/
    
const
Int32 GWL_STYLE = -16;
    
const
Int32 WS_BORDER = (Int32)0x00800000L;
    
const
Int32 WS_THICKFRAME = (Int32)0x00040000L;
    
const
Int32 SWP_NOMOVE = 0x0002;
    
const
Int32 SWP_NOSIZE = 0x0001;
    
const
Int32 SWP_NOZORDER = 0x0004;
    
const
Int32 SWP_FRAMECHANGED = 0x0020;
    
const
Int32 SW_MAXIMIZE = 3;
    
IntPtr HWND_NOTOPMOST =
new
IntPtr(-2);
    
// 目标应用程序的进程.
    
Process m_innerProcess =
null
;
    
#endregion
    
#region 容器
    
private
Panel pan =
null
;
    
public
Panel panel1
    
{
      
set
{ pan = value; }
      
get
{
return
pan; }
    
}
    
private
void
pane()
    
{
      
panel1.Anchor = AnchorStyles.Left | AnchorStyles.Top |
       
AnchorStyles.Right | AnchorStyles.Bottom;
      
panel1.Resize +=
new
EventHandler(panel1_Resize);
    
}
    
private
void
panel1_Resize(
object
sender, EventArgs e)
    
{
      
// 设置目标应用程序的窗体样式.
      
IntPtr innerWnd = m_innerProcess.MainWindowHandle;
      
SetWindowPos(innerWnd, IntPtr.Zero, 0, 0,
        
panel1.ClientSize.Width, panel1.ClientSize.Height,
        
SWP_NOZORDER);
    
}
    
#endregion
    
#region 相应事件
    
private
void
LoadEvent(
string
appFile)
    
{
      
// 启动目标应用程序.
      
m_innerProcess = Process.Start(appFile);
      
m_innerProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
//隐藏
      
// 等待, 直到那个程序已经完全启动. 
      
m_innerProcess.WaitForInputIdle();
      
// 目标应用程序的主窗体.
      
IntPtr innerWnd = m_innerProcess.MainWindowHandle;
      
// 设置目标应用程序的主窗体的父亲(为我们的窗体).
      
SetParent(innerWnd, panel1.Handle);
      
// 除去窗体边框.
      
Int32 wndStyle = GetWindowLong(innerWnd, GWL_STYLE);
      
wndStyle &= ~WS_BORDER;
      
wndStyle &= ~WS_THICKFRAME;
      
SetWindowLong(innerWnd, GWL_STYLE, wndStyle);
      
SetWindowPos(innerWnd, IntPtr.Zero, 0, 0, 0, 0,
        
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
      
// 在Resize事件中更新目标应用程序的窗体尺寸.
      
panel1_Resize(panel1,
null
);
    
}
#endregion
  
}
}

然后在窗口的load事件中加入详细代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.Runtime;
using
System.Runtime.InteropServices;
using
System.Diagnostics;
namespace
将程序窗口嵌入到任务栏中
{
  
public
partial
class
Form1 : Form
  
{
    
private
System.Windows.Forms.Panel panel1;
    
public
Form1()
    
{
      
InitializeComponent();
      
this
.panel1 =
new
System.Windows.Forms.Panel();
      
this
.SuspendLayout();
      
// 
      
// panel1
      
// 
      
this
.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
      
this
.panel1.Location =
new
System.Drawing.Point(0, 0);
      
this
.panel1.Name =
"panel1"
;
      
this
.panel1.Size =
new
System.Drawing.Size(292, 273);
      
this
.panel1.TabIndex = 0;
      
this
.Controls.Add(
this
.panel1);
      
Load +=
new
EventHandler(Form1_Load);
    
}
    
private
void
Form1_Load(
object
sender, EventArgs e)
    
{
      
//string sPath = Environment.GetEnvironmentVariable("windir");//获取系统变量 windir(windows) 
      
const
string
appFile =
        
"C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe"
;
      
InsertWindow insertwin =
new
InsertWindow(panel1, appFile);
    
}
  
}
}

希望本文所述对大家的C#程序设计有所帮助。

 

http://www.jb51.net/article/55821.htm

转载地址:http://dylia.baihongyu.com/

你可能感兴趣的文章
memcache与一致性HASH算法
查看>>
正则表达式引发的血案
查看>>
机器学习中的概率模型和概率密度估计方法及VAE生成式模型详解之三(第1章)...
查看>>
Ubuntu学习之grep
查看>>
远距离混合语音识别方法的研究
查看>>
Java线程实现与安全
查看>>
分享一款意想不到好用的手机PDF编辑器
查看>>
Linux常用文件权限以及修改方法
查看>>
win10系统必做优化,让你的电脑告别卡顿,运行速度至少提升20%
查看>>
shell——read详解
查看>>
我的友情链接
查看>>
大数据教程(1.8):Linux之SSH免密登录配置
查看>>
ftp passive mode
查看>>
安装问题Error: dl failure on line 864
查看>>
oracle表分区详解(按天、按月、按年等)
查看>>
yum update upgrade区别
查看>>
angularjs select 三级联动
查看>>
BufferedReader指定编码及乱码问题解决
查看>>
Zabbix3.0监控Centos 6配置
查看>>
解决MAC下svn run cleanup interrupted错误
查看>>