vc++ 学习笔记
来源:互联网 发布:eclipse java tomcat 编辑:程序博客网 时间:2024/06/05 09:55
一 .全屏
void CXXXDlg::SetFullScreen(){int frameWidth = GetSystemMetrics(SM_CXFRAME);int frameHeight = GetSystemMetrics(SM_CYFRAME);int captionHeight = GetSystemMetrics(SM_CYCAPTION);int screenWidth = GetSystemMetrics(SM_CXSCREEN);int screenHeight = GetSystemMetrics(SM_CYSCREEN);CRect rect;GetClientRect(&rect);rect.left = rect.left - frameWidth;rect.top = rect.top - frameHeight - captionHeight ;rect.bottom = rect.top + screenHeight + 2 * frameHeight + captionHeight;rect.right = rect.left + screenWidth + 2 * frameWidth;ShowWindow(SW_HIDE);SetWindowPos(&wndTopMost, rect.left, rect.top, rect.Width(), rect.Height(), SWP_SHOWWINDOW);}
2.取消全屏
void CMainFrame::EndFullScreen() { if (m_bFullScreen) { // 退出全屏显示,恢复原始窗口显示 ShowWindow(SW_HIDE); SetWindowPlacement(&m_OldWndPlacement); } }// 添加WM_KEYDOWN消息相应函数 void CFullScreenTestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if (nChar == VK_ESCAPE) // 如果按下的是Esc键 { // 获取主窗口指针 CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; // 调用主窗口类的自定义函数EndFullScreen(),便可以退出全屏显示模式 pFrame->EndFullScreen(); } CView::OnKeyDown(nChar, nRepCnt, nFlags); }
二 双击事件响应问题
在MFC的窗口程序中,双击事件会首先由单击事件消息处理函数来响应,而不会跳到双击事件处理函数中。如果要响应双击事件可以在单击消息处理函数中对间隔时间做判断。也可以设置style为 CS_DBLCLKS
void CClickOrDBDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default// AfxMessageBox("one"); MSG message; DWORD st = GetTickCount(); while(1) { if(::PeekMessage(&message, NULL, 0 ,0 , PM_REMOVE)) { ::TranslateMessage(&message); ::DispatchMessage(&message); if(message.message == WM_LBUTTONDBLCLK) { AfxMessageBox("two"); break; } } DWORD et = GetTickCount(); if(et - st > 200) { AfxMessageBox("one"); break; } } CDialog::OnLButtonDown(nFlags, point);}
三 WinPE4.0 中MFC窗口程序不能执行
用vc2010编译的MFC窗口程序在在win8上可以正确执行,在WinPE4.0上通过powershell 调用时没反应,不报错也没有界面。原因是使用了动态编译,程序需要很多动态链接档支持,而预加载系统中没有这些DLL.(我试着装了.NET SDK还是不行)解决办法是使用静态编译方法。这样编译出来的程序会很大,动态编译93k ,静态编译2390k ,确实包进去很多东西呢。
编译设置:
四 界面在哪儿?
MFC分为三种,单文档、多文档、基于对话框,文档是没有界面的。 从视图 -》 资源视图 -》 dialogue 中打开界面 。(找界面找了半天,新手就是很菜)
五 button操作
1 .外观
与VC6.0不同,VC2012中控件有属性窗口,可以在属性窗口中修改Caption | ID | 外观 等信息。也可以添加事件响应函数。
2 .动态改变button的大小
void CAboutDlg::OnButton1() { CRect myRect; GetClientRect(&myRect); //取得客户区的大小 ,窗口左上角总是0,0ClientToScreen(myRect); //转换为屏幕坐标 ,屏幕左上角是0,0MoveWindow(myRect.left, myRect.top, myRect.Width(), myRect.Height()); //MoveWindow使用的是屏幕坐标GetDlgItem(IDC_BUTTON1)->SetWindowPos(NULL,my rect.left,myrect.top,myrect.Width(),myrect.Height(),SWP_SHOWWINDOW); // 改button的大小 }
3 . 类向导
当然事件响应函数也可以在 项目 -》类向导(mfc class wizard)中设置或删除
六 设置配置信息
1 行号 : 工具 -》 选项 -》文本编辑器 -》选一种语言 -》勾行号
2 字体: 工具 -》 选项 -》 环境 -》 字体和颜色
七 添加源文件或头文件
右击解决方案 -》添加 -》 新建项 | 现有项
八 常见错误或禁告
1 <iostream.h>
如果include这个头文件就会报错,因为在2012中已经替换成了<iostream>
2 安全字符串处理函数
如果程序中使用了strcpy这样的CTL库函数,编译会报禁告。因为strcpy对源数据大小没有做判断很容易导致内存溢出。microsoft新建了对应的函数strcpy_s取代C++的CTL库,这些函数在Strsafe.h中
3 字符处理
“ 无法将参数2从 const char * 转换为 LPCWSTR ” 的错误 , 使用TEXT 或 _T来转换常量
MessageBox( NULL, "HelloWorld", "Information", 0 ); //MessageBox( NULL, TEXT("HelloWorld!"), TEXT("Information"), 0 ); MessageBox( NULL, _T("HelloWorld!"), _T("Information"), 0 );
VC2012中默认使用UNICODE字符集,所以ANSI字符就要转换成UNICODE才能被处理。两者不可以强制转换更不能默认转换,而需要使用函数 WidCharToMultiByte() 和MultiByteToWidChar() .使用时注意要先获得目标缓冲区大小然后再转换。
char* TcharToChar (const TCHAR * tchar) { int iLength ; char * _char;//获取字节长度 iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL); //将tchar值赋给_char WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL);return _char;}
有些函数会分别提供 ANSI 和 UNICODE 版本然后通过预编译命令对应到一起,比如Tchar.h中的一段:
#ifdef _UNICODE#define _tcslen wcslen#else#define _tcslen strlen#endif
4 多重定义错误
将函数声明成 static 函数 ,这样就只能在本文件中使用。
用 #pragma once 告诉编译器只编译一次
用#ifdef #enddef 把头文件包起来
九 调试
1 $err,hr
使用$err,hr 可以查看错误信息,相当于调用GetLastError()的结果。调试状态下,在监视1窗口输入$err,hr就可以了
2 可以在监视窗口中查看变量 也可以修改变量值 。甚至对指针变量做强制类型转换 。
3 查看堆栈
调试 -》 窗口 -》 调用堆栈 (alt + 7)
4 模块
调试 -》窗口 -》模块 ,这个窗口中可以看到程序调用了哪些DLL及DLL的信息
5 release debug
只有在debug模式下才能看到变量的值,在release模式下监视窗口显示“错误的指针” 。
十 读写INI文件
在VC程序中利用系统提供的 GetPrivateProfileString 及 WritePrivateProfileString函数直接读写系统配置ini文件(指定目录下的Ini文件)
假设在当前目录下有一个文件名为Test.ini的文件
[Section1]
Item1=huzhifeng
Item2=1234565
1.写INI文件
void CINI_File_TestDlg::OnButtonWrite() {// TODO: Add your control notification handler code here CString strSection = "Section1"; CString strSectionKey = "Item1"; char strBuff[256]; CString strValue = _T(""); CString strFilePath; strFilePath=GetCurrentDirectory(256,strBuff); //获取当前路径 strFilePath.Format("%s//Test.ini",strBuff); GetDlgItemText(IDC_EDIT_NAME,strValue); //获取文本框内容:即姓名 WritePrivateProfileString(strSection,strSectionKey,strValue,strFilePath); //写入ini文件中相应字段 strSectionKey="Item2"; GetDlgItemText(IDC_EDIT_PASSWORD,strValue); //获取文本框内容:即密码 WritePrivateProfileString(strSection,strSectionKey,strValue,strFilePath);}
2.读INI文件内容
void CINI_File_TestDlg::OnButtonRead() {// TODO: Add your control notification handler code here CString strSection = "Section1"; CString strSectionKey = "Item1"; char strBuff[256]; CString strValue = _T(""); CString strFilePath; strFilePath=GetCurrentDirectory(256,strBuff); //获取当前路径 strFilePath.Format("%s//Test.ini",strBuff); GetPrivateProfileString(strSection,strSectionKey,NULL,strBuff,sizeof(strBuff),strFilePath); //读取ini文件中相应字段的内容 strValue=strBuff; SetDlgItemText(IDC_EDIT_NAME,strValue); strSectionKey="Item2"; GetPrivateProfileString(strSection,strSectionKey,NULL,strBuff,80,strFilePath); strValue=strBuff; SetDlgItemText(IDC_EDIT_PASSWORD,strValue); UpdateData(FALSE);}CString WebEnable ;WebEnable.GetBufferSetLength(10);GetPrivateProfileString("GetExtraBarcode","WebEnable",NULL,WebEnable.GetBuffer(10),10,".\\WebConfig.ini");WebEnable.ReleaseBuffer();
十一 MFC中关闭窗口的几种办法:
退出程序用AfxGetMainWnd()->SendMessage(WM_CLOSE);
关闭当前窗口用DestroyWindow( );
关闭模式对话框用EndDialog(0);
十一 文本文件 & 文件夹
1文件是否存在
CFileStatus filestatus;if (CFile::GetStatus(_T("d://softist.txt"), filestatus)) AfxMessageBox(_T("文件存在"));else AfxMessageBox(_T("文件不存在"));
2读 写:
CStdioFile hLogFile ; CString strBarcodeBar; hLogFile.SeekToBegin();hLogFile.WriteString( m_strBarcodeUI);hLogFile.ReadString(strBarcodeBar); hLogFile.Close();
CFile hFile;
//用CFile读xml文件是会师乱码?why?
3 删除文件:
第一种方法:定义一个文件类对象来操作CFile TempFile;TempFile.Remove(指定文件名);第二种方法:DeleteFile("c:\\abc\\test.exe ");//MFC框架中可直接调用此函数第三种方法:system("del c:\\abc\\test.txt");
4 删除目录
_rmdir()
DeleteDirectory(sTempDir)
RemoveDirectory(sTempDir)
5 删除文件夹目录(非空)
bool DeleteDirectory( CString DirName){AfxMessageBox("执行删除文件夹:"+DirName);CString PUBPATH;PUBPATH=DirName;CFileFind tempFind;DirName+="\\*.*";BOOL IsFinded=(BOOL)tempFind.FindFile(DirName);while(IsFinded){IsFinded=(BOOL)tempFind.FindNextFile();if(!tempFind.IsDots()){CString strDirName;strDirName+=PUBPATH;strDirName+="\\";strDirName+=tempFind.GetFileName();AfxMessageBox("strDirName :"+strDirName);if(tempFind.IsDirectory()){//strDirName += PUBPATH;DeleteDirectory(strDirName);}else{SetFileAttributes(strDirName,FILE_ATTRIBUTE_NORMAL); //去掉文件的系统和隐藏属性DeleteFile(strDirName);}}}tempFind.Close();if(!RemoveDirectory(PUBPATH)){return false ;}AfxMessageBox("文件夹删除成功...");return true;}
十二 字符处理
m_IniFileValue.PassSNDir.AppendFormat(_T("\\%s.txt "),m_strBarcodeUI); //字符组合在一起
m_IniFileValue.PassSNDir.Format(TEXT("%s not exist"),m_IniFileValue.PassSNDir); //字符赋值
if(-1 != strMES.Find(_T("5"),0) //从0的位置开始查找字符5 ,找不到返回-1 找到 返回index
m_IniFileValue.PassSNDir.AppendFormat(_T("\\%s.txt "),m_strBarcodeUI)
m_IniFileValue.PassSNDir.Mid(m_IniFileValue.PassSNDir.Find("Next"), m_IniFileValue.PassSNDir.FindOneOf(":") - m_IniFileValue.PassSNDir.Find("Next"));
console 输出UNICODE 字符
如果用cout输出unicode 你会看到一串十六进制数。所以,如果你的编译器设置使用unicode的话,必须用wcout来输出
wcout<<TEXT("output unicode string")<<endl;
CString strOuput;
wcout<<strOuput.GetBuffer(strOuput.GetLength());
十三 退出程序
if (MessageBox("Are you sure exit G-Sensor?","Tips",MB_YESNO|MB_DEFBUTTON2)==IDYES)
{
PostQuitMessage(0);
}
十四 隐藏对话框
定义一个bool变量visible,在构造函数中初始化为false
void CGDIButtonTestDlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) { //if (lpwndpos->flags & SWP_SHOWWINDOW) if(!visible) { lpwndpos->flags &= ~SWP_SHOWWINDOW; PostMessage(WM_WINDOWPOSCHANGING, 0, (LPARAM)lpwndpos); ShowWindow(SW_HIDE); } else { CDialog::OnWindowPosChanging(lpwndpos);} }
在想正常显示的地方visible=true,ShowWindow(SW_SHOW); 即能正常显示。
想正常隐藏,既visible=false,ShowWindow(SW_HIDE);
十五 添加对话框背景图片
响应OnEraseBkgnd消息,然后在这个消息函数里面显示图片! 应该是在APP里加
BOOL CxxDlg::OnEraseBkgnd(CDC* pDC) { BITMAP bm; m_bmp.GetBitmap(&bm); m_pbmCurrent = &m_bmp; CDC dcMem; dcMem.CreateCompatibleDC(pDC); CBitmap* pOldBitmap = dcMem.SelectObject(m_pbmCurrent); pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcMem,0,0,SRCCOPY); dcMem.SelectObject(pOldBitmap);}
十六 创建非模态对话框
CSplashDlg *pSplashDlg = new CSplashDlg();
pSplashDlg->Create(IDD_SPLASH_DIALOG);
pSplashDlg->ShowWindow(SW_SHOW);
pSplashDlg->UpdateWindow();
十七 获取屏幕大小
获取屏幕大小
int with= GetSystemMetrics(SM_CXFULLSCREEN);
int heigh= GetSystemMetrics(SM_CYFULLSCREEN);
通过上边两个函数获取的是显示屏幕的大小,及不包括任务栏等区域。
int cx = GetSystemMetrics( SM_CXSCREEN );
int cy = GetSystemMetrics( SM_CYSCREEN );
这两个函数获取的是真正屏幕的大小。
十八 对话框支持拖动
添加WM_NCHITTEST 消息事件
UINT CMyAgentDlg::OnNcHitTest(CPoint point) { // TODO: Add your message handler code here and/or call default UINT nHitTest=CDialog::OnNcHitTest(point); return (nHitTest==HTCLIENT)?HTCAPTION:nHitTest; //return CDialog::OnNcHitTest(point);}
十九 一个类访问控制另一个类中的变量控件
如果要在类CVDlg 访问控制类CPPDlg中的控件 CSliderCtrl。
首先在类CPPDlg中定义 CSliderCtrl m_sld;
然后在类CVDlg 中定义
CSliderCtrl* m_pSld;
CPPDlg* m_pDlg;
然后在类CVDlg的构造函数中定义:
m_pDlg=new CPPDlg;
m_pDlg->Create(IDD_PP);
m_pSld=&m_pDlg->m_sld;
这样就可以在类CVDlg中任何地方控制类CPPDlg中的控件 CSliderCtrl。
变量,控件都是这么做的。比较正宗的一种方式。
二十 全局函数访问对话框中的控件
CGloabkjDlg *pDlg = (CGloabkjDlg *)(AfxGetApp()->GetMainWnd());
二十一 格盘代码
char *FormatW2K = "CMD.EXE";
//这里我用H:盘,你自己要填入你想格式化的盘
char *FormatW2KParam = "/C \"format.com H:/force/q/u/x/V:MISC\"";
//在后台执行格式化命令
ShellExecute(NULL,"open",FormatW2K,FormatW2KParam,NULL,SW_HIDE);
二十二 系统下关机代码:
TOKEN_PRIVILEGES tp;HANDLE hToken; LUID luid; LPTSTR MachineName=NULL; if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken )){ // PERR("OpenProcessToken",GetLastError()); return ;}if(!LookupPrivilegeValue(MachineName, SE_SHUTDOWN_NAME, &luid)){ // PERR("LookupPrivilegeValue", GetLastError()); return ; }tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL, NULL ); //到这里,是取得权限///ExitWindowsEx(EWX_REBOOT,EWX_FORCE);
1.添加成员变量 CToolBar m_WndToolBar
2.在OnInitDialog() 中 CDialog::OnInitDialog();后添加
if (!m_WndToolBar.CreateEx(this, TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_ALIGN_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS,CRect(4,4,0,0))||!m_WndToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0("未能创建工具栏\n");
return -1;
}
m_WndToolBar.ShowWindow(SW_SHOW);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
二十四
- VC++学习笔记1
- VC++学习笔记2
- VC学习笔记
- VC++ 学习笔记(-)
- VC++ 学习笔记(二)
- VC++学习笔记(三)
- VC++学习笔记(四)
- vc++学习笔记(五)
- VC++7学习笔记
- VC学习笔记
- VC++学习笔记
- VC学习笔记
- VC++学习笔记001
- VC学习笔记
- VC++学习笔记
- VC++第一章学习笔记
- vc 学习笔记 文本编辑
- VC相关学习笔记
- IT大败局----第三章 "缩水''产品的阴霾
- 无法用scott/tiger账户登入 ,无法找到SQLDEVELOPER.BAT ,Unable to find a java Virtual Machine
- Linux运维之构建Cacti网络监控平台
- 如何使用W5200的间接总线接口模式(二)
- JS等比例缩小图片尺寸
- vc++ 学习笔记
- POJ 1511 Invitation Cards (SPFA)
- MySQL 批量模式
- Android属性之build.prop,及property_get/property_set
- POJ 1584 A Round Peg in a Ground Hole
- 时隔两年再读《编程之美》
- 深入剖析Android消息机制
- JS分页
- Eclipse和Maven的结合使用--Please make sure the -vm option in eclipse.ini