Date: | May 9, 2007 / year-entry #164 |
Tags: | other |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20070509-00/?p=26923 |
Comments: | 61 |
Summary: | Sometimes I see people ask a question and get an answer, but the answer doesn't quite work. But instead of trying to understand the answer in order to see why it doesn't work and develop a better solution, they just play stupid. Here's an example. The names have been changed but the story's the same.... |
Sometimes I see people ask a question and get an answer, but the answer doesn't quite work. But instead of trying to understand the answer in order to see why it doesn't work and develop a better solution, they just play stupid. Here's an example. The names have been changed but the story's the same.
An answer came back rather quickly.
Some time later, the customer came back with a follow-up question.
(So much for people knowing what to do when they get this error message.)
Don't be helpless.
Your head isn't just for looks.
At least pretend to try to understand what you're doing.
In this case, the function is #define EPHNT_DUMBO 0 #define EPHNT_BABAR 1 #define EPHNT_WHITE 2 #define EPHNT_BRIGHT_PINK 3
Wow, I bet the person who wrote Armed with this new skill, perhaps you can solve this person's problem:
|
Comments (61)
Comments are closed. |
error C8000: ‘User’ : unable to write code
If people won’t have the habit to delegate responsibility, there were no market for horoscopes.
Was this a trick question? There’s no DS_SHELLEXT.
Ooh, and look at that, I’m guilty of doing the same thing. :)
And I guess the fuller answer can be gleaned from here: http://blogs.msdn.com/oldnewthing/archive/2005/02/08/369090.aspx, which is to say that the user most likely wanted DS_SHELLFONT, viz, "Ah, but now there is a new flag, DS_SHELLFONT. Starting in Windows 2000, if you specify the DS_SHELLFONT dialog style for your DIALOGEX dialog template, then the dialog dimensions are taken relative to the font you specified in your template (which is probably what you wanted) rather than relative to the property sheet frame font. If you leave off the flag (as older programs will), then the property sheet measurement code remains bug-for-bug compatible with previous versions."
If MSDN wasn’t so pathetic with their index nowadays, finding identifiers like this would be simpler.
MSDN prior to 2001 was MUCH better.
Seems that if you don’t write in Managed Code these days, you’re on your own.
Agreed, but don’t you sound grumpy today?
"If MSDN wasn’t so pathetic with their index nowadays, finding identifiers like this would be simpler."
There’s a reason the SDK doesn’t ship with only preparsed headers. If you don’t have ‘grep’, find a copy now. Seriously: grepping headers is substantially faster than looking at documentation to find the name of a constant you can’t quite remember…
From the question: "Is there a file I have to include?"
Almost invariably. To find out "grep [constant] [path to SDK]/include/*.h".
If only there were an easy way of doing the same thing with symbols in libraries. :(
Of course it would help if Windows had some useful utilities… like, say, grep…
Well. You learn something new every day.
My first C# program was rgrep. :)
The venerable ‘find’ command works well enough. Can’t do regular expressions, obviously, but it does work if you just need to find a string.
Otherwise, most good editors have a find-in-files command, and many support regular expressions. All common versions of Visual Studio (6.0, 2002, 2003, 2005) have the feature, as does my favourite slim-line editor, TextPad.
You’ve got no business operating a C++ compiler if you can’t find the definition of a macro or constant you’re using. The Platform SDK doesn’t call out where the macro or constant definitions live – only the function or structure – but they’re not that hard to find. Likewise writing P/Invoke declarations in C# or VB.
There’s the Cygwin tools, or if you don’t care to spend several hundred megs on downloading and installing them, you can always just look for Win32 builds of grep — there are a million of them.
And yeah, findstr is okay, I guess, but I’m used to *nix tools.
You’re going to have to do a lot of grepping to find DS_SHELLEXT :)
I’m fond of windows grep (http://www.wingrep.com/), I even registered a copy!
I agree, the new version of MSDN (the one that shipped with VS 2005) is almost completely worthless for C/C++ Win32 development. I get documentation for just about everything except what I’m looking for. Though I have a feeling this isn’t Raymond’s fault.
Yes Raymond! Get mad! Seriously, let the Hulk out.
Heh. Raymond does not suffer fools gladly. Good on him.
-Buxley
“There’s a reason the SDK doesn’t ship with only preparsed headers. If you don’t have ‘grep’, find a copy now. Seriously: grepping headers is substantially faster than looking at documentation to find the name of a constant you can’t quite remember…”
How does one grep for a constant who’s name they can’t quite remember? Is this like looking in a dictionary to find the correct spelling of a word you don’t remember how to spell?
the great thing about documentation is I can usually remember the name of the function that takes the parameter I can’t remember how to spell. I can also remember how to find the documentation. Its always at http://www.google.com.
This post strikes me as preachy, and not constructive at all. There is two lines worth of information here:
Q: I get an error "DS_SHELLEXT is not defined". Is there a file I have to include?
A: The define is called DS_SHELL_EXT
The bigger problem is that searching headers for approximate bits of knowledge is not easy. IntelliSense could suggest replacements based on a partial match with one of the identifiers in the database.
"This post strikes me as preachy, and not constructive at all. There is two lines worth of information here:
Q: I get an error "DS_SHELLEXT is not defined". Is there a file I have to include?
A: The define is called DS_SHELL_EXT"
Are you sure about that? Perhaps you should reread the post, ignore the preachy tone of it, and listen to the moral of the story.
What about Visual Assist X. It can check the define for you and also autocomplete it. All in all a very primitive example.
"If MSDN wasn’t so pathetic with their index nowadays, finding identifiers like this would be simpler."
MSDN prior to 2001 was MUCH better."
I chiefly use the online versions, which suffer the same problems, but can be gotten around using Google.
It always amuses me that I’m using Google to find stuff on the MSDN site.
Windows *does* have grep, it’s called findstr.
> If only there were an easy way of doing the same thing with symbols in libraries. :(
Oh, act like a man.
link /dump /symbols %systemroot%system32*.dll > exports.txt
findstr /i SomeSymbol exports.txt
You can also write a trivial shell script (yes, evne in cmd.exe’s wretched language) for dumping each DLL to a separate file, and then using "findstr /i SomeSymbol *.txt", which will give you the name of the DLL very easily. For example:
for %i in (%systemroot%system32*.dll) do (link /dump /exports %i >%~ni.txt)
Then later:
findstr /i SomeSymbol *.txt
Hmmm… maybe I misinterpreted your comment.
I read it to be "there’s no point in searching for DS_SHELLEXT – you won’t find it, it’s not there, that’s why you got the error."
But now that I reread it, I see that you more likely meant it as "I assume the user searched for DS_SHELLEXT and didn’t find it; the logical next step from the user’s perspective would be to look for other DS_ constants"? If so, I agree… I retract my cats-have-four-legs comment.
God, some people are so slow when it comes to brain activity, they would pass under the radar or read as "DEAD FISH".
In Visual Studio you could also type DS_ and then hit Alt+Right for autocompletion. Alternatively, if there’s already a DS_SOMETHING in nearby code, right-click on it and select Go to definition.
As for grep, doesn’t anyone use Indexing Service? I wrote a VS add-in to search using Indexing Service years ago. I even have separate catalogs for different SDK/DDK versions, the Rotor versions, just my projects, etc. pp.
Yeah, the MSDN index sucks. Pretty much any time I ask for a function like, say, GetWindowPlacement, I end up getting sent to the modified MFC version and the useless CE documentation. Anyone know how to disable WinCE documentation? (Note: Not Raymond’s fault, not implying that it is, not implying that he can go thwack the MSDE people on the head and get them to change this stupid behavior.)
[quote]How does one grep for a constant who’s name they can’t quite remember? Is this like looking in a dictionary to find the correct spelling of a word you don’t remember how to spell?[/quote]
Always find ApiViewer2004 handly for this purpose.
Type a function name, right-click then click reference. And you have a list of constants to choose from. :)
http://www.activevb.de/rubriken/apiviewer/index-apiviewereng.html
If this is the customer’s first or second time to write Windows programs, I think they deserve a bit more patience. If they’ve been doing it for a few years then this complaint is spot-on. It could be pretty hard to guess which situation this is, just from reading these questions in a newsgroup.
Even for Windows-experienced programmers, it can be hard to figure out why _WIN32_WINNT has to be defined sometimes but not other times, it can be hard to figure out why right-clicking an identifier and choosing "go to definition" doesn’t do so, etc. Then figure out which of 20 "Include" directories is the correct directory to look in, and which rat’s nest of #includes leads to the .h file that has the declaration. It’s doable, but we should have different responses to different programmers depending on their experience.
Wednesday, May 09, 2007 10:48 PM by Bob
What’s useless on one half of a project is crucial on the other half. Yeah it would be nice to have that fine-grained filtering, for example "this search needs MFC and CE but not desktop Win32" etc. But in my experience, if a search came close enough to find one of those pages in the first place, I only need one or two extra mouse clicks and an additional 10 seconds or so in order to find the other pages.
I always think it’s so very Microsoft that if you click on the Windows CE version of a Win32 function, it’s almost always identical to the desktop version even though Windows CE is a completely separate code base (as far as I know). If you know CWnd::ApiFunction(foo,bar) is usually either ApiFunction(m_hWnd,foo,bar) or behaves very much like it, the MFC version is ok too.
It’s all very well to talk about suffering fools and whatnot, but there are two hidden assumptions here that are likely wrong.
1) The user didn’t bother to try to solve the problem himself.
The user may have been scouring his tree looking for DS_SHELLEXT, reading the documentation for property sheet dialog templates, and perhaps even working on other issues while he waited for a response to his email question.
2) If I know an easy way to find the answer, finding the answer is easy.
Finding the answer is easy *when you know what it is.* There are any number of false clues here that are potential time sinks.
> Obviously if you search for DS_SHELLEXT you won’t find anything; that’s why you’re getting the message "undeclared identifier" in the first place.
Thank you for illustrating my point. (As an aside, I’ve noticed that the phrases "obviously", "clearly", "it goes without saying" etc. usually precede a logic error.)
Your argument is:
* The user got an "undeclared identifier" message.
* Misspelled identifiers will result in "undeclared identifier" messages.
Therefore, the identifier was misspelled.
This argument is flawed, though its conclusion happens to be correct in this instance. (Obligatory "cats have four legs" analogy left to the reader.)
> One would hope the next step would be "Well, what dialog styles are defined?"
*A* perfectly reasonable next step, indeed. I, too, would hope that the customer would (eventually) pursue this admirable troubleshooting strategy.
Alas, there are many ways to be wrong, and comparatively few ways to be right…
Thursday, May 10, 2007 12:42 AM by An
Yes Almost, Almost, Almost. Like English and American, almost the same but just enough different to deceive you into writing something that doesn’t mean what you thought it meant.
Even for the 75% of descriptions which are accurate, you have to read the correct page and you have to exclude your memories of what you read for the other version. Examples:
The parameters to a DllMain function.
The return value of EnumWindows when you found what you were looking for.
The return value of GetMessage when it fails.
Bob’s wish is half-right. Meanwhile, if you have to make one or two extra mouse clicks to get the page you really need, you’d better do it.
I guess what he really wants to do is fix the sizing problem of his dialog box. The sizing problem caused by less information about the used font. Measurement of the dialog box depends on the used font. The dialog box template needs information about that. This can either be through DS_SETFONT and/or DS_SHELLFONT. DS_SHELLFONT is easy to use cause it tells the system to use the system font. But whats about that DS_SHELLEXT? Just a suggestion: What he wanted to write is DS_SHELLTEXT (there is no Ext-Style that gives a solution) and what he meant is DS_SHELLFONT. But it doesnt matter.
"It always amuses me that I’m using Google to find stuff on the MSDN site"
Oh! So, so, so, true.
I find this thread interesting in that its been hijacked by people complaining about MSDN (since 2001 !!!). Either we all jus harken back to the gold old days when help was help and not xml/html/webservice/online nonsense, or it truly has become a worse user interface over the years.
It used to be CE links everywhere in MSDN, now its all managed stuff, and why is it every time I install it it seems to have a different underlying technology. I expect next year it’ll have a special Vista-aware UI to replace the one i’ve just gotten used to (again).
Compiler error on DS_SHELLEXT occurs.
Look for list of valid styles.
Phew. Made it. Do you guys need help tieing your shoes as well? Windows programming is for the big boys (and girls). Kindergarten is down the hall.
"How does one grep for a constant who’s name they can’t quite remember? Is this like looking in a dictionary to find the correct spelling of a word you don’t remember how to spell?"
grep is better. If you only know the first and last chars:
grep "DS_.*EXT" blah/*.h
Visual Studio’s Find also understands regular expressions (look for the checkbox)
Most index searches (MSDN, Google, etc.) work on tokens; so they wouldn’t help here, unless you knew the name of one of the other constants beforehand. (Well, once this blog post is indexed, it might help.)
“Find” in the correct file would work, presuming that you knew which was the correct file beforehand.
grep/findstr for DS_ would work admirably, presuming you knew that they existed, and were confident that the “DS_” was not the misspelled part of the identifier.
>
I thought the answer to the question would be "No, there is no file to include".
The question is wrong.
In general, you can make a CE-style help page out of an ordinary Win32 document by simply removing half of the defined constants and changing all pointer types after the first to "must be NULL."
Norman: That’s just it. I’m not wishing for fancy UI at this point, because it’ll never happen. All the filtering options that were half-right in 7.x got the axe in 8.0 because "no one used them." These days, I’m just getting increasingly tempted to learn the registry formats necessary to deindex CE documentation before I go in and start deleting files.
My usual answer to the problem of suffering fools gladly: There are always going to be fools anyway, so the alternative of suffering them miserably is a poor choice. Just who is going to be miserable, anyway?
Raymond’s solution is better: To suffer fools gleefully. If he draws a little fire for poking fun, it only provides more opportunity to laugh at fools.
[I don’t know why everybody is so fixated on grep. Grep is not the answer. The answer is, "Gosh, what are the valid parameters here? Let me look among those." -Raymond]
It’s simple, really:
find /usr/include -follow -name ‘*.h’ |xargs grep DS_|grep SHELL
find, xargs, and grep are the most useful bits of unix I know of. That and custom shell scripts to plug into xargs that mostly reorder args.
Cooney: and you continue to miss the point. IF DS_SHELLEXT appears not to exist (google returns no hits, MSDN the same) then the smartest thing to do is, as Raymond said, figure out what the actual constants that are available are, and try to figure out what the right one was, which, in this case, I assume is DS_SHELLFONT, altho Raymond never actually answered that, and to be honest, which the right constant is isn’t the point of the article; the point is the mindset of being willing to go looking for the right information, rather than hoping someone will come along and tell you.
No, Rick, you’re missing this rather large point: the find thing I posted is an efficient method for locating all the DS_ stuff in the include files, with an intelligent guess at a pattern to narrow the results. I’m handing you a tool.
I think the "next logical step" depends on the user. From this user’s point of view, grep is the next logical step:
His program does not compile because of an unknown identifier => his experience tells him it is certainly because he did not include a header file (compilers like to do that to beginners, whine constantly about headers… gosh, can’t they do what I mean?? :) ) => the next step is to grep all include files to find the correct one.
Of course at this point, when he doesn’t find anything and when google only shows the forum where he got the response, the user SHOULD start to question what he is looking for!!
And start looking for valid identifiers, where they are defined etc.
I tend to agree with Norman that it all depends on the experience the user has. When you begin, you usually don’t question what "experts" tell you, and that’s why you end up looking for "missing header file" instead of "list of valid identifiers which shall include the one I am looking for".
I hate giving absolute solutions, because it makes people come back to me with minor questions, and I become a pre-reference resource. A friendly but slightly indirect pointer to the solution helps ensure that they read the reference, and that they read it before asking me in future. I *like* getting intelligent questions.
"Doesn’t work, eh? Clearly it needs more ninja. Take a peek at the available constants for the function, to see if there are any containing the word ‘ninja’." Problem usually sorts itself out. This is a variant of the "blow dust out of the connector" help strategy.
If I feel that they really need to read the page on the function, I may deliberately mis-specify the function parameters, and add "this will not work, as I do not have the function documentation in front of me: you can find the right syntax for the function in the docs, and while you’re there, check out the section on pirate-handling, too."
All this also has the advantage that you get the reputation as a wizard. Wizards never speak in straight lines.
The general problem is, the youth of today isn’t used to help themselves because they haven’t learned it. Instead of trying to find a solution on their own (Which might need some thinging.), they put their question in a message board. That is much easier: "Let other solve my problem." That works up to a special degree. But one day you will cross that line and then you will be lost.
Whn I was young there was not internet, there were no message boards. How does a for loop work in BASIC? OK, go ask dad. OK, doesn’t no it, so I had to find it out myself.
Sometimes I wonder, if the internet would break down completely, would they be able to survive? ;)
How hard would it be to have a spell-checker in the compiler, so that the error includes something like: "did you mean EPHNT_BRIGHT_PINK?" It won’t always work, and will occasionally have false positives, but would help with many typos like this.
I kind of doubt that Raymond would have no real problem with the user using grep or whatever.
The key here is that the user should do something rather than expect other people to do all of their work.
Another value of looking at the header or the help for the function, is that you might learn more than just the answer to your question.
Cooney–and now your tool, which might be of use in some cases, shows you that DS_SHELLEXT doesn’t exist. Now what?
Hopefully you do what I did first: google or search MSDN, find out that there’s no such thing, and then…try to find out what the valid parameters are. (And I’ll usually just do a search in Windows Explorer before I resort to grep, anyway.)
Real men don’t grep, they findstr :)
Rick C: no, you’re missing the point. The command Cooney gave finds all DS_ constants, so that you can pick out the correct one. (IMO, Raymond Chen is also missing the point – sure, "Gosh, what are the valid parameters here? Let me look among those" is sensible, but how are you supposed to figure out what the valid parameters are in the first place?)
Cooking for Engineers and The Engineer’s Cookbook will be indexed sufficiently far apart for me not to notice the mistake, but then I’m just lazy.
Yeehaw, I tried the search route, but I wasn’t paying any attention when the whole "property sheet" thing was being discussed (I’m here for the zinghappy repartee in the comments section, more than the win32 stuff).
Can ya throw me a function name so I can follow along with the bouncing ball and feel like I learned something? The docs said I should probably understand what I was doing before starting (http://msdn2.microsoft.com/en-us/library/ms652415.aspx), but what do they know? ( "Everyone knows MSDN docs are going downhill" blah blah blah :-)
"Real men don’t grep, they findstr"
Real men don’t actually use Windows. Just because somthing is stupid doesn’t make it manly. It helps, though.
Real men don’t actually use computers, they just stare at them until the computers comply out of fear.
> I kind of doubt that Raymond would have no real problem with the user using grep or whatever.
>
Raymond’s problem is that he may not embrace a utility which isn’t approved by microsoft. He probably would like the user to use grep, but cannot say that officially.
Jealous?
Nah, those are nancyboys. Real men find|xargs grep|awk|unholy.pl before breakfast.
Raymond’s still in the kernel configurator changelog, dontchaknow.