MFC 基礎

?windows桌面應用分為兩種類型: 基于文檔視圖類型 和 基于對話框類型。 通常具有復雜交互控件的程序即為基于對話框類型,相對而言比較復雜,而基于文檔視圖類的應用交互形式比較單一,相對簡單。下面給出基于mfc框架的最基本的桌面程序示例:

// 1. 創建控制臺空項目
// 2. 項目屬性--> 高級-->MFC的應用:[使用標準 Windows 庫]  改成  [在共享 DLL 中使用 MFC]
// 3. 項目屬性-->鏈接器-->系統-->子系統:[控制臺 (/SUBSYSTEM:CONSOLE)] 改成 [窗口 (/SUBSYSTEM:WINDOWS)]#include <afxwin.h>
class BaseWinApp:public CWinApp
{
public:BaseWinApp();virtual BOOL InitInstance() override;
};class BaseMainFrame:public CFrameWnd
{
public:BaseMainFrame();
};BaseMainFrame::BaseMainFrame()
{}BaseWinApp::BaseWinApp()
{}BOOL BaseWinApp::InitInstance()
{BaseMainFrame* pFrame = new BaseMainFrame();pFrame->Create(NULL, "BaseFrame");m_pMainWnd = pFrame;pFrame->ShowWindow(SW_SHOW);pFrame->UpdateWindow();return TRUE;
}BaseWinApp theApp;//全局唯一// 主線程啟動順序(最終進入一個事件循環):
// WinMain: appmodul.cpp
//                 AfxWinMain: winmain.cpp
//                              (CWinApp*)(&theApp)->InitApplication  應用資源初始化,是虛函數,可以在子類中重寫,做一些特殊資源的初始化
//                              (CWinThread*)(&theApp)->InitInstance  用戶重寫的InitInstance
//                              (CWinThread*)(&theApp)->Run: appcore.cpp
//                                                  (CWinThread*)(&theApp)->CWinThread::Run(): thrdcore.cpp  進入事件循環,處理消息// 當消息產生后會在消息循環中偵測到,并在DispatchMessage內部調用對應窗口的處理回調(如AfxWndProc: wincore.cpp)進行消息處理// MFC 中創建線程的兩種方法:
//		1. CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, ...); 調用該接口,傳入線程函數,生成一個CWinThread線程管理對象
//		2. CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass,...); 繼承CWinThread實現新的Thread類,并聲明Runtime信息, 傳入新類的RuntimeClass,生成一個線程管理對象。(即CWinApp的做法)//	通過這兩種方法創建的新線程,與當前線程公用同一個消息隊列,以便在兩個線程之間完成通信

?基于對話框的應用,可以先看win32 框架下的示例,對程序的運行框架有一個大致的理解:

#include <windows.h>
#include <iostream>
#include "resource.h"//要給項目添加資源文件//本例需要在資源文件中添加一個Dialog控件(ID為IDD_DIALOG1)和一個Menu控件(ID為IDR_MENU1,MENU中要增加菜單欄和菜單項)HINSTANCE g_hInstance = NULL;
HWND hddd = NULL;INT_PTR CALLBACK DlgProc(HWND hwndlg,UINT msgID,WPARAM wParam, LPARAM lParam)
{switch (msgID){case WM_SYSCOMMAND:if (wParam == SC_CLOSE){HWND pHwnd = GetParent(hwndlg);DestroyWindow(hwndlg);EnableWindow(pHwnd, TRUE);}else//不知道如何處理的消息,則讓框架處理return FALSE;break;case WM_DESTROY:MessageBox(NULL,L"Dialog Destroyed",L"Notify",MB_OK);break;case WM_COMMAND:if(wParam == IDOK)MessageBox(NULL, L"User Confirmed",L"Dialog Result",  MB_OK);else if(wParam == IDCANCEL)MessageBox(NULL, L"User Denied",  L"Dialog Result",MB_OK);break;default:return FALSE;break;}return TRUE;
}void OnNoModel(HWND hWnd)
{HWND pHwnd = GetParent(hWnd);EnableWindow(pHwnd,FALSE);//HWND hDlg = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1),hWnd,DlgProc);// 等效步驟①②③④⑤⑥//創建對話窗對象,并和對話框控件(資源中創建,ID為IDD_DIALOG1)綁定HRSRC hRs = FindResource(g_hInstance,MAKEINTRESOURCE(IDD_DIALOG1),RT_DIALOG);//①HGLOBAL hGl = LoadResource(g_hInstance,hRs);//②LPDLGTEMPLATE pTemplate = (LPDLGTEMPLATE)LockResource(hGl);//③HWND hDlg = CreateDialogIndirect(g_hInstance,pTemplate,hWnd, DlgProc);//④UnlockResource(hGl);//⑤FreeResource(hGl);//⑥hddd = hDlg;ShowWindow(hDlg, SW_SHOW);//立即返回不阻塞
}void OnCommand(HWND hWnd,WPARAM wParam )
{WORD ID = LOWORD(wParam);//控件IDWORD Code = HIWORD(wParam);//通知類型switch (ID){case ID_FFF:// 資源文件中定義菜單欄下拉的菜單選項對應的資源ID,點擊該菜單項將創建一個對話框出來OnNoModel(hWnd);break;default:break;}
}LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{LRESULT lRet = 0;switch (msgID){case WM_DESTROY:PostQuitMessage(0);break;case WM_COMMAND:OnCommand(hWnd,wParam);break;default:lRet = DefWindowProc(hWnd, msgID, wParam, lParam);break;}return lRet;
}int CALLBACK WinMain(HINSTANCE hIns,HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{g_hInstance = hIns;WNDCLASS wc = {};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName =L"Main";//wc.lpszMenuName = NULL;// IDR_MENU1 在資源文件中添加一個菜單資源,資源ID為IDR_MENU1wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);wc.style = CS_HREDRAW | CS_VREDRAW;RegisterClass(&wc);HWND hWnd = CreateWindowEx(0,L"Main",L"window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);MSG nMsg = {};// AllocConsole();//打日志用// FILE* f = NULL;// freopen_s(&f,"CONOUT$", "w", stdout);while (GetMessage(&nMsg, NULL, 0, 0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//將消息交給窗口處理函數處理}//fclose(f);return 0;
}

對話框程序示例

#include <afxwin.h>
#include <afxcmn.h>
#include "resource.h"//本例需要在資源文件中添加一個Dialog控件(ID為IDD_DIALOG1) class MainDialog : public CDialog
{DECLARE_MESSAGE_MAP()enum { IDD = IDD_DIALOG1 };
public:MainDialog():CDialog(IDD){}void OnIdle(){}//可在此處理低優先級任務
protected:BOOL OnInitDialog() override{return CDialog::OnInitDialog();}void OnClosed(void){::DestroyWindow(this->m_hWnd);}void AFX_MSG_CALL OnSysCommand(UINT msgID, LPARAM lParam){DWORD cmdType = msgID & 0xFFF0;switch (cmdType){case SC_CLOSE://處理標題欄的關閉事件OnClosed();break;default:CDialog::OnSysCommand(msgID, lParam);break;}}void DoDataExchange(CDataExchange* pDX) override{}
};
BEGIN_MESSAGE_MAP(MainDialog, CDialog)ON_WM_SYSCOMMAND()
END_MESSAGE_MAP()class BaseWinApp :public CWinApp
{
public:BaseWinApp();virtual BOOL InitInstance() override;virtual BOOL OnIdle(LONG lCount) override;
};BaseWinApp::BaseWinApp()
{InitApplication();
}BOOL BaseWinApp::InitInstance()
{MainDialog* pFrame = new MainDialog();pFrame->Create(IDD_DIALOG1,NULL);m_pMainWnd = pFrame;pFrame->ShowWindow(SW_SHOW);//LONG wProc = GetWindowLongPtr(pFrame->m_hWnd, GWLP_WNDPROC);//that should be AfxWndProc//WNDPROC fun = AfxWndProc;//BOOL bRet = fun == (WNDPROC)wProc;//delete pFrame;return TRUE;
}BOOL BaseWinApp::OnIdle(LONG lCount)
{if (m_pMainWnd != NULL)((MainDialog*)m_pMainWnd)->OnIdle();return CWinThread::OnIdle(lCount);
}BaseWinApp theApp;

單文檔程序示例


#include <afxwin.h>
#include <afxext.h>
#include "resource.h"//本例需要在資源文件中添加一個Menu控件(ID為IDR_MENU1) 和一個String Table(添加字符串資源:ID=AFX_IDS_UNTITLED, Value=61443,Caption=自定義)class CMyDoc :public CDocument
{DECLARE_DYNCREATE(CMyDoc)
};
IMPLEMENT_DYNCREATE(CMyDoc,CDocument)class CMyView :public CView
{DECLARE_DYNCREATE(CMyView)
public:virtual void OnDraw(CDC* pDC);
};
void CMyView::OnDraw(CDC* pDC)
{pDC->TextOut(100,100,"this is a view wnd");
}
IMPLEMENT_DYNCREATE(CMyView, CView)class CMyFrameWnd : public CFrameWnd
{DECLARE_DYNCREATE(CMyFrameWnd)
};
IMPLEMENT_DYNCREATE(CMyFrameWnd, CFrameWnd)class CMyWinApp : public CWinApp
{
public:virtual BOOL InitInstance();
};BOOL CMyWinApp::InitInstance()
{/************  方式一 Begin************************************///CSingleDocTemplate* pTemplate = new CSingleDocTemplate(IDR_MENU1,//    RUNTIME_CLASS(CMyDoc),//	RUNTIME_CLASS(CMyFrameWnd), //    RUNTIME_CLASS(CMyView));//AddDocTemplate(pTemplate);//OnFileNew();/************  方式一 End************************************/	/**********************方式二 Begin: **************************/ CMyFrameWnd* pFrame = new CMyFrameWnd;CMyDoc* pDoc = new CMyDoc;CCreateContext cct;cct.m_pCurrentDoc = pDoc;cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);pFrame->LoadFrame(IDR_MENU1,WS_OVERLAPPEDWINDOW,NULL,&cct);m_pMainWnd = pFrame;/**********************方式二 End **************************/m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();return TRUE;
}CMyWinApp theApp;

多文檔程序示例

#include <afxwin.h>
#include <afxext.h>
#include "resource.h"
//本例需要在資源文件中添加兩個Menu控件(ID為IDR_MENU1和IDR_MENU2) 和一個String Table(添加字符串資源:ID=AFX_IDS_UNTITLED, Value=61443,Caption=自定義)class CMyDoc :public CDocument
{DECLARE_DYNCREATE(CMyDoc)
};
IMPLEMENT_DYNCREATE(CMyDoc, CDocument)class CMyView :public CView
{DECLARE_DYNCREATE(CMyView)
public:virtual void OnDraw(CDC* pDC);
};
void CMyView::OnDraw(CDC* pDC)
{pDC->TextOut(100, 100, "I am a view wnd");
}
IMPLEMENT_DYNCREATE(CMyView, CView)class CMyChild :public CMDIChildWnd
{DECLARE_DYNCREATE(CMyChild)
};
IMPLEMENT_DYNCREATE(CMyChild, CMDIChildWnd)class CMyFrameWnd : public CMDIFrameWnd
{
public:CMyFrameWnd() :CMDIFrameWnd() {}BOOL PreCreateWindow(CREATESTRUCT& cs) override{m_strTitle = "MasterWnd";//修改主窗口標題return CMDIFrameWnd::PreCreateWindow(cs);}
public:DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMyFrameWnd, CMDIFrameWnd)
END_MESSAGE_MAP()class CMyWinApp : public CWinApp
{
public:virtual BOOL InitInstance();
};BOOL CMyWinApp::InitInstance()
{CMyFrameWnd* pFrame = new CMyFrameWnd();pFrame->LoadFrame(IDR_MENU1);//MENU1為主框架窗口的菜單(MENU1至少需要兩個菜單欄)m_pMainWnd = pFrame;CMultiDocTemplate* pTemplate = new CMultiDocTemplate(IDR_MENU2,//MENU2為子框架窗口的菜單RUNTIME_CLASS(CMyDoc),RUNTIME_CLASS(CMyChild),RUNTIME_CLASS(CMyView));AddDocTemplate(pTemplate);OnFileNew();//創建三個子窗口OnFileNew();OnFileNew();m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();return TRUE;
}CMyWinApp theApp;

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

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

相關文章

npm無法加載文件 因為此系統禁止運行腳本

安裝nodejs后遇到問題&#xff1a; 在項目里【node -v】可以打印出來&#xff0c;【npm -v】打印不出來&#xff0c;顯示npm無法加載文件 因為此系統禁止運行腳本。 但是在winr&#xff0c;cmd里【node -v】,【npm -v】都也可打印出來。 解決方法&#xff1a; cmd里可以打印出…

JVM春招快速學習指南

1.說在前面 在Java相關崗位的春/秋招面試過程中&#xff0c;JVM的學習是必不可少的。本文主要是通過《深入理解Java虛擬機》第三版來介紹JVM的學習路線和方法&#xff0c;并對沒有過JVM基礎的給出閱讀和學習建議&#xff0c;盡可能更加快速高效的進行JVM的學習與秋招面試的備戰…

DeepSeek API 調用 - Spring Boot 實現

DeepSeek API 調用 - Spring Boot 實現 1. 項目依賴 在 pom.xml 中添加以下依賴&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></depe…

認識Electron 開啟新的探索世界一

一、Electron輕松入門 1.搭建開發環境&#xff1a; 一般情況下開發者會使用node.js來創建electron項目&#xff0c;node.js是一個基于Chrome V8引擎的javascript運行環境&#xff0c;所以首先需要到官網去下載安裝node.js 下載鏈接&#xff1a;https://nodejs.org/enhttps://no…

MySQL下載過程

MySQL Enterprise Edition Downloads | Oracle mysql官方下載網址&#xff08;9.2版本&#xff09; 下面的示例是5.7的包&#xff0c;過程是一樣的 port&#xff1a;3308&#xff08;默認的是3306&#xff0c;筆者下了一個占用了該端口&#xff09; root&#xff1a;123456 問題…

【學術投稿】第五屆計算機網絡安全與軟件工程(CNSSE 2025)

重要信息 官網&#xff1a;www.cnsse.org 時間&#xff1a;2025年2月21-23日 地點&#xff1a;中國-青島 簡介 第五屆計算機網絡安全與軟件工程&#xff08;CNSSE 2025&#xff09;將于2025年2月21-23日在中國-青島舉行。CNSSE 2025專注于計算機網絡安全、軟件工程、信號處…

Qt:QWidget核心屬性

目錄 QWidget核心屬性 enab geometry WindowFrame的影響 windowTitle windowIcon qrc文件管理資源 windowOpacity cursor font toolTip focusPolicy styleSheet QWidget核心屬性 在Qt中使用QWidget類表示"控件"&#xff0c;如按鈕、視圖、輸入框、滾動…

Linux TCP 編程詳解與實例

一、引言 在網絡編程的領域中&#xff0c;TCP&#xff08;Transmission Control Protocol&#xff09;協議因其可靠的數據傳輸特性而被廣泛應用。在 Linux 環境下&#xff0c;使用 C 或 C 進行 TCP 編程可以實現各種強大的網絡應用。本文將深入探討 Linux TCP 編程的各個方面&…

原生redis實現分布式鎖

用 原生 Redis&#xff08;Jedis、Lettuce&#xff09; 實現分布式鎖&#xff0c;可以參考 Redisson 的原理&#xff0c;但需要自己處理鎖的自動續期、故障恢復等細節。核心思路是使用 Redis 的 SET NX EX 或 SET PX NX 命令來實現互斥鎖&#xff0c;并利用 Lua 腳本 保障原子性…

論文筆記:Rethinking Graph Neural Networks for Anomaly Detection

目錄 摘要 “右移”現象 beta分布及其小波 實驗 《Rethinking Graph Neural Networks for Anomaly Detection》&#xff0c;這是一篇關于圖&#xff08;graph&#xff09;上異常節點診斷的論文。 論文出處&#xff1a;ICML 2022 論文地址&#xff1a;Rethinking Graph Ne…

神經網絡常見激活函數 6-RReLU函數

文章目錄 RReLU函數導函數函數和導函數圖像優缺點pytorch中的RReLU函數tensorflow 中的RReLU函數 RReLU 隨機修正線性單元&#xff1a;Randomized Leaky ReLU 函數導函數 RReLU函數 R R e L U { x x ≥ 0 a x x < 0 \rm RReLU \left\{ \begin{array}{} x \quad x \ge 0…

Vue(6)

一.路由板塊封裝 &#xff08;1&#xff09;路由的封裝抽離 目標&#xff1a;將路由板塊抽離出來 好處&#xff1a;拆分板塊&#xff0c;利于維護 // 路由的使用步驟 5 2 // 5個基礎步驟 // 1. 下載 v3.6.5 // 2. 引入 // 3. 安裝注冊 Vue.use(Vue插件) // 4. 創建路由對象…

【python】matplotlib(animation)

文章目錄 1、matplotlib.animation1.1、FuncAnimation1.2、修改 matplotlib 背景 2、matplotlib imageio2.1、折線圖2.2、條形圖2.3、散點圖 3、參考 1、matplotlib.animation 1.1、FuncAnimation matplotlib.animation.FuncAnimation 是 Matplotlib 庫中用于創建動畫的一個…

【東莞常平】戴爾R710服務器不開機維修分享

1&#xff1a;2025-02-06一位老客戶的朋友剛開工公司ERP服務器一臺戴爾老服務器故障無法開機&#xff0c;于是經老客戶介紹找到我們。 2&#xff1a;服務器型號是DELL PowerEdge R710 這個服務器至少也有15年以上的使用年限了。 3&#xff1a;客戶反饋的故障問題為&#xff1a;…

Spring AI -使用Spring快速開發ChatGPT應用

前言 Spring在Java生態中一直占據大半江山。最近我發現Spring社區推出了一個Spring AI項目&#xff0c;目前該項目還屬于Spring實驗性項目&#xff0c;但是我們可以通過該項目&#xff0c;可以非常快速的開發出GPT對話應用。 本篇文章將會對SpringAI進行簡單的介紹和使用&#…

經典排序算法復習----C語言

經典排序算法復習 分類 交換類 冒泡快排 分配類 計數排序基數排序 選擇類 選擇排序 堆排序 歸并類 歸并排序 插入類 直接插入排序 希爾排序 折半插入排序 冒泡排序 基于交換。每一輪找最大值放到數組尾部 //冒泡排序 void bubSort(int* arr,int size){bool sorte…

BFS解決拓撲排序(3題)

目錄 拓撲排序 1.如何排序&#xff1f; 2.如何形成拓撲排序 3.如何建圖 1.看數據稠密度 2. 根據算法流程靈活建圖 1.課程表 2.課程表2 3.火星詞典 拓撲排序 找到做事情的先后順序&#xff0c;拓撲排序的結果可能不是唯一的 1.如何排序&#xff1f; 1.找出圖中入度為…

kafka 3.5.0 raft協議安裝

前言 最近做項目&#xff0c;需要使用kafka進行通信&#xff0c;且只能使用kafka&#xff0c;筆者沒有測試集群&#xff0c;就自己搭建了kafka集群&#xff0c;實際上筆者在很早之前就搭建了&#xff0c;因為當時還是zookeeper&#xff08;簡稱ZK&#xff09;注冊元數據&#…

Unity項目接入xLua的一種流程

1. 導入xlua 首先導入xlua&#xff0c;這個不用多說 2. 編寫C#和Lua交互腳本 基礎版本&#xff0c;即xlua自帶的版本 using System.Collections; using System.Collections.Generic; using UnityEngine; using XLua; using System; using System.IO;[Serializable] public…

四次揮手詳解

文章目錄 一、四次揮手各狀態FIN_WAIT_1CLOSE_WAITFIN_WAIT_2LAST_ACKTIME_WAITCLOSE 二、雙方同時調用close()&#xff0c;FIN_WAIT_1狀態后進入CLOSING狀態CLOSING狀態 三、TIME_WAIT狀態詳解(1) TIME_WAIT狀態下的2MSL是什么MSL &#xff08;報文最大生存時間&#xff09;為…