![]() |
| | #1 |
| Registered User Join Date: May 2004
Posts: 164
| OS: windows XP Compiler: MS Visual C++ 6.0 Standard I created a new class derived from CWinThread successfully called Thread: Code: #if !defined(AFX_THREAD_H__9BC5C079_E9F6_42A7_B471_1CA97CC15BB6__INCLUDED_)
#define AFX_THREAD_H__9BC5C079_E9F6_42A7_B471_1CA97CC15BB6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Thread.h : header file
//
class VIEWER; //forward declaration to VIEWER dialog
/////////////////////////////////////////////////////////////////////////////
// Thread thread
class Thread : public CWinThread
{
DECLARE_DYNCREATE(Thread)
protected:
Thread(); // protected constructor used by dynamic creation
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(Thread)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
virtual int Run();
//}}AFX_VIRTUAL
void setOwner(VIEWER* ptrDialog)
{
ptrDlg = ptrDialog;
}
private:
VIEWER* ptrDlg; //the pointer to pointer to object dialog window: VIEWER
// Implementation
protected:
virtual ~Thread(); //protected destructor
// Generated message map functions
//{{AFX_MSG(Thread)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_THREAD_H__9BC5C079_E9F6_42A7_B471_1CA97CC15BB6__INCLUDED_)
Code: // Thread.cpp : implementation file
//
#include "stdafx.h"
#include "FXG.h"
#include "Thread.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// Thread
IMPLEMENT_DYNCREATE(Thread, CWinThread)
Thread::Thread()
:ptrDlg(NULL)
{
}
Thread::~Thread()
{
ptrDlg = NULL;
}
BOOL Thread::InitInstance()
{
// TODO: perform and per-thread initialization here
return TRUE;
}
int Thread::ExitInstance()
{
// TODO: perform any per-thread cleanup here
return CWinThread::ExitInstance();
}
BEGIN_MESSAGE_MAP(Thread, CWinThread)
//{{AFX_MSG_MAP(Thread)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Thread message handlers
int Thread::Run()
{
// TODO: Add your specialized code here and/or call the base class
return CWinThread::Run();
}
Code: HANDLE hThread; Code: //assign handle object to equal call to begin thread and pass //in argurments for Thread::Run() hThread=(HANDLE)_beginthreadex(NULL,0,Thread::Run,this,0,0); [cde] C:\ASE\FXG\VIEWER.cpp(79) : error C2664: '_beginthreadex' : cannot convert parameter 3 from 'int (__thiscall Thread::*)(void)' to 'unsigned int (__stdcall *)(void *)' There is no context in which this conversion is possible [/code] Please help, I have tried 15 different example programs, and been reading for days and not been able to solve the issue. BUT to be positive, I have learned alot that from my research, but I could use some assistance to get this resolved. Thanks again- |
| WaterNut is offline | |
| | #2 |
| Registered User Join Date: May 2004
Posts: 164
| Ok, in reading the error over and then reviewing MSDN notes I notice that it seems like I am passing the wrong type of call, which is why I am getting the type int conversion error to the _beginthreadex() call which apparently expects an address, which I assume is the class where the function is defined, class: Thread, and then the void function with declared pointer MSDN NOTE: Code: uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); |
| WaterNut is offline | |
| | #3 |
| Registered User Join Date: May 2004
Posts: 164
| question relating to MFC vs API Is the function _beginthreadex() API (NOT_MFC)? and AfxBeginThread() is the MFC version of _beginthreadex()? |
| WaterNut is offline | |
| | #4 |
| Registered User Join Date: May 2004
Posts: 164
| Although I don't think I got as much from the learning aspect, which i hope to change in the near future, I did find a good example program for the AfxBeginThread() on code project and it is working for me quite well once I was able to add it to my code. I have alot still to modify, but in case it helps anyone else and to say thanks to Enis, here is the project I downloaded and I am learning from: http://www.codeproject.com/threads/memberthread.asp But I would still appreciate any feedback available, I had hoped to go a less MFC route but I will take what I can get to work in order to push forward and hopefully learn what I need to learn. |
| WaterNut is offline | |
| | #5 |
| CSharpener Join Date: Oct 2006
Posts: 5,336
| Windows API has a CreateThread function _beginthread/_beginthreadex are CRT wrappers for these functions, providing additional initializations required for other CRT functions to work properly in the multythreading environment MFC has CWinThread::CreateThread function and AfxBeginThread for the same reason
__________________ If I have eight hours for cutting wood, I spend six sharpening my axe. |
| vart is offline | |
| | #6 |
| pwns nooblars Join Date: Oct 2005 Location: Portland, Or
Posts: 1,094
| Btw, it is Win32 API, not just API. I had no idea what API(application programming interface) you were talking about when I read the title of your post and had to actually read more to figure it out. |
| Wraithan is offline | |
| | #7 |
| Registered User Join Date: May 2004
Posts: 164
| Vart, thanks for helpful reply, I appreciate your assistance as always that helps. |
| WaterNut is offline | |
| | #8 |
| Registered User Join Date: May 2004
Posts: 164
| return value from inside thread I am tacking this onto my previous thread as it relates to the same problem and code, but the subject is slightly different.... In using MFC's AfxBeginThread, the call to the threads are working, I put message box's inside the functions', the pointer to the threads call and got positive results so I know the thread is working, but now I am trying to figure out how to return the result of the polling thread to my Dialog Window. Not sure if this is something I need to define inside the definition of the function I call with the thread, or if there is some way to pipe the repsonse of the thread back to Dialog and an assigned variable. Class Declaration and the functions I call in the thread (ConfigurePort and ReadString): Code: class VIEWER : public CDialog
{
// Construction
public:
void ControlCap();
VIEWER(CWnd* pParent = NULL); // standard constructor
HANDLE hPort;
void setOwner(VIEWER* ptrDialog)
{
ptrDlg = ptrDialog;
}
static UINT StartThread (LPVOID param);
typedef struct THREADSTRUCT //structure for passing to the controlling function
{
VIEWER* _this;
} THREADSTRUCT;//controlling function header
//define functions for port settings and reading port
//the read byte function
BOOL ReadByte(BYTE &resp)
{
BOOL bReturn = TRUE;
BYTE rx;
DWORD dwBytesTransferred=0;
if (ReadFile (hPort, &rx, 1, &dwBytesTransferred, 0)> 0)
{
if (dwBytesTransferred == 1)
{
resp=rx;
bReturn = TRUE;
}
else bReturn = FALSE;
}
else bReturn = FALSE;
return bReturn;
}
//the read string function
BOOL ReadString(void *outstring, int *length)
{
// MessageBox("In ReadString");
BYTE data;
BYTE dataout[4096]={0};
int index = 0;
while(ReadByte(data)== TRUE)
{
dataout[index++] = data;
}
memcpy(outstring, dataout, index);
*length = index;
return TRUE;
}
//the serial port configuration function
HANDLE ConfigureSerialPort(LPCSTR lpszPortName)
{
// MessageBox("In ConfigPort");
HANDLE hComm = NULL;
DWORD dwError;
DCB PortDCB;
COMMTIMEOUTS CommTimeouts;
// Open the serial port.
hComm = CreateFile (lpszPortName, // Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE,
// Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING, // How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute to copy
// Initialize the DCBlength member.
PortDCB.DCBlength = sizeof (DCB);
// Get the default port setting information.
GetCommState (hComm, &PortDCB);
// Change the DCB structure settings.
PortDCB.BaudRate = 9600; // Current baud
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = TRUE; // Enable parity checking
PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type
PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
PortDCB.fOutX = FALSE; // No XON/XOFF out flow control
PortDCB.fInX = FALSE; // No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE; // Disable error replacement
PortDCB.fNull = FALSE; // Disable null stripping
PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control
PortDCB.fAbortOnError = TRUE; // Do not abort reads/writes on error
PortDCB.ByteSize = 8; // Number of bits/byte, 4-8
PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
// Configure the port according to the specifications of the DCB structure.
if (!SetCommState (hComm, &PortDCB))
{
AfxMessageBox("Could not configure serial port\n");
return NULL;
}
// Retrieve the time-out parameters for all read and write operations
// on the port.
GetCommTimeouts (hComm, &CommTimeouts);
// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts (hComm, &CommTimeouts))
{
AfxMessageBox("Could not set timeouts\n");
return NULL;
}
return hComm;
}
//the close port function
void ClosePort()
{
CloseHandle(hPort);
return;
}
// Dialog Data
//{{AFX_DATA(VIEWER)
enum { IDD = IDD_VIEWER };
CVideoCap m_VideoCap1;
CString m_City;
CString m_State;
CString m_Street;
CString m_Speed;
CString m_Radar;
//}}AFX_DATA
private:
void UpdateConfig();
VIEWER* ptrDlg;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(VIEWER)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(VIEWER)
virtual BOOL OnInitDialog();
afx_msg void OnChangeStreet();
afx_msg void OnChangeCity();
afx_msg void OnChangeSpeed();
afx_msg void OnSelchangeState();
virtual void OnOK();
afx_msg void OnCapture();
afx_msg void OnStop();
afx_msg void OnPause();
afx_msg void OnResume();
afx_msg void OnSnapshot();
afx_msg void OnChangeRadar();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_VIEWER_H__4FE30814_FC1C_42DD_B76F_F060E2892084__INCLUDED_)
and now the actual thread execution: Code: UINT VIEWER::StartThread (LPVOID param)
{
ofstream fout;
fout.open("C:\\threadtest.txt", ios::app);
char data [10];
char clear [2] = "";
char message[8];
int sizeBuffer =8;
int count = 0;
THREADSTRUCT* ts = (THREADSTRUCT*)param;
//open port and configure it
//here is the time-consuming process which interacts with your dialog
// AfxMessageBox ("Thread is started!");
/* ts->_this->m_ctrl_progress.SetRange (0, 1000);
while (ts->_this->m_ctrl_progress.GetPos () < 1000)
{
Sleep(500);
ts->_this->m_ctrl_progress.StepIt ();
} */
ts->_this->ConfigureSerialPort("COM1");
Sleep(500);
do
{
ts->_this->ReadString(message, &sizeBuffer);
count++;
Sleep(50);
if (count ==100)
{
ts->_this->ClosePort();
fout<<"eo data loop"<<endl;
fout.close();
break;
}
}while (count <=100);
//testing only
AfxMessageBox("Loop Completed");
// ts->_this->ClosePort();
//you can also call AfxEndThread() here
AfxEndThread(0,NULL);
return 1;
}
Code: static CString output; outp+=ts->_this->ReadString(message, &sizeBuffer); I will keep cracking at it, but any help would be appreciated - |
| WaterNut is offline | |
| | #9 |
| Registered User Join Date: May 2004
Posts: 164
| oh and yes the output vs outp was a typo, no errors when compiling. Ha Ha! Tried a few other variances, and got, what looks like garble to the output file, but still no difference, I think I am not truly getting the value of the variable, "message" into a point where I can output it to the dialog or to another variable. Which is odd to me, because, message is declared inside the dialog VIEWER::StartThread, so I would think what I am doing is ok: Code: char message[8]; int sizeBuffer =8; ts->_this->ReadString(message, &sizeBuffer); //output to file fout<<message<<endl; |
| WaterNut is offline | |
| | #10 |
| Registered User Join Date: May 2004
Posts: 164
| ok, brain fart.... when I spawn the thread and call the ReadString function passing it the two variables, message and sizeBuffer... Are those variables not accessible because they are being used by the thread, a separate process from the originating dialog process???? If so, would that mean I need a ptr declared inside the original class that would and assign that inside the function definition of ReadString so that it could return or provide a "pointer" to that value to return it to the dialog or a global variable of the dialog??? Yes sorry, I talk to myself, it helps..... |
| WaterNut is offline | |
| | #11 |
| Cat without Hat Join Date: Apr 2003
Posts: 8,492
| Threading is complicated. If you don't quite understand all the rules attached to it, I suggest you do some console programs to properly learn them, i.e. strike Win32 API and MFC from the equation. Threading in Win32 is more complicated. Threads may have attached message queues. Windows have a bit of thread affinity. Threading in MFC is hell. The wrapper objects cannot be transferred between threads. There's lots and lots of pitfalls associated with threading. If you're serious about using MFC and threads, I really recommend you search for the topic on the web, or get "Programming Windows with MFC" by Jeff Prosise.
__________________ All the buzzt! CornedBee"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code." - Flon's Law |
| CornedBee is offline | |
| | #12 |
| Registered User Join Date: May 2004
Posts: 164
| I agree need some additional resources, not easy to find in local stores, But I did just order the book, Windows Programing With MFC online, so I should get it hopefully by the end of the week. Always good to have a reference:-) Still hoping to get some help if possible in the mean time.... |
| WaterNut is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| multithreading in c | thebrighter | C Programming | 8 | 07-10-2007 01:17 PM |
| call webbrowser.Navigate within a thread via post message to UI thread | hanhao | Windows Programming | 2 | 07-01-2007 07:11 AM |
| multithreading question | ichijoji | C++ Programming | 7 | 04-12-2005 10:59 PM |
| Win32 Thread Object Model Revisted | Codeplug | Windows Programming | 5 | 12-15-2004 08:50 AM |
| injecting my own thread into the address space of another process - cannot call any f | Andrew_5342 | Windows Programming | 12 | 05-17-2003 05:58 AM |