配色: 字号:
滚动条自显
2012-03-29 | 阅:  转:  |  分享 
  
参考http://www.codeguru.com/cpp/controls/editctrl/article.php/c3917/Multiline-Edit-Box-with-Automatic-Scroll-Bar-Display.htm



TheProblem

IfyouneedamultilineEditControl,youcanimplementoneatdesigntimebyusingtheResourceEditorandsettingthestylesMultiline,Horizontalscroll,AutoHScroll,Verticalscroll,andAutoVScrollfromtheStylesTabinEditProperties.Or,ifyoucreatetheEditControlfromcodeatruntime,youneedtosetthestylesWS_HSCROLL,WS_VSCROLL,ES_MULTILINE,ES_AUTOHSCROLL,andES_AUTOVSCROLL.Fordisplayingmultiplelines,youneedtoenterCtrl+RETURNinteractivelyfromthekeyboardduringprogramexecution,orfromthecodeyouneedtoseparatethelineswiththesequence"\r\n",forexample:



m_oEdit.SetWindowText(_T("FirstLine\r\nSecondLine\r\n...\r\n"));

Theproblemwiththeseapproachesisthatthescrollbarsarevisibleevenwhentheyarenotneeded;forexample,whentheEditBoxisemptyorwhenthetextisveryshort.ThisproblemissolvedbytheCScrollEditclasspresentedinthisarticle.



TheSolution

TheCScrollEditclassisderivedfromtheCEditMFCclass.Asexplainedbefore,thestylesWS_HSCROLL,WS_VSCROLL,ES_MULTILINE,ES_AUTOHSCROLL,andES_AUTOVSCROLLhavetobesetforproperfunctioningoftheEditControl.Whenthescrollbarsarenotneededfordisplay,theycanbehiddenbycallingthefunctionShowScrollBar():



ShowScrollBar(SB_HORZ,FALSE);

ShowScrollBar(SB_VERT,FALSE);

Theproblemishowtodetectwhenthescrollbarsareneededandwhentheyarenotneeded.ThisisdonebythefunctionCheckScrolling(),whichisthecoreoftheCScrollEditclass:



voidCScrollEdit::CheckScrolling(LPCTSTRlpszString)

{

CRectoRect;

GetClientRect(&oRect);

CClientDCoDC(this);

intiHeight=0;

BOOLbHoriz=FALSE;

CFontpEdtFont=GetFont();

if(pEdtFont!=NULL)

{

//DetermineTextWidthandHeight

SIZEoSize;

CFontpOldFont=oDC.SelectObject(pEdtFont);

//DeterminethelineHeight

oSize=oDC.GetTextExtent(CString(_T("")));

iHeight=oSize.cy;

//TextWidth

intiWidth=0,i=0;

CStringoStr;

//Parsethestring;thelinesinamultilineEditare

//separatedby"\r\n"

while(TRUE==::AfxExtractSubString(oStr,lpszString,

i,_T(''\n'')))

{

if(FALSE==bHoriz)

{

intiLen=oStr.GetLength()-1;

if(iLen>=0)

{

//Eliminatelast''\r''

if(_T(''\r'')==oStr.GetAt(iLen))

oStr=oStr.Left(iLen);

oSize=oDC.GetTextExtent(oStr);

if(iWidth
iWidth=oSize.cx;

if(iWidth>=oRect.Width())

bHoriz=TRUE;

}

}

i++;

}

oDC.SelectObject(pOldFont);

//TextHeight

iHeight=i;

}

ShowHorizScrollBar(bHoriz);

ShowVertScrollBar(iHeight>=oRect.Height());

}

TheideainthisfunctionistoparsetheEditControl''stextandextractthelines(whichareseparatedinthetextbythesequence"\r\n").ThenforgettingthesizeofeachlinetheGetTextExtent()functionisused.Theheightofthetextisdeterminedbymultiplyingtheheightofalinewiththenumberoflines.IftheheightofthetextisgreaterorequalthantheheightoftheEditControl''sclientrectanglethentheverticalscrollbarhastobedisplayed,otherwiseisnotdisplayed.FordisplayingthehorizontalscrollbaritisenoughtodetectjustonelinewiththewidthgreaterthanorequaltothewidthoftheEditControl''sclientrectangle.



ThefunctionCheckScrolling()iscalledfromtwoplaces:



FromthefunctionSetWindowText(),whichisoverloadingtheCWnd::SetWindowText()function:

voidCScrollEdit::SetWindowText(LPCTSTRlpszString)

{

CheckScrolling(lpszString);

CEdit::SetWindowText(lpszString);

}

FromthehandlerOnCheckText()whichistreatingthespecialusermessageUWM_CHECKTEXT:

LRESULTCScrollEdit::OnCheckText(WPARAMwParam,LPARAM

lParam)

{

CStringoStr;

GetWindowText(oStr);

CheckScrolling(oStr);

return0;

}

ThemessageUWM_CHECKTEXTispostedfromtheOnChar()handler(thehandlerfortheWM_CHARmessage)eachtimetheuseriseditinginsidetheEditControl:



voidCScrollEdit::OnChar(UINTnChar,UINTnRepCnt,

UINTnFlags)

{

//PossibleTextChange

PostMessage(UWM_CHECKTEXT);

CEdit::OnChar(nChar,nRepCnt,nFlags);

}

//////////////////////////////

HowtoUsetheCode

UsingtheCScrollEditclassisveryeasy,anditisdemonstratedbytheaccompanyingdemoproject.Youneedtoincludethesourcefiles//ScrollEdit.handScrollEdit.cpp//inyourproject.InScrollEdit.cpp,changetheline



#include"ScrollEditTst.h"

totheappropriate#includeforyourapplication''sheaderfile.Then,declarethecontrolmembervariableintheappropriateheaderfile:



#include"ScrollEdit.h"

//...

CScrollEditm_oScrollEdit;

anddosubclassingintheappropriateplace;forexample,intheOnInitDialog()handler:



m_oScrollEdit.SubclassDlgItem(IDC_EDIT1,this);

m_oScrollEdit.SetWindowText(_T(""));

Theinitializationwithtext_T("")isnecessaryfortheproperinitializationofthescrollbar''sdisplay(inthiscase,theyarenotdisplayedinitially).

///////////////////////////////
献花(0)
+1
(本文系逸书1997首藏)