|
Most peoples gut reaction to progress bars is something like this...
m_wndProgress.SetRange32(0,500);
m_wndProgress.SetPos(0);
for (int i=0;i<500;++i) {
Sleep(50); // Just to slow this down for demo
/*
do work here
*/
m_wndProgress.SetPos(i);
}
However, if you drop this code into a button click handler in a dialog with a progress bar, you'll notice the dialog becomes unresponsive to any user actions such as closing the dialog.
If processing your work takes enough time to require a progress bar, then it probably should allow the user to cancel or abort the activity. The easiest way to perform some lengthy processing while leaving the GUI thread free to respond to the user is to perform the processing in a separate worker thread. The worker thread then can post messages to the GUI thread to allow it to update the progress bar. This allows the GUI's message loop to process in a normal fashion. When we had the GUI thread performing the work as in the snippet above, message processing for the dialog had to wait for the loop to finish. Unresponsive GUI's are a good recipe for short tempers.
Look up AfxBeginThread() for MFC threading
Not quite pseudocode but I hope it helps get the wheels turning.
|
|
|
|
|
|
I'm incerting the OnKeyDown function to catch keyboard events.. Problem is it never makes it to the function..
void MyDlg::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
{
AfxMessageBox(L"Got a key stroke"); <-- never pops up
CDialog::OnKeyDown( nChar, nRepCnt, nFlags );
return;
}
I've got an OnMouseWheel funtion in that works perfectly.. So I have OnKeyDown set in the same way.. Any Ideas?
|
|
|
|
|
Do you have a WM_KEYDOWN entry in the window class' message map?
The WM_KEYDOWN will go to the window with keyboard focus. In a dialog this may be one of the
controls in the dialog.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
yes I have ON_WM_KEYDOWN() in the message map..
hmmmm.. the function is just not hitting..
|
|
|
|
|
Then the window whos class your catching it in doesn't have keyboard focus.
Try using SetFocus() to set the keyboard focus to the dialog and see if it starts to work.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
I must be overiding the keyboard somewhere because I've used SetFocus(), and my OnMouseWheel works to proove it focus.. Looks like I'll have to hunt for the block..
Thanks Mark..
|
|
|
|
|
I must be overiding the keyboard somewhere because I've used SetFocus(), and my OnMouseWheel works to proove it's focus.. Looks like I'll have to hunt for the block..
Thanks Mark..
|
|
|
|
|
Hmm.. still having trouble with this one...
I've started a whole new dialog that I can open child dialogs within..
OnKeyDown() works until I add an object to the parent dialog or open a child dialog..
I've tried SetFocus() every which way possible.. It's just not happening..
There must be a way...
|
|
|
|
|
There is an extreme push towards .NET, but no clear way to go with traditional MFC application.
Would be interesting opinion of Micrrosoft guru on that.
Just woundering, is there any way to convert MFC application to C# app or C++/CLI (rewrite option is not acceptable)?
And how traditional MFC MDI application have to be migrated/mutated towards .NET?
I'll appreciate any opinions/suggestions.
Thanks.
|
|
|
|
|
To go to C# would be a rewrite - different framework, different language.
C++/CLI is the only language that allows you to mix unmanaged code with managed code.
While this is powerful, it also adds to the complexity. Going back and forth between managed and
unmanaged code is tricky at first - there's a learning curve there.
If you want to hold on to your MFC-based codebase, and still take advantage of the rich .NET
framework, then C++/CLI is the only way to go. From my experience this works well.
My 2 cents.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hello,
I have a dialog with edit fields. and i store the data entered into them into MS SQL. Now, for data validation for CString fields, I use simple tes like
If(str=="")
{
Messagebox(something);
}
but for integer fields, VC++ 6.o automatically gives a message "please enter an integer" ,if the integer field is left blank . I get a first chance exception "0xE06D7363: Microsoft C++ Exception." and a messageBox "Please enter an integer." I guess that is because when I call UpdateData(true), there is no value for DoDataExchange. But Is there any way of disabling this message and allow me to display my own message as my application starts behaving unexpectedly after it encounters this exception. Also Could you tell me how to catch this exception thrown because of UpdateData. I could not catch it with normal CExeption * e.
Please help.
|
|
|
|
|
CException only covers MFC exceptions.
If your exception is a C++ exception, you should catch the appropriate exception class or type.
If your unsure what exception class or type could be "thrown" in a particular context, then it would be advisable to research "exception handling" in MSDN as their are different types that you should get familiar with.
If you are in a hurry, you can catch "(...)" which will get just about anything, but this will possibly be frowned upon by some in the community since you basically lose the exception context and basically defeat the exception mechanism. Using "(...)" essentially turns exception handling into an overpriced "goto". To be fair, there are likely some in the community that feel "(...)" is ok to use and even handy. I find myself sitting on the fence with this one.
If the exceptional condition is avoidable, it might be better to locate where it's getting thrown, and prevent the condition in the first place. It just depends on the exception context since some exceptions are, by design, unavoidable, real world, common occurences like file and database exceptions. Some just shouldn't happen like divide by zero and memory access violations These usually indicate flawed logic and should be removed/rethought/redesigned instead of wrapping in a try/catch.
Thats just my 2 cents.
|
|
|
|
|
I'm having a problem with a class I wrote- the destructor isn't being called for some reason and I'm getting a rather large memory leak as a result. I verified that the destructor was not being called through the use of breakpoints. Any help would be appreciated.
Here is the class defenition:
class CCharLinkedList
{
public:
CCharLinkedList();
~CCharLinkedList();
void AddNodeToHead(char DataToAdd[]);
void AddNodeToTail(char DataToAdd[]);
bool DeleteFromHead();
bool DeleteFromTail();
bool CopyFromHead(char DataToCopy[]);
bool CopyFromTail(char DataToCopy[]);
void PrintHeadToTail();
void PrintTailToHead();
protected:
private:
void DeleteList();
CharLinkedListNodeType* HeadPtr;
CharLinkedListNodeType* TailPtr;
};
The destructor implementation:
CCharLinkedList::~CCharLinkedList()
{
DeleteList();
HeadPtr = NULL;
TailPtr = NULL;
}
DeleteList():
void CCharLinkedList::DeleteList()
{
CharLinkedListNodeType* IterationPtr = HeadPtr;
CharLinkedListNodeType* DeletePtr = NULL;
while(IterationPtr != NULL)
{
DeletePtr = IterationPtr;
IterationPtr = IterationPtr->ForwardPtr;
delete DeletePtr;
}
}
The class is declared in the free store in another class header file. The other class has been working fine for a long time. So far I have been able to use the linked list to add nodes, but when it is time to call the destructor upon exiting and delete all the nodes, nothing happens.
|
|
|
|
|
You've shown the code for the class but it's irrelevent to the problem.
What's important is the creation and destruction of the CCharLinkedList object(s).
Are they created/destroyed with new/delete?
Are they member variables in another class? If so, when does the object of THAT class get deleted
or go out of scope?
etc...
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
I only have one CCharLinkedList object. It is allocated on the free store (not new/delete), here:
class CRatiosWin : public CFrameWnd
{
public:
CRatiosWin();
~CRatiosWin();
CRatiosLogic RatiosLogic;
bool GetNewFilePath(CString & Path);
void PrintResults(string results);
bool ReturnValidFilePathSet();
void ResetSearchDialogFlag();
void SetDatabaseFilePathStatus(bool FilePathWasSet);
void SetTimeParameterStatus(bool NewTimeParametersWereSet);
protected:
private:
CRatiosNewSearchDialog NewSearchDialog;
CRatiosSearchTimeParameters TimeParametersDialog;
CCharLinkedList TestLinkedList; :(
CEdit ResultsBox;
BOOL NewSearchDialogIsVisible;
bool ValidFilePathSet;
bool TimeParametersWereSet;
afx_msg void OnClose();
afx_msg void OnOpenFile();
afx_msg void OnNewSearch();
afx_msg void OnOpenSearch();
afx_msg void OnAbout();
afx_msg void OnTestList();
DECLARE_MESSAGE_MAP()
};
I loaded some text into the list by calling this at runtime:
afx_msg void CRatiosWin::OnTestList()
{
fstream ListFileStream;
char chLine[MAXNUMCHARS_LINKLISTNODE];
string strLine = "";
ListFileStream.open("list_test.txt");
while(ListFileStream.eof() == false)
{
getline(ListFileStream, strLine);
ASSERT(strLine.length() < MAXNUMCHARS_LINKLISTNODE);
strcpy(chLine, strLine.c_str());
TestLinkedList.AddNodeToTail(chLine);
}
MessageBox("Sent to file.", "Boink", MB_OK);
ListFileStream.close();
}
All of the above worked fine. But I set breakpoints in the destructor in the previous post and none of them were reached, plus I have a big memory leak.
|
|
|
|
|
Cool thanks. In that case you need to look at when the CRatiosWin object is destroyed.
It is then that the CCharLinkedList member object will be destroyed.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Can I assume that CRatiosWin is not getting deleted in this segment of code?
class CPRatiosApp : public CWinApp
{
public:
BOOL InitInstance()
{
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
m_pMainWnd = new CRatiosWin;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
m_pMainWnd->SetWindowText("Ratios v0.1b");
m_pMainWnd->MoveWindow(0,0,800,600);
return TRUE;
}
} CRatiosApp;
|
|
|
|
|
CoffeeAddict19 wrote: Can I assume that CRatiosWin is not getting deleted in this segment of code?
Yes...correct.
I can't find where m_pMainWnd is destroyed in the MFC source...When I find it I'll post.
Try adding this override to your CPRatiosApp class:
virtual int ExitInstance()
{
if (m_pMainWnd)
{
m_pMainWnd->DestroyWindow();
m_pMainWnd = 0;
}
return CWinApp::ExitInstance();
}
Your destructor should be called when the m_pMainWnd->DestroyWindow(); is executed.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Ok....after reviewing MFC source -
Your destructors should get called when you close the main window (since frame windows are self-
deleting). I found no place where the app classes destroy the main window explicitly.
The ExitInstance() code I posted won't help. You'll need to close the main window before a
breakpoint in your destuctor will be called
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
When I learned to program we had to write stuff like this – why are you? You should be using the ‘list’ template.
Some of the modern MS languages allow you to ignore the fact that if you use ‘new’ you need to supply a ‘delete’, may be that is the problem. Any thing you allocate you need to deallocate – even in C++.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
Hello you wise people out there,
how can I log off a user on Windows NT, XP, Vista platform from a Windows Service?
Do I have to impersonate the user and send a certain message or can I use ExitWindowsEx(0,0)? Which privileges does the Service need?
Thanks for your help
I'm just a beginner longing for wisdom
|
|
|
|
|
Hi
I have 3 dailog boxes(Dlg1,Dlg2,Dlg3) which create a fourth dialog box which is called ChildDlg.How can I understand which one is the parent of the ChildDlg? I tried that;
ChildDlg::Something()
{
Dlg1 *dlg = (Dlg1*)GetParent();
if(Dlg1 is not the parent)
{
delete dlg;
Dlg2 *dlg = (Dlg2*)GetParent();
if(Dlg2 is not the parent)
{
Delete dlg;
Dlg3 *dlg = (Dlg3*)GetParent();
}
}
(After that part of the code I am using dlg as the object of the parent.)
)
I have many methods like this method which I should know which one is the parent.Where is the mistake in this method.It doesn't work.I know I asked a question similar to this one but still I have problems about that subject.
Thanks
|
|
|
|
|
Exactly what is it that you are trying to do?
Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
|
|
|
|
|
why don't you just pass the parent pointer to the ChildDlg when it's created and check the GetParent against that pointer ?
|
|
|
|