|
Hi, someone has PM'med me but I can't sent a reply, so i will answer here.
Barry wrote: I have a situation where I have a user interface thread that is opening a dialog with a progress dialog that is used to show progress on processing going on in the parent thread. The underlying dialog is wrapped in a thread-safe class so messages to the dialog are handled properly. When processing in the parent thread is complete the dialog is gracefully shut down. If the dialog is being moved around when the parent thread tries to shut the thread down by posting a WM_QUIT method to the thread, the ExitInstance method in the CWinThread-derived class used to handle the thread never gets invoked and the thread remains active. I also tried to add a user-defined message with a message handler but the message handler never got invoked when the parent thread sent the message to the thread. Any clues?
I have created a simular test version an can confirm the same error.
I have browsed to the MFC source and have found the problem I have found a solution probably on of the worst in oo design but what the heck if even MFC isn't working like it should
First let me explain what happens.
I have a DLG(main) application wich creates a thread. This thread creates a Modless dlg and closes it on exiting the thread.
The main applaction sends a m_pCloseThread->PostThreadMessage(WM_QUIT,0,0);
To let the thread exit.
This works like intended as long as the dlg in the thread doesn't get moved.
The normal WM_QUIT is getting processed in CWinthread::Run function
...
if (!PumpMessage())
return ExitInstance();
..
But when you move over the window with you mouse the messages of your movement should be redirected to the Message loop of the dialog.
If you click and hold down the left mouse button (in order to drag, but not nessacary) the full message handling is done by the DLG message loop. The thread message loop never gets called any more until you leave the mousebutton. The posted WM_QUIT message isn't processed by the thread message loop (let me call this the parent loop) but by another loop, this loop (child) probably see that the message isn't for him and neglects it.
The parent loop doesn't know anything of that message. I believe it’s a design flaw in the MFC, but this is just my 2 cents :P
I hope that I explained it correctly.
But how do we solve this Design-flaw: Like I said before I have done it Quick and dirty.
1. I've added a Boolean member in the dialog to notify the thread that There was a WM_QUIT sent
2. In the dialog I need to capture a WM_QUIT message. This is done by overriding the WindowProc function (child loop)
LRESULT CClosingInfo::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_QUIT)
{
m_bOopsImDead = true;
}
return CDialog::WindowProc(message, wParam, lParam);
}
3. I also need to override the thread loop (parent) which is in the CWinthread::run function.
The code inside the function can be found in the thrdcore.cpp file of the MFC source codes
int CCloseTrhread::Run()
{
ASSERT_VALID(this);
_AFX_THREAD_STATE* pState = AfxGetThreadState();
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
for (;; )
{
while (bIdle &&
!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
{
if (!OnIdle(lIdleCount++))
bIdle = FALSE;
}
do
{
if (!PumpMessage())
return ExitInstance();
if (IsIdleMessage(&(pState->m_msgCur)))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));
if(m_pCloseWindow->m_bOopsImDead)
{
return ExitInstance();
}
}
}
4. Now instead of calling the thread to close, call the dlg
<code>m_pCloseThread->m_pCloseWindow->PostMessage(WM_QUIT, 0 ,0);
This works also when no one is dragging or holding the dialog.
Hope that this helps, or at least sets you on its way.
Let me know
Kurt Pattyn
codito ergo sum
-- modified at 18:52 Thursday 25th May, 2006
|
|
|
|
|
Thank you friends!
Specially BadKarma! You solved my problem.
We Believe in Excellence
-- modified at 23:34 Friday 17th February, 2006
|
|
|
|
|
Aqueel wrote: I am using CWinThread for threading in MFC. I want to terminate a thread from another function not in the thread function itself. Can i do that?
http://www.flounder.com/workerthreads.htm
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
|
|
|
|
|
pDC->GetSafeHdc(); It will return a pointer to the existing memory or allocate the memory and then return the pointer to this allocated memory.
OR
how i can release this memory
|
|
|
|
|
GetSafeHdc() does not return a pointer. It returns the handle of the device context - you don't need to "release" it.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
It returns a handle to an exiting HDC or NULL. If you single step through the code you will see that calling GetSafeHdc() is equivalent to return(hdc?hdc:NULL), which is kind of silly if you ask me. Because if the test codition faile "hdc?" then the hdc is already equivalent to NULL. The long and the short of it is that GetSafeHdc() does not allocate any memory, it just makes sure that the HDC returned is either valid or NULL.
INTP
Every thing is relative...
|
|
|
|
|
anilksingh wrote: pDC->GetSafeHdc();
just return the reference to selected DC.. the CDC it self manage life cycle of the HDC object.. so you don't need to worry about it.
Secondly you can use DeleteDC api to delete DC
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
|
|
|
|
|
Hi All.
I want to write some code that have some method that in create bitmap of the current screen.
What i mean is when this method is call - there will be create file in name X.bmp that contain the info of the screen ( line pressing on PrtScn button ).
How can i catch the picture ? what windows method (maybe API function) i need to use ?
|
|
|
|
|
You may want to look up PrintWindow and WM_PRINT . There are many other techniques, which you choose depends on what OSs you need to support.
Steve
|
|
|
|
|
I will not explane how it is done, but I suggest searching using the keywords "screen capture". There are lots of Web articles on the subject, and there is probably still a code sample in the MSDN somewhere (the origanal example is probably 15 years old now). I believe there are a few articles at CP on the subject.
INTP
Every thing is relative...
|
|
|
|
|
|
#import "msxml3.dll" rename_namespace ("NEW_MSXML2")<br />
using namespace NEW_MSXML2; <br />
#import "MSSOAP30.dll" exclude("IStream", "ISequentialStream", "_LARGE_INTEGER", "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME") rename_namespace ("NEW_MSSOAPLib30")<br />
using namespace NEW_MSSOAPLib30;
In Debug mode, it creates MSSOAP30.tli and MSSOAP30.tlh files which has NEW_MSXML2 parameter,but in Release mode those two files are getting created with MSXML2 parameter.
Any Idea whats happening?
cheers,
Super
------------------------------------------
Too much of good is bad,mix some evil in it
|
|
|
|
|
super wrote: In Debug mode, it creates MSSOAP30.tli and MSSOAP30.tlh files which has NEW_MSXML2 parameter,but in Release mode those two files are getting created with MSXML2 parameter.
Better post this problem in Microsoft newsgroup!
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
|
|
|
|
|
What if it is some sort of preprocessor issue. I think using the "NEW_" in your new name space name could be causing a problem.
If you called it the "123123_" namespace instead, does that work?
I have seen DUMBER issues than this with preprocessors before. I am leary of calling ANYTHING "NEW" these days, since that seems to be the magic keyword ever since C++ came out
People that start writing code immediately are programmers (or hackers), people that ask questions first are Software Engineers - Graham Shanks
|
|
|
|
|
Hi,
Can I write a shell extension which can process my own shell format?
For example: I have an application which has own data format, and when
drag from this applicaion and drop on explorer, the extension can process this data format.
It's like when you drag some texts and drop on explorer, which generate some special file.
Of course, I want generate my own files.
Anyone can help me?
|
|
|
|
|
How do I dynamically create a button (for example).
I understand how to create a button in code
ie CButton pBut* = new CButton()
pBut->Create( ..... )
but how do I trap when the button is pressed? I can't add entries to the message map because at design time the button doesnt exist?
TIA
|
|
|
|
|
you should overide the OnCommand function. The HIWORD of the wParam contains the action and the LOWAORD of wParama contains the Id of control
nav
|
|
|
|
|
For handling the evenmts on the buttons:
You have to override onCommand method and then in this you can check the id and perform the operations:
In onCommand:
you can get the id in LOWORD(wParam).
Check this and write the code in the following loop.
Cheers
Ganesh
|
|
|
|
|
The last argumen of button.Create is button id. You can use it in message map
CButton *pButton = new CButton;
pButton.Create(WS_VISIBLE|WS_CHILD,CRect(10,10,110,30),this,1 /*Id of the button any id which is unique*/ );
void OnHandler(void)
{
// Something
}
ON_BN_CLICKED(1 /* Last argument of create */,OnHandler)
MANISH RASTOGI
|
|
|
|
|
manish rastogi wrote: ON_BN_CLICKED(1 /* Last argument of create */,OnHandler)
He cannot use a message map as buttons are created dynamically.
Owner drawn
Jesus Loves
|
|
|
|
|
He can if he knows what the ID's will be at compile time...
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
True. But it's not flexible.
Owner drawn
Jesus Loves
|
|
|
|
|
Is there a way to dynamically create an ID?
|
|
|
|
|
ID acts as a unique identifier for the control that you are creating. So make sure that they are unique.
Owner drawn
Jesus Loves
|
|
|
|
|
I realize that, so is there any way to ask the framework to return a unique ID
|
|
|
|