Re: Graphing problem

Tech-Archive recommends: Fix windows errors by optimizing your registry



See below...
On Fri, 8 May 2009 01:42:56 -0700 (PDT), Richard Russell <news@xxxxxxxxxxxxxxx> wrote:

On May 7, 2:36 pm, Joseph M. Newcomer <newco...@xxxxxxxxxxxx> wrote:
I'm sorry, but that is not an exaggeration.

Ahem. "single worst resource in the known universe for proper
programming methodology" is not an exaggeration? I think you need to
get a sense of perspective!

Petzold's programming style is among the very worst possible for doing
Windows programming

Now, sensibly, you're toning down your language ("among the very
worst..."). I'm not sure I would even agree with that, but I'm
pleased that you tacitly accept that your earlier comment was over the
top.
****
All other poor styles of doing Windows programming methodology emulate Petzold. Therefore,
this book is the ancestor of all bad books on Windows programming. So it is among the
worst, only because there are a number of equally bad books that copied his style.

There is nothing salvageable about Petzold's programming style. The notion that you can
reach up, from some random subroutine, and change the state of a menu item, is in and of
itself a poor idea. His overuse of global variables is a disaster. The failure to
maintain any kind of OO discipline in a system which is intrinsically OO (windows are
objects, their messages are virtual methods of those objects) leads to ultimate disaster.
****

You damage any credibility you have by suggesting that Petzold's style is in any
way acceptable.

I didn't make any such suggestion. I criticised your use of
hyperbole, which has no place in a technical discussion.
****
I don't consider factual statements hyperbole. You may not like it, but Petzold's book
fails in almost every way to create proper understanding of modularity, orthogonality, and
maintainability, among other important concepts it gets wrong. While teaching the Windows
API, it also teaches bad program structure. It has caused untold damage to the task of
programming Windows applications. I continue to be amazed that people follow his bad
examples. (Actually, I remain mildly amazed that anyone programs in native Win32 code
given you can write in MFC and do it all more readily, getting code out faster, and code
hwich is more modular and more maintainable per unit effort than native C code)
****

The longest a case should be, excluding the break/return, is one line.

That is your personal opinion, but not one that I suspect many people
share. There is, of course, a point at which the code in a 'case'
should be hived off into a function, but two lines is not it!
****
Why not? Is there some reason that writing code as bad as the example that started this
thread should be justified? Variables that are not initialized? I've seen cases where
resources are not properly released. There is no structure here, just random statements
flung together into a mish-mash of unintelligible and unmaintainable code. For example,
if the case requires a value and that value is not computed in the case, but is computed
outside the case but is meaningless for all other cases, is this good structure? Where
did that HDC get initialized? Let's look at the code:

memDC = CreateCompatibleDC(lhdc);
*****
No declaration of this variable is shown. No initialization is shown. Therefore, this
code is unintelligible.
*****
GetClientRect(hDlg, &r);
*****
Where is r declared? At the top of the block? What good does it do there? This variable
should not be declared until it is needed, and that means it must be declared in this
case. Yes, you have to add { } in the case to declare it, but so what?
*****
hBit = CreateCompatibleBitmap(lhdc, r.right - r.left, r.bottom - r.top);
*****
Where is hBit declared? At the top of the block? What good does it do there? Bad
programming style, an invitation to unmaintainable code. If this variable is important to
this code example, its declaration WILL be shown! But it doesn't need to exist except in
this case
****
pOldBMP = SelectObject(memDC, hBit);
****
Again, where is this variable declared? Why is it not declared exclusive to this case
condition? Putting it at the top of the block is poor style, leads to incomprehensible
and unmaintainable code. And, of course, the need to save the result of SelectObject, for
all those things that could be selected; Petzold never ONCE mentions SaveDC/RestoreDC,
which is the sensible way to handle context for DCs. The notion that everything must be
saved and restored one variable at a time results in code that is incomprehensible when
finished; hard to code, hard to debug, nearly impossible to maintain, and very fragile
under maintenance.
****
hDC = BeginPaint(hDlg, &ps);
****
Where are these variables (hDC, ps) declared? Of COURSE they should be declared in the
scope of this case, not at the top of the block that defines the handler! Petzold never
practiced even marginally good programming style in C. It was poor C code to start.

The scope and lifetime of a variable should be as narrow as possible. The Petzold method
requires creating gratuitous variables whose scope and lifetime exceed their use. Poor
programming methodology.

Also, this suggests that there is an attempt to draw directly on the dialog surface, which
is exceedingly poor practice. And it should be assumed that it will always do the wrong
thing. The correct approach is to create a child control, most likely from class STATIC
but possibly from a registered window class, and draw in that class using that class's
WM_PAINT handler. So the code as written is a poor exemplar of style. Petzold never
encouraged the use of custom classes, which is the only sensible way to handle this
situation.
****

for (i=0; i<no_of_lines; i++){ //Create the lines
****
Ditto for i, no_of_lines. No idea what they are, or for that matter, how no_of_lines gets
initialized. Or the relationship of i to any of the functions that are called; note that
since it is not passed as a parameter to these functions, we have no idea what value it
has in relationship to them, or what the role of any of these variables play in the
computation. In C++, the loop would be written
for(int i = 0; i < no_of_lines; i++)
and the scope of the variable would not exceed the scope of the loop; this can easily be
arranged in C with a little creative syntax, e.g.,
{
int i;
forIi = 0; i < no_of_lines; i++)
...
}
so there is no reason for i to exist outside the scope of the loop. The fact that it does
not get passed into any of the functions suggests poor-beyond-imagination structure if any
of those functions can actually see the variable i.
****
create_data_points();
doplot(memDC, hDlg, plot_type, start, end, point_no);//All of the
plotdata is graphed here
****
Functions whose internal implementation is essential to the correct understanding of this
problem, but which are not shown
****
BitBlt(hDC, r.left, r.top, r.right - r.left, r.bottom - r.top, memDC,
0, 0, SRCCOPY); //when the lines stop this stops also
****
Uses variables that are not local to this context
****
doplot(hDC, hDlg, plot_type, start, end, point_no); //All of the
plotdata is graphed here
****
Uses variables that are not local to this context. Whose types, scope, and lifetime are
not determined. Whose initialization (plot_type, start, end, point_no) is unknown.
****
}
BitBlt(hDC, r.left, r.top, r.right - r.left, r.bottom - r.top, memDC, 0,
0, SRCCOPY);
****
Uses variables which are not local to the scope of this case. Same problem
*****
EndPaint(hDlg, &ps);

*****
Ultimately, this example is so unbelievably poorly written that it is impossible to figure
out what it intends to do, or how it does it. A major contributing factor is the use of
variables whose scope and lifetime are unknown and unknowable. But it is classic Petzold
code.

Had this code been written cleanly and clearly, there is an excellent chance it might have
worked the first time, but as such, there is no way to tell what it is doing, how it is
doing it, what it is doing it to, etc., so the same reasons I cannot understand what is
going on here, the OP probably can't figure it out either.

The first thing to do with this code is to move all of it into a function, and call that
function from the switch statement. I would have written
switch(uMsg)
{
HANDLE_MSG(hDlg, WM_PAINT, dlg_onpaint);

as the entire case

and written

void onpaint(HWND hDlg)

but then again, I would never have attempted to paint directly on the dialog's surface.

So as far as I am concerned, the example has nearly one error per line, of fundamental
design and programming methodology. But this is common with people who emulate Petzold's
style.
joe
Richard.
http://www.rtrussell.co.uk/
To reply by email change 'news' to my forename.
.



Relevant Pages

  • Re: MFC dll and exe porting to 64-bit
    ... Why the obsolete 'char *' instead of the proper LPTSTR? ... We are no longer programming 16-bit windows in an 8-bit character world, ... string arguments should probably be LPCTSTR, that is, const parameters. ... declaration of the function itself, in context (meaning show the surrounding class ...
    (microsoft.public.vc.mfc)
  • Re: AfxRegisterWndClass() within dll
    ... Take as a fundamental programming rule: writing a static declaration like this a mistake. ... multithreading contexts, and in DLL contexts where the DLLs can be loaded dynamically. ... into "fix our multithreading problems" and this is one of the most common failure modes. ...
    (microsoft.public.vc.mfc)
  • Re: How to convert Infix notation to postfix notation
    ... is a definition, the one without a function body is a declaration, also ... You also don't understand the intent or purpose of the feature. ... Prototypes are primarily used to address the fairly common case where the ... You need to actually learn a radically different programming language. ...
    (comp.lang.c)
  • Re: Rene is a hypocrite (OK, what else is new?)
    ... I guess this means that Rene and his minions blew it again :-). ... > underscore can be used to make numbers appear more easy to read. ... misunderstanding of what programmers consider "good programming ... It is creating scope, ...
    (alt.lang.asm)
  • Re: struct problems
    ... because my previous programming experience made the assignment before ... at least three programming languages by copy-pasteing. ... that you are ONLY in the scope of functions. ... GNU C and disregard the limitations of other compilers. ...
    (comp.lang.c)