MFC 編程:Windows 桌面應用程序開發框架

目錄

一.概述

二.MFC 與 Win32 的關系

三.CObject 類

1.CObject 類的主要功能

2.CObject 類的派生類

3.CObject 類成員函數

4.內存管理

對象的創建

對象的銷毀

引用計數

復制對象

5.序列化

序列化的概念

CObject 類的序列化功能

序列化示例

6.運行時類型信息

運行時類型信息的概念

CObject 類的 RTTI 功能

RTTI 示例

四.MFC 消息映射的實現

1.消息映射宏

消息映射宏概述

消息映射宏語法

消息映射宏示例

2.消息處理函數

3.消息處理過程

消息處理過程示例

消息處理過程的要點

五.MFC 對象的創建

1.創建對象

2.初始化對象

3.使用對象

4.銷毀對象

六.應用程序的退出

1.處理未保存的數據

2.釋放資源

3.注銷 MFC DLL

4.退出應用程序

總結


一.概述

????????MFC(Microsoft Foundation Class)是 Microsoft 公司提供的一套 C++ 類庫,用于在 Windows 平臺上開發桌面應用程序。MFC 提供了一套豐富的類和函數,抽象了 Windows API,簡化了 Windows 應用程序的開發過程。MFC 廣泛應用于各種 Windows 桌面應用程序中,包括辦公軟件、圖像處理軟件、游戲等。

二.MFC 與 Win32 的關系

????????Win32 API(Windows API)是 Microsoft 提供的底層 API,用于在 Windows 平臺上開發應用程序。Win32 API 提供了對 Windows 操作系統功能的直接訪問,但使用起來較為復雜和繁瑣。MFC 則是構建在 Win32 API 之上的一層封裝,它提供了一套面向對象的類,簡化了 Windows 應用程序的開發。MFC 抽象了 Win32 API 的細節,為程序員提供了一套更高級別的接口,使他們能夠更容易地實現復雜的 Windows 應用程序。

MFC 與 Win32 的主要區別如下:

  • 抽象層次: Win32 API 是面向過程的,而 MFC 是面向對象的。這意味著 MFC 抽象了 Win32 API 的細節,為程序員提供了一套更易于使用的類和對象。
  • 開發效率: 使用 Win32 API 開發應用程序需要編寫更多的代碼,而使用 MFC 可以顯著提高開發效率。MFC 提供了大量的類和函數,可以幫助程序員快速完成常見任務。
  • 代碼可維護性: 使用 MFC 開發的應用程序代碼通常比使用 Win32 API 開發的代碼更易于理解和維護。MFC 的類和對象具有良好的封裝性,可以提高代碼的可重用性和可維護性。

MFC 與 Win32 的優缺點比較:

特性Win32 APIMFC
抽象層次面向過程面向對象
開發效率較低較高
代碼可維護性較差較好
代碼執行效率較高較低
系統兼容性更好較差

三.CObject 類

????????CObject 類是 MFC 類庫中的基類,所有 MFC 類都直接或間接地派生自 CObject。CObject 類提供了 MFC 類庫的基本功能,包括內存管理、序列化、運行時類型信息等。CObject 類還定義了 MFC 類庫的公共接口,如創建對象、銷毀對象、訪問對象屬性等。

1.CObject 類的主要功能

  • 內存管理:CObject 類提供了內存管理功能,包括分配和釋放內存、跟蹤內存泄漏等。
  • 序列化:CObject 類支持序列化,即可以將對象的狀態保存到文件中或流中,以便以后恢復。
  • 運行時類型信息:CObject 類支持運行時類型信息 (RTTI),即可以獲取對象的類型信息,以便進行動態類型轉換等操作。
  • 公共接口:CObject 類定義了 MFC 類庫的公共接口,如創建對象、銷毀對象、訪問對象屬性等。

2.CObject 類的派生類

????????所有 MFC 類都直接或間接地派生自 CObject。派生自 CObject 類的類可以繼承 CObject 類的所有功能,并可以擴展 CObject 類的功能。

????????MFC 類庫提供了大量的派生自 CObject 的類,這些類可以用于實現各種各樣的 Windows 應用程序功能。例如,CDC 類用于實現設備上下文,CWnd 類用于實現窗口,CDocument 類用于實現文檔等。

3.CObject 類成員函數

????????CObject 類定義了大量的成員函數,用于實現 CObject 類的功能。以下是一些常用的 CObject 類成員函數:

創建對象new 運算符用于創建 CObject 類的對象。例如,以下代碼創建了一個 CDC 對象:

CDC* pDC = new CDC;

銷毀對象delete 運算符用于銷毀 CObject 類的對象。例如,以下代碼銷毀了 pDC 對象:?

delete pDC;

訪問對象屬性:CObject 類定義了大量的屬性,用于訪問對象的屬性值。例如,以下代碼獲取 pDC 對象的設備句柄:?

HWND hWnd = pDC->GetSafeHwnd();

4.內存管理

????????CObject 類提供了內存管理功能,包括對象的創建、銷毀和復制。MFC 類庫使用引用計數來管理對象的內存,當對象的引用計數變為 0 時,對象會被自動銷毀。

對象的創建

????????CObject 類的對象可以使用 new 運算符來創建。例如,以下代碼創建了一個 CDC 對象:

CDC* pDC = new CDC;
對象的銷毀

????????CObject 類的對象可以使用 delete 運算符來銷毀。例如,以下代碼銷毀了 pDC 對象:

delete pDC;
引用計數

????????MFC 類庫使用引用計數來管理對象的內存。每個對象都有一個引用計數,表示指向該對象的引用數。當對象的引用計數變為 0 時,對象會被自動銷毀。

例如,以下代碼創建了兩個指向 CDC 對象 pDC 的引用:

CDC* pDC = new CDC;
CDC* pDC2 = pDC;

此時,pDC 對象的引用計數為 2。

以下代碼將 pDC2 變量設置為 NULL:

pDC2 = NULL;

此時,pDC 對象的引用計數為 1。

以下代碼銷毀 pDC 對象:

delete pDC;

此時,pDC 對象的引用計數變為 0,對象會被自動銷毀。?

復制對象

????????CObject 類的對象可以使用 Clone() 函數來復制。例如,以下代碼復制了 pDC 對象:

CDC* pDC3 = pDC->Clone();

5.序列化

????????CObject 類提供了序列化功能,允許對象將自己的數據保存到磁盤文件中,或從磁盤文件中加載數據。序列化使對象能夠在不同進程或不同計算機之間傳輸數據。

序列化的概念

????????序列化是一種將對象的狀態保存到存儲介質(例如文件、內存或流)中的過程,以便以后可以恢復該狀態。反序列化是指將存儲介質中的數據加載到對象中的過程。

序列化通常用于以下目的:

  • 持久化數據:將對象的狀態保存到磁盤文件中,以便以后可以恢復該狀態。
  • 數據傳輸:將對象的狀態傳輸到另一個進程或另一臺計算機。
  • 存檔和恢復:將對象的備份保存到磁盤文件中,以便在發生故障時可以恢復該對象。
CObject 類的序列化功能

????????CObject 類提供了 Serialize() 函數和 IsSerializable() 函數來支持序列化。

  • Serialize() 函數用于將對象的狀態保存到存儲介質中或從存儲介質中加載數據。
  • IsSerializable() 函數用于判斷對象是否可序列化。

Serialize() 函數的原型如下:

void Serialize(CArchive& ar);

其中,ar 是一個 CArchive 對象,用于指定存儲介質。

Serialize() 函數會依次調用對象的各個成員函數的 Serialize() 函數來序列化對象的成員變量。

IsSerializable() 函數的原型如下:

BOOL IsSerializable();

????????如果對象可序列化,則該函數返回 TRUE;否則,返回 FALSE。

序列化示例

????????以下代碼演示了如何序列化一個 CDC 對象:

CDC* pDC = new CDC;CFile file("test.dat", CFile::modeCreate | CFile::modeWrite);
CArchive ar(&file, CArchive::archiveNormal);pDC->Serialize(&ar);ar.Close();
file.Close();delete pDC;

????????以上代碼將 pDC 對象的狀態保存到 test.dat 文件中。

????????以下代碼演示了如何從 test.dat 文件中加載一個 CDC 對象:

CFile file("test.dat", CFile::modeRead);
CArchive ar(&file, CArchive::archiveNormal);CDC* pDC2 = new CDC;
pDC2->Serialize(&ar);ar.Close();
file.Close();

6.運行時類型信息

????????CObject 類提供了運行時類型信息 (RTTI) 功能,允許對象在運行時獲取自己的類型信息,如類名、屬性名等。運行時類型信息使對象能夠動態地處理數據,實現靈活的編程。

運行時類型信息的概念

????????運行時類型信息 (RTTI) 是一種在運行時獲取對象類型信息的技術。RTTI 使程序能夠在不知道對象具體類型的情況下,對對象進行操作。

RTTI 通常用于以下目的:

  • 動態類型轉換:將對象轉換為另一種類型。
  • 類型檢查:檢查對象是否屬于某種類型。
  • 獲取對象信息:獲取對象的類名、屬性名等信息。
CObject 類的 RTTI 功能

CObject 類提供了以下 RTTI 函數:

  • IsKindOf() 函數:用于判斷對象是否屬于某種類型。
  • GetType() 函數:用于獲取對象的類型信息。
  • GetRuntimeClass() 函數:用于獲取對象的運行時類。

IsKindOf() 函數的原型如下:

BOOL IsKindOf(const CRuntimeClass* pClass);

其中,pClass 是要判斷的類的運行時類。

如果對象屬于 pClass 類或其派生類,則該函數返回 TRUE;否則,返回 FALSE。

GetType() 函數的原型如下:

CRuntimeClass* GetType();

該函數返回對象的運行時類。

GetRuntimeClass() 函數的原型如下:

const CRuntimeClass* GetRuntimeClass();
RTTI 示例

以下代碼演示了如何使用 IsKindOf() 函數來判斷對象是否屬于某種類型:

CDC* pDC = new CDC;if (pDC->IsKindOf(RUNTIME_CLASS(CDC)))
{// pDC 是一個 CDC 對象
}
else
{// pDC 不是一個 CDC 對象
}delete pDC;

以上代碼判斷 pDC 對象是否屬于 CDC 類。如果是,則執行 if 語句塊;否則,執行 else 語句塊。

以下代碼演示了如何使用 GetType() 函數來獲取對象的類型信息:

CDC* pDC = new CDC;CRuntimeClass* pClass = pDC->GetType();CString strClassName = pClass->GetClassName();delete pDC;

四.MFC 消息映射的實現

????????MFC 消息映射是 MFC 框架中一個重要的機制,它實現了 Windows 消息處理機制。MFC 框架將 Windows 消息映射到 MFC 類的成員函數,從而實現了對 Windows 消息的處理。MFC 消息映射機制簡化了 Windows 消息處理過程,使程序員能夠更容易地實現復雜的用戶界面和事件處理。

1.消息映射宏

????????MFC 提供了消息映射宏,如 BEGIN_MESSAGE_MAPON_COMMANDEND_MESSAGE_MAP 等,程序員可以使用這些宏來定義 MFC 類的成員函數與 Windows 消息之間的映射關系。消息映射宏使程序員能夠方便地處理 Windows 消息,而無需直接使用 Windows API 函數。

消息映射宏概述
  • BEGIN_MESSAGE_MAP 宏用于聲明消息映射的開始。
  • ON_COMMAND 宏用于將命令消息映射到成員函數。
  • END_MESSAGE_MAP 宏用于聲明消息映射的結束。
消息映射宏語法
BEGIN_MESSAGE_MAP(CMyClass, CWnd)ON_COMMAND(ID_MYCOMMAND, OnMyCommand)ON_WM_CREATE(&CMyClass::OnCreate)
END_MESSAGE_MAP()
  • CMyClass 是要映射消息的類名。
  • CWndCMyClass 類的基類名。
  • ID_MYCOMMAND 是要映射的命令消息 ID。
  • OnMyCommand 是處理 ID_MYCOMMAND 消息的成員函數名。
  • OnCreate 是處理 WM_CREATE 消息的成員函數名。
消息映射宏示例

?以下代碼演示了如何使用消息映射宏將命令消息 ID_MYCOMMAND 映射到成員函數 OnMyCommand

class CMyClass : public CWnd
{
public:BEGIN_MESSAGE_MAP(CMyClass, CWnd)ON_COMMAND(ID_MYCOMMAND, OnMyCommand)END_MESSAGE_MAP()void OnMyCommand();
};void CMyClass::OnMyCommand()
{// 處理 ID_MYCOMMAND 消息
}

2.消息處理函數

????????消息處理函數是 MFC 框架中用于處理 Windows 消息的函數。MFC 框架提供了默認的消息處理函數,如 CWnd::WindowProc,該函數負責將 Windows 消息路由到相應的成員函數。程序員可以通過重寫 CWnd::WindowProc 函數來處理自定義消息。

以下代碼演示了如何重寫 CWnd::WindowProc 函數來處理自定義消息 WM_MYMESSAGE

class CMyClass : public CWnd
{
public:BEGIN_MESSAGE_MAP(CMyClass, CWnd)ON_WM_MYMESSAGE(&CMyClass::OnMyMessage)END_MESSAGE_MAP()LRESULT OnMyMessage(UINT nMessage, WPARAM wParam, LPARAM lParam);
};LRESULT CMyClass::OnMyMessage(UINT nMessage, WPARAM wParam, LPARAM lParam)
{// 處理 WM_MYMESSAGE 消息return CWnd::OnMyMessage(nMessage, wParam, lParam);
}

3.消息處理過程

MFC 消息處理過程包括以下幾個步驟:

  1. Windows 操作系統將 Windows 消息發送給 MFC 應用程序

????????Windows 操作系統會將各種消息發送給應用程序,例如鼠標點擊、鍵盤按下、窗口創建等。這些消息都被封裝在 Windows 消息結構體中。

  1. MFC 框架將消息路由到相應的 MFC 類

????????MFC 應用程序通常有一個主窗口,負責接收來自 Windows 操作系統的所有消息。主窗口的消息處理函數會根據消息類型將消息路由到相應的 MFC 類。

  1. MFC 類根據消息映射將消息路由到相應的成員函數

????????每個 MFC 類都可以定義自己的消息映射,用于將 Windows 消息映射到成員函數。消息映射通常使用消息映射宏來定義。

  1. 成員函數處理消息并返回結果

????????當一個消息被路由到成員函數后,成員函數會根據消息類型和消息參數來處理消息。處理完成后,成員函數會返回一個結果。

消息處理過程示例

????????以下是一個典型的 MFC 消息處理過程示例:

  1. 用戶點擊一個按鈕。
  2. Windows 操作系統將一個 WM_LBUTTONDOWN 消息發送給 MFC 應用程序。
  3. MFC 應用程序的主窗口接收消息并將其路由到按鈕所在的窗口。
  4. 按鈕所在的窗口的消息處理函數根據消息映射將消息路由到按鈕的 OnClick 成員函數。
  5. OnClick 成員函數處理消息,例如更新按鈕的文本或觸發其他事件。
  6. OnClick 成員函數返回一個結果,指示消息是否已被處理。
消息處理過程的要點
  • MFC 消息處理過程是一個多層的消息路由機制。
  • 消息映射是 MFC 消息處理過程的關鍵。
  • 成員函數負責處理具體的 Windows 消息。

五.MFC 對象的創建

????????MFC 對象的創建通常包括以下幾個步驟:

1.創建對象

使用 new 運算符創建一個 MFC 對象。例如,以下代碼創建了一個 CDC 對象:

CDC* pDC = new CDC;
2.初始化對象

????????調用 MFC 對象的初始化函數,如 CWnd::CreateCDocument::Open 等,來初始化對象的狀態。例如,以下代碼創建了一個窗口并初始化它的狀態:

CWnd* pWnd = new CWnd;
pWnd->Create(WS_OVERLAPPEDWINDOW, _T("My Window"), WS_VISIBLE | WS_CHILD, CRect(0, 0, 300, 200), CWnd::GetDesktopWindow(), IDD_MYDIALOG);
3.使用對象

????????調用 MFC 對象的成員函數來使用對象的功能。例如,以下代碼使用 CDC 對象繪制一個矩形:

pDC->Rectangle(10, 10, 200, 100);
4.銷毀對象

????????當對象不再需要時,調用 delete 運算符銷毀對象。例如,以下代碼銷毀 pDC 和 pWnd 對象:

delete pDC;
delete pWnd;

六.應用程序的退出

????????MFC 應用程序的退出通常包括以下幾個步驟:

1.處理未保存的數據

????????MFC 應用程序通常需要處理未保存的數據,如提示用戶保存或自動保存。例如,以下代碼提示用戶保存文檔:

if (pDoc->IsModified())
{if (MessageBox(_T("是否保存文檔?"), _T("提示"), MB_YESNO) == IDYES){pDoc->Save();}
}

2.釋放資源

????????MFC 應用程序需要釋放占用的資源,如內存、文件句柄等。例如,以下代碼釋放內存:

delete pDC;
delete pWnd;

3.注銷 MFC DLL

????????MFC 應用程序需要注銷 MFC DLL,釋放 MFC 庫占用的資源。例如,以下代碼注銷 MFC DLL:

AfxOleUninitialize();

4.退出應用程序

????????MFC 應用程序調用 PostQuitMessage() 函數退出應用程序。例如,以下代碼退出應用程序:

PostQuitMessage(0);

?

總結

????????MFC 編程框架是 Windows 桌面應用程序開發的一套強大工具,它提供了一套豐富的類和函數,簡化了 Windows 應用程序的開發過程。

????????MFC 抽象了 Win32 API 的細節,為程序員提供了一套統一的接口,使他們能夠更容易地實現復雜的 Windows 應用程序。同時也 廣泛應用于各種 Windows 桌面應用程序中,并提供了大量的類和函數供程序員使用。

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

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

相關文章

uniapp App去除iOS底部安全區域白邊

未設置的情況下,iOS底部安全區域白邊 如圖: 去除方法: 在 mainfest.json 中加入一下代碼: "safearea" : {"bottom" : {"offset" : "none"} }, 去除效果展示:

Git使用筆記

Git使用筆記 介紹Git推送指定的提交 介紹 Git推送指定的提交 在Git中,如果只想推送一個特定的提交(commit),而不是整個分支,可以使用以下步驟: 首先,找到你想要推送的提交的哈希值。通過運行g…

開放式耳機2024超值推薦!教你如何選擇藍牙耳機!

開放式耳機的便利性讓它在我們的日常生活中變得越來越重要。它讓我們擺脫了傳統耳機的限制,享受到了更多的自由。不過,市面上的開放式耳機種類繁多,挑選一款既實用又實惠的產品確實需要一些小竅門。作為一位對開放式耳機頗有研究的用戶&#…

SOLC install 中的問題

solc.install 總是卡死,他拉取的網站出問題了 直接把所有的包都下載下來 sudo add-apt-repository ppa:ethereum/ethereum sudo apt-get update sudo apt-get install solc pip install py-solc-x 文檔 https://web3py.readthedocs.io/en/stable/web3.contract.h…

[WUSTCTF2020]funnyre

ida打開 mian 函數 不能反匯編,往下翻有一處報紅,一看是花指令,還怪長,報紅的都nop后,全選按P重新生成函數 三百多個變量,也是不太可能一個個去解了,剛好前兩天簡單練了一下 angr (…

C++多生產者,多消費者模型

C11實現多生產者,多消費者模型 在C標準庫中實現多生產者多消費者模型,可以使用std::thread、std::queue、互斥鎖(std::mutex)、條件變量(std::condition_variable)等組件。下面是一個簡單的示例,展示如何創建多生產者和多消費者模型&#xf…

3款錄屏錄制軟件,打造專業級視頻內容

隨著技術的不斷發展,人們在日常工作和學習中經常會遇到記錄電腦屏幕的需求,例如錄制游戲過程、制作教程、保存會議記錄等。為了解決這一需求,許多錄屏錄制軟件應運而生。本文將介紹三款常見的錄屏錄制軟件,通過分析它們的特點和使…

一文帶你搞懂DiT(Diffusion Transformer)

節前,我們組織了一場算法崗技術&面試討論會,邀請了一些互聯網大廠朋友、今年參加社招和校招面試的同學。 針對大模型技術趨勢、大模型落地項目經驗分享、新手如何入門算法崗、該如何準備面試攻略、面試常考點等熱門話題進行了深入的討論。 總結鏈接…

ArcGIS中分割與按屬性分割的區別

1、分割ArcGIS批量導出各個市的縣級行政邊界 視頻教學: ArcGIS批量導出各個市的縣級行政邊界002 2、ArcGIS批量導出全國各省的邊界 視頻教學: ArcGIS導出全國各省的邊界003 推薦學習: ArcGIS全系列實戰視頻教程——9個單一課程組合系列直播回…

[書生·浦語大模型實戰營]——第二節:輕松玩轉書生·浦語大模型趣味 Demo

1. 部署InternLM2-Chat-1.8B 模型進行智能對話 1.1配置環境 創建開發機 Intern Studio 官網網址:https://studio.intern-ai.org.cn/ 進入官網后,選擇創建開發機,填寫 開發機名稱 后,點擊 選擇鏡像 使用 Cuda11.7-conda 鏡像&am…

CSS中的Flex布局

目錄 一.什么是Flex布局 二.Flex布局使用 2.1Flex使用語法 2.2基本概念 三.容器的屬性 3.1所有屬性概述 3.2flex-direction 3.3flex-wrap 3.4flex-flow 3.5justify-content 3.6align-items 3.7align-content 四.項目(子元素)的屬性 4.1所有屬性概述 4.2order 4…

遺傳算法(Genetic Algorithm, GA)哪些步驟該丟給GPU

遺傳算法(Genetic Algorithm, GA)是一種啟發式搜索算法,受到生物進化的啟發。在遺傳算法中,種群中的每個個體代表問題的一個候選解,通過迭代選擇、交叉和變異操作,來模擬自然選擇和遺傳過程,從而…

九、OpenAI之圖片生成(Image generation)

學習用DALL.E的API怎樣生成和操作圖片 1 介紹 圖片API提供3個方法來和圖片進行交互: 從0開始基于文字提示創建圖片(DALL.E 3 and DALL.E2)基于一個新的提示詞,通過讓模型替換已有圖像的某些區域來創建圖像的編輯版本;(DALL.E2)…

【FPGA】Verilog:解碼器 | 編碼器 | 多路復用器(Mux, Multiplexer)

0x00 什么是解碼器 解碼器是根據輸入信號在多個輸出位中選擇一個輸出位的裝置。例如,當解碼器接收2位二進制值作為輸入時,它可以接收00、01、10、11四種輸入值,并根據每個輸入值在4個輸出位中選擇一個,輸出為1000、0100、0010、0001中的一種。這樣的解碼器被稱為高電平有效…

ICML 2024 Mamba 論文總結

2024ICML(International Conference on Machine Learning,國際機器學習會議)在2024年7月21日-27日在奧地利維也納舉行 🌟【緊跟前沿】“時空探索之旅”與你一起探索時空奧秘!🚀 歡迎大家關注時空探索之旅 …

【數據結構與算法 | 基礎篇】數組模擬棧

1. 前言 前文我們剛提及了如何用單向鏈表來模擬棧. 我們還可以用數組來模擬棧.使用棧頂指針top來進行棧頂的操作. 2. 數組模擬棧 (1). 棧接口 public interface stack<E> {//壓棧boolean push(E value);//彈棧, 棧非空返回棧頂元素E pop();//返回棧頂元素, 但不彈棧E…

IntelliJ IDEA常用快捷鍵 + 動圖演示!

本文參考了 IntelliJ IDEA 的官網&#xff0c;列舉了IntelliJ IDEA &#xff08;Windows 版&#xff09; 的所有快捷鍵。并在此基礎上&#xff0c;為 90% 以上的快捷鍵提供了動圖演示&#xff0c;能夠直觀的看到操作效果。 該快捷鍵共分 11 種&#xff0c;可以方便的按各類查找…

【通義千問—Qwen-Agent系列2】案例分析(圖像理解圖文生成Agent||多模態助手|| 基于ReAct范式的數據分析Agent)

目錄 前言一、快速開始1-1、介紹1-2、安裝1-3、開發你自己的Agent 二、基于Qwen-Agent的案例分析2-0、環境安裝2-1、圖像理解&文本生成Agent2-2、 基于ReAct范式的數據分析Agent2-3、 多模態助手 附錄1、agent源碼2、router源碼 總結 前言 Qwen-Agent是一個開發框架。開發…

Excel提取某一列的唯一值

點擊【篩選】&#xff08;【高級篩選】&#xff09;&#xff0c;參數里&#xff1a; 列表區域&#xff1a;為需要選擇唯一值的那一列復制到&#xff1a;生成唯一值的目標區域 據說新版本的excel有了unique()函數&#xff0c;可以很快捷的選擇某一列的唯一值&#xff0c;但是博…