ClarionX Updates

    follow me on Twitter

    Subscribe

    Enter your email address:

    Delivered by FeedBurner

    Blog powered by TypePad
    Member since 08/2006

    July 11, 2007

    Twitterfying ClarionX

    Twitter All this week, we have been playing around with Twitter. Twitter has brought internet communication to another level. Some see it as the next irc, some see it as a tumblelog, and others see it as one huge chat room. I think it's a bit more than all of these things, and it's really taking a step forward. Its a way to connect with your community without a lot of effort and in realtime.

    Our experiences with twitter has encouraged us to revamp our blog. Now you can see what we are doing while we are not posting on our blog.

    ClarionX Twitter Updates can be found in the right hand menu.

    Enjoy.

    July 09, 2007

    Graduate Programmer Job - Sydney, Australia

    A company I work with requires a Graduate Programmer ( with or without Clarion Experience)....
    A forward and progressive household brand name seeks an enthusiastic and analytical self starter that is looking to develop their career in the IT world.

    At the core of our business is our technology products and team. These products are varied and range from Desktop Applications to Internet Technologies. The products are respected and renowned throughout the world in our market.

    We are currently looking for an excellent University Graduate to join our Technology Team working from our offices located just south of the Sydney CBD.

    We are currently working on some new and exciting major projects that are set to revolutionise the industry. Our senior members of the team will be working closely with the successful applicant/s providing coaching and mentoring that will ensure that you make the transition from studies to success in the corporate environment.

    This is an entry level position for those candidates that have recently successfully completed their Degree in Computer Science (or equivalent) to work on our Desktop Applications.

    Those that can demonstrate the following skills will be highly considered for this role:

    ? Excellent programming skills
    ? Relational database knowledge
    ? Excellent communication skills
    ? Willingness to learn

    This is an excellent opportunity for graduates that are keen to move in to the corporate world and demonstrate their skills, abilities and knowledge to advance their career progression.

    Applications close 20th July 2007, and all successful applicants will be contacted within a week of a close date.
    Email your applications to jmoore@ljh.com.au

    June 26, 2007

    Get OS Version in Clarion 5 Apps

    Windows Api can help you with your Vista Apps in Clarion5. It's imperative that your app knows what version of windows is running. The win32 fn   is GetVersionExA(ULONG),BOOL,PASCAL,RAW.

    Works for me.

                 GLOBAL DATA:

    OSVERSIONINFO          GROUP,TYPE
    dwOSVersionInfoSize      ULONG
    dwMajorVersion           ULONG
    dwMinorVersion           ULONG
    dwBuildNumber            ULONG
    dwPlatformId             ULONG
    szCSDVersion             BYTE,DIM(128)
                            END

    DATA:

    lOSVersion        GROUP(OSVERSIONINFO)
                      END
    lMajorVersion     LONG
    lMinorVersion     LONG
    lPlatformID       LONG
    szOSVersion       STRING(100)
    szAns             STRING(200)

    VER_PLATFORM_WIN32s             EQUATE(0)
    VER_PLATFORM_WIN32_WINDOWS      EQUATE(1)
    VER_PLATFORM_WIN32_NT           EQUATE(2)

    CODE:

        lOSVersion.dwOSVersionInfoSize = LEN(lOSVersion)
        unused# = GetVersionExA(ADDRESS(lOSVersion))
        lMajorVersion = lOSVersion.dwMajorVersion
        lMinorVersion = lOSVersion.dwMinorVersion
        lPlatformID   = lOSVersion.dwPlatformId

        !MESSAGE(lMajorVersion&','&lMinorVersion)

        CASE lMajorVersion
        OF 6
           szAns = 'Windows VISTA'
        OF 5
           !Added the following to give suppport for Windows XP!
           If lMinorVersion = 0 Then
              szAns = 'Windows 2000'
           ElsIf lMinorVersion = 1 Then
              szAns = 'Windows XP'
           ElsIf lMinorVersion = 2 Then
              szAns = 'Windows 2003 Server'
           End
        OF 4
           If lPlatformID = VER_PLATFORM_WIN32_NT Then
             szAns = 'Windows NT 4.0'
           Else
            IF lMinorVersion = 0 THEN
              szAns = 'Windows 95'
            ELSIF lMinorVersion = 10 THEN
              szAns = 'Windows 98'
            ELSIF lMinorVersion = 90 THEN
              szAns = 'Windows Me'
            END
           End
       OF 3
           If lPlatformID = VER_PLATFORM_WIN32_NT Then
             szAns = 'Windows NT 3.x'
           Else
             szAns = 'Windows 3.x'
           End
       Else
           szAns = 'Unknown Windows Version'
       End

       RETURN CLIP(szAns)

    June 06, 2007

    Computer Name

    How to Get the name of the Computer 101:

    Add this code in to "Inside Global Map Embed"

    MODULE('Windows API')
      GetComputerName(ULONG,ULONG),BOOL,PASCAL,RAW,NAME('GetComputerNameA')
    END

    The Get PC Name Function that implements the API call

    GetPCName            FUNCTION ()       

    szBuffer  CSTRING(255)
    lBufferSize  ULONG

    CODE                                          

    lBufferSize = SIZE(szBuffer)
    unused# = GetComputername(ADDRESS(szBuffer),ADDRESS(lBufferSize)) RETURN CLIP(szBuffer)

    June 04, 2007

    Writing Base64

    We have seen how to decode base64 now lets see how to encode base64....

    This is pretty much a reverse of the decode function with a couple of exceptions. Then base64char function just does a lookup on a number for the corresponding character in the table.

    All we do is loop throuugh the raw string  data in groups of three obviously at the end if the source data is not a multiple of 3 we will buffer with the padding character ''=".

    With each group of three bytes (24 bits) we transform that into four 6 bit characters from our limited character set..

    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

    and the padding char =.

    Here is the code:

    Base64encode

          oString = ''
          BytesLeft# = LEN(CLIP(lString))
          LOOP i# = 1 TO LEN(CLIP(lString)) BY 3
            IF BytesLeft# = 1 THEN
            BigNumber# = BSHIFT(VAL(lString[i#]),16)
            Char1# = BAND(BSHIFT(BigNumber#,-18),111111b)
            Char2# = BAND(BSHIFT(BigNumber#,-12),111111b)
            oString = LEFT(CLIP(oString)) & base64char(Char1#)&base64char(Char2#)&'=='
            ELSIF BytesLeft# = 2 THEN
            BigNumber# = BSHIFT(VAL(lString[i#]),16) + BSHIFT(VAL(lString[i# + 1]),8)
            Char1# = BAND(BSHIFT(BigNumber#,-18),111111b)
            Char2# = BAND(BSHIFT(BigNumber#,-12),111111b)
            Char3# = BAND(BSHIFT(BigNumber#,-6),111111b)
            oString = LEFT(CLIP(oString)) & base64char(Char1#)&base64char(Char2#)&base64char(Char3#)&'='
            ELSE
            BigNumber# = BSHIFT(VAL(lString[i#]),16) + BSHIFT(VAL(lString[i# + 1]),8) + VAL(lString[i# + 2])
            Char1# = BAND(BSHIFT(BigNumber#,-18),111111b)
            Char2# = BAND(BSHIFT(BigNumber#,-12),111111b)
            Char3# = BAND(BSHIFT(BigNumber#,-6),111111b)
            Char4# = BAND(BigNumber#,111111b)
            oString = LEFT(CLIP(oString)) & base64char(Char1#)&base64char(Char2#)&base64char(Char3#)&base64char(Char4#)
            END
            IF BytesLeft# <= 3 THEN BREAK.
            BytesLeft# -= 3
          END
          RETURN LEFT(CLIP(oString))

    Enjoy....obvioulsy this code could be improved. Currenlty it is limited to 4Mb and it involves repeated clips of a large string....til next time

    May 29, 2007

    Reading Base64 ...

    This is the first article in an Internet Protocol/encoding Series...As developers we will at one time or another need to read base64 encoded data....heres my take...

    Base64 is used to encode binary files in a text format suitable to be encapsulated in text documents. One interesting thing about base 64 is that it is one of the only data representation
    schemes in modern use that doesn’t encrypt or compress the data. It just represents data
    in a different form.

    The solution to this problem was to create a data representation protocol that would allow
    binary data to be encapsulated within another document. The defacto standard for doing
    this is called base 64. In fact, some applications use base 64 as an encryption technique,
    albeit a weak one. Basic authentication over the Internet encrypts the username-password
    using base 64.

    Here is a simple base64 decoder algorithm that has been very useful over the years...

    base64decode PROCEDURE(STRING b64)

    b64chars STRING('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')

    oString ANY

    CODE

    oString = '' !Dont use CLEAR it will cause a GPF on an ANY Variable

    ! Base64 strings especially those from emails can contain carriage returns and tabs these must be removed before decoding....

    b64 = StringReplace(b64,CHR(9),'')
    b64 = StringReplace(b64,CHR(10),'')
    b64 = StringReplace(b64,CHR(13),'')

    ! Base64 strings are groups of four characters and need to be stepped through by 4....

    LOOP i# = 1 TO LEN(CLIP(b64)) BY 4

    !Create a 24 bit Number by bit shifting the four chars values by  6 bit segments...

    BigNumber# = BSHIFT(INSTRING(b64[i#],b64chars,1,1)-1,18) + BSHIFT(INSTRING(b64[i#+1],b64chars,1,1)-1,12) + BSHIFT(INSTRING(b64[i#+2],b64chars,1,1)-1,6) + (INSTRING(b64[i#+3],b64chars,1,1)-1)

    !Extract the original 3 ascii chars by bit shifting in the other direction by 8 bit segments...

    Char1# = BAND(BSHIFT(BigNumber#,-16),11111111b)
    Char2# = BAND(BSHIFT(BigNumber#,-8),11111111b)
    Char3# = BAND(BigNumber#,11111111b)

    !handle trailing padding characters thus...and translate the character values...
    IF b64[i#+3] = '=' AND b64[i#+2] ~= '=' THEN
    oString = oString & CHR(Char1#)&CHR(Char2#)
    ELSIF b64[i#+3] = '=' AND b64[i#+2] = '=' THEN
    oString = oString & CHR(Char1#)
    ELSE
    oString = oString & CHR(Char1#)&CHR(Char2#)&CHR(Char3#)
    END
    !repeat operation for each group of four base64 chars

    END

    RETURN CLIP(oString)

    The result is the unencoded text or binary data....for more info on base64 like a encoding checkout RFC 3548...

    March 28, 2007

    Fireside Chats

    In the next few weeks ClarionX will be covering topics sent to them by readers regarding Clarion development on the windows platform.

    So if you have any questions or topics of interest...email us.

    ...

    March 27, 2007

    Global Extension Template - ClarionX.tpl

    How do you write an Global Extension Template?

    You can download the full template here.

    Here is a template I started writing along time ago when I was learning about temples and how they could help me be a more efficient developer....

    Open a text editor and create a new file called for example clarionx.tpl (template)

    1. Define the template Chain

    #TEMPLATE(ClarionXTemplates,'ClarionX Dev Tools 1.0')

    2.  Define the Global Extension Template

    #EXTENSION(ClarionXGlobal,'ClarionX Dev Tools 1.0 Global'),APPLICATION

    ,APPLICATION means that it should only be available as a Global Extension and not at the procedure level.

    3. Give the User/developer  some options to play around with in the IDE...

    To generate an include file, txa or txd and/or perform  backups of application txa after each compile...feel free to take this code and improve it....

    #DISPLAY('ClarionX Dev Tools are Enabled'),AT(10,,,)
    #PROMPT('Generate Include File ' & %Application & '.inc',CHECK),%GenerateAppIncludeFile,DEFAULT(1),AT(10,20,,)
    #PROMPT('Generate TXA File ' & %Application & '.txa',CHECK),%GenerateTxaFile,DEFAULT(0),AT(10,30,,)
    #PROMPT('Generate TXD File ' & %Application & '.txd',CHECK),%GenerateTxdFile,DEFAULT(0),AT(10,40,,)
    #PROMPT('Auto Backup eg. TXA ' & %Application & '_yyyymmdd_hhmmss.txa',CHECK),%AutoBackups,DEFAULT(1),AT(10,50,,)

    These are all pretty self  explanatory steps.

    4. Lets get to the guts....

    To get this template to work we need to make sure this template code is only executed when the template is initialised...

    #ATSTART

    #ENDAT

    Generate INC File .... Pretty Simple

    #IF (%GenerateAppIncludeFile = 1)
    #DECLARE(%AppIncludeFile)
    #SET(%AppIncludeFile,%Application & '.inc')
    #CREATE(%AppIncludeFile)
    #FOR(%Procedure),WHERE(%ProcedureExported = 1)
      %(%Procedure & %Prototype)
    #ENDFOR
    #CLOSE(%AppIncludeFile)
    #ENDIF

    Generate TXA File .... Pretty Simple

    #IF (%GenerateTxaFile = 1)
    #DECLARE(%TxaFile)
    #SET(%TxaFile,%Application & '.txa')
    #CREATE(%TxaFile)
    #EXPORT
    #CLOSE(%TxaFile)
    #ENDIF

    Generate TXD File .... Pretty Simple

    #IF (%GenerateTxdFile = 1)
    #DECLARE(%TxdFile)
    #SET(%TxdFile,%Application & '.txd')
    #CREATE(%TxdFile)
    #MESSAGE('Exporting Dictionary...',2)
    #EXPORT(%DictionaryFile)
    #CLOSE(%TxdFile)
    #ENDIF
    #ENDAT
    #ATEND

    Auto Backup .... Pretty Simple...just a datetime stamped TXA

    #IF (%AutoBackups = 1)
    #DECLARE(%BackupFile)
    #SET(%BackupFile,%Application & '_' & CLIP(FORMAT(%ProgramDateChanged,@d12)) & '_' & CLIP(FORMAT(%ProgramTimeChanged,@t5))&'.txa')
    #CREATE(%BackupFile)
    #MESSAGE('Backing Up Program Settings...',2)
    #EXPORT
    #CLOSE(%BackupFile)
    #ENDIF
    #ENDAT

    You can download the full template here. Simply register it in the template registry and thats it....

    This is a good example of the usefulness of templates. With clarionx.tpl dev tools template you can tick a checkbox and  generate a txa or txd, generate an inc file for your dlls and without knowing it checkpoint your code with autobackups ..... pretty handy.

    More templates coming soon....

    March 16, 2007

    ClarionX Rebooted!

    Today the blog has been revitalised....and we apologise for the tardy posting...but lets move on....

    Recently we have been doing some nifty things with Clarion 6.3 and breaking some new ground in the areas of reusabilty and extending applications.

    So stay tuned....for some Clarion Concept discussions...

    The ClarionX Team

    December 04, 2006

    CALL and UNLOAD...The Never Ending Story...

    Thought Clarion App Extensions...

    Wouldn't it be great if we had and architecture which allowed us or 3rd party clarion developers to extend our applications without modifying the base code ... creative use of CALL, UPLOAD and passing an interface class can achieve this...

    More to follow over the next few weeks....