No announcement yet.

"Bullet-Proof" apps

  • Filter
  • Time
  • Show
Clear All
new posts

  • "Bullet-Proof" apps

    I would like to "Bullet-Proof" my apps. (and before the jokes come, Yes I do realize their is no such thing as "Bullet-PROOF" so maybe "Resistant" should be used instead.

    Basically, what I would like to do is semi-easily track down bugs 5 yrs from now that I write today (either from ignorance, misunderstanding, etc) so I have set out that my next major project I try to declare correctly and add debugging to every routine (in the case I miss something, or something changed in the years to come)

    In my attempt, I could use some help explaining a few things to me. As I see it when using API then you have to use documentation to determine if it returns 0 for no errors or some other value for errors, OR the other way around (so I get that part) but some things elude me at the moment.

    On ERROR...(I get I can only get the correct error if I use ERR for Pb caught-able errors, and GetLastError for Windows errors, but does ON ERROR catch both, most of both, or for that matter could I use my own "ON" <enter value here> statement?)

    Callbacks and WndProc...(I get these, I can declare a callback in many ways, but for readability if I use)
    DECLARE FUNCTION Mdi_Dialog_Proc( _
        BYVAL hWnd    AS DWORD, _                          ' window handle
        BYVAL uMsg    AS DWORD, _                          ' type of message
        BYVAL wParam  AS DWORD, _                          ' first message parameter
        BYVAL lParam  AS LONG _                            ' second message parameter
        ) AS LONG
    1. Is lParam supposed to be long or dword? (semantics I know), also
    2. The return is supposed to be dword? (who does it return to?)
    3. If I have handled a message and do not want to pass a message to underlying procs (like a MDI situation) do I set the return value of the api I called? or exit function in that case before passing? (I know I ran into 1 that this blocked my app from finishing but can not think of the circumstances behind it

    In some areas, it may be considered "Nit-Picking" but in this case I consider "Nit-Picking" saving myself hours if not days tracking down "bugs" that creep up lonnnng after I coded certain functions, and what was the standard when I coded it, is no longer the standard
    Engineer's Motto: If it aint broke take it apart and fix it

    "If at 1st you don't succeed... call it version 1.0"

    "Half of Programming is coding"....."The other 90% is DEBUGGING"

    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

  • #2
    1) lParam will never take on a negative value. Its a 32 bit value, and will never be negative (its actually typedef'ed as a LONG_PTR.

    2) The return from the WndProc() is...

    int __stdcall (C stuff <<)

    and that occasionally takes on negative values, for example, if during the WM_CREATE processing, if you wish to terminate the app rather than continuing, return a (-1) to windows. Windows itself calls the Window Procedure, never your app.

    3) I'd say for every message your app handles, be it WM_SIZE, WM_SETFOCUS, whatever, look up the message in the Api docs from Microsoft, and do exactly what the docs say. They always specify what is to be returned to Windows after handling the message. Sometimes it does get tricky making sure one is not short circuiting proper returns somewhere, particularly with, for example - Exit Function - instead of returning a number to Windows. These are the kinds of things to watch for. My technique is to output darn near every value to an output log file, and to test!, test!, test! Sometimes I just hammer at the keyboard in unexpected ways to see what my program will do. Another trick is to give the program to someone who is practically clueless as to what to do with it and let them hammer at it while you're looking over their shoulder cringing in agony.

    One thing for sure, and I know you already know this Cliff because you are always messing with files - file access is extremely dangerous! You've really gotta wrap all file access operations in 'if' statements constantly testing for failures. The same goes for database accesses.

    It really gives me pleasure when the phone rings and somebody says one of my programs gave him/her an error message and didn't do whatever the user was trying. That gives me pleasure cuz I hate when they say it just crashed. Its always easy to find the problem by then going to the program's output log.

    Another thing that seems to have happened to me is I've slowed down. I'm never trying to write code at breakneck speed anymore. At one time I was only happy if I was sitting at the computer hammering out code. Nowadays I'm just as happy to take a walk and think about it or even 'sleep on it'. I think that improves your algorithims, and oftentimes suggests questions to oneself that further research sheds new light on.


    • #3
      > lParam will never take on a negative value. Its a 32 bit value, and will never be >negative (its actually typedef'ed as a LONG_PT

      Like you said, its a 32-bit value... which means if it's in the range 0x8000000 to 0xFFFFFFFF and cast as a LONG is will be "negative"

      LONG/DWORD casting is immaterial. What counts is when doing arithmetic comparisons against other variables or constants is that the same casting be used for the comparison, or you choose syntax to exclude the sign.

      (SELECT CASE AS LONG will do full 32-bit comparisons; "IF...[=><]" and "SELECT CASE" do signed comparisons)

      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]