|
Thanks, I forgot all about that one. I'll check it out.
|
|
|
|
|
How can I implement a class function, which can be run in separate thread
Example
class AudioIn
{
public:
AudioIn();
virtual ~AudioIn();
void StartProc();
HANDLE Thread;
DWORD m_ThreadID;
HANDLE hEvent;
};
AudioIn::AudioIn()
{
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
Thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)AudioIn::StartProc,NULL,0,&m_ThreadID);
}
Is it possible?
I'm creating console application in VC++.
Sorry for stupid question.
Tomaz
|
|
|
|
|
Yes. One your example, declare StartProc as a static public member function.
Kuphryn
|
|
|
|
|
How can I get few parameters into static class function?
Should I declare a structure
Thread = CreateThread(NULL,0,AudioIn::StartProc,declared-structure,0,&m_ThreadID);
or is there a simple way?
Thank you
Tomaz
|
|
|
|
|
You have to declare a structure and pass a pointer to it. There are some common problems regarding who owns this structure. Consider the following:
void foo()
{
data d;
CreateThread(...,&d,...)
} This seems OK and will probably work some times until it suddenly stops to do it. The reason is that, when the thread starts executing and access d , it is perfectly normal that foo has already exited, and d is no longer valid. So, you have to dynamically allocate the data:
void foo()
{
data* d=new data;
CreateThread(...,d,...)
} Now the problem is who deletes d ? The most reasonable choice is to let the thread delete the data:
MyThread(LPVOID arg)
{
data * d=(data *)arg;
...
delete d;
...
} This is almost perfect: you should take into account the rare case when the thread does not launch (due to insufficient resources, for instance):
void foo()
{
data* d=new data;
if(!CreateThread(...,d,...)){
delete d;
}
} That's it, hope it helps.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hi Tomaz,
the problem is that CreateThread() is a c function...and c doesn't know anything about classes or virtual tables...
try this:
//---------------------------------------------------
void YourClass::AnyFunction()
{
// declarations
DWORD dwId;
// create the thread
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartAddress,(LPVOID)this,0,&dwId);
}
DWORD YourClass::StartAddress(LPVOID lpParam)
{
// call the thread function
((YourClass*)lpParam)->ThreadFunction();
}
void YourClass::ThreadFunction()
{
...
}
//---------------------------------------------------
in the header you should declare the thread start procedure as follows:
static DWORD StartAddress(LPVOID lpParam);
..this should do it
|
|
|
|
|
It is working.
Thank you.
Tomaz
|
|
|
|
|
Hello,
Has anyone had problems catching WM_DROPFILES or EN_DROPFILES messages in a CRichEditView? I read msdn and believe I'm doing everything correctly but I can't seem to catch that message.. I have tried to set DragAcceptFiles(TRUE) in my Init() then in WindowProc() I try to catch WM_DROPFILES.. I have also added ENM_DROPFILES to the eventmask of my rich edit control and tried to catch EN_DROPFILES message and that hasn't worked either.. Here's what I've tried..
in WindowProc()
if (message == WM_NOTIFY)
{
if (((LPNMHDR)lParam)->code == EN_DROPFILES)
{...}
}
if (message == WM_DROPFILES)
{...}
Any ideas??
Rob
Whoever said nothing's impossible never tried slamming a revolving door!
|
|
|
|
|
OnDropFiles should work. See Help under CWnd::DropFiles.
As far as I know, OnDropFiles is already impelemented in CRichEditView. So you have to override this function! That's why you never get notified, because the base installation alredy captured the message.
G. Steudtel
|
|
|
|
|
Would you tell me what API support to recognize CD-ROM status when i push the button eject on CD-ROM. Example it can recognize there are CD in CD-ROM or not.
|
|
|
|
|
char szBuffer[256];
mciSendString("status cdaudio media present", szBuffer, sizeof(szBuffer), NULL);
TRACE("szBuffer = ]%s[\n", szBuffer);
|
|
|
|
|
An alternative to DavidCrow's method:
#include <windows.h>
#include <sys/types.h>
#include <sys/stat.h>
bool drive_present(const char letter)
{
char nul_file[]="#:\\NUL";
nul_file[0]=letter;
DWORD error_mode=::SetErrorMode(0);
::SetErrorMode(error_mode|SEM_FAILCRITICALERRORS);
struct _stat st;
int res=_stat(nul_file,&st)==0;
::SetErrorMode(error_mode);
return res!=0;
} Use drive_present with the drive letter of the CD.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
A Visual C++ application, if run on a system having VC++ not installed, asks for a number of ".dll" files.
Kindly tell me how to make an installer package so as to be able to run it on a machine not having VC++.
In Visual Basic, we have a utility called Package and Deplyment Wizard for this purpose.
I am not able to find any such thing in VC++ .
Gaurav Gumber
|
|
|
|
|
use Depends (look in Microsoft Visual Studio\Common\Tools\DEPENDS.EXE)to list the dlls you'll need to distribute, or
If you are in Multi-Threaded DLL code generation mode you'll need
msvcrt.dll
If you have are using STL and you are in Multi-Threaded DLL code generation mode,
then you'll need to redist msvcp60.dll .
If you have linked to MFC then you'll need the mfc dll(s) which will depend on what parts of MFC you use. At least mfc42.dll
You can save yourself a lot of heartache and simply link statically (Multithreaded instead of Multi-Threaded DLL) to the crt and link statically to MFC.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|
|
|
|
How can i put all dll´s (into Inno Setup) that my program needs to work?
|
|
|
|
|
Hi,
I use a thread, whitch I have created with 'AfxBeginThread'. Within this thread I use an endless while loop [while(1) {//do some thing}]. Is it possible to terminate this thread by the thread-caller? All I could find is to use the TerminateThread function but to do this I have to use before the DuplicateHandle function. Unfortunately I was realy not very successfull by trying this. Can anybody help please?
Thanks a lot
Vassili
|
|
|
|
|
If it is a worker thread, you simply need to exit the thread function. If it is a UI thread, you need to post a WM_QUIT message.
|
|
|
|
|
Yes, it is a worker thread. In my endless while loop I read the serial port. On an port event I send a message to the main program. I also send a message to the main program with the handle of the thread by using GetCurrentThread()
UINT TheThread(LPVOID pParam)
{
HANDLE* pObject = (HANDLE*)pParam;
HANDLE hThread;
.
.
.
hThread = GetCurrentThread();
SendMessage(pObject, WM_MY_MESSAGE, 0, (LPARAM) hThread);
while(1)
{
//here I read the CommPort
.
.
}
return 0;
}
--In the main Program:
LRESULT CMyDlg::MyFunction(WPARAM wParam, LPARAM lParam)
{
m_hThread = (HANDLE) lParam; //m_hThread is a private HANDLE variable of CMyDlg
return 0L;
}
void CMyDlg::OnWhatEver()
{
//TerminateThread(m_hThread, -1);
//CloseHandle(m_hThread);
}
If I use TerminateThread((m_hThread, -1) the application disappears but a process is still running which I have to terminate with the Task Manager. If I use CloseHandle(m_hThread) nothing happens...
You posted befor that I need simply to exit the thread function - this is exactly what I want to do, but how?
|
|
|
|
|
Vassili wrote:
...I need simply to exit the thread function - this is exactly what I want to do, but how?
Change your while(1) loop to have a more meaningful condition. For example:
bool bContinue = true;
while (true == bContinue)
{
}
return 0;
|
|
|
|
|
Hi again,
within the while loop I use the function ReadFile(...). This means that if there is nothing to read from the serial port the process will not step to the next line. It will remain in the ReadFile-step until a new information will come through the port. Because of this I can't use a condition like bContinue. On the other hand only the main program knows when to end the thread. So the question is: is there a way to terminate my thread from the main program? If not then I will have to redesign my complete program
|
|
|
|
|
Is the handle being used by ReadFile() synchronous or asynchronous? By your description, it sounds as though a synchronous handle is being used, thus the blocking in which you describe.
|
|
|
|
|
[edit] Sorry, did not see you already mentioned it. Why do you use DuplicateHandle?[/edit]
BOOL TerminateThread(
HANDLE hThread,
DWORD dwExitCode
);
but this is never recommanded...
~RaGE();
|
|
|
|
|
The sensible way to terminate a thread is to make it terminate itself - generally by setting some sort of flag to signal that the thread should terminate. In its simplest form, the code looks something like this:
extern bool bTerminateFlag;
int YourThreadFunction(LPVOID pParam)
{
while (!bTerminateFlag)
{
do_something...
}
return exit_code;
}
And your function to terminate the thread would look something like this:
int TerminateWorkerThread(HANDLE hWorker)
{
bTerminateFlag = true;
if (WaitForSingleObject(hWorker, INFINITE)!=WAIT_OBJECT_0)
{
}
else
{
return GetExitCodeThread(hWorker);
}
}
This is all very simplified - you'd want proper error checking, you probably shouldn't use a global variable as the terminate flag, and you shouldn't really use WaitForSingleObject in a thread with a message loop. But the principle is there. There's generally very little reason to use TerminateThread, and it can lead to all sorts of problems when your thread is doing something worthwhile, and holding resources open, because the terminated thread doesn't get to do any cleanup.
"We are the knights who say Ni" (The Knights Who Say Ni)
|
|
|
|