VC编程技巧.docx
- 文档编号:5384515
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:30
- 大小:40.83KB
VC编程技巧.docx
《VC编程技巧.docx》由会员分享,可在线阅读,更多相关《VC编程技巧.docx(30页珍藏版)》请在冰豆网上搜索。
VC编程技巧
MFC技巧90例--总结篇(三)
2007-03-0714:
00
21.介绍函数过程中一种任意键退出同时能处理消息的实现方法
1.设置定时器,用于使:
:
GetMessage(...)函数总能快速取到消息.
2.在函数处理中加入:
函数每执行完一步后执行下面的代码.
if(:
:
GetMessage(&msg,0,0,0))
{
if(msg.message>=WM_KEYFIRST&&msg.message<=WM_KEYLAST)return;
:
:
TranslateMessage(&msg);
:
:
DispatchMessage(&msg);
}
else:
:
PostQuitMessage(0);
22.如何隐藏工具栏
添加如下两个函数
隐藏:
voidCMainFrame:
:
OnHide()
{
if(m_wndToolBar.IsWindowVisible())
m_wndToolBar.ModifyStyle(WS_VISIBLE,0);
SendMessage(WM_SIZE);
}
显示:
voidCMainFrame:
:
OnShow()
{
if(!
m_wndToolBar.IsWindowVisible())
m_wndToolBar.ModifyStyle(0,WS_VISIBLE);
SendMessage(WM_SIZE);
}
23.如何动态获取工具条指针并给工具条加标题?
[问题提出]
工具条也是窗口,是窗口就有标题,如何给工具条加标题?
[程序实现]
不想动态改变工具条的标题就在CMainFrame:
:
OnCreate()中:
intCMainFrame:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
......
m_wndToolBar.SetWindowText(_T("Standdard"));
return0;
}
若想动态改变工具条的标题,如下:
声明一个菜单,并响应事件,如响应:
OnMyToolBar()函数
voidCMainFrame:
:
OnMyToolBar()
{
//TODO:
Addyourcommandhandlercodehere
CToolBar*pToolBar=(CToolBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);
pToolBar->SetWindowText(_T("Standdard"));
}
不要在TooBar悬浮时做OnMyToolBar()会出错的.
顺便提一下如何获得状态条的指针:
CStatusBar*pStatusBar=(CStatusBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
24.在状态条中显示鼠标的设备坐标与逻辑坐标
显示器的设备坐标系的原点在客户区的左上角,x轴向右增长,y轴向下增长。
我们要设置的逻辑坐标系的原点则在客户区的中心,x轴向右增长,y轴向上增长,如一个笛卡尔坐标系一般。
为CChildView添加一个成员函数voidOnPrepareDC(CDC*pDC,CPrintInfo*pInfo=NULL);
voidOnPrepareDC(CDC*pDC,CPrintInfo*pInfo){
CRectrect;
//设置映射模式为LOMETRIC(0.1mm),右上为增长方向
pDC->SetMapMode(MM_LOMETRIC);
//将坐标原点定在客户区的中心
GetClientRect(rect);
pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);
}
为CChildView响应鼠标移动消息,并在状态条中显示鼠标的坐标值。
m_ptMouse数据成员是原打算做十字交叉线用的,在此使用没有实际意义。
voidCChildView:
:
OnMouseMove(UINTnFlags,CPointpoint){
CClientDCdc(this);
CStringstr;
OnPrepareDC(&dc);
//要访问类CMainFrame,需要将mainfrm.h文件引入
CMainFrame*pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
//要访问CMainFrame的数据成员m_wndStatusBar,需要手工修改mainfrm.h,public这个数据成员
CStatusBar*pStatus=(CStatusBar*)&pFrame->m_wndStatusBar;
m_ptMouse=point;
str.Format("设备坐标X=%ipixel,Y=%ipixel",m_ptMouse.x,m_ptMouse.y);
pStatus->SetPaneText(1,str);
dc.DPtoLP(&m_ptMouse);
str.Format("逻辑坐标X=%i*0.1mm,Y=%i*0.1mm",m_ptMouse.x,m_ptMouse.y);
pStatus->SetPaneText(2,str);
}
25.如何用VC++动态修改应用程序菜单
[问题提出]
本文将介绍一些使用CMenu的方法,如查找指定菜单,在指定选项前添加菜单项.....
[解决方法]
使用CWnd:
:
GetMenu()访问主菜单,GetMenu()返回指向CMenu对象的指针,它有一些成员函数,允许我们修改一个菜单。
1)如何实现找到一个菜单项:
步骤如下:
{
//动态修改菜单:
//GettheMainMenu
CMenu*pMainMenu=AfxGetMainWnd()->GetMenu();
CMenu*pSubMenu=NULL;
inti;
for(i=0;i<(int)pMainMenu->GetMenuItemCount();i++)
{
pSubMenu=pMainMenu->GetSubMenu(i);
if(pSubMenu&&pSubMenu->GetMenuItemID(0)==ID_FILE_NEW)
break;
}
CStrings;
s.Format("%d",i);//菜单项的位数.
AfxMessageBox(s);
ASSERT(pSubMenu);
}
2)动态编辑菜单:
步骤如下(可以用上例的pSubMenu,要加的菜单你自己定义.):
1)添加一个称为Wzd2,命令ID为IDC_NAME_NEW1的菜单命令到该菜单中,可以用:
pSubMenu->AppendMenu(0,IDC_NAME_NEW1,"New&1");
2)在New1前插入New2,可以用:
pSubMenu->InsertMenu(IDC_NAME_NEW1,MF_BYCOMMAND,IDC_NAME_NEW2,"New&2");
3)把New1改变成New3,可以用:
pSubMenu->ModifyMenu(IDC_NAME_NEW1,MF_BYCOMMAND,IDC_NAME_NEW3,"New&3");
4)删除该菜单中第二项,可以用:
pSubMenu->RemoveMenu(1,MF_BYPOSITION);
26.VC++中的3D按钮的编程
运行AppWizard生成一个基于对话框的test工程,在对话框中加入一个CButton控件。
在CButton控件的General属性页将控件的ID改为IDC_3DTEXTBTN,Caption改为“谁与争疯”,在控件Styles属性页选中OwnerDraw,其余设置保持默认。
用classwizard创建一个新类:
C3dTextButton,基类为CButton。
为C3dTextButton类添加一个protected的函数voidDraw(CDC*pDC,constCRect&rect,UINTstate)。
如下所示编写代码:
voidC3dTextButton:
:
Draw(CDC*pDC,constCRect&rect,UINTstate)
{
CStringtext;GetWindowText(text);
intl=text.GetLength();
CRectrectClient=rect;
//获得控件的字体
CFont*pFont=GetFont();
//确定所选字体有效高度和宽度
LOGFONTlogfont;
pFont->GetObject(sizeof(LOGFONT),&logfont);
if(logfont.lfHeight==0)logfont.lfHeight=20;
logfont.lfWidth=0;//宽度设为0,宽度值由高度确定
logfont.lfWeight=1000;
logfont.lfEscapement=logfont.lfOrientation=0;
CFonttryfont;VERIFY(tryfont.CreateFontIndirect(&logfont));
CFont*pFontOld=pDC->SelectObject(&tryfont);
//根据控件大小,调整字体的高度,使文本与控件协调
CSizetextSizeClient=pDC->GetTextExtent(text,l);
if(rectClient.Width()*textSizeClient.cy>rectClient.Height()*textSizeClient.cx)
{
logfont.lfHeight=:
:
MulDiv(logfont.lfHeight,rectClient.Height(),textSizeClient.cy);
}
else{
logfont.lfHeight=:
:
MulDiv(logfont.lfHeight,rectClient.Width(),textSizeClient.cx);
}
//创建并选择协调后的字体
CFontfont;font.CreateFontIndirect(&logfont);
pDC->SelectObject(&font);
textSizeClient=pDC->GetTextExtent(text,l);
//确定文本与控件边界的距离minx,miny
intminx=rectClient.left+(rectClient.Width()-textSizeClient.cx)/2;
intminy=rectClient.top+(rectClient.Height()-textSizeClient.cy)/2;
intoldBkMode=pDC->SetBkMode(TRANSPARENT);
COLORREFtextcol=:
:
GetSysColor(COLOR_BTNTEXT);
COLORREFoldTextColor=pDC->SetTextColor(textcol);
intcx=minx;
intcy=miny;
ints=(state&ODS_SELECTED)?
-1:
+1;
cx+=3;cy+=3;
//实现3D效果
pDC->SetTextColor(:
:
GetSysColor(COLOR_3DDKSHADOW));
pDC->TextOut(cx-s*2,cy+s*2,text);
pDC->TextOut(cx+s*2,cy-s*2,text);
pDC->TextOut(cx+s*2,cy+s*2,text);
pDC->SetTextColor(:
:
GetSysColor(COLOR_3DHILIGHT));
pDC->TextOut(cx+s*1,cy-s*2,text);
pDC->TextOut(cx-s*2,cy+s*1,text);
pDC->TextOut(cx-s*2,cy-s*2,text);
pDC->SetTextColor(:
:
GetSysColor(COLOR_3DSHADOW));
pDC->TextOut(cx-s*1,cy+s*1,text);
pDC->TextOut(cx+s*1,cy-s*1,text);
pDC->TextOut(cx+s*1,cy+s*1,text);
pDC->SetTextColor(:
:
GetSysColor(COLOR_3DLIGHT));
pDC->TextOut(cx,cy-s*1,text);
pDC->TextOut(cx-s*1,cy,text);
pDC->TextOut(cx-s*1,cy-s*1,text);
pDC->SetTextColor(textcol);
//输出标题
pDC->TextOut(cx,cy,text);
//恢复设备描述表
pDC->SetTextColor(oldTextColor);
pDC->SetBkMode(oldBkMode);
pDC->SelectObject(pFontOld);
}
用classwizard重载C3dTextButton类的DrawItem函数。
编写代码如下所示:
voidC3dTextButton:
:
DrawItem(LPDRAWITEMSTRUCTlpDrawItemStruct)
{
CDC*pDC=CDC:
:
FromHandle(lpDrawItemStruct->hDC);
ASSERT_VALID(pDC);
CRectrectClient=lpDrawItemStruct->rcItem;
Draw(pDC,rectClient,lpDrawItemStruct->itemState);
}
用classwizard为IDC_3DTEXTBTN建立一个C3dTextButton控件变量m_3dTextButton1。
把“3dTextButton.h”加入testDlg头文件。
编译并测试应用程序。
27.如何正确的得到ComBox的指针
CComboBox*mComb=(CComboBox*)GetDlgItem(IDC_DuanCB);
CComboBox*mComb=(CComboBox*):
:
GetDlgItem(m_hWnd,IDC_DuanCB);
28.如何让对话框中的CEdit控件类接收对话框的消息
////////////////////////////////////////////////
//如何让对话框中的CEdit控件类接收对话框的消息
////////////////////////////////////////////////
1、在对话框中增加一个ID为IDC_EDIT1的CEdit1控件
2、通过ClassWizard生成一个基于CEdit的新类CMyEdit,
CMyEdit m_wndEdit;
3、在对话框OnInitDialog()中,将m_wndEdit子类化,使其能够接受对话框的消息。
m_wndEdit.SubclassDlgItem(IDC_EDIT1,this);
29.利用WM_CTLCOLOR消息实现编辑控制(EditControl)的文本与背景色的改变
首先要明白:
WM_CTLCOLOR是一个由控制(Control)发送给它父窗口的通知消息(Notificationmessage)。
实现步骤:
生成一个标准的单文档应用程序框架,假设应用程序的名称为Color。
我将利用它的About对话框做示范。
在Aboutdialog中添加两个Editcontrol,设定其ID为IDC_EDIT1与IDC_EDIT2。
第一种方法(对应于IDC_EDIT1):
按照标准的Windows编程,由其父窗口的消息处理函数负责处理WM_CTLCOLOR消息。
1.在CAboutDlg中添加一个数据成员:
HBRUSHm_brMine;
2.利用向导映射AboutDlg的WM_CTLCOLOR消息,产生函数:
HBRUSHCAboutDlg:
:
OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor);
pDC是AboutDlg的设备上下文,pWnd是AboutDlg中发送该消息的control指针,nCtlColor市Control的类型编码。
对其进行如下修改:
HBRUSHCAboutDlg:
:
OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor)
{
if((pWnd->GetDlgCtrlID()==IDC_EDIT1)&&(nCtlColor==CTLCOLOR_EDIT))
{
COLORREFclr=RGB(255,0,0);
pDC->SetTextColor(clr); //设置红色的文本
clr=RGB(0,0,0);
pDC->SetBkColor(clr); //设置黑色的背景
m_brMine=:
:
CreateSolidBrush(clr);
returnm_brMine; //作为约定,返回背景色对应的刷子句柄
}
else
{
HBRUSHhbr=CDialog:
:
OnCtlColor(pDC,pWnd,nCtlColor);
returnhbr;
}
}
第二种方法(对应于IDC_EDIT2):
利用MFC4.0的新特性:
Messagereflection。
1.利用向导添加一个新的类:
CColorEdit,基类为CEdit;
2.在CColorEdit中添加一个数据成员:
HBRUSHm_bkBrush;
3.利用向导映射CColorEdit的"=WM_CTLCOLOR"消息,产生函数:
HBRUSHCColorEdit:
:
CtlColor(CDC*pDC,UINTnCtlColor);
对其进行如下修改:
HBRUSHCColorEdit:
:
CtlColor(CDC*pDC,UINTnCtlColor)
{
COLORREFclr=RGB(0,0,0);
pDC->SetTextColor(clr); //设置黑色的文本
clr=RGB(255,0,0);
pDC->SetBkColor(clr); //设置红色的背景
m_bkBrush=:
:
CreateSolidBrush(clr);
returnm_bkBrush; //作为约定,返回背景色对应的刷子句柄
}
4.利用向导为IDC_EDIT2生成一个数据成员CColorEditm_coloredit;
5.在定义CAboutDlg的color.cpp文件中加入:
#include"coloredit.h"
30.如何防止密码被非法获取?
[问题提出]
这两天大家比较专注在获取Edit密码框的密码.在盗取时,我们如何防范呢?
[解决方法]
此方法针对于通过SendMessage向此窗口发送WM_GETTEXT或EM_GETLINE消息来取得密码.跟我来.
[程序实现]
方法很简单,用CWnd:
:
DefWindowProc函数拦截得到的消息(向Edit发的).
建立名为My的对话框工程.建立一个Edit控件ID=IDC_EDIT1.建一个新类名为CMyProtectEdit,派生于CEdit.
在MyDlg.cpp中声明全局变量:
BOOLg_bIdentity;
BOOLg_bIdentity;
在MyProtecEdit.cpp中:
externBOOLg_bIdentity;
响应CMyProtectEdit的DefWindowProc函数:
LRESULTCMyProtectEdit:
:
DefWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)
{
//TODO:
Addyourspecializedcodehereand/orcallthebaseclass
//对Edit的内容获取必须通过以下两个消息之一,不对其采用默认的处理:
if((message==WM_GETTEXT)||(message==EM_GETLINE))
{ //检查是否为合法
if(!
g_bIdentity)
{ //非法获取,显示非法信息
AfxMessageBox(_T("不能让你看我的密码,:
(!
"));
return0;
)
g_bIdentity=FALSE;//合法获取
}
returnCEdit:
:
DefWindowProc(message,wParam,lParam);
}
然后在MyDlg.cpp中
voidCMyDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGetPasswordDlg)
//NOTE:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 编程 技巧