|
In addition to what Albert said, language-wise you are "overriding" a virtual function. In the language, that means you are replacing the functionality provided by the base class with your own implementation. In many examples in courses this is what they show, overriding.
In this instance, and in many such classes in the Microsoft Framework, you are, in reality, "extending" the functionality provided by the base class. So, the base class is giving you the opportunity to do *more stuff* than it would do but it still wants to do it's own stuff too. Hence you need to call the base class explicitly to let it do it's stuff. And, as Albert said, whether you call it first or last depends on the functionality you are extending so the documentation / example should help.
For example, every MFC dialog can have an function that handles the event of "InitDialog", the OnInitDialog() function. Since you want to allow the base CDialog class to do its initialization first, the very first thing you should do in your "OnInitDialog()" is to call CDialog::OnInitDialog().
That is the difference between the language defining "Virtual Functions" and an implementaion of a feature (Asynchronous Sockets) using virtual functions to obtain the desired effect.
|
|
|
|
|
Chuck O'Toole wrote: In this instance, and in many such classes in the Microsoft Framework, you are, in reality, "extending" the functionality provided by the base class.
Well put...
|
|
|
|
|
How to enumerate printers connected to the network in metro apps
|
|
|
|
|
You could start by posting your question in the metro forum.
Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness
|
|
|
|
|
|
I assume it is done the same way that any other Windows software does.
Start with EnumPrinters[^] and continue.
Watched code never compiles.
|
|
|
|
|
I copied this off the internet without fully understanding how it works, and now it's not working when I compile as Release version. In Debug it works fine.
Not sure if I should dump it and reinvent the wheel, or if there is just a slight mistake in the code. The part I don't understand is in bold.
WCHAR extension [32];
WCHAR* peek = szFileName + szFileName [ wcslen( szFileName ) - 1 ];
while ( peek >= szFileName )
{
if (*peek == L'.') {
wcsncpy_s ( extension, peek, wcslen( peek ) );
break;
}
peek--;
}
swprintf_s( szFileExtension, L"%s", extension );
Edit:
The peek gets stuck with a 2 dot extension, and won't progress forward like
project.config.user
And then all file extensions are .user after that.
But just in Release
modified 25-Apr-12 22:58pm.
|
|
|
|
|
If you are using MFC, why don't you use CString::ReverseFind('.') ?
|
|
|
|
|
I should of said it was just a stock win32 project in c++
|
|
|
|
|
Further to Flaviu2 said,
if you're not using MFC, this will work:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
wchar_t *wszFilename = L"project.config.user";
wchar_t *extension;
wchar_t *dotPosition;
size_t extensionLength;
dotPosition = wcsrchr(wszFilename, '.');
extensionLength = wcslen(dotPosition);
extension = (wchar_t*) malloc(extensionLength * sizeof(wchar_t));
wcscpy(extension, dotPosition + 1); wprintf(extension);
}
Output:
user
|
|
|
|
|
Ooo, have a 5 'cause it's nice to see people using standard language features and types rather than sucking up to a particular OS/compiler and getting their code stuck on them for evermore.
The only comment I'd make is in the line:
dotPosition = wcsrchr(wszFilename, '.');
Should the character constant be a wide character? I haven't tried compiling it or looking at the standard so I could be very wrong!
Cheers,
Ash
|
|
|
|
|
Thanks mate!
Not so sure, I guess it would have been better to explicitly cast the '.' to a wchar_t. I figured since the function takes a wchar_t that this would be implicitly cast for me.
Compiling with gcc 4.something, the only warning I get was for line 7 (the wszFilename declaration) -
"warning: deprecated conversion from string constant to 'wchar_t*' "
It compiles & runs just fine with the -Wall and -Wextra compiler flags.
If the line in question is changed to:
wchar_t *wszFilename = (wchar_t*)"project.config.user";
Then it compiles with 0 warnings. [EDIT: but crashes like a bus!]
The line should read:
wchar_t *wszFilename = (wchar_t*)L"project.config.user";
Nice catch!
Simon.
modified 26-Apr-12 6:26am.
|
|
|
|
|
If you change wszFilename to a const char * you can avoid the cast. I can't see anywhere wszFilename is modified so you should be alright.
Another thing you might not be aware of: In C you don't need to cast the return value of malloc or calloc - void * is type compatible with any sort of pointer so (at least in C90, not sure about C99) you can convert them to anything implicitly.
Cheers,
Ash
|
|
|
|
|
Well,
I realize that it is just a code sample... but there are alot of novice programmers learning by reading these forums. You might want to free() the memory you allocated for the extension and you forgot to return an integer for the main() function.
Best Wishes,
-David Delaune
|
|
|
|
|
Thanks David,
I certainly had overlooked both of these points. Time I exercised a little more diligence..
Simon
|
|
|
|
|
What if the path is \\server\share\path.path\file?
|
|
|
|
|
|
You kidding me, there's an app for that!
So PathFinderExtension trumps the sample function posted earlier?
Thanks Dave, spent way too much time on it last night.
|
|
|
|
|
There's also a CRT function for this - _splitpath_s /_wsplitpath_s
|
|
|
|
|
That works great. Thanks
But I don't get it. I'm not sure if the wcsncpy_s bombed, or if I have some kind of buffer error, that never got flagged.
I have a registry function that's doing the same thing, but just the 1, so far, all others work fine.
I'm going to post it in a new post.
|
|
|
|
|
jkirkerx wrote: I have a registry function that's doing the same thing, but just the 1, so far, all others work fine.
Not sure but if you post the contents of the function and the calling function I might be able to pinpoint your problem.
Because I am somewhat familiar with the project you are working on... last comment about path handling:
In the future I would recommend that you use the Shell Path Handling Functions[^] when working on the windows platform rather than attempting to implement your own path parser. Over the past 20 years or so there have been hundreds of vulnerabilities associated with path handling/parsing... because many software engineers attempted to implement an algorithm of their own.
Best Wishes,
-David Delaune
|
|
|
|
|
Dear Mr. David Delaune,
I have received your feedback.
Thank you so much. please give me your email!
Best Regards,
L.Q.LONG
|
|
|
|
|
Le Quang Long wrote: Dear Mr. David Delaune,
I have received your feedback.
What feedback?
|
|
|
|
|
THe code snippet assumes UNICODE is being used.
I would suggest to use generic mapping that will work for both: ANSII and UNICODE:
As for retrieving parts of the path why not to let CRT do it for you using generic (_tsplitpath_s)?
For example:
LPTSTR lpszPath = _T("project.config.user");
TCHAR szFilename[MAX_PATH] = {0};
TCHAR szExt[MAX_PATH] = {0};
_tsplitpath_s(lpszPath, NULL, NULL, NULL, NULL, szFilename, _MAX_FNAME, szExt, _MAX_EXT);
JohnCz
|
|
|
|
|
I implemented the PathFinderExtension from Dave's Suggestion, but your suggestion looks quite interesting. hmm.
I didn't know about that function and how to implement it.
The PathFinderExtension is working quite well now, but let me fix my errors first before making any more changes.
|
|
|
|