通過 WIN32 API 實現嵌入程序窗體,win32api
寫了一個不使用 COM, 而是通過 WIN32 API 實現的示例, 它把寫字板程序嵌在了自己的一個面板中.
這麼做可能沒有實際意義, 因為兩個程序之前沒有進行有價值的交互, 這裡僅僅是為了演示這麼做到, 以下是詳細注釋過的主要源代碼.
我把它封裝到一個類中:
[csharp] view plaincopy
- 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事件中 加入
詳細代碼 如下:
[csharp] view plaincopy
- 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);
-
- }
-
-
- }
- }
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技術),當然可以調用窗體程序。