Шаг 84 - Редакторы свойств

Редакторы свойств - вспомогательный элемент компонента, помогающий изменять значения свойств компонента at design-time в красивом (или не очень - как обычно все зависит от программиста) диалоге. Делать это обычно удобнее, чем вручную сидеть и набивать значение свойства в маленькое поле. Вот типпичные примеры редакторов свойств:

gif/84_1.gif (2156 b)

gif/84_2.gif (8226 b)

gif/84_3.gif (2979 b)

Ну, Вы не подумайте, что они у меня так выглядят тоже - узенько и без оконных кнопок - это просто монтаж.

Теперь поняли, какая это хорошая вещь? Для начала добавим свойство Root - папка, от которой отображается дерево. Ну, и какой же редактор свойств нам подойдет больще всего? Конечно же, окно просмотра папки :)). Ну я думаю, мы рекурсивно создавать не будем компонент, а сделаем так:

// ------------- FolderDialog.h
#ifndef FolderDialogH
#define FolderDialogH

//-----------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <dsgnintf.hpp>
//-----------------------------------

//	...

class PACKAGE TFolderDialog : public TCommonDialog
{
//	...
private:
//	...
protected:
//	...
AnsiString FRoot;
//	...

TNotifyEvent FOnClose;
public:
//	...
__published:
//	...
	__property AnsiString Root = {read = FRoot, write = FRoot};
	__property AnsiString StatusText = {read = FStatusText, write = SetStatusText};
//	...
};

class PACKAGE TFolderPropertyEditor : public TStringProperty
{
public:
__fastcall TFolderPropertyEditor(void):Dsgnintf::TStringProperty(Designer,0){};
TPropertyAttributes __fastcall GetAttributes()
{
	return TPropertyAttributes()<<paDialog;
};
void __fastcall Edit();

};
//-----------------------------------
#endif

Файл FolderDialog.cpp:

// ------------- FolderDialog.cpp

#define NO_WIN32_LEAN_AND_MEAN
#include <shlobj.h>
#include <vcl.h>
#pragma hdrstop

#include "FolderDialog.h"
//	...
#pragma package(smart_init)
//	...

//-----------------------------------
bool __fastcall TFolderDialog::Execute(void)
{
//	...

if(FRoot!=NULL){
	if(FRoot.Length()>0)
	{
		LPITEMIDLIST pidl;
		LPSHELLFOLDER folder;
		SHGetDesktopFolder(&folder);
		unsigned long parsed;
		folder->ParseDisplayName(NULL,0,
			WideString(FRoot).c_bstr(),
			&parsed,&pidl,NULL);
		delete folder;
		bi.pidlRoot = pidl;
	};
};

LPITEMIDLIST lst = SHBrowseForFolder(&bi);
FHandle = 0;
if(FOnClose) OnClose(this);
if(!lst) return false;
char buf[MAX_PATH];
SHGetPathFromIDList(lst,buf);
FFolder = buf;
return true;
}
//	...
namespace Folderdialog
{
	void __fastcall PACKAGE Register()
	{
		TComponentClass classes[1] = {__classid(TFolderDialog)};
		RegisterComponents("Ossam", classes, 0);
		PTypeInfo ti = *GetPropInfo(__typeinfo(TFolderDialog),"Root")->PropType;
		RegisterPropertyEditor(ti, __classid(TFolderDialog),
			"Root",__classid(TFolderPropertyEditor));
	}
}
//	...
void __fastcall TFolderPropertyEditor::Edit(void)
{
	BROWSEINFO bi;
	setmem(&bi, sizeof(bi), 0);
	bi.hwndOwner = NULL;
	bi.ulFlags = 0;
	bi.lpszTitle = String("Select Folder").c_str();
	LPITEMIDLIST idl = SHBrowseForFolder(&bi);
	if(idl==NULL) return;
	char buf[MAX_PATH];
	SHGetPathFromIDList(idl,buf);
	SetValue(AnsiString(buf));
};
//	...

Ну вот. Такой вариант редактора свойств Вас устраивает? В следующем шаге еще что-нибудь по поводу редакторов свойств расскажу.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Аванесов Самвел - 08.09.2002