|
Hi Aescleal,
Thanks for your answer. I should been more explicit though. Its a C compiler, STRING is a type definition.
The code is in an Atmel microcontroller and has very little space left in flash for more code, that was why I used the global variable instead of a local pointer each time the function was called.
A work mate pointed out I could use sprintf.. which would likely be no faster, but it would be much cleaner looking.
Your right about the macro calls - I'm going to take those out.
Thanks,
Mark Brock
"We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen
|
|
|
|
|
It was the inline that made me think it was a C++ compiler - I'm not up on C99 (which presumably added it) so sorry about any confusion.
While sprintf is a bit cleaner one thing to watch out for is the size of the code you get linked in when you use sprintf. It's a bit of a monster function so if it's not already linked in the code base you might be better off using strcpy/memcpy [1] to save space. If you're in a corner try both versions and see which is smaller.
Another slight problem with sprintf is that the function has got to parse the format string before it can actually copy anything which usually makes:
sprintf( buff, "%s%s" );
a pretty slow way of doing strcpy and strcat.
One final point (and if you're maintaining a code base it's not something you can change easily to) is to use length prepended strings instead of zero terminated ones. As one of the other posters (Chris L IIRC) pointed out if you know the size of the strings you can use memcpy instead of strcpy. Prepending the size saves you the balls ache of calling strcpy everywhere at the cost of a bit more arithmetic to maintain the length.
Cheers,
Ash
[1] Just about every compiler I've used since 1991 has inlined calls to strcpy and memcpy as it eliminates the function call overhead which is faster and saves space. I've never seen an inlined sprintf implementation in C though.
|
|
|
|
|
_snprintf(...) for avoiding overruns.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
you could probably _snprintf all the parts into the output string.
alternately, if you want to improve performance, take a look at all those strcat calls. each one of those does a scan of the output string, looking for the end.
strcpy(_acLine, pcH1);
strcat(_acLine, acBuff1); <-- full pass over _acLine
strcat(_acLine, pcH2); <-- another full pass over _acLine
strcat(_acLine, acBuff2); <-- another full pass over _acLine
but if you know the lengths of pcH1, acBuff1, pch2 and acBuff2, you will know where the end of _acLine should be after each concatenation.
so you can simply memcpy the substrings directly where they should be:
memcpy(_acLine, pcH1, len_pcH1);
memcpy(_acLine + len_pcH1, acBuff1, len_buff1 );
memcpy(_acLine + len_pcH1 + len_buff1, pcH2, len_pcH2 );
memcpy(_acLine + len_pcH1 + len_buff1 + len_pcH2, acBuff2, len_buff2 );
acLine[len_pcH1 + len_buff1 + len_pcH2 + buff2] = 0;
and if you know the length of acBuff1 and acBuff2 then maybe you could do this:
memcpy(_acLine, pcH1, len_pcH1);
memcpy(_acLine + len_pcH1, lcd_String(dV1), len_buff1 );
memcpy(_acLine + len_pcH1 + len_buff1, pcH2, len_pcH2 );
memcpy(_acLine + len_pcH1 + len_buff1 + len_pcH2, lcd_String(dV2), len_buff2 );
acLine[len_pcH1 + len_buff1 + len_pcH2 + buff2] = 0;
... and get rid of those first two strcpys, too.
or, if you want to get really low-level, just concat the strings yourself. something like:
LPSTR pOut = _acLine;
while (*pcH1) *pOut++=*pcH1++;
while (*acBuff1) *pOut++=*acBuff1++;
while (*pcH2) *pOut++=*pcH2++;
while (*acBuff2) *pOut++=*acBuff2++;
*pOut = 0;
|
|
|
|
|
Hi Chris,
Awesome answer! I do know all the (expected) lengths. I'll give your idea a go tonight!
The first two strcpy calls are horrible... But for some reason the function wouldn't work without them... maybe something to do with the Atmel compiler..
Thanks,
Mark Brock
"We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen
|
|
|
|
|
be sure to try that last chunk of code. that should out-perform any of the others.
|
|
|
|
|
Will do...
I'm going to give this a crack too..
http://en.wikipedia.org/wiki/Duff%27s_device
It will be interesting to see the different execution times of all these methods.
Mark Brock
"We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen
|
|
|
|
|
Hi,
once of my friend asked me about this.
is there any difference between Windows Job and Scheduled Tasks?
I have used the win32_ScheduledJob class for monitoring the scheduled tasks.
But it doesn't return anything even that task in running state.
Please let me know how to create a windows job manually for testing and which win32 class to be used for monitoring?
Thanks
Today's Beautiful Moments are
Tomorrow's Beautiful Memories
|
|
|
|
|
Hi Friends
I have created a class CImageViewer from CStatic. I also need scrolling of image in horizontal and vertical. I set scrollinfo for both scrolls and scrollbars (both) shown in my control. But it does not work. How can i solve this problem
thanks in advance
-kk.tvm-
|
|
|
|
|
Please explain what you mean by "it does not work" and provide relevant code snippet.
|
|
|
|
|
Hi Cédric Moonen,
Basically my class is subclass of CStatic.
I set scrollinfo using below code
void CImageViewer::PreSubclassWindow()
{
CRect rect;
GetClientRect( &rect );
SCROLLINFO si;
ZeroMemory( &si, sizeof( SCROLLINFO ));
si.cbSize = sizeof( SCROLLINFO );
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = nScrWidth;
si.nPage = rect.Width();
si.nPos = 0;
si.nTrackPos = 0;
SetScrollInfo( SB_HORZ, &si );
CStatic::PreSubclassWindow();
}
and handled OnHScroll Message
void CImageViewer::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
SCROLLINFO si;
int nScrollPos = nPos;
pScrollBar->GetScrollInfo( &si );
int nCurPos = si.nPos;
int nMin = si.nMin;
int nMax = si.nMax;
switch( nSBCode )
{
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
nScrollPos = si.nTrackPos;
break;
case SB_LEFT:
nScrollPos = nMin;
break;
case SB_RIGHT:
nScrollPos = nMax;
break;
case SB_LINELEFT:
nScrollPos = nCurPos - 2;
break;
case SB_LINERIGHT:
nScrollPos = nCurPos + 2;
break;
case SB_PAGELEFT:
nScrollPos = nCurPos - 5;
break;
case SB_PAGERIGHT:
nScrollPos = nCurPos + 5;
break;
case SB_ENDSCROLL:
nScrollPos = nCurPos;
break;
}
if(nScrollPos < nMin) nScrollPos = nMin;
else if(nScrollPos > nMax) nScrollPos = nMax;
pScrollBar->SetScrollPos( nScrollPos );
Invalidate();
CStatic::OnHScroll(nSBCode, nPos, pScrollBar);
}
After this a scroll bar appears with my control. But i can't change scroll position.
-kk.tvm-
|
|
|
|
|
kk.tvm wrote: But i can't change scroll position.
Do you mean that the scroll is displayed properly and that you can use it correctly but it doesn't have any effect on your drawing ?
That's what I would guess by seeing your code, since you do not do anything with the scroll position (it's a local variable). What you need to do is remember the scroll position and use it when you draw your picture: you have to apply it as an offset to the picture. It's not because you added a scroll bar to a control that it will magically move when you use the scrollbar. You have to do that yourself by shifting the picture when the scroll is moved.
|
|
|
|
|
Hi Cédric Moonen
ok, i want to write code to scroll the image.
what i mean....
Scrollbar is properly shown with control. But when i press arrow heads (left or right) or thumb it does not move or changed, like disabled.
thanks in advance
-kk.tvm-
|
|
|
|
|
Perhaps your increments are too small compared to the full lenght of the scroll bar. Did you check with the debugger to see the values nMin, nMax, ... to see if everything seems correct ? And compare them to the -2/+2 you add when you click the arrow. I guess they are neglectable compared to nMax.
|
|
|
|
|
Hi Cédric Moonen
Thanks a lot of your valuable reply
-kk.tvm-
|
|
|
|
|
|
Most SIM card readers connect to the computer by USB, that would be a good place to start
|
|
|
|
|
Hi, I have two menu resources (IDR_MAINFRAME) with different conditions (created using 'right mouse-> Insert Copy' on original). I use them in different Releases. The thing is I can't get second one to load, always the original one is shown. I set condition for both VER1 and VER2, I manage Project Properties in resource and c/c++->Preprocessor parts but still cant get the the second one to be loaded?
Thanks in advance
|
|
|
|
|
Try running through the debugger to see exactly what resource id you are using when you try to show the menu.
It's time for a new signature.
|
|
|
|
|
you better load and set the menu at runtime, so you get better control of it.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
It's an IDR_MAINFRAME menu, it loads I guess in MainFrm::OnCreate, why doe I need to do all that, why doesn't it loads corectly?
|
|
|
|
|
your second menu has and different identifier or language. IDR_MAINFRAME2 ? So it wont get loaded, but the standard one.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
No the ID is the same "IDR_MAINFRAME", but they have difrerent 'Language' and 'Condition' property set.
Thanks
|
|
|
|
|
I have a Visual C++ application. In my application I show a list of all the
printers installed. I get the
list of priters with EnumPrinters() function and level 2. However I am
interested only in fetching a list of physical printers and not the Virtual
Priters like "Microsoft Office Document Image Writer" and "Adobe PDF".
How does one distinguish a physical printer from a virtual printer?
I have already looked up DeviceCapabilities() API and DEVMODE structure and
EnumPrinters() with different values for the parameter "Level". But nothing
seems to return valid information to identify if a pinter is virtual or
physical printer. Can someone provide some pointers? Links to some sample
code? thanks in advance.
|
|
|
|
|
You should enumerate the different buses like the USB bus to get all connected devices.
Even then it is not guaranteed that a detected printer is not virtual because some packages like the Device Simulation Framework (DSF) from Microsoft installs a bus driver at the lowest layer in the stack which helps create virtual devices like printers.
|
|
|
|