LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

【C#】Winform开发基础之熟悉Win32 API函数

admin
2024年12月27日 21:51 本文热度 127

前言

在WinForms应用程序中,可以通过调用 Win32 API 来实现更低级别的操作,例如窗口管理、系统信息获取、硬件访问等。Win32 API 是 Windows 操作系统的基础接口,能够提供大量的功能和灵活性。

1. Win32 API 的基本概念

Win32 API 是 Windows 操作系统的核心编程接口,它包括了各种函数、结构、常量等,用于开发 Windows 应用程序。WinForms 应用通常是通过调用user32.dllkernel32.dllgdi32.dll 等动态链接库(DLL)中的函数来与操作系统交互。

调用 Win32 API 的方式

在 WinForms 应用中,可以通过 P/Invoke(平台调用)机制来调用 Win32 API。P/Invoke 允许托管代码(如 C#)调用非托管代码(如 C++ 编写的 Win32 API)。

using System;
using System.Runtime.InteropServices;

class Win32API
{
    // 示例:调用 MessageBox 函数
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);

    static void Main()
    {
        MessageBox(IntPtr.Zero, "Hello, World!""Win32 API"0);
    }
}

执行结果

2. 常见的 Win32 API 函数

以下是 Win32 API 函数的一些常见分类,包含基本功能和 C# 中的声明方式。

1. 窗口管理

  • • CreateWindowEx
    • • 功能:创建一个具有扩展样式的窗口。
    • • 声明方式
      [DllImport("user32.dll", CharSet = CharSet.Auto)]
      public static extern IntPtr CreateWindowEx(
          uint dwExStyle,
          string lpClassName,
          string lpWindowName,
          uint dwStyle,
          int x, int y, int nWidth, int nHeight,
          IntPtr hWndParent,
          IntPtr hMenu,
          IntPtr hInstance,
          IntPtr lpParam
      )
      ;
  • • ShowWindow
    • • 功能:显示或隐藏窗口。
    • • 声明方式
      [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
  • • DestroyWindow
    • • 功能:销毁窗口。
    • • 声明方式
      [DllImport("user32.dll")]
      public static extern bool DestroyWindow(IntPtr hWnd);
  • • GetMessage
    • • 功能:从消息队列中获取消息。
    • • 声明方式
      [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);

2. 消息与事件处理

  • • PostMessage
    • • 功能:将消息放入窗口的消息队列中。
    • • 声明方式
      [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
  • • SendMessage
    • • 功能:发送消息并等待返回结果。
    • • 声明方式
      [DllImport("user32.dll")]
      public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

3. 图形与绘图功能

  • • BeginPaint
    • • 功能:开始绘制窗口的客户区。
    • • 声明方式
      [DllImport("user32.dll")]
      public static extern IntPtr BeginPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint);
  • • EndPaint
    • • 功能:结束绘制操作。
    • • 声明方式
      [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint);
  • • GetClientRect
    • • 功能:获取窗口客户区的矩形区域。
    • • 声明方式
      [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);

4. 文件与目录操作

  • • CreateFile
    • • 功能:创建或打开文件。
    • • 声明方式
      [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      public static extern IntPtr CreateFile(
          string lpFileName,
          uint dwDesiredAccess,
          uint dwShareMode,
          IntPtr lpSecurityAttributes,
          uint dwCreationDisposition,
          uint dwFlagsAndAttributes,
          IntPtr hTemplateFile
      )
      ;
  • • ReadFile
    • • 功能:从文件中读取数据。
    • • 声明方式
      [DllImport("kernel32.dll", SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool ReadFile(
          IntPtr hFile,
          byte[] lpBuffer,
          uint nNumberOfBytesToRead,
          out uint lpNumberOfBytesRead,
          IntPtr lpOverlapped
      )
      ;
  • • WriteFile
    • • 功能:向文件中写入数据。
    • • 声明方式
      [DllImport("kernel32.dll", SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool WriteFile(
          IntPtr hFile,
          byte[] lpBuffer,
          uint nNumberOfBytesToWrite,
          out uint lpNumberOfBytesWritten,
          IntPtr lpOverlapped
      )
      ;

5. 内存管理

  • • GlobalAlloc
    • • 功能:分配全局内存。
    • • 声明方式
      [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
      public static extern IntPtr GlobalAlloc(uint uFlags, uint dwBytes);
  • • GlobalFree
    • • 功能:释放由 GlobalAlloc 分配的内存。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern IntPtr GlobalFree(IntPtr hMem);
  • • HeapAlloc
    • • 功能:从堆中分配内存。
    • • 声明方式
      [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
      public static extern IntPtr HeapAlloc(IntPtr hHeap, uint dwFlags, uint dwBytes);

6. 动态链接库管理

  • • LoadLibrary
    • • 功能:加载 DLL 文件。
    • • 声明方式
      [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
      public static extern IntPtr LoadLibrary(string lpFileName);
  • • GetProcAddress
    • • 功能:获取 DLL 中指定函数的地址。
    • • 声明方式
      [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
      public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
  • • FreeLibrary
    • • 功能:卸载 DLL 文件。
    • • 声明方式
      [DllImport("kernel32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool FreeLibrary(IntPtr hModule);

7. 系统信息与环境

  • • GetSystemInfo
    • • 功能:获取有关当前系统的信息。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
  • • GetVersion
    • • 功能:获取操作系统版本信息。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern uint GetVersion();
  • • GetCurrentProcess
    • • 功能:获取当前进程的句柄。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern IntPtr GetCurrentProcess();

8. 窗口消息与事件

  • • PostQuitMessage
    • • 功能:发送一个退出消息,通常用于终止消息循环。
    • • 声明方式
      [DllImport("user32.dll")]
      public static extern void PostQuitMessage(int nExitCode);
  • • TranslateMessage
    • • 功能:将消息翻译成字符消息。
    • • 声明方式
      [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool TranslateMessage(ref MSG lpMsg);
  • • DispatchMessage
    • • 功能:将消息分派给窗口过程。
    • • 声明方式
      [DllImport("user32.dll")]
      public static extern IntPtr DispatchMessage(ref MSG lpMsg);

9. 线程与进程管理

  • • CreateThread
    • • 功能:创建一个新线程。
    • • 声明方式
      [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      public static extern IntPtr CreateThread(
          IntPtr lpThreadAttributes,
          uint dwStackSize,
          ThreadStart lpStartAddress,
          IntPtr lpParameter,
          uint dwCreationFlags,
          out uint lpThreadId
      )
      ;
  • • ExitThread
    • • 功能:退出当前线程。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern void ExitThread(uint dwExitCode);
  • • GetCurrentThreadId
    • • 功能:获取当前线程的 ID。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern uint GetCurrentThreadId();
  • • TerminateProcess
    • • 功能:终止指定的进程。
    • • 声明方式
      [DllImport("kernel32.dll", SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);

10. 注册表操作

  • • RegOpenKeyEx
    • • 功能:打开注册表键。
    • • 声明方式
      [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      public static extern IntPtr RegOpenKeyEx(
          IntPtr hKey,
          string lpSubKey,
          uint ulOptions,
          uint samDesired,
          ref IntPtr phkResult
      )
      ;
  • • RegSetValueEx
    • • 功能:设置注册表值。
    • • 声明方式
      [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      public static extern int RegSetValueEx(
          IntPtr hKey,
          string lpValueName,
          uint Reserved,
          uint dwType,
          byte[] lpData,
          uint dwData
      )
      ;
  • • RegQueryValueEx
    • • 功能:查询注册表值。
    • • 声明方式
      [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      public static extern int RegQueryValueEx(
          IntPtr hKey,
          string lpValueName,
          ref uint lpReserved,
          ref uint lpType,
          byte[] lpData,
          ref uint lpcbData
      )
      ;
  • • RegCloseKey
    • • 功能:关闭注册表键。
    • • 声明方式
      [DllImport("advapi32.dll", SetLastError = true)]
      public static extern int RegCloseKey(IntPtr hKey);

11. 网络操作

  • • InternetOpen
    • • 功能:打开一个会话,用于访问网络。
    • • 声明方式
      [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
      public static extern IntPtr InternetOpen(
          string lpszAgent,
          uint dwAccessType,
          string lpszProxy,
          string lpszProxyBypass,
          uint dwFlags
      )
      ;
  • • InternetOpenUrl
    • • 功能:打开 URL 地址进行数据传输。
    • • 声明方式
      [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
      public static extern IntPtr InternetOpenUrl(
          IntPtr hInternet,
          string lpszUrl,
          string lpszHeaders,
          uint dwHeadersLength,
          uint dwFlags,
          IntPtr dwContext
      )
      ;
  • • InternetReadFile
    • • 功能:读取数据流中的数据。
    • • 声明方式
      [DllImport("wininet.dll", SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool InternetReadFile(
          IntPtr hFile,
          byte[] lpBuffer,
          uint dwNumberOfBytesToRead,
          out uint lpNumberOfBytesRead
      )
      ;
  • • InternetCloseHandle
    • • 功能:关闭与 Internet 的连接。
    • • 声明方式
      [DllImport("wininet.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool InternetCloseHandle(IntPtr hInternet);

12. 时间与日期

  • • GetSystemTime
    • • 功能:获取当前系统时间。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern void GetSystemTime(out SYSTEMTIME lpSystemTime);
  • • SetSystemTime
    • • 功能:设置系统时间。
    • • 声明方式
      [DllImport("kernel32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool SetSystemTime(ref SYSTEMTIME lpSystemTime);
  • • GetLocalTime
    • • 功能:获取本地时间。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern void GetLocalTime(out SYSTEMTIME lpSystemTime);
  • • SetLocalTime
    • • 功能:设置本地时间。
    • • 声明方式
      [DllImport("kernel32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool SetLocalTime(ref SYSTEMTIME lpSystemTime);

13. 内存和数据操作

  • • VirtualAlloc
    • • 功能:分配或更改内存区域的大小。
    • • 声明方式
      [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      public static extern IntPtr VirtualAlloc(
          IntPtr lpAddress,
          uint dwSize,
          uint flAllocationType,
          uint flProtect
      )
      ;
  • • VirtualFree
    • • 功能:释放先前通过 VirtualAlloc 分配的内存。
    • • 声明方式
      [DllImport("kernel32.dll", SetLastError = true)]
      [return: MarshalAs(UnmanagedType.Bool)]
      public static extern bool VirtualFree(
          IntPtr lpAddress,
          uint dwSize,
          uint dwFreeType
      )
      ;
  • • RtlMoveMemory
    • • 功能:复制内存块的内容。
    • • 声明方式
      [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
      public static extern void RtlMoveMemory(IntPtr dest, IntPtr src, uint size);
  • • ZeroMemory
    • • 功能:将内存区域清零。
    • • 声明方式
      [DllImport("kernel32.dll")]
      public static extern void ZeroMemory(IntPtr dest, uint size);

3. 结构和常量

许多 Win32 API 函数使用结构体和常量。以下是一些常见的结构和常量:

3.1 常用结构

RECT

用于表示一个矩形区域。

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

SYSTEMTIME

表示一个日期和时间。

[StructLayout(LayoutKind.Sequential)]
publicstruct SYSTEMTIME
{
    publicushort wYear;
    publicushort wMonth;
    publicushort wDayOfWeek;
    publicushort wDay;
    publicushort wHour;
    publicushort wMinute;
    publicushort wSecond;
    publicushort wMilliseconds;
}

STARTUPINFO

用于定义启动进程时的配置信息。

[StructLayout(LayoutKind.Sequential)]
publicstruct STARTUPINFO
{
    publicuint cb;
    publicstring lpReserved;
    publicstring lpDesktop;
    publicstring lpTitle;
    publicuint dwX;
    publicuint dwY;
    publicuint dwXSize;
    publicuint dwYSize;
    publicuint dwXCountChars;
    publicuint dwYCountChars;
    publicuint dwFillAttribute;
    publicuint dwFlags;
    publicshort wShowWindow;
    publicshort cbReserved2;
    public IntPtr lpReserved2;
    public IntPtr hStdInput;
    public IntPtr hStdOutput;
    public IntPtr hStdError;
}

PROCESS_INFORMATION

存储有关进程的信息。

[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
    public IntPtr hProcess;
    public IntPtr hThread;
    public uint dwProcessId;
    public uint dwThreadId;
}

3.2 常量

常量通常表示特定的操作标常量通常表示特定的操作标志或状态,在调用 Win32 API 时非常重要。以下是一些常用的 Win32 API 常量。

SW_* 常量

这些常量用于 ShowWindow 函数,控制窗口的显示方式。

public constint SW_HIDE = 0;  // 隐藏窗口
publicconstint SW_SHOWNORMAL = 1;  // 激活并显示窗口
publicconstint SW_SHOWMINIMIZED = 2;  // 最小化窗口
publicconstint SW_SHOWMAXIMIZED = 3;  // 最大化窗口
publicconstint SW_SHOWNOACTIVATE = 4;  // 不激活但显示窗口
publicconstint SW_SHOW = 5;  // 激活并显示窗口,设置窗口大小
publicconstint SW_MINIMIZE = 6;  // 最小化窗口
publicconstint SW_SHOWMINNOACTIVE = 7;  // 最小化窗口但不激活
publicconstint SW_RESTORE = 9;  // 恢复窗口

WM_* 消息常量

这些常量用于 SendMessage 函数,表示不同的窗口消息。

public constuint WM_CLOSE = 0x0010;  // 请求关闭窗口
publicconstuint WM_SETTEXT = 0x000C;  // 设置窗口文本
publicconstuint WM_GETTEXT = 0x000D;  // 获取窗口文本
publicconstuint WM_KEYDOWN = 0x0100;  // 键盘按下
publicconstuint WM_KEYUP = 0x0101;  // 键盘释放
publicconstuint WM_LBUTTONDOWN = 0x0201;  // 鼠标左键按下
publicconstuint WM_LBUTTONUP = 0x0202;  // 鼠标左键释放

PROCESS_* 常量

这些常量用于 CreateProcess 函数,指定进程的创建标志。

public const uint CREATE_NEW_CONSOLE = 0x00000010;  // 创建新控制台
public const uint CREATE_SUSPENDED = 0x00000004;  // 创建时挂起进程
public const uint CREATE_NO_WINDOW = 0x08000000;  // 不创建窗口

FILE_* 常量

这些常量用于 CreateFile 函数,指定文件操作的权限。

public constuint GENERIC_READ = 0x80000000;  // 读取权限
publicconstuint GENERIC_WRITE = 0x40000000;  // 写入权限
publicconstuint OPEN_EXISTING = 3;  // 打开现有文件
publicconstuint CREATE_NEW = 1;  // 创建新文件
publicconstuint FILE_SHARE_READ = 0x00000001;  // 允许其他进程读取文件
publicconstuint FILE_SHARE_WRITE = 0x00000002;  // 允许其他进程写入文件

4. 应用实例

以下是一个完整的示例,展示如何通过调用 Win32 API 获取窗口的标题,最小化窗口,并显示消息框。

示例代码

using System;
using System.Runtime.InteropServices;
using System.Text;

publicclassWin32APIExample
{
    // Win32 API 函数声明
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);

    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);

    // 常量
    publicconstint SW_MINIMIZE = 2;  // 最小化窗口

    public static void Main()
    {
        // 查找指定标题的窗口
        IntPtr hwnd = FindWindow(null"向日葵远程控制");

        if (hwnd != IntPtr.Zero)
        {
            Console.WriteLine("hwnd: 0x" + hwnd.ToString("X16"));
            // 获取窗口标题
            StringBuilder windowTitle = new StringBuilder(256);
            GetWindowText(hwnd, windowTitle, windowTitle.Capacity);
            Console.WriteLine("当前窗口标题: " + windowTitle);
            // 最小化窗口
            ShowWindow(hwnd, SW_MINIMIZE);
            // 显示消息框
            MessageBox(IntPtr.Zero, "窗口已最小化""信息"0);
        }
        else
        {
            Console.WriteLine("未找到指定窗口");
        }
    }
}

运行结果

解释:

  • • FindWindow:通过窗口的标题(此例中为 "向日葵远程控制")查找窗口句柄。
  • • GetWindowText:获取指定窗口的标题。
  • • ShowWindow:通过传入常量 SW_MINIMIZE 来最小化窗口。
  • • MessageBox:弹出一个消息框,通知用户窗口已被最小化。

5. 错误处理

当调用 Win32 API 函数时,如果操作失败,通常需要检查 Marshal.GetLastWin32Error() 来获取最后一次调用的错误代码。通过错误代码,开发者可以了解具体的失败原因。

例如,以下代码演示了如何获取错误代码:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFile(
    string lpFileName,
    uint dwDesiredAccess,
    uint dwShareMode,
    IntPtr lpSecurityAttributes,
    uint dwCreationDisposition,
    uint dwFlagsAndAttributes,
    IntPtr hTemplateFile
)
;

public static void CheckError()
{
    IntPtr hFile = CreateFile("nonexistentfile.txt", GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
    if (hFile == IntPtr.Zero)
    {
        int errorCode = Marshal.GetLastWin32Error();
        Console.WriteLine("Error occurred, error code: " + errorCode);
    }
}

常见错误代码:

  • • 2 (ERROR_FILE_NOT_FOUND):文件未找到。
  • • 5 (ERROR_ACCESS_DENIED):访问被拒绝。
  • • 87 (ERROR_INVALID_PARAMETER):参数无效。

6. 总结

通过使用 Win32 API,WinForms 应用程序能够执行许多底层操作,包括窗口管理、文件操作、进程管理等。P/Invoke 是实现这些操作的桥梁,它允许 C# 代码调用本地的 Win32 API 函数。在使用 Win32 API 时,开发者应了解不同函数的用法、常量和错误处理,以确保应用程序能够正确执行。

在实际开发过程中,尽量避免直接使用 Win32 API,尤其是在复杂应用中,因为它增加了代码的复杂性和错误的可能性。如果可能,使用更高级的 .NET Framework 或 .NET Core 类库,如 System.DiagnosticsSystem.IO 等,来代替 Win32 API。这些类库提供了更好的跨平台支持和易用性。


该文章在 2024/12/28 12:02:14 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved