|
1. How they can call a type(class name) CObject.
As long an object is an instance of a class,
How they can call a class 'CObject' ???
2. Extreme encapsulation!!!
-I've seen this in MFC/ATL implementations:
If they have C++ classes usually they make data members
private and provides public functions for access
Them as read/write (Set***(), Get***), so instead writing
obj.member=5; you write obj.SetMemebr(5); and
type t = obj.member; you write type t = obj.GetMember().
-On the other hand when you use some COM components type libraries
By default (!raw_interfaces_only) they wrap the ccom_ptr
In the *.tli generated files around the interfaces 'transforming'
The interface method calls (__declspace(propput=)...)
po->SetVar(type) into po->_var=type; which is the other way around.
So finally the cool thing is when we have the possibility of right member access we wrap function calls and when we have function calls
We wrap direct member access call. Isn’t this weird?
|
|
|
|
|
( is it a rant or a question ? )
suiram40 wrote:
1. How they can call a type(class name) CObject.
Why not ? I can call my base class CPotato if you want ...
suiram40 wrote:
2. Extreme encapsulation!!!
for the first part, Yeah, this is the way to do OO programming ( IMHO ), to privatize data members, and have setters and getters.
why ? because it's safer. clearer.
if for some reason, you decide to change the name of the variable; you will need to change it everywhere, with getter/setters, you only change the class.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
Maximilien wrote:
I can call my base class CPotato if you want ...
Yes, but would it be able to handle ketchup (for frenched fries), or butter (for mashed)? I like both styles so these accommodations are a requirement!!
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
|
'CPotato' and any other specific category is right fine, but CObject ???
|
|
|
|
|
suiram40 wrote:
but CObject ???
Why not CObject ? It is the least common denominator.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
For point two:
Imagine a simple circle class. You have setters and getters for Area, Radius, and Diameter. Simple grade school math gives the relation between them. Now which are you going to store in your class? If you use setters and getters it doesn't matter because you can change it at anytime without anyone else being affected. (and a good compiler will inline them so there isn't overhead)
Think it doesn't matter? Say you pick area. Well I'm going to use your class, but after a profiler I've discovered that getting the diameter is taking a large part of the CPU time, and the system is too slow. A simple change to the class to store diameter will speed things dramaticly. Of course if you anticipated area being most needed, then area would be right. (even though square roots are slower than powers in general)
Of course the example I gave is contrived. You should get the idea though. In the real world it often turns out that you don't know in advance what you will need to change latter so you use getters and setters everywhere just in case. 95% or more of the time you will never change it, but overall you have saved yourself a lot of work with the getters and setters.
|
|
|
|
|
<snip>
1. How they can call a type(class name) CObject.
As long an object is an instance of a class,
How they can call a class 'CObject' ???
The idea is that all objects in MFC are based on it ... much as object in Java and C#
<snip>
2. Extreme encapsulation!!!
-I've seen this in MFC/ATL implementations:
If they have C++ classes usually they make data members
private and provides public functions for access
Them as read/write (Set***(), Get***), so instead writing
obj.member=5; you write obj.SetMemebr(5); and
type t = obj.member; you write type t = obj.GetMember().
-On the other hand when you use some COM components type libraries
By default (!raw_interfaces_only) they wrap the ccom_ptr
In the *.tli generated files around the interfaces 'transforming'
The interface method calls (__declspace(propput=)...)
po->SetVar(type) into po->_var=type; which is the other way around.
So finally the cool thing is when we have the possibility of right member access we wrap function calls and when we have function calls
We wrap direct member access call. Isn’t this weird?
As others have said its good style to have setters and getters, especially for setters ... Maybe you want a member to be restricted to 1..100 .. How would you do that otherwise ?
Maybe you have a member that constantly needs to be refreshed ... say the exchange rate for Euros to US Dollars. Just returning the current value stored would do no good, and constantly updating the value may be inefficent ... so just make sure you have the current value when you need it.
This is dealt with in other languages via properties ... getters and setters kinda hidden in the syntax.
|
|
|
|
|
CObject is a pure virtual class, the base for all MFC classes... which name would you prefer ???
TOXCCT >>> GEII power
|
|
|
|
|
I am writing a game which will write the players statistics to a file to read later if the player wants to continue.What I need to know is how to do it.Thanks for your time reading this.Please reply if you know.
kyle
|
|
|
|
|
Several options:
fopen family (Ansi C)
CFile (MFC)
ofstream
...
Papa
while (TRUE)
Papa.WillLove ( Bebe ) ;
|
|
|
|
|
To expand on what Papa said - you can pretty much use any file writing class. If you "own" all the code to read/write it, you can pick any format you want, but IMHO text files are the easiest. Debugging code that reads/writes text files is pretty easy, because you can just open your files with Notepad or something and see if everything got written correctly.
If you really want to get fancy, you could get yourself an XML parser and read/write your files in XML. This is good for categorized or hierarchical data.
Quickie example:
#include <fstream>
#include <iostream>
void WriteFile(const char *fileName)
{
std::ofstream outputFile(fileName);
outputFile << "This is some text." << std::endl;
outputFile << "This is some MORE text!!" << std::endl;
double bob = 4.5;
outputFile << bob << std::endl;
outputFile.close();
}
void ReadFile(const char *fileName)
{
std::ifstream inputFile(fileName);
char str1[100];
char str2[100];
inputFile.getline(str1, 100);
inputFile.getline(str2, 100);
double dbl;
inputFile >> dbl;
std::cout >> "Line 1: " >> str1 >> std::endl;
std::cout >> "Line 2: " >> str2 >> std::endl;
std::cout >> "Line 3: " >> dbl >> std::endl;
}
void main()
{
WriteFile("C:\\test.txt");
ReadFile("C:\\test.txt");
}
"Fish and guests stink in three days." - Benjamin Franlkin
|
|
|
|
|
Here how I want to apply.
When the user clicked on run button, application call the function, f1, that does something like reading array and changing something one index by a time. When the job of array index is done, it post the message to go to next job. Another function, f2, was waiting for the message to do its job. As soon as f2 gets the message from f1, it starts its job.
Meanwhile, the user clicked on Stop then immediately the application stop whatever he doing. the the thread coming from.
Hornestly, I have an idea of it.. but not clear and don't really know how to do it.
How to send messages within an application?
Should I use wm_app or wm_user? What if an application has thread in it?
Should I use postmessage() to send message and getmessage to read the message?
Thank you
|
|
|
|
|
Anonymous wrote:
How to send messages within an application?
By using the SendMessage() function.
Anonymous wrote:
Should I use wm_app or wm_user?
Of the two, WM_APP is preferred. However, a unique registered message is even better.
Anonymous wrote:
Should I use postmessage() to send message and getmessage to read the message?
It depends on if you want the message to reside in the application's queue or not. SendMessage() sends a message to another window immediately by calling that window's procedure and waiting for it to return, whereas PostMessage() queues the message and returns immediately. With SendMessage() , the receiving app processes the message immediately, rather than at some later time, by fetching it from its queue. With PostMessage() , the thread or application processes the message when it gets around to it. That is, when its main dispatch loop calls GetMessage() .
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
Thannk you David for answering my question in detail.
I'm new in sending message and reading it.
I only have one dlg ( window). I think I should give you more detail about my program.
My program is dialog based program, which has 3 buttons, print, stop, and exit on it.
When user clicked on print, the thread gets created. the thread is keeping checking whether the global boolean variable stopPrinting = true. ( stopPrinting is set to TRUE when the user clicked on Stop button)
<br />
UINT PrintingThreadFunction(LPVOID lParam)<br />
{<br />
myApp *dlg = (myApp*)lParam;<br />
while(!stopPrinting) <br />
{<br />
dlg->printafile();<br />
}<br />
}<br />
the file sent to the printer and printer send the message "END_DOC" to application back. To catch the message sent from printer, I used RegisterWindowMessage() first and add the following code to messgae map
BEGIN_MESSAGE_MAP(CSMPClientDlg, CDialog)<br />
ON_WM_SYSCOMMAND()<br />
ON_WM_PAINT()<br />
ON_WM_QUERYDRAGICON()<br />
ON_BN_CLICKED(IDC_PRINT, OnBnClickedPrint)<br />
ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel)<br />
ON_BN_CLICKED(IDC_STOP_PRINT, OnBnClickedStopPrint)<br />
<font color = green> ON_REGISTERED_MESSAGE(BlackIcePrintMessage,OnPrinterMsg)</font><br />
END_MESSAGE_MAP()
I want my applicaton to just listen to or waiting for the message from printer to comes and do nothing. Then when the application got the message END_DOC, send the message, PRINT_NEXT_FILE or wake application up so it can move on next one. At the same time, if the user clicked on Stop button, application should drop whatever its doing.
LRESULT myApp::OnPrinterMsg(WPARAM wParam, LPARAM lParam )
{
...
..
if(wParam == END_DOC)
//send the message PRINT_NEXT_FILE
}
thank you
|
|
|
|
|
This is how I create the thread
void myApp::OnPrint()
{
CWinThread *printingThread;
printingThread = AfxBeginThread(PrintingThreadFunction,this);
}
|
|
|
|
|
I'm sorry David.
When you say unique registered message is even better means
use RegisterWindowMessage()?
|
|
|
|
|
Anonymous wrote:
When you say unique registered message is even better means
use RegisterWindowMessage()?
That would be the one!
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
But isn't it for sending messages between applications?
I already used it which is catching Messages from Printer without really knowing it.
How am I going to let my application stop and wait for the message to coming in.. actually application is just talking to itself.
I got confused, let me clearify and see I'm right.
1) create the thread using AfxThreadBegin() when Print button is clicked. So entire GUI is still alive and user can still click on either Stop or Exit button.
2)Print the file, and wait for the message from printer. Now I'm using global bool variables stopPrinting and printNextfile to stop.
<br />
UINT theThread(...)<br />
{<br />
while(!stopPrinting) <br />
{<br />
if(printNextfile)<br />
PrintNextFile();<br />
else if(stopPrinting)<br />
break;<br />
}<br />
}<br />
it is working fine. the program is doing what I want it to do but I dont' really like it coz it takes so much of CPU time. and Dont' really know to improve it
The solution I guess was take out while loop and why dont'I just respond to message. but how to?
Using RegisterWindowMessage and SendMessage() functions will help?
if(END_DOC)
SendMessage(PRINT_NEXT_FILE);
OnPrintNextFile()
{
printNextfile();
}
So how am I going to stop or respond to Stop Button was clicked?
thanks
|
|
|
|
|
Anonymous wrote:
But isn't it for sending messages between applications?
It can also be used within the same application, whether one window is sending a message to itself, or one window is sending a message to another window. As long as you have the target window's handle, it makes no difference that it belongs to another application.
Anonymous wrote:
1) create the thread using AfxThreadBegin() when Print button is clicked. So entire GUI is still alive and user can still click on either Stop or Exit button.
So far, so good.
Anonymous wrote:
2)Print the file, and wait for the message from printer.
How does the printer signal that it is done printing?
BTW, why don't you register? It's much easier to communicate, and it's free!
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
The printer send message like window message.
here what I did
1) BlackIcePrintMessage = RegisterWindowMessage(szREGISTERMESSAGE);
where szREGISTERMESSAGE = "colorPrinter"
2)
BEGIN_MESSAGE_MAP(myApp, CDialog)
ON_REGISTERED_MESSAGE(BlackIcePrintMessage,OnPrinterMsg)
END_MESSAGE_MAP()
3)
LRESULT CSMPClientDlg::OnPrinterMsg(WPARAM wParam, LPARAM lParam )
{
..
..
}
I was using above methods without really understanding it.. I read about it but still get confused. So how can application send the message to itself using the same 3 steps?
My big question ( the most still confused) is a thread... Am I still use the infinate loop inside the thread function and watch or wait for the message coming in. or how?
|
|
|
|
|
Anonymous wrote:
So how can application send the message to itself using the same 3 steps?
It matters not to SendMessage() and PostMessage() of the origin of the message (i.e., registered or some arbitrary number like WM_APP + 5 ). Consider:
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
ON_REGISTERED_MESSAGE(BlackIcePrintMessage, OnPrinterMsg)
END_MESSAGE_MAP()
LRESULT CMyDialog::OnPrinterMsg( WPARAM, LPARAM )
{
AfxMessageBox("The printer has finished doing whatever it was doing!");
}
UINT ThreadProc( LPVOID pParam )
{
HWND hWnd = *((HWND *) pParam);
PostMessage(hWnd, BlackIcePrintMessage, 0, 0);
return 0;
}
void CMyDialog::OnPrint()
{
HWND hWnd = GetSafeHwnd();
AfxBeginThread(ThreadProc, &hWnd);
}
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
Thank you very much Dave
I think I understand and let me try it.
thank you again for taking time to explain it patiently.
|
|
|
|
|
Hi pals,
I am facing a difficulty with CDC across threads.
Actually, i spawn a secondary thread to calculate the display coordinates of the strings. So i am calculating the height and width of the strings based on the font selected in the CDC. It works fine with the scroll view but the calculation goes wrong with the PrintPreview. Bcos ,SelectObject(pMyFont) is always returning NULL.
How do i solve this problem.
Help me out friends. Thanks in advance.
Kumari
|
|
|
|
|
MFC objects do not operate well across threads. There are some Knowledge base articles on MSDN that explain why. Basically they use thread local storage to map the resource handle to the C++ object pointer. So in another thread the mapping does not exist.
So always pass the resource HANDLE rather than an MFC C++ class pointer across threads. then if you want to use MFC classes in the thread you can attach the HANDLE to a thread local scope MFC object.
"No matter where you go, there your are." - Buckaroo Banzai
-pete
|
|
|
|