Announcement

Collapse
No announcement yet.

Basic Programming Question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Basic Programming Question

    I have created several Powerbasic Windows Applications where I have used GLOBAL Variables exclusively. There has been much discussion that this is not a preferred method and LOCAL Variables should be used. How does one then get anything "done" in a CALLBACK Function without any access to Variables (Arrays, etc) defined as LOCAL to PBMAIN? EXAMPLE - User enters a Name in a Textbox Control. I want to check that name in the CALLBACK to see if it is in the Customer Name Array previously loaded (LOCAL ARRAY). Is there a way to do this without using a GLOBAL ARRAY?

  • #2
    There is nothing wrong with using global variables as long as you are careful with them. Try prefixing them with a "g" or something so that you can distinguish them from other variables and not to confuse them with local variables. I put all of my globals into a global TYPE structure and then I only need to deal with the one global TYPE (i.e. Global g As MyGlobalsTYPE)

    Anyone who insists on telling you that globals should never be used is not using the language to its fullest potential. Why hack in weird methods to a program just to avoid globals? Seems backwards to me. Use the language's abilities to get the job done - work with the language rather than against it.
    Paul Squires
    FireFly Visual Designer (for PowerBASIC Windows 10+)
    Version 3 now available.
    http://www.planetsquires.com

    Comment


    • #3
      Lee, if you post compileable source code I'm sure that within a day or two you will discover at least two ways of do what you want! It does not have to be your whole application - just enough to illustrate the problem.

      Comment


      • #4
        >There is nothing wrong with using global variables as long as you are careful with them

        AND

        You can live with your code not being re-entrant... which means if you ever want to support multiple simultaneous instances of a dialog, or change your application to be multi-threaded, you will have a lot more changes to make than simply an extra "DIALOG NEW" or "THREAD CREATE" statement.

        Also, when you use GLOBALs, the functions you write are more than likely not portable.. that is, you won't necessarily be able to use them in other applications or move them to a separate DLL within this application without making some other changes.

        See also: Lunch, Free; no such thing as


        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Have you had problems because you have used globals? I mean problems that could only be rectified by not using globals.

          I myself do not hesitate to use globals when they are the best tool for the job, just as Paul states.

          Globals, though, can become a burden, and when that happens, check out other options.

          As Michael points out, there are times when globals are restrictive, and if you find yourself living during those times, use the most suitable tool. Most suitable to you, the program, your needs, comfort level, programming level, and program requirements.

          Like any of the tools in the Power Basic toolbox, you have to respect the conditions that you use them in.

          There is nothing wrong with wanting to program without globals, but to make your task harder to do so (other than the learning curve) than it has to be is maybe not a good programming practice either.
          Rod
          In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

          Comment


          • #6
            This is one area where the new 9/5 compilers really shine.
            Create a class and use instance variables.
            You have Class access to all variables and portability at the same time.

            James

            Comment


            • #7
              I tend to use a lot of globals and haven't had any major problems, but I don't write that many programs. As I come up with more programs I'm starting to try and reuse code and that's where globals can be annoying. In my more recent stuff, I try to write mostly self contained functions. Not only are these more portable, but I find I can optimize and modify them without causing problems elsewhere in the code. I still find it easier to use globals for some things, and I don't agonize much when I use them, but I'm also learning to think about the future, not just what I'm doing at the moment.

              Comment


              • #8
                Something to consider in deciding whether to use globals and how much to use them is the size of your program. If, like me, you're only writing small, simple programs, it simply makes no difference whether you use globals or not as long as you're comfortable with what you're doing and understand the ins and outs of it.

                As programs become larger and more complex then the avoidance of global variables begins to make a lot more sense. But, except in special situations as mentioned in some earlier posts, sometimes they're still quite useful and can make for simpler programs.

                I think the important thing to remember is that there are no rules in programming unless you're being paid to do it by a company which imposes rules, which most do. Doing it for yourself there are no rules; there are only guidelines.

                Many of the guidelines were developed to solve problems and simplify programming and to help you avoid traps but they're always just guidelines.

                You decide, but decide after you know how to do it either way.

                Barry

                Comment


                • #9
                  I am sure that MCM and others will correct me on mistaken thoughts on this, but such is the debate of Global vs Local

                  In the past I used GLOBALS to store a value to be accessed by multiple functions (and over the years similar programs and re-using code it can become hard to track down when a problem)

                  I also started using "Headers" along with "Includes" to try and group common things together and not cause conflicts (but after time, one would depend on another, and if not in the right order, would not compile)

                  Which is why I put all my declares in a "Header" and the functions in a "Include", and slowly moving back to "If not included, then define and include it"

                  That is a lil above and beyond what your asking, but the basics of keeping local vs global is the variable can be corrupt (or in the midst of changing) depending on where it was accessed from.

                  MCM pulls the classic example of Threads and globals, which I am just now beginning to understand, but if you think of it as 2 copies of the same program, but able to access one variable then if the timing is right, then program 1 could be in the midst of changing the variable, when the OS switches to program 2 and it reads, so it would be like

                  Variable = "WHATSMYVALUE"
                  Program1 = "WHATSMYVALUE" = 123...4
                  Progam2 = "WHATSMYVALUE" = (interupt between 3 and 4) so the return I 123
                  and before the time is up change to 1235
                  now Program1 reply is 1235
                  sort of thing

                  How often does this happen? (not much...but when it does it will drive you NUTS trying to find a "Bug" when it is not a bug, but just the procedure of how things work

                  Nowdays, I am working on thinking not only local variables (both for readability, but also for keeping the value correct depending on what accessed it) is the thread "Or copy of the program" keeps its own value and not a global (which could change)

                  (last statement could be wrong, but best I can explain it with my knowledge)

                  All in all if you can post a example of your particular question, I bet that one or more of us can show you "The many ways to skin the cat" to achieve it
                  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? "

                  Comment


                  • #10
                    > classic example of Threads and globals, which I am just now beginning to understand

                    You were lucky, you were pretty much forced to create a compileable 'small' program to show the problem, and what you ended up with was a wonderful instructional piece, where you can see the problem basically on one screen.

                    We've had other people run into the same problem... except in their cases, it was in a 20,000 line program which had been in production for two years and was now being 'enhanced' to use multiple threads of execution.

                    Track down one of those and you'll see why I said you were lucky.
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      Thank for all the replies - but noone answered the initial question. I wasn't trying to start another debate over Global vs Local variables. My question is very simple - how does one do anything in a CALLBACK without having Global variables. With regular FUNCTIONS I can pass the Local Variables to them and return them back changed, not so with CALLBACK Functions (I assume).

                      Comment


                      • #12
                        >how does one do anything in a CALLBACK without having Global variables.

                        By recognizing that given a window handle (eg CBHNDL) you can get any piece of information in any control.

                        Eg do something based in the current selection in a listbox
                        Code:
                        CALLBACK FUNCTION DlgProc () 
                        
                                CASE somemessage 
                                      CALL  update_Text (CBHNDL) 
                        
                                 .....
                        FUNCTION Update_text (BYVAL hWnd AS LONG) 
                        
                            LISTBOX GET SELECTION TEXT   hWnd, %ID_LISTBOX to s 
                            CONTROL SET TEXT  hWnd, %ID_LABEL, S
                        Or, by using the "DIALOG SET USER" values

                        Code:
                            DIALOG NEW  .... TO hDlg 
                            DIALOG SET USER hDlg, 1, value 
                            CONTROL ADD...
                            DIALOG SHOW....
                        
                        CALLBACK FUNCTION DlgPRoc 
                        
                             CASE importantMessage 
                                  DIALOG GET USER CBHNDL, number TO value 
                                  value = newvalue 
                                  DIALOG SET USER CBHNDL, number, newvalue
                        Go look thru some of my demos in source code forum. I do stuff like this all the time.

                        MCM
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                        • #13
                          One way to do it.
                          James

                          Code:
                          '=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
                          'SED_PBWIN
                          '=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
                          
                          #COMPILE EXE
                          
                          %IDTEXT = 101
                          FUNCTION PBMAIN() AS LONG
                          	REDIM sNames(1 TO 10) AS STRING
                              LOCAL hDlg   AS DWORD
                              LOCAL Result AS LONG
                          	
                          	ARRAY ASSIGN sNames()="One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"
                              '  Create a new dialog template
                              DIALOG NEW 0, "Enter a Number Name",,, 160, 50  TO hDlg
                              '----------------------------------------------------------------
                              '  Add controls to it
                              CONTROL ADD TEXTBOX, hDlg, %IDTEXT, "", 14,  12, 134, 12
                              CONTROL ADD BUTTON, hDlg, %IDOK, "OK", 34, 32, 40, 14, _
                                  %BS_DEFAULT OR %WS_TABSTOP
                              CONTROL ADD BUTTON, hDlg, %IDCANCEL, "Cancel", 84, 32, 40, 14 _
                                 
                          	DIALOG SET USER hDlg,1,VARPTR(sNames(1))
                          	DIALOG SET USER hDlg,2,UBOUND(sNames)
                              '----------------------------------------------------------------
                              '  Display the dialog
                              DIALOG SHOW MODAL hDlg , CALL DlgProc TO Result
                          
                              '----------------------------------------------------------------
                          
                          END FUNCTION
                          
                          CALLBACK FUNCTION DlgProc() AS LONG
                          	LOCAL idx, ub AS LONG
                          	LOCAL sPtr AS STRING PTR
                          	LOCAL sText AS STRING
                          	SELECT CASE CB.MSG
                          		CASE %WM_COMMAND
                          			IF CB.CTL = %IDCANCEL THEN
                          		        DIALOG END CB.HNDL, 0
                          			ELSEIF	CB.CTL = %IDOK THEN
                          				CONTROL GET TEXT CB.HNDL,%IDTEXT TO sText
                          				DIALOG GET USER CB.HNDL,2 TO ub
                          				DIALOG GET USER CB.HNDL,1 TO sPtr
                          				FOR idx = 0 TO ub-1
                          					IF @sPtr[idx] = sText THEN
                          						? "We Have a Match at " + FORMAT$(idx+1)
                          						EXIT FOR
                          					END IF	
                          				NEXT idx	
                          			END IF
                          	END SELECT		
                          	
                          
                          END FUNCTION

                          Comment


                          • #14
                            Originally posted by Lee Bergeron View Post
                            Thank for all the replies - but noone answered the initial question. I wasn't trying to start another debate over Global vs Local variables. My question is very simple - how does one do anything in a CALLBACK without having Global variables. With regular FUNCTIONS I can pass the Local Variables to them and return them back changed, not so with CALLBACK Functions (I assume).
                            When Globals are mentioned in almost any discussion here, Lee, it soon descends into Global vs Local wrestling match.

                            To answer the question "how does one do anything in a CALLBACK without having Global variables.", one has to pass the variables. As has been suggested, a Type containing all the Globals is (most?) convenient.

                            Here's a clumsy example where the Global_Variables Type is Local in the Callback then passed in Calls to Function or Subs. So any Sub/Function called has, in effect, Global variables.

                            '
                            Code:
                            'PBWIN 9.00 - WinApi 05/2008 - XP Pro SP3
                            #Dim All 
                            #Compile Exe  
                            #Include "WIN32API.INC"
                            '
                            Type Global_Variables
                               Variable1  As Long
                               Variable2  As String * 1000
                            End Type         
                             
                             
                            %Id_Exit_Btn = 1000
                            %Id_Sample_Textbox = 1001
                            %Id_Show_Result_Btn = 1002
                            ' 
                            Macro Common_Locals 'Macro easier than retyping and maintains coding consistency
                              Global Dlg_hght, Dlg_Wd As Long 'Global in case want to use in Controls
                              Local hDlg As Dword
                              Local Row, col, hght, wd, Longest,ctr, ln, ln1, i As Long
                              Local  l, s As String
                            End Macro  
                            '
                            CallBack Function Dialog_Processor () As Long             
                              Common_Locals                     
                              Local G As Global_Variables
                               'test of passing
                               g.Variable1  = 10  '<< Set "Global" for testing      
                             
                              Select Case CbMsg     'This is TO determine the message TYPE 
                                 Case %WM_COMMAND  'This processes command messages
                                   Select Case CbCtl
                                     Case %Id_Show_Result_Btn 
                                        Call Testing_Global_Concept1(CbHndl, G) '<< Pass the Callback Handle & the "Globals" to the function
                                          ? g.Variable2 , , Str$(g.Variable1) & " in " & FuncName$  '<< see "Globals" returned
                                     Case %Id_Exit_Btn
                                       Select Case CbCtlMsg        
                                          Case 0
                                            Dialog End CbHndl
                                       End Select
                                   End Select
                              End Select
                            End Function               
                            '
                            Function Testing_Global_Concept1 (Hdl As Dword, G As Global_Variables) As Long
                               Common_Locals    
                                Control Get Text Hdl, %Id_Sample_Textbox To l$
                                 ? l$, , Str$(g.Variable1) & " in " & FuncName$
                                 g.Variable1 = 100 '<< Reset "Global"
                                 g.Variable2  = Str$(g.Variable1 ) & " Returned"  & $CrLf  & l$ '<< set another "Global"
                             
                             
                            End Function
                            '
                            Function PBMain
                              Common_Locals
                              Dlg_hght = 400
                              Dlg_Wd = 400
                              Dialog New Pixels, hdlg, "Demo", , , Dlg_Wd, Dlg_Hght, %WS_SYSMENU To hdlg 'centered
                             
                              Row = 10
                              col = 10
                              Wd = 40
                              Hght = 12
                              Control Add Label, hdlg, -1, " Name & Address ", Col, Row, Wd, Hght
                             
                              s$ = "Brown, Kevin" & $CrLf & _
                                   "123 PBWin Avenue" & $CrLf & _
                                   "PowerBasic, FL 12345"
                             
                              Col = Col + Wd + 10 'just past label 
                              Hght = 15 * 10 'Plenty room for 10 lines of text
                              Wd = Dlg_Wd - 40 - 30 'minus the label and leave a little
                              Control Add TextBox, hdlg, %Id_Sample_Textbox, s$, Col, Row, Wd, Hght, %ES_WantReturn Or %ES_MultiLine
                             
                               hght = 25   
                               Wd = Dlg_Wd - 20
                               Col = 10 'center
                             
                               Row = Dlg_hght - (Hght * 2) - 4 'Just off bottom
                                 Control Add Button, hdlg, %Id_Show_Result_Btn, "Show Textbox Results", col, row, Wd, Hght
                             
                               Row = Dlg_hght - Hght - 2 'Just off bottom
                                 Control Add Button, hdlg, %Id_Exit_Btn, "Abandon Ship", col, row, Wd, Hght
                             
                                 Dialog Show Modal hDlg   Call Dialog_Processor
                            End Function
                            '
                            =========================================
                            An ambassador is an honest man
                            sent to lie abroad for the commonwealth.
                            Sir Henry Wotton
                            =========================================
                            Last edited by Gösta H. Lovgren-2; 6 Nov 2008, 09:49 AM.
                            It's a pretty day. I hope you enjoy it.

                            Gösta

                            JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                            LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                            Comment


                            • #15
                              Just for grins, this is the way I do it.
                              Code:
                              #COMPILE EXE
                              #DIM ALL
                              #IF NOT %DEF(%WINAPI)
                                  #INCLUDE "WIN32API.INC"
                              #ENDIF
                              %IDD_DIALOG1 =  101
                              %IDC_BUTTON1 = 1001
                              %UNKNOWN_VALUE = -1
                              DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
                              DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                              DECLARE FUNCTION SetGetValue(ValueToSet AS LONG, ReturnValue AS LONG, ResetValue AS LONG) AS LONG
                              
                              CALLBACK FUNCTION ShowDIALOG1Proc()
                                  LOCAL LocalReturnValue AS LONG
                              
                                  SELECT CASE AS LONG CBMSG
                                      CASE %WM_INITDIALOG
                                          ' Initialization handler
                              
                                      CASE %WM_NCACTIVATE
                                          STATIC hWndSaveFocus AS DWORD
                                          IF ISFALSE CBWPARAM THEN
                                              ' Save control focus
                                              hWndSaveFocus = GetFocus()
                                          ELSEIF hWndSaveFocus THEN
                                              ' Restore control focus
                                              SetFocus(hWndSaveFocus)
                                              hWndSaveFocus = 0
                                          END IF
                              
                                      CASE %WM_COMMAND
                                          ' Process control notifications
                                          SELECT CASE AS LONG CBCTL
                                              CASE %IDC_BUTTON1
                                                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                              '                        MSGBOX "%IDC_BUTTON1=" + FORMAT$(%IDC_BUTTON1), _
                              '                            %MB_TASKMODAL
                                  SetGetValue %UNKNOWN_VALUE, LocalReturnValue, %UNKNOWN_VALUE
                                  MSGBOX STR$(LocalReturnValue)
                                                  END IF
                              
                                          END SELECT
                                  END SELECT
                              END FUNCTION
                              
                              FUNCTION PBMAIN()
                                  ShowDIALOG1 %HWND_DESKTOP
                              END FUNCTION
                              FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                                  LOCAL lRslt AS LONG
                                  LOCAL hDlg  AS DWORD
                                  LOCAL LocalReturnValue AS LONG
                                  DIALOG NEW hParent, "Dialog1", 70, 70, 96, 23, %WS_POPUP OR %WS_BORDER OR _
                                      %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
                                      %WS_MAXIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME _
                                      OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
                                      %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                                      %WS_EX_RIGHTSCROLLBAR, TO hDlg
                                  CONTROL ADD BUTTON, hDlg, %IDC_BUTTON1, "Button1", 10, 5, 75, 15
                              
                                  SetGetValue 100, LocalReturnValue, %TRUE
                                  SetGetValue %UNKNOWN_VALUE, LocalReturnValue, %UNKNOWN_VALUE
                                  MSGBOX STR$(LocalReturnValue)
                                  
                                  DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                                  FUNCTION = lRslt
                              END FUNCTION
                              '------------------------------------------------------------------------------
                              
                              FUNCTION SetGetValue(ValueToSet AS LONG, ReturnValue AS LONG, ResetValue AS LONG) AS LONG
                                   ON ERROR GOTO ErrHandler
                                   STATIC CurrentValue AS LONG
                                   SELECT CASE ResetValue
                                        CASE %False, %UNKNOWN_VALUE
                                             ReturnValue = CurrentValue
                                        CASE = %TRUE
                                             CurrentValue = ValueToSet
                                             ReturnValue = CurrentValue
                                   END SELECT
                                   FUNCTION = %False        'Pass False if no error in function or True if error in function
                                   EXIT FUNCTION       'Escape function so not to trigger error log
                              ErrHandler:
                                   MSGBOX "An Error Occurred"
                              END FUNCTION
                              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? "

                              Comment


                              • #16
                                try to write mostly self contained functions. Not only are these more portable, but I find I can optimize and modify them without causing problems elsewhere in the code.
                                Frustrating, isn't it? "Gee, I already wrote, tested and debugged code to do [almost] exactly what I want to do again, but I can't re-use my work."


                                I still find it easier to use globals for some thing
                                The Truth: I use one GLOBAL variable and even more than one STATIC in one of my major commercial applications (the EDI Pal(tm) ANSI ASC X12 Viewer-Editor-Printer).

                                However, I always start developing any procedure on the assumption I will want to re-use it in some way, and ask myself how I can create that procedure using only stack-based (LOCAL or passed parameter) variables.
                                Michael Mattias
                                Tal Systems (retired)
                                Port Washington WI USA
                                [email protected]
                                http://www.talsystems.com

                                Comment


                                • #17
                                  Thanx to all who replied - This has really opened my eyes to Event Driven programming. My programs are usually relatively small (utility based) and my techniques are not very high level. I still do most of my programming in "DOS Type" languages so the concepts of event driven programming all need to be learned. With every new Windows Program I try to learn more but this can be very daunting. Is there any instructional books out there explaining event driven programming techniques without being language specific? Otherwise I keep learning bit by bit through these Forums.

                                  Comment


                                  • #18
                                    It took me a while to "get the feel" for "here's an event, coming at you, Deal With It!"

                                    That's in spite of the fact I had previous experience with the model from working on minicomputers (younger members: these don't exist anymore) and mainframes running "message-based systems" (eg IBM CICS, Burroughs GEMCOS or COMS).

                                    The good news is, you will probably have that same "Eureka!" moment I had when it just magically all came into focus and made perfect sense from that day forward.

                                    MCM
                                    Michael Mattias
                                    Tal Systems (retired)
                                    Port Washington WI USA
                                    [email protected]
                                    http://www.talsystems.com

                                    Comment


                                    • #19
                                      Paul answered your question best.

                                      Global variables are there for a reason.

                                      They are very useful for sharing data among subroutines/functions.

                                      The problem is though that if you are not careful with the naming convention used, you may confuse global and local variables and this would cause problems.

                                      The solution ?

                                      Use a unique prefix for all global variables and you not have any problems.
                                      (I like th use the App_ prefix)

                                      ie.

                                      GLOBAL App_MyGlobal1&
                                      GLOBAL App_MyGlobal2&

                                      Some like to use the prefix g:

                                      ie.

                                      GLOBAL gMyGlobal1&
                                      GLOBAL gMyGlobal2&

                                      Personally, I strongly prefer the use of a prefix with an underscore (_) character after it. If you like the g prefix, use:

                                      ie.

                                      GLOBAL g_MyGlobal1&
                                      GLOBAL g_MyGlobal2&

                                      A prefix with an underscore is more readable (noticable) at a glance and you are less likely to confuse it with any local variables.
                                      Chris Boss
                                      Computer Workshop
                                      Developer of "EZGUI"
                                      http://cwsof.com
                                      http://twitter.com/EZGUIProGuy

                                      Comment


                                      • #20
                                        Personally until my post back at #15 Yesterday, 09:56 AM
                                        which is because of my recent issue(s) involving GLOBALS, I used them exclusively for sharing info between subs and functions.

                                        Eventually over years of use, Re-USE, and projects getting larger, I fell into the debate myself of GLOBAL vs LOCAL because of THREADS.

                                        So far, it is true because depending on timing and other factors, I have come to realize that if the variable is in the midst of being set, and another thread gets its "Time-Slice" and is also setting the same variable, then the result would be "Inconclusive"

                                        My advice, is use what works best for you, but when things go awry, then keep it in the back of your mind "What if its my variable?" when you can not figure out when your code "Does NOT work as advertised"

                                        And YES I am still "Guilty as Charged" when it comes to GLOBALS on all my projects just to meet timelines (or to suit the purpose of the moment), while I "Secretely" work on correcting that idea on a future version that will be released when its ready and as stable as "What CURRENTLY is known to be stable in the current release"
                                        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? "

                                        Comment

                                        Working...
                                        X