ClarionX Updates

    follow me on Twitter

    Subscribe

    Enter your email address:

    Delivered by FeedBurner

    Blog powered by TypePad
    Member since 08/2006

    May 27, 2008

    Btrieve 6.15 is my Closest Friend

    For those of you who love "Old School" Database drivers... Btrieve Rocks!

    The core Btrieve 6.15 engine still exists inside Pervasive.SQL and its pretty much the same engine you would have known and loved since its release in 1995 for windows 95/NT.

    It provides extremely efficient, high-speed ISAM data access that can’t be beat by any other access method.

    The latest versions have relational capabilities (a SQL engine).

    Btrieve stands the test of time. Why only now, 27/5/2008 am I considering moving my major application from btrieve 6.15 (circa 1995) to SQL Server Express Edition 2005.

    Btrieve has served me faithfully for 13 years and will go on serving me. Its Gold!

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

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

    September 21, 2006

    How to lose a Customer in 10 days...

    To be a successful software developer, you have to become a skilled communicator.

    You think you're a good communicator...You keep your users informed and you listen to their problems. So why is it that no one appears to read your e-mails or seems capable of following your instructions? Are you surprised to learn that the users have been living with computer issues rather than ask you for help? These are all signs of a breakdown in communication -- which we, as software developers, frequently misinterpret as user indifference or even stupidity. Before long, we find ourselves on a downward spiral toward complete communications failure. Even with the best intentions, it's possible to sabotage your own attempts to communicate with the users by inadvertently committing one or more of the following errors of miscommunication.

    1. Inappropriate nonverbal communication :: Our words may say "Absolutely, yes, of course I don't mind helping you map the network drive," while our facial expressions, tone, and body language simultaneously scream, "You complete and utter knob, do you honestly think that I spent four years at uni, have an IQ of 167, and earned 53 technical certifications just so I could  map your network drive? Would you like me to wipe your arse as well?" --- quote Techrepublic
    2. Showing off :: Using every technical piece of jargon imaginable....all you are doing is making your customer feel stupid...
    3. Losing patience
    4. Being dismissive
    5. Failure to inform
    6. Poor documentation
    7. Lying :: In short, when presented with a problem you can't resolve, for whatever reason, it's far better to be direct with users and help them find a resolution by some other means rather than mask our ignorance or unwillingness as an insoluble technical issue.
    8. Giving too much information :: Honesty may be the best policy, but this does not mean it's appropriate to overburden the users with too much information. They may actually not need you or worse still realise they know more than you...
    9. Not providing training
    10. Failing to listen
      Communication is a two-way process.

    Hopefully these are others errors and not ours...

    ...

    September 05, 2006

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