|
'a' || 'A' is a logical or operation. Thus, the result is either 0 or 1.
try:
case 'A':
case 'a':
etc...
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
i think you would have to use the ascii values of the various letters instead.
|
|
|
|
|
There is no difference between 97 and 'a'.
/ravi
"There is always one more bug..."
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
No, 'a' || 'A' does not mean case 'a' or case 'A' as you intent but case (conditon1 || condition2). Since at least one condition is non-zero, the result of the logical operation is true which is then converted to 1...
So your code in interpreted as:
Forum Visual C++
Subject: Re: is this wright?
Sender: Anonymous
Date: 12:31 30 Apr '02
hi,
i keep getting an error saying ": error C2196: case value '1' already used".
is there another way of having an or function in the middle
<br />
switch (get_textletter)<br />
{<br />
case 1: <br />
get_textletter=0;<br />
break;<br />
<br />
case 1: <br />
get_textletter=1;<br />
break;<br />
...<br />
and the compiler display an error because the same case appears more than once which is illegal.
What you want to do is to repeat the case statement like this:
<br />
switch (get_textletter)<br />
{<br />
case 'a':<br />
case 'A':<br />
get_textletter=0;<br />
break;<br />
<br />
case 'b':<br />
case 'B': <br />
get_textletter=1;<br />
break;<br />
...<br />
In any other case, if there are no break between 2 cases, a comment should be added to show that it was your intent and you not forget it. In case like this one, this is clear that you want to continue with the next case because every case appears unindented and one after the other (without any blank line)...
Philippe Mori
|
|
|
|
|
I am using TCP/IP socket, one application is running on Windows 2000, the other is on VxWorks(a real-time OS). What I am doing is: the Win app will send the VxWorks a request, say REQ_1, VxWorks received REQ_1, send back an acknoledge RESPONSE_1, Win app received RESPONSE_1, will send several KB data to VxWorks.
so the data flow is:
Win App VxWorks
REQ_1 ------------> (wait for reqeust)
(wait for response) <------------ RESPONSE_1
data -------------> (wait for data)
I found out that the first round of handshaking is very fast, it takes almost no time to finish everything (0.000000 according the my TRACE statement). But the second will take 0.08 or 0.09 or 0.10 seconds, and the following one would take 0.2 seconds. So there will be a limit 5 times of handshaking in a seconds. The bottleneck is for the Win App to receive the RESPONSE_1.
I tested it on a 10M LAN as well as on a 100M LAN, and get the same result.
Am I reaching any limit of software handshaking of TCP/IP socket? What did I do wrong?
|
|
|
|
|
Are you using TCP_NODELAY (turns off the Nagle algorithm) in the socket options? In Windows this defaults to 0.2 second delay for a send - I am not sure about VxWorks.
|
|
|
|
|
Wow, got it. After I set it, my program is like flying. Thank you so much!
|
|
|
|
|
Damn it, I thought it was the Nagle algorithm getting in the way, but I wasn't sure at all so I didn't say anything...
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Believe in yourself and be proud of yourself.
|
|
|
|
|
K I know theres loads on this topic but couldnt find anything which solves my dilemma.
I have a multi-threaded service with a time event which is monitored using cached information in a singleton com object i then wish to launch a process in a given directory i.e. zip some files up - Scheduler kindof app.
Now my problem is I've been using CreateProcess with no probs - however here it comes if I set the directory for which I wish to launch the process to have permissions for only a certain user - ie full control and i remove the everyone group then I get the error:
"the client does not have the required permissions."
Now I get this error
1: When Im debugging the service i.e. Im logged in as fred, and fred has the full access permissions on the directory in question.
2: When I set the service to use the same account and not the system account.
Now I looked into CreateProcessAsUser using LoginUser with the token - same problem. Not the best solution if it worked as i dont wish to pass or store the login credentials would much rather use the security credentials of the process so hence looked at: GetCurrentProcess, OpenProcessToken and AdjustTokenPrivileges. Still to no avail now i know i must be doing some wrong and missing something obvious so would appreciate any help.
Heres a snippet not clean but general idea:
HANDLE HToken = NULL;
DWORD dwAccess = TOKEN_ALL_ACCESS;
HANDLE hServProcess = GetCurrentProcess ();
if (OpenProcessToken (hServProcess, dwAccess, &HToken))
{
LUID luid;
TOKEN_PRIVILEGES newState, oldState;
DWORD rl;
LookupPrivilegeValue (_T(""), SE_SECURITY_NAME, &luid);
newState.PrivilegeCount = 1;
newState.Privileges[0].Luid = luid;
newState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges (HToken, FALSE, &newState
, sizeof(oldState), &oldState, &rl))
{
rl = GetLastError();
return rl;
}
// execute zip process
if(CreateProcessAsUser(HToken
, NULL
, settings
, NULL
, NULL
, TRUE
, CREATE_NO_WINDOW
, NULL
, m_pSchedule->DirectoryBuff
, &st
, &proc) == 0);
}
Many thx to anyone who responds - sorry its a long post
|
|
|
|
|
Try this, but instead of using SE_SHUTDOWN_NAME use SE_SECURITY_NAME
BOOL bSuccess = FALSE;
HANDLE hTokenHandle;
// First off , get a handle for this process
HANDLE hProcess = GetCurrentProcess();
LUID tmpLuid;
TOKEN_PRIVILEGES tkp, tkpNewButIgnored;
DWORD lBufferNeeded;
// Now open the Attribute Token
//bSuccess = OpenProcessToken(hProcess, 0x20 | 0x08, &hTokenHandle);
bSuccess = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hTokenHandle);
// Get the present attribute
bSuccess = LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME , &tmpLuid);
// now change it
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = tmpLuid;
//tkp.Privileges[0].Attributes = 0x02;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bSuccess = AdjustTokenPrivileges(hTokenHandle,
FALSE,
&tkp,
sizeof(tkpNewButIgnored),
&tkpNewButIgnored,
&lBufferNeeded);
if(bSuccess == FALSE){
CString sErr = FormatSystemError(GetLastError());
::MessageBox(NULL, sErr, "", MB_OK);
}
bSuccess = CloseHandle(hTokenHandle);
ps. FormatSystemError(DWORD dwError) is my own function
CString CMainDlg::FormatSystemError(DWORD dwErr, BOOL bWithMsgBox){
LPVOID lpMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default
//MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US), // US English
(LPTSTR) &lpMsgBuf,
0,
NULL );
if(bWithMsgBox == TRUE){
::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
}
CString _s((LPCSTR)lpMsgBuf);
LocalFree(lpMsgBuf);
return _s;
}
|
|
|
|
|
Many thx.
Looks like it solved the problem with the privileges only problem now is the call to CreateProcessAsUser fails with GetLastError returning "The Operation completed successfully"
and no, the process was not started.
if(CreateProcessAsUser(HToken
, NULL
, "myapp.exe" // present in system32
, NULL
, NULL
, TRUE
, NORMAL_PRIORITY_CLASS
, NULL
, m_pSchedule->DirectoryBuff
, &st
, &proc) == 0)
{
... GetLastError, CloseHandle(HToken), return
}
CloseHandle(HToken);
btw Im launching a dos program (I dont wish to c the window) - before, when using CreateProcess, I was using the flag CREATE_NOWINDOW which was successful.
|
|
|
|
|
I do not know about creating a process as a user, but I did the following..
CString _sTitle("Title of the window");
STARTUPINFO stInfo;
PROCESS_INFORMATION psInfo;
ZeroMemory(&stInfo, sizeof(STARTUPINFO));
ZeroMemory(&psInfo, sizeof(PROCESS_INFORMATION));
stInfo.cb = sizeof(stInfo);
stInfo.cbReserved2 = NULL;
stInfo.lpDesktop = NULL;
stInfo.dwFlags = STARTF_USESHOWWINDOW;
stInfo.wShowWindow = SW_SHOW;
stInfo.lpTitle = _sTitle.GetBuffer(_sTitle.GetLength());
_sTitle.ReleaseBuffer();
CreateProcess("watchdog.exe",
"cmdline params" ,
NULL,
NULL,
TRUE,
CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE ,
NULL,
NULL,
&stInfo,
&psInfo);
// Wait a bit for the process to init
// But maximal 5 seconds
WaitForInputIdle(psInfo.hProcess, 5000);
It might be that the process is initializing ?
|
|
|
|
|
Thx Phil for the reply - yeah CreateProcess works fine was using that before but CreateProcessAsUser is the painful culprit unfortunately I'm still left with an uninitialised PROCESS_INFORMATION object when the call fails - and GetLastError says it completed successfully
|
|
|
|
|
This is probably a total beginner question!!
How do I convert ..
int iID =5
into a
CString strID
Thanks
|
|
|
|
|
strID.Format("%d", iID) should do the trick...
-Mike Zinni
Software Engineer
email: mzinni@rimail.com
AIM: zin9999
|
|
|
|
|
Thanks for answering me. I thought that would solve a problem that I'm having but it doesn't. So maybe you can help me with this.
The following lines of code are supposed to retrive data from a database. I know this works when all values in the database are strings. But now the first column are integers. The error I get is below. Do you know how I can fix this?
Thanks,
Alan
/***************************************/
long iID;
CString strName, strNumber;
...
while (!recset.IsEOF())
{
//Copy each column into a variable
recset.GetFieldValue("Address ID",iID);
recset.GetFieldValue("First Name",strName);
recset.GetFieldValue("Home Number",strNumber);
//Insert values into the list control
iRec = m_MyListControl.InsertItem(0,iID,1);
m_MyListControl.SetItemText(0,1,strName);
m_MyListControl.SetItemText(0,2,strNumber);
//Go to the next record
recset.MoveNext();
}
Error:
void __thiscall CRecordset::GetFieldValue(const char *,class CDBVariant &,short)' : cannot convert parameter 2 from 'long' to 'class CDBVariant &'
|
|
|
|
|
I havent done much with CRecordSet. But if you have no problems with CStrings, then get the first column into a CString and then convert it to an integer.
Nish
Check out last week's Code Project posting stats presentation from :-
http://www.busterboy.org/codeproject/
Feel free to make your comments.
|
|
|
|
|
You should use a CDBVariant object like this: (read MSDN for details about CDBVariant)
CDBVariant dbv;
recset.GetFieldValue ("Address", dbv);
iID = dbv.m_lLong;
or you can read it in a CString and then call atoi function to get an integer value
If you are going to port your application to VC7 you will notice that GetFieldValue does no longer take a CString as a first parameter. So you should use:
recset.GetFieldValue ((short)0, strName);
This is one bit of VC 6.0 that does not compile on VC 7.0
Best regards,
Alexandru Savescu
|
|
|
|
|
You have two choices here. You can either construct and pass a CDBVariant or you can pass a CString and convert the returned value:
CString strID;
recset.GetFieldValue("Address ID",strID);
long iID = atol(strID);
CDBVariant v;
v.Clear();
v.m_dwType = DBVT_LONG;
recset.GetFieldValue("Address ID", v);
I'm typing this without testing it, but this should be very close to what you need.
Cheers,
Tom Archer
Author, Inside C#
A total abstainer is one who abstains from everything but abstention, and especially from inactivity in the affairs of others.
|
|
|
|
|
i think the best way is
take an object CString strID;
use the following for conversion
strID.Format(" %d ",iID);
strID is a string object containing 5 as string value
u can convert anything into string
eg:
pointer ptr can b converted as
strID.Format(" %x ",ptr);
|
|
|
|
|
I'm building a Document/View based program.
When a user wants to use the program the following should happen:
a) A login dialog box should appear on the screen
b) If a user enters a valid login the program should become accessible
c) If a user enters invalid login information the program should end
d) And also if the user presses Cancel the program should end
something like this:
CDlgLogin dlg;
int nLogin = dlg.DoModal ( );
if( nLogin == IDOK )
{
//check login information
}
else if( nLogin == IDCANCEL )
{
//shutdown the program
}
What I'm not sure about is WHERE to put this information
I've tried the "ProgramView.cpp" and "MainFrm.cpp" files but I always get silly access violations or something like that when a user presses "Cancel"
What do I need to do for this to work ? Please please help me if you can
Best wishes from Iceland
Solini
|
|
|
|
|
The easiest way is to put that stuff into the CYourApp::InitInstance
Regards
Thomas
Finally with Sonork id: 100.10453 Thömmi
Disclaimer: Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.
|
|
|
|
|
A good place to insert this is in your CWinApp -based InitInstance , just before anything else. If the login fails, just return FALSE .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
we have a login screen just as you describe
at the end of InitInstance() we post a message to ourselves mimicking the 'log on' toolbar button
the logon box pops up very nicely
situations to avoid #37: "good morning ... how many sugars do you take in your coffee ... and what was your name again?"
coming soon: situations to avoid #38: "...and the dog was there too?"
|
|
|
|
|