DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

1.工具条和状态条中控件的添加:

方法⑴.只能在ToolBar里创建控件:首先,在ToolBar中创建一个Button,其ID为ID_TOOL_COMBO(我们要将创建的控件放在该Button的位置上).

其次,新创建一个类CMainToolBar,要从CToolBar继承(创建过程大概如下:选择工程/增加到工程/新的类;也可以选择工程的根,然后点击右键,选择新的类;或者CTL+W,选择增加类/新的类 --- 然后在class type里选择Generic Class,在Name栏里输入新类的名字,Base class里输入CToolBar[u1]),创建成功后在该类里创建要增加的控件的对象,如:

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文件的OnCreate函数的最后实现如下:

       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::OnViewStatusBar();

接着在.cpp文件中将StatusBar的ID和OnViewStatusBar 函数绑定在一起,如下所示:BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

           //  {{AFX_MSG_MAP(CMainFrame)

           ON_COMMAND(ID_VIEW_STATUS_BAR, OnViewStatusBar)

        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_wndStatusBar.SetWindowPos(NULL,rc.left,rc.top,rc.Width(),rc.Height(),

SWP_NOZORDER);

       }

最后在OnViewStatusBar()里实现:

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中的创建与此相同,只需更改一下句柄即可

 

2.使工具条上的按钮点击一次为按下,再点击才弹起

bCheck=m_RtfEditToolBar.GetToolBarCtrl().IsButtonChecked(ID_TB_BOLD);

m_RtfEditToolBar.GetToolBarCtrl().CheckButton(ID_TB_BOLD, !bCheck);

 

3.如何隐藏工具栏

添加如下两个函数
隐藏:
void CMainFrame::OnHide() 
{
    if(m_wndToolBar.IsWindowVisible())
        m_wndToolBar.ModifyStyle(WS_VISIBLE,0);
    SendMessage(WM_SIZE);
}

显示:
void CMainFrame::OnShow() 
{
    if(!m_wndToolBar.IsWindowVisible())
        m_wndToolBar.ModifyStyle(0,WS_VISIBLE);
    SendMessage(WM_SIZE);
}

 

4.如何动态获取工具条指针并给工具条加标题?

[问题提出]

工具条也是窗口,是窗口就有标题,如何给工具条加标题?
[程序实现]
不想动态改变工具条的标题就在CMainFrame::OnCreate()中:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 ......
 m_wndToolBar.SetWindowText(_T("Standdard"));

 return 0;
 }
 若想动态改变工具条的标题,如下:
 声明一个菜单,并响应事件,如响应:OnMyToolBar()函数

 void CMainFrame::OnMyToolBar() 
 {
 // TODO: Add your command handler code here
CToolBar *pToolBar = (CToolBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR); 
pToolBar->SetWindowText (_T("Standdard"));
}
不要在TooBar悬浮时做OnMyToolBar()会出错的. 
顺便提一下如何获得状态条的指针:
CStatusBar * pStatusBar =(CStatusBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);

 

5.在状态条中显示鼠标的设备坐标与逻辑坐标

显示器的设备坐标系的原点在客户区的左上角,x轴向右增长,y轴向下增长。我们要设置的逻辑坐标系的原点则在客户区的中心,x轴向右增长,y轴向上增长,如一个笛卡尔坐标系一般。

为CChildView添加一个成员函数void OnPrepareDC(CDC * pDC, CPrintInfo * pInfo = NULL);

void OnPrepareDC(CDC * pDC, CPrintInfo * pInfo){
  CRect rect;

  // 设置映射模式为LOMETRIC (0.1mm),右上为增长方向
  pDC->SetMapMode (MM_LOMETRIC);

  // 将坐标原点定在客户区的中心
  GetClientRect(rect);
  pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);
}
为CChildView响应鼠标移动消息,并在状态条中显示鼠标的坐标值。m_ptMouse数据成员是原打算做十字交叉线用的,在此使用没有实际意义。

void CChildView::OnMouseMove(UINT nFlags, CPoint point){
  CClientDC dc(this);
  CString str;
  
  OnPrepareDC(&dc);

  //要访问类CMainFrame,需要将mainfrm.h文件引入
  CMainFrame * pFrame = (CMainFrame *) AfxGetApp()->m_pMainWnd;

  //要访问CMainFrame的数据成员m_wndStatusBar,需要手工修改mainfrm.h,public这个数据成员
  CStatusBar * pStatus = (CStatusBar *) &pFrame->m_wndStatusBar;
  
  m_ptMouse = point;
  str.Format ("设备坐标 X=%i pixel, Y=%i pixel", m_ptMouse.x, m_ptMouse.y);
  pStatus->SetPaneText(1, str);
  
  dc.DPtoLP(&m_ptMouse);
  str.Format ("逻辑坐标 X=%i * 0.1mm, Y=%i * 0.1mm", m_ptMouse.x, m_ptMouse.y);
  pStatus->SetPaneText(2, str);
}

 

6.如何更新状态条上的现实内容

By default, a CStatusBar pane is not enabled when the pane is created. To activate a pane, you must call the ON_UPDATE_COMMAND_UI() macro for each pane on the status bar and update the panes. Because panes do not send WM_COMMAND messages, you cannot use ClassWizard to activate panes; you must type the code manually. For example, suppose one pane has ID_INDICATOR_PAGE as its identifier and that it contains the current page number in a document. To make the ID_INDICATOR_PAGE pane display text, add the following to a header file (probably the MAINFRM.H file):

afx_msg void OnUpdatePage(CCmdUI *pCmdUI);

Add the following to the application message map:

ON_UPDATE_COMMAND_UI(ID_INDICATOR_PAGE, OnUpdatePage)

Add the following to a source code file (probably MAINFRM.CPP):

void CMainFrame::OnUpdatePage(CCmdUI *pCmdUI)
{
    pCmdUI->Enable();
}

To display text in the panes, either call SetPaneText() or call CCmdUI::SetText() in the OnUpdate() function. For example, you might want to set up an integer variable m_nPage that contains the current page number. Then, the OnUpdatePage() function might read as follows:

void CMainFrame::OnUpdatePage(CCmdUI *pCmdUI)
{
    pCmdUI->Enable();
    char szPage[16];
    wsprintf((LPSTR)szPage, "Page %d", m_nPage);
    pCmdUI->SetText((LPSTR)szPage);
}

This technique causes the page number to appear in the pane during idle processing in the same manner that the application updates other indicators.

posted on   DoubleLi  阅读(521)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2013-05-01 C++标准库和标准模板库
2013-05-01 C++拷贝构造函数(深拷贝,浅拷贝)
2013-05-01 关于函数返回值的几种情况
点击右上角即可分享
微信分享提示