|
I've tried the DRAWCLI sample from MSDN
it uses c++ polymorphism for its
implementation
why all tool's instance pointer are stored in the variable c_tools(CPtrList)
thanks in advance
|
|
|
|
|
I am experiencing problem regarding calling a "PostThreadMessage" function from outside the thread function. A code is attched below... Please go through it and guide me as to how to go about correcting it...
/*
The PRODUCER and OTHER threads post messages to the
CONSUMER thread. All the threads wait on the
"consumerReady" event to be set by the main thread.
*/
#include
#include
#include
typedef struct temp
{
int msid;
char *msg;
}box;
// Thread IDs. Define these globally so the threads can refer to each other.
DWORD producerID, consumerID, otherID;
void get_msg(DWORD quid,box *obj);
void post_msg(DWORD quid,box *obj);
// An event
HANDLE consumerReady;
// The producer thread.
DWORD WINAPI produce(LPVOID)
{
// Do not start producing until all threads are ready.
WaitForSingleObject(consumerReady, INFINITE);
int count = 0;
while(count < 2)
{
box *ptr;
ptr=(box *)malloc(sizeof(box));
ptr->msg = (char *)malloc(10);
strcpy(ptr->msg,"hello\0");
ptr->msid = 12;
post_msg(consumerID,ptr);
// PostThreadMessage(consumerID, WM_USER, (WPARAM)ptr, 0); // works fine if this
// line is used instead
// of above line
Sleep(1000);
printf("\nposted 12");
count++;
}
return 0;
}
// The consumer thread.
DWORD WINAPI consume(LPVOID)
{
// Do not start producing until all threads are ready.
WaitForSingleObject(consumerReady, INFINITE);
Sleep(0);
int count = 0;
while (true)
{
box *ptr;
ptr=(box *)malloc(sizeof(box));
ptr->msg = (char *)malloc(10);
get_msg(consumerID,ptr);
count++;
printf("count %d",count);
}
return 0;
}
DWORD WINAPI other(LPVOID)
{
// Do not start producing until all threads are ready.
WaitForSingleObject(consumerReady, INFINITE);
int count = 0;
// Send simple integers. Use WM_USER messages with the integer values
// in the wParam field.
while(count < 2)
{
box *ptr;
ptr=(box *)malloc(sizeof(box));
ptr->msg = (char *)malloc(10);
strcpy(ptr->msg,"other\0");
ptr->msid = 11;
post_msg(consumerID,ptr);
// PostThreadMessage(consumerID, WM_USER, (WPARAM)ptr, 0); // works fine if this
// line is used instead
// of above line
Sleep(1000);
printf("\nposted 11");
count++;
}
return 0;
}
// main() runs the simulation.
int main()
{
// Create an event which is initially unsignaled
consumerReady = CreateEvent(0, TRUE, FALSE, 0);
// Create the threads and start them immediately.
HANDLE consumerHandle = CreateThread(0, 0, consume, 0, 0, &consumerID);
HANDLE producerHandle = CreateThread(0, 0, produce, 0, 0, &producerID);
HANDLE otherHandle = CreateThread(0, 0, other, 0, 0, &otherID);
//Set the event now that all threads are ready
SetEvent(consumerReady);
//Keep the main thread alive
WaitForSingleObject(producerHandle, INFINITE);
WaitForSingleObject(consumerHandle, INFINITE);
return 0;
}
void post_msg(DWORD quid,box *obj)
{
PostThreadMessage(quid, WM_USER, (WPARAM)obj, 0);
int err = GetLastError();
printf("\n obj_post->msgid %d ",obj->msid);
printf("\n err_post = %d ",err);
}
void get_msg(DWORD quid,box *obj)
{
MSG lmsg;
GetMessage(&lmsg, 0, 0, 0);
obj = (box*)(lmsg.wParam);
int err = GetLastError();
printf("\n obj_get->msgid %d ",obj->msid);
printf("\n obj_get->msg %c ",*(obj->msg));
printf("\n err_get = %d ",err);
}
///////////////////////////////////////////////////////////////////////
The output is given below:
obj_post->msgid 12
err_post = 1444
obj_post->msgid 11
err_post = 1444
posted 12
obj_get->msgid 12
obj_get->msg h
err_get = 0 count 1
posted 11
obj_get->msgid 11
obj_get->msg o
err_get = 0 count 2
obj_post->msgid 11
err_post = 1444
obj_post->msgid 12
err_post = 1444
posted 11
posted 12
////////////////////////////////////////////////////////////
As can be seen , posting the messages results in a error id of 1444(INVALID THREAD IDENTIFIER) which is puzzling cos all the threads are already created....
Any help would be appreciated in this regard...
|
|
|
|
|
Do it like this ...........
Change
DWORD WINAPI consume(LPVOID)
{
WaitForSingleObject(consumerReady, INFINITE);
Sleep(0);
int count = 0;
while (true)
{
box *ptr;
ptr=(box *)malloc(sizeof(box));
ptr->msg = (char *)malloc(10);
get_msg(consumerID,ptr);
count++;
printf("count %d",count);
}
return 0;
}
to
DWORD WINAPI consume(LPVOID)
{
MSG msg;
box* test;
WaitForSingleObject(consumerReady, INFINITE);
Sleep(0);
while (true)
{
get_msg(consumerID,test);
}
return 0;
}
And change
void get_msg(DWORD quid,box *obj)
{
MSG lmsg;
GetMessage(&lmsg, 0, 0, 0);
obj = (box*)(lmsg.wParam);
int err = GetLastError();
printf("\n obj_get->msgid %d ",obj->msid);
printf("\n obj_get->msg %c ",*(obj->msg));
printf("\n err_get = %d ",err);
}
to
void get_msg(DWORD quid,box *obj)
{
MSG lmsg;
GetMessage(&lmsg, 0, 0, 0);
obj = (box*)malloc( sizeof(box)*1);
obj->msid = 0;
obj->msg = (char *)malloc(10);
memset(test->msg,'0',10);
obj = (box*)(lmsg.wParam);
int err = GetLastError();
printf("\n obj_get->msgid %d ",obj->msid);
printf("\n obj_get->msg %c ",*(obj->msg));
printf("\n err_get = %d ",err);
}
|
|
|
|
|
I'm reading data from the serial port with ReadFile(). Now I know that in the middle of the read, I will get a null character (0x00). After the ReadFile statement, the string it's put the characters into only exists until the null character, thinking that position is the null terminating the string, but there's more data that it read past that null which I need. Previously, I'd read one character at a time, if it was a null, it would toss it out. If it wasn't null, it'd copy it to a string. That works but it's too complicated and takes too much time communicating with the serial port. Anyone have an idea I can bypass this null but not have to read each character one at a time. When reading one character at a time, there are some really sticky and annoying timing issues that quickly turn into a minefield for me so any way I can avoid it is fine with me. Thanks in advance, Nate.
|
|
|
|
|
It's not because there is a null character in your string that the rest of your data isn't read from the serial port.
What you can do is read the data (all at once) in to a char[] and then copy character per character into a string if you want to...
Something like this:
int i, index=0;
char DataBuffer[], StringBuffer[];
ReadFile(...)
for (i=0; i < NumberOfBytesRead; i++)
{
if (DataBuffer[i] != '\0')
StringBuffer[index++] = DataBuffer[i];
}
This way you don't have to worry about communication timing and so on.
Don't think you are, know you are...
|
|
|
|
|
That's kind of what I was doing, but I was reading in a byte at a time instead of reading them all in one step, then copy the character if it wasn't null. But that looks pretty sharp though, good call, thanks.
|
|
|
|
|
Since the buffer can contain '\0' characters, you cannot use any string-related functions like strlen() or strcpy() . You'll need to use memcpy() instead if you need to transfer data from one variable to another.
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
ah, makes sense because the string functions read until the first null, good call.
|
|
|
|
|
I am experiencing problem regarding calling a "PostThreadMessage" function from outside the thread function. A code is attched below... Please go through it and guide me as to how to go about correcting it...
/*
The PRODUCER and OTHER threads post messages to the
CONSUMER thread. All the threads wait on the
"consumerReady" event to be set by the main thread.
*/
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
typedef struct temp
{
int msid;
char *msg;
}box;
// Thread IDs. Define these globally so the threads can refer to each other.
DWORD producerID, consumerID, otherID;
void get_msg(DWORD quid,box *obj);
void post_msg(DWORD quid,box *obj);
// An event
HANDLE consumerReady;
// The producer thread.
DWORD WINAPI produce(LPVOID)
{
// Do not start producing until all threads are ready.
WaitForSingleObject(consumerReady, INFINITE);
while(1)
{
box *ptr;
ptr=(box *)malloc(sizeof(box));
ptr->msg = (char *)malloc(10);
strcpy(ptr->msg,"hello\0");
ptr->msid = 12;
post_msg(consumerID,ptr);
Sleep(1000);
}
return 0;
}
// The consumer thread.
DWORD WINAPI consume(LPVOID)
{
// Do not start producing until all threads are ready.
WaitForSingleObject(consumerReady, INFINITE);
Sleep(0);
while (true)
{
box *ptr;
ptr=(box *)malloc(sizeof(box));
ptr->msg = (char *)malloc(10);
get_msg(consumerID,ptr);
}
return 0;
}
DWORD WINAPI other(LPVOID)
{
// Do not start producing until all threads are ready.
WaitForSingleObject(consumerReady, INFINITE);
// Send simple integers. Use WM_USER messages with the integer values
// in the wParam field.
while(1)
{
box *ptr;
ptr=(box *)malloc(sizeof(box));
ptr->msg = (char *)malloc(10);
strcpy(ptr->msg,"other\0");
ptr->msid = 11;
Sleep(1000);
post_msg(consumerID,ptr);
}
return 0;
}
// main() runs the simulation.
int main()
{
// Create an event which is initially unsignaled
consumerReady = CreateEvent(0, TRUE, FALSE, 0);
// Create the threads and start them immediately.
HANDLE producerHandle = CreateThread(0, 0, produce, 0, 0, &producerID);
HANDLE consumerHandle = CreateThread(0, 0, consume, 0, 0, &consumerID);
HANDLE otherHandle = CreateThread(0, 0, other, 0, 0, &otherID);
//Set the event now that all threads are ready
SetEvent(consumerReady);
//Keep the main thread alive
WaitForSingleObject(producerHandle, INFINITE);
WaitForSingleObject(consumerHandle, INFINITE);
return 0;
}
void post_msg(DWORD quid,box *obj)
{
PostThreadMessage(quid, WM_USER, (WPARAM)obj, 0);
int err = GetLastError();
printf("\n obj_post->msgid %d ",obj->msid);
printf("\n err_post = %d ",err);
}
void get_msg(DWORD quid,box *obj)
{
MSG lmsg;
GetMessage(&lmsg, 0, 0, 0);
obj = (box*)(lmsg.wParam);
int err = GetLastError();
printf("\n obj_get->msgid %d ",obj->msid);
printf("\n obj_get->msg %c ",*(obj->msg));
printf("\n err_get = %d ",err);
}
The output is
obj_post->msgid 12
err_post = 1444
obj_get->msgid 12
obj_get->msg h
err_get = 0
obj_get->msgid 11
obj_get->msg o
err_get = 0
obj_post->msgid 11
err_post = 0
obj_post->msgid 12
err_post = 1444
obj_get->msgid 11
obj_get->msg o
err_get = 0
obj_get->msgid 12
obj_get->msg h
err_get = 0
As can be seen in some cases, posting the messages results in a error id of 1444(INVALID THREAD IDENTIFIER) which is puzzling cos all the threads are already created....
Any help would be appreciated in this regard...
|
|
|
|
|
Do it like this ...........
Change
DWORD WINAPI consume(LPVOID)
{
WaitForSingleObject(consumerReady, INFINITE);
Sleep(0);
int count = 0;
while (true)
{
box *ptr;
ptr=(box *)malloc(sizeof(box));
ptr->msg = (char *)malloc(10);
get_msg(consumerID,ptr);
count++;
printf("count %d",count);
}
return 0;
}
to
DWORD WINAPI consume(LPVOID)
{
MSG msg;
box* test;
WaitForSingleObject(consumerReady, INFINITE);
Sleep(0);
while (true)
{
get_msg(consumerID,test);
}
return 0;
}
And change
void get_msg(DWORD quid,box *obj)
{
MSG lmsg;
GetMessage(&lmsg, 0, 0, 0);
obj = (box*)(lmsg.wParam);
int err = GetLastError();
printf("\n obj_get->msgid %d ",obj->msid);
printf("\n obj_get->msg %c ",*(obj->msg));
printf("\n err_get = %d ",err);
}
to
void get_msg(DWORD quid,box *obj)
{
MSG lmsg;
GetMessage(&lmsg, 0, 0, 0);
obj = (box*)malloc( sizeof(box)*1);
obj->msid = 0;
obj->msg = (char *)malloc(10);
memset(test->msg,'0',10);
obj = (box*)(lmsg.wParam);
int err = GetLastError();
printf("\n obj_get->msgid %d ",obj->msid);
printf("\n obj_get->msg %c ",*(obj->msg));
printf("\n err_get = %d ",err);
}
|
|
|
|
|
I am making a login form(very simple). i am storing username and password(both 5 characters each fixed)in file. when i try to login and press login button, it gives the message "MFC application has encountered and error and needs to close...". And some time it raises exception like "dbgHeap on line 1017" . Please somebody could help me. I am pasting complete code of Login button message handler...
BOOL CNewJoiningFormDlg::LogIn()
{
UpdateData(TRUE);
if(m_strLoginName.GetLength()!=5)
{
MessageBox("Login Name must be exactly 5 characters long","Stop",MB_ICONSTOP|MB_OK);
return FALSE;
}
if(m_strPassword.GetLength()!=5)
{
MessageBox("Password must be exactly 5 characters long","Stop",MB_ICONSTOP|MB_OK);
return FALSE;
}
/*---Declare the variables in which login and password will be read from the file*/
CString psw;
CString login;
//--Take the file pointer to the beginning of the file
ASSERT_VALID(m_pPSWFile);
m_pPSWFile->SeekToBegin();
DWORD fileLength=m_pPSWFile->GetLength();
UpdateData(FALSE);
while( (m_pPSWFile->GetPosition()) < fileLength )
{
m_pPSWFile->Read(&login,5);
if(login==m_strLoginName)
{
UpdateData(FALSE);
m_pPSWFile->Read(&psw,5);
if(psw==m_strPassword)
{
UpdateData(FALSE);
AfxMessageBox("You supplied correct Login Name and Password");
return TRUE;
}
}
}
return FALSE;
}
|
|
|
|
|
Your code keeps a file open for it's entire lifetime ?
Have you tried stepping through the code in a debugger, to see which line is causing your error ?
Christian
I have several lifelong friends that are New Yorkers but I have always gravitated toward the weirdo's. - Richard Stringer
|
|
|
|
|
wasife wrote:
UpdateData(TRUE);
Don't use UpdateData() . See here for details.
wasife wrote:
if(m_strLoginName.GetLength()!=5)
Checking the length is unnecessary. Use CEdit::SetLimitText() instead.
wasife wrote:
MessageBox("Login Name must be exactly 5 characters long","Stop",MB_ICONSTOP|MB_OK);
You might consider AfxMessageBox() here, unless you really need a custom caption.
wasife wrote:
m_pPSWFile->Read(&login,5);
The first parameter to Read() is a void* not a CString* . You'll need something like:
LPSTR lpBuffer = login.GetBuffer(5);
m_pPSWFile->Read(lpBuffer, 5);
login.ReleaseBuffer(5); Now login contains the five bytes read from the file.
As far as the error(s) you are getting, I suggest stepping through each statement in the debugger to see which one is at fault.
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
DavidCrow wrote:
Don't use UpdateData().
don't use knives, ever. they have two features that makes them extremely dangerous: their sharp points, and their sharp edges. either of those features could cause a lot of pain and/or damage, if pressed into, or sliced across, your nose.
Image Toolkits | Image Processing | Cleek
|
|
|
|
|
I hope that my Windows client program searches all IP devices on same network and then gets MAC addresses of those.
These IP devices are based on LINUX and the client program should be run on all versions of Windows.
In my thought, this is possible by getting the individual IP of all devices, drawing the MAC address from that IP
and checking if the MAC is in particular range which we need.
First step, the way to getting IPs of all devices on network, may be following.
1) broadcasting to all devices on network
2) using WNetEnumResource
I have not tried 1)way, so I wonder what part of the data from the device has the information of IP.
And I think 2)way has no problem.
Second step, the way to drawing MAC address, may be following.
1) using NetBios()
2) using SendARP()
3) using WinPcap library
Though I tried 1)way, NetBios() can draw only MAC of own PC that my Windows client runs.
2)way is possible on only Windows 2000, Xp, so this way is not proper for me.
3)way is may be possible, But, bucause I think I should program ARP protocol, it will be difficult.
Or, is there any easier way and solution to do those two steps except my thoughts?
And, is there any problem or error of my thoughts?
Please give me advices.
Have a nice day!
|
|
|
|
|
The third way is not impossible.. it's the best way!
Send a broadcast ping packet, receive the answers with the winpcap and extract the mac addresses from it. That should be very easy!
Don't try it, just do it!
|
|
|
|
|
i wrote an dialog based application. now i want to create a setup file for it. any ideas????????
|
|
|
|
|
check out NSIS, made by Nullsoft, the Winamp people. I haven't used it personally, but I bet it's pretty easy to learn and powerful because it's a pretty widely used free installer.
|
|
|
|
|
If you only want to create a setup file for your application , you can use the tools about setup , e.g "Installer VISE" . If you want to write a tool about setup , you should to have a long about step to step base of dialog .
e.g
http://www.vckbase.com/code/listcode.asp?mclsid=3&sclsid=317[^]
sorry for my poor english .
|
|
|
|
|
|
I'm working to let the program know the column No. which user right-clicked the ListView in the HeadCtrl area. There is HitTest() method in CListCtrl class to determine the item No. for a given position, but I can not find the same way in CHeadCtrl.
Can anybody tell me what should I do?
Lisoft
|
|
|
|
|
\\.........
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
\\.........
void CSortListCtrl::OnColumnClick( NMHDR* pNMHDR, LRESULT* pResult )
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
const int iColumn = pNMListView->iSubItem;
*pResult = 0;
}
|
|
|
|
|
Hi,I have made a single document MFC application in VC++, in which several items may be drawn using toolbar(same as MS paint).But the problem is here: I want to make one of the items in such a way that when a user draws (selecting from toolbar)it in drawable area and clicks or double clicks (preferrable if double right click is implemented)on it, another document opens in which the user can also draw using the toolbar as it occurs for the root document.Here also if the specified tool is selected from toolbar and drawn in the child document (i.e. drawable area ) and double right clicked it opens another child document of it and so on..
Again ,if saved ,all the documents (i.e. main document,child document,next child document,...) must be saved and when opened the main document ,it should take care of the rest i.e. when double right clicked on the specified item which was drawn,the corresponding child document should be opened from repository and so on..
There may be several such item drawn in a single document.Is it possible not to open the child documents from repository?
How could I do the above? Please help me step by step.
|
|
|
|
|
I have a function declared like this: bool CSerialControl::DoCommPackage (DWORD dwBlockTime, void *lpvOutputData, unsigned int uiOutputLength, void *lpvIncoming, unsigned int uiExpectedInputLength) { ... }
When I call the function, I have this:
char buf[70];<br />
if (classData->m_serialPort->DoCommPackage(INFINITE, NULL, 0, buf, 70)) { ... do something useful ... }
It gets the right return value, true under the proper circumstances, and does something useful, but in the useful part, the buf character array is unchanged from when it was allocated before the if statement. I don't get why it's unchanged, am I missing something or what? Thanks, Nate.
|
|
|
|
|
bool CSerialControl::DoCommPackage (DWORD dwBlockTime, void *lpvOutputData, unsigned int uiOutputLength, void *lpvIncoming, unsigned int uiExpectedInputLength){
char * p = (char *)lpvIncoming ;
//lpvIncoming is replaced by p
}
e.g
int FuncA(void * lp , int iCount )
{
char * p = (char *)lp;
memset(p,0,iCount);
strcpy(p,"this is a test");
return 1 ;
}
...............................
char str[70];
FuncA(str,70);
|
|
|
|
|