程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 通過 WIN32 API 實現嵌入程序窗體,win32api

通過 WIN32 API 實現嵌入程序窗體,win32api

編輯:C#入門知識

通過 WIN32 API 實現嵌入程序窗體,win32api


寫了一個不使用 COM, 而是通過 WIN32 API 實現的示例, 它把寫字板程序嵌在了自己的一個面板中.  

這麼做可能沒有實際意義, 因為兩個程序之前沒有進行有價值的交互, 這裡僅僅是為了演示這麼做到, 以下是詳細注釋過的主要源代碼.

我把它封裝到一個類中:

 

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



 

 

然後在 窗口的 load事件中 加入


詳細代碼 如下:

 

[csharp] view plaincopy
  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;  
  10. using System.Runtime.InteropServices;  
  11. using System.Diagnostics;  
  12.   
  13. namespace 將程序窗口嵌入到任務欄中  
  14. {  
  15.     public partial class Form1 : Form  
  16.     {  
  17.         private System.Windows.Forms.Panel panel1;  
  18.         public Form1()  
  19.         {  
  20.             InitializeComponent();  
  21.             this.panel1 = new System.Windows.Forms.Panel();  
  22.             this.SuspendLayout();  
  23.             //   
  24.             // panel1  
  25.             //   
  26.             this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;  
  27.             this.panel1.Location = new System.Drawing.Point(0, 0);  
  28.             this.panel1.Name = "panel1";  
  29.             this.panel1.Size = new System.Drawing.Size(292, 273);  
  30.             this.panel1.TabIndex = 0;  
  31.             this.Controls.Add(this.panel1);  
  32.   
  33.             Load += new EventHandler(Form1_Load);  
  34.         }  
  35.   
  36.         private void Form1_Load(object sender, EventArgs e)  
  37.         {  
  38.             //string sPath = Environment.GetEnvironmentVariable("windir");//獲取系統變量 windir(windows)    
  39.             const string appFile =  
  40.                 "C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe";  
  41.             InsertWindow insertwin = new InsertWindow(panel1, appFile);  
  42.   
  43.         }  
  44.   
  45.           
  46.     }  
  47. }  

VS2012 C/C++怎建立WIN32 API窗體應用程序

我也在學窗口設計,這種問題,還是看書理解的比較透徹。
建議你去看〈windows程序設計〉,〈深入淺出mfc〉
純手打,請給分!!!
 

Win32應用程序與windows窗體程序有什不同

win32應用程序是指可以在32位或以上Windows系統中運行的程序,概念比windows窗體大,嚴格說來,窗體程序也是win32應用程序。你問的是vs環境中不同的程序類型的區別吧。win32程序是利用編程語言直接調用windows api編寫的程序,可以在任何裝有正確windows的機器上運行,程序員發揮的空間也最大,能實現在該操作系統中可以編程實現的任何功能。
而.net的窗體應用程序是一種托管代碼,無論你是用c++\c#還是vb編寫,只能在.net環境中應用,就是說你編譯好的軟件在沒有.net framework的機器上是不能運行的,而且功能的實現也要受framework的限制,不能隨心所欲。
可視化的除了窗體程序,你也可以選擇mfc,代碼編寫量比純api編程要小的多,盡管比.net復雜,但應用起來更靈活,而且這個是不依賴.net框架的。
win32包括mfc可以調用操作系統允許的任何程序(甚至可以通過某種技術調用操作系統不允許的操作如hook api技術),當然可以調用窗體程序。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved