知识点:学了就要记住才可以
(2008-08-31)
1、关于inflaterect和deflaterect
简单的说就是左(left) 上(top) 右(right) 下(bottom)
下面列出其全部重载函数
CRect::InflateRect
void InflateRect( int x, int y );
void InflateRect( SIZE size );
void InflateRect( LPCRECT lpRect );
void InflateRect( int l, int t, int r, int b );
参数:
x 指定扩大CRect左和右边的单位数。
y 指定扩大CRect上、下边的单位数。
size 一个指定扩大CRect的单位数的SIZE或CSize。cx值指定扩大左、右边的单位数,cy指定扩大上、下边的单位数。
lpRect 指向一个RECT结构或CRect,指定扩大每一边的单位数。
l 指定扩大CRect左边的单位数。
t 指定扩大CRect上边的单位数。
r 指定扩大CRect右边的单位数。
b 指定扩大CRect下边的单位数。
CRect::DeflateRect
void DeflateRect( int x, int y );
void DeflateRect( SIZE size );
void DeflateRect( LPCRECT lpRect );
void DeflateRect( int l, int t, int r, int b );
参数: x 指定缩小CRect的左和右边的单位数。
y 指定缩小CRect的上、下边的单位数。
size 一个指定缩小CRect的单位数的SIZE或CSize。cx值指定缩小左、右边的单位数,cy指定缩小上、下边的单位数。
lpRect 指向一个RECT结构或CRect,指定缩小每一边的单位数。
l 指定缩小CRect左边的单位数。
t 指定缩小CRect上边的单位数。
r 指定缩小CRect右边的单位数。
b 指定缩小CRect下边的单位数。
2、
要改变CStatic 控件的caption,你可以将它映射到一个CStatic控件的变量,并用m_Static.SetWindowText()来改变,也可以能过给控件一个ID,通过
GetDlgItem(IDC_STATIC1)->SetWindowText()来完成。
3、创建圆角矩形
CRect rtWnd;
GetWindowRect(&rtWnd);
CRgn rgn;
rgn.CreateRoundRectRgn(0,0,rtWnd.Width(),rtWnd.Height(),10,10);
SetWindowRgn((HRGN)rgn,true);
4)、设置对话框的背景颜色
一个基于对话框的MFC AppWizard应用程序中,如何改变对话框的背景颜色呢?对于这个问题,其实可以由几种不同的方法来实现,具体如下(粗斜体代码为增添的):
---- 方法一:调用CWinApp类的成员函数SetDialogBkColor来实现。
---- 其中函数的第一个参数指定了背景颜色,第二个参数指定了文本颜色。下面的例子是将应用程序对话框设置为蓝色背景和红色文本,步骤如下:
---- ① 新建一个基于Dialog的MFC AppWizard应用程序ExampleDlg。
---- ② 在CExampleDlgApp ::InitInstance()中添加如下代码:
BOOL CExampleDlgApp: : InitInstance ( )
{
…
CExampleDlgDlg dlg;
m_pMainWnd = &dlg;
//先于DoModal()调用,将对话框设置为蓝色背景、红色文本
SetDialogBkColor(RGB(0,0,255),RGB(255,0,0));
int nResponse = dlg.DoModal();
…
}
---- 编译并运行,此时对话框的背景色和文本色已发生了改变。值得注意的是:在调用DoModal()之前必须先调用SetDialogBkColor,且此方法是将改变应用程序中所有的对话框颜色,并不能针对某一个指定的对话框。
---- 方法二:重载OnPaint(),即WM_PAINT消息。有关代码如下(以上例工程为准):
void CExampleDlgDlg::OnPaint()
{
if (IsIconic())
…
else
{
CRect rect;
CPaintDC dc(this);
GetClientRect(rect);
dc.FillSolidRect(rect,RGB(0,255,0)); //设置为绿色背景
CDialog::OnPaint();
}
---- 方法三:重载OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor),即WM_CTLCOLOR消息。具体步骤如下(以上例工程为准):
---- ①在CExampleDlgDlg的头文件中,添加一CBrush的成员变量:
class CExampleDlgDlg : public CDialog
{
...
protected:
CBrush m_brush;
...
};
---- ②在OnInitDialog()函数中添加如下代码:
BOOL CExampleDlgDlg::OnInitDialog()
{
...
// TODO: Add extra initialization here
m_brush.CreateSolidBrush(RGB(0, 255, 0)); // 生成一绿色刷子
...
}
---- ③利用ClassWizard重载OnCtlColor(…),即WM_CTLCOLOR消息:
HBRUSH CExampleDlgDlg::OnCtlColor
(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
/*
** 这里不必编写任何代码!
**下行代码要注释掉
** HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
*/
return m_brush; //返加绿色刷子
}
---- 方法四:还是重载OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor),即WM_CTLCOLOR消息。具体步骤如下(以上例工程为准):
---- 步骤①、②同上方法三中的步骤①、②。
---- 步骤③利用ClassWizard重载OnCtlColor(…)(即WM_CTLCOLOR消息)时则有些不同:
HBRUSH CExampleDlgDlg::OnCtlColor
(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
//在这加一条是否为对话框的判断语句
if(nCtlColor ==CTLCOLOR_DLG)
return m_brush; //返加绿色刷子
return hbr;
}
---- 编译并运行即可。
---- 关于如何改变对话框背景颜色的问题,可能还有很多种不同方法可以实现,笔者在这仅举出四种常见的方法。其中方法三的编程似乎有点不太规范,方法四则要比方法三正统些
5、点击打开新的网页
ShellExecute(NULL,"open","http://www.baidu.com",NULL,NULL,SW_MAXIMIZE);
6、在对话框中输出文本、改变静态文本框的字体
CDC* pDC=GetDC();
CString str1("Hello,World1!");
pDC->TextOut(0,50,str1);
CFont font1;
font1.CreateFont(50,0,0,0,400,
false,false,0,
ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"Arial");
//CDC *pDC=GetDC();
CFont *poldFont=pDC->SelectObject(&font1);
m_STATICTestFont.SetFont(&font1,true);
注意要放在OnPaint函数里面才能生效
7、得到系统颜色
COLORREF bkColor = GetSysColor( COLOR_3DFACE );
8、注意:要在类的头文件中的
//{{AFX_MSG(CUserLogin)
//{{AFX_VIRTUAL(CUserLogin)
//{{AFX_DATA(CUserLogin)
中使用真实的类名带C开头的,否则ClassWizard不会正确识别
9、改变某个静态文本框控件的字体大小
CFont font1;
font1.CreateFont(50,0,0,0,400,
false,false,0,
ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"Arial");
CFont *poldFont=dc.SelectObject(&font1);
CWnd* pWnd = GetDlgItem(IDC_STATICUserAccount);
pWnd->SetFont(&font1,true);
font1.DeleteObject();
这句代码CWnd* pWnd表明可以根据某个控件得到主窗口的指针
改变字体颜色:
首先要添加WM_CTLCOLOR消息响应函数
然后在函数中添加如下代码:
switch(nCtlColor)
{
case CTLCOLOR_EDIT:
if(pWnd->GetDlgCtrlID() == IDC_EDIT1)
{
static HBRUSH hbrEdit = ::CreateSolidBrush( RGB(0, 255, 0) );
pDC->SetBkColor( RGB(255, 0, 0) );
pDC->SetTextColor( RGB(0, 255, 0) );
return hbrEdit;
}
case CTLCOLOR_STATIC:
if( pWnd->GetSafeHwnd() == GetDlgItem(IDC_STATIC1)->GetSafeHwnd() )
{
static HBRUSH hbrEdit = ::CreateSolidBrush( RGB(0, 0, 0) );
pDC->SetBkColor( RGB(255, 0, 0) );
pDC->SetTextColor( RGB(0, 255, 0) );
return hbrEdit;
}
}
改变静态文本框控件的背景透明
1)将Static控件的smiple属性设置为true
2)在 case CTLCOLOR_STATIC: 中设置pDc->SetBkMode(TRANSPARENT);
10、获取某个控件的位置区域
RECT rect;
::GetWindowRect(::GetDlgItem(m_hWnd, IDC_YOURCONTROL_ID), &rect);
rect中就是控件IDC_YOURCONTROL_ID的位置。
RECT是一个结构体,CRect是一个MFC类,它从RECT继承,该类实现了许多函数用来操作RECT! 前面的带C的是MFC采用的用来表示它的类的一种约定写法!
CRect 重载了所有与RECT,LPCRECT,LPRECT的操作,
所以在使用时可以不用考虑是RECT/LPCRECT/LPRECT,因为他们会自动转换!
VC之改变控件的大小和位置
用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置。
void MoveWindow(int x,int y,int nWidth,int nHeight);
void MoveWindow(LPCRECT lpRect);
第一种用法需给出控件新的坐标和宽度、高度;
第二种用法给出存放位置的CRect对象;
例:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //获取控件指针,IDC_EDIT1为控件ID号
pWnd->MoveWindow( CRect(0,0,100,100) ); //在窗口左上角显示一个宽100、高100的编辑控件
SetWindowPos()函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况:
BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);
第一个参数我不会用,一般设为NULL;
x、y控件位置;cx、cy控件宽度和高度;
nFlags常用取值:
SWP_NOZORDER:忽略第一个参数;
SWP_NOMOVE:忽略x、y,维持位置不变;
SWP_NOSIZE:忽略cx、cy,维持大小不变;
例:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_BUTTON1 ); //获取控件指针,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 ); //编辑控件的大小和位置都改变
以上方法也适用于各种窗口。
11、 随即显示位图
CTime Time;
Time = CTime::GetCurrentTime();
srand(Time.GetSecond());
int i = rand()%4;
m_Picture.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_BITMAP1+i))); //设置位图
12、万花筒效果
this->RedrawWindow();
r2 = rand()%(r1-10);
if(r2-2 <= 1)
s = 30;
else
s = rand()%(r2-2);
CDC* pDC = GetDC();
CPen pen;
int R,G,B;
R = rand()/2;
G = rand()/2;
B = rand()/2;
pen.CreatePen(PS_SOLID,1,RGB(255*R,255*G,255*B));
pDC->SelectObject(&pen);
pDC->MoveTo(xo-(r1-r2+s),yo);
for(int i=1;i<20000;i++)
{
a1 = (PI/360)*i;
a2 = (r1*1.0/r2)*a1;
xt = int(-(r1-r2)*cos(a1)-s*cos(a2-a1)+xo);
yt = int((r1-r2)*sin(a1)-s*sin(a2-a1)+yo);
pDC->LineTo(xt,yt);
}
pen.DeleteObject();
12、CTabCtrl的用法
1)添加一个CTabCtrl的变量 CTabCtrl m_Tab;
2)DDX_Control(pDX, IDC_CTabCtrl 1, m_Tab);
3) m_imagelist.Create(27,90,ILC_COLOR24|ILC_MASK,1,0);
CBitmap bm;
bm.LoadBitmap(IDB_QA);
CBitmap bmMask;
bmMask.LoadBitmap(IDB_Lock);
m_imagelist.Add(&bm, &bmMask);
//m_imagelist.Add(&bm, RGB(0, 0, 0));
CBitmap bm2;
bm2.LoadBitmap(IDB_Lock);
m_imagelist.Add(&bm2, RGB(0, 0, 0));
CBitmap bm3;
bm3.LoadBitmap(IDB_Zixun);
m_imagelist.Add(&bm3, RGB(0, 0, 0));
m_tab.SetImageList(&m_imagelist);
m_tab.InsertItem(0,"",0);
m_tab.InsertItem(1,"",1);
m_tab.InsertItem(2,"",2);
m_tab.GetCurSel();
13、在VC中使用xml如要添加这样代码:
//--------------------------------------------------------//
#import "msxml.dll"
using namespace MSXML;
//--------------------------------------------------------//
如果你没有安装msxml
可以拷贝msxml.dll到软件目录下面
然后用类似这样的代码:
#import "C:Windowssystem32/MSXML.DLL" named_guids
主要用修改成正确的路径
14、隐藏按钮
把他移动到外面去。
GetDlgItem(ID)->MoveWindow(-100,-100,10,10);
要显示时,就把他移进来,只是位置你要调试一下。
GetDlgItem(ID)->MoveWindow(100,100,100,40);
==========================
如果你觉得这个方法不好操作,那可以使用“建立类向导”,为按钮梆定一个CButton类型的变量,例:m_bt,那么,直接使用m_bt.ShowWindow(SW_HIDE);就可以了。
GetDlgItem(ID)->ShowWindow(SW_HIDE);
15、 <script src="http://blog.csdn.net/js/LoadFeedbackCount.js" type=text/javascript></script> 如何去掉单文档应用程序的标题栏
如何取消标题栏,只保留工具栏?
在MFC 7.0里面
自动生成的单文档框架里面?
---------------------------------------------------------------
显示和隐藏标题栏
方法一:使用API实现
//隐藏TitleBar
LONG lStyle = ::GetWindowLong(this->m_hWnd, GWL_STYLE);
::SetWindowLong(this->m_hWnd, GWL_STYLE, lStyle & ~WS_CAPTION);
::SetWindowPos(this->m_hWnd, NULL, 0, 0, 0, 0,
SWP_NOSIZE ¦ SWP_NOMOVE ¦ SWP_NOZORDER ¦ SWP_NOACTIVATE ¦ SWP_FRAMECHANGED);
// 显示TitleBar
::SetWindowLong(this->m_hWnd, GWL_STYLE, lStyle ¦ WS_CAPTION);
::SetWindowPos(this->m_hWnd, NULL, 0, 0, 0, 0,??SWP_NOSIZE ¦ SWP_NOMOVE ¦ SWP_NOZORDER ¦ SWP_NOACTIVATE ¦ SWP_FRAMECHANGED);
方法二:使用CWnd成员函数ModifyStyle实现
// 隐藏TitleBar
ModifyStyle(WS_CAPTION, 0, SWP_FRAMECHANGED);
// 显示TitleBar
ModifyStyle(0, WS_CAPTION, SWP_FRAMECHANGED);
以上代码,放置在CMainFrame的OnCreate函数的尾部即可~~
16、如何得到屏幕的分辨率
int cx=GetSystemMetrics(SM_CXSCREEN);
int cy=GetSystemMetrics(SM_CYSCREEN);
或者
int GetDeviceCaps(
HDC hdc, // handle to the device context
int nIndex // index of capability to query
);
nIndex=HORZSIZE、VERTSIZE
17、以前对VC不太熟悉,想添加一个类而不继承自MFC的某个类,因为我总是用的ClW,VC就必须让我选择一个基类,很是郁闷,后来我看了别人的截图跟我的VC显示的不一样才知道,原来在工作空间的项目上面点击右键选择New Class可以添加一个不继承自MFC基类的我自己的类。
18、 键盘的捕获
case 0x08: // backspace
case 0x0A: // linefeed
case 0x1B: // escape
MessageBeep((UINT) -1);
return 0;
case 0x09: // tab
// Convert tabs to four consecutive spaces.
for (i = 0; i < 4; i++)
SendMessage(hwndMain, WM_CHAR, 0x20, 0);
return 0;
case 0x0D: // carriage return
// Record the carriage
case WM_KEYDOWN:
switch (wParam)
{
case VK_LEFT: // LEFT ARROW
case VK_RIGHT: // RIGHT ARROW
case VK_UP: // UP ARROW
case VK_DOWN: // DOWN ARROW
MessageBeep((UINT) -1);
return 0;
case VK_HOME: // HOME
// Set the caret's position to the upper left
// corner of the client area.
nCaretPosX = nCaretPosY = 0;
nCurChar = 0;
break;
case VK_END: // END
19、输出待格式的文本
CString st;
st.Format("%s(%s)/r/n%s %s",m_TempUserName,m_TempLoginID,m_TempGroupName,m_TempLevelName);
RECT rc; // output rectangle for DrawText
SetRect(&rc, 50, 90, 280+50, 41+90);
pDC->DrawText( st, &rc, DT_LEFT );
20、命令消息首先被CWinApp类处理,默认的处理流程是CWinApp类->主框架->MDI子框架->活动视图->文档
21、CMainFrame *pMainFrm = (CMainFrame*)AfxGetMainWnd();
这样可以得到MainFrame的访问权利
22、如何设置CFormView不滚动
void CxxxView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
SetScrollSizes(MM_TEXT,CSize(0,0));
}或者
GetSrollBarCtrl
ShowWindow(SW_HIDE)
23、获取view,doc,app指针
1) 在View中获得Doc指针
CYouSDIDoc *pDoc=GetDocument();一个视只能有一个文档。
2) 在App中获得MainFrame指针
CWinApp 中的 m_pMainWnd变量就是MainFrame的指针
也可以:
CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd();
3) 在View中获得MainFrame指针
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;
4) 获得View(已建立)指针
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;
CyouView *pView=(CyouView *)pMain->GetActiveView();
5) 获得当前文档指针
CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd->GetActiveDocument();
6) 获得状态栏与工具栏指针
CStatusBar * pStatusBar=(CStatusBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
CToolBar * pToolBar=(CtoolBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);
7) 如果框架中加入工具栏和状态栏变量还可以这样
(CMainFrame *)GetParent()->m_wndToolBar;
(CMainFrame *)GetParent()->m_wndStatusBar;
8) 在Mainframe获得菜单指针
CMenu *pMenu=m_pMainWnd->GetMenu();
9) 在任何类中获得
应用
程序类
用MFC全局函数AfxGetApp()获得。
24、有一个char *得指针,我怎么得到它指向的字符串的长度
char *p=new char[909];
strlen(p)=909;
sizeof(p)=909;
char * 和CString是一样的,这样就可以了:
char *c;
//给c赋值
CString str(c);
//调用cstring提供的函数就行了
int i=str.GetLength();
25、
也许有用(也谈VC中ModifyStyle&ModifyStyleEx无法改变控件的Style)
一个View中用到了一个CListCtrl,在OnInitialUpdate函数里面他调用了m_listCtrl.ModifyStyleEx(0, LVS_EX_FULLROWSELECT);但是结果是并没有改变View中这个ListCtrl的效果。
非零即真的错误,因为在其他语言中,有true和false,但是0不等于false,非零也不等于true,我今天又犯了一个
了一个类似的错误,
先这样定义了一个#define IOWriteUserID 13 //
后来我又用了一个u_short 类型的参数来传递,于是错误就发生了!
27、使用vc ,且是在菜单的ON_UPDATE_COMMAND_UI事件中调用的EnableMenuItem ,并没有使目标菜单项变为预想的不可用
但是使用CCmdUI::Enable函数却是可以使用菜单在可有用与不可用之间进行转换的。
后来查到原因:
如果命令有一个处理器(ON_COMMAND),MFC enable菜单项;否则,MFC disable菜单项。你可以设置CFrameWnd::m_bAutoMenuEnable = FALSE重载这个行为,这样的话,所有菜单项都将被enable-不管有没有处理器。
所以,在MFC应用程序中,一般不要用EnableMenuItem来enable或disable菜单,而要使用ON_UPDATE_COMMAND_UI处理器来实现菜单的enable或disable。
2) if (pDlg->GetSafeHwnd())
{
pDlg->ShowWindow(TRUE);
}
else
{
pDlg->Create(IDD_DLG);
pDlg->ShowWindow(TRUE);
// pDlg->DoModal();
}
这样做的好处是,dialog 对象中的数据不会在窗口关闭时被销毁,再一次打开窗口时,无需重新初始化和加载!
LVS_EX_CHECKBOXES
SetExtendedStyle(GetExtendedStyle()|LVS_EX_CHECKBOXES);
2)、允许非第一列显示图片。
LVS_EX_SUBITEMIMAGES
SetExtendedStyle(GetExtendedStyle()|LVS_EX_SUBITEMIMAGES);
3)、禁止拖动列宽。重载OnNotify,代码如下。
BOOL CExternListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: Add your specialized code here and/or call the base class
HD_NOTIFY *pHDN = (HD_NOTIFY*)lParam;
if((pHDN->hdr.code==HDN_BEGINTRACKW||pHDN->hdr.code==HDN_BEGINTRACKA))// &&((pHDN->iItem==2)||(pHDN->iItem==3))
{
*pResult=TRUE;
return TRUE;
}
return CListCtrl::OnNotify(wParam, lParam, pResult);
}
4)、解决首次单击不能触发click事件的方法,派生右键down事件处理函数,代码如下:
void CExternListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SetFocus();
CListCtrl::OnLButtonDown(nFlags, point);
}
5)、处理图片单击事件,判断区域,处理单击。代码如下。
void CYourDlg::OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
POINT point;
UINT uFlags;
GetCursorPos(&point);
m_ls.ScreenToClient(&point);
int nItem = m_lst.HitTest(point, &uFlags);
if(nItem >= 0)
{
CRect rc;
m_lst.GetSubItemRect(nItem,3,LVIR_BOUNDS,rc);
if(PtInRect(&rc,point))
{
MessageBox(L"...OnNMClickList");
}
}
*pResult = 0;
}
6)、改变列显示顺序。
int nArQ[] = { 1,2,0,3};
m_lst.GetHeaderCtrl()->SetOrderArray(4,nArQ);
7)、让ListCtrl可以编辑
m_lst.ModifyStyle(0,LVS_EDITLABELS);
8)、让ListCtrl可以选中一行
m_lst.SetExtendedStyle(m_lst.GetExtendedStyle()|LVS_EX_FULLROWSELECT);
m_QAListCtrl->Create(
WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT,
cMainRect, this, 1);
{
// TODO: Add your message handler code here and/or call default
PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));
CBitmapDialog::OnLButtonDown(nFlags, point);
}
19、用VC来开发应用程序,界面是个大问题,必须对windows的绘图机制有充分的了解才可以
总的来说,用对话框应用程序开发,要清楚,
问题:
1、如何在页面初始化的时候就实现画窗口和设置样式的工作,
UpdateWindow();
InvalidateRect();
Invalidate();
怎么样合理使用。