用Win32實現帶分割條(Splitter)的視窗
阿新 • • 發佈:2019-02-04
在MFC中藉助嚮導的幫助很容易就能建立一個帶有分隔條(Splitter)的視窗,但是在Win32中一切都沒有那麼容易,在這篇文章裡我帶領大家用Win32實現一個帶這種Splitter的視窗。
一個Splitter分隔條,能夠將一個視窗分成兩部分,在我們實際的編碼專案中,這分開的兩個視窗能實現各自的功能。但是這個Splitter又是什麼呢? 告訴大家,這個Splitter其實僅僅是兩個分開的視窗的sunken edge。
首先我們在當前視窗下建立兩個子視窗,分別是Edit和Static,這都是Win32內建的子視窗控制元件。這裡要說明一下的是,下面的程式碼中我使用了自己寫就的一個視窗類,一些訊息響應我用這個視窗類的虛擬函式實現了,為了完整起見,我在這裡將整個函式體都列了出來。我的函式命名和引數列表都是參考MFC的,如果對Windows訊息到虛擬函式的對映不是特別明白,可以參考一下MSDN。
{
m_hEdit = CreateWindowEx( WS_EX_CLIENTEDGE,
_T("Edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | ES_MULTILINE,
0, 0, 0, 0,
hwnd, NULL,
pCST->hInstance, NULL );
chlASSERT(m_hEdit);
m_hLabel =
_T("Static"), NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
0, 0, 0, 0,
hwnd, NULL,
pCST->hInstance, NULL );
chlASSERT(m_hLabel);
RECT rc;
GetClientRect(hwnd,&rc);
m_splitterPos = rc.right / 2;
m_hCursor =
}
要說明的是:m_splitterPos是分隔條在水平方向的位置。Edit和Static視窗建立時的大小都是0,因此我們需要在WM_SIZE訊息中讓他們調整到合適的大小。
void KWindow::OnSize(UINT nType, int cx, int cy){
MoveWindow(m_hEdit,0,0,m_splitterPos,cy,true);
MoveWindow(m_hLabel,m_splitterPos,0,cx - m_splitterPos,cy,true);
}
此外我們還需要讓Edit和Static各自顯示一些文字。
void KWindow::OnDraw(HDC hdc){
SetWindowText(m_hLabel,_T("這是一個Static控制元件"));
SetWindowText(m_hEdit,_T("這是一個Edit控制元件"));
}
現在執行一下,分隔條是能看見了:
下面要做的是當滑鼠移到分隔條周圍時,能夠調整分隔條的位置,兩個子視窗的大小也隨之更改。首先我們在WM_LBUTTONDOWN訊息內設定一個標記,表示現在可以調整大小,並設定滑鼠的形狀。在WM_LBUTTONUP訊息內,調整Splitter位置的工作已經結束,因此將標記設定為不允許調整大小,並將滑鼠形狀設定為正常情況。而在WM_MOUSEMOVE訊息內,我們可以設定Splitter的位置。
void KWindow::OnMouseMove(UINT nFlags,POINT pos){
if(nFlags == MK_LBUTTON && m_IsSplit)
{
RECT rc;
GetClientRect(m_hwnd,&rc);
m_splitterPos = pos.x;
SendMessage(m_hwnd,WM_SIZE,NULL,MAKELPARAM(rc.right,rc.bottom));
}
}
void KWindow::OnLButtonDown(UINT nFlags, POINT pos)
{
if( (pos.x >= m_splitterPos - 10) && ( pos.x <= m_splitterPos + 10) )
{
m_IsSplit = true;
SetCursor(m_hCursor);
SetCapture(this->m_hwnd);
}
}
void KWindow::OnLButtonUp(UINT nFlags, POINT pos)
{
if(m_IsSplit)
{
m_IsSplit = false;
ReleaseCapture();
}
}