|
Well, I am new to all this. When you said there design problem and explained it, i didn't understood much. Can you suggest me why it is a design problem, and How it should be designed to avoid the problems.
thanks a lot.
|
|
|
|
|
Please note that the following are recommendations and suggestions due to how I interpret the problem and your solution.
Why do I consider this a design problem?
There are two ways of solving problems like this:
1. sequential (blocking calls, synchronous, one thread)
2. parallel (non-blocking calls, asynchronous, multiple threads)
Whenever you are thinking "I start a thread here and wait for it to end" you are trying to solve a parallel problem in a sequential way or vice versa.
This is bad design.
Either you solve it in a sequential way by having a blocking call to your write function and when you have actually written the data it polls for an acknowledge before returning...or
you solve it in a parallel way by having a thread polling for acknowledgements and set an event when such an ack has been received.
In the latter case you will wait for the event to be signaled in your write function with ::WaitForSingleObject or similar. If the device doesn't respond within proper time your wait function will return WAIT_TIMEOUT and you know that the data was not written. You should select your timeout so that the user doesn't feel that the application has hung, e.g. < 1s.
The whole idea with a worker thread is to perform a task in the background and signal the main thread when the job is done, either by setting an event that another thread may be waiting for or posting a message.
If I have understood your problem correctly it all boils down to the fact that you want to write some data and to know if the data was properly written you are waiting for an acknowledge.
I understand this as the core of your problem.
As I understand it the ACK you are waiting for consists of data, i.e. to be able to know if you have received the ACK you have receive data.
What I would do is have a thread that receives data and interprets it, at least to know if the data received is an ACK and if it is use ::SetEvent() to signal an event. In the write function I would write the data and then call ::WaitForSingleObject with the handle of the event mentioned above as input parameter. If ::WaitForSingleObject returns WAIT_TIMEOUT I can return FALSE, -1 or whatever to notify the caller that the operation failed.
The receiving thread will be terminated when the connection to the device is closed.
HumanOsc recommended you an article written by Joseph Newcomer about worker threads. Joe has written lots of stuff that is absolutely worth reading at his own site: http://www.flounder.com/mvp_tips.htm[^]
The essential essays are in my opinion are about worker threads, message management, time management and "The n Habits of Highly Defective Windows Programs" since they address issues that one have to know as a windows developer combined with healthy coding standards and tips.
Hope this helped you
--
Roger
|
|
|
|
|
How to split the string based on new line character.
I have a string i.e.,
C:\MyDocuments\myDialog\release\myapp.exe
I want to retrive exe name . (ie., myapp.exe)
How it is possible.
I want to retrive right last exe name for all paths.
Give a flexible code.
Praveen Chowdam Kumar
|
|
|
|
|
hey buddy
use CStringT::Tokenize (as far as i think CString and CStringT functions same).
following is an exmple i found for you form msdn go through it.
Example:
The following example demonstrates the use of CStringT::Tokenize.
//typedef CStringT< TCHAR, StrTraitATL< TCHAR > > CAtlString;
CAtlString str( "%First Second#Third" );
CAtlString resToken;
int curPos= 0;
resToken= str.Tokenize("% #",curPos);
while (resToken != "")
{
printf("Resulting token: %s\n", resToken);
resToken= str.Tokenize("% #",curPos);
};
Output:
Resulting Token: First
Resulting Token: Second
Resulting Token: Third
|
|
|
|
|
CString str="C:\MyDocuments\myDialog\release\myapp.exe"
int indx=str.ReverseFind('\\');
if (indx!=-1)
CString fileName=str.Right(indx);
|
|
|
|
|
Why don't you check out the Class Members in CString?
Well, here goes:
Solution 1, CString:
CString cs = "C:\\MyDocuments\\myDialog\\release\\myapp.exe";
CString pureFileName;
int lastSlashOffset = cs.ReverseFind((TCHAR) '\\');
if(lastSlashOffset >= 0 && cs.GetLength > (lastSlashOffset + 1)) {
pureFileName = cs.Mid(pureFileName + 1);
}
// pureFileName contains the file name.
Solution 2 (good old splitpath):
#include <stdlib.h>
#include <stdio.h>
void main( void )
{
char path_buffer[_MAX_PATH];
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
strcpy(path_buffer, "C:\\MyDocuments\\myDialog\\release\\myapp.exe");
_splitpath( path_buffer, drive, dir, fname, ext );
printf( "Path extracted with _splitpath:\n" );
printf( " Drive: %s\n", drive );
printf( " Dir: %s\n", dir );
printf( " Filename: %s\n", fname );
printf( " Ext: %s\n", ext );
}
Output
Path extracted with _splitpath:
Drive: c:
Dir: \MyDocuments\myDialog\release\
Filename: myapp
Ext: .exe
|
|
|
|
|
This is the code that i have Tested with VC.6
it is actually the correction of the answer posted to the
quetion .
If ur using CString so its VC++ and for VC++ this format
is preferable.
<br />
CString str1="C:\\MyDocuments\\myDialog\\release\\myapp.exe";<br />
int indx=str1.ReverseFind('\\');<br />
indx++;<br />
if (indx!=-1)<br />
CString fileName=str1.Mid(indx);<br />
Vikas Amin
Embin Technology
Bombay
vikas.amin@embin.com
|
|
|
|
|
OOps ! I forgot to increment. thanks Vikas.
|
|
|
|
|
#include "shlwapi.h"
CString strPathName = _T("C:\\MyDocuments\\myDialog\\release\\myapp.exe");
LPTSTR pszFileName = PathFindFileName(strPathName);
CString strFileName = pszFileName;
Never forget to search MSDN.
That's all, folks!
One always gets the deserved.
|
|
|
|
|
YoSilver wrote:
PathFindFileName(strPathName);
Similarly you can use _tSplitPath() api also
"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
|
|
|
|
|
i want to chang the data of VT_DATE to the one of VT_BSTR with the VariantChangeTypeEx(&vargDest,&varSrc,2052,0,VT_BSTR) function, but only a part of the data is changed. for example,2005-12-20 0:00:00 is converted to 2005-12-20 of VT_BSTR, but 1899-12-30 21:30:00 is converted to 21:30:00 of VT_BSTR. both 2005-12-20 0:00:00 and 1899-12-30 21:30:00 are from sql server, and 2005-12-20 0:00:00 is smalldatetime; 1899-12-30 21:30:00 is datetime. how can i get the complete VT_BSTR data?
|
|
|
|
|
hi everyone, i want to write some letters on a sphere to give the letters third dimension, and i don't want to use openGl or DirectX, how ?
thanks in advance!
|
|
|
|
|
why not use one of them? If you want to do it yourself then you need to understand the maths involved.
If you just want a simple solution then draw the letters at the middle of the string bigger than at each end.
|
|
|
|
|
sounds like a good idea, i'll try. thanks again
|
|
|
|
|
i have tried,it looks uglily, maybe it is the time to review maths
|
|
|
|
|
In vc6 project with vss, what do the two icons in front of each file mean (one with a downward arrow, one without)? Thanks.
|
|
|
|
|
I have referred to the FAQ but the answer does not solve the problem actually...
Below is my code of creating srevice:
--------------------------------------------------------------------------------------------------
SC_HANDLE hService =
::CreateService(
handle, // handle to SCM database
servicename.c_str(), // name of the service to install
servicename.c_str(), // name that is displayed on SCM
SERVICE_ALL_ACCESS, // can be accessed only by administrators
SERVICE_WIN32_OWN_PROCESS, // service runs its own process
SERVICE_AUTO_START, // started by SCM when StartService() is called
SERVICE_ERROR_IGNORE, // error logged but service started
ss, // pathname of the executable
NULL, // service does not belong to any group
NULL, // service does not use a tag
NULL, // requires NtLmsSp and EventLog service to be running
".\\Administrator", // user name to log on
"s" // password
);
--------------------------------------------------------------------------------------------------
|
|
|
|
|
Hi!Dear,
I got a Link error when compile my windows app on visual studio c++ 6.0.
It says:
"LINK:fatal error LNK1104:can not open file '..\..\baseclasses\debug_unicode\quartz.lib'".
My Project Options:..\..baseclasses\debug_unicode\quartz.lib kernel32.lib ...
And when I changed by Project Options as:
:..\..baseclasses\debug_unicode\kernel32.lib quartz.lib ...
then the link error says:
"LINK:fatal error LNK1104:can not open file '..\..\baseclasses\debug_unicode\kernel32.lib'"
But I am quite sure that I have added the directories of these libray files.
Then,how to kill this matter?
Thanks!
|
|
|
|
|
momer wrote:
"LINK:fatal error LNK1104:can not open file '..\..\baseclasses\debug_unicode\quartz.lib'".
Do these files exist ? Apparently, they are not visible to the compiler.
momer wrote:
But I am quite sure that I have added the directories of these libray files.
Yes, but if you've added their directories to VC, then you need to link to just the file, and not a relative path to the file. Try removing all but the lib name and see how you go.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
If I remember correectly, quartz.lib is part of media player 9 so reinstall that.
Elaine
PS "Madam, can you help me" was appropriate here
The tigress is here
|
|
|
|
|
Trollslayer wrote:
"Madam, can you help me"
"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
|
|
|
|
|
Which is faster when doing a file search on your pc programmatically? CRC's or byte-for-byte checking?
|
|
|
|
|
benjnp wrote:
Which is faster when doing a file search on your pc programmatically? CRC's or byte-for-byte checking?
Offcourse CRC, but what the use of that in file search
"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
|
|
|
|
|
hello
I am experimenting with simulating a key press using the SetKeyboardState
<br />
while(true)<br />
{<br />
<br />
DWORD thread_acum=GetWindowThreadProcessId(GetActiveWindow(),NULL);<br />
<br />
UINT vk,scan;<br />
<br />
LPARAM lparam;<br />
<br />
vk = VkKeyScan('s');<br />
<br />
<br />
AttachThreadInput(thread_acum,GetCurrentThreadId(),TRUE);<br />
<br />
<br />
BYTE byKeybState[256];<br />
GetKeyboardState(byKeybState); <br />
byKeybState[vk] =! (BOOL)::GetKeyState(vk);<br />
<br />
<br />
byKeybState[vk] =!(BOOL)GetKeyState(vk);<br />
SetKeyboardState(byKeybState);<br />
<br />
<br />
<br />
<br />
AttachThreadInput(thread_acum,GetCurrentThreadId(),FALSE);<br />
<br />
<br />
<br />
<br />
Sleep(1000);<br />
<br />
}<br />
why does this not work? No key is pressed
|
|
|
|
|
Spiritofamerica wrote:
SetKeyboardState
Why Don't you use SendInput Api or KeyBD_event api..
"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
|
|
|
|