Re: document class
On Sun, 26 Sep 2010 05:47:35 -0700 (PDT), mfc <mfcp...@googlemail.com> wr=
ote:
On 26 Sep., 04:12, Joseph M. Newcomer <newco...@flounder.com> wrote:
See below...
On Fri, 24 Sep 2010 13:44:00 -0700 (PDT), mfc <mfcp...@googlemail.com>=
wrote:
According to the CXML file class: at the beginning (in the
OnNewDocument method) I will call the xml class method to load the
specific xml file and load all the values / node values from the xml
file into a CStringList; after that I release the xml file.
According to your xml file <display::brightness disabled="true"
level="50"/> - how will you get the information disabled="true" from
the xml file with your call CString brightness =
XML.GetBrightness(_T("myxmlfile.display.brightness"));?
****
I wouldn't. I'd actually retrieve the disabled property and see what i=
ts value was.
****
That means you`re using two separate methods (one for getting the
value of the brightness and one for getting the attribute disabled)?
If the http socket class will (now) get some values from the std:map
in the xml file class, I will send a PostMessage to the visible window
including the threadID as well as a CStringList which includes all key
names of the std::map. I will search for each specific CString value
from this list in the std::map and will return another CStringList to
the http socket server including all values (instead of the keys).
*****
The way I did it was that if the property already existed, I replaced its=
value, and if it
didn't exist, I created it with the value I sent in.
I`m not sure if I got you right, but I don`t want that each class
(http socket class for example) is able to create a new item in the
std::map. The http class should not know that there`s a std::map or
anything else installed in the xml file class (as you pointed it out).
Therefore I think the conecpt using a wrapper class - the same one as
for the CDisplay class - is a good solution.
After creating the http socket connection thread, which is created if
a new connection is accepted. This thread will send a PostMessage to
the document class (GetPropInformation()) getting a pointer of the
wrapper CProperty class back. With this information, the http soc
class is able to get any name/value pairs and to set any values.
Using such a property class, the document class will only hold one
property member - and also do not know anything about xml and so on
class CMIAppDoc : public CDocument
{
protected:
CMIAppDoc();
DECLARE_DYNCREATE(CMIAppDoc)
protected:
CProperty prop;
public:
CProperty* GetProp(void) {return(&prop);}
};
//lparam = thread-id from http soc thread
//wparam is empty
LRESULT VisbileWnd::GetPropInformation(wparam, lparam)
{
::Postthreadmessage(lparam, (WPARAM)GetProp(void), 0);
}
But the html soc class needs the information: which name will (e.g.
display:brightness) represent the brightness value and so on. Only the
xml file class will have this information. And the GetValue(name)
function is global not specified for one node name.
class HttpSoc :
public CConnSoc
{
public:
HttpSoc(void);
~HttpSoc(void);
protected:
CProperty* hprop;
};
CProperty* hprop will get its pointer by using a PostMessage to the
visible window getting the document protected member CPoperty prop;
void HtmlSocClass::GetRequiredInformation(void)
{
CString brightness;
CXml *pxml
pxml= (CXml *)hprop;
brightness = pxml->GetValue(_T("display:brightness"));
}
This example will work but it is not very nice, because it uses
hardcoded-values... if I will change the node name in the xml file
from display:brightness to disp:bright, I have to look for such
hardcoded-values (_T("display:brightness")); to change them too...
that`s not really what I want or prefer. But at the moment I don`t
know a really proper way - maybe using the string table which will
reduce such hardcoded values to one place, where I have to change
them...
By the way, do I have to install the CXml *pxml pointer to determine
which subclass should be called by GetValue? Are you using a different
approach to determine which subclass is the correct one?
void VisibleWindow::OnGetNewHttpRequest(wparam, lparam)
{
CStringList *slist = (CStringList *)wparam;
doc->GetData(slist);
::PostThreadMessage(UWM_SEND_BACK_TO_HTTP, slist, 0);
****
You keep referring to a CStringList as if this makes sense. But you ne=
ver, ever once say
what is IN it. If it is a list of name value pairs parsed from the HTT=
P request, e.g.,
disabled=true&level=50
that makes sense, because you parse this into two array or string element=
s
disabled=true
level=50
but you must never, ever, under any circumstances imaginable, fail to han=
dle the strings
level=50&disabled=true
or
level=50
or
disabled=true
There is no, repeat, no, order dependence in the HTTP specification, and =
to presume that
one exists, or to presume that all parameters are supplied, is a very fra=
gile and probably
unusable design. If each element of your list is of the form
name=value
then you further parse this to extract the name and value, and now you ha=
ve your
name-value pairs. But if all you supplied was
50
` true
then the design should be thrown out.
Essentially, you keep trying to take a simple problem and make it hard.
****
class HttpSoc :
public CConnSoc
{
public:
HttpSoc(void);
~HttpSoc(void);
protected:
CProperty* prop;
};
void HttpSock
with the approach that the http soc class will have a pointer to the
wrapper CProperty class, there`s no need to send a PostMessage back to
the document class (visible window) to change the values or get the
values from the std::map which is installed in the xml file class.
****
Without knowing what you mean by "value" there is no way to tell what thi=
s is trying to
do. Again, if "value" is a string like "level=50" then you are OK, A=
nd why do you presume
that there is any correlation in ordering between the attributes in the G=
etValue call and
attributes in the sequence. To read out a set of values, I would have =
written:
void MyDocClass::GetData(CProperties & props)
{
POSITION pos = XML.GetFirstValuePosition("display:brightness");
while(pos != NULL)
{
CString name;
CString value;
XML.GetValue(pos, name, value);
props.SetValue(name, value);
GetNextValuePos(pos);
}
}
BOOL XML::GetValue(pos, CString & name, CString & value)
But how do you determine during the runtime if a CProperty member is a
member of the Network, the Display or the XML Class?
class CDisplay : public CProperty
class CNetwork : public CProperty
class CXml : public CProperty
CString brightness = prop->GetValue(_T(""));
That's the whole idea. If I store a ip="192.168.168.2" or "level=50",=
the CProperties
class neither knows nor cares that one applies to networks and another app=
lies to
displays. Of course, if I pass a property to the wrong component, it won'=
t be able to
make sense of it, but that's not my problem. In XML, the idea is to use =
the nodes to
provide the typing; so in the network class, I might expect a 'network' no=
de and if I
dn't get a 'network' node, I will complain; in the display class I expect =
a 'display'
node and if I don't get one, I again complain. So my type-checking is not=
on the
properties, but a runtime check on the node type (not a compile-time check=
on the node
type)
But how could you ensure that you will get a display node in the
display class? Could you give me a small example of determining the
node type during the runtime check?
best regards
Hans