ClarionX Updates

    follow me on Twitter

    Subscribe

    Enter your email address:

    Delivered by FeedBurner

    Blog powered by TypePad
    Member since 08/2006

    July 17, 2007

    5 Seconds :: Temporary Accept Loops

    When you have lots of old process code that has heaps of loops but no window event handling here is a quick way to temporarily allow window events to be processed and to release some of those resources for background processes.

    DoEvents PROCEDURE ()

    CODE

    Save# = TARGET{PROP:Timer}

    TARGET{PROP:Timer} = 1

    ACCEPT

      CASE EVENT()

      OF EVENT:Timer

         BREAK

       END

    END

    TARGET{PROP:Timer} = Save#

    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)

    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....

    Cheers Clarion ... My Old Friend...

    When a customer rings you up, gives you a rap and asks you to send an invoice for November and mentions they don't mind paying a premium...if your using C#....that's a miracle...if your using Clarion....its probably because you have delivered a solid product ahead of time and under budget....

    Here is to Clarion and its RAD philosophy....

    How to :: Subclass Windows and do Icons in the System Tray!

    Its simple to add code to your Clarion Application and you too can have icons in the System Tray. The concept is sound and simple to do in windows yourself! Microsoft has all the tools you need in their Windows API to help you extend your clarion apps by yourself...
    Here is a starting point...

    To place icons in the system tray Win API Shell Notify Icon Function does all the work for you - providing an interface to add, change and remove icons from the system tray. (See example code below for implementation)

    If you want animated icons in the System Tray you will need to setup a timer event and change the icons to create the effect of animated gif.

    If you want to capture mouse events on the icon you will need to subclass the windows event handlers of the parent clarion window. (See example code below for implementation)

    Once subclassed you can intercept messages to the window and handle them appropriately....like left mouse clicks on the icon in the system tray. You can also handle windows shutdown grace fully! When windows shuts down it sends a system exit message to all applications running...You can then shutdown your application properly and avoid those Application is still active messages....(See example code below for implementation)

    In further articles I will explain Balloon tips and other issues surrounding icons and windows services.

    Learning through doing is an excellent way to become a better programmer but not necessarily a better developer. Having said that a good mix of both skill sets is essential. I believe that any experience a good or painful one helps us grow.

    Here are some example pieces of code that I use in some of my personal applications at home.

    Example Code: (Subclassing Windows Event handlers)

    After opening window do the following....

    SubClassWindows ROUTINE
    SavedProc1 = Window{PROP:WndProc}
    Window{PROP:WndProc} = ADDRESS(SubFunc1)
    SavedProc2 = Window{PROP:ClientWndProc}
    Window{PROP:ClientWndProc} = ADDRESS(SubFunc2)
    DO SetupNID

    Once subclassed you can intercept messages to the window and handle them appropriately....like left mouse clicks on the icon in the system tray. You can also handle windows shutdown grace fully!

    Example Code: (Subclass WndProc)

    Some code adapted from a clarionmag article some years ago.

    SubFunc1 FUNCTION (hWnd,wMsg,wP,lP) ! Declare Procedure
    WM_QUERYENDSESSION Equate(00011H)
    WM_ENDSESSION Equate(00016H)
    CODE ! Begin processed code
    CASE wMsg
    IF WM_QUERYENDSESSION
         RETURN(TRUE)
    OF WM_ENDSESSION
         POST(EVENT:CloseWindow,,MainThread)
         RETURN(TRUE)
    OF EVENT:NIM
    CASE BAND(lP, 0FFFFh)
    OF LOC:WM_LBUTTONUP ! Left mouse click
       POST(Event:NIM:MouseLeft,,MainThread)
    OF LOC:WM_LBUTTONDBLCLK ! Left mouse double click
       POST(Event:NIM:MouseLeft2,,MainThread)
    OF LOC:WM_RBUTTONDOWN ! Right mouse click - pressed
    OF LOC:WM_RBUTTONUP ! Right mouse click - released
       POST(Event:NIM:MouseRight,,MainThread)
    OF LOC:WM_RBUTTONDBLCLK ! Right mouse double click
       POST(Event:NIM:MouseRight2,,MainThread)
    END
    RETURN(0)
    ELSE
    ! Pass the unhandled event and it's params on to the previous window procedure  in the chain
              RETURN(CallWindowProc(SavedProc1,hWnd,wMsg,wP,lP))
          END
    Example Code:(Icons in the Tray)

    Shell Notify Icon does all the work for you here!!!!

    SetupNID ROUTINE
    TrayCString = 'generic_ico'
    NID:cbSize = SIZE(NotifyIconData)
    NID:hWnd = Window{Prop:Handle}
    NID:uID = 100
    NID:uFlags = NIF_ICON + NIF_MESSAGE + NIF_TIP
    NID:uCBmessage = Event:NIM
    !your defined message to capture in the parent clarion window
    NID:hIcon = LoadIcon(SYSTEM{PROP:APPINSTANCE},ADDRESS(TrayCString))
    NID:ToolTip = CLIP(SVC:ToolTip) & CHR(0)
    DO AddIconToTray
    AddIconToTray ROUTINE
    IF Shell_NotifyIcon(NIM_ADD, ADDRESS(NotifyIconData)) THEN
    Icon change success fult
    END
    ChangeIconInTray ROUTINE
    IF Shell_NotifyIcon(NIM_MODIFY, ADDRESS(NotifyIconData)) THEN
    !Suceeded
    ELSE
    !Failed
    END
    RemoveIconFromTray ROUTINE
    IF Shell_NotifyIcon(NIM_DELETE, ADDRESS(NotifyIconData)) THEN

    Removed

    END

    A lot of this code would be easily adaptable to your own reusable class...enjoy learning...

    November 30, 2006

    Paris Hilton is still in Top 10 Google Search Terms...

    Just checked the a couple of sources on the net and the current top 10 search terms on google are:

    1. google
    2. girls
    3. youtube
    4. games cheat
    5. paris hilton
    6. games
    7. myspace
    8. bigfoot sightings
    9. meaning of names
    10. cindy margolis

     

    Closely followed by terms like dogs, fergie, smack that, white and nerdy, jenna jameson and anime....

    Where is the worlds head at ... the terms should be development, ajax, clarion and software....

    How would you write and article about Clarion that involved Paris Hilton, more girls, youtube, game cheats....sightings of bigfoot and a sighting of celebs Cindy Margolis and Jenna Jameson.....it would be easy to include white and nerdy tho....

    HANG ON just did write a post that included those.... :-)

    Go figure...

    Last update: Sun, 05 Nov 2006 08:37:16 GMT