MFC问题方法总结

本文汇总了MFC编程中常见的问题解决方法,包括对话框绘图、控件操作、文件处理、字体设置、对话框创建、子进程及线程创建等,提供了丰富的代码示例,适合MFC初学者及开发者快速掌握核心技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**

MFC问题方法总结

**
1.在对话框中添加一张图片(bmp);
void CMFC090201Dlg::OnPaint()
{

CPaintDC dc(this); // 用于绘制的设备上下文

CBitmap bmp;
if (!bmp.LoadBitmap(IDB_LIT))
	return;
BITMAP bm;
bmp.GetBitmap(&bm);
CDC mdc;
mdc.CreateCompatibleDC(&dc);
mdc.SelectObject(&bmp);
dc.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&mdc,0,0,SRCCOPY);

}

2.MFC改变picture控件的大小和位置;
SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);

  1. 第一个参数我不会用,一般设为NULL;
  2. x、y控件位置;cx、cy控件宽度和高度;
  3. nFlags常用取值:
    SWP_NOZORDER:忽略第一个参数;
    SWP_NOMOVE:忽略x、y,维持位置不变;
    SWP_NOSIZE:忽略cx、cy,维持大小不变;
    CWnd *pWnd;
    pWnd = GetDlgItem( IDC_picture ); //获取控件指针,IDC_BUTTON1为控件ID号
    pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE ); //把按钮移到窗口的(50,80)处

pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE ); //把编辑控件的大小设为(100,80),位置不变

pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER ); //编辑控件的大小和位置都改变
以上方法也适用于各种窗口。
或者:
CRect rect;
GetDlgItem(IDC_DRAW_AREA)->GetWindowRect(&rect); //IDC_WAVE_DRAW为Picture Control的ID
ScreenToClient(&rect);
GetDlgItem(IDC_DRAW_AREA)->MoveWindow(rect.left, rect.top, 800, 450, true); //固定Picture Control控件的大小

3.获取picture控件的长和宽;
CRect rect;
CWnd *pWnd = GetDlgItem(IDC_picture);//IDC_picture为picture控件ID
pWnd->GetClientRect(&rc);//rc为控件的大小。
int x=rect.Height();
int y=rect.Width()。

4.在picture控件添加icon,属性改为icon,在OnInitDialog()函数下面:
CStatic pStatic = (CStatic)GetDlgItem(IDC_STATIC); //IDC_STATIC picture控件的Id
m_hIconLed = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_OFF));
pStatic->SetIcon(m_hIconLed);

5.创建MFC单文档工程:
项目类型选MFC标准,去掉初始状态栏,去掉使用窗口停靠工具栏,粗框架表示可以用鼠标改变窗口大小;
为菜单按钮添加消息处理函数,先将选定的按钮属性Popup改为False,系统会自动给这个按钮添加ID,然后右键按钮可以添加消息处理函数。
如果想单机按钮弹出对话框,要新建对话框和类,然后按钮的消息处理函数消息类型为COMMAND,类列表为选View类型的类;

6.双缓冲绘图:
CDC MyDC;
CBitmap bmp;
CRect rect;
CDC *dc = m_picDraw.GetDC(); //获得picture控件DC
m_picDraw.GetClientRect(&rect); //picture控件位图
MyDC.CreateCompatibleDC(dc); //依附窗口DC pDC创建兼容内存DC MyDC
bmp.CreateCompatibleBitmap(dc, rect.Width(), rect.Height()); //创建内存兼容位图
MyDC.SelectObject(&bmp); //把内存位图选进内存DC中用来保存在内存DC中绘制的图形 //待理解
MyDC.FillSolidRect(rect, RGB(255, 255, 255)); //背景填充白色,否则可能为黑色
MyDC.FillSolidRect(rect, dc->GetBkColor());
…添加画图代码…
dc->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &MyDC, 0, 0, SRCCOPY);
bmp.DeleteObject();
MyDC.DeleteDC();
ReleaseDC(dc);

7.获取当前对话框DC,画直线:
CDC *pDC=GetDC();
pDC->MoveTo( 270, 560 ); pDC->LineTo( 280, 560 );
ReleaseDC(pDC);

8.MFC在对话框上添加指示灯:(icon图标)
1.先在资源视图中添加icon图标,再在.h文件中添加两个HICON变量;
HICON m_hlcon_open;
HICON m_hlcon_close;
2.在OnInitDialog()函数内添加:
m_hlcon_open = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICON1));
m_hlcon_close = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICON2));
3.在相应的按钮函数体内添加(也可以用定时器实现闪烁):
m_icon_light.SetIcon(m_hlcon_open); 或 m_icon_light.SetIcon(m_hlcon_close);
(m_icon_light为picture控件的变量,IDI_ICON1、IDI_ICON2为指示灯icon图标)

9.在Button控件上添加BMP图片:
1.先在资源视图中添加BMP图片,再在.h文件中添加两个HBITMAP变量;
HBITMAP m_HB_bmp1;
HBITMAP m_HB_bmp2;
2.在OnInitDialog()函数内添加:
m_HB_bmp1 = LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));
m_HB_bmp2 = LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP2));
3.在相应的按钮函数体内添加
m_set.SetBitmap(m_HB_bmp1); 或 m_set.SetBitmap(m_HB_bmp2);
(m_set是CButton类型的控制变量,需要将Button的属性Bitmap改成True)

10.MFC在按钮上添加图标和文字共同显示:
在程序文件中添加CButtonST文件(BtnST.h、BtnST.cpp、BCMenu.h、BCMenu.cpp);
在对话框头文件中添加#include “BtnST.h”,再添加成员变量 CButtonST m_btn;
在OnInitDialog()函数内添加内添加:
m_btn.SubclassDlgItem(IDC_BUTTON1,this);
m_btn.SetIcon(IDI_ICON1);
// m_btn.SetAlign(CButtonST::ST_ALIGN_VERT); //确定图标和文字的位置
// m_btn.SetFlat(FALSE); //去掉显示平面按钮
// m_btn.DrawTransparent(TRUE); //无边框显示

11.GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); //设置控件内容不能改
GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); //设置控件内容能改

12.MFC设置对话框中控件上文字的字体、大小和颜色:
1.在对话框头文件中添加一个CFont类型的私有成员变量:
CFont m_font; // 改变字体和大小
CBrush m_brush; // 改变背景颜色
2.在源文件的构造函数中添加初始化变量的代码:
m_font.CreatePointFont(200,L"楷体");
m_brush.CreateSolidBrush(RGB(0,0,255));
3.添加对话框消息WM_CTLCOLOR的响应函数OnCtlColor(),在函数体内添加代码:
if (pWnd->GetDlgCtrlID() == IDC_STATIC_Message)
{
pDC->SelectObject(&m_font);
}
if (pWnd->GetDlgCtrlID() == IDC_STATIC_Message) //设置字体颜色
{
pDC->SetTextColor(RGB(0,128,255));
// pDC->SetBkMode(TRANSPARENT); //背景透明
}

13.MFC创建文件:
A. 第一种方法:
1.在头文件中添加:
#include //C++输出流,为了创建文件
#include
using namespace std;
2.在源程序中添加:
CString m_strPath; //获取当前exe可执行程序的路径
int nPos;
GetModuleFileName(NULL, m_strPath.GetBufferSetLength(MAX_PATH + 1), MAX_PATH);
m_strPath.ReleaseBuffer();
nPos = m_strPath.ReverseFind(_T(’\’));
m_strPath = m_strPath.Left(nPos);

CString filepath,filename;    //在该路径下创建Config.h文件
filename = "\\Config.h";                
filepath = m_strPath + filename;

ofstream fout(filepath);
            fout<<"输出内容"<<endl;
         附加:(解决CString类型无法输出到文件中的问题)
             std::string str1 = CStringA(m_edit_CG_PW);
 fout << str1.c_str() << endl;
 B.第二种方法:
            fout.open("./bin.txt");   //当前目录下生成bin.txt  //  ../bin.txt 上级目录下生成bin.txt   

14.创建颜色对话框类
CColorDialog dlg; //类中结构体变量成员m_cc中的rgbResult变量用于保存用户选择的颜色
创建字体对话框类
CFontDialog dlg; //类中结构体变量成员m_cf中的lfFaceName变量用于存放字体的名称

15.文件对话框的创建
1.选择某路径下的文件(文件)
void CExample17Dlg::OnBnClickedOpenButton()
{
// TODO: Add your control notification handler code here
// 设置过滤器
TCHAR szFilter[] = _T(“文本文件(.txt)|.txt|所有文件(.)|.||”);
// 构造打开文件对话框
CFileDialog fileDlg(TRUE, _T(“txt”), NULL, 0, szFilter, this);
CString strFilePath;

         // 显示打开文件对话框   
         if (IDOK == fileDlg.DoModal())   
         {   
             // 如果点击了文件对话框上的“打开”按钮,则将选择的文件路径显示到编辑框里   
             strFilePath = fileDlg.GetPathName();   
             SetDlgItemText(IDC_OPEN_EDIT, strFilePath);   
          }   
    }   
  2.选择路径,用于保存文件(路径)
    void CExample17Dlg::OnBnClickedSaveButton()   
    {   
           // TODO: Add your control notification handler code here   
           // 设置过滤器   
           TCHAR szFilter[] = _T("文本文件(*.txt)|*.txt|Word文件(*.doc)|*.doc|所有文件(*.*)|*.*||");   
           // 构造保存文件对话框   
           CFileDialog fileDlg(FALSE, _T("doc"), _T("my"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this);   
           CString strFilePath;   

           // 显示保存文件对话框   
           if (IDOK == fileDlg.DoModal())   
           {   
                 // 如果点击了文件对话框上的“保存”按钮,则将选择的文件路径显示到编辑框里   
                 strFilePath = fileDlg.GetPathName();   
                 SetDlgItemText(IDC_SAVE_EDIT, strFilePath);   
            }   
    }

16.MFC Edit控件设置右侧滑条:
Multiline -> True; //表示该控件支持多行
Want Return -> Ture; //表示该控件支持换行输入
Auto HScroll -> False; //当用户在行尾键入一个字符时,正文将自动向右滚动10 个字符,当用户按回车键时,正文总是滚向左边
Auto VScroll -> True; //当用户在最后一个可见行按回车键时,正文向上滚动一页
Vertical Scroll -> True; //表示该控件具有垂直滚动条

20.MFC 创建子进程、线程:
1.创建子进程(Process):
STARTUPINFO sui;
PROCESS_INFORMATION pi;
ZeroMemory(&sui,sizeof(STARTUPINFO));
sui.cb = sizeof(STARTUPINFO);
sui.wShowWindow = SW_SHOW; //隐藏命令行窗口
sui.dwFlags = STARTF_USESHOWWINDOW; //启动标志,显示窗口
char lpPath[] = “calc”;
BOOL bret = CreateProcess(NULL ,lpPath, NULL, NULL, TRUE, 0, NULL, NULL, &sui, &pi); //第一个参数需要写可执行程序的路径和程序名或第二个参数写命令栏的输入命令
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
2.创建线程(Thread):
HANDLE hThread;
hThread = CreateThread(NULL,0,FunProc,NULL,0,NULL); //第三个参数指向应用程序定义的函数指针,由新线程执行,表明新线程的起始地址
CloseHandle(hThead);

17.MFC 打开外部.exe的四种方法
1.通过创建子进程的方式(如上述例20);
2.WinExec()函数,使用方法如下:
WinExec(“Notepad.exe”, SW_SHOW); // 打开记事本
   WinExec(“D:\Program Files\Test\Test.exe”,SW_SHOWMAXIMIZED); // 以最大化的方式打开Test.exe
注:只能用于打开exe文件。
3.ShellExecute()函数,使用方法如下:
ShellExecute(NULL,“open”,“C:\Test.txt”,NULL,NULL, SW_SHOWNORMAL); // 打开C:\Test.txt 文件
   ShellExecute(NULL, “open”, “http://www.google.com/”, NULL, NULL, SW_SHOWNORMAL); // 打开网页www.google.com
   ShellExecute(NULL,“explore”, “D:\C++”,NULL,NULL,SW_SHOWNORMAL); // 打开目录D:\C++
   ShellExecute(NULL,“print”,“C:\Test.txt”,NULL,NULL , SW_HIDE); // 打印文件C:\Test.txt
   ShellExecute不支持定向输出,操作指令有(open、print、edit、explore、find等)。
4.ShellExecuteEx()函数;

18.Inno Setup打包程序:
https://jingyan.baidu.com/article/36d6ed1f50ecfc1bcf4883aa.html

19.控件设置:
1.设置控件为不可选定状态:
GetDlgItem(IDC_EDIT)->EnableWindow(FALSE); 或 m_edit.EnableWindow(FALSE);
2.设置Radio Button为非选中状态:
m_check.SetCheck(0);
3.设置控件文本内容:
m_SendCtrl.SetWindowText(“hello”); 或者 SetDlgItemText(IDC_EDIT, “hello”);
获取控件文本内容:
CString temp;
m_OpenCloseCtrl.GetWindowText(temp);
4.设置Combo Box的值:
m_combo.SetCurSel(0);
获取当前值:
int index=m_combo.GetCurSel();
插入值:
m_combo.AddString(“1000”);
5.设置控件在窗口的固定位置:
CWnd *pWnd;
pWnd = GetDlgItem(IDC_STATIC_CTRL_PIC); pWnd->SetWindowPos(NULL, 282, 48, 771, 512, SWP_NOZORDER);
6.窗口加载位图:
dc.BitBlt(20, 450, bm.bmWidth, bm.bmHeight, &mdc, 0, 0, SRCCOPY);

dc.StretchBlt(22, 450, 192, 110, &mdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
7.设置编辑框中内容为空:
m_edit.SetWindowText(""); 或 SetDlgItemText(IDC_EDIT, NULL);

20.MFC字符处理:
1.CString::ReverseFind() 和 Find(),查找字符,返回值为字符的索引,索引从左往右且从0开始;
例:CString s( “abcab” );
ASSERT( s.ReverseFind( ‘b’ ) == 4 ); // ReverseFind() 是从右往左查找 ,ps:左边的例子找到的’b’是从左往右的第二个
ASSERT( s.Find( ‘b’ ) == 1 ); // Find() 是从左往右查找
2.CString::Left(int nCount) —返回字符串前nCount个字符的字符串
例:CString str(_T(“Shop,车间”));
str = str.Left(4);
结果:str=“Shop”;
3.CString::Right(int nCount) —返回字符串后nCount个字符的字符串
例:CString str(_T(“Shop,车间”));
str = str.Right(2);
结果:str=“车间”;
4.substr() —获取字符串中指定长度位置的字符
例:string s(“12345asdf”);
string a=s.substr(0,5); //获得字符串s中 从第0位开始的长度为5的字符串 //默认时的长度为从开始位置到尾
结果:a=12345
5.Cstring::GetLength() —返回的是字符个数(不包括结尾的空字符)。
CString 本身就是TCHAR的封装,所以你定义了UNICODE那么他就占两个字节,否则就是一个字节。
按照MSDN的说吗,在选用MBCS多字节字符串编码时,该方法会得到正确的字节数。此时没有问题。
但是在Unicode编码下,一旦出现中文字符,该方法就会少统计。(出现一个中文可能按两个字节算)
例:https://www.cnblogs.com/ransn/p/8016564.html

21.CString函数:
链接:https://blog.youkuaiyun.com/shufac/article/details/20737799
1.void MakeReverse( ); —颠倒字符串的顺序
例:csStr=“ABCDEF中文123456”;
csStr.MakeReverse();
结果:654321文中FEDCBA
2.void MakeUpper( ); —将小写字母转换为大写字母
例:csStr=“abcdef中文123456”;
csStr.MakeUpper();
结果:ABCDEF中文123456
3.void MakeLower( ); —将大写字母转换成小写字母
例:csStr=“ABCDEF中文123456”;
csStr.MakeLower();
结果:abcdef中文123456
4.int Compare( LPCTSTR lpsz ) const; —区分大小写比较两个字符串,相等时返回0,大于时返回1,小于时返回-1
例:csStr=“abcdef中文123456”;
csStr2=“ABCDEF中文123456”; //结果:-1
5.int CompareNoCase( LPCTSTR lpsz ) const; —不区分大小写比较两个字符串,相等时返回0,大于时返回1,小于时返回-1
例:csStr=“abcdef中文123456”;
csStr2=“ABCDEF中文123456”; //结果:1
6.int Delete( int nIndex, int nCount = 1 ) —删除字符,删除从下标nIndex开始的nCount个字符
例:csStr=“ABCDEF”;
csStr.Delete(2,3); //结果:ABF
7.int Insert( int nIndex, TCHAR ch ) —在下标为nIndex的位置,插入字符或字符串。返回插入后对象的长度
int Insert( int nIndex, LPCTSTR pstr )
例:csStr=“abc”; csStr=“abc”;
csStr.Insert(2,‘x’); //结果:abxc csStr.insert(2,“xyz”); //结果:abxyzc
8.int Remove( TCHAR ch ); —移除对象内的指定字符,返回移除的数目
例:csStr=“aabbaacc”;
csStr.Remove(‘a’); //结果:bbcc
9.int Replace( TCHAR chOld, TCHAR chNew ); —替换字符或者字符串
int Replace( LPCTSTR lpszOld, LPCTSTR lpszNew );
例:csStr=“abcdef”; csStr=“abcdef”;
csStr.Replace(‘a’,‘x’); //结果:xbcdef csStr.Replace(“abc”,“xyz”); //结果:xyzdef
10.void TrimLeft( ); void TrimLeft( TCHAR chTarget );
如果没有参数,从左删除字符(\n\t空格等),至到遇到一个非此类字符。
或从左删除字符,被删的字符与chTarget或lpszTargets匹配,一直删到第一个不匹配的字符为止
11.void TrimRight( ); void TrimRight( TCHAR chTarget ); void TrimRight( LPCTSTR lpszTargets );
12.void Empty( ); —清空
13.void SetAt( int nIndex, TCHAR ch ); —给下标为nIndex的字符重新赋值
例:csStr=“abcdef”;
csStr.SetAt(2,‘x’); //结果:abxdef

22.MFC字符类型转换:
1.CString.Format用法:
Format用于转换的格式字符:%c 单个字符、%d 十进制整数(int)、%ld 十进制整数(long)、%f 十进制浮点数(float)、%lf 十进制浮点数(double)、
%o 八进制数、%s 字符串、%u 无符号十进制数、%x 十六进制数
例:CString str;
str.Format(_T("%02X"), m_int); //把整型数转换成十六进制字符两位输出,155->9B
2.strtol()字符串转长整型函数:
例:int m = (int)strtol(str, &m_1, 16); //把str转换成16进制整数
3.itoa();将整型值转换为字符串;
4.atoi();将字符串转换成整型值;

23.MFC Create()函数:
BOOL Create(
LPCTSTR lpszClassName, //类名,如果为NULL,使用预定义的缺省CFrameWnd属性
LPCTSTR lpszWindowName, // 窗口标题
DWORD dwStyle = WS_OVERLAPPEDWINDOW, //窗口风格 WS_VISIBLE->窗体可见
const RECT& rect = rectDefault, //窗口大小
CWnd* pParentWnd = NULL, //指定父窗口
LPCTSTR lpszMenuName = NULL, //菜单
DWORD dwExStyle = 0, //窗口扩展风格
CCreateContext* pContext = NULL); //多文档与单文档窗口时使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值