其实在C#里面API已经被封装了很深了,比如Form f=new Form(); f.show();这样便能创建个窗体并显示出来。完全没了C和汇编的频繁的API调用了,然而实际上在我们实例化个窗体类时仍然是调用那些API!
下面给出相关的API和结构,具体还是摸索中,比如C#获取函数的指针就需要用到委托(有人说委托便是函数指针),但仍然还是些问题比较难以解决……
#region 构建窗体必须的API
/// <summary>
/// 构建窗体必须的API
/// </summary>
static class WinApi
{
/// <summary>
/// 注销窗体
/// </summary>
/// <param name="hwnd"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)]
internal static extern bool DestroyWindow(IntPtr hwnd);
/// <summary>
/// 退出消息
/// </summary>
/// <param name="nExitCode"></param>
[DllImport("kernel32.dll")]
public static extern void PostQuitMessage(int nExitCode);
/// <summary>
/// 消息的默认处理
/// </summary>
/// <param name="hWnd"></param>
/// <param name="Msg"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "DefWindowProc")]
public static extern int DefWindowProc(IntPtr hWnd, uint Msg, int wParam, int lParam);
/// <summary>
/// 获取模块句柄
/// </summary>
/// <param name="lpModuleName"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string lpModuleName);
/// <summary>
/// 注册窗体
/// </summary>
/// <param name="wndClassEx"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern IntPtr RegisterClassEx(WndClassEx wndClassEx);
/// <summary>
/// 创建窗体
/// </summary>
/// <param name="dwExStyle"></param>
/// <param name="lpClassName"></param>
/// <param name="lpWindowName"></param>
/// <param name="dwStyle"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="nWidth"></param>
/// <param name="nHeight"></param>
/// <param name="hWndParent"></param>
/// <param name="hMenu"></param>
/// <param name="hInstance"></param>
/// <param name="lpParam"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern IntPtr CreateWindowEx(int dwExStyle, string lpClassName, string lpWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
/// <summary>
/// 显示窗体
/// </summary>
/// <param name="hWnd"></param>
/// <param name="nCmdShow"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
/// <summary>
/// 更新窗体
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern bool UpdateWindow(IntPtr hWnd);
/// <summary>
/// 获取消息
/// </summary>
/// <param name="lpMsg"></param>
/// <param name="hwnd"></param>
/// <param name="wMsgFilterMin"></param>
/// <param name="wMsgFilterMax"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "GetMessage")]
public static extern int GetMessage(
out Msg lpMsg,
int hwnd,
int wMsgFilterMin,
int wMsgFilterMax
);
/// <summary>
/// 发生消息
/// </summary>
/// <param name="lpMsg"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "DispatchMessage")]
public static extern int DispatchMessage(
ref Msg lpMsg
);
/// <summary>
/// 派发消息
/// </summary>
/// <param name="lpMsg"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "TranslateMessage")]
public static extern int TranslateMessage(
ref Msg lpMsg
);
/// <summary>
/// 导入图标
/// </summary>
/// <param name="hInstance"></param>
/// <param name="lpIconName"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern IntPtr LoadIcon(IntPtr hInstance, string lpIconName);
/// <summary>
/// 导入鼠标
/// </summary>
/// <param name="hInstance"></param>
/// <param name="lpCursorName"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
}
#endregion
#region 窗体结构体
/// <summary>
/// 窗体结构体,用于注册等
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct WndClassEx
{
public int Cbsize;//该结构体占有的字节数
public int style;//指定窗口风格 常用值:CS_VREDRAW(垂直方向自动重画)、CS_HREDRAW(水平方向自动重画)、CS_DBLCLKS(支持鼠标双击)
public IntPtr lpfnWndProc;//函数指针,指向处理窗口消息的函数入口,即窗口处理过程
public int cbClsExtra;//结构体后附加的字节数,一般总为0
public int cbWndExtra;//窗体实例附加的字节数,一般总为0
public IntPtr hInstance;//模块句柄
public IntPtr hIcon;//图标句柄,程序在任务栏中显示的图标
public IntPtr hCursor;//光标句柄
public IntPtr hbrBackgrounp;//窗体背景色句柄
public int lpszMenuName;//菜单名的字符串
public string lpszClassName;//自定义类名,不要与其他类名重复
public IntPtr hIconSm;//小图标句柄
}
#endregion
#region 消息结构体
/// <summary>
/// 消息结构体
/// </summary>
[ StructLayout( LayoutKind.Sequential )]
public struct Msg
{
public IntPtr hwnd;//消息发往的窗口句柄
public uint message;//消息号
public string wParam;//消息参数一
public string lParam;//消息参数二
public int time;//时间
public int pt;//消息发生地点,大多与鼠标有关
}
#endregion
实现过程是
依次调用API函数:GetModuleHandle → RtlZeroMemory → LoadCursor → RegisterClassEx
→ CreateWindowEx → ShowWindow → UpdateWindow
GetMessage → TranslateMessage → DispatchMessageran
然后等待系统回调窗口过程