Chris and Cathleen Lenderman


Software Projects

Being a Software Engineer by trade, I am always looking for something innovative that I can do.

I usually start with the following goals:
  • What can I learn by doing this project?
  • What problem am I solving? What monetary goal does this accomplish?
  • What software is already written that I can integrate into this project?
Often my focus is "How I can save, earn, or track money?"

Here are a list of some of my projects. If you like what you see, let me know


NCIDAndroid - Network Caller ID (NCID) Client for Android

My very first Android app!  Visit this page to learn more about Caller ID for Android

The Problem

  • With all of the running around of modern life, I thought it would be nice to know if someone had called the house while we were away (of course, the simple answer would be to forward the phone, but who wants to do that every time that you leave the house)
  • And, furthermore, I thought it would be nice to see who was calling our Android phones
  • And, even further, I thought it would be nice to receive texts from our Android phones from our laptops or other NCID clients

The Solution

AndroidNCID was born!

Program Summary

  • Written using Android ADT
  • Runs on Android 2.x and above
  • For more details, see this page

Some Neat Things I Learned While Doing This

  • All about Android programming: intents, services, broadcast receivers, preferences, and COMPATIBILITY between different android versions

Special Libraries Used

None



NCIDPop - A cross-platform Network Caller ID (NCID) Client

This app was a rewrite of what was an MFC NCIDPop client.  Visit this page to learn more about NCIDPop. 

But.. prior to writing NCIDPop, I rolled my own solution.  See below for my perspective of why my solution (and subsequently NCIDPop) were needed

The Problem

  • We live in the dark ages and still have a land line (holding out for cells phones that are cheap, without contract, and unlimited in use).
  • Our cordless phone is old, and so is its battery, so it needs to stay on the charge A LOT.
  • Our DIRECTV receiver tells us whose calling "most" (but not "all") of the time. And sometimes we're watching a movie.

The Solution

I went down to the basement and found an old 56K US Robotics Sportster, brought it upstairs, and realized that if I sent the following command, the modem would report CallerID information!
at#CID=1
Since we have a Linux server that is stationary, I hooked the modem into that computer and went to work developing a client/server system that uses socket connections. Here is the program's infrastructure:

Program Summary

  • Pop-up balloon message when new call is received
  • Uses Text-To-Speech to "tell" you who is calling (Windows platform)
  • If a particular computer was off/suspended during a received call, a call summary indicating the number of "missed calls" will be displayed when the computer is resumed
  • A ringtone is played whenever the modem sends a RING statement
  • A caller history is maintained for all calls

Some Neat Things I Learned While Doing This

  • How to program using sockets
  • How to work with the MS Text-to-Speech SDK
  • How to work with the system tray and how to create notification balloons

Special Libraries Used

  • Com4J to support Text-To-Speech 

CDLock - "A Program to Lock your CD-ROM Drive"

Download CDLock

The Problem

  • My daughter has gotten to that age where she is into everything!
  • Rachael has discovered the CD-ROM drives on my laptop and my wife's laptop

The Solution

I created this small application that permits locking and unlocking of all CD-ROM drives on the system. It's not real feature rich right now. If you'd like me to add something to it for you let me know and I'll see what I can do.

Program Summary

  • Selectable option to save settings on exit:
        •     Last selected drive
        •     State of selected drives
  • Program can start up as dialog application or minimized to system tray
  • Tooltip or drive display window will tell you the locked status of the CD-ROM drive selected in the drop down
  • On resume from system hibernate/suspend, restores the locked status of the drive selected in the dropdown

Some Neat Things I Learned While Doing This

  • How to control a device using winioctl
  • How software reuse can help you have something 100% functional very quickly

Special Libraries Used

None


Hibernate - "A utility to assist with Windows hibernation"

Download Hibernate

The Problem

  • My daughter finds great joy in pulling on Cathleen's laptop screen, thus forcing the computer to hibernate

The Solution

I created this small application that will intercept hibernate and suspend attempts and start a 15 second timer. The user can cancel the attempt within that time frame.

Program Summary

  • System trap application
    •      Double click on system tray icon to hibernate manually
    •      Otherwise, issuing suspend or hibernate will display a dialog with a countdown timer

Some Neat Things I Learned While Doing This

  • How to send a broadcast message preventing hibernation from a main window
  • How NOT to send a broadcast message preventing hibernation (apparantly broadcast messages from dialogs are not honored!)
  • How software reuse can help you have something 100% functional very quickly

Special Libraries Used

None


SoundControl - "A quick and dirty volume control application"

Download SoundControl (Windows Server 2003/Windows XP/Windows 2000)

Download SoundControl (Windows Vista/Windows 7)

The Problem

  • My old Inspiron 2200 laptop had sound control ability by using hotkeys
  • My new Inspiron 1525 laptop has some cool "lightup" touch buttons to control sound, but they are slow to adjust master volume

The Solution

I created this small application that increases volume and decreases volume using:
  • "Windows+Arrow Up" and "Windows+Arrow Down" keys (for Windows Server 2003/Windows XP/Windows 2000 version)
  • "ALT+Arrow Up" and "ALT+Arrow Down" keys (for Windows Vista/Windows 7 version)

Program Summary

  • "Terminate and stay resident" (i.e. no GUI frontend)

Some Neat Things I Learned While Doing This

  • How to bind a hotkey to an application
  • How to control volume control with mmsystem (okay, I admit it, I stole a pretty comprehensive solution off of the web!)

Special Libraries Used

None


CBackup - "An Incremental, Simple Backup System"

status reports for 2008-03-30_18h_00m
2008-03-30_18h_00m: Start Time: Sun Mar 30 18:00:03 2008
2008-03-30_18h_00m: baseline: Server-shareroot-pictures: 2007-10-13_18h_00m to 2008-02-06_18h_00m
2008-03-30_18h_00m: End Time: Sun Mar 30 18:01:50 2008
2008-03-30_18h_00m: 3593 Files Processed
2008-03-30_18h_00m: 5 Files Modified Since Last Backup
2008-03-30_18h_00m: 3950450 Bytes Copied During This Backup
2008-03-30_18h_00m: Backup is complete

The Problem

  • My parents run a Bed and Breakfast, and losing data (like, you know, the ENTIRE customer database) would be a bad thing.
  • Just making a backup copy of the data each day was not enough. The database was prone to corruption, and sometimes days would go by before specific corruption was detected.
  • To be successful, this would have to be automated.

The Solution

Create a script to be scheduled to run once a day on multiple computers. The user creates a hierarchal structure to specify which computers, shares and files/directories to back up. CBackup does the rest.
#  Input files are of the following format
#
#  Computerlist.txt   <== Contains a list of all computers
#  |
#  |--ComputerName.txt  <== Contains the share names for a particular computer
#     |
#     |--ComputerName-ShareName.txt  <== Contains the paths for a particular share
#        |
#        |ComputerName-ShareName-Pathname.exclude.txt <== Contains files or directories within the path
#                                                         that should be excluded from the backup
CBackup stores all of its data in human-readable form, so that users can see which files were Modified, Deleted or simply unchanged
CBackup V1.0 - Processing Time: Sun Mar 30 19:00:05 2008
Share and Directory Name: chris/c/Documents and Settings/All Users/Start Menu
# ===== Saved Backups:
2007-12-28_19h_00m
2008-03-29_19h_00m
# ===== Files:
M 2008-03-29 23:25  //chris/c/Documents and Settings/All Users/Start Menu/HP Director.lnk
D 2008-02-10 20:33  //chris/c/Documents and Settings/All Users/Start Menu/Programs/AVG 7.5/Uninstall AVG.lnk
  2007-12-03 19:50  //chris/c/Documents and Settings/All Users/Start Menu/desktop.ini

Program Summary

  • Written in Perl (approx. 800 lines of code)
  • Backups are incremental
  • User specifies number of days of backups to retain and minimum number of backups to retain
  • Incremental backups are baselined after exceeding criteria
  • Text-readable printout to see what files have changed in any given directory
  • Status report provided to user via e-mail on completion
  • Cross-platform compatible with Windows/Linux

Some Neat Things I Learned While Doing This

  • Customized file recursion and file stat optimization
  • Cross-platform capability

Special Libraries Used

  • sendmail.pm


Filefinder - "A utility to find files across multiple user-specified directories"

The Problem

  • At the office, data is constantly coming in to support problem resolution, and it is stored on multiple network volumes.
  • I needed a way to find data quickly and conveniently based upon file name search.
  • I created a batch file for which I could "modify" a search string, but that seemed counterintuitive.
  • I had little justification to create this tool "on the clock" and definitely had zero budget to do it!
  • I can't install libraries or otherwise change configurations!
    •     I started with a threaded approach, but discovered our version of Perl was too old to support threads.
    •     So, I progressed to using pipes, but non-blocking pipes weren't very feasible on Win32.
    •     So, I decided to try sockets, but I discovered that sockets "wouldn't work" with our configuration.
    •     So, I went with a single-threaded approach.
    •     Fortunately, a robust design made the transition between the different styles of programs a very simple change.
  • It has been a while since I worked with Perl Tk, and I wanted to refresh my memory as well as learn more about it.

The Solution

Filefinder was born as one of my own creations! It is clearly overkill, considering it took the place of a 10 line batch file and that its creation took me longer than I would like to admit! Hence the reason why this was done on my time and not company time :)

Given multiple lists of custom paths, the user can select which group he or she wants to search:
[D]
\\chris\c\WINDOWS
\\chris\d\Data

[E]
\\chris\c\Program Files
\\chris\e\archives
Clicking on a path/file will launch that path/file in an application or explorer window.

Program Summary

  • Written in Perl/Tk (approx. 1000 lines of code)
  • Settings are saved in the registry
  • All program users point to the same set of search paths for ease of maintenance
  • Supports plain text, DOS, and Perl regular expression search strings

Some Neat Things I Learned While Doing This

  • Perl threading
  • Perl sockets
  • How to take advantage of some of Tk's intricacies

Special Libraries Used

  • none


MLSHelper - "Provides the ability to look at house listings offline"

The Problem

  • For our relocation to Dallas, we wanted the ability to look at home listings while we are out shopping for houses.
  • We don't have a BlackBerry, iPhone, or any other device with a data plan. I don't even have a cell phone!

The Solution

I wrote a series of macros/scripts to process data from MLS listings provided to me by our real estate agent each day with new/changed listing, placed the data in Excel, and wrote some VBA code to provide several options to browse a listing.

Program Summary

  • Front End:
    •     MLS Listing - Link to the original list of MLS listings provided by our real estate agent.
    •     Local Link - Links to an offline PDF for each house in the original list of MLS listings.
    •     Local Pictures - Links to an offline list of pictures for each house.
    •     Plat Map - Links to an offline plat map for each house.
    •     Realtor.com listing - Links to house listing on Realtor.com based on MLS ID.
  • Back End:
    •     Each "daily" MLS report is saved off in HTML (presently done by hand).
    •     A "text version" of the report is post-processed using regular expressions and then copied into Excel.
    •     A PDF is generated for each MLS report using AutoHotKey and GhostScript, which is then broken into individual PDFs using PDF Split And Merge.
    •     Local Pictures are saved off for each house using an AutoHotKey script.
    •     Plats are saved off (presently done by hand).
    •     Based on named association in Excel, the VBA scripts dynamically provide content based on MLS ID, day of provided reports, plat file name, etc.

Some Neat Things I Learned While Doing This

  • How easy it is to use VBA to create a form and work with that form in Excel.
  • How to generate simple, powerful, dynamic AutoHotKey scripts.
  • As with any program/utility, I had to decide what degree of automation I was after. Since I can literally process each day's listings in five minutes for the back end, I didn't automate the "daily data processing" element to the fullest extent. But it is definitely extendable should I choose to do so in the future.

Special Programs Used


LaserJet Status - "What's My Laser Printer Doing?"

The Problem

  • One day I walked into my office and noticed that the display on my LaserJet 5 had burned out.
  • I wanted a simple way to know what was going on with the printer.
  • (Eventually a new control panel module surfaced on eBay for $5.00 and I solved the problem. But I still use the application: hey, it tells me when my printouts are ready!)

The Solution

Using SNMP, I talk directly to the JetDirect card of my LaserJet 5

Program Summary

  • Written in Visual C++ .NET 2003
  • Provides printer status on mouse over of system tray icon or in status window

Some Neat Things I Learned While Doing This

  • How to create a system tray application
  • How to work with tooltips
  • How to work with SNMP
  • How to make a Windows program not using MFC

Special Libraries Used

  • SNMP - A C++ Wrapper for the WinSnmp library


ExtractInvestments - "How Did My Investments Perform Yesterday, and Where Can I Track It?"

The Problem

  • I like to track my investments rigorously using Microsoft Money '99 as seamlessly as possible.
  • Money '99 is very old, and even if it weren't, quotes for 401(k) and 529 plans aren't exactly going to be available via mainstream outlets.
  • Logging onto individual investment websites every day and tracking things by hand was tedious.

The Solution

Create a script to automate the process. The challenges:
  • How is the underlying Microsoft Jet database (based off of Microsoft Access '95) structured?
  • How do I extract data from secure websites using Perl?
Fortunatly, the design was pretty straight forward:

Program Summary

  • Written in Perl (approx. 500 carefully constructed lines of code)
  • Visits investment websites and extracts the fund, unit, and price data
  • Populates the updated quote information in the Money '99 database
  • If any buys are pending, populates the number of units purchased and the price
  • From there, recording payments and getting updated balance information in Money '99 is not any more difficult than "marking a bill paid"
  • Generates an e-mail report of the results

Some Neat Things I Learned While Doing This

  • Navigating web pages using Perl
  • How to write vb scripts(for "specially" scheduling the script to one once per day on APM/ACPI resume)

Special Libraries Used

  • WWW::Mechanize
  • Crypt::SSLeay
  • Win32::OLE
  • Sendmail.pm


DerbyConnect - "Timing the Pinewood Derby Without Investing in a COTS Program"

The Problem

It was desired to have the ability to time our church's Pinewood Derby "on a budget."

The Solution

Create an application that responds to a stimulus:
  • The intent was to use the parallel port, but the laptop to be used for the derby had a "simulated" parallel port with no direct control over the signal lines
  • An old keyboard was used instead, with input signals being the 1-5 keys

Program Summary

  • Written in Visual C++ .NET 2003
  • Timer starts when "5" is depressed
  • Timer stops for each individual track when 1 throuh 4 are depressed
  • Detects ties and logs results in an output file

Some Neat Things I Learned While Doing This

  • How to do precision timing
  • How to make a simple GUI dynamic
  • How to capture keypresses at different Windows messaging levels
  • How to communicate with the parallel port

Special Libraries Used

  • InpOut.dll (DLL for communicating with the parallel port. Sadly, it was not needed with the final implementation)
  • CHighTime and CHighTimeSpan


MichaelBrowser - "Simplifying My Son's Online Experience"

The Problem

My 3-year old was showing a great interest in the computer, but did not have a simple way to navigate the web.

The Solution

  • I created a Visual Studio C++ .NET program to act as a mini "web browser".
  • In hindsight, I probably could have just created a web page, but, hey, at least I learned something new. Plus, I don't know flash!

Program Summary

  • When the mouse is hovered over a button, it lights up and plays a tune
  • This program is a bit coarse (it doesn't always respond to Windows messages, so sometimes goes to "not responding", but hey, the target audience is my 3 year-old!)

Some Neat Things I Learned While Doing This

  • How data structures can make code quite dynamic!
  • How creating callbacks for individual components can make it easy to detect mouse entry/exit events
  • How to change the background color using a brush
  • How to work with mmsystem
  • How to remember the target audience (perfection isn't always necessary)

Special Libraries Used

None