修改应用程序外观


窗口创建之前修改标题:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT & cs)
{
 //模认style  WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE表示将文档标题作为窗口标题.
 //要取消FWS_ADDTOTITLE才能更改标题

 cs.style&=~FWS_ADDTOTITLE; //直接去掉文档标题
 //cs.style=WS_OVERLAPPEDWINDOW;  //直接设置窗style
 cs.lpszName=_TEXT("自己的标题");
}

窗口创建之后修改标题:
1、在PreCreateWindow中修改标题  cs.lpszName=_TEXT("自己的标题");
2、SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);

去掉最大化按钮
SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) &~WS_MAXIMIZEBOX );

--------------------------------------------------------------------------------------
更改应用程序Icon、Curosr、Background(窗口创建之前)
方法一:  注册一个新的窗口类
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT & cs)
{
 WNDCLASS wls;
 wls.cbClsExtra=0;
 wls.cbWndExtra=0;
 wls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
 wls.hCursor=::LoadCursor(NULL,IDC_HELP);
 wls.hIcon=::LoadIcon(NULL,IDI_ERROR);
 wls.hInstance=::AfxGetInstanceHandle();// 获取当前应用程序实例句柄
 wls.lpfnWndProc=::DefWindowProc; //不能用CWnd类的成员函数,因为参数形式不一致
 wls.lpszClassName=_T("http://kpmyfth.org");//窗口类名
 wls.lpszMenuName=NULL;//不影响创建,因在构造单文档模板时创建CWinApp::InitInstance中
 wls.style=CS_HREDRAW |CS_VREDRAW;

 RegisterClass(&wls);//注册自己的窗口类

 //cs.lpszClass=_T("http://kpmyfth.org");//将主窗口改成自己的窗口类
 //改变了Icon,未改变Cursor和Background,其原因是view类的覆盖,若要继续更改,需在view类的  //PrecreateWindow中实现
}

方法二:调用函数AfxRegisterWndClass
1、在MainFrame::PrecreateWindow中更改Icon:
 cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW |CS_VREDRAW ,0,0,
  LoadIcon(NULL,IDI_WARNING));//?
2、在View::PrecreateWindow中更改Curosr和BackGround:
 cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW |CS_VREDRAW ,
  ::LoadCursor(NULL,IDC_HELP),(HBRUSH)GetStockObject(BLACK_BRUSH),0);


更改应用程序Icon、Curosr、Background(窗口创建之后)

1,更改icon(在MainFrame类中调用SetClassLong如下)
 ::SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
2,更改光标和背景(在view类中调用)
 ::SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(NULL_BRUSH));
 ::SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));

-----------------------------------------------------------------------------------------


实例:  不断变化的图标


1、在MainFrame中添加成员变量
 private:
     HICON m_hIcons[3];
2、在MainFrame的OnCreate中加载图标
 m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
 m_hIcons[1]=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2));
 m_hIcons[2]=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
 //在一个源文件中调用另一个源文件中的全局变量,需要进行外部声明
 //extern CSeanApp theApp;
 //注意三种获取应用程序实例句柄的方法

 SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcon[0];//将图标初始化为第一个图标
3、在MainFrame的OnCreate中设置定时器
 SetTimer(1,1000,False);
4、在MainFrame类中增加虚函数处理
 void CMainFrame::OnTimer(UINT nIDEvent)
 {
  static int index=0;
  SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcon[index];
  index=++index%3;
  CFrameWnd::OnTimer(UINT nIDEvent);
 }
----------------------------------------------------------------------------------------

工具栏编程
一、创建工具栏(参照MFC向导自动生成代码)
1、插入一个自己的工具栏资源IDR_TOOLBAR1;
2、在MainFrame中添加成员变量
   CToolBar m_NewToolBar;//
3、参照向导自动生成的代码编写:
 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 {
  if (!m_NewToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
   | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
   !m_wndToolBar.LoadToolBar(IDR_TOOLBAR1))
  {
   TRACE0("未能创建工具栏/n");
   return -1;      // 未能创建
  }
  m_NewToolBar.EnableDocking(CBRS_ALIGN_ANY);//工具栏可以停靠
  EnableDocking(CBRS_ALIGN_ANY);//框架窗口可以被停靠,两个调用缺一不可
  DockControlBar(&m_wndToolBar);//停靠
 }
 
二、隐藏和显示工具栏  ?
1、添加菜单项,响应命令代码如下:
方法一:ShowWindow
 if(m_newToolBar.IsWindowVisible())
 {
  m_newToolBar.ShowWindow(SW_HIDE);
 }
 else
 {
  m_newToolBar.ShowWindow(SW_SHOW);
 }
 RecalcLayout();//重新调整控件位置,否则只是按钮消失,工具条还在
 DockControlBar(&m_newToolBar);//若不调用则无法浮动?
方法二:CFrameWnd::ShowControlBar
 ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),TRUE);

2、更改菜单项复选标记
为菜单项添加ON_COMMAND_UI响应
void CMainFrame::OnUpdateNewToolBar(CCmdUI * pCmdUI)
{
 pCmdUI->SetCheck(m_NewToolBar.IsWindowVisible());
}

----------------------------------------------------------------------
状态栏编程
一、在状态栏中插入面板
1、插入新的字符串资源IDS_TIMER和IDS_PROGRESS
2、在MainFrm.cpp文件中的indicators数组中添加以上两个字符串资源ID
 static UINT indicators[] =
 {
  ID_SEPARATOR,           // 状态行指示器
  IDS_TIMER,  //自已添加
  IDS_PROGRESS,//自已添加
  ID_INDICATOR_CAPS,
  ID_INDICATOR_NUM,
  ID_INDICATOR_SCRL,
 };
3、新面板添加完毕,显示文本为两字符串资源值

二、实例:在IDS_TIMER所对应面板上动态显示时间
1、在OnCreate函数中设置定时器,SetTimer(1,1000,NULL);
2、添加WM_TIMER消息处理函数
 CMainFrame::OnTimer(UINT nIDEvent)
 { 
  CTime t=CTime::GetCurrentTime();
  CString str=t.Format("%H:%M:%S");
  CClientDC dc(this);
  CSize sz=dc.GetTextExtent(str);//获取字符串长度

  int index=m_wndStatusBar.CommandToIndex(IDS_TIMER);
  m_wndStatusBar.SetPaneInfo(index,IDS_TIMER,SBPS_NORMAL,sz.cx);//设置模板宽度
  m_wndStatusBar.SetPaneText(index,str);//m_wndStatusBar是CMainFrame类的成员函数CStatusBar m_wndStatusBar
  CFrameWnd::OnTimer(nIDEvent);
 }
三、进度条

1、进度条创建方法:
 CProgressCtrl m_progress;
 m_progress.Create(WS_CHILD|WS_VISIBLE,CRect(10,10,200,30),&m_wndStatusBar, IDP_PROGRESS);
 m_progress.SetPos(50);
2、在状态栏IDS_PROGRESS所指示面板上显示进度条
 不能在OnCreate函数中实现,因为OnCreate函数退出时,进度条才完全创建完成,在此之前无法获取面板所在矩形。
 可发送一个自定义消息UM_PROGRESS,并在它的处理函数中创建进度条,
(1) 在MainFrame.h中消息原型声明
 afx_msg LRESULT OnProgress(WPARAM wParam,LPARAM lParam);//在VS2005中对自定义消息的处理函数必须用这种形式
(2) 自定义消息
 #define UM_PROGRESS   WM_USER+1
(3) 消息映射
 BEGIN_MESSAGE_MAP
  ON_MESSAGE(UM_PROGRESS,&CMainFrame::OnProgress)
 END_MESSAGE_MAP
(4) 消息响应函数实现
 LRESULT CMainFrame::OnProgress(WPARAM wParam,LPARAM lParam)
 {
  CRect rect;
  m_wndStatusBar.GetItemRect(2,&rect);//获取指定面板所在矩形
  m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar, 123);
  m_progress.SetPos(50);
 }
(5) 在OnCreate函数中投递UM_PROGRESS消息到消息队列中
 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 {
  ...............
  PostMessage(UM_PROGRESS);//投递后马上返回,等WM_CREATE消息处理完后再处理UM_MESSAGE,此时窗口已完全创建
  //SendMessage(UM_PROGRESS);//直到消息处理完后才返回,此处不能使用
  return 0;
 }
存在问题:当窗口尺寸改变时,进度条位置未随面板位置移动。
解决方法:添加WM_PAINT消息处理函数,在此函数里面移动进度条位置(取消投递UM_PROGRESS消息)
 void CMainFrame::OnPaint()
 {
  CPaintDC dc(this); // device context for painting
  CRect rect;
  m_wndStatusBar.GetItemRect(2,&rect);
  if(!m_progress.m_hWnd)//如果已创建
  {
  
   m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar, 123);
  }
  else
  {
   m_progress.MoveWindow(rect);
  }
  m_progress.SetPos(50);
 }

四、实例:鼠标移动时,在第一个面板上显示当前点的坐标

void CChangeAppStyleView::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 CString str;
 str.Format("x=%d,y=%d",point.x,point.y);
 //(((CMainFrame *)GetParent())->m_wndStatusBar).SetWindowText(str);//方法一
 ((CMainFrame *)GetParent())->SetMessageText(str);//方法二查看CFrameWnd::SetmessageText
 ((CMainFrame *)GetParent())->GetMessageBar()->SetWindowText(str);//方法三
 GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);//方法四
 //AFX_IDW_STATUS_BAR:系统预先定义好的状态栏ID号,可查看CStatusBar::Create
 CView::OnMouseMove(nFlags, point);
}
五、应用程序的启动画面(VC++组件)

-------------------------------------------------------------------------------------------------------------------

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值