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); 

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