|
There are two methods. I've included code with both. I used a bool to signal the other thread, but vastly prefer using events since threads often have waits within them. Also note that I can't remember the last time I checked a thread exit code, but you may have a reason. Finally, if you don't call MFC within the thread (with a few exceptions), you could just use _beginthreadex(). I just did this last week.
1) Call AfxBeingThread() with the CREATE_SUSPENDED flag.
2) set CWinThread::m_bAutoDelete to false
3) Call CWinThread::Resume()
4) At exit, after setting the bool (or setting an event, which is my preferred method), call WaitOnSingleObject() with CWinThread::m_hThread
5) Call GetThreadExitCode() to get exit code
6) Delete the CWinThread object
I've run into problems with MFC complaining about item 6.
CWinThread* StartAfxThread(AFX_THREADPROC pThreadProc, LPVOID pParam = NULL, int priority = THREAD_PRIORITY_NORMAL)
{
CWinThread* pThread = ::AfxBeginThread(pThreadProc, pParam, priority, 0, CREATE_SUSPENDED);
pThread->m_bAutoDelete = false;
pThread->ResumeThread();
return pThread;
}
CWinThread* pThread = StartAfxThread(TheThread);
isRunning = false;
if (::WaitForSingleObject(pThread->m_hThread, 1000) == WAIT_TIMEOUT)
{
::TerminateThread(pThread->m_hThread, (DWORD) -1);
Sleep(10);
}
DWORD exitCode = 0;
::GetExitCodeThread(pThread->m_hThread, &exitCode);
_tprintf(_T("Exit code: %u"), exitCode);
delete pThread;
1) Call AfxBeingThread() with the CREATE_SUSPENDED flag.
2) Duplicate CWindThread::m_hThread
3) Call CWinThread::Resume()
4) At exit, after setting the bool, call WaitOnSingleObject() with the duplicate handle.
5) Call GetThreadExitCode() to get exit code
6) Close the duplicate handle
HANDLE StartAfxThread(AFX_THREADPROC pThreadProc, LPVOID pParam = NULL, int priority = THREAD_PRIORITY_NORMAL)
{
CWinThread* pThread = ::AfxBeginThread(pThreadProc, pParam, priority, 0, CREATE_SUSPENDED);
HANDLE hProcess = GetCurrentProcess();
HANDLE hDup;
if (!::DuplicateHandle(hProcess, pThread->m_hThread, hProcess, &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
hDup = NULL;
pThread->ResumeThread();
return hDup;
}
HANDLE hThread = StartAfxThread(TheThread);
isRunning = false;
if (::WaitForSingleObject(hThread, 1000) == WAIT_TIMEOUT)
{
::TerminateThread(hThread, (DWORD) -1);
Sleep(10);
}
DWORD exitCode = 0;
::GetExitCodeThread(hThread, &exitCode);
_tprintf(_T("Exit code: %u"), exitCode);
CloseHandle(hThread);
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
When the user clicks cancel, I don't want the window to close if the thread is still running. I want to have the thread safely finish first.
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DWORD exitcode;
GetExitCodeThread(hTread->m_hThread, &exitcode);
if (exitcode != STILL_ACTIVE )
OnCancel();
-@SuDhIrKuMaR@-
|
|
|
|
|
By default a CWinThread object with auto delete itself upon thread exit. Not only will the thread handle within be invalid, the pointer itself will be invalid.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
hi all,
anyone have a idea the meaning of the bold lines.
using child pointer to a the parent class.
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
//virtual int area (void) =0;
virtual int area (void)
{return 0;}
void printarea (void)
{ cout << this->area() << endl; }
};
class CTriangle: public CPolygon {
public:
int area (void)
{ return (width * height / 2); }
int test;
};
int main () {
CRectangle rect;
CTriangle trgl;
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &trgl;
CTriangle * ptrgl = (CTriangle *) ▭
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ptrgl->set_values (4,5);
ppoly1->printarea();
ppoly2->printarea();
ptrgl->printarea();
ptrgl->test = 1;
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
cout << ptrgl->area() << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
|
|
|
|
|
The definition of CRectangle isn't present so I can't tell if the cast makes sense. I have to say it look like nonsense to me however. Also, as a general rule avoid C-style casts.
Steve
|
|
|
|
|
Let me restate my question
below code can be compile and run with no problem. but, i confused how the bold line works. I have not initialzed a CTriangle object in the bold line but i can access the data by a CTriangle pointer.
I dont think it is a good practice but i am quite confused how it works...
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void)
{return 0;}
void printarea (void)
{ cout << this->area() << endl; }
};
class CTriangle: public CPolygon {
public:
int area (void)
{ return (width * height / 2); }
int testdata;
};
int main () {
CPolygon poly;
CTriangle trgl;
CPolygon * ppoly2 = &trgl;
CTriangle * ptrgl = (CTriangle *) &poly;
ppoly2->set_values (4,5);
ptrgl->set_values (4,5);
ppoly2->printarea();
ptrgl->printarea();
ptrgl->testdata = 100;
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
cout << ptrgl->area() << endl;
cout << ptrgl->testdata << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
|
|
|
|
|
The fact that it works is a fluke. The local poly is NOT a CTriangle . It just so happens that in the two classes the vtable[^] pointer is at the same location as are the first two members (width and height ). Accessing testdata (via ptrgl ) is wrong in this code. Also the wrong instance of virtual functions will be called. If I could give a single piece of advice to new C++ programmers it would be to stop casting yourself into strife.
Steve
|
|
|
|
|
I search the boards to no avail.
|
|
|
|
|
|
CString strText("GOOD");
char *pChar= (char *)(LPCTSTR)strText;
|
|
|
|
|
Please never suggest that unless you further elaborate.
Such conversion may be used only with extreme care.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Do you mean to say i should elaborate what i have given there an an example?
|
|
|
|
|
I mean since your technique is dangerous hence you should explicitely state whenever it is viable.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
|
I have been looking for a way to access the dictionary in windows.
I have found how to spell check and to edit the dictionary but that is doing a comparison of words in a file utilizing msword.olb in C++.
I am looking to pull a word from the dictionary with the option of pulling the definition with it. Is that possible within the C++/.net environment to utilize the dictionary built into word or word pad this way?
|
|
|
|
|
Hi
I want to make a program that retrieves other windows' pixel values. First i made a default application which title name is "Untitled - NewWindow" and one more MFC project which is trying to draw to that window.
The code is:
void CDeviceContextDlg::OnBnClickedButton1()
{
::EnumWindows(EnumWindowsProc, NULL);
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
if(hwnd == FindWindow(NULL,L"Untitled - NewWindow"))
{
HDC dc = GetDC(hwnd);
CDeviceContextDlg *dlg = (CDeviceContextDlg *)AfxGetMainWnd();
if((dlg->Clientdc.Attach(dc)))
{
dlg->Clientdc.SetBkColor(RGB(255,0,0));
};
};
return TRUE;
}
It gives run-time error. I debugged it and in that line:
HDC dc = GetDC(hwnd);
In Debugger:
dc 0x53011041 {unused=??? } HDC__ *
unused CXX0030: Error: expression cannot be evaluated
Is it because process gdi handle table is process specific and it is impossible to get DC and draw another process' window?
Or is there a way to draw another process' window or getpixel values?
Thanks
|
|
|
|
|
Maybe this [^] helps.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Just fixed the vote on this post of yours.
|
|
|
|
|
Thank you friend.
Anyway don't bother. Let's my personal troll having a touch of glory...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
I am searching ebay for a device that would let you find and punch one troll at a time, with a folded fist, through the internet.
|
|
|
|
|
Well, you can buy one (ore more) of these [^] and then proceed with voodoo ceremony.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
|
I tested this real quick, and it works fine for me.
This example finds a NotePad instance and Blts the Notepad window
to my window (note that "*pThis" in the callback == the HWND for the dialog window)...
BOOL CALLBACK CMFCTesterDlg::EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
if(hwnd == ::FindWindow(NULL, L"Untitled - Notepad"))
{
CMFCTesterDlg *pThis = (CMFCTesterDlg *)lParam;
HWND hwnddest = *pThis;
RECT rect;
::GetWindowRect(hwnd, &rect);
HDC dc = ::GetDCEx(hwnd, NULL, DCX_WINDOW);
HDC destdc = ::GetDC(hwnddest);
::BitBlt(destdc, 0, 0, rect.right-rect.left, rect.bottom-rect.top, dc, 0, 0, SRCCOPY);
::ReleaseDC(hwnddest, destdc);
::ReleaseDC(hwnd, dc);
};
return TRUE;
}
void CMFCTesterDlg::OnOK()
{
::EnumWindows(&CMFCTesterDlg::EnumWindowsProc, (LPARAM)this);
}
Also, why the search within a search (FindWindow() within an EnumWindows() callback)??
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you Mr.Mark Salsbery. Got it.
|
|
|
|
|
iwdu150
I have tried your Percent Progress Bar, and have use it in a application I am building. What I mean is I am using the DLL and the XML. This application that I am building is for my own use and will not be release to the public. The DLL and XML have really come in handy and I have enjoyed using. You did a good job.
The reason I am contacting you is that I noticed that the word ‘TRIAL’ is tacked onto the name ‘Progress Bar Trial.dll’ and ‘Progress Bar Trial.xml’. This has me a little worried, will it expire or maybe die on me in the near future. If not then great; but if so, please let me know. Also let me know how I can get a good copy of it. Once again, great job, I hope I can use it just the way it is.
Bob Allan
rallan@carolina.rr.com
|
|
|
|