[转]VC++界面编程总结(二)
1."属性页的添加:
创建对话框的类,该类要从CpropertyPage继承;然后在要添加该对话框为属性页的类(头文件)里创建CpropertySheet类的一个对象m_tabsheet和新创建的对话框类的对象m_skatch;最后,在.cpp文件里的On
m_tabsheet.Create(this, WS_CHILD | WS_VISIBLE, 0);
"//使选项卡的按钮在下面
"if(m_tabsheet.m_hWnd)
"m_tabsheet.ShowWindow(SW_MAXIMIZE);//显示选项卡
//加入标签,标签名由各个子对话框的标题栏决定
"m_tabsheet.AddPage(&m_skatch);
"//用Create来创建一个属性页
"m_tabsheet.Create(this, WS_CHILD | WS_VISIBLE,
WS_EX_CONTROLPARENT);
"
RECT rect;
"m_tabsheet.GetWindowRect(&rect);
"int width = rect.right - rect.left;
"int height = rect.bottom - rect.top;
"
"//调整属性页的大小和位置
"m_tabsheet.SetWindowPos(NULL, 225, 225, width-82,
height,SWP_NOACTIVATE);
属性页的添加完成。如果要添加多个属性页,则只需要增加多个对象,如下:m_tabsheet.AddPage(&m_skatch1);
m_tabsheet.AddPage(&m_skatch2);
. . . . . .
2."List Control中标题栏(Column)的添加:
创建一个List
Control,其ID为IDC_LIST,在其Styles属性项下的View项里选择Report、Align项里选择Top、Sort项里选择None.
然后在该List所在对话框的类(头文件)里创建ClistCtrl的一个对象m_list然后在.cpp文件的On
CString strname[3];
strname[0]="Screen Name";
strname[1]="Form ID";
strname[2]="Category Path";
for(int i=0;i<3;i++)
{
m_List.InsertColumn(i,strname[i],LVCFMT_LEFT,130);
}
在这之前也要将List
Control的ID与ClistCtrl的对象m_list在DoDataExchange(CDataExchange*
pDX)函数里绑定,如下:
DDX_Control(pDX, IDC_LIST, m_List);
3."ToolBar和StatusBar中控件的添加:
方法⑴.只能在ToolBar里创建控件:首先,在ToolBar中创建一个Button,其ID为ID_TOOL_COMBO(我们要将创建的控件放在该Button的位置上).
其次,新创建一个类CMainToolBar,要从CToolBar继承(创建过程大概如下:选择工程/增加到工程/新的类;也可以选择工程的根,然后点击右键,选择新的类;或者CTL+W,选择增加类/新的类
--- 然后在class type里选择Generic Class,在Name栏里输入新类的名字,Base
class里输入CToolBar),创建成功后在该类里创建要增加的控件的对象,如:
CComboBox""m_wndMyCombo;
CStatic""m_wndCategory, m_wndCategoryPath;
CButton""m_wndOpenButton;
Cedit"""m_wndEdit;
然后在构造函数里初始化如:
m_wndMyCombo.m_hWnd = NULL;
m_wndCategory.m_hWnd = NULL;
m_wndCategoryPath.m_hWnd = NULL;
m_wndOpenButton.m_hWnd = NULL;
m_wndEdit.m_hWnd = NULL;
接着在CMainframe的头文件里创建CMainToolBar的一个对象m_wndToolBar,最后在.cpp文件的On
"int index = 0;
"CRect rect; // 可定义在头文件当中
"// ComboBox
"{
""//找到指定的工具项
""while(m_wndToolBar.GetItemID(index)!=ID_TOOL_COMBO)
"""index++;
""//设置指定工具项的宽度并获取新的区域 120是宽度
""m_wndToolBar.SetButtonInfo(index, ID_TOOL_COMBO, TBBS_SEPARATOR,
120);
""m_wndToolBar.GetItemRect(index, &rect);
""
""//设置位置
""rect.top+=1;
""rect.bottom += 200;
""
""// 创建并显示控件
""if(!m_wndToolBar.m_wndMyCombo.Create(WS_CHILD|WS_VISIBLE|
CBS_AUTOHSCROLL|
"""CBS_DROPDOWNLIST | CBS_HASSTRINGS , rect,
&m_wndToolBar, ID_TOOL_COMBO))
""{
"""TRACE0("Failed to create combo-box\n");
"""return FALSE;
""}
""m_wndToolBar.m_wndMyCombo.ShowWindow(SW_SHOW);
""
""//填充内容"
""m_wndToolBar.m_wndMyCombo.AddString("25%");
""m_wndToolBar.m_wndMyCombo.AddString("50%");
""m_wndToolBar.m_wndMyCombo.AddString("75%");
"
""//选择默认项
""m_wndToolBar.m_wndMyCombo.SetCurSel(0);
""
""//获取到内容并MSGBOX显示出来
""CString strContent;
""m_wndToolBar.m_wndMyCombo.GetWindowText(strContent);
""index = 0;
"}
其他控件都类似创建(只需要注意一下各自的Create函数的参数即可)。
方法⑵.这种方法创建不太容易控制:直接在CMainframe的头文件中创建要增加的控件的对象,如CButton"的对象m_wndAboutButton,然后创建CToolBar或者CstatusBar的对象,如:CstatusBar的对象_wndStatusBar;再增加几个函数如下:
Protected:
virtual void RecalcLayout(BOOL bNotify = TRUE);
"afx_msg void CMainFrame::On
接着在.cpp文件中将StatusBar的ID和On
" // {{AFX_MSG_MAP(CMainFrame)
" ON_COMMAND(ID_VIEW_STATUS_BAR, On
" ON_WM_CREATE()
" // }}AFX_MSG_MAP
END_MESSAGE_MAP()
然后Create函数的最后(返回值之前)实现如下代码:
CRect rc;
"VERIFY(m_wndAboutButton.Create(_T("MyAbout"),
"" WS_VISIBLE,rc,this,ID_APP_ABOUT));
"// TODO: Remove this if you don't want tool tips or a resizeable
toolbar
"m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
"CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
再在RecalcLayout函数里实现:
CRect rc;
if (m_wndStatusBar.m_hWnd)
{
""m_wndStatusBar.GetWindowRect(&rc);
""ScreenToClient(&rc);
""rc.right -= 50;
""m_wndStatusBar.SetWindowPos(NULL,rc.left,rc.top,rc.Width(),rc.Height(),
"""SWP_NOZORDER);
""rc.left = rc.right;
""rc.right += 50;
""m_wndAboutButton.SetWindowPos(NULL,rc.left,rc.top,rc.Width(),rc.Height(),
"""SWP_NOZORDER);
"}
最后在On
BOOL bShow = m_wndStatusBar.GetStyle() &
WS_VISIBLE;
"m_wndAboutButton.SetWindowPos(NULL, 0, 0, 0, 0,
SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
(bShow ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
ToolBar中的创建与此相同,只需更改一下句柄即可。
4."通过Control创建的控件,对其属性的动态控制:
在对话框类的头文件里创建所要改变属性的控件的对象,如要改变一个Button(其ID为IDC_MyButton)的属性,则需创建Cbutton的对象m_button。然后在.cpp中的DoDataExchange函数里将Button的ID和创建的对象绑定在一起:
//{{AFX_DA
""// NOTE: the ClassWizard will add DDX and DDV calls
here
"DDX_Control(pDX, IDC_MyButton, m_button);
"//}}AFX_DA
然后可以在该函数的最后进行初始化:
"m_button.EnableWindow(FALSE);
到这里已经实现了改变属性。如果要动态改变其属性,可如下实现(通过两个Button的点击改变起属性):
// RadioAll Button的点击响应函数
void CPrintDlg::On
{
""// TODO: Add your control notification handler co
""m_button.EnableWindow(TRUE);
}
// RadioSelect Button的点击响应函数
void CPrintDlg::On
{
""// TODO: Add your control notification handler co
""m_button.EnableWindow(FALSE);
}
也可以通过一个Check Button的点击来改变,在其点击响应函数里实现:
m_button.EnableWindow(!m_button.IsWindowEnabled());
其余控件属性的改变都如此。
5."窗口的分割与停靠:
一、新建一个类CMySplitter,基类为CSplitterWnd
二、重载该类的On
void CMySplitter::On
{
"// 限制切分条的运动范围。
"if(point.x<228||point.x>600)
"{
""CWnd::On
"}
"else
"{
""CSplitterWnd::On
"}
}
三、
然后就可以跟一般的窗口分割那样去做了,if(point.x<228||point.x>600)这里的范围可以随你去设置了
^_^,够简单吧。
四、切分窗口
在MaiFram.h建立切分条对象:
protected:
CMySplitter m_wndSplitter; //切分窗口对象
//在MaiFram.cpp中实现窗口切分:
BOOL CMainFrame::On
{
"// 创建拆分器窗口
if (!m_wndSplitter.CreateStatic(this, 1,
2))
""return FALSE;
if (!m_wndSplitter.CreateView(0, 0,
RUNTIME_CLASS(CLeftView),CSize(228,100), pContext)
||!m_wndSplitter.CreateView(0,1,
RUNTIME_CLASS(CDataEditView), CSize(100, 100),
pContext))
"{
""m_wndSplitter.DestroyWindow();
""return FALSE;
"}
"return TRUE;
}
6. ①怎样在程序开始的时候让它最大化?
②vc++做出来的exe文件在窗体的右上方是没有最大化和最小化按钮的,怎样实现这一功能?
③如何在显示窗口时,使最大化按钮变灰?
①在App类里的C…App::InitInstance()中把m_pMainWnd->ShowWindow(SW_SHOW)改成m_pMainWnd->ShowWindow(SW_MAXIMIZE);
②在CreateWidnow时用WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
风格.
③ 第一种方法:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT&
cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by
modifying
// the CREATESTRUCT cs
// disable the maxmini box
cs.style &=
~WS_MAXIMIZEBOX;
return TRUE;
}
第二种方法:
CMenu
*pMenu=AfxGetApp()->m_pMainWnd->GetSystemMenu(FALSE);
int x=pMenu->GetMenuItemCount(
);
UINT
pID=pMenu->GetMenuItemID(x-1);
pMenu->EnableMenuItem(pID,
MF_DISABLED);
第三种方法:
ModifyStyle(WS_MAXIMIZEBOX, 0);
这个函数也可以是最大化按钮失效!
并且可以在程序中动态的改变窗口的风格
7. 更改属性页标题
void CProSheet::SetPageTitle(int nPage, int nImage, CString
strTitle)
{
TC_ITEM item;
//item.mask = TCIF_TEXT|TCIF_IMAGE; //设置图标+文字
item.mask = TCIF_IMAGE; //只设置图标
item.iImage = nImage;
// item.pszText = strTitle.GetBuffer(0); //设置文字
GetTabControl ()->SetItem (nPage,
&item);
//要设置文字时就将上面2行有注释符的代码前的注释符去掉
}
8. 创建动态菜单
void CMainFrame::On
{
"CMenu menu;
"if(!menu.CreateMenu())
"return;
"menu.AppendMenu(MF_STRING,0,"开始");
"menu.AppendMenu(MF_STRING,0,"结束");
"CRect rc;
"m_wndToolBar.SendMessage(TB_GETRECT, pnmtb->iItem,
(LPARAM)&rc);
"m_wndToolBar.ClientToScreen(&rc);
"menu.TrackMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON |
TPM_VERTICAL,
"""rc.left, rc.bottom, this,
&rc);
//"menu.DestroyMenu();
"menu.detach();
}
9.关于打印
1.要打印哪个视就
((CMainFrame*)AfxGetMainWnd())->m_wndSplitter.SetActivePane(...)
//要打印的那个视对应的Pane
2.有一个单文档工程,文档窗口被切分:左视图由CTreeView 的派生类管理,右视图由CListView
的派生类CMyListView(其为风格为LVS_REPORT)管理,我想为右视图添加打印和打印预览,我在MyListView.cpp中添加了
ON_COMMAND(ID_FILE_PRINT,CListView::On
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CListView::On
BOOL CMyListView::On
{
// TODO: call DoPreparePrinting to invoke the Print dialog
box
// return CListView::On
pInfo->SetMaxPage(2);
BOOL
bret=DoPreparePrinting(pInfo);
pInfo->m_nNumPreviewPages=2;
return bret;
}
3.
下面是从MSDN中摘出来的一段,是用来改变消息路由的。用了这段代码之后,CView中的消息(菜单,控件,子窗口)将先被CMyShape类来处理。不知道你要的是不是这样的效果。
// This example illustrates extending the framework's standard
command
// route from the view to objects managed by the view. This
example
// is from an object-oriented drawing application, similar to
the
// DRAWCLI sample application, which draws and edits
"shapes".
BOOL CMyView::On
AFX_CMDHANDLERINFO* pHandlerInfo)
{
// Extend the framework's command route from the view
to
// the application-specific CMyShape that is currently
selected
// in the view. m_pActiveShape is NULL if no shape
object
// is currently selected in the
view.
if ((m_pActiveShape != NULL)
&&
m_pActiveShape->On
return TRUE;
// If the object(s) in the extended command route don't
handle
// the command, then let the base class On
return CView::On
}
// The command handler for ID_SHAPE_COLOR (menu command to
change
// the color of the currently selected shape) was added
to
// the message map of CMyShape (note, not CMyView) using
ClassWizard.
// The menu item will be automatically enabled or disabled,
depending
// on whether a CMyShape is currently selected in the view,
that is,
// depending on whether CMyView::m_pActiveView is NULL. It is
not
// necessary to implement an ON_UPDATE_COMMAND_UI handler to
enable
// or disable the menu item.
BEGIN_MESSAGE_MAP(CMyShape,
CCmdTarget)
//{{AFX_MSG_MAP(CMyShape)
ON_COMMAND(ID_SHAPE_COLOR, On
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
如果你只是想调用On
CMDIFrameWnd *pFrame =
(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
// Get the active MDI child window.
CMDIChildWnd *pChild =
(CMDIChildWnd *)
pFrame->GetActiveFrame();
// or CMDIChildWnd *pChild =
pFrame->MDIGetActive();
// Get the active view attached to the active MDI
child
// window.
CMyView *pView = (CMyView *)
pChild->GetActiveView();
pView->On
4.
void CMyReportView::On
{
char Filter[] = "Crystal Report files(*.rpt)|*.rpt|All
files(*.*)|*.*||";
CRect rect;
CFileDialog
OpenDlg(TRUE,0,0,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,(LPCTSTR)Filter,NULL);
if(OpenDlg.DoModal()!=IDOK) ///显示文件对话框
return;
CString m_fName=OpenDlg.GetPathName();
///取得文件名
if(m_CrystalReport)
m_CrystalReport.DestroyWindow();
GetClientRect(rect);
///////////////////创建控件///////////////
if (!m_CrystalReport.Create(AfxRegisterWndClass(0,
AfxGetApp()->LoadStandardCursor(IDC_ARROW)),WS_CHILD|WS_VISIBLE,rect,this,IDC_CRYSTALREPORT1))
{
AfxMessageBox("控件创建失败!");
return ;
}
m_CrystalReport.SetWindowParentHandle((long)(this->m_hWnd));///设置父窗口
m_CrystalReport.SetWindowBorderStyle(0);
///设置为没有边框
m_CrystalReport.SetWindowLeft(0);
///左空间
m_CrystalReport.SetWindowTop(0);
///顶部空间
m_CrystalReport.SetWindowControls(FALSE);
///不显示工具条
m_CrystalReport.SetReportFileName(m_fName);
///设置报表文件
m_CrystalReport.SetWindowWidth(rect.Width());
///设置窗口宽度
m_CrystalReport.SetWindowHeight(rect.Height());
///设置窗口高度
m_CrystalReport.SetFormulas(0, "Company=\"VC知识库\"");
///将报表中的Company变量的值设置为VC知识库
m_CrystalReport.SetDestination(0);
///设置输出对象是屏幕
m_CrystalReport.PrintReport(); ///显示报表
}
void CMyReportView::On
{
if(m_CrystalReport &&
m_CrystalReport.GetReportFileName() !=
"")
{
m_CrystalReport.SetDestination(1);
///设置输出对象是打印机
m_CrystalReport.PrintReport(); ///打印
}
10. Scroll
创建一个基于CScrollview的SDI Project(在第6步中选CScrollview)
若你已创建了,这步可以省略。
然后:
改为如
void CTestView::On
{
CScrollView::On
CSize sizeTotal;
// TODO: calculate the total size of this
view
sizeTotal.cx = 1024; //改这两个
sizeTotal.cy = 768; //
SetScrollSizes(MM_TEXT, sizeTotal);
}
11. 修改主窗口风格
AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名、窗口是叠加型的、可改变窗口大小等。要修改窗口的缺省风格,需要重载CWnd::PreCreateWindow(CREATESTRUCT&
cs)函数,并在其中修改CREATESTRUCT型参数cs。
CWnd::PreCreateWindow
函数先于窗口创建函数执行。如果该函数被重载,则窗口创建函数将使用CWnd::PreCreateWindow
函数返回的CREATESTRUCT cs参数所定义的窗口风格来创建窗口;否则使用预定义的窗口风格。
CREATESTRUCT结构定义了创建函数创建窗口所用的初始参数,其定义如下:
typedef struct tagCREATESTRUCT {
LPVOID lpCreateParams; // 创建窗口的基本参数
HANDLE hInstance; // 拥有将创建的窗口的模块实例句柄
HMENU hMenu; // 新窗口的菜单句柄
HWND hwndParent; // 新窗口的父窗口句柄
int cy; // 新窗口的高度
int cx; // 新窗口的宽度
int y; // 新窗口的左上角Y坐标
int x; // 新窗口的左上角X坐标
LONG style; // 新窗口的风格
LPCSTR lpszName; // 新窗口的名称
LPCSTR lpszClass; // 新窗口的窗口类名
DWORD dwExStyle; // 新窗口的扩展参数
} CREATESTRUCT;
CREATESTRUCT结构的style域定义了窗口的风格。比如,缺省的MDI主窗口的风格中就包括FWS_ADDTOTITLE(在标题条中显示当前的工作文档名)、FWS_PREFIXTITLE(把文档名放在程序标题的前面)、WS_THICKFRAME(窗口具有可缩放的边框)等风格。由于多种风格参数由逻辑或(“|”)组合在一起的,因此添加某种风格,就只需用“|”把对应的参数加到CREATESTRUCT结构的style域中;删除已有的风格,则需用“&”连接CREATESTRUCT结构的style域与该风格的逻辑非值。
CREATESTRUCT结构的x、y、cx、cy域分别定义了窗口的初始位置和大小,因此,在CWnd::PreCreateWindow
函数中给它们赋值,将能定义窗口的初始显示位置和大小。
下例中的代码将主框窗口的大小将固定为1/4屏幕,标题条中仅显示窗口名,不显示文档名。
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT&
cs)
{
// TODO: Modify the Window class or styles here by
modifying
// the CREATESTRUCT cs
// 修改主窗风格
cs.style &= ~FWS_ADDTOTITLE;
//去除标题条中的文档名
cs.style &= ~WS_THICKFRAME;
//去除可改变大小的边框
cs.style |= WS_DLGFRAME; //增加不能改变大小的边框
// 确定主窗的大小和初始位置
int cxScreen =
::GetSystemMetrics(SM_CXSCREEN);//获得屏幕宽
int cyScreen = ::GetSystemMetrics(SM_CYSCREEN);
//获得屏幕高
cs.x = 0; // 主窗位于左上角
cs.y = 0;
cs.cx = cxScreen/2; // 主窗宽为1/2屏幕宽
cs.cy = cxScreen/2; // 主窗高为1/2屏幕高
return
CMDIFrameWnd::PreCreateWindow(cs);
}
12. 控制滚动条
BOOL CDiagramShowView::PreTranslateMessage(MSG*
pMsg)
{
"CFileTreeDoc* pDoc = (CFileTreeDoc*)GetDocument();
"CPoint point = GetScrollPosition();
"
"if(pMsg->message ==
WM_KEYDOWN)
"{
""switch(pMsg->wParam)
""{
""case VK_LEFT:
"""if( point.x > 10)
"""{
""""EndPoint.x = EndPoint.x - 10;
""""EndPoint.y = EndPoint.y;
"""}
"""else
"""{
""""EndPoint.x = 0;
""""EndPoint.y = EndPoint.y;
"""}
"""ScrollToPosition(EndPoint);
"""InvalidateRect(NULL,TRUE);
"""break;
""case VK_RIGHT:
"""if( point.x <
pDoc->intDiagramColumnCount *
pDoc->intColumnWidth - 10 )
"""{
""""EndPoint.x = EndPoint.x + 10;
""""EndPoint.y = EndPoint.y;
"""}
"""else
"""{
""""EndPoint.y = pDoc->intDiagramColumnCount *
pDoc->intColumnWidth;
""""EndPoint.x = EndPoint.x;
"""}
"""ScrollToPosition(EndPoint);
"""InvalidateRect(NULL,TRUE);
"""break;
""case VK_UP:
"""if( point.y > 10)
"""{
""""EndPoint.y = EndPoint.y - 10;
""""EndPoint.x = EndPoint.x;
"""}
"""else
"""{
""""EndPoint.y = 0;
""""EndPoint.x = EndPoint.x;
"""}
"""ScrollToPosition(EndPoint);
"""InvalidateRect(NULL,TRUE);
"""break;
""case VK_DOWN:
"""if( point.y <
pDoc->intDiagramRowCount *
pDoc->intRowHeight - 10 )
"""{
""""EndPoint.y = EndPoint.y + 10;
""""EndPoint.x = EndPoint.x;
"""}
"""else
"""{
""""EndPoint.y = pDoc->intDiagramRowCount *
pDoc->intRowHeight;
""""EndPoint.x = EndPoint.x;
"""}
"""ScrollToPosition(EndPoint);
"""InvalidateRect(NULL,TRUE);
"""break;
""default:
"""break;
""}
"}
"return FALSE;
}
// 通过正负号判断是向上还是向下滚动
if(zDelta==120)
向上滚动
if(zDelta==-120)
向下滚动
BOOL CDiagramShowView::On
{
"CFileTreeDoc* pDoc = (CFileTreeDoc*)GetDocument();
"CPoint point = GetScrollPosition();
"
"if(zDelta==120)
"{
""if( point.y >= 20 )
""{
"""EndPoint.x = point.x;
"""EndPoint.y = point.y;
"""
"""EndPoint.x = EndPoint.x;
"""EndPoint.y = EndPoint.y - 20;
""}
""else
""{
"""EndPoint.x = EndPoint.x;
"""EndPoint.y = 0;
""}
"}
"
"if(zDelta==-120)
"{
""if( point.y <=
pDoc->intDiagramRowCount *
pDoc->intRowHeight - 20 )
""{
"""EndPoint.x = point.x;
"""EndPoint.y = point.y;
"""
"""EndPoint.x = EndPoint.x;
"""EndPoint.y = EndPoint.y + 20;
""}
""else
""{
"""EndPoint.x = EndPoint.x;
"""EndPoint.y = EndPoint.y;
""}
"}
"
"ScrollToPosition(EndPoint);
"InvalidateRect(NULL,TRUE);
"return CScrollView::On
}
13. 属性页处理通知消息
CPropertyPageImpl有一个消息映射处理WM_NOTIFY。如果通知代码是PSN_*的值,On
由于WTL 3和WTL 7设计的改变,从而存在两套不同的通知处理机制。在WTL
3中通知处理函数返回的值与PSN_*消息的返回值不同,例如,WTL 3是这样处理PSN_WIZFINISH的:
case PSN_WIZFINISH:
lResult = !pT->On
break;
On
在WTL 7中,On
#define _WTL_NEW_PAGE_NOTIFY_HANDLERS
编写新的代码没有理由不使用WTL 7的消息处理函数,所以这里就不介绍WTL 3的消息处理方式。
CPropertyPageImpl
为所有消息提供了默认的通知消息处理函数,你可以重载与你的程序有关的消息处理函数完成特殊的操作。默认的消息处理函数和相应的行为如下:
int On
BOOL On
int On
void On
BOOL On
int On
int On
INT_PTR On
void On
BOOL On
int On
HWND On
14.使工具条上的按钮点击一次为按下,再点击才弹起
bCheck=m_RtfEditToolBar.GetToolBarCtrl().IsButtonChecked(ID_TB_BOLD);
m_RtfEditToolBar.GetToolBarCtrl().CheckButton(ID_TB_BOLD,
!bCheck);