www.pudn.com > ecc-0.3.16-src.zip > eccPropertyHandler.cpp
/* ========================================================================== ecc - Erik's Code Collection Copyright (C) 2003-2005 - Erik Dienske This file is part of ecc. ecc is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ecc is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ecc; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ===========================================================================*/ //--------------------------------------------------------------------------- #include#pragma hdrstop #include "eccPropertyHandler.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- /* TPropertyHandler v1.0 ===================== Author: Erik Dienske TPropertyHandler allows control of the properties and values of descendants of TComponent (VCL components). Every function has a description, take a look at the header file too. ------ Example 1: TPropertyHandler ph(f_Main); Caption = ph.GetValue("BorderIcons"); Example 2: TPropertyHandler ph; Caption = ph.GetNameValue(Form1, "WindowState"); Example 3: TPropertyHandler* ph = new TPropertyHandler(CheckBox1); Caption = ph.SetValue("Checked","true"); delete ph; ------ If you #define PROPERTYHANDLER_SHOW_WARNINGS warnings will be displayed (using ShowMessage()) if a property does not exist or if the default Component is not defined - for debugging purposes. ------ If a returned string contains several lines it does not display nice in components like a Memo if you use: Memo->Lines->Add .. but is does look right if you use: Memo->Lines->Text = .. */ //=========================================================================== namespace ecc { //=========================================================================== //--------------------------------------------------------------------------- TPropertyHandler::TPropertyHandler() { FDefaultComponent = NULL; } //--------------------------------------------------------------------------- TPropertyHandler::TPropertyHandler(TComponent* comp) { FDefaultComponent = comp; } //--------------------------------------------------------------------------- //=========================================================================== //== Private functions: (For internal use by TPropertyHandler) //=========================================================================== bool TPropertyHandler::DefaultComponentExists() { #ifdef PROPERTYHANDLER_SHOW_WARNINGS if (FDefaultComponent == NULL) { ShowMessage( "TPropertyHandler warning:\n\n" "Default Component is not defined." ); } #endif return (FDefaultComponent != NULL); } //--------------------------------------------------------------------------- String TPropertyHandler::BuildNameValue(TComponent* comp, String prName) { return prName + "=" + GetPropValue(comp, prName, true); } //--------------------------------------------------------------------------- String TPropertyHandler::GetClassNamesValues(TComponent* comp, String prName) { TObject *subObj = (TObject *)GetOrdProp(comp, prName); if (subObj == NULL) return ""; // In case the prop-value is empty (like Action). /* TObject* subObj is needed to find out if the subprop points to another Component (like ActiveControl). If it is only the value of that property is returned (ie.: "CheckBox1"). If it is a class like Font all of the props+values of comp->Font are returned. */ if (dynamic_cast (subObj)) { // Find out if subObj points to another Component by casting. return prName + "=" + GetValue((TComponent*)subObj,"Name"); } /* subObj does not point to another Component, but we can convert it to a TComponent* subComp so it can be used te get the subProps+values. This sounds weird but don't forget that a TFont encapsulated in a TForm becomes a descendant of TForm, which is a descendant of TComponent!! */ TComponent* subComp = (TComponent*)subObj; TStringList *tempList = new TStringList; String temp; try { PTypeInfo TypeInfo = (PTypeInfo)subComp->ClassInfo(); PPropList PropList = new TPropList; GetPropInfos(TypeInfo, PropList); tempList->Sorted = true; for (int i=0; i < PropertyCount(subComp); i++) { String subProp = String(PropList[i]->Name); tempList->Add( prName + "." + subProp + "=" + GetPropValue(subComp, subProp, true) ); } delete[] PropList; temp = tempList->Text; // Remove trailing carriage-returns: int cr = temp.LastDelimiter("\r"); if (cr) temp.Delete(cr, 2); } __finally { delete tempList; } return temp; } //=========================================================================== //== Published 'information'-functions: //=========================================================================== int TPropertyHandler::PropertyCount(TComponent* comp) { PTypeInfo TypeInfo = (PTypeInfo)comp->ClassInfo(); PTypeData TypeData = GetTypeData(TypeInfo); return (int)TypeData->PropCount; } //--------------------------------------------------------------------------- int TPropertyHandler::PropertyCount() { if (!DefaultComponentExists()) return -1; return PropertyCount(FDefaultComponent); } //--------------------------------------------------------------------------- bool TPropertyHandler::IsClass(TComponent* comp, String prName) { Typinfo::TTypeKind kind = PropType((TObject*)comp, prName); return (kind == tkClass); } //--------------------------------------------------------------------------- bool TPropertyHandler::IsClass(String prName) { if (!DefaultComponentExists()) return false; return IsClass(FDefaultComponent, prName); } //--------------------------------------------------------------------------- bool TPropertyHandler::PropertyExists(TComponent* comp, String prName) { if (prName == "sped_sped_MaxRecentFiles") ShowMessage("sped_MaxRecentFiles"); if (!IsPublishedProp(comp, prName)) { // #ifdef PROPERTYHANDLER_SHOW_WARNINGS ShowMessage( "TPropertyHandler warning:\n\n" "Property '" + GetName(comp) + "." + prName + "' does not exist." ); // #endif return false; } return true; } //--------------------------------------------------------------------------- bool TPropertyHandler::PropertyExists(String prName) { if (!DefaultComponentExists()) return false; return PropertyExists(FDefaultComponent, prName); } //--------------------------------------------------------------------------- //=========================================================================== //== Published Get... -functions: //=========================================================================== //--------------------------------------------------------------------------- String TPropertyHandler::GetName(TComponent* comp) { return comp->Name; } //--------------------------------------------------------------------------- String TPropertyHandler::GetName() { if (!DefaultComponentExists()) return ""; return GetName(FDefaultComponent); } //--------------------------------------------------------------------------- Variant TPropertyHandler::GetValue(TComponent* comp, String prName) { if (!PropertyExists(comp, prName)) return NULL; if (IsClass(comp, prName)) return NULL; return GetPropValue(comp, prName, true); // Parameter true: Strings are preferred returntype (see TypeInfo.pas). } //--------------------------------------------------------------------------- Variant TPropertyHandler::GetValue(String prName) { if (!DefaultComponentExists()) return NULL; return GetValue(FDefaultComponent, prName); } //--------------------------------------------------------------------------- String TPropertyHandler::GetNameValue(TComponent* comp, String prName) { if (!PropertyExists(comp, prName)) return ""; if (IsClass(comp, prName)) return GetClassNamesValues(comp, prName); return BuildNameValue(comp, prName); } //--------------------------------------------------------------------------- String TPropertyHandler::GetNameValue(String prName) { if (!DefaultComponentExists()) return ""; return GetNameValue(FDefaultComponent, prName); } //--------------------------------------------------------------------------- String TPropertyHandler::GetNamesValues(TComponent* comp, String prNames) { String list, prop, name1, name2; int prop_start = 1, prop_end, sep; while (prop_start < prNames.Length()) { // Extract (next) prop from props: prop_end = prNames.Pos(";"); // Find end of prop. if (!prop_end) prop_end = prNames.Length() + 1; // Last prop. else prNames[prop_end] = ' '; // Remove ';'. prop = prNames.SubString(prop_start, prop_end - prop_start); prop_start = prop_end + 1; // Get the value: if (!PropertyExists(comp, prop)) continue; if (IsClass(comp, prop)) list = list + GetClassNamesValues(comp, prop) + "\n"; else list = list + BuildNameValue(comp, prop) + "\n"; } return list; } //--------------------------------------------------------------------------- String TPropertyHandler::GetNamesValues(String prNames) { if (!DefaultComponentExists()) return ""; return GetNamesValues(FDefaultComponent, prNames); } //--------------------------------------------------------------------------- String TPropertyHandler::GetAllNamesValues(TComponent* comp) { String list; TStringList *tempList = new TStringList; try { tempList->Sorted = true; PTypeInfo TypeInfo = (PTypeInfo)comp->ClassInfo(); PPropList PropList = new TPropList; GetPropInfos(TypeInfo, PropList); String data; for (int i=0; i < PropertyCount(comp); i++) { String prName = String(PropList[i]->Name); if (PropIsType(comp, prName, tkMethod)) continue; // Skip events. if (IsClass(comp, prName)) { data = GetClassNamesValues(comp, prName); } else data = BuildNameValue(comp, prName); if (!data.IsEmpty()) tempList->Append( data ); } delete[] PropList; list = tempList->Text; } __finally { delete tempList; } return list; } //--------------------------------------------------------------------------- String TPropertyHandler::GetAllNamesValues() { if (!DefaultComponentExists()) return ""; return GetAllNamesValues(FDefaultComponent); } //--------------------------------------------------------------------------- void TPropertyHandler::SetValue(TComponent* comp, String prName, Variant prValue) { if ((prValue.Type() == varBoolean) && (prValue == -1)) prValue = 1; // Fixes the bug. SetPropValue(comp, prName, prValue); } //--------------------------------------------------------------------------- void TPropertyHandler::SetValue(String prName, Variant prValue) { if (!DefaultComponentExists()) return; SetValue(FDefaultComponent, prName, prValue); } //--------------------------------------------------------------------------- void TPropertyHandler::SetNameValue(TComponent* comp, String prName_Value) { if (prName_Value.LastDelimiter("\r\n")) { // Multi-line string, so call SetNamesValues(): SetNamesValues(comp, prName_Value); return; } String name2, name1, value; // Reads like this: "name2.name1=value". int sep = prName_Value.Pos("="); String names = prName_Value.SubString(1, sep - 1); value = prName_Value.SubString(sep + 1, prName_Value.Length() - sep + 1); sep = names.Pos("."); if (sep) { // Format is "propname.subprop=val": name1 = names.SubString(sep + 1, names.Length() - sep + 1); name2 = names.SubString(1, sep - 1); // name2 is the subcomp of comp. if (!IsPublishedProp(comp, name2)) // No warning. { /* name2 is not a component of comp, but it might be a component of its own, like CheckBox1 is a sub-component of Form1. */ if ((comp = GetSubComponent(comp, name2)) == NULL) return; else { SetPropValue(comp, name1, value); return; } } if (!IsClass(comp, name2)) return; // Get pointer to subObj: TObject *subObj = (TObject *)GetOrdProp(comp, name2); if (subObj == NULL) return; SetPropValue(subObj, name1, value); } else { // Format is "propname=val": SetPropValue(comp, names, value); } } //--------------------------------------------------------------------------- void TPropertyHandler::SetNameValue(String prName_Value) { if (!DefaultComponentExists()) return; SetNameValue(FDefaultComponent, prName_Value); } //--------------------------------------------------------------------------- void TPropertyHandler::SetNamesValues(TComponent* comp, String prNames_Values) { // Process every line: TStringList *list = new TStringList; try { list->Text = prNames_Values; int pos = 0; while (pos < list->Count) { SetNameValue(comp, list->Strings[pos]); ++pos; } } __finally { delete list; } } //--------------------------------------------------------------------------- void TPropertyHandler::SetNamesValues(String prNames_Values) { if (!DefaultComponentExists()) return; SetNamesValues(FDefaultComponent, prNames_Values); } //--------------------------------------------------------------------------- TComponent* TPropertyHandler::GetSubComponent(TComponent* comp, String prName) { for (int i = 0; i < comp->ComponentCount; i++) { if (comp->Components[i]->Name == prName) return comp->Components[i]; } return NULL; } //--------------------------------------------------------------------------- TComponent* TPropertyHandler::GetSubComponent(String prName) { if (!DefaultComponentExists()) return NULL; return GetSubComponent(FDefaultComponent, prName); } //--------------------------------------------------------------------------- //=========================================================================== } // namespace ecc; //===========================================================================