1.场景
在本项目中,商品是最核心的对象。
处理是围绕对商品的操作进行的,如商品管理和发布商品。
商品图片是商品的属性之一,允许为一种商品提供正面,侧面和整体图片(全部或部分)。
编辑商品的界面demo如下图:
下面提供的实现,是对原有代码的改写。
这种代码没有什么技巧可言,就是直接,没有多余的东西。实现这一点需要了解,利用和发掘开发工具提供的元素(能力)。
代码的美人标准:减一行太瘦,增一行太肥。
2.代码示例
2.1定义
//---------------------------------------------------------------------------
///< 商品图片类
struct CGoodsPic {
int index_; /// 1-前视图 2-侧视图 3-俯视图
int format_; //格式(保留) 0-未指定
string ext_name_; //扩展名
string file_name_; ///< 文件名
char *data_; ///< 图片数据
unsigned long len_; ///< 图片数据大小(字节数)
CGoodsPic():index_(0),format_(0),data_(0),len_(0) {
}
~CGoodsPic() {
if (data_) delete []data_;
}
///< 清除图片对象信息
void Reset() {
format_ = 0;
ext_name_.clear();
if (data_) delete []data_;
len_ = 0;
}
};
//---------------------------------------------------------------------------
///< 商品类(demo)
class CGoods {
public:
string barcode_; ///< 条码
///...其它属性
map<int, CGoodsPic*> pics_; // 图片
///< 取指定序号的图片对象
CGoodsPic* GetPic(unsigned short index) {
map<int,CGoodsPic*>::iterator iter = pics_.find(index);
return iter==pics_.end() ? 0 :iter->second;
}
///< 设置商品的图片对象
int SetPic(unsigned short index,CGoodsPic *pic) {
pics_[index] = pic;
return 0;
}
///< 删除指定序号的图片
int RemovePic(unsigned short index) {
map<int,CGoodsPic*>::iterator iter = pics_.find(index);
if (iter!=pics_.end()) {
delete iter->second;
pics_.erase(iter);
return 0;
}
return -1;
}
///< 商品图片数
unsigned int GetPicCount() const { return pics_.size(); }
};
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *btnAdd;
TButton *btnDelete;
TButton *btnOk;
TImage *imgNullPic;
TPageControl *pcPicture;
TTabSheet *TabSheet1;
TTabSheet *TabSheet2;
TTabSheet *TabSheet3;
void __fastcall btnAddClick(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall btnDeleteClick(TObject *Sender);
void __fastcall btnOkClick(TObject *Sender);
private: // User declarations
CGoods goods_; ///< 商品对象
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
2.2实现
//---------------------------------------------------------------------------
///< 增加图片
void __fastcall TForm1::btnAddClick(TObject *Sender)
{
///< 让用户选择文件
TOpenDialog* pDlg = new TOpenDialog(this);
pDlg->Filter = "图片文件 (*.*)|*.*";
pDlg->Title = "选择商品图片文件";
pDlg->Options.Clear();
pDlg->Options << ofFileMustExist << ofHideReadOnly << ofNoChangeDir;
if(!pDlg->Execute() ) { ///< 用户取消,则结束
delete pDlg;
return;
}
///< 选择的图片文件名
AnsiString strFileName = pDlg->FileName;
delete pDlg;
///< 检查文件是否为空.空文件不做后续处理
DWORD file_size = GetFileSize(strFileName.c_str(),0);
if (file_size==0)
return;
///< 当前活动页(对应一种图片:正面,侧面,整体)
int index = pcPicture->ActivePageIndex;
assert(index!=-1);
int pic_index = index+1; ///< 图片序号,定义的图片顺序显示在pcPicture
TImage *image = (TImage*)pcPicture->ActivePage->Controls[0];
///< 无效的或不可识别的文件会导致异常(如PNG文件)
try {
image->Picture->LoadFromFile(strFileName);
}
catch(const Exception &E) {
ShowMessage("无效的或不可识别的文件");
return;
}
///< 读图片数据到TStringStream
TGraphic *graph = image->Picture->Graphic;
AnsiString data;
TStringStream* pSS = new TStringStream(data);
graph->SaveToStream(pSS);
data = pSS->DataString;
delete pSS;
CGoodsPic *goods_pic = goods_.GetPic(pic_index);
if (goods_pic) { ///< 如果已有图片,则重置图片对象.此操作为更换图片
goods_pic->Reset();
}
else { ///< 否则是新增图片
goods_pic = new CGoodsPic;
goods_pic->index_ = pic_index;
}
///< 设置图片数据信息
AnsiString ext_name = ExtractFileExt(strFileName);
if (!ext_name.IsEmpty())
goods_pic->ext_name_ = ext_name.c_str();
goods_pic->file_name_ = strFileName.c_str();
goods_pic->len_ = data.Length();
goods_pic->data_ = new char[goods_pic->len_];
memcpy(goods_pic->data_,data.c_str(),goods_pic->len_);
///< 设置商品图片信息
goods_.SetPic(pic_index,goods_pic);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
for (int i=0;i<pcPicture->PageCount;i++) {
TTabSheet *sheet = pcPicture->Pages[i];
TImage *image = new TImage(sheet);
image->Parent = sheet;
image->Transparent = true;
image->Align = alClient;
///< 初始时设置缺省图片,表示"没有指定商品图片"
image->Picture->Assign(imgNullPic->Picture);
}
}
//---------------------------------------------------------------------------
///< 删除图片
void __fastcall TForm1::btnDeleteClick(TObject *Sender)
{
if (goods_.GetPic(pcPicture->ActivePageIndex+1)==0)
return;
TImage *image = (TImage*)pcPicture->ActivePage->Controls[0];
///< 恢复缺省图片
image->Picture->Assign(imgNullPic->Picture);
///< 删除图片
int pic_index = pcPicture->ActivePageIndex+1;
goods_.RemovePic(pic_index);
return;
}
//---------------------------------------------------------------------------
///< 验证图片信息
void __fastcall TForm1::btnOkClick(TObject *Sender)
{
unsigned int pic_num = goods_.GetPicCount(); ///< 有效图片个数
map<int, CGoodsPic*>::iterator iter = goods_.pics_.begin();
while(iter!=goods_.pics_.end()) {
CGoodsPic *pic = iter->second;
ShowMessage(pic->file_name_.c_str());
iter++;
}
}