|
IMO I believe that the Document should be designed first. It is possible to create multiple views of the same document. In fact, each of these views can display some different aspect of your document. Therefore, because the Document is the item that all of the views have in common, the document is the object that should be designed first.
It may be useful however, to take into account what you want your view to display, this may give you some clues as to the types of data that may be required in your Document object, but may not be immediately apparent.
kuphryn wrote:
Lastly, let say I have other classes that manipulate the data in the file *before* outputing it. Where should I instantiate these classes in documents or in view? I am not completely clear as to rank of document and view.
Here is an attempt to create a quick diagram of a clean design for what you have described.
This is not an inheritance model, but a model of the owners of all of the objects. The arrows
point to the child objects that a parent object owns.
--------------------------------------------------
| |
| Main Window |
| |
--------------------------------------------------
| | | |
| | | |
| | | |
V | V V
------------ | ------------- --------------
| View 1 | | | View 2 | | Document |
------------ | ------------- | Mutator |
| --------------
|
V
----------------
| Document |
----------------
In this diagram, all of the objects are owned by the main window, the simply point to the document, and use the data in the document. View the Document as a piece of data with accessor functions.
With this in mind then you will need other classes that manage the data (document mutators), whether you edit it with an edit control or some other method. These items should be owned and controlled by the main window / main module. This allows the data to be separated from the implementation. This design would also allow you to reuse the document object that you created in a completely different app with a completely different front end (optimal code resue).
While I know that this is not always the final result in the practice of software engineering, it is a main goal of object oriented software design.
|
|
|
|
|
Thanks.
Your diagram is clear.
Also, how about determining where to include command and command handlers, including updates? If I remember correctly, Promise emphasizes any commands having to do with the mouse and keyboard should be in view.
MFC is very powerful. Microsoft designed MFC to be flexible. For example, I was not clear as to how a view object knows when to draw an interpretting of document data on the screen. I believe documents calls friends classes of view. That is flexible.
Kuphryn
|
|
|
|
|
Your right, besides displaying the document, the views other purpose is to manage the UI commands that relate to the document through that view.
Deciding where the command handlers should go can be tricky, I think that it all depends on whether you want your design to lean towards the conceptually perfect object-oriented design, or the completely function software implementation. I think that it is best to create an implementation that is somewhere in the middle.
What I mean by this, is the line gets a little blurry where certain members should actually be placed. I think that in most cases, especially programs with simple views, the handlers, and mutators can be placed directly in your view class.
The fact is that most of the sample programs that you find in books are small, and the authors develop their samples with this technique. When you start getting larger projects, possibly with multiple views, and events that have alot of common code, this is when you should start breaking your classes down and creating the mutator classes that I spoke of earlier.
Hope this helps, it is simply my opinion, but my opinion is based on years of experience and alot of reading of other peoples opinions and experiences.
|
|
|
|
|
kilowatt: Thanks! Yeah, I could foresee that it could become difficult to pick where command UI handlers should be. When you said OOP concept, are you implying command UI being in view or in documents? I believe OOP is extremely powerful because the concept related to real life.
As I mentioned in the topic of "New Milestone," document/view architecture has shine light on my understanding of MFC. It gave me confident to push further (finish the book), and along the way, begin to take pay close attention and take notes for future projects (implement my C++ programs using MFC). I am not quite to that point yet, but MFC is beginning to come together nicely relative to my learning MFC.
-----
Multiple view per document: (AsmGuru62 brought up this issue at programmersheaven)
Lets consider the example AsmGuru62 mentioned about formatting data in text and HEX. As of chapter 10 in Prosise' book, he has not brought up the concept of multiple view. He did mention multiple documents as an upcoming topic, but not multiple view.
First, for multiple view, do you approach it exactly the same way as singular view? Do you use ClassWizard to add a new a new derivative of CView or one of CView's derivative (scroll, etc.)?
-----
I am at a point with MFC where I see the *lego* pieces, but I have limited experience assembling the pieces together. That includes mapping related commands to related class derivatives, etc. I believe that comes with experience.
Kuphryn
|
|
|
|
|
if (Promise == Prosise) goto WinAPI;
|
|
|
|
|
little question:
i am using an ifstream and getline like this
while (1)
{
if (!std::getline (file, line1))
break;
}
well.. this works very well.. but some of the textfiles i'm reading don't have got CR+LF in their last line.. means that this call returns false.. and that i am missing the last line.
can somebody explain me how to do this correctly or a workaround?
Sometimes I think the surest sign for intelligent life elsewhere in
the universe is that none of them ever tried to contact us.
|
|
|
|
|
I'm not able to reproduce your problem. This tiny program
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ifstream in("test.txt");
for( ; ; ){
string str;
if(!getline(in,str))break;
cout<<str<<"LF"<<endl;
}
return 0;
} emits the same output no matter whether the last line of test.txt is CR+LF terminated or not.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
yeah.. it really works.. so i've cut out the original code.. cause it is a little bit more complex.. but i thought i cut it down to the "root of its evil"
while (1)
{
if (!std::getline (file, line1))
break;
std::streampos here = file.tellg();
std::getline (file, line2);
file.seekg (here);
....
}
well.. the code is something like 2 steps forward, one step back.. i use this because i need the context of every single line in the text file..
it works perfectly for text files where the last line is terminated with CR+LF, but if the file is not terminated with CR+LF it breaks when reading this line.. and not when the EOF is reached..
thanks in advance
bernhard
Sometimes I think the surest sign for intelligent life elsewhere in
the universe is that none of them ever tried to contact us.
|
|
|
|
|
This patch seems to fix the thing
while (1)
{
if (!std::getline (file, line1))
break;
std::streampos here = file.tellg();
std::getline (file, line2);
<font color=#ff0000>file.clear();</font>
file.seekg (here);
....
} But my impression is that the code should work without the patch... maybe it's an STL bug. I'll do some more investigation later.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
well.. i hardly can believe this (this problem is hanging around in my head since three month..)
it is not an a+ project..
AND NOW IT FINALLY WORKS.. THANK YOU !
really great...
bernhard
Sometimes I think the surest sign for intelligent life elsewhere in
the universe is that none of them ever tried to contact us.
|
|
|
|
|
enclosed an article of Microsoft, source of this statement:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q240015
Krz
FIX: getline Template Function Reads Extra Character (Q240015)
-------------------------------------------------------------------------
The information in this article applies to:
The Standard C++ Library, used with:
Microsoft Visual C++, 32-bit Enterprise Edition, version 6.0
Microsoft Visual C++, 32-bit Professional Edition, version 6.0
Microsoft Visual C++, 32-bit Learning Edition, version 6.0
-------------------------------------------------------------------------
SYMPTOMS
The Standard C++ Library template getline function reads an extra character after encountering the delimiter. Please refer to the sample program in the More Information section for details.
RESOLUTION
Modify the getline member function, which can be found in the following system header file string, as follows:
else if (_Tr::eq((_E)_C, _D))
{_Chg = true;
// _I.rdbuf()->snextc(); /* Remove this line and add the line below.*/
_I.rdbuf()->sbumpc();
break; }
NOTE : Because the resolution involves modifying a system header file, extreme care should be taken to ensure that nothing else is changed in the header file. Microsoft is not responsible for any problems resulting from unwanted changes to the system header files.
STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.
This problem was corrected in Microsoft Visual C++ .NET.
MORE INFORMATION
The following sample program demonstrates the bug:
//test.cpp
//Compiler options : /GX
#include <string>
#include <iostream>
int main () {
std::string s,s2;
std::getline(std::cin,s);
std::getline(std::cin,s2);
std::cout << s <<'\t'<< s2 << std::endl;
return 0;
}
Actual Results:
Hello<enter key="">
World<enter key="">
<enter key="">
Hello World
Expected Results:
Hello<enter key="">
World<enter key="">
Hello World
-------------------------------------------------------------------------
Published Sep 16 1999 12:33PM Issue Type kbbug
Last Modifed Feb 11 2002 7:06PM Additional Query Words STL
Keywords kbtemplate kbLangCPP kbSTL kbVC kbVC600 kbVC600bug kbNoUpdate
|
|
|
|
|
Hello All,
How do I create a color ramp from two ranges of colors? some of 2 by 2 matrix. Anyone with a suitable algorithm?
Best regards,
Paul.
Paul Selormey, Bsc (Elect Eng), MSc (Mobile Communication) is currently Windows open source developer in Japan.
|
|
|
|
|
A 2x2 matrix requires you decide to ignore red, green or blue. Better you convert to HLS and then ignore one of those. Anyhow, once you decide which value to keep constant, just build a range between the two value sets you want to work with.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
|
|
|
|
|
Thanks.
Best regards,
Paul.
Paul Selormey, Bsc (Elect Eng), MSc (Mobile Communication) is currently Windows open source developer in Japan.
|
|
|
|
|
My memory has failed me badly and the code from when I did this last time was lost in a major disaster.
If I have an Bitmap drawn on a MemDC what is the fast way to put it in a CBitmap object which is then to be added to a CImageList.
I have searched the site and not found the answer.
Happy programming!!
|
|
|
|
|
Build a BITMAP from CDC::GetCurrentBitmap, use that to create a new CBitmap, put it into a CDC and BitBlt. I think if you grab GetCurrentBitmap, you'll have troubles as the DC owns it.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
|
|
|
|
|
If you create a simple microsoft Win32 DLL function, it creates an entry point file plus the stdafx files which contain the windows.h include file.
However, if you start adding header and cpp files which make reference to stuff like CRecordSet and have references to stuff like afxdb, then Windows.h and afxdb.h get in one another's way.
Then, if you comment out the windows.h and use afxdb.h, you get an error as following:
Linking...
nafxcwd.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in test2.obj
Debug/test2.dll : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
And if you comment out the DLLMain at this point, everything compiles well.
Why does this happen? Can I not have a DLL with a DLLMain which also uses afxdb.h? How do I go about fixing this problem?
thanks
|
|
|
|
|
First, remove the windows.h include, and change it to afxwin.h.
Second, regular MFC DLLs are made completely differently from plain Win32 DLLs. You need a global CWinApp object, and MFC provides the DllMain().
--Mike--
Fetchez la vache!
My really out-of-date homepage
Sonork - 100.10414 AcidHelm
Big fan of Alyson Hannigan and Jamie Salé.
|
|
|
|
|
Hmmm.
Look at this code snippet :-
STDMETHODIMP CNishFirst::GetArray(BSTR **pbstrArray)
{
// TODO: Add your implementation code here
USES_CONVERSION;
BSTR *tmpArray[25];
for(int i=0;i<25;i++)
*tmpArray[i]=SysAllocString(A2W("Nish Test"));
*pbstrArray=*tmpArray;
return S_OK;
}
You'd think it was fine [ignoring that amazing warning I got which I had reported in the previous thread]
But when I tried to test the function using VB I got an error saying that I was attempting to use an OLE Automation feature not supported by VB!
Nish
My most recent CP article :-
A newbie's elementary guide to spawning processes
www.busterboy.org
|
|
|
|
|
Aaah, you're going to love this, Nish.
To pass arrays in Automation, you're going to have to use the dreaded... SAFEARRAY. The old C-style array is not supported. Have fun with SAFEARRAY (I know I do!)
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
Derek Waters wrote:
Aaah, you're going to love this, Nish.
I hope so too
Derek Waters wrote:
To pass arrays in Automation, you're going to have to use the dreaded... SAFEARRAY. The old C-style array is not supported. Have fun with SAFEARRAY (I know I do!)
Hmmm. Safe Arrays!!!
Nish
p.s. This ATL stuff is deeper than I imagined even though I had imagined it to be pretty deep, so you can guess how deep it really is.
My most recent CP article :-
A newbie's elementary guide to spawning processes
www.busterboy.org
|
|
|
|
|
interface INishFirst : IDispatch
{
[id(1), helpstring("method GetString")] HRESULT GetString([in] BSTR* pbstrInString, [out,retval] BSTR* pbstrOutString);
[id(2), helpstring("method GetArray")] HRESULT GetArray([out,retval] BSTR** pbstrArray);
};
It's showing an error :-
warning MIDL2039 : interface does not conform to [oleautomation] attribute : [ Parameter 'pbstrArray' of Procedure 'GetArray' ( Interface 'INishFirst' ) ]
Am I not allowed to have BSTR **s????
My most recent CP article :-
A newbie's elementary guide to spawning processes
www.busterboy.org
|
|
|
|
|
BSTR is already a pointer. So BSTR** is a "triple pointer" (omg! ), which of course is not supported by automation.
From MSDN:
typedef OLECHAR FAR* BSTR;
|
|
|
|
|
You can have BSTR **, so long as you don't want your COM object to be Automation-compatible (ie usable in ASP). The Automation type standard is quite strict on this sort of thing.
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
I might want to add:
- use BSTR for your [in] param
- use BSTR* for your [out] param
Edit: fixed the little bug in my 2nd statement
|
|
|
|
|