C#通过WIN32 API实现嵌入程序窗体

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

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

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

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

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事件中加入详细代码如下:

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#程序设计有所帮助。

(0)

相关推荐

  • C#基于TimeSpan实现倒计时效果的方法

    本文实例展示了C#基于TimeSpan实现倒计时效果的方法,比较实用的功能,对于初学者来说有一定的学习参考价值.具体实现方法如下: 示例代码如下: using System; using System.Threading; namespace ConsoleApplication29 { class Program { static void Main(string[] args) { try { DateTime _timeEnd = DateTime.Now.AddSeconds(62);

  • c#用Treeview实现FolderBrowerDialog 和动态获取系统图标(运用了Win32 dll类库)

    事情是这样子的.我需要做一个下面的东东: 这个不难啊,然后就用FolderBrowerDialog这个神器,嗯 还不错,刚开始客户用了也很喜欢. 可是过了一段时间之后,客户说 要屏蔽右键功能,他不想让其他通过右键能打开或浏览文件夹,如下面 红色要给屏蔽. 我一开始以为只是一个参数问题,就爽快的答应了客户咯.可是啊后来找啊找 找到天荒地老也木有找到...放弃了,然后改用了TreeView..结果,版本出来了,先截图: 好吧,确实很丑哦.. 复制代码 代码如下: public MyDirectory

  • C#实现的Win32控制台线程计时器功能示例

    本文实例讲述了C#实现的Win32控制台线程计时器功能.分享给大家供大家参考,具体如下: 在C#中提供了三种类型的计时器: 1.基于 Windows 的标准计时器(System.Windows.Forms.Timer) 2.基于服务器的计时器(System.Timers.Timer) 3.线程计时器(System.Threading.Timer) 一.基于 Windows 的标准计时器(System.Windows.Forms.Timer) 首先注意一点就是:Windows 计时器是为单线程环境

  • c#使用win32api实现获取光标位置

    方法一:需要调用win32api,winform.wpf通用 [DllImport("user32.dll")] public static extern bool GetCursorPos(out POINT lpPoint); [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; public POINT(int x, int y) { this.X = x;

  • C#实现windows form倒计时的方法

    本文实例讲述了C#实现windows form倒计时的方法.分享给大家供大家参考.具体实现方法如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace date { public partial cl

  • c#编写的番茄钟倒计时器代码

    恩  主要大家可以看下思路吧  图形界面里 除了图标和音乐两个资源 别的都是代码. 时间没有用timer组件 是自创的Time类在一个线程中进行的倒计时.  对于导出记录 创建了一个Record类  别的就没什么了  .... Program.cs 复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace 番茄钟 {   

  • C#利用win32 Api 修改本地系统时间、获取硬盘序列号

    C#利用win32 Api 修改本地系统时间.获取硬盘序列号,可以用于软件注册机制的编写! 复制代码 代码如下: using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace Fengyun {     public class Win32     {         #region 修改本地系统时间         [DllIm

  • C#结合JavaScript实现秒杀倒计时的方法

    本文实例讲述了C#结合JavaScript实现秒杀倒计时的方法.分享给大家供大家参考.具体如下: 最近做个秒杀活动,要用到倒计时.要求每周三上午10:00开始倒计时 private string Dtime() { byte tempB = (byte)DateTime.Now.DayOfWeek; byte dayByte = (byte)DayOfWeek.Wednesday; DateTime wednesdayNow = DateTime.Now.AddDays(dayByte - te

  • C#通过WIN32 API实现嵌入程序窗体

    本文实例讲述了C#通过WIN32 API实现嵌入程序窗体的方法,分享给大家供大家参考.具体如下: 这是一个不使用COM,而是通过WIN32 API实现的示例, 它把写字板程序嵌在了自己的一个面板中. 这么做可能没有实际意义, 因为两个程序之前没有进行有价值的交互, 这里仅仅是为了演示这么做到, 以下是详细注释过的主要源代码. 我们把它封装到一个类中: using System; using System.Collections.Generic; using System.Linq; using

  • C++获得其他程序窗体控件中信息的方法

    本文实例讲述了C++获得其他程序窗体控件中信息的方法.分享给大家供大家参考.具体分析如下: 这里演示了获得其他程序窗体控件信息的方法, 用FindWindow API找到文本框句柄,用SendMessage(WM_GETTEXT)获得文本 #include <windows.h> BOOL CALLBACK EnumChildProc(HWND hWnd,LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev

  • win32 api实现2048游戏示例

    自学的win32编程,写了一个win32 API版2048,自己摸索着写的,按上下左右箭头开始游戏 复制代码 代码如下: #include <windows.h>#include <stdlib.h>#include <stdio.h>#include <ctime>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//全局操作数组int arr[4][4] = { { 0, 0, 0, 0 }, {

  • python3应用windows api对后台程序窗口及桌面截图并保存的方法

    python的版本及依赖的库的安装 #版本python 3.7.1 pip install pywin32==224 pip install numpy==1.15.3 pip install opencv-python==3.4.2.16 pip install opencv-contrib-python==3.4.2.16 pip install Pillow-PIL==0.1.dev0 对后台窗口截图 #对后台窗口截图 import win32gui, win32ui, win32con

  • 微信小程序api列表汇总包括网络API,媒体API,文件API ,微信小程序支付流程,位置API,界面API等

    1)网络 API 列表: wx.request 发起网络请求 wx.uploadFile 上传文件 wx.downloadFile 下载文件 wx.connectSocket 创建 WebSocket 连接 wx.onSocketOpen 监听 WebSocket 打开 wx.onSocketError 监听 WebSocket 错误 wx.sendSocketMessage 发送 WebSocket 消息 wx.onSocketMessage 接受 WebSocket 消息 wx.closeS

  • c#之利用API函数实现动画窗体的方法详解

    这里主要利用API函数Animate Window实现窗体左右,上下,扩展,淡入滑动或滚动动画效果,步骤如下:1.新建窗体,使用2个GroupBox控件.2.在控件1中添加2个RadioButton控件,并设置Text分别为"滚动窗体","滑动窗体",并使前者Checked设置为True.3.在空间2中添加6个按钮,Text分别为"自左向右动画","自右向左动画","自上向下动画","自下向上动画

  • VC++实现通过API来查看程序错误信息的方法

    本文实例介绍了VC++通过API查看错误信息的方法,可以在遇到错误的时候,将显示出错信息并退出处理,具体的实现代码如下: if((m_hBitMap=(HBITMAP)::LoadImage(NULL,filepath,IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE))==NULL) { LPVOID lpMsgBuf; DWORD dw = ::GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOC

  • android开发教程之获取使用当前api的应用程序名称

    比如要获取打开摄像头的应用程序名称,只需要在frameworks/base/core/android/hardware/Camera.java中open()方法中加上如下代码就可以了. 复制代码 代码如下: Application application = ActivityThread.currentApplication();if (application != null) {    String packageName = application.getPackageName();   

  • C#传值方式实现不同程序窗体间通信实例

    当Form2的AcceptChange按钮按下,需要修改Form1中ListBox中相应列的值,因此可以考虑同时将Form1中的ListBox控件当参数也传入Form2,所有修改工作都在Form2中完成,根据这个思路,Form2代码如下: 复制代码 代码如下: publicpartial class Form2 : Form         {             private string text;             private ListBox lb;            

随机推荐