zoukankan      html  css  js  c++  java
  • 在winform上内嵌入其它的程序

    这段代码很有意义,用于把一个程序的界面嵌入到我们自己程序的某个指定窗体上.

    比如在某个项目里,我需要把基恩士的激光扫描轮廓显示给客户看,但是激光的DLL中并没有这种功能提供. 于是我想先启动激光的官方程序用以显示轮廓, 然后再把这种显示界面嵌入到我自己程序的界面上指定的位置上.

    在笔者构想的PLC仿真器由梯形图编辑器, 3D仿真组态环境两部分组成, 这两部分就可以考虑开发成独立的软件,然后嵌入到我需要的另外的一款PLC仿真教学软件中去.

    源代码如下:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.ComponentModel;
      4 using System.Data;
      5 using System.Drawing;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Windows.Forms;
      9 using System.Runtime.InteropServices;
     10 using System.Diagnostics;
     11 using System.Threading;
     12 
     13 namespace WindowsFormsApplication1
     14 {
     15     public partial class Form1 : Form
     16     {
     17         Process p;
     18 
     19         public Form1()
     20         {
     21             InitializeComponent();
     22         }
     23 
     24         #region API
     25         [DllImport("user32.dll")]
     26         private static extern int SetParent(IntPtr hWndChild, IntPtr hWndParent);
     27 
     28         [DllImport("user32.dll")]
     29         private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
     30 
     31         [DllImport("user32.dll", SetLastError = true)]
     32         private static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
     33 
     34         [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
     35         private static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter,
     36                     int X, int Y, int cx, int cy, uint uFlags);
     37 
     38         [DllImport("user32.dll")]
     39         private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
     40 
     41         [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
     42         private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint newLong);
     43 
     44         [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
     45         private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
     46 
     47         [DllImport("user32.dll", CharSet = CharSet.Auto)]
     48         private static extern bool ShowWindow(IntPtr hWnd, short State);
     49 
     50         private const int HWND_TOP = 0x0;
     51         private const int WM_COMMAND = 0x0112;
     52         private const int WM_QT_PAINT = 0xC2DC;
     53         private const int WM_PAINT = 0x000F;
     54         private const int WM_SIZE = 0x0005;
     55         private const int SWP_FRAMECHANGED = 0x0020;
     56         public enum ShowWindowStyles : short
     57         {
     58             SW_HIDE = 0,
     59             SW_SHOWNORMAL = 1,
     60             SW_NORMAL = 1,
     61             SW_SHOWMINIMIZED = 2,
     62             SW_SHOWMAXIMIZED = 3,
     63             SW_MAXIMIZE = 3,
     64             SW_SHOWNOACTIVATE = 4,
     65             SW_SHOW = 5,
     66             SW_MINIMIZE = 6,
     67             SW_SHOWMINNOACTIVE = 7,
     68             SW_SHOWNA = 8,
     69             SW_RESTORE = 9,
     70             SW_SHOWDEFAULT = 10,
     71             SW_FORCEMINIMIZE = 11,
     72             SW_MAX = 11
     73         }
     74         #endregion
     75 
     76         private void Form1_Load(object sender, EventArgs e)
     77         {
     78             p = new Process();
     79             //需要启动的程序
     80             p.StartInfo.FileName = @"calc.exe";
     81             //为了美观,启动的时候最小化程序
     82             p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
     83             //启动
     84             p.Start();
     85 
     86             //这里必须等待,否则启动程序的句柄还没有创建,不能控制程序
     87             Thread.Sleep(10000);
     88             //最大化启动的程序
     89             ShowWindow(p.MainWindowHandle, (short)ShowWindowStyles.SW_MAXIMIZE);
     90             //设置被绑架程序的父窗口
     91             SetParent(p.MainWindowHandle, this.Handle);
     92             //改变尺寸
     93             ResizeControl();
     94         }
     95 
     96         //控制嵌入程序的位置和尺寸
     97         private void ResizeControl()
     98         {
     99             SendMessage(p.MainWindowHandle, WM_COMMAND, WM_PAINT, 0);
    100             PostMessage(p.MainWindowHandle, WM_QT_PAINT, 0, 0);
    101 
    102             SetWindowPos(
    103             p.MainWindowHandle,
    104               HWND_TOP,
    105               0 - 10,//设置偏移量,把原来窗口的菜单遮住
    106                0 - 32,
    107               (int)this.Width + 32,
    108               (int)this.Height + 32,
    109               SWP_FRAMECHANGED);
    110 
    111             SendMessage(p.MainWindowHandle, WM_COMMAND, WM_SIZE, 0);
    112         }
    113 
    114         private void Form1_SizeChanged(object sender, EventArgs e)
    115         {
    116             ResizeControl();
    117         }
    118 
    119         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    120         {
    121             p.Kill();
    122             p.Dispose();
    123         }
    124     }
    125 }

    核心功能利用了windows API中的SetParent()

    程序运行后, 先启动calc.exe(windows计算器), 然后等待10秒后再显示本程序自己的窗体, 这时你会发现这个窗体已经把calc.exe的界面包含进来的.

    这样你就可以清楚的看到嵌入的效果是怎么样的.

    效果如上图所示. 但是你的程序在退出前,要自己"杀掉"计算器的进程, 否则你的程序退出它还在.

    本文源代码

      原创文章,出处 : http://www.cnblogs.com/hackpig/

  • 相关阅读:
    “贴身外教”是英语口语的学习方法综合解决方案
    浅谈提高英语口语的最有效方法
    【PERL】Perl默认的内部变量
    Perl——哈希的创建和引用
    linux和windows下,C/C++开发的延时函数,sleep函数
    linux标准库#include <unistd.h>与windows的#include <windows.h>(C语言开发)
    linux 如何显示一个文件的某几行(中间几行)
    使程序在Linux下后台运行
    Perl中关于数组的输出——需要注意的地方
    linux下C/C++,多线程pthread
  • 原文地址:https://www.cnblogs.com/hackpig/p/5783604.html
Copyright © 2011-2022 走看看