孙鑫VC++学习笔记(转载至程序员之家--虎非龙)[6--10]

第6课
1.当对某菜单添加消息响应函数时,4个类的消息响应优先次序分别是:1.View;2.CDOC;3.CMainFrame.4.CWinAPP.为什么?请参阅《深入浅出》
2.消息分类:a;标准消息(以WM_开头的消息,但不包括ON_COMMAND);b;命令消息 ON_COMMAND(IDM_PHONE1, OnPhone1),菜单和工具栏的消息。c.通告消息:按钮,列表框发出的消息。
CCmdTarget只能接受命令消息。而从CCmdTarget派生的CWnd可以接收命令消息,也可以接受标准消息。
3.确定菜单的索引号,注意从0开始,分隔符也算数。什么叫弹出菜单(Popup Menu)?一个子菜单只能有一个缺省菜单。 //GetMenu()->GetSubMenu(0)->SetDefaultItem(5,TRUE);
str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),
   GetSystemMetrics(SM_CYMENUCHECK));//获得系统的菜单的位图的大小。
/* SetMenu(NULL);//移除菜单

CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
SetMenu(&menu);
menu.Detach();*/增加菜单,此处detach(),如果是局部变量。
4.
void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)
{
if(2==pCmdUI->m_nIndex)
  pCmdUI->Enable();//当此菜单显示时,设为可用。
}
5.右键弹出菜单功能的实现方法有两个:
  a.Project->Add to Project->component and controls->文件夹VC components->Popup Menu OK
  b.用TrackPopupMenu()实现。
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CMenu *pPopup=menu.GetSubMenu(0);
ClientToScreen(&point);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
   GetParent());
6.动态创建菜单的方法:

CMenu menu;
menu.CreatePopupMenu();
// GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMenu,"WinSun");
GetMenu()->InsertMenu(2,MF_BYPOSITION | MF_POPUP,(UINT)menu.m_hMenu,"WinSun");
menu.AppendMenu(MF_STRING,IDM_HELLO,"Hello");
menu.AppendMenu(MF_STRING,112,"Weixin");
menu.AppendMenu(MF_STRING,113,"Mybole");
menu.Detach();
GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,114,"Welcome");
GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,
   MF_BYCOMMAND | MF_STRING,115,"维新");
// GetMenu()->DeleteMenu(1,MF_BYPOSITION);
// GetMenu()->GetSubMenu(0)->DeleteMenu(2,MF_BYPOSITION);
7.为动态创建的菜单增加消息响应的步骤
  a.在resource.h中增加#define IDM_HELLO 123
  b.在MainFrm.h中加入afx_msg void OnHello();
  c.MainFrm.cpp中加入ON_COMMAND(IDM_HELLO,OnHello)
  d.最后加入
void CMainFrame::OnHello()
{
MessageBox("Hello!");
}
8.动态增加电话号码本步骤
  a.处理WM_Char消息。如果回车,则清空字符串,窗口重绘invalidate,将人名加入到菜单中,将字符串保存集合类CStringArray中,用的是成员函数Add方法。
  b.取出动态创建的菜单的数据的方法。
    1)创建一个弹出菜单,弹出菜单下面有4个子菜单。将子菜单的ID号连续。
    2)在resource.h中添加#define IDM_PHONE1 123....
    3)添加其消息响应函数。注意注释中的文字
BEGIN_MESSAGE_MAP(CMenu2View, CView)
//{{AFX_MSG_MAP(CMenu2View)
ON_WM_CHAR()
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)//下面的4句代码原来在此处。
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(IDM_PHONE1, OnPhone1)//一定要这4句代码移到此处。
ON_COMMAND(IDM_PHONE2, OnPhone2)
ON_COMMAND(IDM_PHONE3, OnPhone3)
ON_COMMAND(IDM_PHONE4, OnPhone4)
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
    4)填写代码
9.如何在MainFrame中拦截OnCommand消息?答,在它增加OnCommand的消息处理函数即可。
10.错误调试方法:Missing ";" before "*"
CMenu2Doc* GetDocument();//因为CMenu2Doc是个不认识的变量,将其头文件包含进即可。

 

 

 

第7课
1.如果在SDI中要调用对话框
  a.先插入一个对话框资源;
  b.然后在ClassWizards中为其创建一个类。其目的是比较方便为添加按纽和消息响应函数。
  c.然后实例化它。在实例化时,必须将其头文件包含进去。
2.创建非模态对话框,注意它不能是局部变量。当 点击非模态对话框的OnOK按纽时,它并没有关闭,而是隐藏了。需要调用destroyWindow().
3.一个对象只能一个按纽。为什么?因为在Wincore.cpp的628行有代码 ASSERT(pWnd->m_hWnd == NULL);   // only do once而创建后它的m_hWnd就不为0了。此处ASSERT的用法是如果括号里面不为真,则程序崩溃。
4.如何为静态文本框增加消息响应?首先将IDC_STATIC改名。同时还需要将Notify特性复选中。
5.完成加法功能。
  a.GetDlgItem();
  b.GetDlgItemText();
  c.GetDlgItemInt();
  d.将IDC_EDIT1关联CEDIT类型变量
  e.将IDC_EDIT1关联int型变量。注意调用 UpdateData();
  f. //::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
//::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
//GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
  g. SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);
SendDlgItemMessage(IDC_EDIT2,WM_GETTEXT,10,(LPARAM)ch2);
6.点击按纽改变窗口尺寸
   if(GetDlgItemText(IDC_BUTTON2,str),str=="收缩<<")
{
  SetDlgItemText(IDC_BUTTON2,"扩展>>");
static CRect rectLarge;
static CRect rectSmall;

if(rectLarge.IsRectNull())
{
  CRect rectSeparator;
  GetWindowRect(&rectLarge);
  GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator);

  rectSmall.left=rectLarge.left;
  rectSmall.top=rectLarge.top;
  rectSmall.right=rectLarge.right;
  rectSmall.bottom=rectSeparator.bottom;
}
if(str=="收缩<<")
{
  SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),
   SWP_NOMOVE | SWP_NOZORDER);
}
else
{
  SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(),
   SWP_NOMOVE | SWP_NOZORDER);
}
7.回车时将输入焦点移动到下一个控件
SetWindowLong()改变窗口的属性。
方法1:
改变控件的回调函数,注意IDC_EDIT1的MultiLine要复选上。
WNDPROC prevProc;
LRESULT CALLBACK WinSunProc(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
if(uMsg==WM_CHAR && wParam==0x0d)
{
  //::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));
  //SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));
  CString str;
  str.Format("%d",hwnd);
  AfxMessageBox(str);//, UINT nType = MB_OK, UINT nIDHelp = 0 );
//  AfxGetApp()->
  SetFocus(::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE));
  return 1;
}
else
{
  return prevProc(hwnd,uMsg,wParam,lParam);
}
}
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// TOD Add extra initialization here
prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,
  (LONG)WinSunProc);//设置回调函数
return TRUE;  // return TRUE unless you set the focus to a control
               // EXCEPTION: OCX Property Pages should return FALSE
}
方法2:
在OnOK响应函数中加入代码
//GetDlgItem(IDC_EDIT1)->GetNextWindow()->SetFocus();
//GetFocus()->GetNextWindow()->SetFocus();
//GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus();
GetNextDlgTabItem(GetFocus())->SetFocus();

 

 

 

第8课  对话框
1.如何改变按纽的字体?在对话框的属性中改变字体的属性即可
2.逃跑按纽的实现
  1.从CButton派生一个类,CWeixinBtn
  2.将IDC_EDIT1关联成员变量m_btn1,类型为CWeixinBtn,注意要包含头文件。
  3.在CWeixinBtn中加一个指针成员变量CWeixinBtn *pWeixinBtn,然后将其地址初始化。
  4.在新类中增加鼠标移动的消息处理。
3.属性表单
  1.插入属性页资源。Insert->new Resource->Dialog
  2.当选择Classwizard菜单时,系统提示是否为创建新的类,我们将其从CPropertyPage派生!这样可以为

方便为其增加消息响应函数。
  3.插入新的从CPropertySheet派生的类,在类中增加3个CPropertyPage的实例。
  4.在view中增加菜单项,当点击时显示属性表单,出现中文乱码,修改CPropertyPage属性为中文,另外将

其字体设为宋体。
  5.在CPropertyPage中设置SetWizardButtons可将其属性改为上一步、完成!
  6.为IDC_RADIO1关联成员变量,需要先设置Group属性才行。另外别忘记调用UpdateData().
  7.为CPropertyPage增加虚函数,OnWizardNext,如果用户点击下一步时,不想让他进入下一步,刚返回-1


  8.将用户的选择输出到屏幕上,此时可以在View中增加几个成员变量,用来接收用户选择的数据。
4.memset()的用法! memset(m_bLike,0,sizeof(m_bLike));

 

 

 

第9课
1.修改外观和图标可以在MainFrm中进行,而修改背景和光标只能在View中进行。为什么?因为view的显示挡

在了MainFrame的前面。
  a.在MainFrame中
      PreCreateWindow()中,在窗口创建之前,用重新注册窗口类的方法,比较麻烦。在PreCreateWindow

()中修改
      也可以用简单的方法,用全局函数
//cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,0,0,
// LoadIcon(NULL,IDI_WARNING));
     在窗口创建之后,在OnCreate()中修改
//SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);
//SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX);
// SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
  b.在View中
    PreCreateWindow()中
//cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
// LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockObject(BLACK_BRUSH),NULL);
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
    OnCreate()中
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));
SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));
2.创建一个不断变化的图标。用定时器和SetClassLong完成
  a.准备三个图标文件,放在RES文件夹,Insert->Resource-三个图标,
  b.在CMainFrame中增加图标句柄数组,m_hIcons[3]
m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE

(IDI_ICON1));//MAKEINTRESOURCE是一个宏,它将整数转化为Win32的资源类型,简单的说它是一个类型转换

#define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i)))
m_hIcons[1]=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2));//此处需要用到

theAPP对象,故要在文件中声明extern CStyleApp theApp;
m_hIcons[2]=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
然后将其初始化
  c.然后在定时器中实现
3.工具栏的编程
  a.加入分隔符的方法,向右拖动即可;
  b.删除按纽的方法,拖出即可。
4.创建一个新的工具栏的方法
  a.插入一个工具栏,画出其图形。
  b.在头文件中,定义CToolBar m_newToolBar
  c.在MainFrm.cpp的OnCreate()中调用
if (!m_newToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_RIGHT
  | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
  !m_newToolBar.LoadToolBar(IDR_TOOLBAR1))
{
  TRACE0("Failed to create toolbar/n");
  return -1;      // fail to create
}  
  d.点击“新的工具栏”菜单时,隐藏工具栏。两种方法
  第一种/*if(m_newToolBar.IsWindowVisible())
{
  m_newToolBar.ShowWindow(SW_HIDE);
}
else
{
  m_newToolBar.ShowWindow(SW_SHOW);
}
RecalcLayout();
DockControlBar(&m_newToolBar);*/
  第二种ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);
  e.将菜单增加复选标记。在OnUpdateUI中加入代码
    pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());
5.状态栏编程
  a.Indicator[]数组中有状态栏的信息
  如果要增加,可以在String Table中加入一个IDS_Timer,然后将其加入到[]中。
  b.在时间栏显示时间,代码略,比较简单
6.进度栏
  a.增加成员变量,CProgressCtrl m_progress
  b.OnCreate中 m_progress.Create(WS_CHILD | WS_VISIBLE,// | PBS_VERTICAL,
  rect,&m_wndStatusBar,123);
m_progress.SetPos(50);*/

  c.将其创建到状态栏的方法!如果在OnCreate()中创建,则不成立,因为获取矩形大小时失败。
    解决办法,用自定义消息:
    在MainFrm.h中#define UM_PROGRESS  WM_USER+1
afx_msg void OnProgress();
    在MainFrm.cpp中
ON_MESSAGE(UM_PROGRESS,OnProgress)
然后实现这个函数
void CMainFrame::OnProgress()
{
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
m_progress.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
  rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
}
     最后在OnCreate中调用 PostMessage(UM_PROGRESS);//不能用SendMessage()
   d.解决重绘时进度栏改变的问题。在OnPain()中重写代码
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
m_progress.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
  rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
然后在定时器消息处理函数中加入
m_progress.StepIt();
   e.显示鼠标位置。在View中增加OnMouseMove()处理函数
CString str;
str.Format("x=%d,y=%d",point.x,point.y);
//((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);
//((CMainFrame*)GetParent())->SetMessageText(str);
//((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);
GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);
7.加入启动画面
  Project-Component and ->Visual C++ Components->SplashScreen->插入

 

 

 

第10课
1.画图:
   a.创建四个菜单,为其添加消息响应;
   b.在View中添加m_DrawType,保存绘画类型;
   c.增加成员变量,m_PtOrigin,当按下鼠标左键时,保存此点;
   d.在OnLButtonUp中画点,线,矩形,椭圆,别忘记设置成透明画刷
2.为其添加一个设置对话框(线型和线宽)
   a.创建对话框,为其创建一个新类关联它;
   b.为其中的线宽关联成员变量;
   c.在View中增加一个菜单,响应新的对话框;
   d.添加线型选项设置,将其Group属性选中,并为单选按纽关联成员变量。在view中增加一个线型变量m_nLineStyle
3.添加一个颜色对话框
   a.实例化一个CColorDialog
   b.调用DoModal方法
4.添加字体对话框,将选择的字体在View中显示出来。
   a.实例化一个对象;
   b.为View添加一个字体成员变量,得到用户选择的字体。
   c.调用Invadate()发出重绘消息;
   d.再次注意一个对象只能创建一次,故要再次创建,必须将原告的删除!
5.为设置对话框增加示例功能。
   a.当控件内容改变时,发出En_change消息。而Radio按纽则为Clicked。需先UpdateData()。另外还需要ScreenToClient(&rect)
6.改变对话框的背景色和控件颜色。
  每个控件被绘制时都发出WM_CTlColor消息,
7.如何改变OK按纽的字体和背景?
  OK按纽
  a.创建一个新类,CTestBtn,基类为CButton
  b.在类中增加虚函数,DrawItem,添加代码。
  c.将OK按纽关联成员变量。类型为CTestBtn,注意将OK按纽的OwnerDraw特性选中。
  Cancel按纽
  用新类来改变。
  a.加入新文件。
  b.为Cancel关联一个成员变量,类型为CSXBtn;
  c.调用CSXBtn的方法。
  Cancel2按纽
  a.方法同上。
8.在窗口中贴图,4个步骤
  1、创建位图
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
2、创建兼容DC
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
3、将位图选到兼容DC中
dcCompatible.SelectObject(&bitmap);
4、将兼容DC中的位图贴到当前DC中。在WM_EraseBkgnd()中调用,但不能再调用基类的擦除背景函数。也可以在OnDraw函数中完成,但效率低,图像会闪烁,因为它先擦除背景,慢。
pDC->BitBlt(rect.left,rect.top,rect.Width(),
rect.Height(),&dcCompatible,0,0,SRCCOPY);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值