vc++ 学习笔记

 一 .全屏

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,0
	ClientToScreen(myRect);  //转换为屏幕坐标 ,屏幕左上角是0,0
	MoveWindow(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);

二十四

 

 

 

 

 

 

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值