自己之前對WIN API編程一直是望而生畏,沒有信心和毅力去學習。但是進行Windows編程人員或多或少地會遇到或使用到WIN API。無論你是JAVA或NET程序員,都是間接使用了WIN API,兩個運行環境只是對WIN API進行了一層不同的封裝而已。
《精通.NET互操作》深入講解了P/Invoke, C++ Interop 和COM Interop。由於該書講解較深,有點枯燥,我每次也就看個五六頁。如果想了解互操作或進行WIN API編程的,建議閱讀。
下面是我使用和看過的兩個實例:
1.動態顯示窗口
#region 動畫啟動窗體
[DllImportAttribute("user32.dll")]
private static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);
/*
1. AW_SLIDE : 使用滑動類型, 默認為該類型. 當使用 AW_CENTER 效果時, 此效果被忽略
2. AW_ACTIVE: 激活窗口, 在使用了 AW_HIDE 效果時不可使用此效果
3. AW_BLEND: 使用淡入效果
4. AW_HIDE: 隱藏窗口
5. AW_CENTER: 與 AW_HIDE 效果配合使用則效果為窗口幾內重疊, 單獨使用窗口向外擴展.
6. AW_HOR_POSITIVE : 自左向右顯示窗口
7. AW_HOR_NEGATIVE: 自右向左顯示窗口
8. AW_VER_POSITVE: 自頂向下顯示窗口
9. AW_VER_NEGATIVE : 自下向上顯示窗口
*/
public const Int32 AW_HOR_POSITIVE = 0x00000001;
public const Int32 AW_HOR_NEGATIVE = 0x00000002;
public const Int32 AW_VER_POSITIVE = 0x00000004;
public const Int32 AW_VER_NEGATIVE = 0x00000008;
public const Int32 AW_CENTER = 0x00000010;
public const Int32 AW_HIDE = 0x00010000;
public const Int32 AW_ACTIVATE = 0x00020000;
public const Int32 AW_SLIDE = 0x00040000;
public const Int32 AW_BLEND = 0x00080000;
//動態關閉窗體
private void XFormMain_FormClosed(object sender, FormClosedEventArgs e)
{
//動態關閉窗體
AnimateWindow(this.Handle, 800, AW_SLIDE + AW_HIDE + AW_CENTER);
}
#endregion
public XFormMain()
{
InitializeComponent();
//動畫啟動
AnimateWindow(this.Handle, 800, AW_SLIDE + AW_CENTER);
}
user32.dll存在於C:\WINDOWS\system32,調用AnimateWindow函數方法實現窗口的動態顯示。可以查看MSDN來獲取該方法的詳細說明。
2.VS2005中文輸入法自動轉換為全角的兩種解決方法
//VS2005中文輸入法自動轉換為全角的兩種解決方法 ----- 之二 ----- 使用繼承的方法
//最近在用VS2005做項目的時候,一直忍受著VS2005輸入法自動切換到全角的Bug的作怪,一邊等待
//著微軟給我們一個解決的方案。但是,我的項目都要作為產品打包出去了,微軟還是悶頭不對
//這個Bug出一個解決方法。怎麼辦?我可以忍受這個輸入法來回切換之苦,可用戶體驗可不會饒過我們的。
//弄不好,來個集體罷用,讓我們都到微軟喝西北風去啊!
//總不能就這麼交出產品出去吧,只有自己動手了。下面我用兩種方法來實現如何避免輸入法的這個Bug。
//首先,建立一個獨立的類如下:
//使用這個類的方法為:
// 修改所有的Form的繼承關系,比如,你有這樣的一個Form類:
//public partial class Form1 :ImeForm
//{
// // ...
//}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Collections;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Controls.Windows
{
public class ImeForm : System.Windows.Forms.Form
{
//聲明一些API函數
[DllImport("imm32.dll")]
public static extern IntPtr ImmGetContext(IntPtr hwnd);
[DllImport("imm32.dll")]
public static extern bool ImmGetOpenStatus(IntPtr himc);
[DllImport("imm32.dll")]
public static extern bool ImmSetOpenStatus(IntPtr himc, bool b);
[DllImport("imm32.dll")]
public static extern bool ImmGetConversionStatus(IntPtr himc, ref int lpdw, ref int lpdw2);
[DllImport("imm32.dll")]
public static extern int ImmSimulateHotKey(IntPtr hwnd, int lngHotkey);
private const int IME_CMODE_FULLSHAPE = 0x8;
private const int IME_CHOTKEY_SHAPE_TOGGLE = 0x11;
//重載Form的OnActivated
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
IntPtr HIme = ImmGetContext(this.Handle);
if (ImmGetOpenStatus(HIme)) //如果輸入法處於打開狀態
{
int iMode = 0;
int iSentence = 0;
bool bSuccess = ImmGetConversionStatus(HIme, ref iMode, ref iSentence); //檢索輸入法信息
if (bSuccess)
{
if ((iMode & IME_CMODE_FULLSHAPE) > 0) //如果是全角
ImmSimulateHotKey(this.Handle, IME_CHOTKEY_SHAPE_TOGGLE); //轉換成半角
}
}
}
}
}
以前在vs2005開發會遇到該問題,但是MS已經給出補丁了,不會再出現該問題,我們只是想看看imm32.dll中三個方法的使用。
上面兩個例子,向我們展示如何使用WIN API編程,涉及到函數方法的查詢和常量定義的值的查詢。函數查詢主要是使用MSDN,MSDN是最權威的。至於常量值查詢可使用網上的小工具。WIN API編程工具推薦:《API常量查詢1.0》和《易用api伴侶》較好