这两天弄个简单的s60列表框。没想到出现以下的意外:
第一个图正常显示,第二个图,按下down键后,焦点下移,但是前一个列表项仍高光。
第三个。列表项滚动发生覆盖。
原因查出来了:
就是它:
BaseConstructL(EAknEnableSkin);
采用的是“基于控件的传统的symbianOS 架构。”
说白了,就是给控件找个容器装起来。容器在UI里建立。
上代码吧:
//ebooks.h
/*
* ListBox.h
*
* Created on: 2012-10-9
* Author: Administrator
*/
#ifndef LISTBOX_H_
#define LISTBOX_H_
#include <akniconarray.h> // CAknIcon
#include <aknlists.h> // CAknSingleStyleListBox
#include <barsread.h> // TResource Reader
#include <e32def.h> // STATIC_CAST
#include <eikclbd.h> // CColumnListBoxData
#include <eikmenub.h> // CEikMenuBar
#include <DynamicList.mbg> // icons
#include <ebooks_0xE4700052.rsg> // R_DYNAMICLIST_SAVED_GAMES_LISTBOX
#include <stringloader.h> // StringLoader
#include <uikon.hrh> // TKeyCode #defines
#include <badesca.h> // CDesCArray
#include <coecntrl.h> // CCoeControl
#include <eiklbo.h> // MEikListBoxObserver
#include <UTF.H>
#include<EscapeUtils.h>
#include <charconv.h>
#include <aknlists.h>
#include <aknview.h>
class CAknColumnListBox;
class ListBox: public CCoeControl, MEikListBoxObserver
{
public:
virtual ~ListBox();
static ListBox* NewL(const TRect& aRect);
static ListBox* NewLC(const TRect& aRect);
private:
void ConstructL(const TRect& aRect);
void HandleListBoxEventL(CEikListBox* aListBox, TListBoxEvent aListBoxEvent);
void AddInfoToList(TInt aIndex, const TDesC& aText);
private: // from CoeControl
void SizeChanged();
TInt CountComponentControls() const;
CCoeControl* ComponentControl(TInt aIndex) const;
void Draw(const TRect& aRect) const;
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
private:
//CAknSingleStyleListBox* iListBox;
CEikColumnListBox* iListBox;
CDesCArrayFlat* iArray;
};
#endif /* LISTBOX_H_ */
//ebooks.cpp
/*
* ListBox.cpp
*
* Created on: 2012-10-9
* Author: Administrator
*/
#include "ListBox.h"
#include <akniconarray.h> // CAknIcon
#include <aknlists.h> // CAknSingleStyleListBox
#include <barsread.h> // TResource Reader
#include <e32def.h> // STATIC_CAST
#include <eikclbd.h> // CColumnListBoxData
#include <eikmenub.h> // CEikMenuBar
#include <ebooks_0xE4700052.rsg> // R_DYNAMICLIST_SAVED_GAMES_LISTBOX
#include <stringloader.h> // StringLoader
#include <uikon.hrh> // TKeyCode #defines
#define KListPosition TPoint(0,0)
ListBox::~ListBox()
{
// TODO Auto-generated destructor stub
delete iListBox;
delete iArray;
}
void ListBox::ConstructL(const TRect& aRect)
{
// CreateWindowL();
// CreateWindowL();
//add your code here ...
//construct a listbox
/* iListBox = new(ELeave) CAknSingleStyleListBox;
iListBox->SetContainerWindowL( *this);
iListBox->SetListBoxObserver(this);
iListBox->ConstructL(this,EAknListBoxSelectionList|EAknListBoxLoopScrolling);
iListBox->CreateScrollBarFrameL(ETrue);
iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOn,CEikScrollBarFrame::EOn);
iListBox->ItemDrawer()->ColumnData()->EnableMarqueeL(ETrue);
iListBox->Model()->SetOwnershipType( ELbmOwnsItemArray );
iListBox->ActivateL();
CDesCArray* items = static_cast<CDesCArray*>(iListBox->Model()->ItemTextArray());
//以下是要具体显示在界面上的内容,根据你的需要可以进行修改,如从FS中读出某个文件夹下的文件列表
items->AppendL(_L("\tData Structure"));
items->AppendL(_L("\tBusiness English"));
items->AppendL(_L("\tWeb Programming"));
items->AppendL(_L("\tComputer Networks"));
iListBox->HandleItemAdditionL();
iListBox->SetCurrentItemIndex(0);
iListBox->DrawNow(); */
CreateWindowL();
iListBox = new(ELeave) CAknSingleNumberStyleListBox();
CleanupStack::PushL(iListBox);
iListBox->ConstructL(this, EAknListBoxMarkableList | EAknListBoxMultiselectionList);
iListBox->SetContainerWindowL(*this);
iListBox->SetRect(aRect);
iListBox->CreateScrollBarFrameL(ETrue); iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOn,CEikScrollBarFrame::EAuto);
iArray = new (ELeave) CDesCArrayFlat(10);
CleanupStack::PushL(iArray);
CTextListBoxModel* model = iListBox->Model();
model->SetItemTextArray( iArray );
model->SetOwnershipType(ELbmDoesNotOwnItemArray);
CleanupStack::Pop(2); // !!! (2);
TBuf<32> strDate;
strDate.Append(_L("hello list"));
TInt zero=0;
TInt one=1;
AddInfoToList(zero, strDate);
AddInfoToList(one, strDate);
AddInfoToList(2, strDate);
AddInfoToList(3, strDate);
AddInfoToList(4, strDate);
AddInfoToList(5, strDate);
AddInfoToList(6, strDate);
AddInfoToList(7, strDate);
AddInfoToList(8, strDate);
AddInfoToList(9, strDate);
AddInfoToList(10, strDate);
iListBox->ActivateL();
// m_pListBox->MakeVisible(ETrue);
iListBox->SetFocus( ETrue );
// m_pListBox->DrawNow();
//End Single ListBox
SetRect(aRect);
ActivateL();
}
ListBox* ListBox::NewL(const TRect& aRect)
{
ListBox* self = ListBox::NewLC(aRect);
CleanupStack::Pop(self);
return self;
}
ListBox* ListBox::NewLC(const TRect& aRect)
{
ListBox* self = new (ELeave) ListBox;
CleanupStack::PushL(self);
self->ConstructL(aRect);
return self;
}
/**
*
* Called by framework when the view size is changed. Resizes the
* iLabel accordingly.
*
*/
void ListBox::SizeChanged()
{
//iListBox->SetExtent (KListPosition, iListBox->MinimumSize());
//iListBox->SetExtent(TPoint(20,20),TSize(200,300));
// DrawNow();
if (iListBox)
{
iListBox->SetRect(Rect());
// iItemList->ListBox()->SetRect(Rect());
}
}
/**
* Called by the framework in compound controls
* @return The number of controls in this CDynamicListContainer
*/
TInt ListBox::CountComponentControls() const
{
return 1; // return number of controls inside this container
}
/**
* Called by the framework in compound controls
* @param The index of the control to return
* @return The control for aIndex
*/
CCoeControl* ListBox::ComponentControl(TInt aIndex) const
{
switch (aIndex)
{
case 0:
return iListBox;
default:
return NULL;
}
}
/**
* Called by the framework to draw this control. Clears the area in
* aRect.
* @param aRect in which to draw
*/
void ListBox::Draw(const TRect& aRect) const
{
//CWindowGc& gc = SystemGc();
//gc.Clear(aRect);
CWindowGc& gc = SystemGc();
// Gets the control's extent
TRect rect = Rect();
// Clears the screen
gc.Clear(rect);
}
void ListBox::HandleListBoxEventL(CEikListBox* /*aListBox*/, TListBoxEvent aListBoxEvent)
{
// if the Select Key has been pressed
if ((aListBoxEvent == MEikListBoxObserver::EEventEnterKeyPressed) ||
(aListBoxEvent == MEikListBoxObserver::EEventItemClicked))
{
//PlaySelectedGame();
/*TBuf<256> aResult;
TBuf<256> afterResult;
//iListBox=iPalmLawListBoxRuleDir->ListBox();
TInt index =iSavedGamesListBox->CurrentItemIndex(); // 获得当前列表项index
// 取得列表项的值
GetSelectedItemsLC(iSavedGamesListBox,aResult, index);
aResult.TrimLeft(); // 去左空格
//afterResult.Copy(aResult.Mid(2));
//afterResult.Append(aResult.Mid(2));
//_LIT(fullpath,"C:\\");
//aResult.Copy(fullpath);
//获取目录项结束
CTextListBoxModel* model = iSavedGamesListBox->Model(); // not taking ownership
model->SetOwnershipType (ELbmOwnsItemArray);
CDesCArray* savedGamesArray = STATIC_CAST(CDesCArray*, model->ItemTextArray());
savedGamesArray->Reset();
GetFileListAndSubDirList(aResult,*savedGamesArray);
iSavedGamesListBox->HandleItemAdditionL();
iSavedGamesListBox->SetFocus( ETrue );
//iSavedGamesListBox->SetCurrentItemIndexAndDraw(appView->iListIndex);
iSavedGamesListBox->ActivateL();
//iSavedGamesListBox->DrawDeferred();
iSavedGamesListBox->DrawNow();*/
}
}
/**
* Called by the framework whenever a key event occurs.
* Passes the key event to the saved games list if it is not null, otherwise returns
* EKeyWasNotConsumed
* @param aKeyEvent the Key event which occured, e.g. select key pressed
* @param aType the type of Key event which occurred, e.g. key up, key down
* @return TKeyResponse EKeyWasNotConsumed if the key was not processed, EKeyWasConsumed if it was
*/
TKeyResponse ListBox::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
if(aType != EEventKey)
{
return EKeyWasNotConsumed;
}
else if(iListBox)
{
return iListBox->OfferKeyEventL( aKeyEvent, aType );
}
else
{
return EKeyWasNotConsumed;
}
}
void ListBox::AddInfoToList(TInt aIndex, const TDesC& aText)
{
TBuf<64> sBuf;
sBuf.AppendNum(aIndex);
sBuf.Append(_L("\t"));
sBuf.Append(aText);
iArray->AppendL(sBuf);
// update listbox
iListBox->HandleItemAdditionL();
}
APPUI.h中加入容器作为它的成员变量
ListBox* listbox_container;
APPUI.CPP 中在::ConstructL()中进行注册。
BaseConstructL(EAknEnableSkin);
listbox_container=ListBox::NewL(ClientRect());
listbox_container->SetMopParent(this);
//listbox_container->s
AddToStackL(listbox_container);