Win32æ¶æ¯æºå¶æ¯Windowsæä½ç³»ç»æä¾çä¸ç§éä¿¡åäºä»¶å¤çæºå¶ï¼ç¨äºå¨çªå£ä¹é´ä¼ éæ¶æ¯åéç¥ãçªå£å¥æå¨Win32æ¶æ¯æºå¶ä¸æ®æ¼çéè¦çè§è²ã
å¨Win32ç¼ç¨ä¸ï¼æ¯ä¸ªçªå£é½æä¸ä¸ªå¯ä¸ççªå£å¥æï¼Handleï¼ï¼å®æ¯ä¸ä¸ªæ è¯ç¬¦ï¼ç¨äºè¯å«åæä½ç¹å®ççªå£å¯¹è±¡ãéè¿çªå£å¥æï¼å¯ä»¥åæå®ççªå£åéæ¶æ¯ï¼å¹¶å¤çæ¥æ¶å°çæ¶æ¯ã
çªå£å¥æå¨Win32æ¶æ¯æºå¶ä¸å ·æä»¥ä¸ä½ç¨ï¼
1. æ è¯çªå£ï¼çªå£å¥æå¯ä»¥å¯ä¸å°æ è¯ä¸ä¸ªçªå£å¯¹è±¡ï¼ä½¿å¾å ¶ä»ç¨åºæç»ä»¶å¯ä»¥éè¿å¥ææ¥è®¿é®è¯¥çªå£ã
2. åéæ¶æ¯ï¼éè¿çªå£å¥æï¼å¯ä»¥ä½¿ç¨Windows API彿°`SendMessage`æ`PostMessage`åæå®ççªå£åéæ¶æ¯ãæ¶æ¯å¯ä»¥æ¯ç³»ç»å®ä¹çé¢å®ä¹æ¶æ¯ï¼ä¹å¯ä»¥æ¯èªå®ä¹çåºç¨ç¨åºæ¶æ¯ãæ¶æ¯å¯ä»¥å å«åæ°åæ°æ®ï¼ç¨äºè§¦åç¹å®çæä½æéç¥çªå£è¿è¡æäºå¤çã
3. æ¥æ¶æ¶æ¯ï¼éè¿çªå£è¿ç¨ï¼Window Procedureï¼ï¼çªå£å¯ä»¥å¤çæ¥æ¶å°çæ¶æ¯ãçªå£è¿ç¨æ¯ä¸ä¸ªåè°å½æ°ï¼ç¨äºå¤ççªå£æ¥æ¶å°çæ¶æ¯å¹¶æ§è¡ç¸åºçæä½ãéè¦æ³¨æçæ¯ï¼çªå£è¿ç¨å¿ é¡»ä¸çªå£å¯¹è±¡å ³èï¼é常å¨å建çªå£æ¶ä½¿ç¨å½æ°`CreateWindowEx`æå®ã
4. æ§å¶çªå£è¡ä¸ºï¼éè¿å¤çæ¥æ¶å°çæ¶æ¯ï¼å¯ä»¥æ§å¶çªå£çè¡ä¸ºåå¤è§ãä¾å¦ï¼å¯ä»¥æ ¹æ®æ¥æ¶å°ç`WM_CLOSE`æ¶æ¯å³å®æ¯å¦å ³éçªå£ï¼éè¿`WM_PAINT`æ¶æ¯æ¥éç»çªå£å 容çã
ä¸ãWinformsçªå£å¥æï¼Handleï¼
C#ä¸ççªå£å¥æï¼Handleï¼æ¯ä¸ä¸ªå¯ä¸æ è¯ç¬¦ï¼ç¨äºè¡¨ç¤ºçªå£å¨æä½ç³»ç»ä¸çå®ä¾ãæ¯ä¸ªçªå£é½æä¸ä¸ªç¬ç¹ççªå£å¥æï¼å¯ä»¥éè¿è¯¥å¥æä¸çªå£è¿è¡äº¤äºåæä½ã
å¨C#ä¸ï¼å¯ä»¥ä½¿ç¨Control.Handle屿§æ¥è·åçªå£ç奿ãè¯¥å±æ§æ¯IntPtrç±»åï¼å®å è®¸ä½ ç´æ¥ä¸åºå±çæä½ç³»ç»äº¤äºã
以䏿¯ä¸äºå ³äºC#çªå£å¥æçç®è¦ä»ç»ï¼
- å¯ä¸æ§ï¼æ¯ä¸ªçªå£å¥æå¨æä½ç³»ç»ä¸æ¯å¯ä¸çï¼å®å¯ä»¥ç¨æ¥å¯ä¸æ è¯ä¸ä¸ªçªå£å®ä¾ãè¿ä½¿å¾ä½ è½å¤åç¡®å®ä½å¹¶ä¸ç¹å®ççªå£è¿è¡äº¤äºã
- è·¨è¿ç¨éä¿¡ï¼çªå£å¥æå¯ç¨äºå®ç°è·¨è¿ç¨éä¿¡ãå¦æä½ æä¸¤ä¸ªåºç¨ç¨åºï¼æ³è¦å®ä»¬ä¹é´è¿è¡æ¶æ¯ä¼ éæå ±äº«æ°æ®ï¼ä½ å¯ä»¥ä½¿ç¨çªå£å¥ææ¥å®ç°è·¨è¿ç¨çéä¿¡ã
- çªå£æä½ï¼ä½¿ç¨çªå£å¥æï¼ä½ å¯ä»¥æ§è¡åç§çªå£æä½ï¼å¦æå°åãæå¤§åãæ¢å¤ãå ³éçãéè¿åçªå£å¥æåéç¸åºçæ¶æ¯ï¼å¯ä»¥å¯¹çªå£è¿è¡æä½ã
- æ¶æ¯ä¼ éï¼çªå£å¥æè¿å¯ç¨äºå®ç°æ¶æ¯ä¼ éãéè¿åéæ¶æ¯ç»çªå£å¥æï¼ä½ å¯ä»¥å¨åºç¨ç¨åºä¸çä¸åé¨åä¹é´ä¼ éæ¶æ¯ï¼ä»¥å®ç°éä¿¡å交äºã
- èµæºç®¡çï¼çªå£å¥æä¹ä¸èµæºç®¡çç¸å ³ãéè¿å¨ä¸éè¦æ¶éæ¾çªå£å¥æï¼å¯ä»¥ææå°ç®¡çç³»ç»èµæºï¼å¹¶é¿å å åæ³æ¼çé®é¢ã
请注æä»¥ä¸å ç¹ï¼
- çªå£å¥ææ¯ä¸ä¸ªéæç®¡èµæºï¼å®ä¸æä½ç³»ç»ç´§å¯ç¸å ³ãå¨ä½¿ç¨çªå£å¥ææ¶ï¼éè°¨æ å¤çï¼ç¡®ä¿æ£ç¡®éæ¾èµæºã
- çªå£å¥æåªå¨çªå£å建åæå¯ç¨ãå¨å建çªå£ä¹åæéæ¯çªå£ä¹åï¼çªå£å¥æå°æ æã
- çªå£å¥ææ¯ä¸ä¸ªæ´æ°å¼ï¼å¯ä»¥è½¬æ¢ä¸ºIntPtrç±»åæ¥è¿è¡æä½ã
éè¿äºè§£å使ç¨çªå£å¥æï¼å¯ä»¥å¨C#䏿´å¥½å°ç®¡ççªå£ï¼å®ç°çªå£ä¹é´çéä¿¡å交äºï¼å¹¶å¯¹çªå£è¿è¡åç§æä½ã
äºãçªå£å¥ææ¶æ¯ä¼ é
å¨C# WinFormsä¸ï¼å¯ä»¥éè¿çªå£å¥æï¼Handleï¼æ¥è¿è¡æ¶æ¯ä¼ éãçªå£å¥ææ¯æ¯ä¸ªå建ççªå£é½æçå¯ä¸æ è¯ç¬¦ãè¦åéæ¶æ¯ç»å ¶ä»çªå£ï¼å¯ä»¥ä½¿ç¨SendMessageæSendMessageTimeout彿°æ¥å®ç°ãè¿ä¸¤ä¸ªå½æ°ä½äºuser32.dllåºä¸ï¼å¯ä»¥éè¿DllImportæ¥å¼å ¥ã
以䏿¯ä¸ä¸ªç¤ºä¾ä»£ç ï¼å¦ä½åæå®çªå£åéæ¶æ¯ï¼
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public partial class Form1 : Form
{
// å¼å
¥ SendMessage 彿°
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
// å®ä¹å¸¸é
private const int WM_USER = 0x0400; // èªå®ä¹æ¶æ¯èµ·å§å¼
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// è·åç®æ çªå£å¥æï¼åè®¾ç®æ çªå£çæ é¢ä¸º"TargetWindow"ï¼
IntPtr targetHandle = FindWindow(null, "TargetWindow");
if (targetHandle != IntPtr.Zero)
{
// åéèªå®ä¹æ¶æ¯ç»ç®æ çªå£
SendMessage(targetHandle, WM_USER + 1, IntPtr.Zero, IntPtr.Zero);
}
}
}
å¨ä¸é¢ç代ç ä¸ï¼æä»¬éè¿FindWindow彿°æ¾å°ç®æ çªå£ç奿ï¼ç¶å使ç¨SendMessage彿°å°èªå®ä¹çæ¶æ¯ï¼WM_USER + 1ï¼åéç»ç®æ çªå£ã注æï¼æ¥æ¶æ¶æ¯ççªå£éè¦å¨å ¶æ¶æ¯å¤ç彿°ä¸è¿è¡å¤çãä½ å¯ä»¥éåç®æ çªå£çWndProcæ¹æ³ï¼ä»¥ä¾¿å¨æ¥æ¶å°æ¶æ¯æ¶æ§è¡ç¸åºçé»è¾ã
protected override void WndProc(ref Message m)
{
// 夿æ¯å¦æ¥æ¶å°èªå®ä¹æ¶æ¯
if (m.Msg == WM_USER + 1)
{
// æ§è¡æ¶æ¯å¤çé»è¾
MessageBox.Show("Received custom message!");
}
// è°ç¨ç¶ç±»çWndProcæ¹æ³ç»§ç»å¤çå
¶ä»æ¶æ¯
base.WndProc(ref m);
}
è¿æ ·ï¼å½ç®æ çªå£æ¥æ¶å°èªå®ä¹æ¶æ¯æ¶ï¼ä¼å¼¹åºä¸ä¸ªæ¶æ¯æ¡æ¾ç¤º"Received custom message!"ã
éè¿çªå£å¥æè¿è¡æ¶æ¯ä¼ 鿝ä¸ç§å¸¸è§çæ¹å¼ï¼å¨C# WinFormsä¸å¯ä»¥æ¹ä¾¿å°å®ç°çªå£é´çéä¿¡å交äºã
ä¸ãC# Winform åC++ MFCéè¿çªå£å¥æéä¿¡
C# WinformåC++ MFCä¹é´å¯ä»¥éè¿çªå£å¥æè¿è¡éä¿¡ãä¸é¢æ¯ä¸ç§åºæ¬çæ¹å¼æ¥å®ç°è¿ç§éä¿¡ï¼
- C# Winformçªå£ç«¯ï¼
- é¦å ï¼å¨C#çWinformçªå£ä¸ï¼ä½¿ç¨FindWindowæFindWindowEx彿°æ¥æç´¢C++ MFCçªå£ç奿ãè¿ä¸¤ä¸ªå½æ°ä½äºuser32.dllåºä¸ï¼å¯ä»¥ä½¿ç¨DllImportæ¥å¼å ¥ã
- è·åå°C++ MFCçªå£ç奿ä¹åï¼å¯ä»¥ä½¿ç¨SendMessageæPostMessage彿°åè¯¥å¥æåéæ¶æ¯ã
- C++ MFCçªå£ç«¯ï¼
- å¨C++ MFCçªå£ç±»ç代ç ä¸ï¼éåçªå£çOnWndMsgæ¹æ³æ¥å¤çæ¥æ¶å°çæ¶æ¯ã
- 使ç¨HWNDç±»åçå¥ææ¥æ¶å°C# Winformçªå£åéçæ¶æ¯ï¼å¹¶æ§è¡ç¸åºçé»è¾ã
ä¸é¢æ¯ä¸ä¸ªç®åç示ä¾ä»£ç æ¥æ¼ç¤ºC# Winformçªå£åC++ MFCçªå£éè¿çªå£å¥æè¿è¡éä¿¡ï¼
C# Winformçªå£ç«¯ä»£ç ï¼
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public partial class Form1 : Form
{
// å¼å
¥ FindWindow 彿°
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
// å¼å
¥ SendMessage 彿°
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
// å®ä¹å¸¸é
private const int WM_USER = 0x0400; // èªå®ä¹æ¶æ¯èµ·å§å¼
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// è·åç®æ çªå£å¥æï¼åè®¾ç®æ è¿ç¨ççªå£ç±»å为"MFCWindowClass"ï¼
IntPtr targetHandle = FindWindow("MFCWindowClass", null);
if (targetHandle != IntPtr.Zero)
{
// åéèªå®ä¹æ¶æ¯ç»ç®æ çªå£
SendMessage(targetHandle, WM_USER + 1, IntPtr.Zero, IntPtr.Zero);
}
}
}
C++ MFCçªå£ç«¯ä»£ç ï¼
// MFCçªå£ç±»ä»£ç
LRESULT CMyMFCWindow::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (message == WM_USER + 1)
{
// æ§è¡æ¥æ¶å°C# Winformçªå£åéçæ¶æ¯çé»è¾
// ...
// è¿å0è¡¨ç¤ºæ¶æ¯å·²è¢«å¤ç
return 0;
}
// è°ç¨åºç±»çæ¶æ¯å¤çæ¹æ³
return CWnd::OnWndMsg(message, wParam, lParam, bHandled);
}
å¨ä¸é¢ç示ä¾ä¸ï¼æä»¬å¨C# Winformçªå£ä¸ä½¿ç¨FindWindow彿°è·åå°C++ MFCçªå£ç奿ï¼å¹¶ä½¿ç¨SendMessage彿°åè¯¥å¥æåéèªå®ä¹æ¶æ¯ãå¨C++ MFCçªå£ä¸ï¼æä»¬éåäºçªå£ç±»çOnWndMsgæ¹æ³æ¥å¤çæ¥æ¶å°çæ¶æ¯ï¼ä»¥æ§è¡ç¸åºçé»è¾ã请注æï¼ç¡®ä¿å¨è¿è¡è·¨è¯è¨ï¼C#åC++ï¼ççªå£éä¿¡æ¶ï¼è¦éµå®æä½ç³»ç»åå®å ¨æ§è¦æ±ï¼å¹¶ç¡®ä¿æ£ç¡®å¤çå¼å¸¸åé误æ åµãå¦å¤ï¼è¿éè¦æ³¨æC#åC++ä¹é´çæ°æ®ä¼ éåç±»å转æ¢çç¸å ³é®é¢ï¼ä»¥ç¡®ä¿éä¿¡çæ£ç¡®æ§åç¨³å®æ§ã
åã使ç¨çªå£å¥ææ¶è¦éµå¾ªä¸äºè§èåæ³¨æäºé¡¹
使ç¨çªå£å¥ææ¶ï¼éè¦éµå¾ªä¸äºè§èåæ³¨æäºé¡¹ã以䏿¯å ¶ä¸çä¸äºéè¦æ¹é¢ï¼
1. è·¨çº¿ç¨æä½ï¼çªå£å¥ææ¯ä¸ç¹å®çº¿ç¨å ³èçï¼å æ¤å¨ä¸å线ç¨ä¹é´ä½¿ç¨çªå£å¥ææ¶éè¦æ³¨æè·¨çº¿ç¨å®å ¨æ§ãé常æ åµä¸ï¼åºè¯¥å¨å建çªå£å¥æç线ç¨ä¸æ§è¡æä½ã妿éè¦å¨å ¶ä»çº¿ç¨ä¸æ§è¡æä½ï¼å¯ä»¥ä½¿ç¨`Control.Invoke`æ`Control.BeginInvoke`æ¥ç¡®ä¿å¨æ£ç¡®ç线ç¨ä¸æ§è¡çªå£å¥æç¸å ³çæä½ã
2. çå½å¨æç®¡çï¼çªå£å¥æçå建å鿝ç±WinFormsæ¡æ¶èªå¨ç®¡çãé常æ åµä¸ï¼æ éæå¨å建æéæ¾çªå£å¥æãç¸åï¼åºè¯¥éè¿å建åå¤çæ§ä»¶æ¥ç®¡ççªå£å¥æççå½å¨æãç¡®ä¿å¨ä¸åéè¦æ¶åæ¶éæ¯ç¸å ³çæ§ä»¶ã
3. çªå£å¥æçå¯ä¸æ§ï¼çªå£å¥ææ¯å¯ä¸æ è¯ä¸ä¸ªçªå£çå¼ãæ¯ä¸ªçªå£å¥æé½æ¯å¯ä¸çï¼å¹¶ä¸ä¸ä¼éçæ¶é´æ¹åãå æ¤ï¼å¨ä½¿ç¨çªå£å¥æè¿è¡äº¤äºæ¶ï¼ç¡®ä¿æä½çæ¯æ£ç¡®ççªå£å¥æã
4. å®å ¨æ§åæéï¼çªå£å¥ææä¾äºç´æ¥è®¿é®åºå±æä½ç³»ç»çè½åï¼å æ¤éè¦æ³¨æå®å ¨æ§åæéé®é¢ãç¡®ä¿åªå¯¹èªå·±åºç¨ç¨åºå é¨ççªå£è¿è¡æä½ï¼ä¸è¦è¯å¾è®¿é®å ¶ä»åºç¨ç¨åºæç³»ç»çº§çªå£ï¼ä»¥é¿å æ½å¨çå®å ¨é®é¢ã
5. 跨平å°å ¼å®¹æ§ï¼çªå£å¥ææ¯ä¸Windowsæä½ç³»ç»ç´§å¯ç¸å ³çæ¦å¿µï¼å æ¤ä¸éç¨äºå ¶ä»æä½ç³»ç»ã妿éè¦å®ç°è·¨å¹³å°å ¼å®¹æ§ï¼åºè¯¥èè使ç¨å ¶ä»è·¨å¹³å°æ¡æ¶æææ¯ï¼å¦QtãGTK+çã
æ»ä¹ï¼å¨ä½¿ç¨çªå£å¥ææ¶ï¼å¿ é¡»éµå¾ªä¸è¿°è§èåæ³¨æäºé¡¹ï¼ä»¥ç¡®ä¿å®å ¨ãå¯é å髿å°è¿è¡çªå£æä½å交äºã