• Welcome to SQLitening Support Forum.
 

News:

Welcome to the SQLitening support forums!

Main Menu

Old decrepit fart

Started by ken_anthony, July 17, 2016, 02:19:03 AM

Previous topic - Next topic

ken_anthony

I guess I'm supposed to introduce myself here...

I've forgotten everything. My first program was saved on paper tape. My first computer was a Cosmac Elf. I was normalizing DBs in 1980 but didn't know what a normalized DB was until 1996.

I've played with an alphabet soup of languages but did real work in VB6 (over a million line of code maintained and upgraded by little ol' me in just one project. By talking directly with customers I added features that made it a best seller and open to new markets.)

I started working professionally from 1980 in NYC but mostly have worked in the west coast (CA & WA.)

I worked a year in WA from CA in my pajamas (the commute was great!) Got sick, divorced, but I'm a nice bum. Just got my first domain and hope to bring in a few pennies next year. SQLitening and PowerBASIC are a big part of that hope.


Bern Ertl

Hi Ken, welcome to the forum.

Good luck with your project and I'll be glad to help where I can with any questions about SQLitening.

cj

ODF,
SQLitening works just as well with VB6.
If you need any help with PB or VB6, let us know.


ken_anthony

Can't find my VB6 install disks. I saw VB6Pro on EBay for $65, but failed to snap it up. Amazon had it listed from $$500 to $1,000.

Working in PowerBASIC is extremely slow for me. When I was working, a thousand lines of VB code a day was not unusual for me. With PB, a dozen lines is more typical. SQLitening is the bright spot. It just works.

I can't find the Firefly IDE for PB, just the version for FreeBasic. None of the other IDEs suit me, so I'm just using PB's editor. I've got EZGUI 5 but I'm not using it on this first project.

SQLite Expert is a good tool for developing the DB structure, but I can do that in SQL code, so it's nice to have but non essential.

I've got about 35 parts to complete for my project. I haven't finished one yet, but I've completed most of the main screen, menu items and have stub files for 24 screens. I'm using one file per window (old VB habits are hard to break.) I wish PB had file scope variables. Using globals makes my skin crawl. In over a million lines of VB code I had only one global and that was a DB class!

We kept the DB open, not using ODBC except for management and returned disconnected ADO recordsets. It was fast. With SQLitening, I'm opening and closing the DB for just about every access, trying to avoid nesting which would screw things up. My project has a host DB and multiple session DBs paired with client DBs. So I'm doing a lot of opening and closing, but that doesn't seem to hurt performance.

I'm sooo old.

cj

#4
You can get pretty fast using PBFORMS 2.0  by leaving it open and click back and forth been source code and it.
I use forms already built and modify them so all the callbacks are there and only need to modifiy code within it
or the subs and functions called from the callbacks.
Another thing to do is force yourself to put code in a DLL or DLLs so you don't have to rewrite so much code.

It is too easy to fall in the trap of just copying and pasting code.
Another way is use include files so that the code is always there. 

Working on a PBFORMS skeleton/template might take awhile, but once completed you won't have to start from
scratch with everything.  Its a step backward to build your template then many steps forward with new projects. 
In some projects not having the ability to just add an OCX to the project is truly missed.

I see the visual studio people having commented on no VB6 downloads and suggest getting a MSDN subscription.
Be careful if you go that route that the VB6 is included with it.   

If you really love VB6 stay with it and unfortunately spend the money.  Ouch for what they are charging.
Maybe somebody on the PowerBASIC BBS would be willing to give up a copy.  Never hear about VB6 there.

.




cj

#5
PB supports classes too and another way for globals  (which I also avoid.)
A single global variable isn't hard in PowerBASIC with or without a class.
Not sure if any of this is of help.
I don't mind globals if they start with a g, don't see too many and if multithreaded see THREADSAFE or CRITICAL_SECTION.


REM %IncludeGlobals = 1

#IF %DEF(%IncludeGlobals)
#INCLUDE "MyGlobals.INC" 'globals, threaded variables, macro in an include file
'These values can be GET at startup and PUT on program end

#ELSE 'use directly in program instead of MyGlobals.Inc on disk
MACRO Dollar(Pennies) = USING$("#,.##",Pennies * .01)
$Constant1 = "Constant One"

TYPE MyGlobalType
  name AS STRING * 64
  bal  AS QUAD
END TYPE
GLOBAL g AS MyGlobalType

GLOBAL gs AS STRING
GLOBAL gSomething AS STRING
THREADED tSomething AS STRING
#ENDIF

FUNCTION PBMAIN () AS LONG
  InitGlobals
  DisplayAll
END FUNCTION

SUB InitGlobals
  GLOBAL g AS MyGlobalType
  g.name = "First name in global type"
  g.bal  = 9999
  gs         = "This is the gs string"
  gSomething = "This is another string"
  tSomething = "threaded string for easy threaded applications"
END SUB

SUB DisplayAll
  ? CHR$(g.Name,$CR,money(g.bal),$CR,gs,$CR,gSomething,$CR,tSomething,$CR,$Constant1)
END SUB

FUNCTION Money(BYVAL Pennies AS EXT) AS STRING
  FUNCTION = SWITCH$(  _
   pennies = 0, ".00", _
   pennies > -100 AND pennies < 100, USING$(".##",pennies * .01##), _
   pennies< > 0,TRIM$(USING$("#,.##",pennies * .01##)))
END FUNCTION





This example could have easily passed a global to a thread function, but was avoided.
It used a single global (which wasn't really needed) to just accumulate results of all the threads.
The global was within a helper function using the THREADSAFE option.

http://www.sqlitening.com/support/index.php?topic=9602.0


ken_anthony

Also, thx Bern. CJ, I got your email.

I found a backup of my VB6 disks (good old fart habits) but I'm done with Microsoft. This is the subform template I've been using...

'---------------------------------
' fNAME.bas --
'---------------------------------

'replace NAME (case sensitive) with <form_name>.

Global gNAME as Dword
' set gForeColor, gBackColor in main module.

Sub show_(nParent As Dword)
    Local hDlg, nStyle As Dword
    nStyle = %WS_Caption Or %WS_SysMenu
    Dialog New nParent, "", 5, 5, 200, 100, nStyle To gNAME
    Dialog  Set Color gNAME, gForeColor, gBackColor
    Dialog Show Modal gNAME, Call cb_NAME
End Sub

CallBack Function cb_NAME()

    Select Case As Long CbMsg
        Case %WM_InitDialog

        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
            Select Case As Long CbCtl
                Case 0
            End Select
    End Select
End Function

ken_anthony

Oops,

show_ should be show_NAME

cj

#8
If not using PBFORMS  here is a simple modeless dialog example which allows examining input
at the keystroke level from the callback or within the message pump.   It might be a good idea
to even start with one of the many Gary Beene programs in the source code forum of PowerBASIC.

As the program gets bigger, I usually put most of the code into an include file or a DLL so it is out of sight, but
reusable so I don't rewrite the same code.


#DIM ALL
#UNIQUE VAR ON
#INCLUDE ONCE "WIN32API.INC"
%LABEL1          = 201
%TEXTBOX1        = 301
%TEXTBOX2        = 302
'
FUNCTION PBMAIN()
  MyDialog %HWND_DESKTOP
END FUNCTION
'
FUNCTION Pump1(hDlg AS DWORD) AS LONG
  LOCAL msg AS TagMsg, k AS LONG
  WHILE GetMessage(msg, %NULL, 0, 0)
    SELECT CASE Msg.message
      k = Msg.wParam
      CASE %WM_SYSKEYDOWN 'ALT keys
      CASE %WM_KEYDOWN
        IF ISTRUE(LOWRD(GetKeyState(%VK_CONTROL)) AND &H8000) THEN 'control key pressed
        ELSEIF ISTRUE(LOWRD(GetKeyState(%VK_SHIFT)) AND &H8000) THEN 'shift and character
          IF k>64 AND k< 91 THEN SetLabel hDlg, "Last character " + STR$(k+32) + "/" + CHR$(k+32)
        ELSE
           SELECT CASE k
             CASE 9    :SetLabel hDlg, "TAB"
             CASE 13   :SetLabel hDlg, "ENTER to TAB":Msg.wParam = 9
             CASE ELSE :SetLabel hDlg, "Last character " + STR$(k) + "/" + CHR$(k)
           END SELECT
        END IF
    END SELECT
    IF IsDialogMessage(hDlg, Msg) = %FALSE THEN
      TranslateMessage Msg
      DispatchMessage Msg
    END IF
  LOOP WHILE IsWindow(hdlg)
END FUNCTION
'
SUB SetLabel(hDlg AS DWORD, s AS STRING)
  CONTROL SET TEXT hDlg,%LABEL1, s
END SUB
'
FUNCTION MyDialog(BYVAL hParent AS DWORD) AS LONG
  LOCAL hDlg   AS DWORD
  DIALOG NEW hParent, "Test",200,100,200,100, %WS_OVERLAPPEDWINDOW TO hDlg
  CONTROL ADD LABEL,   hDlg, %LABEL1,   "", 10, 10, 100, 12
  CONTROL ADD TEXTBOX, hDlg, %TEXTBOX1, "", 10, 30, 100, 12
  CONTROL ADD TEXTBOX, hDlg, %TEXTBOX2, "", 10, 50, 100, 12
  DIALOG SHOW MODELESS hDlg CALL MyCallBack
  Pump1 hDlg
END FUNCTION
'
CALLBACK FUNCTION MyCallBack
  SELECT CASE AS LONG CB.MSG
    CASE %WM_INITDIALOG
    CASE %WM_COMMAND
      SELECT CASE AS LONG CB.CTL
        CASE %TEXTBOX1
          SELECT CASE AS LONG CB.CTLMSG
            CASE %EN_CHANGE
              DIALOG SET TEXT CB.HNDL, "TEXTBOX1 %EN_CHANGE"
            CASE %EN_SETFOCUS
              DIALOG SET TEXT CB.HNDL, "TEXTBOX1 SET FOCUS"
          END SELECT
        CASE %TEXTBOX2
          SELECT CASE AS LONG CB.CTLMSG
            CASE %EN_CHANGE
              DIALOG SET TEXT CB.HNDL, "TEXTBOX2 %EN_CHANGE"
            CASE %EN_SETFOCUS
              DIALOG SET TEXT CB.HNDL, "TEXTBOX2 SET FOCUS"
          END SELECT
        CASE %IDOK
          'handle Enter key here instead of in message loop (optional)
          'IF GetDlgCtrlId(GetFocus) = %IDCANCEL THEN 'if exit button
          '  DIALOG END CB.HNDL, 0 'whatever..
          'ELSE 'else textbox - move to next
          '  SetFocus GetNextDlgTabItem(CB.HNDL, GetFocus, 0)
          'END IF
      END SELECT
    CASE %WM_CLOSE 'close before destroy
    CASE %WM_DESTROY
  END SELECT
END FUNCTION


ken_anthony

Looks good. In my example I realized right after posting it that the forecolor and backcolor should be constants rather than globals, but still set in the main module. I'm also putting together a SLL of general functions. If I'd realized that after 18 years we still wouldn't have a developer environment as good as VB6 I would have worked on that. Others have done some great work but I'm reminded of a guy I knew that was a gold miner. He told me his most important tool was a teaspoon. How's that I asked. Well, lots of people know where gold can be found and usually start their day early. They move tons of dirt from spots that have the right geological attributes. The guy I know goes later in the day, after all those tons of dirt have been moved, get's out his teaspoon and digs out the last few inches where picks and shovels didn't reach and finds the nuggets wedged between hard rock channels. To emphasize the point he'd show me his latest nuggets which were quite small but well worth the time he put into it.

I need this first project to afford support staff for future projects. This first one has to be idiot proof beyond the better idiots they keep producing. Actually, I'm quite sympathetic to the user. Whatever we write for them is unknown country so as a programmer it's always a good idea to suppress our natural arrogant tendencies. Some person didn't close a door on an interlock this morning and I was trapped on my floor. That's why I call it a lift where others confuse it with an elevator. I'm from NY... that's not an elevator. <a href="https://en.wikipedia.org/wiki/Otis_Elevator_Company">Ask Otis</a>! But I still made my appointment on time this morning.