TOOLBAR and ProgressCtrl

更改窗口样式

一,工具栏
可以如下重载函数:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    // Create a window without min/max buttons or sizable border
    cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER;

    // Size the window to 1/3 screen size and center it
    cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3;
    cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3;
    cs.y = ((cs.cy * 3) - cs.cy) / 2;
    cs.x = ((cs.cx * 3) - cs.cx) / 2;

    // Call the base-class version
    return CFrameWnd::PreCreateWindow(cs);
}

如何更改文档标题:
必须在默认的样式里先去掉FWS_ADDTOTITLE样式,
在单文档应用程序中,默认的样式是:WS_OVERLAPPEDWINDOW and FWS_ADDTOTITLE styles的联合
FWS_ADDTOTITLE 是通知框架将文档的标题赋给窗口的标题
如下: cs.style&=~FWS_ADDTOTITLE ;
 cs.lpszName="ok文档";
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU|WS_THICKFRAME| WS_MINIMIZEBOX   | WS_MAXIMIZEBOX)
WS_OVERLAPPED:产生一个层叠的窗口,一个层叠的窗口有一个标题栏和一个边框。

WS_CAPTION:创建一个有标题栏的窗口。

WS_SYSMENU:创建一个在标题栏上带有系统菜单的窗口,要和WS_CAPTION类型一起使用。

WS_THICKFRAME:创建一个具有可调边框的窗口。

WS_MINIMIZEBOX:创建一个具有最小化按钮的窗口,必须同时设定WS_ SYSMENU类型。

WS_MAXIMIZEBOX:创建一个具有最大化按钮的窗口,必须同时设定WS_ SYSMENU类型。

 

如何设定或者获取窗口信息

SetWindowLong/GetWindowLong
在FRAME类中的OnCreate函数里添加
 SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW&~WS_MAXIMIZEBOX );

全局函数AfxGetInstanceHandle()获取当前实例句柄,MAKEINTSOURSE()是一个宏,用来把一个资源ID号转换为资源管理函数兼容的值,返回的是LPTSTR类型。
  m_hIcons[1]=LoadIcon(AfxGetInstanceHandle(),MAKEINTSOURSE(IDC_ICON2));

virtual LRESULT DefWindowProc( UINT message, WPARAM wParam, LPARAM lParam );---在CWND类的
LRESULT DefWindowProc(-------全局的API
  HWND hWnd,      // handle to window
  UINT Msg,       // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);

如何修改鼠标样式,或者背景什么的?
 
在框架类里修改光标或者背景是毫无意义的,但是可以更改图标
1.以下是放在CMainFrame::PreCreateWindow函数里
WNDCLASS wcs;
 wcs.cbClsExtra=0;
wcs.cbWndExtra=0;
wcs.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wcs.hIcon=LoadIcon(NULL,IDI_ERROR);
wcs.hCursor =LoadCursor(NULL,IDC_HELP);
wcs.hInstance=AfxGetInstanceHandle();
wcs.lpfnWndProc=::DefWindowProc  ;
wcs.lpszClassName="wbs";
wcs.lpszMenuName=NULL;//不会影响框架的菜单
wcs.style=CS_HREDRAW|CS_VREDRAW;//是窗口类的样式和框架的样式没关系


RegisterClass(&wcs);//注册窗口类
 

cs.lpszClass="wbs";//在样式里添加此类的名称-----------这一句就必须放在CView::PreCreateWindow

2.
LPCTSTR AFXAPI AfxRegisterWndClass( UINT nClassStyle, HCURSOR hCursor = 0, HBRUSH hbrBackground = 0, HICON hIcon = 0 );
AfxRegisterWndClass函数将返回一个已经注册过的窗口类
在CFrame类里添加如下语句
cs.lpszClass= AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));

在CView类里添加
 cs.lpszClass= AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,0,NULL,0);修改图标或者背景灯

 

如何在已创建窗口后,修改窗口样式
SetClassLong/GetClassLong
用法和SetWindowLong/GetWindowLong类似

如何获得当前实例号

1.在CApp类中有一个全局变量
CMyStyleApp theApp; 当需要在view中调用的时候,,必须添加如下代码
extern CMyStyleApp theApp;--声明一个变量
从而调用其内部的局部变量实例号m_hInstance,

2.CWinApp* AfxGetApp( );
::AfxGetApp()->m_hInstance

3.AfxGetInstanceHandle()


如何使一个值保持在某个范围内?
int index=0;
index=++index%3;----数据保持在3的范围以内

如何将局部变量放在数据区中,而不是堆栈中,从而保持数据的生命周期有效?
在函数里:
 static int index=0;

 

如何创建一个TOOLBAR?
void CControlBar::EnableDocking( DWORD dwStyle ); ----验证工具栏是否停靠在客户区哪里
void CFrameWnd::EnableDocking( DWORD dwStyle ); ----验证框架是否停靠在客户区哪里
CFrameWnd::DockControlBar
void DockControlBar( CControlBar * pBar, UINT nDockBarID = 0, LPCRECT lpRect = NULL );-----将控件停靠在工具栏上
CFrameWnd::RecalcLayout();  -----将Toolbar、DialogBar等可浮动的东西安排位置、处理和View、Frame之间的位置关系的
virtual void RecalcLayout( BOOL bNotify = TRUE );

如何隐藏工具栏?
1.  if(m_newToolBar.IsWindowVisible())
 {
  m_newToolBar.ShowWindow(SW_HIDE);
 }
 else
 {
  m_newToolBar.ShowWindow(SW_SHOW);
 }
 
 RecalcLayout();
 DockControlBar(&m_newToolBar);

2.
CFrameWnd::ShowControlBar
void ShowControlBar( CControlBar* pBar, BOOL bShow, BOOL bDelay );---bShow 为false工具栏将不显示,bDelay false 立马显示 true 工具栏将淡淡显示

ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);


如何将菜单项选中?
在菜单项的UPDATE_COMMAND_UI事件中添加
pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());即可

 

二.进度条

如何在进度条中动态显示系统时间
在CFrame类中找到
static UINT indicators[] =
{
 ID_SEPARATOR,           // status line indicator
 IDS_TIMER,
 IDS_PROGRESS,
 ID_INDICATOR_CAPS,
 ID_INDICATOR_NUM,
 ID_INDICATOR_SCRL,
};并添加你在STRING table表里添加的ID

在CFrame类OnCreate方法里
        CTime t=CTime::GetCurrentTime();--获取系统时间
 CString str=t.Format("%H:%M:%S");
 CClientDC dc(this);
 CSize sz=dc.GetTextExtent(str);---获得文字宽高等信息
 int index=0;
 index=m_wndStatusBar.CommandToIndex(IDS_TIMER);---根据在STRING table表里添加的ID来获取再进度条中的index
 m_wndStatusBar.SetPaneInfo(index,IDS_TIMER,SBPS_NORMAL,sz.cx);--设置需要显示的进度条适当的宽度
 m_wndStatusBar.SetPaneText(index,str);---给设置项设置需要显示的文字

当然需要动态显示实时时间,,必须要设置定时器 SetTimer(1,1000,NULL);
截取ONtime事件后,再调用以上的代码即可

 

如何自定制事件?
在CFrame头文件中添加
#define UM_PROGRESS  WM_USER+1   ----WM_USER以下的都是系统自留的,不可占用
 也同样添加引发的事件。
 afx_msg void OnProgress();

在CFeame的CPP中,找到关系映射,添加如下代码
 ON_MESSAGE(UM_PROGRESS,OnProgress)

在别处调用可以如此
 SendMessage(UM_PROGRESS);
  PostMessage(UM_PROGRESS);
当然两者的区别是什么呢?
      PostMessage是将消息加入到消息队列中,当系统信息一条一条处理完成后,才执行到如此
     而当SendMessage放在程序里是立即执行的


如何将CProgess放入进度条?
在ONPAINT函数中
 CPaintDC dc(this); 
 m_wndStatusBar.GetItemRect(2,&rect);
 if(!m_progress.m_hWnd)---判断是否创建过进度条
  m_progress.Create(WS_CHILD | WS_VISIBLE ,//| PBS_SMOOTH,
   rect,&m_wndStatusBar,123);
 else
  m_progress.MoveWindow(rect);---如果创建,直接移动窗口位置即可
 m_progress.SetPos(50); 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章