C#基礎(⑦user32.dll)

我們來詳細學習如何使用?user32.dll,它是 Windows 系統中負責用戶界面交互的核心 DLL,包含窗口管理、消息處理、鍵盤鼠標輸入等功能。下面從基礎到進階,一步一步教你調用其中的常用函數。

在 C# 中調用?user32.dll?需要使用?DllImport?特性,這需要引入?System.Runtime.InteropServices?命名空間。所有示例都基于這個前提,先創建一個控制臺應用程序(或 Windows 應用程序),并在代碼開頭添加:

using System;
using System.Runtime.InteropServices; // 必須引入,用于DllImport

第一步:調用最基礎的函數 —— 顯示消息框(MessageBox)

MessageBox?是?user32.dll?中最常用的函數之一,用于顯示系統風格的彈窗。

步驟 1:聲明函數

首先需要在 C# 中聲明?user32.dll?中的?MessageBox?函數,函數定義要和 DLL 中的原生接口一致:

// 聲明 user32.dll 中的 MessageBox 函數
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd,       // 父窗口句柄(null表示無父窗口)string lpText,     // 彈窗內容string lpCaption,  // 彈窗標題uint uType         // 彈窗樣式(按鈕、圖標組合)
);

CharSet = CharSet.Unicode:確保中文等字符正常顯示。
返回值 int:表示用戶點擊的按鈕(如 1 = 確定,2 = 取消)。

步驟 2:調用函數

在?Main?方法中調用聲明好的函數,測試不同樣式的彈窗:

static void Main(string[] args)
{// 示例1:基礎彈窗(只有"確定"按鈕)int result1 = MessageBox(IntPtr.Zero,       // 無父窗口"這是一個簡單的消息框", // 內容"基礎示例",         // 標題0x00000000         // 樣式:只有"確定"按鈕(0));Console.WriteLine($"用戶點擊了按鈕:{result1}"); // 點擊"確定"會輸出 1// 示例2:帶"確定"和"取消"按鈕 + 警告圖標int result2 = MessageBox(IntPtr.Zero,"是否繼續操作?","確認提示",0x00000003 | 0x00000030  // 0x3=確定+取消;0x30=警告圖標(組合用 |));Console.WriteLine($"用戶點擊了按鈕:{result2}"); // 確定=1,取消=2
}

運行效果
第一個彈窗只有 “確定” 按鈕,點擊后控制臺輸出 1。
第二個彈窗有 “確定”“取消” 按鈕和警告圖標,點擊對應按鈕會輸出 1 或 2。

第二步:獲取屏幕分辨率(GetSystemMetrics)

GetSystemMetrics?函數可以獲取系統相關的尺寸信息,比如屏幕寬度、高度。

步驟 1:聲明函數

// 聲明獲取系統尺寸的函數
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int nIndex);

參數 nIndex:指定要獲取的信息(比如 0 = 屏幕寬度,1 = 屏幕高度)。

步驟 2:調用函數

static void Main(string[] args)
{// 獲取屏幕寬度(參數 0 表示 SM_CXSCREEN)int screenWidth = GetSystemMetrics(0);// 獲取屏幕高度(參數 1 表示 SM_CYSCREEN)int screenHeight = GetSystemMetrics(1);Console.WriteLine($"屏幕分辨率:{screenWidth} × {screenHeight}");// 額外示例:獲取任務欄高度(參數 29 表示 SM_CYCAPTION)int taskbarHeight = GetSystemMetrics(29);Console.WriteLine($"任務欄高度:{taskbarHeight} 像素");
}

運行效果

控制臺會輸出你的屏幕分辨率(如?1920 × 1080)和任務欄高度。

第三步:查找窗口并操作(FindWindow + SetWindowText)

    FindWindow:根據窗口標題或類名查找窗口句柄(類似窗口的 “身份證”)。
    SetWindowText:修改窗口的標題。

    // 查找窗口(根據類名和窗口名)
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);// 修改窗口標題
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern bool SetWindowText(IntPtr hWnd, string lpString);

    步驟 2:調用函數(實戰:修改記事本窗口標題)
    先手動打開一個記事本(Notepad),標題默認為 “無標題 - 記事本”。
    運行以下代碼:

    static void Main(string[] args)
    {// 查找記事本窗口(類名"Notepad",標題"無標題 - 記事本")IntPtr notepadWnd = FindWindow("Notepad", "無標題 - 記事本");if (notepadWnd != IntPtr.Zero){// 找到窗口后,修改標題bool success = SetWindowText(notepadWnd, "被C#修改過的標題 - 記事本");if (success){Console.WriteLine("記事本標題修改成功!");}else{Console.WriteLine("標題修改失敗");}}else{Console.WriteLine("未找到記事本窗口,請先打開記事本");}
    }

    運行效果

    如果記事本已打開且標題正確,它的標題會被改為 “被 C# 修改過的標題 - 記事本”。

    四、移動鼠標:SetCursorPos?函數

    SetCursorPos?可以直接設置鼠標指針在屏幕上的位置,非常直觀。

    步驟 1:聲明函數

    using System;
    using System.Runtime.InteropServices;class User32Demo
    {// 聲明 SetCursorPos 函數:設置鼠標位置[DllImport("user32.dll")]public static extern extern bool SetCursorPos(int X, int Y);// 參數:X(水平坐標)、Y(垂直坐標),返回值:是否成功
    }

    步驟 2:使用函數移動鼠標

    static void Main(string[] args)
    {// 1. 移動鼠標到屏幕左上角(0, 0)bool success1 = SetCursorPos(0, 0);Console.WriteLine($"移動到左上角:{ (success1 ? "成功" : "失敗") }");// 等待1秒,讓你看清效果System.Threading.Thread.Sleep(1000);// 2. 移動鼠標到屏幕中心(假設屏幕分辨率是1920×1080)int screenWidth = 1920;  // 可通過前面學的 GetSystemMetrics(0) 獲取實際寬度int screenHeight = 1080; // 可通過 GetSystemMetrics(1) 獲取實際高度bool success2 = SetCursorPos(screenWidth / 2, screenHeight / 2);Console.WriteLine($"移動到中心:{ (success2 ? "成功" : "失敗") }");// 等待1秒System.Threading.Thread.Sleep(1000);// 3. 移動鼠標到右下角bool success3 = SetCursorPos(screenWidth - 10, screenHeight - 10);Console.WriteLine($"移動到右下角:{ (success3 ? "成功" : "失敗") }");
    }

    運行效果

    鼠標會依次移動到屏幕左上角 → 中心 → 右下角,每次移動后會在控制臺顯示結果。

    五、發送窗口消息:SendMessage?函數

    SendMessage?是?user32.dll?中非常強大的函數,它可以向指定窗口發送各種消息(如點擊按鈕、輸入文本、關閉窗口等),實現對窗口的精細控制。

    先理解:什么是 “窗口消息”?
    Windows 系統中,所有窗口交互都是通過 “消息” 機制實現的。例如:

    點擊按鈕 → 窗口收到 WM_LBUTTONDOWN(左鍵按下)消息
    鍵盤輸入 → 窗口收到 WM_CHAR(字符輸入)消息
    窗口關閉 → 窗口收到 WM_CLOSE 消息

    SendMessage 就是手動給窗口發送這些消息,模擬用戶操作。

    步驟 1:聲明函數和常用消息常量

    class User32Demo
    {// 聲明 SendMessage 函數:發送消息到窗口[DllImport("user32.dll", CharSet = CharSet.Unicode)]public static extern IntPtr SendMessage(IntPtr hWnd,    // 目標窗口句柄(通過 FindWindow 獲取)uint Msg,       // 消息類型(如 WM_CLOSE 表示關閉窗口)IntPtr wParam,  // 消息參數1(根據消息類型變化)string lParam   // 消息參數2(字符串類型,如輸入的文本));// 常用消息常量(可在微軟文檔中查詢更多)public const uint WM_CLOSE = 0x0002;         // 關閉窗口消息public const uint WM_SETTEXT = 0x000C;       // 設置窗口文本(如輸入框內容)public const uint WM_LBUTTONDOWN = 0x0201;   // 鼠標左鍵按下public const uint WM_LBUTTONUP = 0x0202;     // 鼠標左鍵釋放(模擬點擊)
    }

    步驟 2:實戰 1:關閉指定窗口(發送?WM_CLOSE?消息)

    以關閉記事本為例:

    static void Main(string[] args)
    {// 1. 先找到記事本窗口(確保已打開,標題為"無標題 - 記事本")IntPtr notepadWnd = FindWindow("Notepad", "無標題 - 記事本");if (notepadWnd == IntPtr.Zero){Console.WriteLine("未找到記事本窗口");return;}// 2. 發送關閉窗口消息(WM_CLOSE)SendMessage(notepadWnd, User32Demo.WM_CLOSE, IntPtr.Zero, null);Console.WriteLine("已發送關閉消息,記事本應該會關閉");
    }// 注意:需要先聲明前面學過的 FindWindow 函數
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    運行效果

    如果記事本已打開,會收到關閉消息并彈出保存提示(和手動點擊關閉按鈕效果一致)。

    步驟 3:實戰 2:向記事本輸入文本(發送?WM_SETTEXT?消息)

    記事本的編輯區域是一個子窗口(類名?"Edit"),需要先找到它的句柄,再發送輸入消息:

    static void Main(string[] args)
    {// 1. 找到記事本主窗口IntPtr notepadWnd = FindWindow("Notepad", null); // 忽略標題,找所有記事本if (notepadWnd == IntPtr.Zero){Console.WriteLine("請先打開一個記事本");return;}// 2. 找到記事本的編輯區域子窗口(類名"Edit",無標題)IntPtr editWnd = FindWindowEx(notepadWnd, IntPtr.Zero, "Edit", null);if (editWnd == IntPtr.Zero){Console.WriteLine("未找到編輯區域");return;}// 3. 發送輸入文本消息(WM_SETTEXT)SendMessage(editWnd, User32Demo.WM_SETTEXT, IntPtr.Zero, "這是通過 SendMessage 輸入的文本!");Console.WriteLine("已向記事本輸入文本");
    }// 額外聲明 FindWindowEx 函數(用于查找子窗口)
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindowEx(IntPtr hWndParent,  // 父窗口句柄IntPtr hWndChildAfter, // 起始子窗口(null表示從第一個開始)string lpClassName, // 子窗口類名string lpWindowName // 子窗口標題
    );

    運行效果

    記事本的編輯區域會自動填入文本 “這是通過 SendMessage 輸入的文本!”。

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/web/95354.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/web/95354.shtml
    英文地址,請注明出處:http://en.pswp.cn/web/95354.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    Markdown格式.md文件的編輯預覽使用

    推薦工具Visual Studio Code (VS Code) - 強烈推薦特點:微軟出品,免費、開源、跨平臺(Windows, macOS, Linux)。擁有海量插件市場。編輯體驗:安裝 Markdown All in One 等插件后,可以獲得語法高亮、實時預覽…

    TypeScript:unknown 類型

    作為前端開發工程師,在 TypeScript 中使用 unknown 類型是提升類型安全的關鍵實踐。下面我會結合實際開發場景詳細講解其特性和價值。unknown 核心特性1.類型安全的頂級類型與 any 類似,可接受任何類型的賦值:let userInput: unknown; userIn…

    2025 批量下載hasmart所有知乎回答,文章和想法,導出txt,html和pdf

    之前分享過文章2025 一鍵批量下載備份知乎回答/文章/想法/專欄/視頻/收藏夾,導出txt,html和 pdf ,今天繼續下載hasmart這個號的所有知乎回答 下載的知乎回答目錄,包含發布時間和標題,點擊可跳轉對應回答。 2019年發布…

    mapbox高階,結合threejs(threebox)添加管道,實現管道流動效果

    ????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言 1.1 ??mapboxgl.Map 地圖對象 1.2 ??mapboxgl.Map style屬性 1.3 ??threebox add加載網格對象 二、??…

    語音識別后處理——如何語音斷句加上標點、順滑、ITN等

    基本流程 基于cpu的計算: 前往intel官網下載libmkl相關的庫:libmkl_core.a、libmkl_gf_lp64.a、libmkl_sequential.a # 靜默安裝 ./intel-onemkl-2025.2.0.629_offline.sh -a -s --eula accept默認安裝目錄:/opt/intel/oneapi libmkl相關的…

    [吾愛出品] 圖片轉換王 v1.01 - 多格式支持 / 支持pds、Ai格式

    [吾愛出品] 圖片轉換王 多格式支持 鏈接:https://pan.xunlei.com/s/VOZ81aeES9JDqlcvXPKYlxwqA1?pwdni9b# 圖片轉換王」是一款專為設計師、自媒體從業者及普通用戶打造的專業圖片格式轉換工具,秉持綠色便攜理念,無需繁瑣安裝步驟&#xf…

    GitLab 18.3 正式發布,更新多項 DevOps、CI/CD 功能【一】

    沿襲我們的月度發布傳統,極狐GitLab 發布了 18.3 版本,該版本帶來了通過直接轉移進行遷移、CI/CD 作業令牌的細粒度權限控制、自定義管理員角色、Kubernetes 1.33 支持、通過 API 讓流水線執行策略訪問 CI/CD 配置等幾十個重點功能的改進。下面是對部分重…

    【macOS】垃圾箱中文件無法清理的--特殊方法

    【macOS】垃圾箱中文件無法清理的特殊方法直接拖拽到 Beyond Compare App中,刪除時,選擇以下選項即可徹底刪除。1.在macOS桌面,將垃圾箱打開2.將垃圾文件和文件夾,拖拽到Beyond Compare界面3.選中待刪除的文件和文件夾如上圖。4.鼠…

    Python UV 管理如何使用鏡像源安裝 Python

    uv python install [版本號] --mirrorhttps://github.com/astral-sh/python-build-standalone/releases/download/這是默認情況下 uv python 安裝命令,命令會找到 astral 公司在 Github 上的存儲庫,然后進行下載。我們只需要為 mirror 增加任意 Github 鏡…

    SPI片選踩坑實錄(硬件片選和軟件片選)

    SPI(Serial Peripheral Interface,串行外設接口)的片選信號(Chip Select,簡稱 CS 或 SS,即 Slave Select)是 SPI 通信中用于選擇從設備的關鍵控制信號,其作用是在多從設備的 SPI 總線…

    從理論到RTL,實戰實現高可靠ECC校驗(附完整開源代碼/腳本)(3) RTL實現實戰

    第二部分:ECC (30, 24)RTL實現實戰 - 精雕細琢的硬件衛士 理論是基石,實現是關鍵。本部分將 手把手構建參數化、可綜合、高可靠的ECC編解碼器 。本部分將以MIPI 協議中Packet Header 用到的ECC(30,24) 為例…

    揭密設計模式:像搭樂高一樣構建功能的裝飾器模式

    揭密設計模式:像搭樂高一樣構建功能的裝飾器模式 在軟件開發中,我們常常會遇到一個問題:如何給一個對象動態地添加新功能,同時又不想修改它的代碼?如果直接在原有類上修修補補,代碼會變得臃腫復雜&#xff…

    【Vue】前端 vue2項目搭建入門級(二)

    本文不同于【Vue】前端 vue2項目搭建入門級(一),本文創建vue2項目方式是一鍵創建vue2 項目,不需要自己配置。1.cmd進入根目錄,輸入vue create project(vue create 項目名)創建一個project的項目…

    基于SQLite索引的智能圖片壓縮存儲系統設計與實現

    摘要 本文介紹一種基于SQLite索引的智能圖片壓縮存儲系統,通過融合圖像質量壓縮與數據壓縮技術,實現60-80%的壓縮率,較傳統方法壓縮效率提升4-5倍。系統采用“大文件存儲索引數據庫”架構,針對性解決海量圖片數據遷移與存儲中的核…

    【一張圖看懂Kafka消息隊列架構】

    一張圖看懂Kafka消息隊列架構Kafka架構全景圖ApacheKafka作為當今最流行的分布式消息隊列系統,其架構設計精巧而高效。通過一張典型的Kafka架構圖,我們可以清晰地看到幾個核心組件:生產者(Producer)、消費者(Consumer)、主題(Topic)、分區(Pa…

    計算機三級嵌入式填空題——真題庫(24)原題附答案速記

    1.表征數字音頻每秒鐘數據量的參數稱為波形聲音的__碼率__。CD音樂的聲音信號的采樣率約為44kHz,量化位數為16位,采用雙聲道,則該參數的值為__1408__kb/s。(碼率取樣頻率*量化位數*聲道數44kHz*16*21408kb/s)2.利用載波…

    Gradle vs. Maven,Java 構建工具該用哪個?

    Java構建工具的甜咸粽子之爭,就是 Gradle 和 Maven 該用哪個? 隨心所欲的手動擋 vs. 穩如老狗的自動擋 Maven用的是pom.xml。很多人一聽XML就頭大,覺得又臭又長。但換個角度想,XML的缺點正是它最大的優點:死板、規范、…

    將Markdown文檔輸出成Word格式

    大家好!今天想和大家分享一個技術文檔格式轉換的小故事。有個朋友在軟件行業從事文檔工作,她們的手冊是用Markdown編寫的,使用Facebook的Docsaurus框架,在線瀏覽很方便,但輸出Word格式卻很不方便,問我是否有…

    COMSOL基于Voronoi毛細管及多邊形骨料ITZ的微介觀混凝土水分擴散模型

    本案例是通過COMSOL對論文An innovative method for mesoscale modelling of moisture diffusion in concrete(https://doi.org/10.1016/j.cemconcomp.2024.105836)中Voronoi毛細管、多邊形骨料、ITZ、水泥漿體多相材料的幾何模型復現。 其中論文中的混…

    機器學習和高性能計算中常用的幾種浮點數精度

    浮點數 (Floating-Point Number) 是一種在計算機中表示帶有小數部分的數字的方式。它通過科學記數法類似的方式(尾數 基數 ^ 指數)來近似表示實數。浮點數的精度決定了它可以表示的數值范圍以及數值之間的精細程度。 常見的浮點數精度包括:F…