• DaveS (unregistered)

    Hah! That way, when people complain due to poor application response, he can decrease the timer event delay and collect a bonus for "performance enhancements"!

    Brillant!

  • no1 (unregistered) in reply to DaveS

    Wow! this is a true WTF! I wonder if the original author(s) of this super advanced Paybck application were trying to "outsmart" MS VB6 events or they just didn't know any better?

  • (cs) in reply to no1

    It can be worst than the shit I usually found in my current job old code. GUI Forms where the user must click the buttons in a rather obscure order to get things working. If (s)he clicks in the wrong order, heavy shit may happen. I'm going to send you some snippets of this crap as soon as I figure out which one is WORST...

  • (cs)

    Event....Whats an Event?????

  • (cs)

    I would hate to have to be on the one who has to use that.

  • (cs) in reply to Sweets

    OMG, every three seconds? i hope you're exaggerating!

    Can't believe someone could make a program and not know what an event is, its impossible?

     

  • (cs)

    Dude, that code smells like my ass!

    This is probably one the funniest things I've ever seen on here Alex!  Thank you for making my day.

  • (cs)

    This is a system for those of us who are nostalgic for the good old days of the C-64, when most operations of moderate complexity required a 30-second wait.  If only he could work ", 8, 1" into the interface somehow.

  • (cs) in reply to fregas

    Even worse, they apparently understand events (the timer), just not the concept that a user can generate them.

  • (cs) in reply to fregas
    fregas:

    Dude, that code smells like my ass!



    You mean you didn't wipe or wash it in a year?
  • (cs)
    Alex Papadimoulis:

    Payback requires users to wait around for the timer event to fire and change the enabled/disabled and visible/invisible state of other controls.



    Come on - it's not a bug, it's a feature. If it weren't for the up to 3s delay, how would you be able to trigger an illegal action? You just couldn't!

  • (cs)

    I'm pretty sure this programmer knew what events are... after all, he/she wrote one! I strongly suspect it was a case of, "hey, I've got to put this validation in the events for lstCourses, lstCourseTypes, txtCourseType, etc... but damn, I don't want to repeat the same block of code everywhere. What do I do? I know, I'll put it all in a timer event!" And not realizing that you can actually, you know, create your own functions inside of a form, and you don't have to rely on double-clicking on a control in the designer.

    And you have to love using Hungarian notation for controls (tspCourseInfo? WTF is a 'tsp'?) but not for the variables.

    And that stupid default VB6 icon on the window. They might as well just put "Crapware" in the title bar.

    Of course, with the advent of the web, users now expect there to be a slight delay after they click on something. Maybe they would get confused if stuff happened instantly. Maybe this is a very forward-looking approach, after all!

     

  • (cs)

    There is a mandatory 3-second waiting period on potentially stupid database interactions.

  • (cs)

    I am not a VB person, but does an event fire is something else comes and changes the state programmatically. What if another section of the program was changing lstCourseTypes.Enabled or lstCourses.Enabled - say when a network resource giving this data went down. Sure, a sane person would put this code into its own routine and then whoever programmatically changed something on GUI could simply call UpdateControls to make sure their changes were reflected in the control logic.

    This could even be a defensive move because the bozo in the next cube (who is also the boss' son) will not make a change in his code that does the change and insists that you change because his code is properly designed.

    Or it could be that the coder is simply clueless.

  • diaphanein (unregistered)

    This is the sort of code that demonstrates why every developer ought to be instructed in state machines. 

  • (cs)

    I can't see any reason to use a timer in this fashion...Even if you needed things to happen in 3 second increments, it would be far far better to handle that in the backend code rather than make users work with a half-assed cyclical system.

    I can't imagine a scenario where you'd want a user interface to have any sort of functionality dependant on a timer...The user should always be able to do their user things...If you have some crazy transaction journaling system in the background that fires every 66789 seconds or something, they don't need to know about it. The whole point of an interface is to hide that crap from them, so their tiny minds don't asplode.

  • David (unregistered)

    I've seen code that does just this without the big delay, that is, setting control state from a central routine when the application is idle (like here for example). The programmer in this case probably saw something like this, thought, "Keen! I gotta do it like that!" and couldn't figure out any other way in VB. It's been too long since I've done VB, so I don't remember if it has something akin to Application.Idle or not.

  • (cs) in reply to DaveS

    Event handlers, anyone?   Anyone?  ANYONE????
    ....
    ....
    ....
    </dead_silence>

  • (cs) in reply to christoofar

    This is offtopic, but Oliver Klozoff and I have finally finished battling a problem with a C++ component written at my company that warranted a new design antipattern article (I added it to wikipedia)

    http://en.wikipedia.org/wiki/Object_cesspool

  • (cs) in reply to David

    You all's guess is as good as mine on this one.  I've looked through the other forms in this application and they all use a more sane method of deciding which controls are visible/enabled under which circumstances.  My guess is the original developer just though this'd be neat.

  • (cs)

    GalacticCmdr: The event fires no matter what triggered it. If something changes the value in the field, then the _Change() event kicks off.

    And I know someone else beat me to this, but I totally believe the reason this was done is that they didn't want to repeat the validation code in every text box. If only VB would let you write your OWN functions...

    PS- tsp = tablespoon. In this case though, I think it means "tabstrip", which is the name of the control with all the tabs on it that affects which screen you're looking at.

  • Dave Markle (unregistered)

    You know, this whole thing can be cured with a few easy steps, and by downloading the free cygwin unix tools from the web.

    Steps to fix the problem:

    1. Go to http://www.cygwin.com/.
    2. Click "Install or update now!"
    3. When windows prompts you if you want to run the downloaded application, click the "Run" button.
    4. Windows will give you a message that the digital signature of setup.exe could not be verified.  Click "Run".
    5. Click the "Next" button until you get to the download site prompt.  When prompted for a Download Site, pick one near the top, as those tend to be faster.
    6. Select the default install packages.  You do not need the X11 packages, so you can save some time there with that download.
    7. Allow the install to complete.
    8. Open up cmd.exe, or the cygwin shell that will be put in your start menu.
    9. type CD <PAYBACK PROJECT DIRECTORY> [ENTER].
    10. type "rm -rf * [ENTER]"

    Problem solved!  Now, wasn't that easy?

  • (cs) in reply to christoofar

    That's nice. They give the user 3 seconds to change their mind if they click the wrong item.
    Very thoughtful.

    Hey Alex: I picked up a copy of your book. Pretty cool!

  • (cs)

    One small correction to the original post.  The timer event fires 3 times every second, not 1 time every 3 seconds.  This means that users probably aren't going to notice having to wait a few seconds for things on the form to change, but it's silly nonetheless

    To point out another problem, notice the cases in which SelectedItem is set to true.  It is only set to true if the correct listbox's ListIndex is greater than 0.  This means that several controls that should be enabled/disabled when the user selects an item in the listbox aren't changed when the user selects the first item in the list.  And yes, the first item in each list is a valid item that the users should be able to update.

  • (cs)

    Maybe the programmer wanted to program to behave like an AJAX application.

  • blasterz (unregistered) in reply to A Wizard A True Star
    A Wizard A True Star:

    (tspCourseInfo? WTF is a 'tsp'?)

    Not really certain, but I think there are 3 of them in a tbsCourseInfo

  • (cs) in reply to Dave Markle

    David Markle: That's way too many steps. The original programmer should just pull out the hard drive and beat it with a hammer. Then use the hammer on his own fingers to assure he will never ever write code again.

    And I hadn't noticed the ListIndex > 0 part. The first item in the list truly will not enable any of the controls. Maybe this guy put something like "==Select from this list==" as the first ListItem, because he didn't know how to handle an empty ListBox. Or maybe he just doesn't know that the index is 0-based. A lot of things in VB aren't, but some things are. It's just Microsoft's way of keeping you on your toes.

  • (cs) in reply to Dave Markle
    Anonymous:
    9) type CD <payback project="" directory=""> [ENTER].



    bash: CD: command not found

    By the way, parameterless "cd" in bash changes the working directory to ~, not /

    </payback>
  • (cs)

    One of the little utilities at my first job involved a phony 4-second progress bar when activating/deactivating it, to go along with the user's perspective that we were patching functionality in pretty much every program in the system.  (Actually, we were only adding/removing a single program in front of another single program.)  And yes, we eventually "improved performance" by removing the delay.

  • (cs) in reply to John Smallberries
    John Smallberries:
    Hey Alex: I picked up a copy of your book.


    Did someone drop it?

  • JuliaPepin (unregistered) in reply to Manni
    Manni:

    PS- tsp = tablespoon



    tsp = teaspoon
    tbsp = tablespoon

    maybe Alex meant "tps"?
  • (cs) in reply to JuliaPepin
    JuliaPepin:
    Manni:

    PS- tsp = tablespoon



    tsp = teaspoon
    tbsp = tablespoon

    maybe Alex meant "tps"?

    This is exactly why everything I cook ends up tasking like tree bark. You damn Brits and your metric system, I'll never get used to it.

  • (cs)

    Ya know, if you simply call ControlTimer_Timer from every event that actually should update the UI state, this would work pretty well...  I've seen more bizarrely coded "ManageUIState()" type procs before.

    And you can burn bonus cycles three times a second just in case you screw up!

    Extra bonus reliability points if you can make it take a half second to process each event!

  • (cs)

    At least they use source code control.

  • (cs) in reply to Satanicpuppy
    Satanicpuppy:
    I can't see any reason to use a timer in this fashion...Even if you needed things to happen in 3 second increments, it would be far far better to handle that in the backend code rather than make users work with a half-assed cyclical system.

    I can't imagine a scenario where you'd want a user interface to have any sort of functionality dependant on a timer...The user should always be able to do their user things...If you have some crazy transaction journaling system in the background that fires every 66789 seconds or something, they don't need to know about it. The whole point of an interface is to hide that crap from them, so their tiny minds don't asplode.


    I wrote a monitoring program for dealing with Windows services across a network.  The listbox was updated every so often as services came on-line or were no longer available.  The user could select a service and start or stop it.  The "blink" when the list was updated was a bit of a bother, but this was a very low use app.

    Sincerely,

    Gene Wirchenko

  • (cs) in reply to Alexis de Torquemada
    Alexis de Torquemada:
    John Smallberries:
    Hey Alex: I picked up a copy of your book.


    Did someone drop it?


    huh? I don't...oh wait...I got it!
    It's like to "pick up" can have 2 different meanings! Or maybe I met the book at a bar and had sex with it! That's 3 meanings!

    Oh, that's rich.
  • userdefined (unregistered) in reply to Dave Markle
    Anonymous:
    You know, this whole thing can be cured with a few easy steps, and by downloading the free cygwin unix tools from the web.

    Steps to fix the problem:
    <snip>[install cygwin]</snip>
    1. Open up cmd.exe, or the cygwin shell that will be put in your start menu.
    2. type CD <payback project="" directory=""> [ENTER].
    3. type "rm -rf * [ENTER]"

    Problem solved!  Now, wasn't that easy?



    Well, let's see, at step 8, if you run cmd.exe, then proceed to step 9 you will do nothing more than leave yourself in the directory you were in anyway ("CD" == "echo the directory I'm currently in"). Since the default is to put you into %USER_PROFILE% when you initially fire off the dos prompt, when you perform step 10 (assuming the cygwin "rm" command is able to be found from the cmd prompt, which iirc it isn't in a default install of cygwin unless someone alters their environment variables manually) you've just succeeded in removing most or all of your windows profile, including "my documents" etc. However, the OS is fine with that, and will simply go merrily along laughing at you (they're all gonna laugh at you ... )

    If at step 8 you run cygwin, CD doesn't work, leaving you in the default directory (which is ~ under the cygwin install directory) and rm will remove the contents of your cygwin home directory, which is even less of a bother to the OS than going the other route...

    Oh, wait. it was a joke ...
    </payback>
  • (cs) in reply to Alexis de Torquemada

    Alexis de Torquemada:
    John Smallberries:
    Hey Alex: I picked up a copy of your book.


    Did someone drop it?

    Heh -- actually, I was a contributor to it. Although I encourage you to buy the book, O'Reilley has the Hack I wrote avaiable as a sample: http://www.oreilly.com/catalog/visualstudiohks/ (see Hack#7).

  • Raw (unregistered) in reply to A Wizard A True Star

    Actually, I have had to resort to this method when using controls which lacked the needed events (which is a WTF in itself, but not mine), but then I set it to check five times a second or so, often enough to not be percieved as slow.

    I have not done it often and only as a last resort, and I am not proud of it, but sometimes you just have to go with whatever works.

    And you have to love using Hungarian notation for controls (tspCourseInfo? WTF is a 'tsp'?) but not for the variables.

    Actually a very common VB practice, with a very practical reason. Variables are defined in the same method, close to where you are working. There may be an occasional variable with a larger scope, but these are few and easily remembered (unless you are doing something very wrong).

    Controls, however, are often not defined in the viewable code. In fact, you have to go to the property window to get a closer look at them. In this case, it makes sense to be a bit more clear about it. It also makes it easy to keep track of GUI components when quickly looking through the code. Most GUI parts is usually along the lines of either

    control data=data from dataset/object

    or

    dataset/object data=control data

    usually coupled with some validation code and some occasional derived values. Being able to quickly sort out what's part of the GUI makes a lot of sense in these cases.

    And that stupid default VB6 icon on the window. They might as well just put "Crapware" in the title bar.

    Actually, most likely the form has probably removed the icon (since it has a close button), but VB still displays it in design mode, where this screenshot is taken. It doesn't make sense to make the executable bigger because of an icon that is never shown.

  • spotcatbug (unregistered)

    He could improve the efficiency of the timer routine by having it check a flag to see if anything has changed. If the flag isn't set the routine just exits. Otherwise, it does its thing and then unsets the flag.

    Then, he just needs to make sure the flag is set whenever something changes.

    Yes, I'm kidding (we're always kidding!). But doesn't this seem like the next step this person would take on the road (hopefully) to the correct solution?

  • smithy (unregistered)

     amazing if i say sdo myself keep it up i mean wow im a hacker and have been for 3 years but i have never seen anything like that its amazing welldone

  • (cs) in reply to Sean
    Sean:
    This is a system for those of us who are nostalgic for the good old days of the C-64, when most operations of moderate complexity required a 30-second wait.  If only he could work ", 8, 1" into the interface somehow.


    +1 to that.

       -dave-

  • (cs) in reply to Alex Papadimoulis
    Alex Papadimoulis:

    Alexis de Torquemada:
    John Smallberries:
    Hey Alex: I picked up a copy of your book.


    Did someone drop it?

    Heh -- actually, I was a contributor to it. Although I encourage you to buy the book, O'Reilley has the Hack I wrote avaiable as a sample: http://www.oreilly.com/catalog/visualstudiohks/ (see Hack#7).

     

    The URL in the PDF file doesn't work [:'(] I get a directory listing denied error.. Did you forget to tell IIS what your index document is?

     

    Drak

  • Sir 420 (unregistered) in reply to Manni
    Manni:

    This is exactly why everything I cook ends up tasking like tree bark. You damn Brits and your metric system, I'll never get used to it.



    Brits and metric system? 

    stop creating wtfs
  • gabriel (unregistered) in reply to fregas

    Dude, that code smells like my ass!

    i wouldn't difamate my ass like that...

  • Gilbert (unregistered)

    No comment on the body of code, but conceptualy I think the developer was aiming at an independant state machine. Not a bad idea at all - no need to trap the events of every possible user input, and more easily extensible. Perhaps the developer should be directed towards something like an ApplicationOnIdle event.

  • Shannon Barber (unregistered) in reply to Gilbert

    If VB didn't suck rocks for event driven programming code like this wouldn't be needed.  Updating the GUI consistently from a timer is better than the absolutely mess you end up with when you have mutually dependant widgets..

    The root cause is that OnChange should be called only when the user changes it.  If I change it with code don't tell me it changed; I know it changed, I just changed it.

    For a demostrative example, try implementing Windows' Calc with VB (or any other modern widget kit other than MFC; despite all the criticism this is straight-forward in MFC because GUI updates are made atomic via UpdateData).

  • (cs) in reply to Shannon Barber
    Anonymous:
    If VB didn't suck rocks for event driven programming code like this wouldn't be needed.  Updating the GUI consistently from a timer is better than the absolutely mess you end up with when you have mutually dependant widgets..

    The root cause is that OnChange should be called only when the user changes it.  If I change it with code don't tell me it changed; I know it changed, I just changed it.

    For a demostrative example, try implementing Windows' Calc with VB (or any other modern widget kit other than MFC; despite all the criticism this is straight-forward in MFC because GUI updates are made atomic via UpdateData).


    Trust me, this isn't needed and it is not better than using typical event driven programming in VB.  This is wonky, overly complex for what the situation needs, and allows a chance, albeit ever so slight, for the user to use controls when they should be disabled.
  • (cs) in reply to Sweets

    Sweets:
    Event....Whats an Event?????

    Well actually he IS handling an event: ControlTimer_Timer() ...

  • Gilbert (unregistered) in reply to Shannon Barber
    Anonymous:

    The root cause is that OnChange should be called only when the user changes it.  If I change it with code don't tell me it changed; I know it changed, I just changed it.


    Good point, and VB's not the only language with this problem.

    Edit1.OnChange := nil;
    try
    ....
    finally
      Edit1.OnChange := Edit1Change;
    end;

    is a common delphi situation. An OnGUIChange event could be useful, but more often than not you want your state to always reflect the current GUI situation regardles of where the change was made. So,  i would still go with an independant state machine.

Leave a comment on “It's Payback Time!”

Log In or post as a guest

Replying to comment #:

« Return to Article