|
John: Its ok to use a database in a thread as long as you don't try to use it (CRecordset) in more than one thread.
Yes, I also think so. The problem is CRecordset. But - in my case - it does not depend on using it in more than one thread. I first created a CRecordset and did some SELECT statements, after that i used CDatabase (or another CRecordset) for the insertion of records. And thats it: the first CRecordset is bound to the database and the insertion by other instances causes the error. So, now i'm using only one CRecordset and everything works well .
bdiamond: I started using ADO instead which I find to be a lot simpler
OK, that's good to know . I'll remember that in next projects.
|
|
|
|
|
Hi
I have a vc++ application, which i would like to distribute as evaluation copy. The application should not run if the specified 30 days is over.
It should handle system time changes etc.
Could anyone help me out !
Thanks and regards
The Best Relligion is Science.
Once you understand it, you will know God.
|
|
|
|
|
The best way to distribute an evaluation copy is to limit it's functionality. That is, comment out sections of code that offer functionality you do not want to provide in a trial version. Then build a trial version.
Another alternative is to limit the amount of executions. This can be handled by keeping a record of the execution times inside the executable itself, which makes it more difficult to hack. Using time periods is always difficult, because changing the BIOS date will mix up any period counters, and there's no way you can detect it, if done correctly.
So, when you hand out evaluation copies, cripple them. This allows your testers to evaluate the product, but they can't hack it (as there's nothing to gain), and if they feel like purchasing the full version, you can sell it to them.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Hi
Thankyou for your time.
I have a specific requirement for 30 day trial versions that is the main concern.
I just want to know the trick behind creating the 30 day trial versions.
Thanks & Regards
The Best Relligion is Science.
Once you understand it, you will know God.
|
|
|
|
|
I just want to know the trick behind creating the 30 day trial versions.
Either write a hidden file or registry key that contains a data that you program checks at startup or roll out an encrypted code that the user is emailed that contains the date that the program quits working.
John
|
|
|
|
|
Hi
Thankyou very much.
I will be back after trying out some trials
Regards
The Best Relligion is Science.
Once you understand it, you will know God.
|
|
|
|
|
You have to remember that if you put full functionality in your trial code hackers will try to find a way around your protection routines so try to put multiple checks (of the expiration date and possibly a crc check of the executable) in your program to make it difficult to crack.
John
|
|
|
|
|
My suggestiion is to set a registry key in a place known only by you or in several places in registry.
Your program should have for example 50 hours when it can be avalaible.
In registry you set at first the value 50
And when your program starts you shoul set a timer
SetTimer(NULL,NULL,50*60000,TimerProc);
and when the time elapses the TimerProc should change the registry key to EXPIRED or something like this.
The program should always start by reading this key and if it is expired close and if it is not set the timer.
This should work
gabby
|
|
|
|
|
Hi
thank you all,
This will work fine if you limit the trial version by the number of hours.
I want to limit the application the by number of days. Say If he is not using the application for 5 days after installing, his trial period should count that also..
I know there is always a crack for that..it is impossible to build a crack proof system, but what I want is somewhat difficult algorithm
Thanks and regards
The Best Relligion is Science.
Once you understand it, you will know God.
|
|
|
|
|
Can anyone tell me why what seems like a simple cast fails to compile in one case, but passes when the code is rearranged.
Let me show you what I mean.
IA and IB are my own COM interfaces with one method taking the other as a parameter.
This fails:
<font color=green>
IAPtr PB = NULL;
IBPtr pA = NULL;
<font color=green>
..
pB->SomeMethod(&pA); <font color=green>
I get the error message:
General.cpp(319) : error C2664: 'MyLibrary::IA::SomeMethod' : cannot convert parameter 1 from '_com_ptr_t<_IIID>::Interface ** ' to 'IUnknown ** '
But This works:
<font color=green>
IAPtr pB = NULL;
IBPtr pA = NULL;
IUnknown* pUnk = NULL;
<font color=green>
..
pUnk = static_cast<IUnknown*>(pA)
pB->SomeMethod(&pUnk);
Surely these equate to the same thing?
I Dream of Absolute Zero
|
|
|
|
|
Actually, they don't.
The pointer pA points to a pointer to the interface class IA , which, according to COM rules, inherits from IUnknown , either directly or indirectly. However, it looks like you use the COM helper classes to declare IAPtr and IBPtr . When you do this, they can no longer be directly cast, but require explicit casting. To skip using COM helper classes, define the pointers in the following manner:
typedef IAPtr IA* After this, you can no longer directly use them, but must instantate and initialize them manually. The prize is that they support direct casting.
The method you describe assumes a pointer to the IUnknown interface pointer. What you're passing it is a pointer to a pointer to IA . These two are not automatically compatible.
Using the following call would solve the case without extra work:
pB->SomeMethod( &(reinterpret_cast<IUnknown*>(pA)) ); -Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Thanks for that explanation.
Can't say I fully understand, but when it comes to COM, who does?
I do get the general jist though.
Antti Keskinen wrote:
Using the following call would solve the case without extra work:pB->SomeMethod( &(reinterpret_cast<iunknown*>(pA)) );
I had tried something similiar :
pB->SomeMethod(reinterpret_cast<IUnknown**>(&pA));
But that didn't compile, so I gave up on that train of thought
Thanks again.
I Dream of Absolute Zero
|
|
|
|
|
Hi!
I got data stored in CString variable. The data consist of mulitiline numbers each number in new line. The length of the CString depends on the data and is various. How can I delete e.g. 5 lines from the end of the CString?
Thanks in advance.
|
|
|
|
|
Answer: basic math, pen and a paper.
Following your description, if you'd need to delete the last 5 lines, this means that you'd need to delete so many characters starting from the end that you'd reach the fifth '\n' character. The lines in a CString object are stored sequentically, with line changes denoted as '\n' and the end of the string as '\0'.
An example. Consider that your arbitary string is structured as follows "111111111111\n22222222222\n333333333333\n44444444444\n555555555555\n6666666666666\n77777777777\0".
Now, if you'd need to delete the last two lines, you'd first need to determine how many lines there are on the string. This means finding how many '\n' characters are found. The line quantity is this added with 1 (last line doesn't have a '\n'). When you had this amount, in this case, 7, and would need to delete 2 lines, it would leave us 4 '\n' characters, right ? So, let's search until we find the fifth '\n' character. After we get it's index, we delete characters from the string, starting from this index. Thus, the last fifth '\n' is replaced by a '\0', and all remaining characters are deleted.
Finding the amount of '\n' is easy: start from the beginning, find the first one. Then start again, from the index returned by the first search plus one. By using this recursive search method, you can run through the string and find out how many line changes you have.
It's pretty straigthforward, although might feel difficult at first. But the quicker you start, the quicker you get it done
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Your idea is pretty good. Thanks!!
|
|
|
|
|
hope this helps...
==>From MSDN:
Deletes a character or characters from a string starting with the character at the given index.
int Delete(
int iIndex,
int nCount = 1
);
Parameters
iIndex
The zero-based index of the first character in the CStringT object to delete.
nCount
The number of characters to be removed.
Return Value
The length of the changed string.
Remarks
If nCount is longer than the string, the remainder of the string will be removed.
Example
The following example demonstrates the use of CStringT::Delete.
//typedef CStringT< TCHAR, StrTraitATL< TCHAR > > CAtlString;
CAtlString str( "Soccer is best!");
printf("Before: %s\n", (LPCTSTR) str);
int n = str.Delete(6, 3);
printf("After: %s\n", (LPCTSTR) str);
_ASSERT(n == str.GetLength());
Output
Before: Soccer is best!
After: Soccer best!
See Also
CStringT Overview | Class Members
"If I don't see you in this world, I'll see you in the next one... and don't be late." ~ Jimi Hendrix
|
|
|
|
|
Hi!
I was thinking of that function but in my case the length of the CString depends on the data and is various so I don’t know exactly the iIndex. And that’s why I can’t use the function delete.
Thanks.
|
|
|
|
|
Here's a list of some basic CString members you can use:
CString is quite a powerful and easy class, you'll be able to use these members in order to get the required result.
Good luck!
AllocSysString Allocates a BSTR from CStringT data.
AnsiToOem Makes an in-place conversion from the ANSI character set to the OEM character set.
AppendFormat Appends formatted data to an existing CStringT object.
Collate Compares two strings (case sensitive, uses locale-specific information).
CollateNoCase Compares two strings (case insensitive, uses locale-specific information).
Compare Compares two strings (case sensitive).
CompareNoCase Compares two strings (case insensitive).
Delete Deletes a character or characters from a string.
Find Finds a character or substring inside a larger string.
FindOneOf Finds the first matching character from a set.
Format Formats the string as sprintf does.
FormatMessage Formats a message string.
FormatMessageV Formats a message string using a variable argument list.
FormatV Formats the string using a variable list of arguments.
GetEnvironmentVariable Sets the string to the value of the specified environment variable.
Insert Inserts a single character or a substring at the given index within the string.
Left Extracts the left part of a string.
LoadString Loads an existing CStringT object from a Windows resource.
MakeLower Converts all the characters in this string to lowercase characters.
MakeReverse Reverses the string.
MakeUpper Converts all the characters in this string to uppercase characters.
Mid Extracts the middle part of a string.
OemToAnsi Makes an in-place conversion from the OEM character set to the ANSI character set.
Remove Removes indicated characters from a string.
Replace Replaces indicated characters with other characters.
ReverseFind Finds a character inside a larger string; starts from the end.
Right Extracts the right part of a string.
SetSysString Sets an existing BSTR object with data from a CStringT object.
SpanExcluding Extracts characters from the string, starting with the first character, that are not in the set of characters identified by pszCharSet.
SpanIncluding Extracts a substring that contains only the characters in a set.
Tokenize Extracts specified tokens in a target string.
Trim Trims all leading and trailing whitespace characters from the string.
TrimLeft Trims leading whitespace characters from the string.
TrimRight Trims trailing whitespace characters from the string.
"If I don't see you in this world, I'll see you in the next one... and don't be late." ~ Jimi Hendrix
|
|
|
|
|
Can anyone tell whether can we convert UTF-8 text file to unicode text file programmatically.
|
|
|
|
|
Why not?
Read in each line and use MultiByteToWideChar on it.
Write out the converted strings to another file.
|
|
|
|
|
Any examplecode how to use that MultiByteToWideChar(...) ?
_____________________________
...and justice for all
APe
|
|
|
|
|
MultiByteToWideChar(
CP_UTF8, // code page - UTF-8 since you know that is your source's code page
MB_PRECOMPOSED, // character-type options
lpMultiByteStr, // pointer to your UTF-8 string read from file
cbMultiByte, // number of bytes in string - length of line read from file
lpWideCharStr, // this is where the data will be converted into the wide-character buffer
cchWideChar // size of the wide character buffer
);
I like to make the wide character buffer at least 1.5 times larger than the source string in case you get several multi-bute characters in your input stream.
|
|
|
|
|
hi ,
i'm using coledatetime class for storing time value.
COleDateTime stTime(/*some time value*/);
CString s=stTime.Format(VAR_TIMEVALUEONLY);
if time value is 12:00:00 AM then value of s is blank.
other wise it is giving proper time values.
what could be problem.
thanks,
prasad
|
|
|
|
|
prasad_som wrote:
what could be problem
It is not actually a problem. It is a feature , as documented in the MSDN[^].
Why not specifically specify the time format your require?
e.g. stTime.Format(_T("%H:%M%:S")); <font color=green>// will give '23:16:23' for example</font>
I Dream of Absolute Zero
|
|
|
|
|
By chance, see if this makes a difference:
CString s = stTime.Format((DWORD) VAR_TIMEVALUEONLY);
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|