工具栏(AIt+T )与工具栏(T)如何t文件转换dwg文件工具

下次自动登录
现在的位置:
& 综合 & 正文
VC如何在VC5中控制工具条的停靠位置
作者:宋立波
在VC5 中开发大型应用时,工具条通常是程序中必不可少的重要功能因素, 其中工具条在整个窗口中的停靠位置尤其关键,它直接影响到程序界面的外观形 象。下面针对笔者实际开发中各类工具条停靠位置的控制过程,详细阐述其实现 技巧。   一、标准工具条停靠位置的控制   VC5 应用程序向导生成的框架中,都具有普通工具条的控制方法。正 常情况下工具条类CToolBar是控制条类CControlBar 的派生类,其显示的初始 停靠位置是通过调用继承的函数CControlBar::EnableDocking(DWORD dwStyle)来 确定的,其参数dwStyle用来指定停靠具体位置,与本文有关的风格如下(其余请 参阅VC5的联机文档):   CBRS_ALIGN_TOP 停靠在框架窗口客户区域顶部   CBRS_ALIGN_BOTTOM 停靠在框架窗口客户区域底部   CBRS_ALIGN_LEFT 停靠在框架窗口客户区域左边   CBRS_ALIGN_RIGHT 停靠在框架窗口客户区域右边   CBRS_ALIGN_ANY 停靠在框架窗口客户区域任何位置   在利用应用程序向导AppWizard 生成的应用程序中,其控制代码默认的停靠 位置控制风格为CBRS_ALIGN_ANY,即允许停靠在框架窗口客户区域的任何边上。 工具条在正常显示时为停靠在窗口客户区域的顶部,控制指令为 EnableDocking(CBRS_ALIGN_ANY)或m_wndToolBar。EnableDocking(CBRS_ALIGN_ANY) , 注意,在实际程序控制时前者必须处于所有其它控制代码的前面,否则浮动工具 条或特殊工具条等部分代码可能无法奏效。具体控制方法请参考利用应用程序向 导生成的任何一个程序实例的框架代码部分中的建立函数ONCREATE()。   应用程序的单文档和多文档的窗口框架类均为CFrameWnd 的派生类,其指定 工具条的停靠位置均是通过调用继承的函数 CFrameWnd::EnableDocking(DWORD dwDockStyle)来实现的,其可选的参数除上述五种之外,还增加了 CBRS_FLOAT_MULTI参数,这个参数主要是为设计浮动工具条而增加的,其用来确 定一个框架窗口中允许存在多个浮动工具条。同样,利用应用程序向导 AppWizard 生成的应用程序,其默认的停靠位置也是CBRS_ALIGN_ANY,即允许工 具条停靠在框架窗口的任何边上,其默认的初始位置为框架窗口的顶部,即为 EnableDocking(CBRS_ALIGN_ANY)或m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY)。
  二、浮动工具条停靠位置的控制   如果在一个框架窗口中存在多个标准或浮动工具条时,需要利用函数 void DockControlBar(CControlBar *pBar,UINT nDockBarID=0,LPCRECT lpRect= NULL)来 确定要控制停靠位置的工具条,它也是CFrameWnd类的成员函数,其中参数pBar用 来指向被控制停靠位置的工具条对象指针,参数nDockBarID用来确定工具条停靠 在框架窗口的哪条边上,其控制风格的具体取值为:   AFX_IDW_DOCKBAR_TOP 停靠在框架窗口的顶部   AFX_IDW_DOCKBAR_BOTTOM 停靠在框架窗口的底部   AFX_IDW_DOCKBAR_LEFT 停靠在框架窗口的左边   AFX_IDW_DOCKBAR_RIGHT 停靠在框架窗口的右边   当参数nDockBarID的取值为0时,则工具条可以停靠在框架窗口中的任何一 个可停靠的边上,其默认的初始位置为窗口顶部。   三、并列工具条停靠位置的控制   很多大型应用程序中都存在这样的工具条,将多个工具条同时并列停靠在某 窗口的某一条边上。对于这种停靠方法,利用上述工具条控制函数 DockControlBar的lpRect参数,通过控制工具条的停靠矩形区域的方法可以实现。 如笔者实现的函数如下:   (一)在实现文件MainFrm.h中增加如下成员函数定义   void DockControlBarLeftOf(CToolBar* Bar,CToolBar* LeftOf);   (二)在实现文件MainFrm.cpp中增加如下成员函数   void CMainFrame::DockControlBarLeftOf(CToolBar* Bar,CToolBar* LeftOf)    { //设置工具条并列停靠在同一条边上    C //矩形区域定义    DWORD    UINT n=0;    RecalcLayout();//重新显示    LeftOf-&GetWindowRect(&rect);    rect.OffsetRect(1,0);//设置偏移值以停靠在同一边上    dw=LeftOf-&GetBarStyle();    n=(dw&CBRS_ALIGN_TOP)?AFX_IDW_DOCKBAR_TOP:n;    n=(dw&CBRS_ALIGN_BOTTOM&&n==0)?AFX_IDW_DOCKBAR_BOTTOM:n;    n=(dw&CBRS_ALIGN_LEFT&&n==0)?AFX_IDW_DOCKBAR_LEFT:n;    n=(dw&CBRS_ALIGN_RIGHT&&n==0)?AFX_IDW_DOCKBAR_RIGHT:n;    DockControlBar(Bar,n,&rect);    }   在这个函数中应注意对RecalcLayout()函数和OffsetRect()函数的调用, 前一个函数用来重新显示被调整的客户区和工具条,后一个函数用来重新确定 矩形区域,这相当于利用鼠标将第二个工具条窗口拖动到前一个工具条上然后释放。   (三)修改应用程序建立函数OnCreate()中的相应DockControlBar()函数 为DoctControlBarOf()函数,并正确设置工具条对象的指针,如笔者实现程序 中的控制代码如下:   EnableDocking(CBRS_
在自己的应用程序定制多媒体真彩封页,可以使应用程序在显示名称和版权 特性时丰富程序界面,避免由于应用程序启动前进行大量数据初始化时用户进 行较长时间的空等待过程,在给应用程序增加了生动特性和专业特性的同时, 也起到了宣传和广告的作用。虽然VC5中具有特定的类来实现这一功能,但通过 定制自己的应用程序多媒体启动封页,还可使自己的应用程序别具一格。VC5中 的实现步骤:
  1.制作封页位图:制作应用程序多媒体启动封页真彩位图,记录位图的高 度和宽度,建立所需要的其它多媒体声音等文件;
  2.建立应用程序:利用FILE-〉NEW菜单建立名为START的多文档应用程序框 架,并利用类向导AppWizard增加基类为generic CWnd 的新类CSplashWnd,将 新类的文件改名为splash.h和splash.cpp,并增加WM_CREATE和WM_PAINT的消息 映射函数;
  3.定义变量和函数:在splash.h中定义如下成员变量和函数:
  public:
   BOOL Create(CWnd* pParentWnd=NULL);
   HANDLE hBitsS
   LPSTR pBitsS
   UINT iW,iH;
  4.建立启动封页窗口:在splash.cpp中增加Create函数,建立显示位图的 弹出窗口:
  #include "windowsx.h"//增加扩展窗口建立
  ......
  struct{//位图文件头结构
   BITMAPINFOHEADER H
  BOOL CSplashWnd::Create(CWnd* pParentWnd)
  { //建立显示位图的弹出窗口
   return CreateEx(0,AfxRegisterWndClass(0,
   AfxGetApp()-〉LoadStandardCursor(IDC_ARROW)),
   NULL,WS_POPUP|WS_VISIBLE,0,0,672,480,
   pParentWnd-〉GetSafeHwnd(),NULL);
  int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
  { ......
   // TODO: Add your specialized creation code here
   CenterWindow();//使弹出窗口居中
   return 0;
  5.完善析构函数:在splash.cpp中完善析构函数,为显示位图作准备:
  CSplashWnd::CSplashWnd()//完善析构函数
  { iW=672;iH=480;//位图的宽度和高度
   Info.Header.biSize=sizeof(BITMAPINFOHEADER);
   Info.Header.biWidth=iW;
   Info.Header.biHeight=iH;
   Info.Header.biPlanes=1L;
   Info.Header.biBitCount=24L;
   hBitsSrc=::GlobalAlloc(GHND,(long)(iW*iH*3));//分配内存
   pBitsSrc=(LPSTR)::GlobalLock(hBitsSrc);//加锁内存
  CSplashWnd::~CSplashWnd()
  { ::GlobalUnlock(hBitsSrc);//解锁内存
   ::GlobalFree(hBitsSrc);//释放内存
  6.显示真彩位图:在splash.cpp中完善Onpaint函数,实现真彩位图的显示:
  void CSplashWnd::OnPaint()
  {......// TODO: Add your message handler code here
   fbmp.Open("c://windows//EMC1.BMP",CFile::modeRead|
   CFile::typeBinary|CFile::shareExclusive);//打开文件
   fbmp.Seek(54,CFile::begin);//位图文件头为54字节
   fbmp.ReadHuge(pBitsSrc,(long)(iW*iH*3));//读文件
   fbmp.Close();//关闭文件
   HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,
   (BITMAPINFOHEADER FAR*)&(Info.Header),CBM_INIT,
   pBitsSrc,(LPBITMAPINFO)&Info,DIB_RGB_COLORS);//建立位图
   HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);//建立内存
   HBITMAP hBitmapOld=SelectBitmap(hMemDC,hBitmap);//选择对象
   ::StretchBlt(dc.m_hDC,0,0,iW,iH,hMemDC,
   0,0,iW,iH,SRCCOPY);//显示真彩位图
   ::DeleteObject(SelectObject(hMemDC,hBitmapOld));//删除位图
  7.弹出窗口类声明:在Mainfrm.h中增加代码,为显示和撤销弹出窗口作准备:
  class CsplashW//闪烁窗口类
  ......
  class CMainFrame : public CMDIFrameWnd
  {......
  public:
   CSplashWnd SplashW//声明类
  8.真彩封页的实现:在Mainfrm.cpp中增加显示弹出窗口、播放音乐、延时 功能和撤销弹出窗口的代码,以实现真彩封页的整个处理过程:
  #include "splash.h" //新类支持
  #include "mmsystem.h"//多媒体支持
  #pragma comment(lib,"WINMM.LIB")//多媒体支持
  ......
  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
   SplashWnd.Create(this);//创建弹出窗口
   SplashWnd.ShowWindow(SW_SHOW);//显示弹出窗口
   SplashWnd.UpdateWindow();//更新弹出窗口
   int dd=sndPlaySound("c://windows//reminder.wav",
   SND_ASYNC|SND_LOOP);//异步播放WAV文件
   if (dd==FALSE){//参数SND_ASYNC
在CFormView 中产生CBitmapButtom: 例如要生成一个OPEN和一个SAVE的CBitmapButtom,可按如下方法:
class CMainWindow : public CFrameWnd { private: CBitmapButtom m_OpenB CBitmapButtom m_SaveB CBitmapButtom m_SaveB public: ...... };
int CMainWindow : OnCreate(LPREATESTRUCT) { CR rect.SetRect(4,4,36.36); m_OpenButtom.Create(NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, rect, this, IDB_OPEN); m_OpenBittom.LoadBitmap("OPENU","OPEND");
// m_SaveButtom 如上
。。。。。。。 return 0; }
BEGING_MESSAGE_MAP(CMainWindow, CFromView) .
BEGING_MESSAGE_MAP(CMainWindow, CFromView) . ON_BN_CLICKED (IDB_OPEN, OnOpen) . . END_MESSAGE_MAP()
//如果以上方法不行请检查你的BITMAP 资源,APPSTUDIO中,"OPENU"和 // "OPEND" 等的资源名称都是需要用引号引起来的, LoadBitmap不成功 // "OPEND" 等的资源名称都是需要用引号引起来的, LoadBitmap不成功 // 很可能就是由此产生的。 // AutoLoad的用法下次再POST出来
---- 当前,用AppWizard新建的支持文档/视的SDI项目,只含有从CWinApp, CFrameWnd,CDocument,CView或CView的子类派生的4个类,在CWinApp的 InitInstance函数中只实现了一个管理文档/普通视的文档模板.
---- 若想实现管理文档/滚动视,及管理文档/两行一列可编辑分隔器这样 两个文档模板,只需做:
---- (1) 用AppWizard新建名为T2的支持文档/视的SDI项目,建立的最后 一步,选择CScrollView派生视类.
---- 建立完后,此项目的文件名及类名为:
T2App.h,T2App.cpp: 含CT2App类的声明及实现 MainFrame.h,MainFrame.cpp: 含CMainFrame类的声明及实现 T2Doc.h,T2Doc.cpp: 含CT2Doc类的声明及实现 T2View.h,T2View.cpp: 含CT2View类的声明及实现 (2) 用ClassWizard从CFrameWnd生成名为F2的框架类,从CEditView生成名 为V的视类.
---- (3) 新建一菜单,其ID值为M2,然后新建一串表条目,其ID,VALUE, CAPTION域分别等于M2,M2的值(在resource.h可找到),"/n/nTEMPLATE2".
---- (4) 在CWinApp.cpp中,加入#include "F2.h"及#include "V.h".
---- 在InitInstance函数的AddDocTemplate(pDocTemplate)语句后,加入以 下语句,以生成 与M2菜单及串表相关的第2个文档模板:
pDocTemplate=new CSingleDocTemplate( M2, RUNTIME_CLASS(CT2Doc), RUNTIME_CLASS(F2), RUNTIME_CLASS(V)); AddDocTemplate(pDocTemplate); ---- (5) 在F2.h中,加入成员变量private: CSplitterWnd m_在F2.cpp中,加入 #include "V.h".
---- 重载框架类F2的成员函数F2::OnCreateClient:
CR GetClientRect(&rc); m_splitter.CreateStatic(this,2,1); //建立两行一列分隔器 m_splitter.CreateView(0,0,pContext- & m_pNewViewClass,CSize (rc.Width(),rc.Height()/2),pContext);
m_splitter.CreateView(1,0,RUNTIME_CLASS (V),CSize(0,0),pContext); SetActiveView((CView*)m_splitter.GetPane(0,0)); return TRUE; ---- 初启此SDI,或用户点击了"文件"- &"新建"菜单项时,将出现要求选定 模板类型的"新建"对话框,选定"T2"将运行滚动视模板,而点击"TEMPLATE2" 将运行两行一列可编辑分隔器模板.
---- 要使滚动视中的水平和垂直滚动条可见,可在CT2View::OnInitialUpdate() 中,将sizeTotal.cx,sizeTotal.cy置为大于600的值.
---- 对支持文档/视的MDI项目,可照搬以上的做法,但要从CMDIChildWnd派 生F2框架类.初启此MDI时,不会出现"新建"对话框,这点与SDI不同.仅当用户 点击了"文件"- &"新建"菜单 项时,才会出现"新建"对话框.
有两种方法。其一,调用CWnd: : GetDlgItem,获取一个CWnd*指针调用成员函数。 下例调用GetDlgItem,将返回值传给一个CSpinButtonCtrl*以便调用 CSpinButtonCtrl : : SetPos 函数: BOOL CSampleDialog : : OnInitDialog ( ) { CDialog : : OnInitDialog ( )
//Get pointer to spin button . CSpinButtonCtrl * pSpin - ( CSpinButtonCtrl *) GetDlgItem(IDC_SPIN) ASSERT _ VALID (pSpin) //Set spin button’s default position . pSpin —& SetPos (10)
return TRUE }
其二, 可以使用ClassWizard将控件和成员变量联系起来。在ClassWizard中简单 地选择Member Variables标签,然后选择Add Variable …按钮。如果在对话资源 编辑器中,按下Ctrl键并双击控件即可转到Add Member Variable对话。
如何用VC++实现在对话框的控件上显示ToolTip 并在状态条上显示控件的信息 ---- 利用 VC++ 的 AppWizard,可以很容易地实现工具条和菜单项的 ToolTip 或在状态条上显 示帮助信息,但要在对话框的控件上显示 ToolTip 并在状态条 上显示控件信息并不是那么容易, 其实,利用 VC++ 中的 WM_SETCURSOR 与 TTN_NEEDTEXT 消息就可达到目的。具体操作如下:
---- 利用 VC++ 的 MFC AppWizard 生成一个 SDI 或 MDI 的应用程序
---- 编辑对话框控件的字符串资源
---- 例如:
---- IDC_DBBUTTON1 = "this is 肖天鹏的第一自制按钮/n天 鹏", 其中字符 串"this is 肖天鹏的第一自制按钮"将在鼠标移到控件上时显示在状态条上,字 符串"天 鹏"将作为 ToolTip 显示。
---- 建立消息映射。
---- 在对话框的头文件 (*.H) 中加入以下代码:
protected: void SetStatusText(UINT nID=0); //{{AFX_MSG(CFileOp1) afx_msg void OnDestroy(); afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); //}}AFX_MSG afx_msg BOOL OnTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult ); DECLARE_MESSAGE_MAP()
---- 在对话框的实现文件 (*.CPP) 中加入以下代码:
BEGIN_MESSAGE_MAP(CFileOp1, CDialog) //{{AFX_MSG_MAP(CFileOp1) ON_WM_DESTROY() ON_WM_SETCURSOR() //}}AFX_MSG_MAP ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnTipNotify) END_MESSAGE_MAP()
---- 编辑消息处理函数。
BOOL CFileOp1::OnSetCursor (CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default if(pWnd==this) SetStatusText(); else { TOOLTIPTEXT m_ m_psttt.hdr.hwndFrom=m_hW m_psttt.hdr.idFrom=pWnd- &GetDlgCtrlID(); m_psttt.hdr.code=TTN_NEEDTEXT; m_psttt.uFlags= TTF_IDISHWND; SetStatusText(pWnd- &GetDlgCtrlID()); this- &SendMessage(WM_NOTIFY, m_psttt.hdr.idFrom,(LPARAM)&m_psttt); } return CDialog::OnSetCursor (pWnd, nHitTest, message); }
void CFileOp1::OnDestroy() { SetStatusText(); CDialog::OnDestroy(); }
void CFileOp1::SetStatusText(UINT nID) { if(nID==0) nID=AFX_IDS_IDLEMESSAGE; CWnd *pWnd=AfxGetMainWnd()- &GetDescendantWindow (AFX_IDW_STATUS_BAR); if(pWnd) { AfxGetMainWnd()- &SendMessage (WM_SETMESSAGESTRING ,nID); pWnd- &SendMessage(WM_IDLEUPDATECMDUI); pWnd- &UpdateWindow(); } }
BOOL CFileOp1::OnTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) { TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; UINT nID =pNMHDR- &idF if (pTTT- &uFlags & TTF_IDISHWND) { nID = ::GetDlgCtrlID((HWND)nID); if(nID) { TCHAR szFullText[256]; CString StrTipT AfxLoadString(nID,szFullText); AfxExtractSubString(StrTipText, szFullText,1,’/n’); if(!StrTipText.IsEmpty()) strcpy(pTTT- &lpszText,StrTipText); pTTT- &hinst = AfxGetResourceHandle(); return(TRUE); } } return(FALSE); }
---- 在 Stdafx.h 文件中加入以下指令:
#include 〈 afxpriv.h& #include 〈 afxres.h&
---- 将该对话框作为一个 SDI 或 MDI 应用程序的主框架的子窗口,生成这样 一个对话框后,当你把鼠标移到某个控件 ( 必须有相应的字符串资源 )上时, 就会出现该控件的 ToolTip 和状态条信息。
  VC++ 5.0风格的工具栏具有平面外观,左边带有一个“把手”,你可以通过 鼠标拖动这个“把手”来移动工具栏。工具栏各组间带有分隔线(如图1所示)。 当鼠标在工具栏上面移动时,工具栏上的相应按钮会突出显示。本文所讨论的增 强型工具栏CEnhanceToolBar类由CToolBar类所派生,是CToolBar类的补充和扩展。
  如果你并不在乎工具栏有没有“把手”的话,要生成平面工具栏是十分简单 的。你只需要在CMainFrame的OnCreate()函数中添加一句话就可以(必须加在工 具栏生成函数之后,因为MFC在生成工具栏时,要清除其式样):
  //MainFrm.cpp
  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
   ......
  if(!m_wndToolBar.Create(this)
  //!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
   TRACE0("Failed to create toolbar/n");
   return -1; // fail to create
  m_wndToolBar.ModifyStyle(0,TBSTYLE_FLAT);
  //设置工具栏为平面格式
   ......
  如果你的计算机安装了4.71.1712.3版本的COMCTL32.DLL(该动态库随 IE 4.0一同发行),那就更好了,你的工具栏就会自动绘制分隔线。你可以通过 鼠标拖动工具栏的非按钮区域来移动这种工具栏。GetRight中的工具栏就是这 样的。
  如果你要得到更好看(更“专业”)的工具栏,那么就请跟我一步步地做下去。
  1.添加一个新类,本文中叫做CEnhanceToolBar类,由CToolBar类派生。
  2.为CEnhanceToolBar类添加成员变量和函数的声明,并且根据你的需要设 置其访问属性。
  //EnhanceToolBar.h
  // Overrides
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CEnhanceToolBar)
  //按钮状态变化时调用此函数
  virtual void OnUpdateCmdUI(CFrameWnd*pTarget,BOOL bDisableIfNoHndler);
  //}}AFX_VIRTUAL
  // Implementation
  public:
   void DrawGrip(CWindowDC*pDC,CRect& rectWindow);//“把手”绘制函数
   void EraseNonClient();//擦除非客户区
   void DrawSpace();//分隔线绘制函数
   void RedrawBackground();//背景重绘函数
  private:
   int ButtonN//工具栏的按钮数(包括分隔线)
   COLORREF HiLight, S//3D控件的加亮色和阴影色
  3.添加成员函数的定义:
  //EnhanceToolBar.cpp
  void CenhanceToolBar :: OnUpdateCmdUI(CframeWnd * pTarget, BOOL bDisableIfNoHndler)
  {//按钮状态变化时调用此函数
   static CUIntArray S
   int I
   UINT dwS
   for (Index = 0; Index & ButtonN Index++)
   dwStyle = GetButtonStyle(Index);
   Styles.SetAtGrow(Index,dwStyle);//保存按钮的式样
  CToolBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
  //调用基类的处理函数
   for (Index = 0; Index & ButtonN Index++)
   {//设置选中的按钮(checked button)为按下的状态
   dwStyle = GetButtonStyle(Index);
   if (dwStyle & TBBS_DISABLED)
  //如果按钮为禁用状态,则返回(避免闪烁)
   if (dwStyle & TBBS_CHECKBOX)
   if (dwStyle & TBBS_CHECKED)
   dwStyle |= TBBS_PRESSED;
   dwStyle &= ~TBBS_PRESSED;
   SetButtonStyle(Index,dwStyle);//设置按钮的式样
   //检查按钮的式样是否改变(按下或释放)
   for (Index = 0; Index & ButtonN Index++)
   dwStyle = GetButtonStyle(Index);
   if (Styles[Index] != dwStyle)
   RedrawBackground();//重新绘制背景
   Invalidate();//重新绘制整个工具栏
  //已更新整个工具栏,因此没必要继续循环
  void CEnhanceToolBar::DrawGrip(CWindowDC *pDC, CRect& rectWindow)
  {//绘制把手
   if (IsFloating())//如果工具栏是浮动状态,则不绘制“把手”
   CRect GripRect = rectW//得到把手的矩形区域
   GripRect.DeflateRect(1,1);//矩形区域的各边向中心靠近一个像素
  if (m_dwStyle & CBRS_ORIENT_HORZ)
  //如果工具栏为水平状态,则“把手”在左边
   GripRect.right = GripRect.left + 3;//绘制第一条隆起的棱
   pDC-&Draw3dRect(GripRect, HiLight, Shadow);
   GripRect.OffsetRect(4,0);//绘制第二条隆起的棱
MDI框架的客户区被另一个窗口的框架所覆盖.为了改变客户区的背景色,你需要 重画这个客户窗口.为了做到这点,你要处理消息WM_ERASEBKND产生一个新类,从 CWnd继承,姑且称之为CMDIClient.给它加上一个成员变量, #include "MDIClient.h" class CMainFrame : public CMDIFrameWnd { ... protected: CMDIClient m_wndMDIC } 在CMainFrame中重载CMDIFrameWnd::OnCreateClient BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { if ( CMDIFrameWnd::OnCreateClient(lpcs, pContext) ) { m_wndMDIClient.SubclassWindow(m_hWndMDIClient); return TRUE; } else return FALSE; } 然后就可以加入对消息WM_ERASEBKGND的处理了.
调用CWnd : : SetWindowText可以改变任何窗口(包括控件)的标题。 //Set title for application’s main frame window . AfxGetMainWnd ( ) —& SetWindowText (_T("Application title") )
//Set title for View’s MDI child frame window . GetParentFrame ( ) —& SetWindowText ("_T ("MDI Child Frame new title") )
//Set title for dialog’s push button control. GetDigitem (IDC_BUTTON) —& SetWindowText (_T ("Button new title ") ) 如果需要经常修改窗口的标题(注:控件也是窗口),应该考虑使用半文档化的函数 AfxSetWindowText。该函数在AFXPRIV.H中说明,在WINUTIL.CPP中实现,在联机帮助 中找不到它,它在AFXPRIV.H中半文档化, 在以后发行的MFC中将文档化。 AfxSetWindowText的实现如下: voik AFXAPI AfxSetWindowText (HWND hWndCtrl , LPCTSTR IpszNew ) { itn nNewLen= Istrlen (Ipaznew) TCHAR szOld [256] //fast check to see if text really changes (reduces flash in the controls ) if (nNewLen &_contof (szOld) || : : GetWindowText (hWndCrtl, szOld , _countof (szOld) !=nNewLen || Istrcmp (szOld , IpszNew)! = 0 { //change it : : SetWindowText(hWndCtrl , IpszNew ) } }
静态函数CWnd:: GetDesktopWindow 返回桌面窗口的指针。下例说明了MFC函数 CFrameWnd::BeginModalStae是如何使用该函数进入内部窗口列表的。
void CFrameWnd::BeginModalState () { … //first count all windows that need to be disabled UINT nCount=0 HWND hWnd= :: GetWindow (:: GetDesktopWindow(), GW_CHILD) while (hWnd!=NULL) { if (:: IsWindowEnabled (hwnd) && CWnd::FromHandlePermanent (hWnd)!=NULL && AfxIsDescendant (pParent-&m_hWnd, hWnd) && :: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0)==0) { ++nCount } hWnd=:: GetWindow (hWnd, GW_HWNDNEXT) }
当窗口需要确定鼠标位置时Windows向窗口发送WM_NCHITTEST信息,可以处理该 信息使Windows认为鼠标在窗口标题上。对于对话框和基于对话的应用程序,可 以使用ClassWizard处理该信息并调用基类函数, 如果函数返回HTCLIENT 则表 明鼠标在客房区域,返回HTCAPTION表明鼠标在Windows的标题栏中。 UINT CSampleDialog : : OnNcHitTest (Cpoint point ) { UINT nHitTest =Cdialog: : OnNcHitTest (point ) return (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest }
上述技术有两点不利之处, 其一是在窗口的客户区域双击时,窗口将极大; 其二, 它不适合包含几个视窗的主框窗口。 还有一种方法,当用户按下鼠标左键使主框窗口认为鼠标在其窗口标题上,使 用ClassWizard在视窗中处理WM_LBUTTODOWN信息并向主框窗口发送一个WM_NCLBUTTONDOWN 信息和一个单击测试HTCAPTION。 void CSampleView : : OnLButtonDown (UINT nFlags , Cpoint point ) { CView : : OnLButtonDow (nFlags , pont )
//Fool frame window into thinking somene clicked on its caption bar . GetParentFrame ( ) —& PostMessage ( WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARAM (poitn .x , point .y) )
} 该技术也适用于对话框和基于对的应用程序,只是不必调用 CWnd: :GetParentFrame 。 void CSampleDialog : : OnLbuttonDown (UINT nFlags, Cpoint point ) { Cdialog : : OnLButtonDow (nFlags, goint ) //Fool dialog into thinking simeone clicked on its caption bar . PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (point.x , point. y ) ) }
可以使用新的SDK函数SetWindowRgn。该函数将绘画和鼠标消息限定在窗口的一 个指定的区域,实际上使窗口成为指定的不规则形状。 使用AppWizard创建一个 基于对的应用程序并使用资源编辑器从主对话资源中删除所在的缺省控件、标题 以及边界。 给对话类增加一个CRgn数据成员,以后要使用该数据成员建立窗口区域。 Class CRoundDlg : public CDialog { … private : Crgn m_rgn : // window region … } 修改OnInitDialog函数建立一个椭圆区域并调用SetWindowRgn将该区域分配给窗口: BOOL CRoundDlg : : OnInitDialog ( ) { CDialog : : OnInitDialog ( )
//Get size of dialog . CRect rcDialog GetClientRect (rcDialog )
// Create region and assign to window . m_rgn . CreateEllipticRgn (0 , 0 , rcDialog.Width( ) , rcDialog.Height ( ) ) SetWindowRgn (GetSafeHwnd ( ) , (HRGN) m_ rgn ,TRUE )
return TRUE }
通过建立区域和调用SetWindowRgn,已经建立一个不规则形状的窗口,下面的例子 程序是修改OnPaint函数使窗口形状看起来象一个球形体。 voik CRoundDlg : : OnPaint ( ) { CPaintDC de (this) // device context for painting . //draw ellipse with out any border dc. SelecStockObject (NULL_PEN) //get the RGB colour components of the sphere color COLORREF color= RGB( 0 , 0 , 255) BYTE byRed =GetRValue (color) BYTE byGreen = GetGValue (color) BYTE byBlue = GetBValue (color)
// get the size of the view window Crect rect GetClientRect (rect)
// get minimun number of units int nUnits =min (rect.right , rect.bottom )
//calculate he horiaontal and vertical step size float fltStepHorz = (float) rect.right /nUnits float fltStepVert = (float) rect.bottom /nUnits
int nEllipse = nUnits/3 // calculate how many to draw int nIndex // current ellipse that is being draw
CBrush brush // bursh used for ellipse fill color CBrush *pBrushOld // previous brush that was selected into dc //draw ellipse , gradually moving towards upper-right corner for (nIndex = 0 nIndes & + nEllipse nIndes++) { //creat solid brush brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ). ( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue) /nEllipse ) ) )
//select brush into dc pBrushOld= dc .SelectObject (&brhsh)
//draw ellipse dc .Ellipse ( (int) fltStepHorz * 2, (int) fltStepVert * nIndex , rect. right -( (int) fltStepHorz * nIndex )+ 1, rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1)
//delete the brush brush.DelecteObject ( ) } }
最后,处理WM_NCHITTEST消息,使当击打窗口的任何位置时能移动窗口。 UINT CRoundDlg : : OnNchitTest (Cpoint point ) { //Let user move window by clickign anywhere on thewindow . UINT nHitTest = CDialog : : OnNcHitTest (point) rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest
原著:Roger Onslow
本文所讨论的工具栏类是同标准的 MFC CToolBar 一同工作的。
注意:你必须有新的 COMCTL32.DLL (版本4.7或更高)。它是随 Internet Explorer 3 一同发行,并且将做为 Windows 98 的标准组件。如果你使用的是 VC++ 5,则你已经有该 动态库了。
所谓类似 Word 97 的增强工具栏具有平面外观,它的左边带有“gripper”并且各组 间带有分隔线。当鼠标移动到上面时,按钮就会突出来。
MFC 使用样式位来控制其平面外观。所以你不能在建立工具栏时来设置这 种样式,你必须建立之后使用SetFlatLookStyle()函数来修改其样式。
平面外观工具栏是透明绘制的。不幸的是,MFC 没有介绍该如何编写这种透明的工具栏, 所以需要你重绘背景。这要通过变尺寸和移动信息来实现,例如当你拖动可移动的工具栏。 你也可以通过其按钮样式改变时来实现。例如,当按钮从按状态变成释放状态时,背景需要 重新绘制。
工具栏控制本身并不在各组按钮间绘制分隔线,只是在其间增加一个空格。该类将 截取 WM_PAINT 消息,并在正确的位置添加分隔线。
工具栏控制也不支持在起左边或顶部的gripper。该类将调整其用户区并绘制相应 的gripper。
使用本类,只要简单的把你的 CToolBar 变成 CFlatToolBar,并在建立工具栏后 调用 SetFlatLookStyle() 函数 (既当工具栏位图装入之后 )。
// FlatToolBar.h // (c) 1997, Roger Onslow
class CFlatToolBar : public CToolBar { DECLARE_DYNAMIC(CFlatToolBar);
public: void SetFlatLookStyle(); void RepaintBackground(); void DrawSeparators(); void DrawSeparators(CClientDC* pDC); void EraseNonClient(); void DrawGripper(CWindowDC *pDC, CRect& rectWindow);
protected: // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CFlatToolBar) virtual void OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler); //}}AFX_VIRTUAL
// 消息处理函数 protected: //{{AFX_MSG(CFlatToolBar) afx_msg void OnWindowPosChanging(LPWINDOWPOS lpWndPos); afx_msg void OnPaint(); afx_msg void OnNcPaint(); afx_msg void OnNcCalcSize( BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp ); //}}AFX_MSG
DECLARE_MESSAGE_MAP(); }; //*************************************************************** // FlatToolBar.cpp
#include "stdafx.h" #include "flattoolbar.h"
#ifdef _DEBUG #undef THIS_FILE #define new DEBUG_NEW static char BASED_CODE THIS_FILE[] = __FILE__; #endif
BEGIN_MESSAGE_MAP(CFlatToolBar, CToolBar) //{{AFX_MSG_MAP(CFlatToolBar) ON_WM_WINDOWPOSCHANGING() ON_WM_PAINT() ON_WM_NCPAINT() ON_WM_NCCALCSIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP()
IMPLEMENT_DYNAMIC(CFlatToolBar,CToolBar) // 必须在建立之后,因为MFC要清除多余的样式位 void CFlatToolBar::SetFlatLookStyle() { // 设置平面样式(透明的) ModifyStyle(0,TBSTYLE_FLAT);
// others are... // #define TBSTYLE_TOOLTIPS 0x0100 // #define TBSTYLE_WRAPABLE 0x0200 // #define TBSTYLE_ALTDRAG 0x0400 // #define TBSTYLE_FLAT 0x0800 // #define TBSTYLE_LIST 0x1000 } // 因为按钮是透明的,所以我们需要重新绘制背景
void CFlatToolBar::RepaintBackground() { CR GetWindowRect(&rc); // 获取工具栏的矩形区域 CWnd* pParent = GetParent(); // 获取父窗口 pParent-&ScreenToClient(&rc); // 转换为父窗口的坐标 pParent-&InvalidateRect(&rc); // 绘制其下面的矩形 } // 在用户区中绘制分隔线
void CFlatToolBar::DrawSeparators() { CClientDC dc(this); // get a dc for the client area DrawSeparators(&dc); // draw the separators on it } // 绘制分隔线 void CFlatToolBar::DrawSeparators(CClientDC* pDC) { // 水平与垂直 bool ishorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0;
// 获取按钮数目 int nIndexMax = (int)DefWindowProc(TB_BUTTONCOUNT, 0, 0); int nI
// 试一下每个按钮 for (nIndex = 0; nIndex & nIndexM nIndex++) { UINT dwStyle = GetButtonStyle(nIndex); UINT wStyle = LOWORD(dwStyle);
// 如果是分隔线 if (wStyle == TBBS_SEPARATOR) { // 获取它的矩形和宽度 CR GetItemRect(nIndex,rect);
让你的工具栏多姿多彩
  ---- 应用程序的工具栏上除了可以放置图形按钮和一些控件,实现快捷操作外, 我们还可以在其上播放动画,以增加程序动感,并使用户知道程序正在工作。此功能 在VC++可以中通过向工具栏添加播放动画的标准控件-CanimateCtrl来方便的实现这 一效果。本程序允许用户通过"查看/动画"菜单播放与关闭动画。 ---- 开始编制程序之前,应先选择合适的AVI文件,供程序调用。本文使用sample.avi., 放置在c:/temp目录下。
---- AVI文件可以用一些AVI编辑器中自己进行制作,如Adobe Premiere 5.1, Corel Photo-Paint 8等,也可以使用现有AVI资源,制作和选择时,应考虑到工具栏 大小适合播放视频图象较小的动画(本文选取的AVI文件中图象大小为 27 x 14 象素, Pixel depth是4位。
程序具体实现步骤如下:
---- 1. 创建工程
---- 用MFC AppWizard(exe)创建一个新工程AnimateToolbar,在MFC AppWizard-Step 1 对话框选中"Single Document"选项后,单击Finish按钮,在接着弹出的对话框中单击OK按 钮,工程创建完毕。
---- 2. 创建菜单资源
---- 在菜单"查看中添加"动画(A )"菜单项,并设置其标识号为ID_VIEW_ANIMATE, 状态栏提示(Prompt)设为"播放/停止动画"。
---- 3. 添加工具栏上按纽位图资源。
---- 在位图资源上添加一个新的按纽,标识号设为ID_ANIMATE。
---- 4. 往工具栏中添加一个CanimateCtrl控件,并播放动画。
---- (1) 在CmainFrame类中声明下面的成员变量:
class CMainFrame : public CFrameWnd { … public: BOOL IsAnimationA//是否播放动画标识 CAnimateCtrl m_A … }
---- (2)在CmainFrame类构造函数中初始化IsAnimationActive变量: CMainFrame::CMainFrame() { // TODO: add member initialization code here IsAnimationActive=TRUE; }
---- (3)在CMainFrame::OnCreate函数中创建CAnimateCtrl控件 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { … CR m_wndToolBar.SetButtonInfo (12,ID_VIEW_ANIMATE, TBBS_SEPARATOR,40); m_wndToolBar.GetItemRect (12,&rect); DWORD dwStyle = WS_CHILD|WS_VISIBLE|ACS_AUTOPLAY| ACS_TRANSPARENT|ACS_CENTER; if (!m_Animate.Create( dwStyle, rect, &m_wndToolBar, 0 )) return FALSE; … }
---- (4) 使用ClassWizard处理菜单项"查看/动画"标识号ID为(ID_VIEW_ANIMATE) 的COMMAND和UPDATE_COMMAND_UI消息,并增加下述代码。该段代码根据可以让用户在播 放动画与关闭动画之间进行切换。 void CMainFrame::OnViewAnimate() { // TODO: Add your command handler code here if(IsAnimationActive){ m_Animate.Open("c://temp//sample.avi"); IsAnimationActive=FALSE;
} else{ m_Animate.Stop(); m_Animate.Close(); IsAnimationActive=TRUE; } }
void CMainFrame::OnUpdateViewAnimate(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here pCmdUI-&SetCheck(!IsAnimationActive? 1 : 0); }
---- 本程序在Visual C++ 6.0,Windows 98环境下调试通过。
一、给文档/视图应用程序做启动画面 (一) 建立一个单文档/视图应用程序Hs 从File菜单选择New对话,在Projects选项卡中选择AppWizard(ex e)图标。键入Hs 作为项目名并单击OK。在第一步中选中Single Docum ent单选按钮,其它接受所有默认选项。 (二) 添加启动画面 当AppWizard完成,而且Visual C++打开项目的时候,从Project菜单中选择 Add To P roject,并单击位于次级菜单上的Components and Controls...,选 择Splash screen组件,如图1所示,单击Insert。接受所有的默认设置。 图1 以上几步就建立起了一个有主框架结构的应用程序,并使它具有了启动画面。 二、给基于对话框的应用程序做启动画面 (一)建立基于对话框的应用程序Spla 从File菜单选择New对话,在Projects选项卡中选择AppWizard(ex e)图标。键入Spla 作为项目名并单击OK。在第一步中选中Dialog B ased单选按钮,其它接受所有默认选项。 (二)做启动画面 这里做启动画面如果仍采用前述用Gallery来插入是不行的,因为基于对话框的应用 程序没有主框架。不过我们可以把上面建立起的启动画面文件移植过来,然后,对程 序进行少许编程修改就行。请按照下面的步骤来做: 1. 将Splash.cpp和Splash.h两个文件从Hs工程中拷贝到你的工程中。添加如下代 码到CSplaApp的InitInstance()函数中。
#include "Splash.h"//头文件请放在开始位置 BOOL CSplaApp::InitInstance() { CCommandLineInfo cmdI ParseCommandLine(cmdInfo); CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash); ... }
2. 接下来,使用ClassWizard来添加OnCreate函数到你的对话框类中,并且添加如下代码: #include "Splash.h"//头文件请放在开始位置 int CSplaDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... CSplashWnd::ShowSplashScreen(this); ... }
3. 将Splash16.bmp文件从Hs工程中拷贝到你的工程中。打开Wor kspace的Resouce项, 将Splash16.bmp插入。打开Properties将IDB_BI TMAP1改为IDB_SPLASH,这个ID值只要 和程序中一致起来就行,现在这样改最简便。 现在可以编译运行程序了,程序运行时出现如图2的启动画面。图 2 这是默认的画面,你可以打开图形编辑器自己加工。如果你要改变启动画面的停留时间, 就修改SetTime中的第二个参数,这里是750毫秒。
int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... // Set a timer to destroy the splash screen. SetTimer(1, 750, NULL); return 0; } 本程序在VC6.0下通过。
&&&&推荐文章:
【上篇】【下篇】}

我要回帖

更多关于 t文件如何转换dwg文件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信