|
There are several options: one way would be to provide a static Create function within the base class, another would be to delegate that to an external factory class which does only instanciate the class.
I tend to prefer the second option because in the first, you include too much "knowledge" in the base class (it shouldn't know which classes inherits from itself).
|
|
|
|
|
Does it make sense, from an OO design point of view to have such a hierarchy of classes ?
I'm no expert, but I wondering what functionalities a small, medium or large buildings would be
different ?
This signature was proudly tested on animals.
|
|
|
|
|
The buildings theme was simply a demonstration - there are cases in which this arises.
|
|
|
|
|
Hi
I need a timer that doesn't rely on windows.
I need something like:
StartTimer()
CallBack MyJob()
StopTimer()
where MyJob() keeps running every few seconds as controlled by the timer but stops if something calls StopTimer().
I tried using CWnd::SetTimer() (and CWnd::KillTimer()):
int j = 1;<br />
<br />
void CMyClass::StartTimer()<br />
{<br />
CWnd::SetTimer(NULL, 0, 1000, (TIMERPROC) MyFunc);<br />
while(j)<br />
{<br />
MSG msg;<br />
GetMessage(&msg, NULL, 0, 0);<br />
DisplatchMessage(&msg);<br />
}<br />
}<br />
<br />
void CALLBACK CMyClass:MyFunc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)<br />
{<br />
DoJob();<br />
--j;<br />
}<br />
<br />
void CMyClass:DoJob()<br />
{<br />
int iN = 0;<br />
}<br />
<br />
void CMyClass::StopTimer()<br />
{<br />
CWnd::KillTimer(NULL, 0);<br />
}<br />
but this means DoJob() only runs once, as the CallBack stops the while loop that dispatches the message. If I don't change j, the program gets stuck runngin DoJob forever, obviously, and the client never gets a chance to call StopTimer().
How do I solve this problem?
Thanks in advance.
|
|
|
|
|
Then you have to rely on WaitForSingleObject.
SetEvent will do the trick for you.
Please refer msdn for more info
Величие не Бога может быть недооценена.
|
|
|
|
|
|
Kiriko wrote: If I don't change j, the program gets stuck runngin DoJob forever, obviously, and the client never gets a chance to call StopTimer().
This is because your implementation of
Kiriko wrote: while(j)
{
MSG msg;
GetMessage(&msg, NULL, 0, 0);
DisplatchMessage(&msg);
}
is wrong. That means GetMessage will wait for getting message and the while loop is running for infinite time.
Btw, I feel you're trying to implement something simple as complicated.
I prefer you try for thread. And the thread function would be something like,
ThreadProc(...)
{
while( j )
{
DoJob();
Sleep( 1000 );
}
}
Usage of events will be better for stopping the thread.
- ns ami -
|
|
|
|
|
Please read my article at IPTECH-OFFSHORE blog. It's in french but the source code you can download might be enough expressive :
http://www.iptech-offshore.net/blog/?p=58[^]
Easy Profiler : a compile-time profiler for C++
www.potatosoftware.com
|
|
|
|
|
Create a extra thread which does the job. WaitForSingleObject() will helo by waiting and also exiting the thread.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
I am currently cross-training to VC++ and I could do with some help if somebody has the time please.
I know this is simple but I just can't get it.
I am using vc++ in VS6. As an exercise, I am building an app with 4 forms. The main form has 3 buttons - btn1, btn2 and btn3 (labelled 'Standard Calculator', 'Math Calculator' and 'Share Calculator' respectively). When a user clicks on a button, I want to display the relevant calculator (form). When the user closes a calculator by clicking the 'Close' button, I want to re-display the main form.
I have built the app in VS6 as a Dialog-based Document but I don't know how to display the secondary forms (the calculators). Should I have used an SDI with multiple forms? I have RTFM (plenty of manuals in fact) but I just can't get it. If I had any hair, I would pull it out.
All help, direction or link will be most appreciated.
RaymondBear
|
|
|
|
|
Using SDI will be a option.
Otherwise you have use more than one dialog.
When you click standard calculator, then you can show the Standard Calc Dialog and hide the normal calc dialog, similarly vice versa.
Величие не Бога может быть недооценена.
modified on Thursday, August 20, 2009 5:26 AM
|
|
|
|
|
Thanks for the response ARJ 09.
The following thread from Cedric Moonen is closer to what I am trying to do.
Any input from you is much appreciated.
I just want control to pass between dialogs. From the main frame to a calculator and back again
but I don't know where to put the code.
RaymondBear
|
|
|
|
|
I guess by "forms" you are talking about a dialog, right ? It is a bit confusing because, in general, the term "forms" relate to managed C++ or C# (AFAIK). If you are 100% that you are doing pure C++ (well, with VC6 I guess that will be the case), then you have to create a new dialog and open that dialog.
To do so, create a new dialog resource in your resource files and open the class wizard. When doing so, it will ask you if you want to create a new class to associate with the resource and you have to say yes.
You can then use this new dialog class in your code and open the dialog by calling the DoModal() method.
You might want to look for more information by googling for dialog and MFC.
EDIT: by the way, choosing between an SDI app or a dialog based app really depends on what you want to do. If you want your calculator top open in a new window (new dialog), and you don't have something like data to be saved (the 'document'), the it is better to stick to a dialog based application because it is easier and you won't need all the stuff provided by an SDI app.
|
|
|
|
|
Thanks Cédric. I appreciate your help.
It is the 'and open the dialog by calling the DoModal() method.' part that I am having trouble with.
This is part of the generated code from my main dialog.
CBearsCalcsDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
/////////////////////////////////////////////////////////////////
I'm guessing that in here I need code that reads something like -
if (btn1 = True)
display form2
elseif (btn2 = True)
display form3
elseif (btn3 = True)
display form4
//////////////////////////////////////////////////////////////////
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
RaymondBear
|
|
|
|
|
auitsrxc wrote: It is the 'and open the dialog by calling the DoModal() method.' part that I am having trouble with.
If you followed the previous step, you should have a new class created in your project. When you want to open the dialog, simply create an instance of the class and call DoModal:
CMyNewDialog newDialog;<br />
newDialog.DoModal();
Of course, you need to have the class which has been created by the class wizard. Don't forget to include the header file of the class.
|
|
|
|
|
Thanks Cédric.
It is 22:30 here (Sydney) and I have been cutting mainframe code all day.
I will start a new app tomorrow and follow your advice. I know that one day the penny will drop
and this will all fall into place. It is just not today.
Thanks again.
RaymondBear
|
|
|
|
|
Me again Cédric.
The answer for me lies in the use of the DoModal() function. I have been chasing this problem from the wrong end. I have been searching on multiple forms/documents when I should have been looking for DoModal examples.
I think I will be Ok now so thanks again.
Regards,
Raymond
RaymondBear
|
|
|
|
|
I'm stuck in VC6 with not being able to have a 'Condition' on my string table.
Our main product and a 'light' version are built from the same project with a different build configuration.
They share toolbar button IDs (same tools, but fewer in light), but I'd like to change the associated string table entries in the light version.
e.g., a given tool ID might have string resource
"My main tool\nMain Tool"
whereas in the light version I might want it to say
"My tool\nTool"
I've though of some approaches:
1) Edit the compiled binary resources - works, but I have to remember to do it everytime / its quite tedious.
2) Try to do something with UpdateResource, but I'm failing to get that to work - can you use it to edit your own resources?
3) Have a separate set of tool IDs for the light version (not eminently maintainable).
Is there really no elegant way to do this?
modified on Wednesday, August 19, 2009 11:24 PM
|
|
|
|
|
you can use a resource dll. http://msdn.microsoft.com/de-de/library/d8ws31ff(VS.80).aspx
I have done this many times for other languages.
Tip: the "light" resources belonging in the exe module, and the "full" in the dll. And the dll gets shipped with the full version.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
Thanks for the suggestion - but for the sake of the five or six strings I need to modify, having a whole different copy of the resources seems like overkill - especially since they'd need to be kept in sync.
The simplest way is probably to just use different button IDs in the light version and duplicate the code linking them up to the same functions as in the full version.
It feels a bit ugly, but might be the best.
|
|
|
|
|
That is a fine solution. Include different toolbars and decide before loading which will get included.
I had a similar problem a while ago. I made a toolbar with all buttons and deleted the not needed at startup. In your case you need too have two buttons for the same command ID_CMD1_RELEASE and ID_CMD1_DEMO.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
OK, I've mostly solved this programmatically!
I overrode OnSetMessageString (WM_SETMESSAGESTRING) and OnToolTipNotification (TTN_NEEDTEXT) in CMainFrame and replaced the string IDs of the relevant tools with equivalent light versions based on conditional compiler directives.
It still uses the 'wrong' string in the light version toolbar customisation dialog, but that is part of a 3rd party framework. I can live with that anyway.
I'm happy now!
|
|
|
|
|
Hello,
I tried set the wallpaper with tis code:
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, pp,SPIF_UPDATEINIFILE);
but got some errors:
stdafx.obj : error LNK2028: unresolved token (0A000323) "extern "C" int __stdcall SystemParametersInfoW(unsigned int,unsigned int,void *,unsigned int)" (?SystemParametersInfoW@@$$J216YGHIIPAXI@Z) referenced in function "private: void __clrcall Autorun::kepek::toolStripMenuItem5_Click(class System::Object ^,class System::EventArgs ^)" (?toolStripMenuItem5_Click@kepek@Autorun@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>Autorun.obj : error LNK2028: unresolved token (0A00001E) "extern "C" int __stdcall SystemParametersInfoW(unsigned int,unsigned int,void *,unsigned int)" (?SystemParametersInfoW@@$$J216YGHIIPAXI@Z) referenced in function "private: void __clrcall Autorun::kepek::toolStripMenuItem5_Click(class System::Object ^,class System::EventArgs ^)" (?toolStripMenuItem5_Click@kepek@Autorun@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>Autorun.obj : error LNK2019: unresolved external symbol "extern "C" int __stdcall SystemParametersInfoW(unsigned int,unsigned int,void *,unsigned int)" (?SystemParametersInfoW@@$$J216YGHIIPAXI@Z) referenced in function "private: void __clrcall Autorun::kepek::toolStripMenuItem5_Click(class System::Object ^,class System::EventArgs ^)" (?toolStripMenuItem5_Click@kepek@Autorun@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)
1>stdafx.obj : error LNK2001: unresolved external symbol "extern "C" int __stdcall SystemParametersInfoW(unsigned int,unsigned int,void *,unsigned int)" (?SystemParametersInfoW@@$$J216YGHIIPAXI@Z)
1>C:\Visual Studio 2008\Projects\Autorun\Debug\Autorun.exe : fatal error LNK1120: 3 unresolved externals
and also tried with #include <shlobj.h>,->36 error.
Please help,what's wrong ?
Thanks for the Help !
|
|
|
|
|
What type of project are you using?
#include is for the compiler.
You are getting a linker error.
Try adding user32.lib in you project properties at
Project Properties -> Configuration Properties -> Linker -> Input -> Additional Dependencies .
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
A small addition to the suggestion by Superman.
Please include Windows.h as well.
|
|
|
|