更改窗口樣式
一,工具欄
可以如下重載函數:
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);