关于mfc:MFC基于对话框使用dll进行多语言切换

title: MFC基于对话框应用dll进行多语言切换 categories:[MFC] tags:[音视频编程] date: 2021/12/15 作者:hackett 微信公众号:加班猿 一、前言Qt应用qm文件切换有两种加载形式,比拟容易一些 在资源文件中加载(这个比拟好):长处: 在程序公布时不必把最新的.qm文件拷贝到加载门路中,升高了批改翻译时界面没有翻译或翻译不精确的危险;不会把翻译的信息裸露给用户;毛病: 资源文件会编译时可执行程序,所以会导致可执行程序的体积变大(然而.qm文件个别很小,这个毛病能够忽略不计);当只批改翻译不批改源码时也必须从新编译可执行程序。在程序内部加载: 长处: 当只批改翻译不批改源码时不必从新编译可执行程序,只有替换批改后的.qm文件;不会影响可执行程序的大小;毛病: 程序公布时,要把最新.qm文件中复制到相应加载门路下(在理论开发中常常会忘了这个步骤),导致没有翻译或翻译不精确;把翻译信息裸露给用户,可能会被用户批改(不可抗因素,能够疏忽)。有个需要MFC界面须要做一个多语言切换,百度了一番,MFC实现多国语言有不少办法: VS提供对话框的“插入正本”办法;将要显示的界面文字做一个相似ini文件,加载界面的时候各控件用SetWindowText来显示不同的语言内容;制作Dll资源文件,不同语言调用不同的Dll;综合下来dll形式比拟适宜本人的需要,就应用这个来做 二、筹备工作visual studio中新建一个MFC我的项目 【文件】——【新建】——【我的项目】,抉择“MFC 应用程序”,项目名称:test,放在workspace文件夹里 抉择“基于对话框”,勾销“应用 Unicode 库” 【实现】实现对基于对话框MFC我的项目的创立。 界面轻易来两个按钮跟text、Edit Control 右键【增加资源】——【Menu】——【新建】 ,建一个menu来进行语言的抉择,增加语言切换选项 关上test.rc的属性,找到【杂项】的Menu中选中刚刚的IDR_MENU1,做好这些就能够筹备dll的制作了 三、制作dll创立英文版的dllvisual studio中 解决方案右键 【增加】——【新建我的项目】 抉择MFC DLL,输出我的项目名English,确定 MFC DLL向导不做批改,采纳默认的共享MFC DLL规定设置,【实现】。 删除DLL中不须要的文件 移除工程的“资源文件”下的English.rc,English.rc2文件,“头文件”下的Resource.h文件,并到对应目录将其删除 导入相干文件: 将workspace\test下的“test.rc”、“resource.h”复制到英文DLL我的项目的文件夹test\English下。 而后将test的workspace\test\res文件夹中的文件全副复制到英文DLL我的项目对应的文件夹下。 再将上述文件增加到 English 我的项目中。 右击English我的项目,【增加】——【现有项】,如图所示 批改English我的项目的相干资源属性为英语,并将对应的button和text翻译成英文 批改English我的项目属性。【配置属性】——【链接器】——【高级】,“无入口点”改为“是(/NOENTRY)”。 接下来就能够右键【生成】生成English.dll 按English我的项目的办法可创立中文、日语、其余语言版本。 文本框中的显示内容也能够采纳从配置文件读取,形式跟读取语言配置的一样操作 test.h// test.h : PROJECT_NAME 应用程序的主头文件//#pragma once#ifndef __AFXWIN_H__ #error "在蕴含此文件之前蕴含“stdafx.h”以生成 PCH 文件"#endif#include "resource.h" // 主符号// CtestApp:// 无关此类的实现,请参阅 test.cpp//class CtestApp : public CWinApp{public: CtestApp();// 重写public: virtual BOOL InitInstance(); // 新增加代码private: CString pExePath; char m_strLanguage[MAX_PATH]; HINSTANCE m_hLangDLL;// 实现 DECLARE_MESSAGE_MAP()};extern CtestApp theApp;test.cpp// test.cpp : 定义应用程序的类行为。//#include "stdafx.h"#include "test.h"#include "testDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// CtestAppBEGIN_MESSAGE_MAP(CtestApp, CWinApp) ON_COMMAND(ID_HELP, &CWinApp::OnHelp)END_MESSAGE_MAP()// CtestApp 结构CtestApp::CtestApp(){ // 反对重新启动管理器 m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; // TODO: 在此处增加结构代码, // 将所有重要的初始化搁置在 InitInstance 中 // 新增代码 // 初始化变量 memset(m_strLanguage,0,sizeof(m_strLanguage)); m_hLangDLL=NULL;}// 惟一的一个 CtestApp 对象CtestApp theApp;BOOL CtestApp::InitInstance(){ // 如果一个运行在 Windows XP 上的利用程序清单指定要 // 应用 ComCtl32.dll 版本 6 或更高版本来启用可视化形式, //则须要 InitCommonControlsEx()。否则,将无奈创立窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置为包含所有要在应用程序中应用的 // 公共控件类。 InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); AfxEnableControlContainer(); // 创立 shell 管理器,以防对话框蕴含 // 任何 shell 树视图控件或 shell 列表视图控件。 CShellManager *pShellManager = new CShellManager; // 规范初始化 // 如果未应用这些性能并心愿减小 // 最终可执行文件的大小,则应移除下列 // 不须要的特定初始化例程 // 更改用于存储设置的注册表项 // TODO: 应适当批改该字符串, // 例如批改为公司或组织名 SetRegistryKey(_T("应用程序向导生成的本地应用程序")); // ***********新增代码。语言选择 ********** // 读取 INI 文件中的设置 pExePath = CtestDlg::GetExePath(); pExePath += _T("\\ip.ini"); ::GetPrivateProfileString(_T("Language"), _T("currentlanguage"), _T(""),m_strLanguage, MAX_PATH, pExePath); // 加载对应的 DLL 文件 switch (atoi(m_strLanguage)) { case LANG_CHINESE: m_hLangDLL=::LoadLibrary("Chinese.dll"); break; case LANG_ENGLISH: m_hLangDLL=::LoadLibrary("English.dll"); break; default: m_hLangDLL=::LoadLibrary("Chinese.dll"); break; } if (m_hLangDLL!=NULL) { AfxSetResourceHandle(m_hLangDLL); } else { AfxMessageBox("语言DLL文件加载失败!"); exit(1); // 非正常终止程序 } // *************************************** CtestDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: 在此搁置解决何时用 // “确定”来敞开对话框的代码 } else if (nResponse == IDCANCEL) { // TODO: 在此搁置解决何时用 // “勾销”来敞开对话框的代码 } else if (nResponse == -1) { TRACE(traceAppMsg, 0, "正告: 对话框创立失败,应用程序将意外终止,如果您在对话框上应用 MFC 控件,则无奈 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n"); } // 删除下面创立的 shell 管理器。 if (pShellManager != NULL) { delete pShellManager; } // 因为对话框已敞开,所以将返回 FALSE 以便退出应用程序, // 而不是启动应用程序的音讯泵。 return FALSE;}testDlg.cpp// testDlg.cpp : 实现文件//#include "stdafx.h"#include "test.h"#include "testDlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“对于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx{public: CAboutDlg();// 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 反对// 实现protected: DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){ CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP() // CtestDlg 对话框CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CtestDlg::IDD, pParent){ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // 初始化变量 m_hLangDLL=NULL;}void CtestDlg::DoDataExchange(CDataExchange* pDX){ CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CtestDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, &CtestDlg::OnBnClickedButton1) ON_COMMAND(ID_MENU_CHINESE, &CtestDlg::OnChinese) ON_COMMAND(ID_MENU_ENGLISH, &CtestDlg::OnEnglish)END_MESSAGE_MAP()// CtestDlg 音讯处理程序BOOL CtestDlg::OnInitDialog(){ CDialogEx::OnInitDialog(); // 将“对于...”菜单项增加到零碎菜单中。 // IDM_ABOUTBOX 必须在系统命令范畴内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将主动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此增加额定的初始化代码 m_menu.LoadMenu(IDR_MENU1); // 留神这里须要加载menu SetMenu(&m_menu); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE}void CtestDlg::OnSysCommand(UINT nID, LPARAM lParam){ if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); }}// 如果向对话框增加最小化按钮,则须要上面的代码// 来绘制该图标。对于应用文档/视图模型的 MFC 应用程序,// 这将由框架主动实现。void CtestDlg::OnPaint(){ if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设施上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); }}//当用户拖动最小化窗口时零碎调用此函数获得光标//显示。HCURSOR CtestDlg::OnQueryDragIcon(){ return static_cast<HCURSOR>(m_hIcon);}CString CtestDlg::GetExePath() { char szExePath[MAX_PATH] = {0}; GetModuleFileName(AfxGetApp()->m_hInstance, szExePath, 256); int i = (int)strlen(szExePath) - 1; for (; i >= 0 && szExePath[i] != '\\'; i--) ; szExePath[i + 1] = 0; return szExePath;}void CtestDlg::OnBnClickedButton1(){}BOOL CtestDlg::ResetDialog(){ //TODO: 解决可能已增加的附加资源 AfxOleTerm(FALSE); if(m_hLangDLL) { FreeLibrary(m_hLangDLL); } STARTUPINFO StartupInfo={0}; PROCESS_INFORMATION ProcessInfo; StartupInfo.cb=sizeof(STARTUPINFO); char Path[256]; GetModuleFileName(NULL,(LPSTR)(LPCTSTR)Path,250); CreateProcess(NULL,(LPSTR)(LPCTSTR)Path,NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo,&ProcessInfo); return TRUE;}void CtestDlg::OnChinese(){ // TODO: 在此增加命令解决程序代码 pExePath = GetExePath(); pExePath += _T("\\ip.ini"); int iRet = MessageBox(_T("Make sure to switch to the Chinese version?"),_T("Tips"),MB_YESNO); if (iRet == IDYES) { WritePrivateProfileString(_T("Language"), _T("currentlanguage"), "0", pExePath); m_hLangDLL=::LoadLibrary("Chinese.dll"); if (m_hLangDLL!=NULL) { ResetDialog(); AfxSetResourceHandle(m_hLangDLL); exit(1); } else { AfxMessageBox("语言Chinese.dll文件加载失败!"); exit(1); // 非正常终止程序 } }}void CtestDlg::OnEnglish(){ // TODO: 在此增加命令解决程序代码 pExePath = GetExePath(); pExePath += _T("\\Config.ini"); int iRet = MessageBox(_T("确定切换到英文版本?"),_T("提醒"),MB_YESNO); if (iRet == IDYES) { WritePrivateProfileString(_T("Language"), _T("currentlanguage"), "1", pExePath); m_hLangDLL=::LoadLibrary("English.dll"); if (m_hLangDLL!=NULL) { ResetDialog(); AfxSetResourceHandle(m_hLangDLL); exit(1); } else { AfxMessageBox("语言English.dll文件加载失败!"); exit(1); //非正常终止程序 } }}testDlg.h// testDlg.h : 头文件//#pragma once// 增加宏定义#define LANG_CHINESE 0#define LANG_ENGLISH 1#define LANG_JAPNESE 2// CtestDlg 对话框class CtestDlg : public CDialogEx{// 结构public: CtestDlg(CWnd* pParent = NULL); // 规范构造函数// 对话框数据 enum { IDD = IDD_TEST_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 反对// 实现protected: HICON m_hIcon; // 生成的音讯映射函数 virtual BOOL OnInitDialog(); virtual BOOL ResetDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP()public: afx_msg void OnBnClickedButton1(); afx_msg void OnChinese(); afx_msg void OnEnglish(); static CString GetExePath(); CString pExePath; HINSTANCE m_hLangDLL; CMenu m_menu;};ip.ini[Language]currentlanguage=0四、遇到的坑1、用dll进行多语言切换的时候不要用 MFC Button Control类型的button,用一般的button(不然程序运行会一闪而过) ...

December 17, 2021 · 4 min · jiezi

关于mfc:MFC界面控件显示提示信息

一、前言在编写dll工程的时候,我习惯生成一个MFC的exe进行测试dll的性能。然而有的时候dll中的某些接口的某个参数反对多种配置,这个时候去找对应的文档阐明感觉比拟麻烦,因而最好将文档中的对应阐明在界面中进行显示,这就防止了频繁的查看文档。 二、次要流程1、定义CToolTipCtrl对象在须要应用提醒的界面类中顶一个CToolTipCtrl对象 2、设置提示信息在对应界面类的OnInitDialog函数中,实现如下的代码: //提示信息m_Mytip.Create(this);CString strTip = _T("1——connect,\r\n 2——accept,\r\n 3——disconn,\r\n ");strTip.AppendFormat(_T("%s"), _T("1——url,\r\n 2——data,\r\n 3——ip_data,\r\n"));strTip.AppendFormat(_T("%s"),_T("0x40——dns,\r\n 0x80——smb,\r\n 0x1000——cb,\r\n"));strTip.AppendFormat(_T("%s"),_T("0x2000——add_rule,\r\n 0x4000——del_rule,\r\n 0x8000——notify_caller,\r\n"));strTip.AppendFormat(_T("%s"),_T("0x400000——block,\r\n 0x800000——allow\r\n"));m_Mytip.AddTool(GetDlgItem(IDC_EDIT_FLAGS), strTip);strTip = _T("1——in,\r\n 2——out,\r\n 3——both,\r\n 17——send,\r\n 18——recv\r\n");m_Mytip.AddTool(GetDlgItem(IDC_EDIT_DIRECTION), strTip);strTip = _T("1——ICMP,\r\n 6——TCP,\r\n 17——UDP\r\n");m_Mytip.AddTool(GetDlgItem(IDC_EDIT_PROT), strTip);strTip = _T("2——AF_INET,\r\n 23——AF_INET6\r\n");m_Mytip.AddTool(GetDlgItem(IDC_EDIT_IP_FAMILY), strTip);m_Mytip.SetDelayTime(TTDT_INITIAL, 100); //设置提早m_Mytip.SetDelayTime(TTDT_AUTOPOP, 20000); //显示提醒工夫m_Mytip.SetMaxTipWidth(200); //设置显示宽度,超长主动换行m_Mytip.SetTipTextColor( RGB(85,123,205) ); //设置提醒文本的色彩m_Mytip.SetTipBkColor( RGB(255,255,255)); //设置提示框的背景色彩m_Mytip.Activate(TRUE); //设置是否启用提醒3、重写PreTranslateMessage函数关上工程的Class View(Ctrl+Shift+C),找到应用CToolTipCtrl类的界面类,关上其属性,点击Oerrides 抉择PreTranslateMessage,此时在对应界面类中会生成一下内容: //头文件virtual BOOL PreTranslateMessage(MSG* pMsg);//cpp文件BOOL CSetNetDrvRuleDialog::PreTranslateMessage(MSG* pMsg){ // TODO: Add your specialized code here and/or call the base class return CDialog::PreTranslateMessage(pMsg);}4、鼠标在控件上显示提醒内容在PreTranslateMessage中增加代码 BOOL CSetNetDrvRuleDialog::PreTranslateMessage(MSG* pMsg){ // TODO: Add your specialized code here and/or call the base class if(pMsg->message == WM_MOUSEMOVE ) m_Mytip.RelayEvent(pMsg); return CDialog::PreTranslateMessage(pMsg);}到此,当用户将鼠标移到到对应控件上时,会显示对应的提示信息 ...

May 26, 2021 · 1 min · jiezi

关于mfc:CSplitterWnd动态分割

动态宰割不提了,网上一大堆。要害是动静宰割要怎么办?1、从未切分到切分2、从切分到未切分3、从切分状态m到切分状态n的转变比方这里要实现一个通达信的看盘窗口,分成主窗口和指标窗口。指标窗口可随时敞开,也可随时关上。 通过屡次尝试,最终确定以下方法 在OnCreateClient中,动态创建目前将要展现的视图,并且保留document指针 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext){ CRect rect; GetClientRect(&rect); CView* view = new CMFCApplication4View(); view->Create(NULL,NULL,WS_CHILD|WS_VISIBLE,rect,this,AFX_IDW_PANE_FIRST,pContext); m_pDocument = pContext->m_pCurrentDoc; return TRUE;}切换到宰割视图的时候,先将原来的窗口设置id为一个非AFX_IDW_PANE_FIRST的数字,而后动态创建宰割,之后将原来的窗口Destroy掉,并且调用InitialUpdateFrame使得新创建的外部视图能够应用document反对。 void CMainFrame::OnSplit(){ CWnd* oldView = GetDlgItem(AFX_IDW_PANE_FIRST); oldView->SetDlgCtrlID(1000); createSplitter(oldView); oldView->DestroyWindow(); GetDlgItem(AFX_IDW_PANE_FIRST)->GetParentFrame()->InitialUpdateFrame( m_pDocument, TRUE );}void CMainFrame::createSplitter(CWnd* oldView){ CAutoDeleteSplitterWnd* splitter = new CAutoDeleteSplitterWnd; if(!splitter->CreateStatic(this,2,1,WS_CHILD|WS_VISIBLE,AFX_IDW_PANE_FIRST)){ return; } CCreateContext context; context.m_pCurrentDoc =m_pDocument; context.m_pCurrentFrame = this; splitter->CreateView(0,0,RUNTIME_CLASS(CMyView),CSize(0,100),&context); splitter->CreateView(1,0,RUNTIME_CLASS(CMFCApplication4View),CSize(0,100),&context); CRect rect; oldView->GetWindowRect(&rect); ScreenToClient(&rect); splitter->MoveWindow(&rect,TRUE);}CAutoDeleteSplitterWnd 是一个继承CSplitterWndEx的类,关键在于void CAutoDeleteSplitterWnd::OnNcDestroy(){ delete this;}切换回来的代码与后面一模一样。 void CMainFrame::OnNotSplit(){ CWnd* oldView = GetDlgItem(AFX_IDW_PANE_FIRST); oldView->SetDlgCtrlID(1000); createSingleView(oldView); oldView->DestroyWindow(); GetDlgItem(AFX_IDW_PANE_FIRST)->GetParentFrame()->InitialUpdateFrame( m_pDocument, TRUE );}void CMainFrame::createSingleView(CWnd* oldView){ CCreateContext context; context.m_pCurrentDoc =m_pDocument; context.m_pCurrentFrame = this; context.m_pNewViewClass = RUNTIME_CLASS(CMFCApplication4View); CRect rect; GetClientRect(&rect); CView* view = new CMFCApplication4View(); view->Create(NULL,NULL,WS_CHILD|WS_VISIBLE,rect,this,AFX_IDW_PANE_FIRST,&context); }

May 2, 2021 · 1 min · jiezi

关于mfc:请教COM组件获取函数返回值类型字符串形式的类型名

当初,我能够依据GetFuncDesc函数获取到 FUNCDESC ,返回值类型是否蕴含在elemdescFunc ? 查了文档类型是ELEMDESC。 这个字段蕴含两个字段,我通过动静调试,得悉在tdesc中有数据,他是一个TYPEDESC 类型。 这个外面有2个整数。 比方我调试的时候失去: vt = 26 lpValue=1f835080 如何依据这两个整数失去一个字符串模式的类型名呢? 求教各位大神。 查文档一堆,调试一堆。就是整不进去,托付了。 或者说下面这个思路是不是有不对的中央? 请大侠斧正。 上面附各种文档 ==========TYPEDESC 文档 字段lpValue 如果变量为 VT_SAFEARRAY 或 VT_PTR,则 lpValue 字段蕴含指向指定元素类型的 TYPEDESC 的指针。vt 批示由此 TYPEDESC 形容的项的 Variant 类型。 =======================ELEMDESC文档desc 蕴含无关元素的信息。tdesc 标识元素的类型。 =================FUNCDESC 文档 字段callconv 指定函数的调用约定。cParams 计算参数的总数。cParamsOpt 计算可选参数。cScodes 计算容许的返回值。elemdescFunc 蕴含函数的返回类型。funckind 指定函数是虚构的、动态的还是仅反对调度的。invkind 指定属性函数的类型。lprgelemdescParam 批示 cParams 的大小。lprgscode 存储函数可在 16 位零碎中返回的谬误的计数。memid 标识函数成员 ID。oVft 指定 FUNC_VIRTUAL 在 VTBL 中的偏移量。wFuncFlags 批示函数的 FUNCFLAGS。[url]https://book.douban.com/douli...[/url][url]https://movie.douban.com/doul...[/url][url]https://www.douban.com/doulis...[/url][url]https://m.douban.com/doulist/...[/url][url]https://book.douban.com/douli...[/url][url]https://movie.douban.com/doul...[/url][url]https://www.douban.com/doulis...[/url][url]https://m.douban.com/doulist/...[/url][url]https://book.douban.com/douli...[/url][url]https://movie.douban.com/doul...[/url][url]https://www.douban.com/doulis...[/url][url]https://m.douban.com/doulist/...[/url][url]https://book.douban.com/douli...[/url][url]https://movie.douban.com/doul...[/url][url]https://www.douban.com/doulis...[/url][url]https://m.douban.com/doulist/...[/url][url]https://book.douban.com/douli...[/url][url]https://movie.douban.com/doul...[/url][url]https://www.douban.com/doulis...[/url][url]https://m.douban.com/doulist/...[/url][url]https://book.douban.com/douli...[/url][url]https://movie.douban.com/doul...[/url][url]https://www.douban.com/doulis...[/url][url]https://m.douban.com/doulist/...[/url][url]https://book.douban.com/douli...[/url][url]https://movie.douban.com/doul...[/url][url]https://www.douban.com/doulis...[/url][url]https://m.douban.com/doulist/...[/url][url]https://book.douban.com/douli...[/url][url]https://movie.douban.com/doul...[/url]

February 18, 2021 · 1 min · jiezi

关于mfc:问问大家怎么理解-If-this-DLL-is-dynamically-linked-against-the-MFC

Note! If this DLL is dynamically linked against the MFC DLLs, any functions exported from this DLL which call into MFC must have the AFX_MANAGE_STATE macro added at the very beginning of the function. For example: extern "C" BOOL PASCAL EXPORT ExportedFunction() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); normal function body here} It is very important that this macro appear in each function, prior to any calls into MFC. This means that it must appear as the first statement within the function, even before any object variable declarations as their constructors may generate calls into the MFC DLL. ...

February 18, 2021 · 1 min · jiezi

关于SegmentFault:古老的MFC你还会用吗

大家好,我是Sean!最近基于MFC做了个小软件,在此记录一下MFC的一些知识点。 创立基于对话框的一个利用 关键步骤如上述截图,前面点击下一步晓得实现即可。 对于MFC界面控件的应用通过左侧资源视图能够找到Dialog、Menu、Icon等文件,咱们能够往Dialog中增加控件,如按钮、编辑框。增加完控件之后,能够通过批改属性批改控件的ID及其他属性,并能够通过右键增加事件处理程序(回调函数),增加变量到对话框类当中。 Button 一般按钮按钮事件处理程序,这个比较简单,个别就用单击或双击回调函数(BN_CLICKED BN_DOUBLECLICKED)具体点击后的逻辑在回调函数中实现即可: void CVisionFastInputDlg::OnBnClickedAddButton(){ // code ...}Edit Control 一般文本编辑框一般文本编辑框事件处理程序,我应用了EN_CHANGE,当编辑框中的内容有变动的时候,触发回调。罕用代码操作如下: void My_Dlg::OnEnChangeTextValueEdit(){ // 获取文本框内容 CString value; GetDlgItemText(IDC_TEXT_VALUE_EDIT, value); // CString转std::string std::string v = CT2A(value); // std::string转CString m_value = v.c_str(); // 获取光标地位 POINT cp = m_value_edit.GetCaretPos(); // 设置光标地位 SetCaretPos(cp); ShowCaret(); // 更新数据,FALSE代表从代码中的变量更新到界面,TRUE代表从界面更新到代码中的变量 UpdateData(FALSE);}Static Text 动态文本这个在设置属性的时候间接把内容填写好就行了。 List Control 表格这个属性设置要讲View设置为Report,这样能力是表格款式,并通过右键增加变量将其增加到界面类中,这个控件有些初始化的操作,回调函数罕用NM_DBLCLK、NM_CLICK,及单击双击回调,单击回调能够用来刷新index,双击回调能够用来触发新的对话框。罕用代码如下: // 头文件中控件变量 CListCtrl m_list; // 增加表头 CString colums[] = {TEXT("No"), TEXT("Name"), TEXT("Sex")}; // 增加列并设置宽度 m_list.InsertColumn(0, colums[0], LVCFMT_LEFT, 200); m_list.InsertColumn(1, colums[1], LVCFMT_LEFT, 800); m_list.InsertColumn(2, colums[2], LVCFMT_LEFT, 200); // 最初一列自适应宽度 m_list.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER); // 设置属性,单行选中 m_list.SetExtendedStyle(m_shortcut_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES ); // 增加第一行数据 m_list.InsertItem(0, TEXT("1001")); m_list.SetItemText(0, 1, TEXT("Henry Ha")); m_list.SetItemText(0, 2, TEXT("Male")); // 增加第二行数据 m_list.InsertItem(1, TEXT("1002")); m_list.SetItemText(2, 1, TEXT("Marry Li")); m_list.SetItemText(3, 2, TEXT("Male")); // 删除所有行 m_list.DeleteAllItems();Combo-box Control 下拉抉择框这个是个下拉菜单,增加回调函数ON_CBN_SELCHANGE ...

January 20, 2021 · 2 min · jiezi

关于mfc:自定义消息的定义与使用

自定义音讯的响应和资源音讯的响应有很多类似之处;资源音讯的响应是以资源的ID号作为标识的;自定义的音讯要本人申明音讯ID。

September 21, 2020 · 1 min · jiezi

关于mfc:Windows消息传递机制

音讯和音讯类型 音讯队列 MFC的音讯映射

August 20, 2020 · 1 min · jiezi