Announcement

Collapse
No announcement yet.

Question about ShowData (in Fred's SDK tutorial )

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

  • Question about ShowData (in Fred's SDK tutorial )

    After copying the code for all four files, and successfully compiling it, I get a runtime error
    ===
    the procedure entry point sqlallochandle could not be located in ODBC32.dll
    ===
    On my system ODBC32.dll is located in the System32 folder.

    I tried both approaches as mentioned in the text (copied below for convienient reference), but I get this run time error both ways.

    =========================================================
    =========================================================

    '*******************************************
    'file name: showdata.inc (2nd of 4)
    '*******************************************

    '************************************************* *************************************************
    'this is essentially the main include file for the application showdata.bas. i find that in a major
    'application containing many forms/dialogs there will be common functions that aren't specific to any
    'particular form. these routines can be kept in a main include file such as this. also, types,
    'equates and global variables can go there too. in this particular application i put in here the
    'only two global variables, several equates (the control ids for the buttons, list box and text box),
    'and the type i use to pass the window procedure parameters to message handlers. here they are...
    '************************************************* *************************************************

    Code:
    global sztextboxdisplay as asciiz*16 'holds the class name string 'frmtextbox'
    global szlistboxdisplay as asciiz*16 'holds the class name string 'frmlistbox'
    %idc_button_1=1001 'ctrl id for button on frmmainwindow. goes in 9th parameter of createwindow() call.
    %idc_button_2=1002 'ctrl id for button on frmmainwindow. goes in 9th parameter of createwindow() call.
    %idc_edit_box=1003 'control id for text/edit box
    %idc_list_box=1004 'control id for listbox
    %idc_lb_load =1005 'control id for button at bottom of frmlistbox

    type wndeventargs 'type holds parameters for window procedure
    hins as dword
    hwnd as dword
    wparam as dword
    lparam as dword
    end type'************************************************* *************************************************
    'also with this file i included the odbc equates and function declarations i needed to make this app
    'work in the absence of including the three main odbc includes along with the includes at the top
    'of showdata.bas (the main program file). i didn't want to force my readers into having to go to the
    'internet (at www.powerbasic.com) to download special files (the odbc includes) just to get this app
    'to work, so i pulled four function declarations and eight equates out of the odbc includes, and am
    'including them right here in the source code of showdata.inc. here they are...
    '************************************************* *************************************************

    Code:
    'odbc equates and function declarations needed to make sqldrivers() work.
    %sql_null_handle = 0&
    %sql_handle_env = 1
    %sql_attr_odbc_version = 200
    %sql_ov_odbc3 = 3???
    %sql_is_integer = (-6)
    %sql_fetch_next = 1
    %sql_no_data = 100
    %sql_error = -1
    '
    declare function sqlallochandle lib "odbc32.dll" alias "sqlallochandle" _
    ( _
    byval handletype as integer,_
    byval inputhandle as dword,_
    byref outputhandle as dword _
    ) as integer
    '
    declare function sqlsetenvattr lib "odbc32.dll" alias "sqlsetenvattr" _
    ( _
    byval environmenthandle as dword,_
    byval attribute as long,_
    byref value as any,_
    byval stringlength as long _
    ) as integer
    '
    declare function sqldrivers lib "odbc32.dll" alias "sqldrivers" _
    ( _
    byval henv as dword,_
    byval fdirection as word,_
    byref szdriverdesc as asciiz,_
    byval cbdriverdescmax as integer,_
    byref pcbdriverdesc as integer,_
    byref szdriverattributes as asciiz,_
    byval cbdrvrattrmax as integer,_
    byref pcbdrvrattr as integer _
    ) as integer
    '
    declare function sqlfreehandle lib "odbc32.dll" alias "sqlfreehandle" _
    ( _
    byval handletype as integer,_
    byval thehandle as dword _
    ) as integer'************************************************* *************************************************
    'now the situation with these odbc equates and declares is this. if by some chance you might be
    'interested in learning to use the odbc api functions to work with databases, then you really should
    'go to...
    '
    ' http://www.powerbasic.com/files/pub/...e/pbodbc30.zip
    '
    'and get the three necessary odbc includes for your work. the three necessary includes are
    'sqltypes.inc, sql32.inc and sqlext32.inc. if you get those files from the pb downloads then you can
    'modify this app to use them instead of the 41 lines of code listed above. in that case just delete
    'those eight equates and four function declarations and change the includes at the top of showdata.bas
    'like so...

    '************************
    'file name: showdata.bas
    '************************
    '
    '************************************************* *****************************************
    '#compile exe
    '#dim all
    '#include "win32api.inc" '<<this file is courtesy of powerbasic and you should be thankful for it
    '#include "sqltypes.inc" '<<odbc include !!!!!
    '#include "sql32.inc" '<<odbc include !!!!!
    '#include "sqlext32.inc"' '<<odbc include !!!!!
    '#include "showdata.inc" '<<my main include for app equates, declares and functions
    '#include "frmtextbox.inc" '<<my include that contains code for the text/edit box form
    '#include "frmlistbox.inc" '<<my include that contains code for the list box form
    '************************************************* *****************************************
    'if you check back in showdata.bas you'll see those three odbc includes are missing, but this
    'app should work fine without them as i copied the necessary equates and declares directly
    'into the code here. but if you don't get those includes from powerbasic don't delete those
    'lines or this app won't even comple much less run!
    '************************************************* *****************************************



    '************************************************* ****************************************
    'function name: blngetsqldriverdata(heditbox as dword) as long
    'purpose: sets up odbc environment for calls to sqldrivers
    ' and fills text box with driver names and driver
    ' attribute-value pairs
    'return value %true or %false indicating success or failure
    'parameters one parameter - handle to edit box to fill with
    ' driver descriptions and driver attribute values
    '************************************************* *****************************************
    'the purpose of this application is just to show you how to load data into a text box or
    'list box using sdk style code and calling windows api functions. i mentioned in
    'frmtextbox.inc that for that purpose you could consider what goes on in this particular
    'function as an inscrutable 'black box' out of which data flows faithfully if not somewhat
    'mysteriously. but if you want a very detailed blow by blow description of how this function
    'works, see the following post in source code:
    '
    'sqldrivers() demo http://www.powerbasic.com/support/pb...ad.php?t=25068
    '
    '************************************************* *****************************************

    Code:
    function blngetsqldriverdata(heditbox as dword) as long
    local ilen1 as integer,ilen2 as integer
    local szdriverattr as asciiz*256
    local szdriverdes as asciiz*64
    local ptrbyte as byte ptr
    local strarr() as string
    local strtext as string
    local henvr as dword
    register i as long
    '
    if sqlallochandle(%sql_handle_env,%sql_null_handle,henvr)<>%sql_error then
    call sqlsetenvattr(henvr,%sql_attr_odbc_version,byval %sql_ov_odbc3,%sql_is_integer)
    while sqldrivers(henvr,%sql_fetch_next,szdriverdes,64,ilen1,szdriverattr,256,ilen2)<>%sql_no_data
    strtext=strtext & szdriverdes & chr$(13,10) & chr$(13,10)
    decr ilen2 'convert one based count of bytes to zero basing for pointer use.
    ptrbyte=varptr(szdriverattr) 'loop through szdriverattr buffer one byte at a time for ilen2 bytes
    for i=0 to ilen2 'substituting commas ( chr$(44) ) for null bytes. ilen1 and ilen2
    if @ptrbyte[i]=0 then 'are output parameters in sqldrivers() odbc function call. then
    @ptrbyte[i]=44 'powerbasic's parse statement will parse driver attribute pairs into
    end if 'string array for output. 'the last byte at ilen2 was a null that
    next i 'got turned into a comma, so lets remove it. storing a null byte
    @ptrbyte[ilen2]=0 'there will also decrease length of string by one.
    redim strarr(parsecount(szdriverattr)-1) 'parsecount returns a one based count, but parse
    parse szdriverattr,strarr() 'starts storing parsed strings into element zero
    for i=0 to ubound(strarr,1) 'of strarr(), so it is best to use parsecount - 1.
    strtext=strtext & strarr(i) & chr$(13,10) 'add crlf after each string to get them into seperate
    next i 'lines.
    strtext=strtext & chr$(13,10) & chr$(13,10)
    loop
    call sqlfreehandle(%sql_handle_env,henvr)
    call setwindowtext(heditbox,byval strptr(strtext))
    blngetsqldriverdata=%true
    else
    blngetsqldriverdata=%false
    end if
    end function

  • #2
    Because of the change of the forum software, some posts have become converted to lower case. Therefore, the alias names of the functions are incorrect.

    Code:
    '**************************
    'File Name:  ShowData.inc
    '**************************
    
    '**************************************************************************************************
    'This is essentially the main include file for the application.  I find that in a major application
    'containing many forms/dialogs there will be common functions that aren't specific to any particular
    'form.  These routines can be kept in a main include file such as this.  Also, types, equates and
    'global variables can go there too.  In this particular application I put in here several equates
    '(the control ids for the buttons, list box and text box), and the type I use to pass the window
    'procedure parameters to message handlers.  Here they are...
    '**************************************************************************************************
    %IDC_BUTTON_1               =  1201
    %IDC_BUTTON_2               =  1202
    %IDC_EDIT_BOX               =  1203
    %IDC_LIST_BOX               =  1204
    %IDC_LB_LOAD                =  1205
    
    Type WndEventArgs
      hWnd                      As Dword
      wParam                    As Dword
      lParam                    As Dword
    End Type
    
    '**************************************************************************************************
    'Also with this file I included the ODBC equates and function declarations I needed to make this app
    'work in the absence of including the three main ODBC includes along with the includes at the top
    'of ShowData.bas (the main program file).  For you see, by my including that ODBC function call to
    'load the edit box with database driver information, I complicated things for myself considerably
    'here.  I didn't want to force my readers into having to go to the internet (at www.Powerbasic.com)
    'to download special files (the ODBC Includes) just to get this app to work, so I pulled four
    'function declarations and eight equates out of the ODBC includes, and am including them right here
    'in the source code of ShowData.inc.  Here they are...
    '**************************************************************************************************
    
    'ODBC equates and function declarations needed to make SQLDrivers() work.
    %SQL_NULL_HANDLE             = 0&
    %SQL_HANDLE_ENV              = 1
    %SQL_ATTR_ODBC_VERSION       = 200
    %SQL_OV_ODBC3                = 3???
    %SQL_IS_INTEGER              = (-6)
    %SQL_FETCH_NEXT              = 1
    %SQL_NO_DATA                 = 100
    %SQL_ERROR                   = -1
    
    Declare Function SQLAllocHandle Lib "ODBC32.DLL" Alias "SQLAllocHandle" _
    ( _
      Byval HandleType          As Integer,_
      Byval InputHandle         As Dword,_
      Byref OutPutHandle        As Dword _
    ) As Integer
    
    Declare Function SQLSetEnvAttr LIB "ODBC32.DLL" ALIAS "SQLSetEnvAttr" _
    ( _
      Byval EnvironmentHandle   As Dword,_
      Byval Attribute           As Long,_
      Byref Value               As Any,_
      Byval StringLength        As Long _
    ) As Integer
    
    Declare Function SQLDrivers LIB "ODBC32.DLL" ALIAS "SQLDrivers" _
    ( _
      Byval henv                As Dword,_
      Byval fDirection          As Word,_
      Byref szDriverDesc        As Asciiz,_
      Byval cbDriverDescMax     As Integer,_
      Byref pcbDriverDesc       As Integer,_
      Byref szDriverAttributes  As Asciiz,_
      Byval cbDrvrAttrMax       As Integer,_
      Byref pcbDrvrAttr         As Integer _
    ) As Integer
    
    Declare Function SQLFreeHandle LIB "ODBC32.DLL" ALIAS "SQLFreeHandle" _
    ( _
      Byval HandleType          As Integer,_
      Byval TheHandle           As Dword _
    ) As Integer
    
    
    '*****************************************************************************************
    'Function Name:  blnGetSQLDriverData(hEditBox As Dword) As Long
    'Purpose:        Sets up ODBC Environment for Calls To SQLDrivers
    '                and fills text box with driver names and driver
    '                attribute-value pairs
    'Return Value    %TRUE or %FALSE indicating success or failure
    'Parameters      One parameter - handle to edit box to fill with
    '                driver descriptions and driver attribute values
    '******************************************************************************************
    Function blnGetSQLDriverData(hEditBox As Dword) As Long
      Local iLen1 As Integer,iLen2 As Integer
      Local szDriverAttr As Asciiz*256
      Local szDriverDes As Asciiz*64
      Local ptrByte As Byte Ptr
      Local strArr() As String
      Local strText As String
      Local hEnvr As Dword
      Register i As Long
    
      If SQLAllocHandle(%SQL_HANDLE_ENV,%SQL_NULL_HANDLE,hEnvr)<>%SQL_ERROR Then
         Call SQLSetEnvAttr(hEnvr,%SQL_ATTR_ODBC_VERSION,Byval %SQL_OV_ODBC3,%SQL_IS_INTEGER)
         While SQLDrivers(hEnvr,%SQL_FETCH_NEXT,szDriverDes,64,iLen1,szDriverAttr,256,iLen2)<>%SQL_NO_DATA
           strText=strText & szDriverDes & Chr$(13,10) & Chr$(13,10)
           Decr iLen2
           ptrByte=VarPtr(szDriverAttr)  'Loop through szDriverAttr buffer one byte at a time for iLen2 bytes
           For i=0 To iLen2              'substituting commas ( Chr$(44) ) for null bytes.  iLen1 and iLen2
             If @ptrByte[i]=0 Then       'are output parameters in SQLDrivers() ODBC function call.  Then
                @ptrByte[i]=44           'PowerBASIC's Parse statement will parse driver attribute pairs into
             End If                      'string array for output.
           Next i
           @ptrByte[iLen2]=0             'The last byte at iLen2 was a null that got turned into a comma.
           ReDim strArr(ParseCount(szDriverAttr)-1)
           Parse szDriverAttr,strArr()
           For i=0 To UBound(strArr,1)
             strText=strText & strArr(i) & Chr$(13,10)
           Next i
           strText=strText & Chr$(13,10) & Chr$(13,10)
         Loop
         Call SQLFreeHandle(%SQL_HANDLE_ENV,hEnvr)
         Call SetWindowText(hEditBox,Byval StrPtr(strText))
         blnGetSQLDriverData=%TRUE
      Else
         blnGetSQLDriverData=%FALSE
      End If
    End Function
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      Thank you Jose. That was the problem.

      Comment


      • #4
        Larry,

        when posting source code, especially larger pieces like you did, enclosing the code within [ code ][ /code ] (without the spaces), improves readability a lot, as the forum keeps proper formatting:

        (Without code tags)

        Type WndEventArgs
        hWnd As Dword
        wParam As Dword
        lParam As Dword
        End Type

        (With code tags)

        Code:
        Type WndEventArgs
          hWnd                      As Dword
          wParam                    As Dword
          lParam                    As Dword
        End Type

        Comment


        • #5
          Code:
          redim strarr(parsecount(szdriverattr)-1) 'parsecount returns a one based count, but parse
          parse szdriverattr,strarr() 'starts storing parsed strings into element zero
          Not directly on topic, but for those who are more comfortable with '1-based' arrays but don't want to give up the documented performance benefits of using zero-based arrays...

          Code:
            N = NumberOfItems in array
            REDIM  theArray (n) 
            PARSE  bigString, theArray()     ' parse into elements 0:n-1
              ---   or ------
            LINE INPUT #h, TheArray()      ' load from disk into elements 0:n-1
            ARRAY INSERT theArray(0), ""   ' shift elements to 1:n
          This makes element zero a null and moves all your 'records' to elements 1 to N

          MCM
          Last edited by Michael Mattias; 1 Nov 2007, 08:57 AM.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            [QUOTE=Knuth Konrad;267413]Larry,

            when posting source code, especially larger pieces like you did, enclosing the code within [ code ][ /code ] (without the spaces), improves readability a lot, as the forum keeps proper formatting:


            Looking back at my opening post, I see what you mean. And when I post code of my own (usually) I do use the tags.

            But in this case I was quoting someone else. And that someone else had used the tags in THEIR post.
            So, why did the quoting process remove the tags? I PROBABLY should have attempted to edit my post before I submitted it.

            ===
            On the ohter hand, the message board software POSITIVELY should have handled this for me.
            ===

            ?No es?

            Comment


            • #7
              Michael,

              Thanks for the tip.

              I'm usually agnostic when it comes to zero based arrays versus the alternatives. But that is mostly because I've not yet found an application where it made a real difference in performeace.

              One of these days, however, I'll find a strong need for better performance with a non-zero based array, and I will smile as I contemplate your contribution. (I might even send you another note.)

              Comment

              Working...
              X