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);

二十四

 

 

 

 

 

 

   

原创粉丝点击